diagnostics: introduce class diagnostic_option_classifier
This patch gathers the 6 fields in diagnostic_context relating to keeping track of overriding the severity of warnings, and pushing/popping those severities, moving them all into a new class diagnostic_option_classifier. No functional change intended. gcc/ChangeLog: * diagnostic.cc (diagnostic_context::push_diagnostics): Convert to... (diagnostic_option_classifier::push): ...this. (diagnostic_context::pop_diagnostics): Convert to... (diagnostic_option_classifier::pop): ...this. (diagnostic_context::initialize): Move code to... (diagnostic_option_classifier::init): ...this new function. (diagnostic_context::finish): Move code to... (diagnostic_option_classifier::fini): ...this new function. (diagnostic_context::classify_diagnostic): Convert to... (diagnostic_option_classifier::classify_diagnostic): ...this. (diagnostic_context::update_effective_level_from_pragmas): Convert to... (diagnostic_option_classifier::update_effective_level_from_pragmas): ...this. (diagnostic_context::diagnostic_enabled): Update for refactoring. * diagnostic.h (struct diagnostic_classification_change_t): Move into... (class diagnostic_option_classifier): ...this new class. (diagnostic_context::option_unspecified_p): Update for move of fields into m_option_classifier. (diagnostic_context::classify_diagnostic): Likewise. (diagnostic_context::push_diagnostics): Likewise. (diagnostic_context::pop_diagnostics): Likewise. (diagnostic_context::update_effective_level_from_pragmas): Delete. (diagnostic_context::m_classify_diagnostic): Move into class diagnostic_option_classifier. (diagnostic_context::m_option_classifier): Likewise. (diagnostic_context::m_classification_history): Likewise. (diagnostic_context::m_n_classification_history): Likewise. (diagnostic_context::m_push_list): Likewise. (diagnostic_context::m_n_push): Likewise. (diagnostic_context::m_option_classifier): New. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
This commit is contained in:
parent
a526cc6ff3
commit
38763e2c18
2 changed files with 163 additions and 92 deletions
|
@ -149,13 +149,63 @@ diagnostic_set_caret_max_width (diagnostic_context *context, int value)
|
|||
context->m_source_printing.max_width = value;
|
||||
}
|
||||
|
||||
void
|
||||
diagnostic_option_classifier::init (int n_opts)
|
||||
{
|
||||
m_n_opts = n_opts;
|
||||
m_classify_diagnostic = XNEWVEC (diagnostic_t, n_opts);
|
||||
for (int i = 0; i < n_opts; i++)
|
||||
m_classify_diagnostic[i] = DK_UNSPECIFIED;
|
||||
m_push_list = nullptr;
|
||||
m_n_push = 0;
|
||||
}
|
||||
|
||||
void
|
||||
diagnostic_option_classifier::fini ()
|
||||
{
|
||||
XDELETEVEC (m_classify_diagnostic);
|
||||
m_classify_diagnostic = nullptr;
|
||||
free (m_push_list);
|
||||
m_n_push = 0;
|
||||
}
|
||||
|
||||
/* Save all diagnostic classifications in a stack. */
|
||||
|
||||
void
|
||||
diagnostic_option_classifier::push ()
|
||||
{
|
||||
m_push_list = (int *) xrealloc (m_push_list, (m_n_push + 1) * sizeof (int));
|
||||
m_push_list[m_n_push ++] = m_n_classification_history;
|
||||
}
|
||||
|
||||
/* Restore the topmost classification set off the stack. If the stack
|
||||
is empty, revert to the state based on command line parameters. */
|
||||
|
||||
void
|
||||
diagnostic_option_classifier::pop (location_t where)
|
||||
{
|
||||
int jump_to;
|
||||
|
||||
if (m_n_push)
|
||||
jump_to = m_push_list [-- m_n_push];
|
||||
else
|
||||
jump_to = 0;
|
||||
|
||||
const int i = m_n_classification_history;
|
||||
m_classification_history =
|
||||
(diagnostic_classification_change_t *) xrealloc (m_classification_history, (i + 1)
|
||||
* sizeof (diagnostic_classification_change_t));
|
||||
m_classification_history[i].location = where;
|
||||
m_classification_history[i].option = jump_to;
|
||||
m_classification_history[i].kind = DK_POP;
|
||||
m_n_classification_history ++;
|
||||
}
|
||||
|
||||
/* Initialize the diagnostic message outputting machinery. */
|
||||
|
||||
void
|
||||
diagnostic_context::initialize (int n_opts)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Allocate a basic pretty-printer. Clients will replace this a
|
||||
much more elaborated pretty-printer if they wish. */
|
||||
this->printer = XNEW (pretty_printer);
|
||||
|
@ -165,12 +215,10 @@ diagnostic_context::initialize (int n_opts)
|
|||
memset (m_diagnostic_count, 0, sizeof m_diagnostic_count);
|
||||
m_warning_as_error_requested = false;
|
||||
m_n_opts = n_opts;
|
||||
m_classify_diagnostic = XNEWVEC (diagnostic_t, n_opts);
|
||||
for (i = 0; i < n_opts; i++)
|
||||
m_classify_diagnostic[i] = DK_UNSPECIFIED;
|
||||
m_option_classifier.init (n_opts);
|
||||
m_source_printing.enabled = false;
|
||||
diagnostic_set_caret_max_width (this, pp_line_cutoff (this->printer));
|
||||
for (i = 0; i < rich_location::STATICALLY_ALLOCATED_RANGES; i++)
|
||||
for (int i = 0; i < rich_location::STATICALLY_ALLOCATED_RANGES; i++)
|
||||
m_source_printing.caret_chars[i] = '^';
|
||||
m_show_cwe = false;
|
||||
m_show_rules = false;
|
||||
|
@ -326,8 +374,7 @@ diagnostic_context::finish ()
|
|||
delete m_file_cache;
|
||||
m_file_cache = nullptr;
|
||||
|
||||
XDELETEVEC (m_classify_diagnostic);
|
||||
m_classify_diagnostic = nullptr;
|
||||
m_option_classifier.fini ();
|
||||
|
||||
/* diagnostic_context::initialize allocates this->printer using XNEW
|
||||
and placement-new. */
|
||||
|
@ -1052,9 +1099,11 @@ default_diagnostic_finalizer (diagnostic_context *context,
|
|||
range. If OPTION_INDEX is zero, the new setting is for all the
|
||||
diagnostics. */
|
||||
diagnostic_t
|
||||
diagnostic_context::classify_diagnostic (int option_index,
|
||||
diagnostic_t new_kind,
|
||||
location_t where)
|
||||
diagnostic_option_classifier::
|
||||
classify_diagnostic (const diagnostic_context *context,
|
||||
int option_index,
|
||||
diagnostic_t new_kind,
|
||||
location_t where)
|
||||
{
|
||||
diagnostic_t old_kind;
|
||||
|
||||
|
@ -1074,10 +1123,10 @@ diagnostic_context::classify_diagnostic (int option_index,
|
|||
/* Record the command-line status, so we can reset it back on DK_POP. */
|
||||
if (old_kind == DK_UNSPECIFIED)
|
||||
{
|
||||
old_kind = !m_option_enabled (option_index,
|
||||
m_lang_mask,
|
||||
m_option_state)
|
||||
? DK_IGNORED : (m_warning_as_error_requested
|
||||
old_kind = !context->m_option_enabled (option_index,
|
||||
context->m_lang_mask,
|
||||
context->m_option_state)
|
||||
? DK_IGNORED : (context->warning_as_error_requested_p ()
|
||||
? DK_ERROR : DK_WARNING);
|
||||
m_classify_diagnostic[option_index] = old_kind;
|
||||
}
|
||||
|
@ -1104,37 +1153,6 @@ diagnostic_context::classify_diagnostic (int option_index,
|
|||
return old_kind;
|
||||
}
|
||||
|
||||
/* Save all diagnostic classifications in a stack. */
|
||||
void
|
||||
diagnostic_context::push_diagnostics (location_t where ATTRIBUTE_UNUSED)
|
||||
{
|
||||
m_push_list = (int *) xrealloc (m_push_list, (m_n_push + 1) * sizeof (int));
|
||||
m_push_list[m_n_push ++] = m_n_classification_history;
|
||||
}
|
||||
|
||||
/* Restore the topmost classification set off the stack. If the stack
|
||||
is empty, revert to the state based on command line parameters. */
|
||||
void
|
||||
diagnostic_context::pop_diagnostics (location_t where)
|
||||
{
|
||||
int jump_to;
|
||||
int i;
|
||||
|
||||
if (m_n_push)
|
||||
jump_to = m_push_list [-- m_n_push];
|
||||
else
|
||||
jump_to = 0;
|
||||
|
||||
i = m_n_classification_history;
|
||||
m_classification_history =
|
||||
(diagnostic_classification_change_t *) xrealloc (m_classification_history, (i + 1)
|
||||
* sizeof (diagnostic_classification_change_t));
|
||||
m_classification_history[i].location = where;
|
||||
m_classification_history[i].option = jump_to;
|
||||
m_classification_history[i].kind = DK_POP;
|
||||
m_n_classification_history ++;
|
||||
}
|
||||
|
||||
/* Helper function for print_parseable_fixits. Print TEXT to PP, obeying the
|
||||
escaping rules for -fdiagnostics-parseable-fixits. */
|
||||
|
||||
|
@ -1246,14 +1264,14 @@ diagnostic_context::get_any_inlining_info (diagnostic_info *diagnostic)
|
|||
/* Update the kind of DIAGNOSTIC based on its location(s), including
|
||||
any of those in its inlining stack, relative to any
|
||||
#pragma GCC diagnostic
|
||||
directives recorded within CONTEXT.
|
||||
directives recorded within this object.
|
||||
|
||||
Return the new kind of DIAGNOSTIC if it was updated, or DK_UNSPECIFIED
|
||||
otherwise. */
|
||||
|
||||
diagnostic_t
|
||||
diagnostic_context::
|
||||
update_effective_level_from_pragmas (diagnostic_info *diagnostic)
|
||||
diagnostic_option_classifier::
|
||||
update_effective_level_from_pragmas (diagnostic_info *diagnostic) const
|
||||
{
|
||||
if (m_n_classification_history <= 0)
|
||||
return DK_UNSPECIFIED;
|
||||
|
@ -1444,14 +1462,14 @@ diagnostic_context::diagnostic_enabled (diagnostic_info *diagnostic)
|
|||
return false;
|
||||
|
||||
/* This tests for #pragma diagnostic changes. */
|
||||
diagnostic_t diag_class = update_effective_level_from_pragmas (diagnostic);
|
||||
diagnostic_t diag_class
|
||||
= m_option_classifier.update_effective_level_from_pragmas (diagnostic);
|
||||
|
||||
/* This tests if the user provided the appropriate -Werror=foo
|
||||
option. */
|
||||
if (diag_class == DK_UNSPECIFIED
|
||||
&& (m_classify_diagnostic[diagnostic->option_index]
|
||||
!= DK_UNSPECIFIED))
|
||||
diagnostic->kind = m_classify_diagnostic[diagnostic->option_index];
|
||||
&& !option_unspecified_p (diagnostic->option_index))
|
||||
diagnostic->kind = m_option_classifier.get_current_override (diagnostic->option_index);
|
||||
|
||||
/* This allows for future extensions, like temporarily disabling
|
||||
warnings for ranges of source code. */
|
||||
|
|
131
gcc/diagnostic.h
131
gcc/diagnostic.h
|
@ -168,16 +168,6 @@ struct diagnostic_info
|
|||
} m_iinfo;
|
||||
};
|
||||
|
||||
/* Each time a diagnostic's classification is changed with a pragma,
|
||||
we record the change and the location of the change in an array of
|
||||
these structs. */
|
||||
struct diagnostic_classification_change_t
|
||||
{
|
||||
location_t location;
|
||||
int option;
|
||||
diagnostic_t kind;
|
||||
};
|
||||
|
||||
/* Forward declarations. */
|
||||
typedef void (*diagnostic_starter_fn) (diagnostic_context *,
|
||||
diagnostic_info *);
|
||||
|
@ -240,6 +230,79 @@ public:
|
|||
void on_diagram (const diagnostic_diagram &diagram) override;
|
||||
};
|
||||
|
||||
/* A stack of sets of classifications: each entry in the stack is
|
||||
a mapping from option index to diagnostic severity that can be changed
|
||||
via pragmas. The stack can be pushed and popped. */
|
||||
|
||||
class diagnostic_option_classifier
|
||||
{
|
||||
public:
|
||||
void init (int n_opts);
|
||||
void fini ();
|
||||
|
||||
/* Save all diagnostic classifications in a stack. */
|
||||
void push ();
|
||||
|
||||
/* Restore the topmost classification set off the stack. If the stack
|
||||
is empty, revert to the state based on command line parameters. */
|
||||
void pop (location_t where);
|
||||
|
||||
bool option_unspecified_p (int opt) const
|
||||
{
|
||||
return get_current_override (opt) == DK_UNSPECIFIED;
|
||||
}
|
||||
|
||||
diagnostic_t get_current_override (int opt) const
|
||||
{
|
||||
gcc_assert (opt < m_n_opts);
|
||||
return m_classify_diagnostic[opt];
|
||||
}
|
||||
|
||||
diagnostic_t
|
||||
classify_diagnostic (const diagnostic_context *context,
|
||||
int option_index,
|
||||
diagnostic_t new_kind,
|
||||
location_t where);
|
||||
|
||||
diagnostic_t
|
||||
update_effective_level_from_pragmas (diagnostic_info *diagnostic) const;
|
||||
|
||||
private:
|
||||
/* Each time a diagnostic's classification is changed with a pragma,
|
||||
we record the change and the location of the change in an array of
|
||||
these structs. */
|
||||
struct diagnostic_classification_change_t
|
||||
{
|
||||
location_t location;
|
||||
int option;
|
||||
diagnostic_t kind;
|
||||
};
|
||||
|
||||
int m_n_opts;
|
||||
|
||||
/* For each option index that can be passed to warning() et al
|
||||
(OPT_* from options.h when using this code with the core GCC
|
||||
options), this array may contain a new kind that the diagnostic
|
||||
should be changed to before reporting, or DK_UNSPECIFIED to leave
|
||||
it as the reported kind, or DK_IGNORED to not report it at
|
||||
all. */
|
||||
diagnostic_t *m_classify_diagnostic;
|
||||
|
||||
/* History of all changes to the classifications above. This list
|
||||
is stored in location-order, so we can search it, either
|
||||
binary-wise or end-to-front, to find the most recent
|
||||
classification for a given diagnostic, given the location of the
|
||||
diagnostic. */
|
||||
diagnostic_classification_change_t *m_classification_history;
|
||||
|
||||
/* The size of the above array. */
|
||||
int m_n_classification_history;
|
||||
|
||||
/* For pragma push/pop. */
|
||||
int *m_push_list;
|
||||
int m_n_push;
|
||||
};
|
||||
|
||||
/* This data structure bundles altogether any information relevant to
|
||||
the context of a diagnostic message. */
|
||||
class diagnostic_context
|
||||
|
@ -273,8 +336,7 @@ public:
|
|||
|
||||
bool option_unspecified_p (int opt) const
|
||||
{
|
||||
gcc_assert (opt < m_n_opts);
|
||||
return m_classify_diagnostic[opt] == DK_UNSPECIFIED;
|
||||
return m_option_classifier.option_unspecified_p (opt);
|
||||
}
|
||||
|
||||
bool report_diagnostic (diagnostic_info *);
|
||||
|
@ -287,9 +349,22 @@ public:
|
|||
diagnostic_t
|
||||
classify_diagnostic (int option_index,
|
||||
diagnostic_t new_kind,
|
||||
location_t where);
|
||||
void push_diagnostics (location_t where ATTRIBUTE_UNUSED);
|
||||
void pop_diagnostics (location_t where);
|
||||
location_t where)
|
||||
{
|
||||
return m_option_classifier.classify_diagnostic (this,
|
||||
option_index,
|
||||
new_kind,
|
||||
where);
|
||||
}
|
||||
|
||||
void push_diagnostics (location_t where ATTRIBUTE_UNUSED)
|
||||
{
|
||||
m_option_classifier.push ();
|
||||
}
|
||||
void pop_diagnostics (location_t where)
|
||||
{
|
||||
m_option_classifier.pop (where);
|
||||
}
|
||||
|
||||
void emit_diagram (const diagnostic_diagram &diagram);
|
||||
|
||||
|
@ -376,9 +451,6 @@ private:
|
|||
bool diagnostic_enabled (diagnostic_info *diagnostic);
|
||||
|
||||
void get_any_inlining_info (diagnostic_info *diagnostic);
|
||||
diagnostic_t
|
||||
update_effective_level_from_pragmas (diagnostic_info *diagnostic);
|
||||
|
||||
|
||||
/* Data members.
|
||||
Ideally, all of these would be private and have "m_" prefixes. */
|
||||
|
@ -401,27 +473,8 @@ private:
|
|||
al. */
|
||||
int m_n_opts;
|
||||
|
||||
/* For each option index that can be passed to warning() et al
|
||||
(OPT_* from options.h when using this code with the core GCC
|
||||
options), this array may contain a new kind that the diagnostic
|
||||
should be changed to before reporting, or DK_UNSPECIFIED to leave
|
||||
it as the reported kind, or DK_IGNORED to not report it at
|
||||
all. */
|
||||
diagnostic_t *m_classify_diagnostic;
|
||||
|
||||
/* History of all changes to the classifications above. This list
|
||||
is stored in location-order, so we can search it, either
|
||||
binary-wise or end-to-front, to find the most recent
|
||||
classification for a given diagnostic, given the location of the
|
||||
diagnostic. */
|
||||
diagnostic_classification_change_t *m_classification_history;
|
||||
|
||||
/* The size of the above array. */
|
||||
int m_n_classification_history;
|
||||
|
||||
/* For pragma push/pop. */
|
||||
int *m_push_list;
|
||||
int m_n_push;
|
||||
/* The stack of sets of overridden diagnostic option severities. */
|
||||
diagnostic_option_classifier m_option_classifier;
|
||||
|
||||
/* True if we should print any CWE identifiers associated with
|
||||
diagnostics. */
|
||||
|
|
Loading…
Add table
Reference in a new issue