[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