[cfe-commits] r158571 - in /cfe/trunk: lib/Frontend/PrintPreprocessedOutput.cpp lib/Lex/Lexer.cpp test/Lexer/pragma-operators.cpp test/Preprocessor/_Pragma-location.c test/Preprocessor/comment_save.c

Jordan Rose jordan_rose at apple.com
Fri Jun 15 16:33:51 PDT 2012


Author: jrose
Date: Fri Jun 15 18:33:51 2012
New Revision: 158571

URL: http://llvm.org/viewvc/llvm-project?rev=158571&view=rev
Log:
[-E] Emit a rewritten _Pragma on its own line.

1. Teach Lexer that pragma lexers are like macro expansions at EOF.
2. Treat pragmas like #define/#undef when printing.
3. If we just printed a directive, add a newline before any more tokens.
(4. Miscellaneous cleanup in PrintPreprocessedOutput.cpp)

PR10594 and <rdar://problem/11562490> (two separate related problems)

Modified:
    cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp
    cfe/trunk/lib/Lex/Lexer.cpp
    cfe/trunk/test/Lexer/pragma-operators.cpp
    cfe/trunk/test/Preprocessor/_Pragma-location.c
    cfe/trunk/test/Preprocessor/comment_save.c

Modified: cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp?rev=158571&r1=158570&r2=158571&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp (original)
+++ cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp Fri Jun 15 18:33:51 2012
@@ -87,7 +87,7 @@
   unsigned CurLine;
 
   bool EmittedTokensOnThisLine;
-  bool EmittedMacroOnThisLine;
+  bool EmittedDirectiveOnThisLine;
   SrcMgr::CharacteristicKind FileType;
   SmallString<512> CurFilename;
   bool Initialized;
@@ -103,7 +103,7 @@
     CurLine = 0;
     CurFilename += "<uninit>";
     EmittedTokensOnThisLine = false;
-    EmittedMacroOnThisLine = false;
+    EmittedDirectiveOnThisLine = false;
     FileType = SrcMgr::C_User;
     Initialized = false;
 
@@ -111,10 +111,15 @@
     UseLineDirective = PP.getLangOpts().MicrosoftExt;
   }
 
-  void SetEmittedTokensOnThisLine() { EmittedTokensOnThisLine = true; }
+  void setEmittedTokensOnThisLine() { EmittedTokensOnThisLine = true; }
   bool hasEmittedTokensOnThisLine() const { return EmittedTokensOnThisLine; }
 
-  bool StartNewLineIfNeeded();
+  void setEmittedDirectiveOnThisLine() { EmittedDirectiveOnThisLine = true; }
+  bool hasEmittedDirectiveOnThisLine() const {
+    return EmittedDirectiveOnThisLine;
+  }
+
+  bool startNewLineIfNeeded(bool ShouldUpdateCurrentLine = true);
   
   virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
                            SrcMgr::CharacteristicKind FileType,
@@ -158,11 +163,7 @@
 void PrintPPOutputPPCallbacks::WriteLineInfo(unsigned LineNo,
                                              const char *Extra,
                                              unsigned ExtraLen) {
-  if (EmittedTokensOnThisLine || EmittedMacroOnThisLine) {
-    OS << '\n';
-    EmittedTokensOnThisLine = false;
-    EmittedMacroOnThisLine = false;
-  }
+  startNewLineIfNeeded(/*ShouldUpdateCurrentLine=*/false);
 
   // Emit #line directives or GNU line markers depending on what mode we're in.
   if (UseLineDirective) {
@@ -207,23 +208,21 @@
   } else {
     // Okay, we're in -P mode, which turns off line markers.  However, we still
     // need to emit a newline between tokens on different lines.
-    if (EmittedTokensOnThisLine || EmittedMacroOnThisLine) {
-      OS << '\n';
-      EmittedTokensOnThisLine = false;
-      EmittedMacroOnThisLine = false;
-    }
+    startNewLineIfNeeded(/*ShouldUpdateCurrentLine=*/false);
   }
 
   CurLine = LineNo;
   return true;
 }
 
