diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Basic/Diagnostic.cpp | 17 | ||||
-rw-r--r-- | clang/lib/Lex/Pragma.cpp | 44 |
2 files changed, 52 insertions, 9 deletions
diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp index 78b8b0a8559..6ba5907a34c 100644 --- a/clang/lib/Basic/Diagnostic.cpp +++ b/clang/lib/Basic/Diagnostic.cpp @@ -201,6 +201,7 @@ Diagnostic::Diagnostic(DiagnosticClient *client) : Client(client) { ErrorOccurred = false; FatalErrorOccurred = false; NumDiagnostics = 0; + NumErrors = 0; CustomDiagInfo = 0; CurDiagID = ~0U; @@ -210,13 +211,27 @@ Diagnostic::Diagnostic(DiagnosticClient *client) : Client(client) { ArgToStringCookie = 0; // Set all mappings to 'unset'. - memset(DiagMappings, 0, sizeof(DiagMappings)); + DiagMappings BlankDiags(diag::DIAG_UPPER_LIMIT/2, 0); + DiagMappingsStack.push_back(BlankDiags); } Diagnostic::~Diagnostic() { delete CustomDiagInfo; } + +void Diagnostic::pushMappings() { + DiagMappingsStack.push_back(DiagMappingsStack.back()); +} + +bool Diagnostic::popMappings() { + if (DiagMappingsStack.size() == 1) + return false; + + DiagMappingsStack.pop_back(); + return true; +} + /// getCustomDiagID - Return an ID for a diagnostic with the specified message /// and level. If this is the first request for this diagnosic, it is /// registered and created, otherwise the existing ID is returned. diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp index bb0b71e2268..fbdbd0b6e76 100644 --- a/clang/lib/Lex/Pragma.cpp +++ b/clang/lib/Lex/Pragma.cpp @@ -518,13 +518,23 @@ struct PragmaDependencyHandler : public PragmaHandler { }; /// PragmaDiagnosticHandler - e.g. '#pragma GCC diagnostic ignored "-Wformat"' +/// Since clang's diagnostic supports extended functionality beyond GCC's +/// the constructor takes a clangMode flag to tell it whether or not to allow +/// clang's extended functionality, or whether to reject it. struct PragmaDiagnosticHandler : public PragmaHandler { - PragmaDiagnosticHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {} +private: + const bool ClangMode; +public: + PragmaDiagnosticHandler(const IdentifierInfo *ID, + const bool clangMode) : PragmaHandler(ID), + ClangMode(clangMode) {} virtual void HandlePragma(Preprocessor &PP, Token &DiagToken) { Token Tok; PP.LexUnexpandedToken(Tok); if (Tok.isNot(tok::identifier)) { - PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid); + unsigned Diag = ClangMode ? diag::warn_pragma_diagnostic_clang_invalid + : diag::warn_pragma_diagnostic_gcc_invalid; + PP.Diag(Tok, Diag); return; } IdentifierInfo *II = Tok.getIdentifierInfo(); @@ -538,8 +548,22 @@ struct PragmaDiagnosticHandler : public PragmaHandler { Map = diag::MAP_IGNORE; else if (II->isStr("fatal")) Map = diag::MAP_FATAL; - else { - PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid); + else if (ClangMode) { + if (II->isStr("pop")) { + if(!PP.getDiagnostics().popMappings()) + PP.Diag(Tok, diag::warn_pragma_diagnostic_clang_cannot_ppp); + return; + } + + if (II->isStr("push")) { + PP.getDiagnostics().pushMappings(); + return; + } + + PP.Diag(Tok, diag::warn_pragma_diagnostic_clang_invalid); + return; + } else { + PP.Diag(Tok, diag::warn_pragma_diagnostic_gcc_invalid); return; } @@ -571,10 +595,12 @@ struct PragmaDiagnosticHandler : public PragmaHandler { if (Literal.hadError) return; if (Literal.Pascal) { - PP.Diag(StrToks[0].getLocation(), diag::warn_pragma_diagnostic_invalid); + unsigned Diag = ClangMode ? diag::warn_pragma_diagnostic_clang_invalid + : diag::warn_pragma_diagnostic_gcc_invalid; + PP.Diag(Tok, Diag); return; } - + std::string WarningName(Literal.GetString(), Literal.GetString()+Literal.GetStringLength()); @@ -689,7 +715,8 @@ void Preprocessor::RegisterBuiltinPragmas() { AddPragmaHandler("GCC", new PragmaDependencyHandler( getIdentifierInfo("dependency"))); AddPragmaHandler("GCC", new PragmaDiagnosticHandler( - getIdentifierInfo("diagnostic"))); + getIdentifierInfo("diagnostic"), + false)); // #pragma clang ... AddPragmaHandler("clang", new PragmaPoisonHandler( getIdentifierInfo("poison"))); @@ -698,7 +725,8 @@ void Preprocessor::RegisterBuiltinPragmas() { AddPragmaHandler("clang", new PragmaDependencyHandler( getIdentifierInfo("dependency"))); AddPragmaHandler("clang", new PragmaDiagnosticHandler( - getIdentifierInfo("diagnostic"))); + getIdentifierInfo("diagnostic"), + true)); AddPragmaHandler("STDC", new PragmaSTDC_FP_CONTRACTHandler( getIdentifierInfo("FP_CONTRACT"))); |