xref: /dragonfly/contrib/gcc-4.7/gcc/optc-gen.awk (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1#  Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010, 2011
2#  Free Software Foundation, Inc.
3#  Contributed by Kelley Cook, June 2004.
4#  Original code from Neil Booth, May 2003.
5#
6# This program is free software; you can redistribute it and/or modify it
7# under the terms of the GNU General Public License as published by the
8# Free Software Foundation; either version 3, or (at your option) any
9# later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; see the file COPYING3.  If not see
18# <http://www.gnu.org/licenses/>.
19
20# This Awk script reads in the option records generated from
21# opt-gather.awk, combines the flags of duplicate options and generates a
22# C file.
23#
24
25# This program uses functions from opt-functions.awk and code from
26# opt-read.awk.
27#
28# Usage: awk -f opt-functions.awk -f opt-read.awk -f optc-gen.awk \
29#            [-v header_name=header.h] < inputfile > options.c
30
31# Dump that array of options into a C file.
32END {
33print "/* This file is auto-generated by optc-gen.awk.  */"
34print ""
35n_headers = split(header_name, headers, " ")
36for (i = 1; i <= n_headers; i++)
37          print "#include " quote headers[i] quote
38print "#include " quote "opts.h" quote
39print "#include " quote "intl.h" quote
40print "#include " quote "insn-attr-common.h" quote
41print ""
42
43if (n_extra_c_includes > 0) {
44          for (i = 0; i < n_extra_c_includes; i++) {
45                    print "#include " quote extra_c_includes[i] quote
46          }
47          print ""
48}
49
50for (i = 0; i < n_enums; i++) {
51          name = enum_names[i]
52          type = enum_type[name]
53          print "static const struct cl_enum_arg cl_enum_" name \
54              "_data[] = "
55          print "{"
56          print enum_data[name] "  { NULL, 0, 0 }"
57          print "};"
58          print ""
59          print "static void"
60          print "cl_enum_" name "_set (void *var, int value)"
61          print "{"
62          print "  *((" type " *) var) = (" type ") value;"
63          print "}"
64          print ""
65          print "static int"
66          print "cl_enum_" name "_get (const void *var)"
67          print "{"
68          print "  return (int) *((const " type " *) var);"
69          print "}"
70          print ""
71}
72
73print "const struct cl_enum cl_enums[] ="
74print "{"
75for (i = 0; i < n_enums; i++) {
76          name = enum_names[i]
77          ehelp = enum_help[name]
78          if (ehelp == "")
79                    ehelp = "NULL"
80          else
81                    ehelp = quote ehelp quote
82          unknown_error = enum_unknown_error[name]
83          if (unknown_error == "")
84                    unknown_error = "NULL"
85          else
86                    unknown_error = quote unknown_error quote
87          print "  {"
88          print "    " ehelp ","
89          print "    " unknown_error ","
90          print "    cl_enum_" name "_data,"
91          print "    sizeof (" enum_type[name] "),"
92          print "    cl_enum_" name "_set,"
93          print "    cl_enum_" name "_get"
94          print "  },"
95}
96print "};"
97print "const unsigned int cl_enums_count = " n_enums ";"
98print ""
99
100print "const struct gcc_options global_options_init =\n{"
101for (i = 0; i < n_extra_vars; i++) {
102          var = extra_vars[i]
103          init = extra_vars[i]
104          if (var ~ "=" ) {
105                    sub(".*= *", "", init)
106          } else {
107                    init = "0"
108          }
109          sub(" *=.*", "", var)
110          name = var
111          sub("^.*[ *]", "", name)
112          sub("\\[.*\\]$", "", name)
113          var_seen[name] = 1
114          print "  " init ", /* " name " */"
115}
116for (i = 0; i < n_opts; i++) {
117          name = var_name(flags[i]);
118          if (name == "")
119                    continue;
120
121          init = opt_args("Init", flags[i])
122          if (init != "") {
123                    if (name in var_init && var_init[name] != init)
124                              print "#error multiple initializers for " name
125                    var_init[name] = init
126          }
127}
128for (i = 0; i < n_opts; i++) {
129          name = var_name(flags[i]);
130          if (name == "")
131                    continue;
132
133          if (name in var_seen)
134                    continue;
135
136          if (name in var_init)
137                    init = var_init[name]
138          else
139                    init = "0"
140
141          print "  " init ", /* " name " */"
142
143          var_seen[name] = 1;
144}
145for (i = 0; i < n_opts; i++) {
146          name = static_var(opts[i], flags[i]);
147          if (name != "") {
148                    print "  0, /* " name " (private state) */"
149                    print "#undef x_" name
150          }
151}
152for (i = 0; i < n_opts; i++) {
153          if (flag_set_p("SetByCombined", flags[i]))
154                    print "  false, /* frontend_set_" var_name(flags[i]) " */"
155}
156print "};"
157print ""
158print "struct gcc_options global_options;"
159print "struct gcc_options global_options_set;"
160print ""
161
162print "const char * const lang_names[] =\n{"
163for (i = 0; i < n_langs; i++) {
164          macros[i] = "CL_" langs[i]
165          gsub( "[^" alnum "_]", "X", macros[i] )
166          s = substr("         ", length (macros[i]))
167          print "  " quote langs[i] quote ","
168    }
169
170print "  0\n};\n"
171print "const unsigned int cl_options_count = N_OPTS;\n"
172print "#if (1U << " n_langs ") > CL_MIN_OPTION_CLASS"
173print "  #error the number of languages exceeds the implementation limit"
174print "#endif"
175print "const unsigned int cl_lang_count = " n_langs ";\n"
176
177print "const struct cl_option cl_options[] =\n{"
178
179j = 0
180for (i = 0; i < n_opts; i++) {
181          back_chain[i] = "N_OPTS";
182          indices[opts[i]] = j;
183          # Combine the flags of identical switches.  Switches
184          # appear many times if they are handled by many front
185          # ends, for example.
186          while( i + 1 != n_opts && opts[i] == opts[i + 1] ) {
187                    flags[i + 1] = flags[i] " " flags[i + 1];
188                    if (help[i + 1] == "")
189                              help[i + 1] = help[i]
190                    else if (help[i] != "" && help[i + 1] != help[i])
191                              print "warning: multiple different help strings for " \
192                                        opts[i] ":\n\t" help[i] "\n\t" help[i + 1] \
193                                        | "cat 1>&2"
194                    i++;
195                    back_chain[i] = "N_OPTS";
196                    indices[opts[i]] = j;
197          }
198          j++;
199}
200
201for (i = 0; i < n_opts; i++) {
202          # With identical flags, pick only the last one.  The
203          # earlier loop ensured that it has all flags merged,
204          # and a nonempty help text if one of the texts was nonempty.
205          while( i + 1 != n_opts && opts[i] == opts[i + 1] ) {
206                    i++;
207          }
208
209          len = length (opts[i]);
210          enum = opt_enum(opts[i])
211
212          # If this switch takes joined arguments, back-chain all
213          # subsequent switches to it for which it is a prefix.  If
214          # a later switch S is a longer prefix of a switch T, T
215          # will be back-chained to S in a later iteration of this
216          # for() loop, which is what we want.
217          if (flag_set_p("Joined.*", flags[i])) {
218                    for (j = i + 1; j < n_opts; j++) {
219                              if (substr (opts[j], 1, len) != opts[i])
220                                        break;
221                              back_chain[j] = enum;
222                    }
223          }
224
225          s = substr("                                  ", length (opts[i]))
226          if (i + 1 == n_opts)
227                    comma = ""
228
229          if (help[i] == "")
230                    hlp = "0"
231          else
232                    hlp = quote help[i] quote;
233
234          missing_arg_error = opt_args("MissingArgError", flags[i])
235          if (missing_arg_error == "")
236                    missing_arg_error = "0"
237          else
238                    missing_arg_error = quote missing_arg_error quote
239
240
241          warn_message = opt_args("Warn", flags[i])
242          if (warn_message == "")
243                    warn_message = "0"
244          else
245                    warn_message = quote warn_message quote
246
247          alias_arg = opt_args("Alias", flags[i])
248          if (alias_arg == "") {
249                    if (flag_set_p("Ignore", flags[i]))
250                              alias_data = "NULL, NULL, OPT_SPECIAL_ignore"
251                    else
252                              alias_data = "NULL, NULL, N_OPTS"
253          } else {
254                    alias_opt = nth_arg(0, alias_arg)
255                    alias_posarg = nth_arg(1, alias_arg)
256                    alias_negarg = nth_arg(2, alias_arg)
257
258                    if (var_ref(opts[i], flags[i]) != "-1")
259                              print "#error Alias setting variable"
260
261                    if (alias_posarg != "" && alias_negarg == "") {
262                              if (!flag_set_p("RejectNegative", flags[i]) \
263                                  && opts[i] ~ "^[Wfm]")
264                                        print "#error Alias with single argument " \
265                                                  "allowing negative form"
266                    }
267                    if (alias_posarg != "" \
268                        && flag_set_p("NegativeAlias", flags[i])) {
269                              print "#error Alias with multiple arguments " \
270                                        "used with NegativeAlias"
271                    }
272
273                    alias_opt = opt_enum(alias_opt)
274                    if (alias_posarg == "")
275                              alias_posarg = "NULL"
276                    else
277                              alias_posarg = quote alias_posarg quote
278                    if (alias_negarg == "")
279                              alias_negarg = "NULL"
280                    else
281                              alias_negarg = quote alias_negarg quote
282                    alias_data = alias_posarg ", " alias_negarg ", " alias_opt
283          }
284
285          neg = opt_args("Negative", flags[i]);
286          if (neg != "")
287                    idx = indices[neg]
288          else {
289                    if (flag_set_p("RejectNegative", flags[i]))
290                              idx = -1;
291                    else {
292                              if (opts[i] ~ "^[Wfm]")
293                                        idx = indices[opts[i]];
294                              else
295                                        idx = -1;
296                    }
297          }
298          # Split the printf after %u to work around an ia64-hp-hpux11.23
299          # awk bug.
300          printf("  { %c-%s%c,\n    %s,\n    %s,\n    %s,\n    %s, %s, %u,",
301                 quote, opts[i], quote, hlp, missing_arg_error, warn_message,
302                 alias_data, back_chain[i], len)
303          printf(" %d,\n", idx)
304          condition = opt_args("Condition", flags[i])
305          cl_flags = switch_flags(flags[i])
306          cl_bit_fields = switch_bit_fields(flags[i])
307          cl_zero_bit_fields = switch_bit_fields("")
308          if (condition != "")
309                    printf("#if %s\n" \
310                           "    %s,\n" \
311                           "    0, %s,\n" \
312                           "#else\n" \
313                           "    0,\n" \
314                           "    1 /* Disabled.  */, %s,\n" \
315                           "#endif\n",
316                           condition, cl_flags, cl_bit_fields, cl_zero_bit_fields)
317          else
318                    printf("    %s,\n" \
319                           "    0, %s,\n",
320                           cl_flags, cl_bit_fields)
321          printf("    %s, %s }%s\n", var_ref(opts[i], flags[i]),
322                 var_set(flags[i]), comma)
323}
324
325print "};"
326
327}
328