move handling of -pedantic and -pedantic-errors into Diagnostics,
out of Warnings.cpp. This simplifies warnings.cpp and makes it more efficient. llvm-svn: 69266
This commit is contained in:
parent
f9150bac01
commit
b8e73158e1
|
@ -67,14 +67,9 @@ namespace clang {
|
|||
MAP_ERROR = 3, //< Map this diagnostic to an error.
|
||||
MAP_FATAL = 4, //< Map this diagnostic to a fatal error.
|
||||
|
||||
/// Map this diagnostic to "warning", but make it immune to
|
||||
/// -pedantic-errors. This happens when you specify -Wfoo for an
|
||||
/// extension warning.
|
||||
MAP_WARNING_NO_PEDANTIC_ERROR = 5,
|
||||
|
||||
/// Map this diagnostic to "warning", but make it immune to -Werror and
|
||||
/// -pedantic-errors. This happens when you specify -Wno-error=foo.
|
||||
MAP_WARNING_NO_WERROR = 6
|
||||
/// Map this diagnostic to "warning", but make it immune to -Werror. This
|
||||
/// happens when you specify -Wno-error=foo.
|
||||
MAP_WARNING_NO_WERROR = 5
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -145,6 +140,12 @@ public:
|
|||
Ignored, Note, Warning, Error, Fatal
|
||||
};
|
||||
|
||||
/// ExtensionHandling - How do we handle otherwise-unmapped extension? This
|
||||
/// is controlled by -pedantic and -pedantic-errors.
|
||||
enum ExtensionHandling {
|
||||
Ext_Ignore, Ext_Warn, Ext_Error
|
||||
};
|
||||
|
||||
enum ArgumentKind {
|
||||
ak_std_string, // std::string
|
||||
ak_c_string, // const char *
|
||||
|
@ -158,9 +159,10 @@ public:
|
|||
|
||||
private:
|
||||
unsigned char AllExtensionsSilenced; // Used by __extension__
|
||||
bool IgnoreAllWarnings; // Ignore all warnings: -w
|
||||
bool WarningsAsErrors; // Treat warnings like errors:
|
||||
bool SuppressSystemWarnings;// Suppress warnings in system headers.
|
||||
bool IgnoreAllWarnings; // Ignore all warnings: -w
|
||||
bool WarningsAsErrors; // Treat warnings like errors:
|
||||
bool SuppressSystemWarnings; // Suppress warnings in system headers.
|
||||
ExtensionHandling ExtBehavior; // Map extensions onto warnings or errors?
|
||||
DiagnosticClient *Client;
|
||||
|
||||
/// DiagMappings - Mapping information for diagnostics. Mapping info is
|
||||
|
@ -226,6 +228,13 @@ public:
|
|||
void setSuppressSystemWarnings(bool Val) { SuppressSystemWarnings = Val; }
|
||||
bool getSuppressSystemWarnings() const { return SuppressSystemWarnings; }
|
||||
|
||||
/// setExtensionHandlingBehavior - This controls whether otherwise-unmapped
|
||||
/// extension diagnostics are mapped onto ignore/warning/error. This
|
||||
/// corresponds to the GCC -pedantic and -pedantic-errors option.
|
||||
void setExtensionHandlingBehavior(ExtensionHandling H) {
|
||||
ExtBehavior = H;
|
||||
}
|
||||
|
||||
/// AllExtensionsSilenced - This is a counter bumped when an __extension__
|
||||
/// block is encountered. When non-zero, all extension diagnostics are
|
||||
/// entirely silenced, no matter how they are mapped.
|
||||
|
|
|
@ -262,6 +262,7 @@ Diagnostic::Diagnostic(DiagnosticClient *client) : Client(client) {
|
|||
IgnoreAllWarnings = false;
|
||||
WarningsAsErrors = false;
|
||||
SuppressSystemWarnings = false;
|
||||
ExtBehavior = Ext_Ignore;
|
||||
|
||||
ErrorOccurred = false;
|
||||
FatalErrorOccurred = false;
|
||||
|
@ -371,7 +372,15 @@ Diagnostic::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass) const {
|
|||
switch (MappingInfo & 7) {
|
||||
default: assert(0 && "Unknown mapping!");
|
||||
case diag::MAP_IGNORE:
|
||||
return Diagnostic::Ignored;
|
||||
// Ignore this, unless this is an extension diagnostic and we're mapping
|
||||
// them onto warnings or errors.
|
||||
if (!isBuiltinExtensionDiag(DiagID) || // Not an extension
|
||||
ExtBehavior == Ext_Ignore || // Extensions ignored anyway
|
||||
(MappingInfo & 8) != 0) // User explicitly mapped it.
|
||||
return Diagnostic::Ignored;
|
||||
Result = Diagnostic::Warning;
|
||||
if (ExtBehavior == Ext_Error) Result = Diagnostic::Error;
|
||||
break;
|
||||
case diag::MAP_ERROR:
|
||||
Result = Diagnostic::Error;
|
||||
break;
|
||||
|
@ -384,9 +393,18 @@ Diagnostic::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass) const {
|
|||
return Diagnostic::Ignored;
|
||||
|
||||
Result = Diagnostic::Warning;
|
||||
|
||||
// If this is an extension diagnostic and we're in -pedantic-error mode, and
|
||||
// if the user didn't explicitly map it, upgrade to an error.
|
||||
if (ExtBehavior == Ext_Error &&
|
||||
(MappingInfo & 8) == 0 &&
|
||||
isBuiltinExtensionDiag(DiagID))
|
||||
Result = Diagnostic::Error;
|
||||
|
||||
if (WarningsAsErrors)
|
||||
Result = Diagnostic::Error;
|
||||
break;
|
||||
|
||||
case diag::MAP_WARNING_NO_WERROR:
|
||||
// Diagnostics specified with -Wno-error=foo should be set to warnings, but
|
||||
// not be adjusted by -Werror or -pedantic-errors.
|
||||
|
@ -634,8 +652,7 @@ static bool EvalPluralExpr(unsigned ValNo, const char *Start, const char *End) {
|
|||
/// {1:form0|%100=[10,20]:form2|%10=[2,4]:form1|:form2}
|
||||
static void HandlePluralModifier(unsigned ValNo,
|
||||
const char *Argument, unsigned ArgumentLen,
|
||||
llvm::SmallVectorImpl<char> &OutStr)
|
||||
{
|
||||
llvm::SmallVectorImpl<char> &OutStr) {
|
||||
const char *ArgumentEnd = Argument + ArgumentLen;
|
||||
while (1) {
|
||||
assert(Argument < ArgumentEnd && "Plural expression didn't match.");
|
||||
|
|
|
@ -65,21 +65,17 @@ static bool WarningOptionCompare(const WarningOption &LHS,
|
|||
}
|
||||
|
||||
static void MapGroupMembers(const WarningOption *Group, diag::Mapping Mapping,
|
||||
Diagnostic &Diags,
|
||||
llvm::SmallVectorImpl<unsigned short> &ControlledDiags) {
|
||||
Diagnostic &Diags) {
|
||||
// Option exists, poke all the members of its diagnostic set.
|
||||
if (const short *Member = Group->Members) {
|
||||
for (; *Member != -1; ++Member) {
|
||||
for (; *Member != -1; ++Member)
|
||||
Diags.setDiagnosticMapping(*Member, Mapping);
|
||||
ControlledDiags.push_back(*Member);
|
||||
}
|
||||
}
|
||||
|
||||
// Enable/disable all subgroups along with this one.
|
||||
if (const char *SubGroups = Group->SubGroups) {
|
||||
for (; *SubGroups != (char)-1; ++SubGroups)
|
||||
MapGroupMembers(&OptionTable[(unsigned char)*SubGroups], Mapping,
|
||||
Diags, ControlledDiags);
|
||||
MapGroupMembers(&OptionTable[(unsigned char)*SubGroups], Mapping, Diags);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,13 +83,19 @@ bool clang::ProcessWarningOptions(Diagnostic &Diags) {
|
|||
Diags.setSuppressSystemWarnings(true); // Default to -Wno-system-headers
|
||||
Diags.setIgnoreAllWarnings(OptNoWarnings);
|
||||
|
||||
// If -pedantic or -pedantic-errors was specified, then we want to map all
|
||||
// extension diagnostics onto WARNING or ERROR unless the user has futz'd
|
||||
// around with them explicitly.
|
||||
if (OptPedanticErrors)
|
||||
Diags.setExtensionHandlingBehavior(Diagnostic::Ext_Error);
|
||||
else if (OptPedantic)
|
||||
Diags.setExtensionHandlingBehavior(Diagnostic::Ext_Warn);
|
||||
else
|
||||
Diags.setExtensionHandlingBehavior(Diagnostic::Ext_Ignore);
|
||||
|
||||
// FIXME: -fdiagnostics-show-option
|
||||
// FIXME: -Wfatal-errors / -Wfatal-errors=foo
|
||||
|
||||
/// ControlledDiags - Keep track of the options that the user explicitly
|
||||
/// poked with -Wfoo, -Wno-foo, or -Werror=foo.
|
||||
llvm::SmallVector<unsigned short, 256> ControlledDiags;
|
||||
|
||||
for (unsigned i = 0, e = OptWarnings.size(); i != e; ++i) {
|
||||
const std::string &Opt = OptWarnings[i];
|
||||
const char *OptStart = &Opt[0];
|
||||
|
@ -152,47 +154,7 @@ bool clang::ProcessWarningOptions(Diagnostic &Diags) {
|
|||
continue;
|
||||
}
|
||||
|
||||
MapGroupMembers(Found, Mapping, Diags, ControlledDiags);
|
||||
}
|
||||
|
||||
// If -pedantic or -pedantic-errors was specified, then we want to map all
|
||||
// extension diagnostics onto WARNING or ERROR unless the user has futz'd
|
||||
// around with them explicitly.
|
||||
if (OptPedantic || OptPedanticErrors) {
|
||||
// Sort the array of options that has been poked at directly so we can do
|
||||
// efficient queries.
|
||||
std::sort(ControlledDiags.begin(), ControlledDiags.end());
|
||||
|
||||
// Don't worry about iteration off the end down below.
|
||||
ControlledDiags.push_back(diag::DIAG_UPPER_LIMIT);
|
||||
|
||||
diag::Mapping Mapping =
|
||||
OptPedanticErrors ? diag::MAP_ERROR : diag::MAP_WARNING;
|
||||
|
||||
// Loop over all of the extension diagnostics. Unless they were explicitly
|
||||
// controlled, reset their mapping to Mapping. We walk through the
|
||||
// ControlledDiags in parallel with this walk, which is faster than
|
||||
// repeatedly binary searching it.
|
||||
//
|
||||
llvm::SmallVectorImpl<unsigned short>::iterator ControlledDiagsIt =
|
||||
ControlledDiags.begin();
|
||||
|
||||
// TODO: if it matters, we could make tblgen produce a list of just the
|
||||
// extension diags to avoid skipping ones that don't matter.
|
||||
for (unsigned short i = 0; i != diag::DIAG_UPPER_LIMIT; ++i) {
|
||||
// If this diagnostic was controlled, ignore it.
|
||||
if (i == *ControlledDiagsIt) {
|
||||
++ControlledDiagsIt;
|
||||
while (i == *ControlledDiagsIt) // ControlledDiags can have dupes.
|
||||
++ControlledDiagsIt;
|
||||
// Do not map this diagnostic ID#.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Okay, the user didn't control this ID. If it is an example, map it.
|
||||
if (Diagnostic::isBuiltinExtensionDiag(i))
|
||||
Diags.setDiagnosticMapping(i, Mapping);
|
||||
}
|
||||
MapGroupMembers(Found, Mapping, Diags);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
Loading…
Reference in New Issue