forked from OSchip/llvm-project
[clang][diagnostics] Add '-Wundef-prefix' warning option
Summary: Add an `-Wundef-prefix=<arg1>,<arg2>...` option, which is similar to `-Wundef`, but only give warnings for undefined macros with the given prefixes. Reviewers: ributzka, steven_wu, cishida, bruno, arphaman, rsmith Reviewed By: ributzka, arphaman Subscribers: riccibruno, dexonsmith, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D80751 This patch was authored by Zixu Wang <zixu_wang@apple.com>
This commit is contained in:
parent
ecae672ac2
commit
89a0c4066b
|
@ -312,6 +312,9 @@ def pp_macro_not_used : Warning<"macro is not used">, DefaultIgnore,
|
|||
def warn_pp_undef_identifier : Warning<
|
||||
"%0 is not defined, evaluates to 0">,
|
||||
InGroup<DiagGroup<"undef">>, DefaultIgnore;
|
||||
def warn_pp_undef_prefix : Warning<
|
||||
"%0 is not defined, evaluates to 0">,
|
||||
InGroup<DiagGroup<"undef-prefix">>, DefaultIgnore;
|
||||
def warn_pp_ambiguous_macro : Warning<
|
||||
"ambiguous expansion of macro %0">, InGroup<AmbiguousMacro>;
|
||||
def note_pp_ambiguous_macro_chosen : Note<
|
||||
|
|
|
@ -98,6 +98,10 @@ public:
|
|||
/// prefixes removed.
|
||||
std::vector<std::string> Warnings;
|
||||
|
||||
/// The list of prefixes from -Wundef-prefix=... used to generate warnings
|
||||
/// for undefined macros.
|
||||
std::vector<std::string> UndefPrefixes;
|
||||
|
||||
/// The list of -R... options used to alter the diagnostic mappings, with the
|
||||
/// prefixes removed.
|
||||
std::vector<std::string> Remarks;
|
||||
|
|
|
@ -483,6 +483,9 @@ def Wnonportable_cfstrings : Joined<["-"], "Wnonportable-cfstrings">, Group<W_Gr
|
|||
def Wp_COMMA : CommaJoined<["-"], "Wp,">,
|
||||
HelpText<"Pass the comma separated arguments in <arg> to the preprocessor">,
|
||||
MetaVarName<"<arg>">, Group<Preprocessor_Group>;
|
||||
def Wundef_prefix_EQ : CommaJoined<["-"], "Wundef-prefix=">, Group<W_value_Group>,
|
||||
Flags<[CC1Option, CoreOption, HelpHidden]>, MetaVarName<"<arg>">,
|
||||
HelpText<"Enable warnings for undefined macros with a prefix in the comma separated list <arg>">;
|
||||
def Wwrite_strings : Flag<["-"], "Wwrite-strings">, Group<W_Group>, Flags<[CC1Option, HelpHidden]>;
|
||||
def Wno_write_strings : Flag<["-"], "Wno-write-strings">, Group<W_Group>, Flags<[CC1Option, HelpHidden]>;
|
||||
def W_Joined : Joined<["-"], "W">, Group<W_Group>, Flags<[CC1Option, CoreOption]>,
|
||||
|
|
|
@ -1688,6 +1688,9 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
|
|||
}
|
||||
Opts.MessageLength =
|
||||
getLastArgIntValue(Args, OPT_fmessage_length_EQ, 0, Diags);
|
||||
|
||||
Opts.UndefPrefixes = Args.getAllArgValues(OPT_Wundef_prefix_EQ);
|
||||
|
||||
addDiagnosticArgs(Args, OPT_W_Group, OPT_W_value_Group, Opts.Warnings);
|
||||
addDiagnosticArgs(Args, OPT_R_Group, OPT_R_value_Group, Opts.Remarks);
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Lex/Preprocessor.h"
|
||||
#include "clang/Basic/IdentifierTable.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
|
@ -26,9 +25,12 @@
|
|||
#include "clang/Lex/LiteralSupport.h"
|
||||
#include "clang/Lex/MacroInfo.h"
|
||||
#include "clang/Lex/PPCallbacks.h"
|
||||
#include "clang/Lex/Preprocessor.h"
|
||||
#include "clang/Lex/Token.h"
|
||||
#include "llvm/ADT/APSInt.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/SaveAndRestore.h"
|
||||
|
@ -251,8 +253,24 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
|
|||
// If this identifier isn't 'defined' or one of the special
|
||||
// preprocessor keywords and it wasn't macro expanded, it turns
|
||||
// into a simple 0
|
||||
if (ValueLive)
|
||||
if (ValueLive) {
|
||||
PP.Diag(PeekTok, diag::warn_pp_undef_identifier) << II;
|
||||
|
||||
const DiagnosticsEngine &DiagEngine = PP.getDiagnostics();
|
||||
// If 'Wundef' is enabled, do not emit 'undef-prefix' diagnostics.
|
||||
if (DiagEngine.isIgnored(diag::warn_pp_undef_identifier,
|
||||
PeekTok.getLocation())) {
|
||||
const std::vector<std::string> UndefPrefixes =
|
||||
DiagEngine.getDiagnosticOptions().UndefPrefixes;
|
||||
const StringRef IdentifierName = II->getName();
|
||||
if (llvm::any_of(UndefPrefixes,
|
||||
[&IdentifierName](const std::string &Prefix) {
|
||||
return IdentifierName.startswith(Prefix);
|
||||
}))
|
||||
PP.Diag(PeekTok, diag::warn_pp_undef_prefix)
|
||||
<< AddFlagValue{llvm::join(UndefPrefixes, ",")} << II;
|
||||
}
|
||||
}
|
||||
Result.Val = 0;
|
||||
Result.Val.setIsUnsigned(false); // "0" is signed intmax_t 0.
|
||||
Result.setIdentifier(II);
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
// RUN: %clang_cc1 %s -Eonly -Wundef -verify=undef
|
||||
// RUN: %clang_cc1 %s -Eonly -Wundef-prefix=A,BC -verify=undef-prefix
|
||||
// RUN: %clang_cc1 %s -Eonly -Wundef -Wundef-prefix=A,BC -verify=both
|
||||
// RUN: %clang_cc1 %s -Eonly -Werror=undef -verify=undef-error
|
||||
// RUN: %clang_cc1 %s -Eonly -Werror=undef-prefix -Wundef-prefix=A,BC -verify=undef-prefix-error
|
||||
// RUN: %clang_cc1 %s -Eonly -Werror=undef -Wundef-prefix=A,BC -verify=both-error
|
||||
|
||||
extern int x;
|
||||
|
||||
#if AB // #1
|
||||
#endif
|
||||
// undef-warning@#1 {{'AB' is not defined, evaluates to 0}}
|
||||
// undef-prefix-warning@#1 {{'AB' is not defined, evaluates to 0}}
|
||||
// both-warning@#1 {{'AB' is not defined, evaluates to 0}}
|
||||
// undef-error-error@#1 {{'AB' is not defined, evaluates to 0}}
|
||||
// undef-prefix-error-error@#1 {{'AB' is not defined, evaluates to 0}}
|
||||
// both-error-error@#1 {{'AB' is not defined, evaluates to 0}}
|
||||
|
||||
#if B // #2
|
||||
#endif
|
||||
// undef-warning@#2 {{'B' is not defined, evaluates to 0}}
|
||||
// no warning for undef-prefix
|
||||
// both-warning@#2 {{'B' is not defined, evaluates to 0}}
|
||||
// undef-error-error@#2 {{'B' is not defined, evaluates to 0}}
|
||||
// no error for undef-prefix
|
||||
// both-error-error@#2 {{'B' is not defined, evaluates to 0}}
|
||||
|
||||
#define BC 0
|
||||
#if BC // no warning/error
|
||||
#endif
|
||||
|
||||
#undef BC
|
||||
#if BC // #3
|
||||
#endif
|
||||
// undef-warning@#3 {{'BC' is not defined, evaluates to 0}}
|
||||
// undef-prefix-warning@#3 {{'BC' is not defined, evaluates to 0}}
|
||||
// both-warning@#3 {{'BC' is not defined, evaluates to 0}}
|
||||
// undef-error-error@#3 {{'BC' is not defined, evaluates to 0}}
|
||||
// undef-prefix-error-error@#3 {{'BC' is not defined, evaluates to 0}}
|
||||
// both-error-error@#3 {{'BC' is not defined, evaluates to 0}}
|
||||
|
||||
// Test that #pragma-enabled 'Wundef' can override 'Wundef-prefix'
|
||||
#pragma clang diagnostic error "-Wundef"
|
||||
|
||||
#if C // #4
|
||||
#endif
|
||||
// undef-error@#4 {{'C' is not defined, evaluates to 0}}
|
||||
// undef-prefix-error@#4 {{'C' is not defined, evaluates to 0}}
|
||||
// both-error@#4 {{'C' is not defined, evaluates to 0}}
|
||||
// undef-error-error@#4 {{'C' is not defined, evaluates to 0}}
|
||||
// undef-prefix-error-error@#4 {{'C' is not defined, evaluates to 0}}
|
||||
// both-error-error@#4 {{'C' is not defined, evaluates to 0}}
|
Loading…
Reference in New Issue