Copy diagnostic pragmas to the preprocessed output, from Richard Osborne!

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133633 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Douglas Gregor 2011-06-22 19:41:48 +00:00
Родитель b27c7a199b
Коммит c09ce1224d
4 изменённых файлов: 120 добавлений и 4 удалений

Просмотреть файл

@ -16,6 +16,7 @@
#include "clang/Lex/DirectoryLookup.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/DiagnosticIDs.h"
#include "llvm/ADT/StringRef.h"
#include <string>
@ -124,6 +125,24 @@ public:
virtual void PragmaMessage(SourceLocation Loc, llvm::StringRef Str) {
}
/// PragmaDiagnosticPush - This callback is invoked when a
/// #pragma gcc dianostic push directive is read.
virtual void PragmaDiagnosticPush(SourceLocation Loc,
llvm::StringRef Namespace) {
}
/// PragmaDiagnosticPop - This callback is invoked when a
/// #pragma gcc dianostic pop directive is read.
virtual void PragmaDiagnosticPop(SourceLocation Loc,
llvm::StringRef Namespace) {
}
/// PragmaDiagnostic - This callback is invoked when a
/// #pragma gcc dianostic directive is read.
virtual void PragmaDiagnostic(SourceLocation Loc, llvm::StringRef Namespace,
diag::Mapping mapping, llvm::StringRef Str) {
}
/// MacroExpands - This is called by
/// Preprocessor::HandleMacroExpandedIdentifier when a macro invocation is
/// found.
@ -232,6 +251,24 @@ public:
Second->PragmaMessage(Loc, Str);
}
virtual void PragmaDiagnosticPush(SourceLocation Loc,
llvm::StringRef Namespace) {
First->PragmaDiagnosticPush(Loc, Namespace);
Second->PragmaDiagnosticPush(Loc, Namespace);
}
virtual void PragmaDiagnosticPop(SourceLocation Loc,
llvm::StringRef Namespace) {
First->PragmaDiagnosticPop(Loc, Namespace);
Second->PragmaDiagnosticPop(Loc, Namespace);
}
virtual void PragmaDiagnostic(SourceLocation Loc, llvm::StringRef Namespace,
diag::Mapping mapping, llvm::StringRef Str) {
First->PragmaDiagnostic(Loc, Namespace, mapping, Str);
Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
}
virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI) {
First->MacroExpands(MacroNameTok, MI);
Second->MacroExpands(MacroNameTok, MI);

Просмотреть файл

@ -26,6 +26,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Config/config.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/ErrorHandling.h"
#include <cstdio>
using namespace clang;
@ -122,6 +123,12 @@ public:
virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
const std::string &Str);
virtual void PragmaMessage(SourceLocation Loc, llvm::StringRef Str);
virtual void PragmaDiagnosticPush(SourceLocation Loc,
llvm::StringRef Namespace);
virtual void PragmaDiagnosticPop(SourceLocation Loc,
llvm::StringRef Namespace);
virtual void PragmaDiagnostic(SourceLocation Loc, llvm::StringRef Namespace,
diag::Mapping Map, llvm::StringRef Str);
bool HandleFirstTokOnLine(Token &Tok);
bool MoveToLine(SourceLocation Loc) {
@ -361,6 +368,43 @@ void PrintPPOutputPPCallbacks::PragmaMessage(SourceLocation Loc,
EmittedTokensOnThisLine = true;
}
void PrintPPOutputPPCallbacks::
PragmaDiagnosticPush(SourceLocation Loc, llvm::StringRef Namespace) {
MoveToLine(Loc);
OS << "#pragma " << Namespace << " diagnostic push";
EmittedTokensOnThisLine = true;
}
void PrintPPOutputPPCallbacks::
PragmaDiagnosticPop(SourceLocation Loc, llvm::StringRef Namespace) {
MoveToLine(Loc);
OS << "#pragma " << Namespace << " diagnostic pop";
EmittedTokensOnThisLine = true;
}
void PrintPPOutputPPCallbacks::
PragmaDiagnostic(SourceLocation Loc, llvm::StringRef Namespace,
diag::Mapping Map, llvm::StringRef Str) {
MoveToLine(Loc);
OS << "#pragma " << Namespace << " diagnostic ";
switch (Map) {
default: llvm_unreachable("unexpected diagnostic kind");
case diag::MAP_WARNING:
OS << "warning";
break;
case diag::MAP_ERROR:
OS << "error";
break;
case diag::MAP_IGNORE:
OS << "ignored";
break;
case diag::MAP_FATAL:
OS << "fatal";
break;
}
OS << " \"" << Str << '"';
EmittedTokensOnThisLine = true;
}
/// HandleFirstTokOnLine - When emitting a preprocessed file in -E mode, this
/// is called for the first token on each new line. If this really is the start

Просмотреть файл

@ -836,8 +836,11 @@ struct PragmaDebugHandler : public PragmaHandler {
/// PragmaDiagnosticHandler - e.g. '#pragma GCC diagnostic ignored "-Wformat"'
struct PragmaDiagnosticHandler : public PragmaHandler {
private:
const char *Namespace;
public:
explicit PragmaDiagnosticHandler() : PragmaHandler("diagnostic") {}
explicit PragmaDiagnosticHandler(const char *NS) :
PragmaHandler("diagnostic"), Namespace(NS) {}
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
Token &DiagToken) {
SourceLocation DiagLoc = DiagToken.getLocation();
@ -848,6 +851,7 @@ public:
return;
}
IdentifierInfo *II = Tok.getIdentifierInfo();
PPCallbacks *Callbacks = PP.getPPCallbacks();
diag::Mapping Map;
if (II->isStr("warning"))
@ -861,10 +865,13 @@ public:
else if (II->isStr("pop")) {
if (!PP.getDiagnostics().popMappings(DiagLoc))
PP.Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
else if (Callbacks)
Callbacks->PragmaDiagnosticPop(DiagLoc, Namespace);
return;
} else if (II->isStr("push")) {
PP.getDiagnostics().pushMappings(DiagLoc);
if (Callbacks)
Callbacks->PragmaDiagnosticPush(DiagLoc, Namespace);
return;
} else {
PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
@ -916,6 +923,8 @@ public:
Map, DiagLoc))
PP.Diag(StrToks[0].getLocation(),
diag::warn_pragma_diagnostic_unknown_warning) << WarningName;
else if (Callbacks)
Callbacks->PragmaDiagnostic(DiagLoc, Namespace, Map, WarningName);
}
};
@ -1010,13 +1019,13 @@ void Preprocessor::RegisterBuiltinPragmas() {
AddPragmaHandler("GCC", new PragmaPoisonHandler());
AddPragmaHandler("GCC", new PragmaSystemHeaderHandler());
AddPragmaHandler("GCC", new PragmaDependencyHandler());
AddPragmaHandler("GCC", new PragmaDiagnosticHandler());
AddPragmaHandler("GCC", new PragmaDiagnosticHandler("GCC"));
// #pragma clang ...
AddPragmaHandler("clang", new PragmaPoisonHandler());
AddPragmaHandler("clang", new PragmaSystemHeaderHandler());
AddPragmaHandler("clang", new PragmaDebugHandler());
AddPragmaHandler("clang", new PragmaDependencyHandler());
AddPragmaHandler("clang", new PragmaDiagnosticHandler());
AddPragmaHandler("clang", new PragmaDiagnosticHandler("clang"));
AddPragmaHandler("STDC", new PragmaSTDC_FENV_ACCESSHandler());
AddPragmaHandler("STDC", new PragmaSTDC_CX_LIMITED_RANGEHandler());

Просмотреть файл

@ -0,0 +1,26 @@
// RUN: %clang_cc1 -E %s | FileCheck %s
// CHECK: #pragma GCC diagnostic warning "-Wall"
#pragma GCC diagnostic warning "-Wall"
// CHECK: #pragma GCC diagnostic ignored "-Wall"
#pragma GCC diagnostic ignored "-Wall"
// CHECK: #pragma GCC diagnostic error "-Wall"
#pragma GCC diagnostic error "-Wall"
// CHECK: #pragma GCC diagnostic fatal "-Wall"
#pragma GCC diagnostic fatal "-Wall"
// CHECK: #pragma GCC diagnostic push
#pragma GCC diagnostic push
// CHECK: #pragma GCC diagnostic pop
#pragma GCC diagnostic pop
// CHECK: #pragma clang diagnostic warning "-Wall"
#pragma clang diagnostic warning "-Wall"
// CHECK: #pragma clang diagnostic ignored "-Wall"
#pragma clang diagnostic ignored "-Wall"
// CHECK: #pragma clang diagnostic error "-Wall"
#pragma clang diagnostic error "-Wall"
// CHECK: #pragma clang diagnostic fatal "-Wall"
#pragma clang diagnostic fatal "-Wall"
// CHECK: #pragma clang diagnostic push
#pragma clang diagnostic push
// CHECK: #pragma clang diagnostic pop
#pragma clang diagnostic pop