-bool PrintPPOutputPPCallbacks::StartNewLineIfNeeded() {
-  if (EmittedTokensOnThisLine || EmittedMacroOnThisLine) {
+bool
+PrintPPOutputPPCallbacks::startNewLineIfNeeded(bool ShouldUpdateCurrentLine) {
+  if (EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) {
     OS << '\n';
     EmittedTokensOnThisLine = false;
-    EmittedMacroOnThisLine = false;
-    ++CurLine;
+    EmittedDirectiveOnThisLine = false;
+    if (ShouldUpdateCurrentLine)
+      ++CurLine;
     return true;
   }
   
@@ -307,7 +306,7 @@
 
   MoveToLine(MI->getDefinitionLoc());
   PrintMacroDefinition(*MacroNameTok.getIdentifierInfo(), *MI, PP, OS);
-  EmittedMacroOnThisLine = true;
+  setEmittedDirectiveOnThisLine();
 }
 
 void PrintPPOutputPPCallbacks::MacroUndefined(const Token &MacroNameTok,
@@ -317,12 +316,13 @@
 
   MoveToLine(MacroNameTok.getLocation());
   OS << "#undef " << MacroNameTok.getIdentifierInfo()->getName();
-  EmittedMacroOnThisLine = true;
+  setEmittedDirectiveOnThisLine();
 }
 
 void PrintPPOutputPPCallbacks::PragmaComment(SourceLocation Loc,
                                              const IdentifierInfo *Kind,
                                              const std::string &Str) {
+  startNewLineIfNeeded();
   MoveToLine(Loc);
   OS << "#pragma comment(" << Kind->getName();
 
@@ -343,11 +343,12 @@
   }
 
   OS << ')';
-  EmittedTokensOnThisLine = true;
+  setEmittedDirectiveOnThisLine();
 }
 
 void PrintPPOutputPPCallbacks::PragmaMessage(SourceLocation Loc,
                                              StringRef Str) {
+  startNewLineIfNeeded();
   MoveToLine(Loc);
   OS << "#pragma message(";
 
@@ -366,26 +367,29 @@
   OS << '"';
 
   OS << ')';
-  EmittedTokensOnThisLine = true;
+  setEmittedDirectiveOnThisLine();
 }
 
 void PrintPPOutputPPCallbacks::
 PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) {
+  startNewLineIfNeeded();
   MoveToLine(Loc);
   OS << "#pragma " << Namespace << " diagnostic push";
-  EmittedTokensOnThisLine = true;
+  setEmittedDirectiveOnThisLine();
 }
 
 void PrintPPOutputPPCallbacks::
 PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) {
+  startNewLineIfNeeded();
   MoveToLine(Loc);
   OS << "#pragma " << Namespace << " diagnostic pop";
-  EmittedTokensOnThisLine = true;
+  setEmittedDirectiveOnThisLine();
 }
 
 void PrintPPOutputPPCallbacks::
 PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
                  diag::Mapping Map, StringRef Str) {
+  startNewLineIfNeeded();
   MoveToLine(Loc);
   OS << "#pragma " << Namespace << " diagnostic ";
   switch (Map) {
@@ -403,7 +407,7 @@
     break;
   }
   OS << " \"" << Str << '"';
-  EmittedTokensOnThisLine = true;
+  setEmittedDirectiveOnThisLine();
 }
 
 /// HandleFirstTokOnLine - When emitting a preprocessed file in -E mode, this
@@ -471,10 +475,9 @@
                             Token &PragmaTok) {
     // Figure out what line we went to and insert the appropriate number of
     // newline characters.
-    Callbacks->StartNewLineIfNeeded();
+    Callbacks->startNewLineIfNeeded();
     Callbacks->MoveToLine(PragmaTok.getLocation());
     Callbacks->OS.write(Prefix, strlen(Prefix));
-    Callbacks->SetEmittedTokensOnThisLine();
     // Read and print all of the pragma tokens.
     while (PragmaTok.isNot(tok::eod)) {
       if (PragmaTok.hasLeadingSpace())
@@ -483,7 +486,7 @@
       Callbacks->OS.write(&TokSpell[0], TokSpell.size());
       PP.LexUnexpandedToken(PragmaTok);
     }
-    Callbacks->StartNewLineIfNeeded();
+    Callbacks->setEmittedDirectiveOnThisLine();
   }
 };
 } // end anonymous namespace
@@ -497,6 +500,10 @@
   PrevPrevTok.startToken();
   PrevTok.startToken();
   while (1) {
+    if (Callbacks->hasEmittedDirectiveOnThisLine()) {
+      Callbacks->startNewLineIfNeeded();
+      Callbacks->MoveToLine(Tok.getLocation());
+    }
 
     // If this token is at the start of a line, emit newlines if needed.
     if (Tok.isAtStartOfLine() && Callbacks->HandleFirstTokOnLine(Tok)) {
@@ -533,7 +540,7 @@
       if (Tok.getKind() == tok::comment)
         Callbacks->HandleNewlinesInToken(&S[0], S.size());
     }
-    Callbacks->SetEmittedTokensOnThisLine();
+    Callbacks->setEmittedTokensOnThisLine();
 
     if (Tok.is(tok::eof)) break;
 

Modified: cfe/trunk/lib/Lex/Lexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Lexer.cpp?rev=158571&r1=158570&r2=158571&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Lexer.cpp (original)
+++ cfe/trunk/lib/Lex/Lexer.cpp Fri Jun 15 18:33:51 2012
@@ -2402,7 +2402,7 @@
   BufferPtr = CurPtr;
 
   // Finally, let the preprocessor handle this.
-  return PP->HandleEndOfFile(Result);
+  return PP->HandleEndOfFile(Result, isPragmaLexer());
 }
 
 /// isNextPPTokenLParen - Return 1 if the next unexpanded token lexed from

