diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-06-15 23:33:51 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-06-15 23:33:51 +0000 |
commit | 0cdd1fe3ec29b5cbff9a728966ace5c5b5d614f7 (patch) | |
tree | 491d04bd2b9e24f7aa9c54aa522bcd10daebc7dd /lib/Frontend/PrintPreprocessedOutput.cpp | |
parent | 63734d2349783662bf4b7fc24eed4cb31383b00d (diff) |
[-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)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@158571 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Frontend/PrintPreprocessedOutput.cpp')
-rw-r--r-- | lib/Frontend/PrintPreprocessedOutput.cpp | 65 |
1 files changed, 36 insertions, 29 deletions
diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp index 9e1587c8fa..7e0bc6bb2d 100644 --- a/lib/Frontend/PrintPreprocessedOutput.cpp +++ b/lib/Frontend/PrintPreprocessedOutput.cpp @@ -87,7 +87,7 @@ private: unsigned CurLine; bool EmittedTokensOnThisLine; - bool EmittedMacroOnThisLine; + bool EmittedDirectiveOnThisLine; SrcMgr::CharacteristicKind FileType; SmallString<512> CurFilename; bool Initialized; @@ -103,7 +103,7 @@ public: CurLine = 0; CurFilename += "<uninit>"; EmittedTokensOnThisLine = false; - EmittedMacroOnThisLine = false; + EmittedDirectiveOnThisLine = false; FileType = SrcMgr::C_User; Initialized = false; @@ -111,10 +111,15 @@ public: 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 @@ public: 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 @@ bool PrintPPOutputPPCallbacks::MoveToLine(unsigned LineNo) { } 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 @@ void PrintPPOutputPPCallbacks::MacroDefined(const Token &MacroNameTok, MoveToLine(MI->getDefinitionLoc()); PrintMacroDefinition(*MacroNameTok.getIdentifierInfo(), *MI, PP, OS); - EmittedMacroOnThisLine = true; + setEmittedDirectiveOnThisLine(); } void PrintPPOutputPPCallbacks::MacroUndefined(const Token &MacroNameTok, @@ -317,12 +316,13 @@ void PrintPPOutputPPCallbacks::MacroUndefined(const Token &MacroNameTok, 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 @@ void PrintPPOutputPPCallbacks::PragmaComment(SourceLocation Loc, } OS << ')'; - EmittedTokensOnThisLine = true; + setEmittedDirectiveOnThisLine(); } void PrintPPOutputPPCallbacks::PragmaMessage(SourceLocation Loc, StringRef Str) { + startNewLineIfNeeded(); MoveToLine(Loc); OS << "#pragma message("; @@ -366,26 +367,29 @@ void PrintPPOutputPPCallbacks::PragmaMessage(SourceLocation Loc, 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 @@ PragmaDiagnostic(SourceLocation Loc, StringRef Namespace, break; } OS << " \"" << Str << '"'; - EmittedTokensOnThisLine = true; + setEmittedDirectiveOnThisLine(); } /// HandleFirstTokOnLine - When emitting a preprocessed file in -E mode, this @@ -471,10 +475,9 @@ struct UnknownPragmaHandler : public PragmaHandler { 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 @@ struct UnknownPragmaHandler : public PragmaHandler { Callbacks->OS.write(&TokSpell[0], TokSpell.size()); PP.LexUnexpandedToken(PragmaTok); } - Callbacks->StartNewLineIfNeeded(); + Callbacks->setEmittedDirectiveOnThisLine(); } }; } // end anonymous namespace @@ -497,6 +500,10 @@ static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok, 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 @@ static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok, if (Tok.getKind() == tok::comment) Callbacks->HandleNewlinesInToken(&S[0], S.size()); } - Callbacks->SetEmittedTokensOnThisLine(); + Callbacks->setEmittedTokensOnThisLine(); if (Tok.is(tok::eof)) break; |