Import pre-release gcc-5.0 to new vendor branch
[dragonfly.git] / contrib / gcc-5.0 / gcc / opth-gen.awk
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
19 # This Awk script reads in the option records generated from 
20 # opt-gather.awk, combines the flags of duplicate options and generates a
21 # C header file.
22 #
23 # This program uses functions from opt-functions.awk and code from
24 # opt-read.awk.
25 # Usage: awk -f opt-functions.awk -f opt-read.awk -f opth-gen.awk \
26 #            < inputfile > options.h
27
28 # Dump out an enumeration into a .h file.
29 # Combine the flags of duplicate options.
30 END {
31 print "/* This file is auto-generated by opth-gen.awk.  */"
32 print ""
33 print "#ifndef OPTIONS_H"
34 print "#define OPTIONS_H"
35 print ""
36 print "#include \"flag-types.h\""
37 print ""
38
39 if (n_extra_h_includes > 0) {
40         for (i = 0; i < n_extra_h_includes; i++) {
41                 print "#include " quote extra_h_includes[i] quote
42         }
43         print ""
44 }
45
46 print "#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS) && !defined(IN_RTS)"
47 print "#ifndef GENERATOR_FILE"
48 print "#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS)"
49 print "struct GTY(()) gcc_options"
50 print "#else"
51 print "struct gcc_options"
52 print "#endif"
53 print "{"
54 print "#endif"
55
56 for (i = 0; i < n_extra_vars; i++) {
57         var = extra_vars[i]
58         sub(" *=.*", "", var)
59         orig_var = var
60         name = var
61         type = var
62         type_after = var
63         sub("^.*[ *]", "", name)
64         sub("\\[.*\\]$", "", name)
65         sub("\\[.*\\]$", "", type)
66         sub(" *" name "$", "", type)
67         sub("^.*" name, "", type_after)
68         var_seen[name] = 1
69         print "#ifdef GENERATOR_FILE"
70         print "extern " orig_var ";"
71         print "#else"
72         print "  " type " x_" name type_after ";"
73         print "#define " name " global_options.x_" name
74         print "#endif"
75 }
76
77 for (i = 0; i < n_opts; i++) {
78         if (flag_set_p("Save", flags[i]))
79                 have_save = 1;
80
81         name = var_name(flags[i]);
82         if (name == "")
83                 continue;
84
85         if (name in var_seen)
86                 continue;
87
88         var_seen[name] = 1;
89         print "#ifdef GENERATOR_FILE"
90         print "extern " var_type(flags[i]) name ";"
91         print "#else"
92         print "  " var_type(flags[i]) "x_" name ";"
93         print "#define " name " global_options.x_" name
94         print "#endif"
95 }
96 for (i = 0; i < n_opts; i++) {
97         name = static_var(opts[i], flags[i]);
98         if (name != "") {
99                 print "#ifndef GENERATOR_FILE"
100                 print "  " var_type(flags[i]) "x_" name ";"
101                 print "#define x_" name " do_not_use"
102                 print "#endif"
103         }
104 }
105 for (i = 0; i < n_opts; i++) {
106         if (flag_set_p("SetByCombined", flags[i])) {
107                 print "#ifndef GENERATOR_FILE"
108                 print "  bool frontend_set_" var_name(flags[i]) ";"
109                 print "#endif"
110         }
111 }
112 print "#ifndef GENERATOR_FILE"
113 print "};"
114 print "extern struct gcc_options global_options;"
115 print "extern const struct gcc_options global_options_init;"
116 print "extern struct gcc_options global_options_set;"
117 print "#define target_flags_explicit global_options_set.x_target_flags"
118 print "#endif"
119 print "#endif"
120 print ""
121
122 # All of the optimization switches gathered together so they can be saved and restored.
123 # This will allow attribute((cold)) to turn on space optimization.
124
125 # Change the type of normal switches from int to unsigned char to save space.
126 # Also, order the structure so that pointer fields occur first, then int
127 # fields, and then char fields to provide the best packing.
128
129 print "#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS) && !defined(IN_RTS)"
130 print ""
131 print "/* Structure to save/restore optimization and target specific options.  */";
132 print "struct GTY(()) cl_optimization";
133 print "{";
134
135 n_opt_char = 3;
136 n_opt_short = 0;
137 n_opt_int = 0;
138 n_opt_enum = 0;
139 n_opt_other = 0;
140 var_opt_char[0] = "unsigned char x_optimize";
141 var_opt_char[1] = "unsigned char x_optimize_size";
142 var_opt_char[2] = "unsigned char x_optimize_debug";
143
144 for (i = 0; i < n_opts; i++) {
145         if (flag_set_p("Optimization", flags[i])) {
146                 name = var_name(flags[i])
147                 if(name == "")
148                         continue;
149
150                 if(name in var_opt_seen)
151                         continue;
152
153                 var_opt_seen[name]++;
154                 otype = var_type_struct(flags[i]);
155                 if (otype ~ "^((un)?signed +)?int *$")
156                         var_opt_int[n_opt_int++] = otype "x_" name;
157
158                 else if (otype ~ "^((un)?signed +)?short *$")
159                         var_opt_short[n_opt_short++] = otype "x_" name;
160
161                 else if (otype ~ "^((un)?signed +)?char *$")
162                         var_opt_char[n_opt_char++] = otype "x_" name;
163
164                 else if (otype ~ ("^enum +[_" alnum "]+ *$"))
165                         var_opt_enum[n_opt_enum++] = otype "x_" name;
166
167                 else
168                         var_opt_other[n_opt_other++] = otype "x_" name;
169         }
170 }
171
172 for (i = 0; i < n_opt_other; i++) {
173         print "  " var_opt_other[i] ";";
174 }
175
176 for (i = 0; i < n_opt_int; i++) {
177         print "  " var_opt_int[i] ";";
178 }
179
180 for (i = 0; i < n_opt_enum; i++) {
181         print "  " var_opt_enum[i] ";";
182 }
183
184 for (i = 0; i < n_opt_short; i++) {
185         print "  " var_opt_short[i] ";";
186 }
187
188 for (i = 0; i < n_opt_char; i++) {
189         print "  " var_opt_char[i] ";";
190 }
191
192 print "};";
193 print "";
194
195 # Target and optimization save/restore/print functions.
196 print "/* Structure to save/restore selected target specific options.  */";
197 print "struct GTY(()) cl_target_option";
198 print "{";
199
200 n_target_char = 0;
201 n_target_short = 0;
202 n_target_int = 0;
203 n_target_enum = 0;
204 n_target_other = 0;
205
206 for (i = 0; i < n_target_save; i++) {
207         if (target_save_decl[i] ~ "^((un)?signed +)?int +[_" alnum "]+$")
208                 var_target_int[n_target_int++] = target_save_decl[i];
209
210         else if (target_save_decl[i] ~ "^((un)?signed +)?short +[_" alnum "]+$")
211                 var_target_short[n_target_short++] = target_save_decl[i];
212
213         else if (target_save_decl[i] ~ "^((un)?signed +)?char +[_ " alnum "]+$")
214                 var_target_char[n_target_char++] = target_save_decl[i];
215
216         else if (target_save_decl[i] ~ ("^enum +[_" alnum "]+ +[_" alnum "]+$")) {
217                 var_target_enum[n_target_enum++] = target_save_decl[i];
218         }
219         else
220                 var_target_other[n_target_other++] = target_save_decl[i];
221 }
222
223 if (have_save) {
224         for (i = 0; i < n_opts; i++) {
225                 if (flag_set_p("Save", flags[i])) {
226                         name = var_name(flags[i])
227                         if(name == "")
228                                 name = "target_flags";
229
230                         if(name in var_save_seen)
231                                 continue;
232
233                         var_save_seen[name]++;
234                         otype = var_type_struct(flags[i])
235                         if (otype ~ "^((un)?signed +)?int *$")
236                                 var_target_int[n_target_int++] = otype "x_" name;
237
238                         else if (otype ~ "^((un)?signed +)?short *$")
239                                 var_target_short[n_target_short++] = otype "x_" name;
240
241                         else if (otype ~ "^((un)?signed +)?char *$")
242                                 var_target_char[n_target_char++] = otype "x_" name;
243
244                         else if (otype ~ ("^enum +[_" alnum "]+ +[_" alnum "]+"))
245                                 var_target_enum[n_target_enum++] = otype "x_" name;
246
247                         else
248                                 var_target_other[n_target_other++] = otype "x_" name;
249                 }
250         }
251 } else {
252         var_target_int[n_target_int++] = "int x_target_flags";
253 }
254
255 for (i = 0; i < n_target_other; i++) {
256         print "  " var_target_other[i] ";";
257 }
258
259 for (i = 0; i < n_target_enum; i++) {
260         print "  " var_target_enum[i] ";";
261 }
262
263 for (i = 0; i < n_target_int; i++) {
264         print "  " var_target_int[i] ";";
265 }
266
267 for (i = 0; i < n_target_short; i++) {
268         print "  " var_target_short[i] ";";
269 }
270
271 for (i = 0; i < n_target_char; i++) {
272         print "  " var_target_char[i] ";";
273 }
274
275 print "};";
276 print "";
277 print "";
278 print "/* Save optimization variables into a structure.  */"
279 print "extern void cl_optimization_save (struct cl_optimization *, struct gcc_options *);";
280 print "";
281 print "/* Restore optimization variables from a structure.  */";
282 print "extern void cl_optimization_restore (struct gcc_options *, struct cl_optimization *);";
283 print "";
284 print "/* Print optimization variables from a structure.  */";
285 print "extern void cl_optimization_print (FILE *, int, struct cl_optimization *);";
286 print "";
287 print "/* Print different optimization variables from structures provided as arguments.  */";
288 print "extern void cl_optimization_print_diff (FILE *, int, cl_optimization *ptr1, cl_optimization *ptr2);";
289 print "";
290 print "/* Save selected option variables into a structure.  */"
291 print "extern void cl_target_option_save (struct cl_target_option *, struct gcc_options *);";
292 print "";
293 print "/* Restore selected option variables from a structure.  */"
294 print "extern void cl_target_option_restore (struct gcc_options *, struct cl_target_option *);";
295 print "";
296 print "/* Print target option variables from a structure.  */";
297 print "extern void cl_target_option_print (FILE *, int, struct cl_target_option *);";
298 print "";
299 print "/* Print different target option variables from structures provided as arguments.  */";
300 print "extern void cl_target_option_print_diff (FILE *, int, cl_target_option *ptr1, cl_target_option *ptr2);";
301 print "";
302 print "/* Compare two target option variables from a structure.  */";
303 print "extern bool cl_target_option_eq (const struct cl_target_option *, const struct cl_target_option *);";
304 print "";
305 print "/* Hash option variables from a structure.  */";
306 print "extern hashval_t cl_target_option_hash (const struct cl_target_option *);";
307 print "";
308 print "/* Hash optimization from a structure.  */";
309 print "extern hashval_t cl_optimization_hash (const struct cl_optimization *);";
310 print "";
311 print "/* Anything that includes tm.h, does not necessarily need this.  */"
312 print "#if !defined(GCC_TM_H)"
313 print "#include \"input.h\" /* for location_t */"
314 print "bool                                                                  "
315 print "common_handle_option_auto (struct gcc_options *opts,                  "
316 print "                           struct gcc_options *opts_set,              "
317 print "                           const struct cl_decoded_option *decoded,   "
318 print "                           unsigned int lang_mask, int kind,          "
319 print "                           location_t loc,                            "
320 print "                           const struct cl_option_handlers *handlers, "
321 print "                           diagnostic_context *dc);                   "
322 for (i = 0; i < n_langs; i++) {
323     lang_name = lang_sanitized_name(langs[i]);
324     print "bool                                                                  "
325     print lang_name "_handle_option_auto (struct gcc_options *opts,              "
326     print "                           struct gcc_options *opts_set,              "
327     print "                           size_t scode, const char *arg, int value,  "
328     print "                           unsigned int lang_mask, int kind,          "
329     print "                           location_t loc,                            "
330     print "                           const struct cl_option_handlers *handlers, "
331     print "                           diagnostic_context *dc);                   "
332 }
333 print "void cpp_handle_option_auto (const struct gcc_options * opts, size_t scode,"
334 print "                             struct cpp_options * cpp_opts);"
335 print "void init_global_opts_from_cpp(struct gcc_options * opts,      "
336 print "                               const struct cpp_options * cpp_opts);"    
337 print "#endif";
338 print "#endif";
339 print "";
340
341 for (i = 0; i < n_opts; i++) {
342         name = opt_args("Mask", flags[i])
343         if (name == "") {
344                 opt = opt_args("InverseMask", flags[i])
345                 if (opt ~ ",")
346                         name = nth_arg(0, opt)
347                 else
348                         name = opt
349         }
350         if (name != "" && mask_bits[name] == 0) {
351                 mask_bits[name] = 1
352                 vname = var_name(flags[i])
353                 mask = "MASK_"
354                 mask_1 = "1"
355                 if (vname != "") {
356                         mask = "OPTION_MASK_"
357                         if (host_wide_int[vname] == "yes")
358                                 mask_1 = "HOST_WIDE_INT_1"
359                 } else
360                         extra_mask_bits[name] = 1
361                 print "#define " mask name " (" mask_1 " << " masknum[vname]++ ")"
362         }
363 }
364 for (i = 0; i < n_extra_masks; i++) {
365         if (extra_mask_bits[extra_masks[i]] == 0)
366                 print "#define MASK_" extra_masks[i] " (1 << " masknum[""]++ ")"
367 }
368
369 for (var in masknum) {
370         if (var != "" && host_wide_int[var] == "yes") {
371                 print" #if defined(HOST_BITS_PER_WIDE_INT) && " masknum[var] " >= HOST_BITS_PER_WIDE_INT"
372                 print "#error too many masks for " var
373                 print "#endif"
374         }
375         else if (masknum[var] > 31) {
376                 if (var == "")
377                         print "#error too many target masks"
378                 else
379                         print "#error too many masks for " var
380         }
381 }
382 print ""
383
384 for (i = 0; i < n_opts; i++) {
385         name = opt_args("Mask", flags[i])
386         if (name == "") {
387                 opt = opt_args("InverseMask", flags[i])
388                 if (opt ~ ",")
389                         name = nth_arg(0, opt)
390                 else
391                         name = opt
392         }
393         if (name != "" && mask_macros[name] == 0) {
394                 mask_macros[name] = 1
395                 vname = var_name(flags[i])
396                 mask = "OPTION_MASK_"
397                 if (vname == "") {
398                         vname = "target_flags"
399                         mask = "MASK_"
400                         extra_mask_macros[name] = 1
401                 }
402                 print "#define TARGET_" name \
403                       " ((" vname " & " mask name ") != 0)"
404                 print "#define TARGET_" name "_P(" vname ")" \
405                       " ((" vname " & " mask name ") != 0)"
406         }
407 }
408 for (i = 0; i < n_extra_masks; i++) {
409         if (extra_mask_macros[extra_masks[i]] == 0)
410                 print "#define TARGET_" extra_masks[i] \
411                       " ((target_flags & MASK_" extra_masks[i] ") != 0)"
412 }
413 print ""
414
415 for (i = 0; i < n_opts; i++) {
416         opt = opt_args("InverseMask", flags[i])
417         if (opt ~ ",") {
418                 vname = var_name(flags[i])
419                 mask = "OPTION_MASK_"
420                 if (vname == "") {
421                         vname = "target_flags"
422                         mask = "MASK_"
423                 }
424                 print "#define TARGET_" nth_arg(1, opt) \
425                       " ((" vname " & " mask nth_arg(0, opt) ") == 0)"
426         }
427 }
428 print ""
429
430 for (i = 0; i < n_langs; i++) {
431         macros[i] = "CL_" lang_sanitized_name(langs[i])
432         s = substr("            ", length (macros[i]))
433         print "#define " macros[i] s " (1U << " i ")"
434     }
435 print "#define CL_LANG_ALL   ((1U << " n_langs ") - 1)"
436
437 print ""
438 print "enum opt_code"
439 print "{"
440         
441 for (i = 0; i < n_opts; i++)
442         back_chain[i] = "N_OPTS";
443
444 enum_value = 0
445 for (i = 0; i < n_opts; i++) {
446         # Combine the flags of identical switches.  Switches
447         # appear many times if they are handled by many front
448         # ends, for example.
449         while( i + 1 != n_opts && opts[i] == opts[i + 1] ) {
450                 flags[i + 1] = flags[i] " " flags[i + 1];
451                 i++;
452         }
453
454         len = length (opts[i]);
455         enum = opt_enum(opts[i])
456         enum_string = enum " = " enum_value ","
457
458         # Aliases do not get enumeration names.
459         if ((flag_set_p("Alias.*", flags[i]) \
460              && !flag_set_p("SeparateAlias", flags[i])) \
461             || flag_set_p("Ignore", flags[i])) {
462                 enum_string = "/* " enum_string " */"
463         }
464
465         # If this switch takes joined arguments, back-chain all
466         # subsequent switches to it for which it is a prefix.  If
467         # a later switch S is a longer prefix of a switch T, T
468         # will be back-chained to S in a later iteration of this
469         # for() loop, which is what we want.
470         if (flag_set_p("Joined.*", flags[i])) {
471                 for (j = i + 1; j < n_opts; j++) {
472                         if (substr (opts[j], 1, len) != opts[i])
473                                 break;
474                         back_chain[j] = enum;
475                 }
476         }
477
478         s = substr("                                          ",
479                    length (enum_string))
480
481         if (help[i] == "")
482                 hlp = "0"
483         else
484                 hlp = "N_(\"" help[i] "\")";
485
486         print "  " enum_string s "/* -" opts[i] " */"
487         enum_value++
488 }
489
490 print "  N_OPTS,"
491 print "  OPT_SPECIAL_unknown,"
492 print "  OPT_SPECIAL_ignore,"
493 print "  OPT_SPECIAL_program_name,"
494 print "  OPT_SPECIAL_input_file"
495 print "};"
496 print ""
497 print "#ifdef GCC_C_COMMON_C"
498 print "/* Mapping from cpp message reasons to the options that enable them.  */"
499 print "#include <cpplib.h>"
500 print "struct cpp_reason_option_codes_t"
501 print "{"
502 print "  const int reason;              /* cpplib message reason.  */"
503 print "  const int option_code; /* gcc option that controls this message.  */"
504 print "};"
505 print ""
506 print "static const struct cpp_reason_option_codes_t cpp_reason_option_codes[] = {"
507 for (i = 0; i < n_opts; i++) {
508     # With identical flags, pick only the last one.  The
509     # earlier loop ensured that it has all flags merged,
510     # and a nonempty help text if one of the texts was nonempty.
511     while( i + 1 != n_opts && opts[i] == opts[i + 1] ) {
512         i++;
513     }
514     cpp_reason = nth_arg(0, opt_args("CppReason", flags[i]));
515     if (cpp_reason != "") {
516         cpp_reason = cpp_reason ",";
517         printf("  {%-40s %s},\n", cpp_reason, opt_enum(opts[i]))
518     }
519 }
520 printf("  {%-40s 0},\n", "CPP_W_NONE,")
521 print "};"
522 print "#endif"
523 print ""
524 print "#endif /* OPTIONS_H */"
525 }