1# Copyright (C) 2003-2013 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. 30END { 31print "/* This file is auto-generated by opth-gen.awk. */" 32print "" 33print "#ifndef OPTIONS_H" 34print "#define OPTIONS_H" 35print "" 36print "#include \"flag-types.h\"" 37print "" 38 39if (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 46print "#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS) && !defined(IN_RTS)" 47print "#ifndef GENERATOR_FILE" 48print "#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS)" 49print "struct GTY(()) gcc_options" 50print "#else" 51print "struct gcc_options" 52print "#endif" 53print "{" 54print "#endif" 55 56for (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 77for (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} 96for (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} 105for (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} 112print "#ifndef GENERATOR_FILE" 113print "};" 114print "extern struct gcc_options global_options;" 115print "extern const struct gcc_options global_options_init;" 116print "extern struct gcc_options global_options_set;" 117print "#define target_flags_explicit global_options_set.x_target_flags" 118print "#endif" 119print "#endif" 120print "" 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 129print "#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS) && !defined(IN_RTS)" 130print "" 131print "/* Structure to save/restore optimization and target specific options. */"; 132print "struct GTY(()) cl_optimization"; 133print "{"; 134 135n_opt_char = 2; 136n_opt_short = 0; 137n_opt_int = 0; 138n_opt_enum = 1; 139n_opt_other = 0; 140var_opt_char[0] = "unsigned char x_optimize"; 141var_opt_char[1] = "unsigned char x_optimize_size"; 142var_opt_enum[0] = "enum fp_contract_mode x_flag_fp_contract_mode"; 143 144for (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 172for (i = 0; i < n_opt_other; i++) { 173 print " " var_opt_other[i] ";"; 174} 175 176for (i = 0; i < n_opt_int; i++) { 177 print " " var_opt_int[i] ";"; 178} 179 180for (i = 0; i < n_opt_enum; i++) { 181 print " " var_opt_enum[i] ";"; 182} 183 184for (i = 0; i < n_opt_short; i++) { 185 print " " var_opt_short[i] ";"; 186} 187 188for (i = 0; i < n_opt_char; i++) { 189 print " " var_opt_char[i] ";"; 190} 191 192print "};"; 193print ""; 194 195# Target and optimization save/restore/print functions. 196print "/* Structure to save/restore selected target specific options. */"; 197print "struct GTY(()) cl_target_option"; 198print "{"; 199 200n_target_char = 0; 201n_target_short = 0; 202n_target_int = 0; 203n_target_enum = 0; 204n_target_other = 0; 205 206for (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 223if (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 255for (i = 0; i < n_target_other; i++) { 256 print " " var_target_other[i] ";"; 257} 258 259for (i = 0; i < n_target_enum; i++) { 260 print " " var_target_enum[i] ";"; 261} 262 263for (i = 0; i < n_target_int; i++) { 264 print " " var_target_int[i] ";"; 265} 266 267for (i = 0; i < n_target_short; i++) { 268 print " " var_target_short[i] ";"; 269} 270 271for (i = 0; i < n_target_char; i++) { 272 print " " var_target_char[i] ";"; 273} 274 275print "};"; 276print ""; 277print ""; 278print "/* Save optimization variables into a structure. */" 279print "extern void cl_optimization_save (struct cl_optimization *, struct gcc_options *);"; 280print ""; 281print "/* Restore optimization variables from a structure. */"; 282print "extern void cl_optimization_restore (struct gcc_options *, struct cl_optimization *);"; 283print ""; 284print "/* Print optimization variables from a structure. */"; 285print "extern void cl_optimization_print (FILE *, int, struct cl_optimization *);"; 286print ""; 287print "/* Save selected option variables into a structure. */" 288print "extern void cl_target_option_save (struct cl_target_option *, struct gcc_options *);"; 289print ""; 290print "/* Restore selected option variables from a structure. */" 291print "extern void cl_target_option_restore (struct gcc_options *, struct cl_target_option *);"; 292print ""; 293print "/* Print target option variables from a structure. */"; 294print "extern void cl_target_option_print (FILE *, int, struct cl_target_option *);"; 295print ""; 296print "/* Anything that includes tm.h, does not necessarily need this. */" 297print "#if !defined(GCC_TM_H)" 298print "#include \"input.h\" /* for location_t */" 299print "bool " 300print "common_handle_option_auto (struct gcc_options *opts, " 301print " struct gcc_options *opts_set, " 302print " const struct cl_decoded_option *decoded, " 303print " unsigned int lang_mask, int kind, " 304print " location_t loc, " 305print " const struct cl_option_handlers *handlers, " 306print " diagnostic_context *dc); " 307for (i = 0; i < n_langs; i++) { 308 lang_name = lang_sanitized_name(langs[i]); 309 print "bool " 310 print lang_name "_handle_option_auto (struct gcc_options *opts, " 311 print " struct gcc_options *opts_set, " 312 print " size_t scode, const char *arg, int value, " 313 print " unsigned int lang_mask, int kind, " 314 print " location_t loc, " 315 print " const struct cl_option_handlers *handlers, " 316 print " diagnostic_context *dc); " 317} 318print "#endif"; 319print "#endif"; 320print ""; 321 322for (i = 0; i < n_opts; i++) { 323 name = opt_args("Mask", flags[i]) 324 if (name == "") { 325 opt = opt_args("InverseMask", flags[i]) 326 if (opt ~ ",") 327 name = nth_arg(0, opt) 328 else 329 name = opt 330 } 331 if (name != "" && mask_bits[name] == 0) { 332 mask_bits[name] = 1 333 vname = var_name(flags[i]) 334 mask = "MASK_" 335 mask_1 = "1" 336 if (vname != "") { 337 mask = "OPTION_MASK_" 338 if (host_wide_int[vname] == "yes") 339 mask_1 = "HOST_WIDE_INT_1" 340 } else 341 extra_mask_bits[name] = 1 342 print "#define " mask name " (" mask_1 " << " masknum[vname]++ ")" 343 } 344} 345for (i = 0; i < n_extra_masks; i++) { 346 if (extra_mask_bits[extra_masks[i]] == 0) 347 print "#define MASK_" extra_masks[i] " (1 << " masknum[""]++ ")" 348} 349 350for (var in masknum) { 351 if (var != "" && host_wide_int[var] == "yes") { 352 print" #if defined(HOST_BITS_PER_WIDE_INT) && " masknum[var] " >= HOST_BITS_PER_WIDE_INT" 353 print "#error too many masks for " var 354 print "#endif" 355 } 356 else if (masknum[var] > 31) { 357 if (var == "") 358 print "#error too many target masks" 359 else 360 print "#error too many masks for " var 361 } 362} 363print "" 364 365for (i = 0; i < n_opts; i++) { 366 name = opt_args("Mask", flags[i]) 367 if (name == "") { 368 opt = opt_args("InverseMask", flags[i]) 369 if (opt ~ ",") 370 name = nth_arg(0, opt) 371 else 372 name = opt 373 } 374 if (name != "" && mask_macros[name] == 0) { 375 mask_macros[name] = 1 376 vname = var_name(flags[i]) 377 mask = "OPTION_MASK_" 378 if (vname == "") { 379 vname = "target_flags" 380 mask = "MASK_" 381 extra_mask_macros[name] = 1 382 } 383 print "#define TARGET_" name \ 384 " ((" vname " & " mask name ") != 0)" 385 } 386} 387for (i = 0; i < n_extra_masks; i++) { 388 if (extra_mask_macros[extra_masks[i]] == 0) 389 print "#define TARGET_" extra_masks[i] \ 390 " ((target_flags & MASK_" extra_masks[i] ") != 0)" 391} 392print "" 393 394for (i = 0; i < n_opts; i++) { 395 opt = opt_args("InverseMask", flags[i]) 396 if (opt ~ ",") { 397 vname = var_name(flags[i]) 398 mask = "OPTION_MASK_" 399 if (vname == "") { 400 vname = "target_flags" 401 mask = "MASK_" 402 } 403 print "#define TARGET_" nth_arg(1, opt) \ 404 " ((" vname " & " mask nth_arg(0, opt) ") == 0)" 405 } 406} 407print "" 408 409for (i = 0; i < n_langs; i++) { 410 macros[i] = "CL_" lang_sanitized_name(langs[i]) 411 s = substr(" ", length (macros[i])) 412 print "#define " macros[i] s " (1U << " i ")" 413 } 414print "#define CL_LANG_ALL ((1U << " n_langs ") - 1)" 415 416print "" 417print "enum opt_code" 418print "{" 419 420for (i = 0; i < n_opts; i++) 421 back_chain[i] = "N_OPTS"; 422 423enum_value = 0 424for (i = 0; i < n_opts; i++) { 425 # Combine the flags of identical switches. Switches 426 # appear many times if they are handled by many front 427 # ends, for example. 428 while( i + 1 != n_opts && opts[i] == opts[i + 1] ) { 429 flags[i + 1] = flags[i] " " flags[i + 1]; 430 i++; 431 } 432 433 len = length (opts[i]); 434 enum = opt_enum(opts[i]) 435 enum_string = enum " = " enum_value "," 436 437 # Aliases do not get enumeration names. 438 if ((flag_set_p("Alias.*", flags[i]) \ 439 && !flag_set_p("SeparateAlias", flags[i])) \ 440 || flag_set_p("Ignore", flags[i])) { 441 enum_string = "/* " enum_string " */" 442 } 443 444 # If this switch takes joined arguments, back-chain all 445 # subsequent switches to it for which it is a prefix. If 446 # a later switch S is a longer prefix of a switch T, T 447 # will be back-chained to S in a later iteration of this 448 # for() loop, which is what we want. 449 if (flag_set_p("Joined.*", flags[i])) { 450 for (j = i + 1; j < n_opts; j++) { 451 if (substr (opts[j], 1, len) != opts[i]) 452 break; 453 back_chain[j] = enum; 454 } 455 } 456 457 s = substr(" ", 458 length (enum_string)) 459 460 if (help[i] == "") 461 hlp = "0" 462 else 463 hlp = "N_(\"" help[i] "\")"; 464 465 print " " enum_string s "/* -" opts[i] " */" 466 enum_value++ 467} 468 469print " N_OPTS," 470print " OPT_SPECIAL_unknown," 471print " OPT_SPECIAL_ignore," 472print " OPT_SPECIAL_program_name," 473print " OPT_SPECIAL_input_file" 474print "};" 475print "" 476print "#endif /* OPTIONS_H */" 477} 478