]> granicus.if.org Git - clang/commitdiff
Expand macros in pragmas with -fms-extensions and -E
authorReid Kleckner <reid@kleckner.net>
Thu, 20 Feb 2014 22:59:51 +0000 (22:59 +0000)
committerReid Kleckner <reid@kleckner.net>
Thu, 20 Feb 2014 22:59:51 +0000 (22:59 +0000)
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
lib/Frontend/PrintPreprocessedOutput.cpp
lib/Parse/ParsePragma.cpp
test/Preprocessor/print-pragma-microsoft.c [new file with mode: 0644]

index f1ed897251bb83e80cfc99abbbd4ab91603e6d10..dc58573352619490f6ed3d0ffe80e213f5a0be77 100644 (file)
@@ -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);
index f3393bfe51ce49fa103aee17fb1ef4d5d6551af6..fd470ec5fdb531d540bc97129692bf804bc6f57c 100644 (file)
@@ -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();
   }
index 6a1b5fff54a79bdefd58ab1a8353843d3c014107..f5491fff9b5efb5a480e3b6d80672c96aa0dcdcc 100644 (file)
@@ -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 (file)
index 0000000..5c4fb4f
--- /dev/null
@@ -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)