optc-gen.awk 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
  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. # This Awk script reads in the option records generated from
  19. # opt-gather.awk, combines the flags of duplicate options and generates a
  20. # C file.
  21. #
  22. # This program uses functions from opt-functions.awk and code from
  23. # opt-read.awk.
  24. #
  25. # Usage: awk -f opt-functions.awk -f opt-read.awk -f optc-gen.awk \
  26. # [-v header_name=header.h] < inputfile > options.c
  27. # Dump that array of options into a C file.
  28. END {
  29. # Record first EnabledBy and LangEnabledBy uses.
  30. n_enabledby = 0;
  31. for (i = 0; i < n_langs; i++) {
  32. n_enabledby_lang[i] = 0;
  33. }
  34. for (i = 0; i < n_opts; i++) {
  35. enabledby_arg = opt_args("EnabledBy", flags[i]);
  36. if (enabledby_arg != "") {
  37. logical_and = index(enabledby_arg, " && ");
  38. if (logical_and != 0) {
  39. # EnabledBy(arg1 && arg2)
  40. split_sep = " && ";
  41. } else {
  42. # EnabledBy(arg) or EnabledBy(arg1 || arg2 || arg3)
  43. split_sep = " \\|\\| ";
  44. }
  45. n_enabledby_names = split(enabledby_arg, enabledby_names, split_sep);
  46. if (logical_and != 0 && n_enabledby_names > 2) {
  47. print "#error EnabledBy (Wfoo && Wbar && Wbaz) not currently supported"
  48. }
  49. for (j = 1; j <= n_enabledby_names; j++) {
  50. enabledby_name = enabledby_names[j];
  51. enabledby_index = opt_numbers[enabledby_name];
  52. if (enabledby_index == "") {
  53. print "#error Enabledby: " enabledby_name
  54. } else {
  55. condition = "";
  56. if (logical_and != 0) {
  57. opt_var_name_1 = search_var_name(enabledby_names[1], opt_numbers, opts, flags, n_opts);
  58. opt_var_name_2 = search_var_name(enabledby_names[2], opt_numbers, opts, flags, n_opts);
  59. if (opt_var_name_1 == "") {
  60. print "#error " enabledby_names[1] " does not have a Var() flag"
  61. }
  62. if (opt_var_name_2 == "") {
  63. print "#error " enabledby_names[2] " does not have a Var() flag"
  64. }
  65. condition = "opts->x_" opt_var_name_1 " && opts->x_" opt_var_name_2;
  66. }
  67. if (enables[enabledby_name] == "") {
  68. enabledby[n_enabledby] = enabledby_name;
  69. n_enabledby++;
  70. }
  71. enables[enabledby_name] = enables[enabledby_name] opts[i] ";";
  72. enablesif[enabledby_name] = enablesif[enabledby_name] condition ";";
  73. }
  74. }
  75. }
  76. enabledby_arg = opt_args("LangEnabledBy", flags[i]);
  77. if (enabledby_arg != "") {
  78. enabledby_langs = nth_arg(0, enabledby_arg);
  79. enabledby_name = nth_arg(1, enabledby_arg);
  80. enabledby_posarg = nth_arg(2, enabledby_arg);
  81. enabledby_negarg = nth_arg(3, enabledby_arg);
  82. lang_enabled_by(enabledby_langs, enabledby_name, enabledby_posarg, enabledby_negarg);
  83. }
  84. }
  85. print "/* This file is auto-generated by optc-gen.awk. */"
  86. print ""
  87. n_headers = split(header_name, headers, " ")
  88. for (i = 1; i <= n_headers; i++)
  89. print "#include " quote headers[i] quote
  90. print "#include " quote "opts.h" quote
  91. print "#include " quote "intl.h" quote
  92. print "#include " quote "insn-attr-common.h" quote
  93. print ""
  94. if (n_extra_c_includes > 0) {
  95. for (i = 0; i < n_extra_c_includes; i++) {
  96. print "#include " quote extra_c_includes[i] quote
  97. }
  98. print ""
  99. }
  100. for (i = 0; i < n_enums; i++) {
  101. name = enum_names[i]
  102. type = enum_type[name]
  103. print "static const struct cl_enum_arg cl_enum_" name \
  104. "_data[] = "
  105. print "{"
  106. print enum_data[name] " { NULL, 0, 0 }"
  107. print "};"
  108. print ""
  109. print "static void"
  110. print "cl_enum_" name "_set (void *var, int value)"
  111. print "{"
  112. print " *((" type " *) var) = (" type ") value;"
  113. print "}"
  114. print ""
  115. print "static int"
  116. print "cl_enum_" name "_get (const void *var)"
  117. print "{"
  118. print " return (int) *((const " type " *) var);"
  119. print "}"
  120. print ""
  121. }
  122. print "const struct cl_enum cl_enums[] ="
  123. print "{"
  124. for (i = 0; i < n_enums; i++) {
  125. name = enum_names[i]
  126. ehelp = enum_help[name]
  127. if (ehelp == "")
  128. ehelp = "NULL"
  129. else
  130. ehelp = quote ehelp quote
  131. unknown_error = enum_unknown_error[name]
  132. if (unknown_error == "")
  133. unknown_error = "NULL"
  134. else
  135. unknown_error = quote unknown_error quote
  136. print " {"
  137. print " " ehelp ","
  138. print " " unknown_error ","
  139. print " cl_enum_" name "_data,"
  140. print " sizeof (" enum_type[name] "),"
  141. print " cl_enum_" name "_set,"
  142. print " cl_enum_" name "_get"
  143. print " },"
  144. }
  145. print "};"
  146. print "const unsigned int cl_enums_count = " n_enums ";"
  147. print ""
  148. print "const struct gcc_options global_options_init =\n{"
  149. for (i = 0; i < n_extra_vars; i++) {
  150. var = extra_vars[i]
  151. init = extra_vars[i]
  152. if (var ~ "=" ) {
  153. sub(".*= *", "", init)
  154. } else {
  155. init = "0"
  156. }
  157. sub(" *=.*", "", var)
  158. name = var
  159. sub("^.*[ *]", "", name)
  160. sub("\\[.*\\]$", "", name)
  161. var_seen[name] = 1
  162. print " " init ", /* " name " */"
  163. }
  164. for (i = 0; i < n_opts; i++) {
  165. name = var_name(flags[i]);
  166. if (name == "")
  167. continue;
  168. init = opt_args("Init", flags[i])
  169. if (init != "") {
  170. if (name in var_init && var_init[name] != init)
  171. print "#error multiple initializers for " name
  172. var_init[name] = init
  173. }
  174. }
  175. for (i = 0; i < n_opts; i++) {
  176. name = var_name(flags[i]);
  177. if (name == "")
  178. continue;
  179. if (name in var_seen)
  180. continue;
  181. if (name in var_init)
  182. init = var_init[name]
  183. else
  184. init = "0"
  185. print " " init ", /* " name " */"
  186. var_seen[name] = 1;
  187. }
  188. for (i = 0; i < n_opts; i++) {
  189. name = static_var(opts[i], flags[i]);
  190. if (name != "") {
  191. print " 0, /* " name " (private state) */"
  192. print "#undef x_" name
  193. }
  194. }
  195. for (i = 0; i < n_opts; i++) {
  196. if (flag_set_p("SetByCombined", flags[i]))
  197. print " false, /* frontend_set_" var_name(flags[i]) " */"
  198. }
  199. print "};"
  200. print ""
  201. print "struct gcc_options global_options;"
  202. print "struct gcc_options global_options_set;"
  203. print ""
  204. print "const char * const lang_names[] =\n{"
  205. for (i = 0; i < n_langs; i++) {
  206. macros[i] = "CL_" lang_sanitized_name(langs[i])
  207. s = substr(" ", length (macros[i]))
  208. print " " quote langs[i] quote ","
  209. }
  210. print " 0\n};\n"
  211. print "const unsigned int cl_options_count = N_OPTS;\n"
  212. print "#if (1U << " n_langs ") > CL_MIN_OPTION_CLASS"
  213. print " #error the number of languages exceeds the implementation limit"
  214. print "#endif"
  215. print "const unsigned int cl_lang_count = " n_langs ";\n"
  216. print "const struct cl_option cl_options[] =\n{"
  217. j = 0
  218. for (i = 0; i < n_opts; i++) {
  219. back_chain[i] = "N_OPTS";
  220. indices[opts[i]] = j;
  221. # Combine the flags of identical switches. Switches
  222. # appear many times if they are handled by many front
  223. # ends, for example.
  224. while( i + 1 != n_opts && opts[i] == opts[i + 1] ) {
  225. flags[i + 1] = flags[i] " " flags[i + 1];
  226. if (help[i + 1] == "")
  227. help[i + 1] = help[i]
  228. else if (help[i] != "" && help[i + 1] != help[i])
  229. print "#error Multiple different help strings for " \
  230. opts[i] ":\n\t" help[i] "\n\t" help[i + 1]
  231. i++;
  232. back_chain[i] = "N_OPTS";
  233. indices[opts[i]] = j;
  234. }
  235. j++;
  236. }
  237. for (i = 0; i < n_opts; i++) {
  238. # With identical flags, pick only the last one. The
  239. # earlier loop ensured that it has all flags merged,
  240. # and a nonempty help text if one of the texts was nonempty.
  241. while( i + 1 != n_opts && opts[i] == opts[i + 1] ) {
  242. i++;
  243. }
  244. len = length (opts[i]);
  245. enum = opt_enum(opts[i])
  246. # If this switch takes joined arguments, back-chain all
  247. # subsequent switches to it for which it is a prefix. If
  248. # a later switch S is a longer prefix of a switch T, T
  249. # will be back-chained to S in a later iteration of this
  250. # for() loop, which is what we want.
  251. if (flag_set_p("Joined.*", flags[i])) {
  252. for (j = i + 1; j < n_opts; j++) {
  253. if (substr (opts[j], 1, len) != opts[i])
  254. break;
  255. back_chain[j] = enum;
  256. }
  257. }
  258. s = substr(" ", length (opts[i]))
  259. if (i + 1 == n_opts)
  260. comma = ""
  261. if (help[i] == "")
  262. hlp = "0"
  263. else
  264. hlp = quote help[i] quote;
  265. missing_arg_error = opt_args("MissingArgError", flags[i])
  266. if (missing_arg_error == "")
  267. missing_arg_error = "0"
  268. else
  269. missing_arg_error = quote missing_arg_error quote
  270. warn_message = opt_args("Warn", flags[i])
  271. if (warn_message == "")
  272. warn_message = "0"
  273. else
  274. warn_message = quote warn_message quote
  275. alias_arg = opt_args("Alias", flags[i])
  276. if (alias_arg == "") {
  277. if (flag_set_p("Ignore", flags[i]))
  278. alias_data = "NULL, NULL, OPT_SPECIAL_ignore"
  279. else
  280. alias_data = "NULL, NULL, N_OPTS"
  281. } else {
  282. alias_opt = nth_arg(0, alias_arg)
  283. alias_posarg = nth_arg(1, alias_arg)
  284. alias_negarg = nth_arg(2, alias_arg)
  285. if (var_ref(opts[i], flags[i]) != "-1")
  286. print "#error Alias setting variable"
  287. if (alias_posarg != "" && alias_negarg == "") {
  288. if (!flag_set_p("RejectNegative", flags[i]) \
  289. && opts[i] ~ "^[Wfm]")
  290. print "#error Alias with single argument " \
  291. "allowing negative form"
  292. }
  293. if (alias_posarg != "" \
  294. && flag_set_p("NegativeAlias", flags[i])) {
  295. print "#error Alias with multiple arguments " \
  296. "used with NegativeAlias"
  297. }
  298. alias_opt = opt_enum(alias_opt)
  299. if (alias_posarg == "")
  300. alias_posarg = "NULL"
  301. else
  302. alias_posarg = quote alias_posarg quote
  303. if (alias_negarg == "")
  304. alias_negarg = "NULL"
  305. else
  306. alias_negarg = quote alias_negarg quote
  307. alias_data = alias_posarg ", " alias_negarg ", " alias_opt
  308. }
  309. neg = opt_args("Negative", flags[i]);
  310. if (neg != "")
  311. idx = indices[neg]
  312. else {
  313. if (flag_set_p("RejectNegative", flags[i]))
  314. idx = -1;
  315. else {
  316. if (opts[i] ~ "^[Wfm]")
  317. idx = indices[opts[i]];
  318. else
  319. idx = -1;
  320. }
  321. }
  322. # Split the printf after %u to work around an ia64-hp-hpux11.23
  323. # awk bug.
  324. printf(" { %c-%s%c,\n %s,\n %s,\n %s,\n %s, %s, %u,",
  325. quote, opts[i], quote, hlp, missing_arg_error, warn_message,
  326. alias_data, back_chain[i], len)
  327. printf(" %d,\n", idx)
  328. condition = opt_args("Condition", flags[i])
  329. cl_flags = switch_flags(flags[i])
  330. cl_bit_fields = switch_bit_fields(flags[i])
  331. cl_zero_bit_fields = switch_bit_fields("")
  332. if (condition != "")
  333. printf("#if %s\n" \
  334. " %s,\n" \
  335. " 0, %s,\n" \
  336. "#else\n" \
  337. " 0,\n" \
  338. " 1 /* Disabled. */, %s,\n" \
  339. "#endif\n",
  340. condition, cl_flags, cl_bit_fields, cl_zero_bit_fields)
  341. else
  342. printf(" %s,\n" \
  343. " 0, %s,\n",
  344. cl_flags, cl_bit_fields)
  345. printf(" %s, %s }%s\n", var_ref(opts[i], flags[i]),
  346. var_set(flags[i]), comma)
  347. }
  348. print "};"
  349. print "\n\n"
  350. print "bool "
  351. print "common_handle_option_auto (struct gcc_options *opts, "
  352. print " struct gcc_options *opts_set, "
  353. print " const struct cl_decoded_option *decoded, "
  354. print " unsigned int lang_mask, int kind, "
  355. print " location_t loc, "
  356. print " const struct cl_option_handlers *handlers, "
  357. print " diagnostic_context *dc) "
  358. print "{ "
  359. print " size_t scode = decoded->opt_index; "
  360. print " int value = decoded->value; "
  361. print " enum opt_code code = (enum opt_code) scode; "
  362. print " "
  363. print " gcc_assert (decoded->canonical_option_num_elements <= 2); "
  364. print " "
  365. print " switch (code) "
  366. print " { "
  367. # Handle EnabledBy
  368. for (i = 0; i < n_enabledby; i++) {
  369. enabledby_name = enabledby[i];
  370. print " case " opt_enum(enabledby_name) ":"
  371. n_enables = split(enables[enabledby_name], thisenable, ";");
  372. n_enablesif = split(enablesif[enabledby_name], thisenableif, ";");
  373. if (n_enables != n_enablesif) {
  374. print "#error n_enables != n_enablesif: Something went wrong!"
  375. }
  376. for (j = 1; j < n_enables; j++) {
  377. opt_var_name = var_name(flags[opt_numbers[thisenable[j]]]);
  378. if (opt_var_name != "") {
  379. condition = "!opts_set->x_" opt_var_name
  380. if (thisenableif[j] != "") {
  381. value = "(" thisenableif[j] ")"
  382. } else {
  383. value = "value"
  384. }
  385. print " if (" condition ")"
  386. print " handle_generated_option (opts, opts_set,"
  387. print " " opt_enum(thisenable[j]) ", NULL, " value ","
  388. print " lang_mask, kind, loc, handlers, dc);"
  389. } else {
  390. print "#error " thisenable[j] " does not have a Var() flag"
  391. }
  392. }
  393. print " break;\n"
  394. }
  395. print " default: "
  396. print " break; "
  397. print " } "
  398. print " return true; "
  399. print "} "
  400. # Handle LangEnabledBy
  401. for (i = 0; i < n_langs; i++) {
  402. lang_name = lang_sanitized_name(langs[i]);
  403. mark_unused = " ATTRIBUTE_UNUSED";
  404. print "\n\n"
  405. print "bool "
  406. print lang_name "_handle_option_auto (struct gcc_options *opts" mark_unused ", "
  407. print " struct gcc_options *opts_set" mark_unused ", "
  408. print " size_t scode" mark_unused ", const char *arg" mark_unused ", int value" mark_unused ", "
  409. print " unsigned int lang_mask" mark_unused ", int kind" mark_unused ", "
  410. print " location_t loc" mark_unused ", "
  411. print " const struct cl_option_handlers *handlers" mark_unused ", "
  412. print " diagnostic_context *dc" mark_unused ") "
  413. print "{ "
  414. print " enum opt_code code = (enum opt_code) scode; "
  415. print " "
  416. print " switch (code) "
  417. print " { "
  418. for (k = 0; k < n_enabledby_lang[i]; k++) {
  419. enabledby_name = enabledby[lang_name,k];
  420. print " case " opt_enum(enabledby_name) ":"
  421. n_thisenable = split(enables[lang_name,enabledby_name], thisenable, ";");
  422. for (j = 1; j < n_thisenable; j++) {
  423. n_thisenable_args = split(thisenable[j], thisenable_args, ",");
  424. if (n_thisenable_args == 1) {
  425. thisenable_opt = thisenable[j];
  426. value = "value";
  427. } else {
  428. thisenable_opt = thisenable_args[1];
  429. with_posarg = thisenable_args[2];
  430. with_negarg = thisenable_args[3];
  431. value = "value ? " with_posarg " : " with_negarg;
  432. }
  433. opt_var_name = var_name(flags[opt_numbers[thisenable_opt]]);
  434. if (opt_var_name != "") {
  435. print " if (!opts_set->x_" opt_var_name ")"
  436. print " handle_generated_option (opts, opts_set,"
  437. print " " opt_enum(thisenable_opt) ", NULL, " value ","
  438. print " lang_mask, kind, loc, handlers, dc);"
  439. } else {
  440. print "#error " thisenable_opt " does not have a Var() flag"
  441. }
  442. }
  443. print " break;\n"
  444. }
  445. print " default: "
  446. print " break; "
  447. print " } "
  448. print " return true; "
  449. print "} "
  450. }
  451. #Handle CPP()
  452. print "\n"
  453. print "#include " quote "cpplib.h" quote;
  454. print "void"
  455. print "cpp_handle_option_auto (const struct gcc_options * opts, "
  456. print " size_t scode, struct cpp_options * cpp_opts)"
  457. print "{ "
  458. print " enum opt_code code = (enum opt_code) scode; "
  459. print " "
  460. print " switch (code) "
  461. print " { "
  462. for (i = 0; i < n_opts; i++) {
  463. # With identical flags, pick only the last one. The
  464. # earlier loop ensured that it has all flags merged,
  465. # and a nonempty help text if one of the texts was nonempty.
  466. while( i + 1 != n_opts && opts[i] == opts[i + 1] ) {
  467. i++;
  468. }
  469. cpp_option = nth_arg(0, opt_args("CPP", flags[i]));
  470. if (cpp_option != "") {
  471. opt_var_name = var_name(flags[i]);
  472. init = opt_args("Init", flags[i])
  473. if (opt_var_name != "" && init != "") {
  474. print " case " opt_enum(opts[i]) ":"
  475. print " cpp_opts->" cpp_option " = opts->x_" opt_var_name ";"
  476. print " break;"
  477. } else if (opt_var_name == "" && init == "") {
  478. print "#error CPP() requires setting Init() and Var() for " opts[i]
  479. } else if (opt_var_name != "") {
  480. print "#error CPP() requires setting Init() for " opts[i]
  481. } else {
  482. print "#error CPP() requires setting Var() for " opts[i]
  483. }
  484. }
  485. }
  486. print " default: "
  487. print " break; "
  488. print " } "
  489. print "}\n"
  490. print "void"
  491. print "init_global_opts_from_cpp(struct gcc_options * opts, "
  492. print " const struct cpp_options * cpp_opts)"
  493. print "{ "
  494. for (i = 0; i < n_opts; i++) {
  495. # With identical flags, pick only the last one. The
  496. # earlier loop ensured that it has all flags merged,
  497. # and a nonempty help text if one of the texts was nonempty.
  498. while( i + 1 != n_opts && opts[i] == opts[i + 1] ) {
  499. i++;
  500. }
  501. cpp_option = nth_arg(0, opt_args("CPP", flags[i]));
  502. opt_var_name = var_name(flags[i]);
  503. if (cpp_option != "" && opt_var_name != "") {
  504. print " opts->x_" opt_var_name " = cpp_opts->" cpp_option ";"
  505. }
  506. }
  507. print "} "
  508. }