]>
Commit | Line | Data |
---|---|---|
c6d9a88c | 1 | /* params.c - Run-time parameters. |
a5544970 | 2 | Copyright (C) 2001-2019 Free Software Foundation, Inc. |
c6d9a88c MM |
3 | Written by Mark Mitchell <mark@codesourcery.com>. |
4 | ||
1322177d | 5 | This file is part of GCC. |
c6d9a88c | 6 | |
1322177d LB |
7 | GCC is free software; you can redistribute it and/or modify it under |
8 | the terms of the GNU General Public License as published by the Free | |
9dcd6f09 | 9 | Software Foundation; either version 3, or (at your option) any later |
1322177d | 10 | version. |
c6d9a88c | 11 | |
1322177d LB |
12 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 | for more details. | |
c6d9a88c MM |
16 | |
17 | You should have received a copy of the GNU General Public License | |
9dcd6f09 NC |
18 | along with GCC; see the file COPYING3. If not see |
19 | <http://www.gnu.org/licenses/>. */ | |
c6d9a88c MM |
20 | |
21 | #include "config.h" | |
22 | #include "system.h" | |
4977bab6 | 23 | #include "coretypes.h" |
4c77620d | 24 | #include "common/common-target.h" |
c6d9a88c | 25 | #include "params.h" |
d78182cc | 26 | #include "params-enum.h" |
718f9c0f | 27 | #include "diagnostic-core.h" |
f622a56b | 28 | #include "diagnostic.h" |
f4452176 | 29 | #include "spellcheck.h" |
c6d9a88c MM |
30 | |
31 | /* An array containing the compiler parameters and their current | |
32 | values. */ | |
33 | ||
34 | param_info *compiler_params; | |
35 | ||
36 | /* The number of entries in the table. */ | |
c6d9a88c MM |
37 | static size_t num_compiler_params; |
38 | ||
48476d13 JM |
39 | /* Whether the parameters have all been initialized and had their |
40 | default values determined. */ | |
41 | static bool params_finished; | |
42 | ||
d78182cc TV |
43 | #define DEFPARAM(ENUM, OPTION, HELP, DEFAULT, MIN, MAX) |
44 | #define DEFPARAMENUM5(ENUM, OPTION, HELP, DEFAULT, V0, V1, V2, V3, V4) \ | |
45 | static const char *values_ ## ENUM [] = { #V0, #V1, #V2, #V3, #V4, NULL }; | |
46 | #include "params.def" | |
47 | #undef DEFPARAMENUM5 | |
48 | #undef DEFPARAM | |
49 | ||
4c77620d JM |
50 | static const param_info lang_independent_params[] = { |
51 | #define DEFPARAM(ENUM, OPTION, HELP, DEFAULT, MIN, MAX) \ | |
d78182cc TV |
52 | { OPTION, DEFAULT, MIN, MAX, HELP, NULL }, |
53 | #define DEFPARAMENUM5(ENUM, OPTION, HELP, DEFAULT, \ | |
54 | V0, V1, V2, V3, V4) \ | |
55 | { OPTION, (int)ENUM ## _KIND_ ## DEFAULT, 0, 4, HELP, values_ ## ENUM }, | |
4c77620d JM |
56 | #include "params.def" |
57 | #undef DEFPARAM | |
d78182cc TV |
58 | #undef DEFPARAMENUM5 |
59 | { NULL, 0, 0, 0, NULL, NULL } | |
4c77620d JM |
60 | }; |
61 | ||
f622a56b TC |
62 | static bool |
63 | validate_param (const int value, const param_info param, const int index); | |
64 | ||
65 | ||
c6d9a88c MM |
66 | /* Add the N PARAMS to the current list of compiler parameters. */ |
67 | ||
6a4d6760 | 68 | void |
3d7aafde | 69 | add_params (const param_info params[], size_t n) |
c6d9a88c | 70 | { |
48476d13 JM |
71 | gcc_assert (!params_finished); |
72 | ||
c6d9a88c | 73 | /* Allocate enough space for the new parameters. */ |
d3bfe4de KG |
74 | compiler_params = XRESIZEVEC (param_info, compiler_params, |
75 | num_compiler_params + n); | |
f622a56b TC |
76 | param_info *dst_params = compiler_params + num_compiler_params; |
77 | ||
c6d9a88c | 78 | /* Copy them into the table. */ |
f622a56b TC |
79 | memcpy (dst_params, params, n * sizeof (param_info)); |
80 | ||
c6d9a88c MM |
81 | /* Keep track of how many parameters we have. */ |
82 | num_compiler_params += n; | |
f622a56b TC |
83 | |
84 | /* Initialize the pretty printing machinery in case we need to print an error, | |
85 | but be sure not to initialize it if something else already has, e.g. a | |
86 | language front-end like cc1. */ | |
87 | if (!diagnostic_ready_p ()) | |
88 | diagnostic_initialize (global_dc, 0); | |
89 | ||
ac712e4e TC |
90 | /* Now perform some validation and validation failures trigger an error so |
91 | initialization will stop. */ | |
92 | for (size_t i = num_compiler_params - n; i < n; i++) | |
93 | validate_param (params[i].default_value, params[i], (int)i); | |
c6d9a88c MM |
94 | } |
95 | ||
4c77620d JM |
96 | /* Add all parameters and default values that can be set in both the |
97 | driver and the compiler proper. */ | |
98 | ||
99 | void | |
100 | global_init_params (void) | |
101 | { | |
3edf64aa DM |
102 | gcc_assert (!params_finished); |
103 | ||
4c77620d JM |
104 | add_params (lang_independent_params, LAST_PARAM); |
105 | targetm_common.option_default_params (); | |
106 | } | |
107 | ||
48476d13 JM |
108 | /* Note that all parameters have been added and all default values |
109 | set. */ | |
110 | ||
111 | void | |
112 | finish_params (void) | |
113 | { | |
114 | params_finished = true; | |
115 | } | |
116 | ||
3edf64aa DM |
117 | /* Reset all state within params.c so that we can rerun the compiler |
118 | within the same process. For use by toplev::finalize. */ | |
119 | ||
120 | void | |
121 | params_c_finalize (void) | |
122 | { | |
123 | XDELETEVEC (compiler_params); | |
124 | compiler_params = NULL; | |
125 | num_compiler_params = 0; | |
126 | params_finished = false; | |
127 | } | |
128 | ||
48476d13 JM |
129 | /* Set the value of the parameter given by NUM to VALUE in PARAMS and |
130 | PARAMS_SET. If EXPLICIT_P, this is being set by the user; | |
131 | otherwise it is being set implicitly by the compiler. */ | |
128dc8e2 JM |
132 | |
133 | static void | |
134 | set_param_value_internal (compiler_param num, int value, | |
48476d13 | 135 | int *params, int *params_set, |
128dc8e2 JM |
136 | bool explicit_p) |
137 | { | |
138 | size_t i = (size_t) num; | |
139 | ||
48476d13 JM |
140 | gcc_assert (params_finished); |
141 | ||
142 | params[i] = value; | |
128dc8e2 | 143 | if (explicit_p) |
48476d13 | 144 | params_set[i] = true; |
128dc8e2 JM |
145 | } |
146 | ||
f622a56b TC |
147 | /* Validate PARAM and write an error if invalid. */ |
148 | ||
149 | static bool | |
150 | validate_param (const int value, const param_info param, const int index) | |
151 | { | |
152 | /* These paremeters interpret bounds of 0 to be unbounded, as such don't | |
153 | perform any range validation on 0 parameters. */ | |
154 | if (value < param.min_value && param.min_value != 0) | |
155 | { | |
156 | error ("minimum value of parameter %qs is %u", | |
157 | param.option, param.min_value); | |
158 | return false; | |
159 | } | |
160 | else if (param.max_value > param.min_value && value > param.max_value) | |
161 | { | |
162 | error ("maximum value of parameter %qs is %u", | |
163 | param.option, param.max_value); | |
164 | return false; | |
165 | } | |
166 | else if (targetm_common.option_validate_param (value, index)) | |
167 | return true; | |
168 | ||
169 | return false; | |
170 | } | |
171 | ||
d78182cc TV |
172 | /* Return true if it can find the matching entry for NAME in the parameter |
173 | table, and assign the entry index to INDEX. Return false otherwise. */ | |
174 | ||
175 | bool | |
176 | find_param (const char *name, enum compiler_param *index) | |
177 | { | |
178 | for (size_t i = 0; i < num_compiler_params; ++i) | |
179 | if (strcmp (compiler_params[i].option, name) == 0) | |
180 | { | |
181 | *index = (enum compiler_param) i; | |
182 | return true; | |
183 | } | |
184 | ||
185 | return false; | |
186 | } | |
187 | ||
f4452176 DM |
188 | /* Look for the closest match for NAME in the parameter table, returning it |
189 | if it is a reasonable suggestion for a misspelling. Return NULL | |
190 | otherwise. */ | |
191 | ||
192 | const char * | |
193 | find_param_fuzzy (const char *name) | |
194 | { | |
195 | best_match <const char *, const char *> bm (name); | |
196 | for (size_t i = 0; i < num_compiler_params; ++i) | |
197 | bm.consider (compiler_params[i].option); | |
198 | return bm.get_best_meaningful_candidate (); | |
199 | } | |
200 | ||
d78182cc TV |
201 | /* Return true if param with entry index INDEX should be defined using strings. |
202 | If so, return the value corresponding to VALUE_NAME in *VALUE_P. */ | |
203 | ||
204 | bool | |
205 | param_string_value_p (enum compiler_param index, const char *value_name, | |
206 | int *value_p) | |
207 | { | |
208 | param_info *entry = &compiler_params[(int) index]; | |
209 | if (entry->value_names == NULL) | |
210 | return false; | |
211 | ||
212 | *value_p = -1; | |
213 | ||
214 | for (int i = 0; entry->value_names[i] != NULL; ++i) | |
215 | if (strcmp (entry->value_names[i], value_name) == 0) | |
216 | { | |
217 | *value_p = i; | |
218 | return true; | |
219 | } | |
220 | ||
221 | return true; | |
222 | } | |
223 | ||
48476d13 JM |
224 | /* Set the VALUE associated with the parameter given by NAME in PARAMS |
225 | and PARAMS_SET. */ | |
c6d9a88c MM |
226 | |
227 | void | |
48476d13 JM |
228 | set_param_value (const char *name, int value, |
229 | int *params, int *params_set) | |
c6d9a88c MM |
230 | { |
231 | size_t i; | |
232 | ||
233 | /* Make sure nobody tries to set a parameter to an invalid value. */ | |
e16acfcd | 234 | gcc_assert (value != INVALID_PARAM_VAL); |
c6d9a88c | 235 | |
d78182cc TV |
236 | enum compiler_param index; |
237 | if (!find_param (name, &index)) | |
238 | { | |
239 | /* If we didn't find this parameter, issue an error message. */ | |
240 | error ("invalid parameter %qs", name); | |
241 | return; | |
242 | } | |
243 | i = (size_t)index; | |
244 | ||
f622a56b | 245 | if (validate_param (value, compiler_params[i], i)) |
d78182cc TV |
246 | set_param_value_internal ((compiler_param) i, value, |
247 | params, params_set, true); | |
c6d9a88c | 248 | } |
090fa0ab | 249 | |
48476d13 JM |
250 | /* Set the value of the parameter given by NUM to VALUE in PARAMS and |
251 | PARAMS_SET, implicitly, if it has not been set explicitly by the | |
f622a56b | 252 | user either via the commandline or configure. */ |
128dc8e2 JM |
253 | |
254 | void | |
48476d13 JM |
255 | maybe_set_param_value (compiler_param num, int value, |
256 | int *params, int *params_set) | |
128dc8e2 | 257 | { |
48476d13 JM |
258 | if (!params_set[(int) num]) |
259 | set_param_value_internal (num, value, params, params_set, false); | |
128dc8e2 JM |
260 | } |
261 | ||
262 | /* Set the default value of a parameter given by NUM to VALUE, before | |
263 | option processing. */ | |
264 | ||
265 | void | |
266 | set_default_param_value (compiler_param num, int value) | |
267 | { | |
48476d13 JM |
268 | gcc_assert (!params_finished); |
269 | ||
270 | compiler_params[(int) num].default_value = value; | |
271 | } | |
272 | ||
273 | /* Return the default value of parameter NUM. */ | |
274 | ||
275 | int | |
276 | default_param_value (compiler_param num) | |
277 | { | |
278 | return compiler_params[(int) num].default_value; | |
279 | } | |
280 | ||
281 | /* Initialize an array PARAMS with default values of the | |
282 | parameters. */ | |
283 | ||
284 | void | |
285 | init_param_values (int *params) | |
286 | { | |
287 | size_t i; | |
288 | ||
289 | gcc_assert (params_finished); | |
290 | ||
291 | for (i = 0; i < num_compiler_params; i++) | |
292 | params[i] = compiler_params[i].default_value; | |
128dc8e2 JM |
293 | } |
294 | ||
090fa0ab GF |
295 | /* Return the current value of num_compiler_params, for the benefit of |
296 | plugins that use parameters as features. */ | |
297 | ||
298 | size_t | |
299 | get_num_compiler_params (void) | |
300 | { | |
301 | return num_compiler_params; | |
302 | } |