diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-09-09 22:45:38 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-09-09 22:45:38 +0000 |
commit | 80c60f72848896f867f6b7e664e7060d9e78f019 (patch) | |
tree | f485a7c8e94a54a3095e9bc3be9be852db88a2ef /lib | |
parent | 748de8eda222f087434d8bd703176b316a061341 (diff) |
When we parse a pragma, keep track of how that pragma was originally
spelled (#pragma, _Pragma, __pragma). In -E mode, use that information
to add appropriate newlines when translating _Pragma and __pragma into
#pragma, like GCC does. Fixes <rdar://problem/8412013>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113553 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Frontend/PrintPreprocessedOutput.cpp | 24 | ||||
-rw-r--r-- | lib/Lex/PPDirectives.cpp | 3 | ||||
-rw-r--r-- | lib/Lex/Pragma.cpp | 68 | ||||
-rw-r--r-- | lib/Parse/ParsePragma.cpp | 24 | ||||
-rw-r--r-- | lib/Parse/ParsePragma.h | 18 |
5 files changed, 96 insertions, 41 deletions
diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp index 5ae02f97bd..2159d3e80d 100644 --- a/lib/Frontend/PrintPreprocessedOutput.cpp +++ b/lib/Frontend/PrintPreprocessedOutput.cpp @@ -120,6 +120,8 @@ public: void SetEmittedTokensOnThisLine() { EmittedTokensOnThisLine = true; } bool hasEmittedTokensOnThisLine() const { return EmittedTokensOnThisLine; } + bool StartNewLineIfNeeded(); + virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason, SrcMgr::CharacteristicKind FileType); virtual void Ident(SourceLocation Loc, const std::string &str); @@ -138,7 +140,7 @@ public: return ConcatInfo.AvoidConcat(PrevPrevTok, PrevTok, Tok); } void WriteLineInfo(unsigned LineNo, const char *Extra=0, unsigned ExtraLen=0); - + bool LineMarkersAreDisabled() const { return DisableLineMarkers; } void HandleNewlinesInToken(const char *TokStr, unsigned Len); /// MacroDefined - This hook is called whenever a macro definition is seen. @@ -213,6 +215,17 @@ bool PrintPPOutputPPCallbacks::MoveToLine(unsigned LineNo) { return true; } +bool PrintPPOutputPPCallbacks::StartNewLineIfNeeded() { + if (EmittedTokensOnThisLine || EmittedMacroOnThisLine) { + OS << '\n'; + EmittedTokensOnThisLine = false; + EmittedMacroOnThisLine = false; + ++CurLine; + return true; + } + + return false; +} /// FileChanged - Whenever the preprocessor enters or exits a #include file /// it invokes this handler. Update our conception of the current source @@ -438,12 +451,15 @@ struct UnknownPragmaHandler : public PragmaHandler { UnknownPragmaHandler(const char *prefix, PrintPPOutputPPCallbacks *callbacks) : Prefix(prefix), Callbacks(callbacks) {} - virtual void HandlePragma(Preprocessor &PP, Token &PragmaTok) { + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &PragmaTok) { // Figure out what line we went to and insert the appropriate number of // newline characters. + if (Introducer == PIK__Pragma || Introducer == PIK___pragma) + 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::eom)) { if (PragmaTok.hasLeadingSpace()) @@ -452,7 +468,7 @@ struct UnknownPragmaHandler : public PragmaHandler { Callbacks->OS.write(&TokSpell[0], TokSpell.size()); PP.LexUnexpandedToken(PragmaTok); } - Callbacks->OS << '\n'; + Callbacks->StartNewLineIfNeeded(); } }; } // end anonymous namespace diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index 8da7def9ed..5e3b16e60d 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -17,6 +17,7 @@ #include "clang/Lex/MacroInfo.h" #include "clang/Lex/LexDiagnostic.h" #include "clang/Lex/CodeCompletionHandler.h" +#include "clang/Lex/Pragma.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" #include "llvm/ADT/APInt.h" @@ -588,7 +589,7 @@ TryAgain: // C99 6.10.6 - Pragma Directive. case tok::pp_pragma: - return HandlePragmaDirective(); + return HandlePragmaDirective(PIK_HashPragma); // GNU Extensions. case tok::pp_import: diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp index a7b289e137..3d6bc2aa83 100644 --- a/lib/Lex/Pragma.cpp +++ b/lib/Lex/Pragma.cpp @@ -35,7 +35,9 @@ PragmaHandler::~PragmaHandler() { EmptyPragmaHandler::EmptyPragmaHandler() {} -void EmptyPragmaHandler::HandlePragma(Preprocessor &PP, Token &FirstToken) {} +void EmptyPragmaHandler::HandlePragma(Preprocessor &PP, + PragmaIntroducerKind Introducer, + Token &FirstToken) {} //===----------------------------------------------------------------------===// // PragmaNamespace Implementation. @@ -73,7 +75,9 @@ void PragmaNamespace::RemovePragmaHandler(PragmaHandler *Handler) { Handlers.erase(Handler->getName()); } -void PragmaNamespace::HandlePragma(Preprocessor &PP, Token &Tok) { +void PragmaNamespace::HandlePragma(Preprocessor &PP, + PragmaIntroducerKind Introducer, + Token &Tok) { // Read the 'namespace' that the directive is in, e.g. STDC. Do not macro // expand it, the user can have a STDC #define, that should not affect this. PP.LexUnexpandedToken(Tok); @@ -89,7 +93,7 @@ void PragmaNamespace::HandlePragma(Preprocessor &PP, Token &Tok) { } // Otherwise, pass it down. - Handler->HandlePragma(PP, Tok); + Handler->HandlePragma(PP, Introducer, Tok); } //===----------------------------------------------------------------------===// @@ -98,12 +102,12 @@ void PragmaNamespace::HandlePragma(Preprocessor &PP, Token &Tok) { /// HandlePragmaDirective - The "#pragma" directive has been parsed. Lex the /// rest of the pragma, passing it to the registered pragma handlers. -void Preprocessor::HandlePragmaDirective() { +void Preprocessor::HandlePragmaDirective(unsigned Introducer) { ++NumPragma; // Invoke the first level of pragma handlers which reads the namespace id. Token Tok; - PragmaHandlers->HandlePragma(*this, Tok); + PragmaHandlers->HandlePragma(*this, PragmaIntroducerKind(Introducer), Tok); // If the pragma handler didn't read the rest of the line, consume it now. if (CurPPLexer && CurPPLexer->ParsingPreprocessorDirective) @@ -170,7 +174,7 @@ void Preprocessor::Handle_Pragma(Token &Tok) { } } - Handle_Pragma(StrVal, PragmaLoc, RParenLoc); + Handle_Pragma(PIK__Pragma, StrVal, PragmaLoc, RParenLoc); // Finally, return whatever came after the pragma directive. return Lex(Tok); @@ -216,13 +220,14 @@ void Preprocessor::HandleMicrosoft__pragma(Token &Tok) { SourceLocation RParenLoc = Tok.getLocation(); - Handle_Pragma(StrVal, PragmaLoc, RParenLoc); + Handle_Pragma(PIK___pragma, StrVal, PragmaLoc, RParenLoc); // Finally, return whatever came after the pragma directive. return Lex(Tok); } -void Preprocessor::Handle_Pragma(const std::string &StrVal, +void Preprocessor::Handle_Pragma(unsigned Introducer, + const std::string &StrVal, SourceLocation PragmaLoc, SourceLocation RParenLoc) { @@ -241,7 +246,7 @@ void Preprocessor::Handle_Pragma(const std::string &StrVal, EnterSourceFileWithLexer(TL, 0); // With everything set up, lex this as a #pragma directive. - HandlePragmaDirective(); + HandlePragmaDirective(Introducer); } @@ -704,7 +709,8 @@ namespace { /// PragmaOnceHandler - "#pragma once" marks the file as atomically included. struct PragmaOnceHandler : public PragmaHandler { PragmaOnceHandler() : PragmaHandler("once") {} - virtual void HandlePragma(Preprocessor &PP, Token &OnceTok) { + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &OnceTok) { PP.CheckEndOfDirective("pragma once"); PP.HandlePragmaOnce(OnceTok); } @@ -714,7 +720,8 @@ struct PragmaOnceHandler : public PragmaHandler { /// rest of the line is not lexed. struct PragmaMarkHandler : public PragmaHandler { PragmaMarkHandler() : PragmaHandler("mark") {} - virtual void HandlePragma(Preprocessor &PP, Token &MarkTok) { + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &MarkTok) { PP.HandlePragmaMark(); } }; @@ -722,7 +729,8 @@ struct PragmaMarkHandler : public PragmaHandler { /// PragmaPoisonHandler - "#pragma poison x" marks x as not usable. struct PragmaPoisonHandler : public PragmaHandler { PragmaPoisonHandler() : PragmaHandler("poison") {} - virtual void HandlePragma(Preprocessor &PP, Token &PoisonTok) { + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &PoisonTok) { PP.HandlePragmaPoison(PoisonTok); } }; @@ -731,21 +739,24 @@ struct PragmaPoisonHandler : public PragmaHandler { /// as a system header, which silences warnings in it. struct PragmaSystemHeaderHandler : public PragmaHandler { PragmaSystemHeaderHandler() : PragmaHandler("system_header") {} - virtual void HandlePragma(Preprocessor &PP, Token &SHToken) { + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &SHToken) { PP.HandlePragmaSystemHeader(SHToken); PP.CheckEndOfDirective("pragma"); } }; struct PragmaDependencyHandler : public PragmaHandler { PragmaDependencyHandler() : PragmaHandler("dependency") {} - virtual void HandlePragma(Preprocessor &PP, Token &DepToken) { + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &DepToken) { PP.HandlePragmaDependency(DepToken); } }; struct PragmaDebugHandler : public PragmaHandler { PragmaDebugHandler() : PragmaHandler("__debug") {} - virtual void HandlePragma(Preprocessor &PP, Token &DepToken) { + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &DepToken) { Token Tok; PP.LexUnexpandedToken(Tok); if (Tok.isNot(tok::identifier)) { @@ -783,7 +794,8 @@ struct PragmaDebugHandler : public PragmaHandler { struct PragmaDiagnosticHandler : public PragmaHandler { public: explicit PragmaDiagnosticHandler() : PragmaHandler("diagnostic") {} - virtual void HandlePragma(Preprocessor &PP, Token &DiagToken) { + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &DiagToken) { Token Tok; PP.LexUnexpandedToken(Tok); if (Tok.isNot(tok::identifier)) { @@ -866,7 +878,8 @@ public: /// PragmaCommentHandler - "#pragma comment ...". struct PragmaCommentHandler : public PragmaHandler { PragmaCommentHandler() : PragmaHandler("comment") {} - virtual void HandlePragma(Preprocessor &PP, Token &CommentTok) { + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &CommentTok) { PP.HandlePragmaComment(CommentTok); } }; @@ -874,7 +887,8 @@ struct PragmaCommentHandler : public PragmaHandler { /// PragmaMessageHandler - "#pragma message("...")". struct PragmaMessageHandler : public PragmaHandler { PragmaMessageHandler() : PragmaHandler("message") {} - virtual void HandlePragma(Preprocessor &PP, Token &CommentTok) { + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &CommentTok) { PP.HandlePragmaMessage(CommentTok); } }; @@ -883,7 +897,8 @@ struct PragmaMessageHandler : public PragmaHandler { /// macro on the top of the stack. struct PragmaPushMacroHandler : public PragmaHandler { PragmaPushMacroHandler() : PragmaHandler("push_macro") {} - virtual void HandlePragma(Preprocessor &PP, Token &PushMacroTok) { + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &PushMacroTok) { PP.HandlePragmaPushMacro(PushMacroTok); } }; @@ -893,7 +908,8 @@ struct PragmaPushMacroHandler : public PragmaHandler { /// macro to the value on the top of the stack. struct PragmaPopMacroHandler : public PragmaHandler { PragmaPopMacroHandler() : PragmaHandler("pop_macro") {} - virtual void HandlePragma(Preprocessor &PP, Token &PopMacroTok) { + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &PopMacroTok) { PP.HandlePragmaPopMacro(PopMacroTok); } }; @@ -935,7 +951,8 @@ static STDCSetting LexOnOffSwitch(Preprocessor &PP) { /// PragmaSTDC_FP_CONTRACTHandler - "#pragma STDC FP_CONTRACT ...". struct PragmaSTDC_FP_CONTRACTHandler : public PragmaHandler { PragmaSTDC_FP_CONTRACTHandler() : PragmaHandler("FP_CONTRACT") {} - virtual void HandlePragma(Preprocessor &PP, Token &Tok) { + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &Tok) { // We just ignore the setting of FP_CONTRACT. Since we don't do contractions // at all, our default is OFF and setting it to ON is an optimization hint // we can safely ignore. When we support -ffma or something, we would need @@ -947,7 +964,8 @@ struct PragmaSTDC_FP_CONTRACTHandler : public PragmaHandler { /// PragmaSTDC_FENV_ACCESSHandler - "#pragma STDC FENV_ACCESS ...". struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler { PragmaSTDC_FENV_ACCESSHandler() : PragmaHandler("FENV_ACCESS") {} - virtual void HandlePragma(Preprocessor &PP, Token &Tok) { + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &Tok) { if (LexOnOffSwitch(PP) == STDC_ON) PP.Diag(Tok, diag::warn_stdc_fenv_access_not_supported); } @@ -957,7 +975,8 @@ struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler { struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler { PragmaSTDC_CX_LIMITED_RANGEHandler() : PragmaHandler("CX_LIMITED_RANGE") {} - virtual void HandlePragma(Preprocessor &PP, Token &Tok) { + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &Tok) { LexOnOffSwitch(PP); } }; @@ -965,7 +984,8 @@ struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler { /// PragmaSTDC_UnknownHandler - "#pragma STDC ...". struct PragmaSTDC_UnknownHandler : public PragmaHandler { PragmaSTDC_UnknownHandler() {} - virtual void HandlePragma(Preprocessor &PP, Token &UnknownTok) { + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &UnknownTok) { // C99 6.10.6p2, unknown forms are not allowed. PP.Diag(UnknownTok, diag::ext_stdc_pragma_ignored); } diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp index ddba09ae0f..42c1c5f5a2 100644 --- a/lib/Parse/ParsePragma.cpp +++ b/lib/Parse/ParsePragma.cpp @@ -21,7 +21,9 @@ using namespace clang; // #pragma GCC visibility comes in two variants: // 'push' '(' [visibility] ')' // 'pop' -void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP, Token &VisTok) { +void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP, + PragmaIntroducerKind Introducer, + Token &VisTok) { SourceLocation VisLoc = VisTok.getLocation(); Token Tok; @@ -74,7 +76,9 @@ void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP, Token &VisTok) { // pack '(' [integer] ')' // pack '(' 'show' ')' // pack '(' ('push' | 'pop') [',' identifier] [, integer] ')' -void PragmaPackHandler::HandlePragma(Preprocessor &PP, Token &PackTok) { +void PragmaPackHandler::HandlePragma(Preprocessor &PP, + PragmaIntroducerKind Introducer, + Token &PackTok) { SourceLocation PackLoc = PackTok.getLocation(); Token Tok; @@ -222,16 +226,22 @@ static void ParseAlignPragma(Sema &Actions, Preprocessor &PP, Token &FirstTok, Actions.ActOnPragmaOptionsAlign(Kind, FirstTok.getLocation(), KindLoc); } -void PragmaAlignHandler::HandlePragma(Preprocessor &PP, Token &AlignTok) { +void PragmaAlignHandler::HandlePragma(Preprocessor &PP, + PragmaIntroducerKind Introducer, + Token &AlignTok) { ParseAlignPragma(Actions, PP, AlignTok, /*IsOptions=*/false); } -void PragmaOptionsHandler::HandlePragma(Preprocessor &PP, Token &OptionsTok) { +void PragmaOptionsHandler::HandlePragma(Preprocessor &PP, + PragmaIntroducerKind Introducer, + Token &OptionsTok) { ParseAlignPragma(Actions, PP, OptionsTok, /*IsOptions=*/true); } // #pragma unused(identifier) -void PragmaUnusedHandler::HandlePragma(Preprocessor &PP, Token &UnusedTok) { +void PragmaUnusedHandler::HandlePragma(Preprocessor &PP, + PragmaIntroducerKind Introducer, + Token &UnusedTok) { // FIXME: Should we be expanding macros here? My guess is no. SourceLocation UnusedLoc = UnusedTok.getLocation(); @@ -298,7 +308,9 @@ void PragmaUnusedHandler::HandlePragma(Preprocessor &PP, Token &UnusedTok) { // #pragma weak identifier // #pragma weak identifier '=' identifier -void PragmaWeakHandler::HandlePragma(Preprocessor &PP, Token &WeakTok) { +void PragmaWeakHandler::HandlePragma(Preprocessor &PP, + PragmaIntroducerKind Introducer, + Token &WeakTok) { // FIXME: Should we be expanding macros here? My guess is no. SourceLocation WeakLoc = WeakTok.getLocation(); diff --git a/lib/Parse/ParsePragma.h b/lib/Parse/ParsePragma.h index 0feaa9919e..9dfaceaead 100644 --- a/lib/Parse/ParsePragma.h +++ b/lib/Parse/ParsePragma.h @@ -25,7 +25,8 @@ class PragmaAlignHandler : public PragmaHandler { public: explicit PragmaAlignHandler(Sema &A) : PragmaHandler("align"), Actions(A) {} - virtual void HandlePragma(Preprocessor &PP, Token &FirstToken); + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &FirstToken); }; class PragmaGCCVisibilityHandler : public PragmaHandler { @@ -34,7 +35,8 @@ public: explicit PragmaGCCVisibilityHandler(Sema &A) : PragmaHandler("visibility"), Actions(A) {} - virtual void HandlePragma(Preprocessor &PP, Token &FirstToken); + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &FirstToken); }; class PragmaOptionsHandler : public PragmaHandler { @@ -43,7 +45,8 @@ public: explicit PragmaOptionsHandler(Sema &A) : PragmaHandler("options"), Actions(A) {} - virtual void HandlePragma(Preprocessor &PP, Token &FirstToken); + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &FirstToken); }; class PragmaPackHandler : public PragmaHandler { @@ -52,7 +55,8 @@ public: explicit PragmaPackHandler(Sema &A) : PragmaHandler("pack"), Actions(A) {} - virtual void HandlePragma(Preprocessor &PP, Token &FirstToken); + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &FirstToken); }; class PragmaUnusedHandler : public PragmaHandler { @@ -62,7 +66,8 @@ public: PragmaUnusedHandler(Sema &A, Parser& p) : PragmaHandler("unused"), Actions(A), parser(p) {} - virtual void HandlePragma(Preprocessor &PP, Token &FirstToken); + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &FirstToken); }; class PragmaWeakHandler : public PragmaHandler { @@ -71,7 +76,8 @@ public: explicit PragmaWeakHandler(Sema &A) : PragmaHandler("weak"), Actions(A) {} - virtual void HandlePragma(Preprocessor &PP, Token &FirstToken); + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &FirstToken); }; } // end namespace clang |