/* params.c - Run-time parameters.
- Copyright (C) 2001, 2003, 2004, 2005, 2007, 2008, 2009, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 2001-2019 Free Software Foundation, Inc.
Written by Mark Mitchell <mark@codesourcery.com>.
This file is part of GCC.
#include "config.h"
#include "system.h"
#include "coretypes.h"
-#include "tm.h"
+#include "common/common-target.h"
#include "params.h"
+#include "params-enum.h"
#include "diagnostic-core.h"
+#include "diagnostic.h"
+#include "spellcheck.h"
/* An array containing the compiler parameters and their current
values. */
default values determined. */
static bool params_finished;
+#define DEFPARAM(ENUM, OPTION, HELP, DEFAULT, MIN, MAX)
+#define DEFPARAMENUM5(ENUM, OPTION, HELP, DEFAULT, V0, V1, V2, V3, V4) \
+ static const char *values_ ## ENUM [] = { #V0, #V1, #V2, #V3, #V4, NULL };
+#include "params.def"
+#undef DEFPARAMENUM5
+#undef DEFPARAM
+
+static const param_info lang_independent_params[] = {
+#define DEFPARAM(ENUM, OPTION, HELP, DEFAULT, MIN, MAX) \
+ { OPTION, DEFAULT, MIN, MAX, HELP, NULL },
+#define DEFPARAMENUM5(ENUM, OPTION, HELP, DEFAULT, \
+ V0, V1, V2, V3, V4) \
+ { OPTION, (int)ENUM ## _KIND_ ## DEFAULT, 0, 4, HELP, values_ ## ENUM },
+#include "params.def"
+#undef DEFPARAM
+#undef DEFPARAMENUM5
+ { NULL, 0, 0, 0, NULL, NULL }
+};
+
+static bool
+validate_param (const int value, const param_info param, const int index);
+
+
/* Add the N PARAMS to the current list of compiler parameters. */
void
/* Allocate enough space for the new parameters. */
compiler_params = XRESIZEVEC (param_info, compiler_params,
num_compiler_params + n);
+ param_info *dst_params = compiler_params + num_compiler_params;
+
/* Copy them into the table. */
- memcpy (compiler_params + num_compiler_params,
- params,
- n * sizeof (param_info));
+ memcpy (dst_params, params, n * sizeof (param_info));
+
/* Keep track of how many parameters we have. */
num_compiler_params += n;
+
+ /* Initialize the pretty printing machinery in case we need to print an error,
+ but be sure not to initialize it if something else already has, e.g. a
+ language front-end like cc1. */
+ if (!diagnostic_ready_p ())
+ diagnostic_initialize (global_dc, 0);
+
+ /* Now perform some validation and validation failures trigger an error so
+ initialization will stop. */
+ for (size_t i = num_compiler_params - n; i < n; i++)
+ validate_param (params[i].default_value, params[i], (int)i);
+}
+
+/* Add all parameters and default values that can be set in both the
+ driver and the compiler proper. */
+
+void
+global_init_params (void)
+{
+ gcc_assert (!params_finished);
+
+ add_params (lang_independent_params, LAST_PARAM);
+ targetm_common.option_default_params ();
}
/* Note that all parameters have been added and all default values
params_finished = true;
}
+/* Reset all state within params.c so that we can rerun the compiler
+ within the same process. For use by toplev::finalize. */
+
+void
+params_c_finalize (void)
+{
+ XDELETEVEC (compiler_params);
+ compiler_params = NULL;
+ num_compiler_params = 0;
+ params_finished = false;
+}
+
/* Set the value of the parameter given by NUM to VALUE in PARAMS and
PARAMS_SET. If EXPLICIT_P, this is being set by the user;
otherwise it is being set implicitly by the compiler. */
params_set[i] = true;
}
+/* Validate PARAM and write an error if invalid. */
+
+static bool
+validate_param (const int value, const param_info param, const int index)
+{
+ /* These paremeters interpret bounds of 0 to be unbounded, as such don't
+ perform any range validation on 0 parameters. */
+ if (value < param.min_value && param.min_value != 0)
+ {
+ error ("minimum value of parameter %qs is %u",
+ param.option, param.min_value);
+ return false;
+ }
+ else if (param.max_value > param.min_value && value > param.max_value)
+ {
+ error ("maximum value of parameter %qs is %u",
+ param.option, param.max_value);
+ return false;
+ }
+ else if (targetm_common.option_validate_param (value, index))
+ return true;
+
+ return false;
+}
+
+/* Return true if it can find the matching entry for NAME in the parameter
+ table, and assign the entry index to INDEX. Return false otherwise. */
+
+bool
+find_param (const char *name, enum compiler_param *index)
+{
+ for (size_t i = 0; i < num_compiler_params; ++i)
+ if (strcmp (compiler_params[i].option, name) == 0)
+ {
+ *index = (enum compiler_param) i;
+ return true;
+ }
+
+ return false;
+}
+
+/* Look for the closest match for NAME in the parameter table, returning it
+ if it is a reasonable suggestion for a misspelling. Return NULL
+ otherwise. */
+
+const char *
+find_param_fuzzy (const char *name)
+{
+ best_match <const char *, const char *> bm (name);
+ for (size_t i = 0; i < num_compiler_params; ++i)
+ bm.consider (compiler_params[i].option);
+ return bm.get_best_meaningful_candidate ();
+}
+
+/* Return true if param with entry index INDEX should be defined using strings.
+ If so, return the value corresponding to VALUE_NAME in *VALUE_P. */
+
+bool
+param_string_value_p (enum compiler_param index, const char *value_name,
+ int *value_p)
+{
+ param_info *entry = &compiler_params[(int) index];
+ if (entry->value_names == NULL)
+ return false;
+
+ *value_p = -1;
+
+ for (int i = 0; entry->value_names[i] != NULL; ++i)
+ if (strcmp (entry->value_names[i], value_name) == 0)
+ {
+ *value_p = i;
+ return true;
+ }
+
+ return true;
+}
+
/* Set the VALUE associated with the parameter given by NAME in PARAMS
and PARAMS_SET. */
/* Make sure nobody tries to set a parameter to an invalid value. */
gcc_assert (value != INVALID_PARAM_VAL);
- /* Scan the parameter table to find a matching entry. */
- for (i = 0; i < num_compiler_params; ++i)
- if (strcmp (compiler_params[i].option, name) == 0)
- {
- if (value < compiler_params[i].min_value)
- error ("minimum value of parameter %qs is %u",
- compiler_params[i].option,
- compiler_params[i].min_value);
- else if (compiler_params[i].max_value > compiler_params[i].min_value
- && value > compiler_params[i].max_value)
- error ("maximum value of parameter %qs is %u",
- compiler_params[i].option,
- compiler_params[i].max_value);
- else
- set_param_value_internal ((compiler_param) i, value,
- params, params_set, true);
- return;
- }
-
- /* If we didn't find this parameter, issue an error message. */
- error ("invalid parameter %qs", name);
+ enum compiler_param index;
+ if (!find_param (name, &index))
+ {
+ /* If we didn't find this parameter, issue an error message. */
+ error ("invalid parameter %qs", name);
+ return;
+ }
+ i = (size_t)index;
+
+ if (validate_param (value, compiler_params[i], i))
+ set_param_value_internal ((compiler_param) i, value,
+ params, params_set, true);
}
/* Set the value of the parameter given by NUM to VALUE in PARAMS and
PARAMS_SET, implicitly, if it has not been set explicitly by the
- user. */
+ user either via the commandline or configure. */
void
maybe_set_param_value (compiler_param num, int value,