summaryrefslogtreecommitdiffstats
path: root/lib/Lex/Pragma.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Lex/Pragma.cpp')
-rw-r--r--lib/Lex/Pragma.cpp208
1 files changed, 116 insertions, 92 deletions
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index a7b289e..f0475bc 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);
}
@@ -287,7 +292,7 @@ void Preprocessor::HandlePragmaPoison(Token &PoisonTok) {
if (Tok.is(tok::eom)) return;
// Can only poison identifiers.
- if (Tok.isNot(tok::identifier)) {
+ if (Tok.isNot(tok::raw_identifier)) {
Diag(Tok, diag::err_pp_invalid_poison);
return;
}
@@ -324,6 +329,9 @@ void Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {
PresumedLoc PLoc = SourceMgr.getPresumedLoc(SysHeaderTok.getLocation());
+ if (PLoc.isInvalid())
+ return;
+
unsigned FilenameLen = strlen(PLoc.getFilename());
unsigned FilenameID = SourceMgr.getLineTableFilenameID(PLoc.getFilename(),
FilenameLen);
@@ -478,23 +486,32 @@ void Preprocessor::HandlePragmaComment(Token &Tok) {
Callbacks->PragmaComment(CommentLoc, II, ArgumentString);
}
-/// HandlePragmaMessage - Handle the microsoft #pragma message extension. The
-/// syntax is:
-/// #pragma message(messagestring)
-/// messagestring is a string, which is fully macro expanded, and permits string
-/// concatenation, embedded escape characters etc. See MSDN for more details.
+/// HandlePragmaMessage - Handle the microsoft and gcc #pragma message
+/// extension. The syntax is:
+/// #pragma message(string)
+/// OR, in GCC mode:
+/// #pragma message string
+/// string is a string, which is fully macro expanded, and permits string
+/// concatenation, embedded escape characters, etc... See MSDN for more details.
void Preprocessor::HandlePragmaMessage(Token &Tok) {
SourceLocation MessageLoc = Tok.getLocation();
Lex(Tok);
- if (Tok.isNot(tok::l_paren)) {
+ bool ExpectClosingParen = false;
+ switch (Tok.getKind()) {
+ case tok::l_paren:
+ // We have a MSVC style pragma message.
+ ExpectClosingParen = true;
+ // Read the string.
+ Lex(Tok);
+ break;
+ case tok::string_literal:
+ // We have a GCC style pragma message, and we just read the string.
+ break;
+ default:
Diag(MessageLoc, diag::err_pragma_message_malformed);
return;
}
- // Read the string.
- Lex(Tok);
-
-
// We need at least one string.
if (Tok.isNot(tok::string_literal)) {
Diag(Tok.getLocation(), diag::err_pragma_message_malformed);
@@ -522,11 +539,13 @@ void Preprocessor::HandlePragmaMessage(Token &Tok) {
llvm::StringRef MessageString(Literal.GetString(), Literal.GetStringLength());
- if (Tok.isNot(tok::r_paren)) {
- Diag(Tok.getLocation(), diag::err_pragma_message_malformed);
- return;
+ if (ExpectClosingParen) {
+ if (Tok.isNot(tok::r_paren)) {
+ Diag(Tok.getLocation(), diag::err_pragma_message_malformed);
+ return;
+ }
+ Lex(Tok); // eat the r_paren.
}
- Lex(Tok); // eat the r_paren.
if (Tok.isNot(tok::eom)) {
Diag(Tok.getLocation(), diag::err_pragma_message_malformed);
@@ -580,7 +599,7 @@ IdentifierInfo *Preprocessor::ParsePragmaPushOrPopMacro(Token &Tok) {
// Create a Token from the string.
Token MacroTok;
MacroTok.startToken();
- MacroTok.setKind(tok::identifier);
+ MacroTok.setKind(tok::raw_identifier);
CreateString(&StrVal[1], StrVal.size() - 2, MacroTok);
// Get the IdentifierInfo of MacroToPushTok.
@@ -611,7 +630,7 @@ void Preprocessor::HandlePragmaPushMacro(Token &PushMacroTok) {
PragmaPushMacroInfo[IdentInfo].push_back(MacroCopyToPush);
}
-/// HandlePragmaPopMacro - Handle #pragma push_macro.
+/// HandlePragmaPopMacro - Handle #pragma pop_macro.
/// The syntax is:
/// #pragma pop_macro("macro")
void Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) {
@@ -627,7 +646,11 @@ void Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) {
if (iter != PragmaPushMacroInfo.end()) {
// Release the MacroInfo currently associated with IdentInfo.
MacroInfo *CurrentMI = getMacroInfo(IdentInfo);
- if (CurrentMI) ReleaseMacroInfo(CurrentMI);
+ if (CurrentMI) {
+ if (CurrentMI->isWarnIfUnused())
+ WarnUnusedMacroLocs.erase(CurrentMI->getDefinitionLoc());
+ ReleaseMacroInfo(CurrentMI);
+ }
// Get the MacroInfo we want to reinstall.
MacroInfo *MacroToReInstall = iter->second.back();
@@ -700,11 +723,39 @@ void Preprocessor::RemovePragmaHandler(llvm::StringRef Namespace,
PragmaHandlers->RemovePragmaHandler(NS);
}
+bool Preprocessor::LexOnOffSwitch(tok::OnOffSwitch &Result) {
+ Token Tok;
+ LexUnexpandedToken(Tok);
+
+ if (Tok.isNot(tok::identifier)) {
+ Diag(Tok, diag::ext_on_off_switch_syntax);
+ return true;
+ }
+ IdentifierInfo *II = Tok.getIdentifierInfo();
+ if (II->isStr("ON"))
+ Result = tok::OOS_ON;
+ else if (II->isStr("OFF"))
+ Result = tok::OOS_OFF;
+ else if (II->isStr("DEFAULT"))
+ Result = tok::OOS_DEFAULT;
+ else {
+ Diag(Tok, diag::ext_on_off_switch_syntax);
+ return true;
+ }
+
+ // Verify that this is followed by EOM.
+ LexUnexpandedToken(Tok);
+ if (Tok.isNot(tok::eom))
+ Diag(Tok, diag::ext_pragma_syntax_eom);
+ return false;
+}
+
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 +765,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 +774,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 +784,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 +839,9 @@ 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) {
+ SourceLocation DiagLoc = DiagToken.getLocation();
Token Tok;
PP.LexUnexpandedToken(Tok);
if (Tok.isNot(tok::identifier)) {
@@ -802,12 +860,12 @@ public:
else if (II->isStr("fatal"))
Map = diag::MAP_FATAL;
else if (II->isStr("pop")) {
- if (!PP.getDiagnostics().popMappings())
+ if (!PP.getDiagnostics().popMappings(DiagLoc))
PP.Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
return;
} else if (II->isStr("push")) {
- PP.getDiagnostics().pushMappings();
+ PP.getDiagnostics().pushMappings(DiagLoc);
return;
} else {
PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
@@ -857,7 +915,7 @@ public:
}
if (PP.getDiagnostics().setDiagnosticGroupMapping(WarningName.c_str()+2,
- Map))
+ Map, DiagLoc))
PP.Diag(StrToks[0].getLocation(),
diag::warn_pragma_diagnostic_unknown_warning) << WarningName;
}
@@ -866,7 +924,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 +933,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 +943,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,62 +954,23 @@ 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);
}
};
// Pragma STDC implementations.
-enum STDCSetting {
- STDC_ON, STDC_OFF, STDC_DEFAULT, STDC_INVALID
-};
-
-static STDCSetting LexOnOffSwitch(Preprocessor &PP) {
- Token Tok;
- PP.LexUnexpandedToken(Tok);
-
- if (Tok.isNot(tok::identifier)) {
- PP.Diag(Tok, diag::ext_stdc_pragma_syntax);
- return STDC_INVALID;
- }
- IdentifierInfo *II = Tok.getIdentifierInfo();
- STDCSetting Result;
- if (II->isStr("ON"))
- Result = STDC_ON;
- else if (II->isStr("OFF"))
- Result = STDC_OFF;
- else if (II->isStr("DEFAULT"))
- Result = STDC_DEFAULT;
- else {
- PP.Diag(Tok, diag::ext_stdc_pragma_syntax);
- return STDC_INVALID;
- }
-
- // Verify that this is followed by EOM.
- PP.LexUnexpandedToken(Tok);
- if (Tok.isNot(tok::eom))
- PP.Diag(Tok, diag::ext_stdc_pragma_syntax_eom);
- return Result;
-}
-
-/// 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) {
- // 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
- // to diagnose that we are ignoring FMA.
- LexOnOffSwitch(PP);
- }
-};
-
/// 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) {
- if (LexOnOffSwitch(PP) == STDC_ON)
+ virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+ Token &Tok) {
+ tok::OnOffSwitch OOS;
+ if (PP.LexOnOffSwitch(OOS))
+ return;
+ if (OOS == tok::OOS_ON)
PP.Diag(Tok, diag::warn_stdc_fenv_access_not_supported);
}
};
@@ -957,15 +979,18 @@ 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) {
- LexOnOffSwitch(PP);
+ virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+ Token &Tok) {
+ tok::OnOffSwitch OOS;
+ PP.LexOnOffSwitch(OOS);
}
};
/// 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);
}
@@ -981,6 +1006,7 @@ void Preprocessor::RegisterBuiltinPragmas() {
AddPragmaHandler(new PragmaMarkHandler());
AddPragmaHandler(new PragmaPushMacroHandler());
AddPragmaHandler(new PragmaPopMacroHandler());
+ AddPragmaHandler(new PragmaMessageHandler());
// #pragma GCC ...
AddPragmaHandler("GCC", new PragmaPoisonHandler());
@@ -994,7 +1020,6 @@ void Preprocessor::RegisterBuiltinPragmas() {
AddPragmaHandler("clang", new PragmaDependencyHandler());
AddPragmaHandler("clang", new PragmaDiagnosticHandler());
- AddPragmaHandler("STDC", new PragmaSTDC_FP_CONTRACTHandler());
AddPragmaHandler("STDC", new PragmaSTDC_FENV_ACCESSHandler());
AddPragmaHandler("STDC", new PragmaSTDC_CX_LIMITED_RANGEHandler());
AddPragmaHandler("STDC", new PragmaSTDC_UnknownHandler());
@@ -1002,6 +1027,5 @@ void Preprocessor::RegisterBuiltinPragmas() {
// MS extensions.
if (Features.Microsoft) {
AddPragmaHandler(new PragmaCommentHandler());
- AddPragmaHandler(new PragmaMessageHandler());
}
}
OpenPOWER on IntegriCloud