opt-functions.awk 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. # Copyright (C) 2003-2015 Free Software Foundation, Inc.
  2. # Contributed by Kelley Cook, June 2004.
  3. # Original code from Neil Booth, May 2003.
  4. #
  5. # This program is free software; you can redistribute it and/or modify it
  6. # under the terms of the GNU General Public License as published by the
  7. # Free Software Foundation; either version 3, or (at your option) any
  8. # later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; see the file COPYING3. If not see
  17. # <http://www.gnu.org/licenses/>.
  18. # Some common subroutines for use by opt[ch]-gen.awk.
  19. # Define some helpful character classes, for portability.
  20. BEGIN {
  21. lower = "abcdefghijklmnopqrstuvwxyz"
  22. upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  23. digit = "0123456789"
  24. alnum = lower "" upper "" digit
  25. }
  26. # Return nonzero if FLAGS contains a flag matching REGEX.
  27. function flag_set_p(regex, flags)
  28. {
  29. # Ignore the arguments of flags with arguments.
  30. gsub ("\\([^)]+\\)", "", flags);
  31. return (" " flags " ") ~ (" " regex " ")
  32. }
  33. # Return STRING if FLAGS contains a flag matching regexp REGEX,
  34. # otherwise return the empty string.
  35. function test_flag(regex, flags, string)
  36. {
  37. if (flag_set_p(regex, flags))
  38. return string
  39. return ""
  40. }
  41. # Return a field initializer, with trailing comma, for a field that is
  42. # 1 if FLAGS contains a flag matching REGEX and 0 otherwise.
  43. function flag_init(regex, flags)
  44. {
  45. if (flag_set_p(regex, flags))
  46. return "1 /* " regex " */, "
  47. else
  48. return "0, "
  49. }
  50. # If FLAGS contains a "NAME(...argument...)" flag, return the value
  51. # of the argument. Return the empty string otherwise.
  52. function opt_args(name, flags)
  53. {
  54. flags = " " flags
  55. if (flags !~ " " name "\\(")
  56. return ""
  57. sub(".* " name "\\(", "", flags)
  58. if (flags ~ "^{")
  59. {
  60. sub ("^{", "", flags)
  61. sub("}\\).*", "", flags)
  62. }
  63. else
  64. sub("\\).*", "", flags)
  65. return flags
  66. }
  67. # Return the Nth comma-separated element of S. Return the empty string
  68. # if S does not contain N elements.
  69. function nth_arg(n, s)
  70. {
  71. while (n-- > 0) {
  72. if (s !~ ",")
  73. return ""
  74. sub("[^,]*, *", "", s)
  75. }
  76. sub(",.*", "", s)
  77. return s
  78. }
  79. # Return a bitmask of CL_* values for option flags FLAGS.
  80. function switch_flags (flags)
  81. {
  82. result = "0"
  83. for (j = 0; j < n_langs; j++) {
  84. regex = langs[j]
  85. gsub ( "\\+", "\\+", regex )
  86. result = result test_flag(regex, flags, " | " macros[j])
  87. }
  88. result = result \
  89. test_flag("Common", flags, " | CL_COMMON") \
  90. test_flag("Target", flags, " | CL_TARGET") \
  91. test_flag("PchIgnore", flags, " | CL_PCH_IGNORE") \
  92. test_flag("Driver", flags, " | CL_DRIVER") \
  93. test_flag("Joined", flags, " | CL_JOINED") \
  94. test_flag("JoinedOrMissing", flags, " | CL_JOINED") \
  95. test_flag("Separate", flags, " | CL_SEPARATE") \
  96. test_flag("Undocumented", flags, " | CL_UNDOCUMENTED") \
  97. test_flag("NoDWARFRecord", flags, " | CL_NO_DWARF_RECORD") \
  98. test_flag("Warning", flags, " | CL_WARNING") \
  99. test_flag("Optimization", flags, " | CL_OPTIMIZATION")
  100. sub( "^0 \\| ", "", result )
  101. return result
  102. }
  103. # Return bit-field initializers for option flags FLAGS.
  104. function switch_bit_fields (flags)
  105. {
  106. vn = var_name(flags);
  107. if (host_wide_int[vn] == "yes")
  108. hwi = "Host_Wide_Int"
  109. else
  110. hwi = ""
  111. result = ""
  112. sep_args = opt_args("Args", flags)
  113. if (sep_args == "")
  114. sep_args = 0
  115. else
  116. sep_args--
  117. result = result sep_args ", "
  118. result = result \
  119. flag_init("SeparateAlias", flags) \
  120. flag_init("NegativeAlias", flags) \
  121. flag_init("NoDriverArg", flags) \
  122. flag_init("RejectDriver", flags) \
  123. flag_init("RejectNegative", flags) \
  124. flag_init("JoinedOrMissing", flags) \
  125. flag_init("UInteger", flags) \
  126. flag_init("Host_Wide_Int", hwi) \
  127. flag_init("ToLower", flags) \
  128. flag_init("Report", flags)
  129. sub(", $", "", result)
  130. return result
  131. }
  132. # If FLAGS includes a Var flag, return the name of the variable it specifies.
  133. # Return the empty string otherwise.
  134. function var_name(flags)
  135. {
  136. return nth_arg(0, opt_args("Var", flags))
  137. }
  138. # Return the name of the variable if FLAGS has a HOST_WIDE_INT variable.
  139. # Return the empty string otherwise.
  140. function host_wide_int_var_name(flags)
  141. {
  142. split (flags, array, "[ \t]+")
  143. if (array[1] == "HOST_WIDE_INT")
  144. return array[2]
  145. else
  146. return ""
  147. }
  148. # Return true if the option described by FLAGS has a globally-visible state.
  149. function global_state_p(flags)
  150. {
  151. return (var_name(flags) != "" \
  152. || opt_args("Mask", flags) != "" \
  153. || opt_args("InverseMask", flags) != "")
  154. }
  155. # Return true if the option described by FLAGS must have some state
  156. # associated with it.
  157. function needs_state_p(flags)
  158. {
  159. return (flag_set_p("Target", flags) \
  160. && !flag_set_p("Alias.*", flags) \
  161. && !flag_set_p("Ignore", flags))
  162. }
  163. # If FLAGS describes an option that needs state without a public
  164. # variable name, return the name of that field, minus the initial
  165. # "x_", otherwise return "". NAME is the name of the option.
  166. function static_var(name, flags)
  167. {
  168. if (global_state_p(flags) || !needs_state_p(flags))
  169. return ""
  170. gsub ("[^" alnum "]", "_", name)
  171. return "VAR_" name
  172. }
  173. # Return the type of variable that should be associated with the given flags.
  174. function var_type(flags)
  175. {
  176. if (flag_set_p("Defer", flags))
  177. return "void *"
  178. else if (flag_set_p("Enum.*", flags)) {
  179. en = opt_args("Enum", flags);
  180. return enum_type[en] " "
  181. }
  182. else if (!flag_set_p("Joined.*", flags) && !flag_set_p("Separate", flags))
  183. return "int "
  184. else if (flag_set_p("UInteger", flags))
  185. return "int "
  186. else
  187. return "const char *"
  188. }
  189. # Return the type of variable that should be associated with the given flags
  190. # for use within a structure. Simple variables are changed to signed char
  191. # type instead of int to save space.
  192. function var_type_struct(flags)
  193. {
  194. if (flag_set_p("UInteger", flags))
  195. return "int "
  196. else if (flag_set_p("Enum.*", flags)) {
  197. en = opt_args("Enum", flags);
  198. return enum_type[en] " "
  199. }
  200. else if (!flag_set_p("Joined.*", flags) && !flag_set_p("Separate", flags)) {
  201. if (flag_set_p(".*Mask.*", flags)) {
  202. if (host_wide_int[var_name(flags)] == "yes")
  203. return "HOST_WIDE_INT "
  204. else
  205. return "int "
  206. }
  207. else
  208. return "signed char "
  209. }
  210. else
  211. return "const char *"
  212. }
  213. # Given that an option has flags FLAGS, return an initializer for the
  214. # "var_enum", "var_type" and "var_value" fields of its cl_options[] entry.
  215. function var_set(flags)
  216. {
  217. if (flag_set_p("Defer", flags))
  218. return "0, CLVC_DEFER, 0"
  219. s = nth_arg(1, opt_args("Var", flags))
  220. if (s != "")
  221. return "0, CLVC_EQUAL, " s
  222. s = opt_args("Mask", flags);
  223. if (s != "") {
  224. vn = var_name(flags);
  225. if (vn)
  226. return "0, CLVC_BIT_SET, OPTION_MASK_" s
  227. else
  228. return "0, CLVC_BIT_SET, MASK_" s
  229. }
  230. s = nth_arg(0, opt_args("InverseMask", flags));
  231. if (s != "") {
  232. vn = var_name(flags);
  233. if (vn)
  234. return "0, CLVC_BIT_CLEAR, OPTION_MASK_" s
  235. else
  236. return "0, CLVC_BIT_CLEAR, MASK_" s
  237. }
  238. if (flag_set_p("Enum.*", flags)) {
  239. en = opt_args("Enum", flags);
  240. return enum_index[en] ", CLVC_ENUM, 0"
  241. }
  242. if (var_type(flags) == "const char *")
  243. return "0, CLVC_STRING, 0"
  244. return "0, CLVC_BOOLEAN, 0"
  245. }
  246. # Given that an option called NAME has flags FLAGS, return an initializer
  247. # for the "flag_var" field of its cl_options[] entry.
  248. function var_ref(name, flags)
  249. {
  250. name = var_name(flags) static_var(name, flags)
  251. if (name != "")
  252. return "offsetof (struct gcc_options, x_" name ")"
  253. if (opt_args("Mask", flags) != "")
  254. return "offsetof (struct gcc_options, x_target_flags)"
  255. if (opt_args("InverseMask", flags) != "")
  256. return "offsetof (struct gcc_options, x_target_flags)"
  257. return "-1"
  258. }
  259. # Given the option called NAME return a sanitized version of its name.
  260. function opt_sanitized_name(name)
  261. {
  262. gsub ("[^" alnum "]", "_", name)
  263. return name
  264. }
  265. # Given the option called NAME return the appropriate enum for it.
  266. function opt_enum(name)
  267. {
  268. return "OPT_" opt_sanitized_name(name)
  269. }
  270. # Given the language called NAME return a sanitized version of its name.
  271. function lang_sanitized_name(name)
  272. {
  273. gsub( "[^" alnum "_]", "X", name )
  274. return name
  275. }
  276. # Search for a valid var_name among all OPTS equal to option NAME.
  277. # If not found, return "".
  278. function search_var_name(name, opt_numbers, opts, flags, n_opts)
  279. {
  280. opt_var_name = var_name(flags[opt_numbers[name]]);
  281. if (opt_var_name != "") {
  282. return opt_var_name;
  283. }
  284. for (k = 0; k < n_opts; k++) {
  285. if (opts[k] == name && var_name(flags[k]) != "") {
  286. return var_name(flags[k]);
  287. }
  288. }
  289. return ""
  290. }
  291. # Handle LangEnabledBy(ENABLED_BY_LANGS, ENABLEDBY_NAME, ENABLEDBY_POSARG,
  292. # ENABLEDBY_NEGARG). This function does not return anything.
  293. function lang_enabled_by(enabledby_langs, enabledby_name, enabledby_posarg, enabledby_negarg)
  294. {
  295. n_enabledby_arg_langs = split(enabledby_langs, enabledby_arg_langs, " ");
  296. if (enabledby_posarg != "" && enabledby_negarg != "") {
  297. with_args = "," enabledby_posarg "," enabledby_negarg
  298. } else if (enabledby_posarg == "" && enabledby_negarg == "") {
  299. with_args = ""
  300. } else {
  301. print "#error LangEnabledBy("enabledby_langs","enabledby_name", " \
  302. enabledby_posarg", " enabledby_negargs \
  303. ") with three arguments, it should have either 2 or 4"
  304. }
  305. n_enabledby_array = split(enabledby_name, enabledby_array, " \\|\\| ");
  306. for (k = 1; k <= n_enabledby_array; k++) {
  307. enabledby_index = opt_numbers[enabledby_array[k]];
  308. if (enabledby_index == "") {
  309. print "#error LangEnabledBy("enabledby_langs","enabledby_name", " \
  310. enabledby_posarg", " enabledby_negargs") has invalid ENABLEDBY_NAME"
  311. } else {
  312. for (j = 1; j <= n_enabledby_arg_langs; j++) {
  313. lang_name = lang_sanitized_name(enabledby_arg_langs[j]);
  314. lang_index = lang_numbers[enabledby_arg_langs[j]];
  315. if (enables[lang_name,enabledby_array[k]] == "") {
  316. enabledby[lang_name,n_enabledby_lang[lang_index]] = enabledby_array[k];
  317. n_enabledby_lang[lang_index]++;
  318. }
  319. enables[lang_name,enabledby_array[k]] \
  320. = enables[lang_name,enabledby_array[k]] opts[i] with_args ";";
  321. }
  322. }
  323. }
  324. }