Index: clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h =================================================================== --- clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h +++ clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h @@ -94,7 +94,8 @@ SrcMgr::CharacteristicKind) override; void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *, SourceLocation StateLoc, unsigned) override; - void PragmaWarning(SourceLocation Loc, StringRef, ArrayRef) override; + void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier, + ArrayRef) override; void PragmaWarningPush(SourceLocation Loc, int) override; void PragmaWarningPop(SourceLocation Loc) override; void PragmaAssumeNonNullBegin(SourceLocation Loc) override; Index: clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp =================================================================== --- clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp +++ clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp @@ -234,7 +234,8 @@ parseToLocation(NameLoc); } void ExpandModularHeadersPPCallbacks::PragmaWarning(SourceLocation Loc, - StringRef, ArrayRef) { + PragmaWarningSpecifier, + ArrayRef) { parseToLocation(Loc); } void ExpandModularHeadersPPCallbacks::PragmaWarningPush(SourceLocation Loc, Index: clang-tools-extra/pp-trace/PPCallbacksTracker.h =================================================================== --- clang-tools-extra/pp-trace/PPCallbacksTracker.h +++ clang-tools-extra/pp-trace/PPCallbacksTracker.h @@ -121,7 +121,7 @@ diag::Severity mapping, llvm::StringRef Str) override; void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name, SourceLocation StateLoc, unsigned State) override; - void PragmaWarning(SourceLocation Loc, llvm::StringRef WarningSpec, + void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier WarningSpec, llvm::ArrayRef Ids) override; void PragmaWarningPush(SourceLocation Loc, int Level) override; void PragmaWarningPop(SourceLocation Loc) override; Index: clang-tools-extra/pp-trace/PPCallbacksTracker.cpp =================================================================== --- clang-tools-extra/pp-trace/PPCallbacksTracker.cpp +++ clang-tools-extra/pp-trace/PPCallbacksTracker.cpp @@ -78,6 +78,12 @@ "PMK_Message", "PMK_Warning", "PMK_Error" }; +// PragmaWarningSpecifier strings. +static const char *const PragmaWarningSpecifierStrings[] = { + "PWS_Default", "PWS_Disable", "PWS_Error", "PWS_Once", "PWS_Suppress", + "PWS_Level1", "PWS_Level2", "PWS_Level3", "PWS_Level4", +}; + // ConditionValueKind strings. static const char *const ConditionValueKindStrings[] = { "CVK_NotEvaluated", "CVK_False", "CVK_True" @@ -267,11 +273,11 @@ // Callback invoked when a #pragma warning directive is read. void PPCallbacksTracker::PragmaWarning(SourceLocation Loc, - llvm::StringRef WarningSpec, + PragmaWarningSpecifier WarningSpec, llvm::ArrayRef Ids) { beginCallback("PragmaWarning"); appendArgument("Loc", Loc); - appendArgument("WarningSpec", WarningSpec); + appendArgument("WarningSpec", WarningSpec, PragmaWarningSpecifierStrings); std::string Str; llvm::raw_string_ostream SS(Str); Index: clang-tools-extra/test/pp-trace/pp-trace-pragma-ms.cpp =================================================================== --- clang-tools-extra/test/pp-trace/pp-trace-pragma-ms.cpp +++ clang-tools-extra/test/pp-trace/pp-trace-pragma-ms.cpp @@ -86,15 +86,15 @@ // CHECK-NEXT: Introducer: PIK_HashPragma // CHECK-NEXT: - Callback: PragmaWarning // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:17:9" -// CHECK-NEXT: WarningSpec: disable +// CHECK-NEXT: WarningSpec: PWS_Disable // CHECK-NEXT: Ids: [1, 2, 3] // CHECK-NEXT: - Callback: PragmaWarning // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:17:9" -// CHECK-NEXT: WarningSpec: error +// CHECK-NEXT: WarningSpec: PWS_Error // CHECK-NEXT: Ids: [4, 5, 6] // CHECK-NEXT: - Callback: PragmaWarning // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:17:9" -// CHECK-NEXT: WarningSpec: suppress +// CHECK-NEXT: WarningSpec: PWS_Suppress // CHECK-NEXT: Ids: [7, 8, 9] // CHECK-NEXT: - Callback: EndOfMainFile // CHECK-NEXT: ... Index: clang/include/clang/Lex/PPCallbacks.h =================================================================== --- clang/include/clang/Lex/PPCallbacks.h +++ clang/include/clang/Lex/PPCallbacks.h @@ -252,9 +252,20 @@ } /// Callback invoked when a \#pragma warning directive is read. - virtual void PragmaWarning(SourceLocation Loc, StringRef WarningSpec, - ArrayRef Ids) { - } + enum PragmaWarningSpecifier { + PWS_Default, + PWS_Disable, + PWS_Error, + PWS_Once, + PWS_Suppress, + PWS_Level1, + PWS_Level2, + PWS_Level3, + PWS_Level4, + }; + virtual void PragmaWarning(SourceLocation Loc, + PragmaWarningSpecifier WarningSpec, + ArrayRef Ids) {} /// Callback invoked when a \#pragma warning(push) directive is read. virtual void PragmaWarningPush(SourceLocation Loc, int Level) { @@ -540,7 +551,7 @@ Second->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State); } - void PragmaWarning(SourceLocation Loc, StringRef WarningSpec, + void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier WarningSpec, ArrayRef Ids) override { First->PragmaWarning(Loc, WarningSpec, Ids); Second->PragmaWarning(Loc, WarningSpec, Ids); Index: clang/lib/Frontend/PrintPreprocessedOutput.cpp =================================================================== --- clang/lib/Frontend/PrintPreprocessedOutput.cpp +++ clang/lib/Frontend/PrintPreprocessedOutput.cpp @@ -155,7 +155,7 @@ void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) override; void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace, diag::Severity Map, StringRef Str) override; - void PragmaWarning(SourceLocation Loc, StringRef WarningSpec, + void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier WarningSpec, ArrayRef Ids) override; void PragmaWarningPush(SourceLocation Loc, int Level) override; void PragmaWarningPop(SourceLocation Loc) override; @@ -580,10 +580,24 @@ } void PrintPPOutputPPCallbacks::PragmaWarning(SourceLocation Loc, - StringRef WarningSpec, + PragmaWarningSpecifier WarningSpec, ArrayRef Ids) { MoveToLine(Loc, /*RequireStartOfLine=*/true); - OS << "#pragma warning(" << WarningSpec << ':'; + + OS << "#pragma warning("; + switch(WarningSpec) { + case PWS_Default: OS << "default"; break; + case PWS_Disable: OS << "disable"; break; + case PWS_Error: OS << "error"; break; + case PWS_Once: OS << "once"; break; + case PWS_Suppress: OS << "suppress"; break; + case PWS_Level1: OS << '1'; break; + case PWS_Level2: OS << '2'; break; + case PWS_Level3: OS << '3'; break; + case PWS_Level4: OS << '4'; break; + } + OS << ':'; + for (ArrayRef::iterator I = Ids.begin(), E = Ids.end(); I != E; ++I) OS << ' ' << *I; OS << ')'; Index: clang/lib/Lex/Pragma.cpp =================================================================== --- clang/lib/Lex/Pragma.cpp +++ clang/lib/Lex/Pragma.cpp @@ -1432,14 +1432,19 @@ // Figure out which warning specifier this is. bool SpecifierValid; - StringRef Specifier; - llvm::SmallString<1> SpecifierBuf; + PPCallbacks::PragmaWarningSpecifier Specifier; if (II) { - Specifier = II->getName(); - SpecifierValid = llvm::StringSwitch(Specifier) - .Cases("default", "disable", "error", "once", - "suppress", true) - .Default(false); + int SpecifierInt = llvm::StringSwitch(II->getName()) + .Case("default", PPCallbacks::PWS_Default) + .Case("disable", PPCallbacks::PWS_Disable) + .Case("error", PPCallbacks::PWS_Error) + .Case("once", PPCallbacks::PWS_Once) + .Case("suppress", PPCallbacks::PWS_Suppress) + .Default(-1); + if ((SpecifierValid = SpecifierInt != -1)) + Specifier = + static_cast(SpecifierInt); + // If we read a correct specifier, snatch next token (that should be // ":", checked later). if (SpecifierValid) @@ -1447,9 +1452,10 @@ } else { // Token is a numeric constant. It should be either 1, 2, 3 or 4. uint64_t Value; - Specifier = PP.getSpelling(Tok, SpecifierBuf); if (PP.parseSimpleIntegerLiteral(Tok, Value)) { - SpecifierValid = (Value >= 1) && (Value <= 4); + if ((SpecifierValid = (Value >= 1) && (Value <= 4))) + Specifier = static_cast( + PPCallbacks::PWS_Level1 + Value - 1); } else SpecifierValid = false; // Next token already snatched by parseSimpleIntegerLiteral.