xref: /dragonfly/contrib/gcc-4.7/gcc/optc-gen.awk (revision 0db87cb7)
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