aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-09-09 22:45:38 +0000
committerDouglas Gregor <dgregor@apple.com>2010-09-09 22:45:38 +0000
commit80c60f72848896f867f6b7e664e7060d9e78f019 (patch)
treef485a7c8e94a54a3095e9bc3be9be852db88a2ef /lib
parent748de8eda222f087434d8bd703176b316a061341 (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.cpp24
-rw-r--r--lib/Lex/PPDirectives.cpp3
-rw-r--r--lib/Lex/Pragma.cpp68
-rw-r--r--lib/Parse/ParsePragma.cpp24
-rw-r--r--lib/Parse/ParsePragma.h18
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