Modified: cfe/trunk/test/Lexer/pragma-operators.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/pragma-operators.cpp?rev=158571&r1=158570&r2=158571&view=diff
==============================================================================
--- cfe/trunk/test/Lexer/pragma-operators.cpp (original)
+++ cfe/trunk/test/Lexer/pragma-operators.cpp Fri Jun 15 18:33:51 2012
@@ -9,7 +9,6 @@
 // CHECK: #line
 // CHECK: #pragma warning(push)
 // CHECK:  int foo() { return 0; } }
-// CHECK: #line
 // CHECK: #pragma warning(pop)
 #define A(X) extern "C" { __pragma(warning(push)) \
   int X() { return 0; } \

Modified: cfe/trunk/test/Preprocessor/_Pragma-location.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/_Pragma-location.c?rev=158571&r1=158570&r2=158571&view=diff
==============================================================================
--- cfe/trunk/test/Preprocessor/_Pragma-location.c (original)
+++ cfe/trunk/test/Preprocessor/_Pragma-location.c Fri Jun 15 18:33:51 2012
@@ -1,4 +1,47 @@
-// RUN: %clang_cc1 %s -E | not grep 'scratch space'
+// RUN: %clang_cc1 %s -fms-extensions -E | FileCheck %s
+// We use -fms-extensions to test both _Pragma and __pragma.
 
-#define push _Pragma ("pack(push)")
-push
+// A long time ago the pragma lexer's buffer showed through in -E output.
+// CHECK-NOT: scratch space
+
+#define push_p _Pragma ("pack(push)")
+push_p
+// CHECK: #pragma pack(push)
+
+push_p _Pragma("pack(push)") __pragma(pack(push))
+// CHECK: #pragma pack(push)
+// CHECK-NEXT: #line 11 "{{.*}}_Pragma-location.c"
+// CHECK-NEXT: #pragma pack(push)
+// CHECK-NEXT: #line 11 "{{.*}}_Pragma-location.c"
+// CHECK-NEXT: #pragma pack(push)
+
+
+#define __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS _Pragma("clang diagnostic push") \
+_Pragma("clang diagnostic ignored \"-Wformat-extra-args\"")
+#define __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS _Pragma("clang diagnostic pop")
+
+void test () {
+  1;_Pragma("clang diagnostic push") \
+  _Pragma("clang diagnostic ignored \"-Wformat-extra-args\"")
+  _Pragma("clang diagnostic pop")
+
+  2;__PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS
+  3;__PRAGMA_POP_NO_EXTRA_ARG_WARNINGS
+}
+
+// CHECK: void test () {
+// CHECK-NEXT:   1;
+// CHECK-NEXT: #line 24 "{{.*}}_Pragma-location.c"
+// CHECK-NEXT: #pragma clang diagnostic push
+// CHECK-NEXT: #pragma clang diagnostic ignored "-Wformat-extra-args"
+// CHECK-NEXT: #pragma clang diagnostic pop
+
+// CHECK:   2;
+// CHECK-NEXT: #line 28 "{{.*}}_Pragma-location.c"
+// CHECK-NEXT: #pragma clang diagnostic push
+// CHECK-NEXT: #line 28 "{{.*}}_Pragma-location.c"
+// CHECK-NEXT: #pragma clang diagnostic ignored "-Wformat-extra-args"
+// CHECK-NEXT:   3;
+// CHECK-NEXT: #line 29 "{{.*}}_Pragma-location.c"
+// CHECK-NEXT: #pragma clang diagnostic pop
+// CHECK-NEXT: }

Modified: cfe/trunk/test/Preprocessor/comment_save.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/comment_save.c?rev=158571&r1=158570&r2=158571&view=diff
==============================================================================
--- cfe/trunk/test/Preprocessor/comment_save.c (original)
+++ cfe/trunk/test/Preprocessor/comment_save.c Fri Jun 15 18:33:51 2012
@@ -10,3 +10,13 @@
 #endif
 /* baz */
 // CHECK: /* baz */
+
+_Pragma("unknown") // after unknown pragma
+// CHECK: #pragma unknown
+// CHECK-NEXT: #
+// CHECK-NEXT: // after unknown pragma
+
+_Pragma("comment(\"abc\")") // after known pragma
+// CHECK: #pragma comment("abc")
+// CHECK-NEXT: #
+// CHECK-NEXT: // after known pragma





More information about the cfe-commits mailing list