From 3f8bf21873f0276b3c991ab1ad3fb3d85781f6a5 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 20 Feb 2014 22:59:51 +0000 Subject: [PATCH] Expand macros in pragmas with -fms-extensions and -E gcc never expands macros in pragmas and MSVC always expands macros before processing pragmas. Clang usually allows macro expansion, except in a handful of pragmas, most of which are handled by the lexer. Also remove PPCallbacks for pragmas that are currently handled in the parser. Without a Parser, such as with clang -E, these callbacks would never be called. Fixes PR18576. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@201821 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Lex/PPCallbacks.h | 25 ------------- lib/Frontend/PrintPreprocessedOutput.cpp | 43 ++++------------------ lib/Parse/ParsePragma.cpp | 9 ----- test/Preprocessor/print-pragma-microsoft.c | 20 ++++++++++ 4 files changed, 27 insertions(+), 70 deletions(-) create mode 100644 test/Preprocessor/print-pragma-microsoft.c diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h index f1ed897251..dc58573352 100644 --- a/include/clang/Lex/PPCallbacks.h +++ b/include/clang/Lex/PPCallbacks.h @@ -161,18 +161,6 @@ public: PragmaIntroducerKind Introducer) { } - /// \brief Callback invoked when a \#pragma comment directive is read. - virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, - const std::string &Str) { - } - - /// \brief Callback invoked when a \#pragma detect_mismatch directive is - /// read. - virtual void PragmaDetectMismatch(SourceLocation Loc, - const std::string &Name, - const std::string &Value) { - } - /// \brief Callback invoked when a \#pragma clang __debug directive is read. /// \param Loc The location of the debug directive. /// \param DebugType The identifier following __debug. @@ -387,19 +375,6 @@ public: Second->Ident(Loc, str); } - virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, - const std::string &Str) { - First->PragmaComment(Loc, Kind, Str); - Second->PragmaComment(Loc, Kind, Str); - } - - virtual void PragmaDetectMismatch(SourceLocation Loc, - const std::string &Name, - const std::string &Value) { - First->PragmaDetectMismatch(Loc, Name, Value); - Second->PragmaDetectMismatch(Loc, Name, Value); - } - virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace, PragmaMessageKind Kind, StringRef Str) { First->PragmaMessage(Loc, Namespace, Kind, Str); diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp index f3393bfe51..fd470ec5fd 100644 --- a/lib/Frontend/PrintPreprocessedOutput.cpp +++ b/lib/Frontend/PrintPreprocessedOutput.cpp @@ -138,11 +138,6 @@ public: const Module *Imported); virtual void Ident(SourceLocation Loc, const std::string &str); virtual void PragmaCaptured(SourceLocation Loc, StringRef Str); - virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, - const std::string &Str); - virtual void PragmaDetectMismatch(SourceLocation Loc, - const std::string &Name, - const std::string &Value); virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace, PragmaMessageKind Kind, StringRef Str); virtual void PragmaDebug(SourceLocation Loc, StringRef DebugType); @@ -402,36 +397,6 @@ static void outputPrintable(llvm::raw_ostream& OS, } } -void PrintPPOutputPPCallbacks::PragmaComment(SourceLocation Loc, - const IdentifierInfo *Kind, - const std::string &Str) { - startNewLineIfNeeded(); - MoveToLine(Loc); - OS << "#pragma comment(" << Kind->getName(); - - if (!Str.empty()) { - OS << ", \""; - outputPrintable(OS, Str); - OS << '"'; - } - - OS << ')'; - setEmittedDirectiveOnThisLine(); -} - -void PrintPPOutputPPCallbacks::PragmaDetectMismatch(SourceLocation Loc, - const std::string &Name, - const std::string &Value) { - startNewLineIfNeeded(); - MoveToLine(Loc); - OS << "#pragma detect_mismatch(\"" << Name << '"'; - outputPrintable(OS, Name); - OS << "\", \""; - outputPrintable(OS, Value); - OS << "\")"; - setEmittedDirectiveOnThisLine(); -} - void PrintPPOutputPPCallbacks::PragmaMessage(SourceLocation Loc, StringRef Namespace, PragmaMessageKind Kind, @@ -615,7 +580,13 @@ struct UnknownPragmaHandler : public PragmaHandler { Callbacks->OS << ' '; std::string TokSpell = PP.getSpelling(PragmaTok); Callbacks->OS.write(&TokSpell[0], TokSpell.size()); - PP.LexUnexpandedToken(PragmaTok); + + // Expand macros in pragmas with -fms-extensions. The assumption is that + // the majority of pragmas in such a file will be Microsoft pragmas. + if (PP.getLangOpts().MicrosoftExt) + PP.Lex(PragmaTok); + else + PP.LexUnexpandedToken(PragmaTok); } Callbacks->setEmittedDirectiveOnThisLine(); } diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp index 6a1b5fff54..f5491fff9b 100644 --- a/lib/Parse/ParsePragma.cpp +++ b/lib/Parse/ParsePragma.cpp @@ -1253,11 +1253,6 @@ void PragmaDetectMismatchHandler::HandlePragma(Preprocessor &PP, return; } - // If the pragma is lexically sound, notify any interested PPCallbacks. - if (PP.getPPCallbacks()) - PP.getPPCallbacks()->PragmaDetectMismatch(CommentLoc, NameString, - ValueString); - Actions.ActOnPragmaDetectMismatch(NameString, ValueString); } @@ -1328,9 +1323,5 @@ void PragmaCommentHandler::HandlePragma(Preprocessor &PP, return; } - // If the pragma is lexically sound, notify any interested PPCallbacks. - if (PP.getPPCallbacks()) - PP.getPPCallbacks()->PragmaComment(CommentLoc, II, ArgumentString); - Actions.ActOnPragmaMSComment(Kind, ArgumentString); } diff --git a/test/Preprocessor/print-pragma-microsoft.c b/test/Preprocessor/print-pragma-microsoft.c new file mode 100644 index 0000000000..5c4fb4ffc9 --- /dev/null +++ b/test/Preprocessor/print-pragma-microsoft.c @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 %s -fsyntax-only -fms-extensions -E -o - | FileCheck %s + +#define BAR "2" +#pragma comment(linker, "bar=" BAR) +// CHECK: #pragma comment(linker, "bar=" "2") +#pragma comment(user, "Compiled on " __DATE__ " at " __TIME__) +// CHECK: #pragma comment(user, "Compiled on " "{{[^"]*}}" " at " "{{[^"]*}}") + +#define KEY1 "KEY1" +#define KEY2 "KEY2" +#define VAL1 "VAL1\"" +#define VAL2 "VAL2" + +#pragma detect_mismatch(KEY1 KEY2, VAL1 VAL2) +// CHECK: #pragma detect_mismatch("KEY1" "KEY2", "VAL1\"" "VAL2") + +#define _CRT_PACKING 8 +#pragma pack(push, _CRT_PACKING) +// CHECK: #pragma pack(push, 8) +#pragma pack(pop) -- 2.40.0