23 #include "llvm/ADT/STLExtras.h"
24 #include "llvm/ADT/StringSwitch.h"
25 #include "llvm/ADT/StringExtras.h"
26 #include "llvm/Support/CrashRecoveryContext.h"
27 #include "llvm/Support/ErrorHandling.h"
29 using namespace clang;
31 #include "llvm/Support/raw_ostream.h"
52 llvm::DeleteContainerSeconds(Handlers);
60 bool IgnoreNull)
const {
63 return IgnoreNull ?
nullptr : Handlers.lookup(StringRef());
67 assert(!Handlers.lookup(Handler->
getName()) &&
68 "A handler with this name is already registered in this namespace");
69 Handlers[Handler->
getName()] = Handler;
73 assert(Handlers.lookup(Handler->
getName()) &&
74 "Handler not registered in this namespace");
75 Handlers.erase(Handler->
getName());
91 PP.
Diag(Tok, diag::warn_pragma_ignored);
105 void Preprocessor::HandlePragmaDirective(
SourceLocation IntroducerLoc,
108 Callbacks->PragmaDirective(IntroducerLoc, Introducer);
117 PragmaHandlers->HandlePragma(*
this, Introducer, Tok);
120 if ((CurTokenLexer && CurTokenLexer->isParsingPreprocessorDirective())
127 class LexingFor_PragmaRAII {
129 bool InMacroArgPreExpansion;
135 LexingFor_PragmaRAII(
Preprocessor &PP,
bool InMacroArgPreExpansion,
137 : PP(PP), InMacroArgPreExpansion(InMacroArgPreExpansion),
138 Failed(
false), OutTok(Tok) {
139 if (InMacroArgPreExpansion) {
145 ~LexingFor_PragmaRAII() {
146 if (InMacroArgPreExpansion) {
165 void Preprocessor::Handle_Pragma(
Token &Tok) {
178 LexingFor_PragmaRAII _PragmaLexing(*
this, InMacroArgPreExpansion, Tok);
185 if (Tok.
isNot(tok::l_paren)) {
186 Diag(PragmaLoc, diag::err__Pragma_malformed);
187 return _PragmaLexing.failed();
193 Diag(PragmaLoc, diag::err__Pragma_malformed);
197 if (Tok.
is(tok::r_paren))
199 return _PragmaLexing.failed();
203 Diag(Tok, diag::err_invalid_string_udl);
206 if (Tok.
is(tok::r_paren))
208 return _PragmaLexing.failed();
216 if (Tok.
isNot(tok::r_paren)) {
217 Diag(PragmaLoc, diag::err__Pragma_malformed);
218 return _PragmaLexing.failed();
221 if (InMacroArgPreExpansion)
232 if (StrVal[0] ==
'L' || StrVal[0] ==
'U' ||
233 (StrVal[0] ==
'u' && StrVal[1] !=
'8'))
234 StrVal.erase(StrVal.begin());
235 else if (StrVal[0] ==
'u')
236 StrVal.erase(StrVal.begin(), StrVal.begin() + 2);
238 if (StrVal[0] ==
'R') {
241 assert(StrVal[1] ==
'"' && StrVal[StrVal.size() - 1] ==
'"' &&
242 "Invalid raw string token!");
245 unsigned NumDChars = 0;
246 while (StrVal[2 + NumDChars] !=
'(') {
247 assert(NumDChars < (StrVal.size() - 5) / 2 &&
248 "Invalid raw string token!");
251 assert(StrVal[StrVal.size() - 2 - NumDChars] ==
')');
255 StrVal.erase(0, 2 + NumDChars);
256 StrVal.erase(StrVal.size() - 1 - NumDChars);
258 assert(StrVal[0] ==
'"' && StrVal[StrVal.size()-1] ==
'"' &&
259 "Invalid string token!");
262 unsigned ResultPos = 1;
263 for (
unsigned i = 1, e = StrVal.size() - 1; i != e; ++i) {
265 if (StrVal[i] ==
'\\' && i + 1 < e &&
266 (StrVal[i + 1] ==
'\\' || StrVal[i + 1] ==
'"'))
268 StrVal[ResultPos++] = StrVal[i];
270 StrVal.erase(StrVal.begin() + ResultPos, StrVal.end() - 1);
278 StrVal[StrVal.size()-1] =
'\n';
290 StrVal.size(), *
this);
292 EnterSourceFileWithLexer(TL,
nullptr);
303 void Preprocessor::HandleMicrosoft__pragma(
Token &Tok) {
309 if (Tok.
isNot(tok::l_paren)) {
310 Diag(PragmaLoc, diag::err__Pragma_malformed);
319 PragmaToks.push_back(Tok);
320 if (Tok.
is(tok::l_paren))
322 else if (Tok.
is(tok::r_paren) && NumParens-- == 0)
328 Diag(PragmaLoc, diag::err_unterminated___pragma);
335 PragmaToks.back().setKind(tok::eod);
337 Token *TokArray =
new Token[PragmaToks.size()];
338 std::copy(PragmaToks.begin(), PragmaToks.end(), TokArray);
354 Diag(OnceTok, diag::pp_pragma_once_in_main_file);
364 assert(CurPPLexer &&
"No current lexer?");
366 CurLexer->ReadToEndOfLine();
368 CurPTHLexer->DiscardToEndOfLine();
388 if (Tok.
is(tok::eod))
return;
391 if (Tok.
isNot(tok::raw_identifier)) {
392 Diag(Tok, diag::err_pp_invalid_poison);
405 Diag(Tok, diag::pp_poisoning_existing_macro);
418 Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
444 FilenameID,
false,
false,
455 if (FilenameTok.
is(tok::eod))
460 bool Invalid =
false;
461 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer, &Invalid);
469 if (Filename.empty())
476 nullptr, CurDir,
nullptr,
nullptr,
nullptr);
478 if (!SuppressIncludeNotFoundError)
479 Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
490 while (DependencyTok.
isNot(tok::eod)) {
496 if (!Message.empty())
497 Message.erase(Message.end()-1);
498 Diag(FilenameTok, diag::pp_out_of_date_dependency) << Message;
506 Token PragmaTok = Tok;
510 if (Tok.
isNot(tok::l_paren)) {
511 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
518 if (Tok.
isNot(tok::string_literal)) {
519 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
525 Diag(Tok, diag::err_invalid_string_udl);
534 if (Tok.
isNot(tok::r_paren)) {
535 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
540 assert(StrVal[0] ==
'"' && StrVal[StrVal.size()-1] ==
'"' &&
541 "Invalid string token!");
546 MacroTok.setKind(tok::raw_identifier);
547 CreateString(StringRef(&StrVal[1], StrVal.size() - 2), MacroTok);
562 if (!IdentInfo)
return;
573 PragmaPushMacroInfo[IdentInfo].push_back(MI);
587 if (!IdentInfo)
return;
590 llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> >::iterator iter =
591 PragmaPushMacroInfo.find(IdentInfo);
592 if (iter != PragmaPushMacroInfo.end()) {
595 if (MI->isWarnIfUnused())
596 WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
601 MacroInfo *MacroToReInstall = iter->second.back();
603 if (MacroToReInstall)
608 iter->second.pop_back();
609 if (iter->second.size() == 0)
610 PragmaPushMacroInfo.erase(iter);
612 Diag(MessageLoc, diag::warn_pragma_pop_macro_no_push)
625 if (Tok.
isNot(tok::l_paren)) {
626 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
"(";
631 Token SourceFilenameTok;
633 if (SourceFilenameTok.
is(tok::eod)) {
638 StringRef SourceFileName;
640 if (SourceFilenameTok.
is(tok::string_literal) ||
641 SourceFilenameTok.
is(tok::angle_string_literal)) {
642 SourceFileName =
getSpelling(SourceFilenameTok, FileNameBuffer);
643 }
else if (SourceFilenameTok.
is(tok::less)) {
645 FileNameBuffer.push_back(
'<');
649 SourceFileName = FileNameBuffer;
651 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
654 FileNameBuffer.clear();
658 if (Tok.
isNot(tok::comma)) {
659 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
",";
663 Token ReplaceFilenameTok;
665 if (ReplaceFilenameTok.
is(tok::eod)) {
670 StringRef ReplaceFileName;
671 if (ReplaceFilenameTok.
is(tok::string_literal) ||
672 ReplaceFilenameTok.
is(tok::angle_string_literal)) {
673 ReplaceFileName =
getSpelling(ReplaceFilenameTok, FileNameBuffer);
674 }
else if (ReplaceFilenameTok.
is(tok::less)) {
676 FileNameBuffer.push_back(
'<');
680 ReplaceFileName = FileNameBuffer;
682 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
688 if (Tok.
isNot(tok::r_paren)) {
689 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
")";
695 StringRef OriginalSource = SourceFileName;
697 bool SourceIsAngled =
700 bool ReplaceIsAngled =
703 if (!SourceFileName.empty() && !ReplaceFileName.empty() &&
704 (SourceIsAngled != ReplaceIsAngled)) {
707 DiagID = diag::warn_pragma_include_alias_mismatch_angle;
709 DiagID = diag::warn_pragma_include_alias_mismatch_quote;
730 if (!Namespace.empty()) {
734 if (
PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace)) {
736 assert(InsertNS !=
nullptr &&
"Cannot have a pragma namespace and pragma"
737 " handler with the same name!");
742 PragmaHandlers->AddPragma(InsertNS);
748 "Pragma handler already exists for this identifier!");
761 if (!Namespace.empty()) {
762 PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace);
763 assert(Existing &&
"Namespace containing handler does not exist!");
766 assert(NS &&
"Invalid namespace, registered as a regular pragma handler!");
772 if (NS != PragmaHandlers.get() && NS->
IsEmpty()) {
773 PragmaHandlers->RemovePragmaHandler(NS);
782 if (Tok.
isNot(tok::identifier)) {
783 Diag(Tok, diag::ext_on_off_switch_syntax);
789 else if (II->
isStr(
"OFF"))
791 else if (II->
isStr(
"DEFAULT"))
794 Diag(Tok, diag::ext_on_off_switch_syntax);
800 if (Tok.
isNot(tok::eod))
801 Diag(Tok, diag::ext_pragma_syntax_eod);
810 Token &OnceTok)
override {
821 Token &MarkTok)
override {
830 Token &PoisonTok)
override {
838 PragmaSystemHeaderHandler() :
PragmaHandler(
"system_header") {}
840 Token &SHToken)
override {
848 Token &DepToken)
override {
856 Token &DepToken)
override {
859 if (Tok.
isNot(tok::identifier)) {
860 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
865 if (II->
isStr(
"assert")) {
866 llvm_unreachable(
"This is an assertion!");
867 }
else if (II->
isStr(
"crash")) {
869 }
else if (II->
isStr(
"parser_crash")) {
872 Crasher.
setKind(tok::annot_pragma_parser_crash);
875 }
else if (II->
isStr(
"llvm_fatal_error")) {
876 llvm::report_fatal_error(
"#pragma clang __debug llvm_fatal_error");
877 }
else if (II->
isStr(
"llvm_unreachable")) {
878 llvm_unreachable(
"#pragma clang __debug llvm_unreachable");
879 }
else if (II->
isStr(
"macro")) {
886 PP.
Diag(MacroName, diag::warn_pragma_diagnostic_invalid);
887 }
else if (II->
isStr(
"overflow_stack")) {
888 DebugOverflowStack();
889 }
else if (II->
isStr(
"handle_crash")) {
890 llvm::CrashRecoveryContext *CRC =llvm::CrashRecoveryContext::GetCurrent();
893 }
else if (II->
isStr(
"captured")) {
896 PP.
Diag(Tok, diag::warn_pragma_debug_unexpected_command)
913 if (Tok.
isNot(tok::eod)) {
914 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol)
915 <<
"pragma clang __debug captured";
922 Toks->
setKind(tok::annot_pragma_captured);
931 #pragma warning(disable : 4717)
933 static void DebugOverflowStack() {
934 void (*
volatile Self)() = DebugOverflowStack;
938 #pragma warning(default : 4717)
946 const char *Namespace;
948 explicit PragmaDiagnosticHandler(
const char *NS) :
951 Token &DiagToken)
override {
955 if (Tok.
isNot(tok::identifier)) {
956 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
962 if (II->
isStr(
"pop")) {
964 PP.
Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
968 }
else if (II->
isStr(
"push")) {
983 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
990 std::string WarningName;
995 if (Tok.
isNot(tok::eod)) {
996 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_diagnostic_invalid_token);
1000 if (WarningName.size() < 3 || WarningName[0] !=
'-' ||
1001 (WarningName[1] !=
'W' && WarningName[1] !=
'R')) {
1002 PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_invalid_option);
1009 WarningName.substr(2), SV, DiagLoc))
1010 PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_unknown_warning)
1024 Token &Tok)
override {
1033 if (Tok.
isNot(tok::l_paren)) {
1034 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
"(";
1041 if (II && II->
isStr(
"push")) {
1045 if (Tok.
is(tok::comma)) {
1048 if (Tok.
is(tok::numeric_constant) &&
1051 if (Level < 0 || Level > 4) {
1052 PP.
Diag(Tok, diag::warn_pragma_warning_push_level);
1058 }
else if (II && II->
isStr(
"pop")) {
1068 if (!II && !Tok.
is(tok::numeric_constant)) {
1069 PP.
Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1074 bool SpecifierValid;
1075 StringRef Specifier;
1079 SpecifierValid = llvm::StringSwitch<bool>(Specifier)
1080 .Cases(
"default",
"disable",
"error",
"once",
1092 SpecifierValid = (Value >= 1) && (Value <= 4);
1094 SpecifierValid =
false;
1098 if (!SpecifierValid) {
1099 PP.
Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1102 if (Tok.
isNot(tok::colon)) {
1103 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
":";
1110 while (Tok.
is(tok::numeric_constant)) {
1114 PP.
Diag(Tok, diag::warn_pragma_warning_expected_number);
1117 Ids.push_back(
int(Value));
1123 if (Tok.
isNot(tok::semi))
1129 if (Tok.
isNot(tok::r_paren)) {
1130 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
")";
1135 if (Tok.
isNot(tok::eod))
1136 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma warning";
1142 PragmaIncludeAliasHandler() :
PragmaHandler(
"include_alias") {}
1144 Token &IncludeAliasTok)
override {
1165 const StringRef Namespace;
1168 bool PragmaNameOnly =
false) {
1171 return PragmaNameOnly ?
"message" :
"pragma message";
1173 return PragmaNameOnly ?
"warning" :
"pragma warning";
1175 return PragmaNameOnly ?
"error" :
"pragma error";
1177 llvm_unreachable(
"Unknown PragmaMessageKind!");
1182 StringRef Namespace = StringRef())
1186 Token &Tok)
override {
1189 bool ExpectClosingParen =
false;
1193 ExpectClosingParen =
true;
1197 case tok::string_literal:
1201 PP.
Diag(MessageLoc, diag::err_pragma_message_malformed) <<
Kind;
1205 std::string MessageString;
1210 if (ExpectClosingParen) {
1211 if (Tok.
isNot(tok::r_paren)) {
1212 PP.
Diag(Tok.
getLocation(), diag::err_pragma_message_malformed) << Kind;
1218 if (Tok.
isNot(tok::eod)) {
1219 PP.
Diag(Tok.
getLocation(), diag::err_pragma_message_malformed) << Kind;
1225 ? diag::err_pragma_message
1226 : diag::warn_pragma_message) << MessageString;
1230 Callbacks->
PragmaMessage(MessageLoc, Namespace, Kind, MessageString);
1239 Token &PushMacroTok)
override {
1250 Token &PopMacroTok)
override {
1258 struct PragmaSTDC_FENV_ACCESSHandler :
public PragmaHandler {
1259 PragmaSTDC_FENV_ACCESSHandler() :
PragmaHandler(
"FENV_ACCESS") {}
1261 Token &Tok)
override {
1266 PP.
Diag(Tok, diag::warn_stdc_fenv_access_not_supported);
1271 struct PragmaSTDC_CX_LIMITED_RANGEHandler :
public PragmaHandler {
1272 PragmaSTDC_CX_LIMITED_RANGEHandler()
1275 Token &Tok)
override {
1283 PragmaSTDC_UnknownHandler() {}
1285 Token &UnknownTok)
override {
1287 PP.
Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
1293 struct PragmaARCCFCodeAuditedHandler :
public PragmaHandler {
1294 PragmaARCCFCodeAuditedHandler() :
PragmaHandler(
"arc_cf_code_audited") {}
1296 Token &NameTok)
override {
1305 if (BeginEnd && BeginEnd->
isStr(
"begin")) {
1307 }
else if (BeginEnd && BeginEnd->
isStr(
"end")) {
1316 if (Tok.
isNot(tok::eod))
1317 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1328 PP.
Diag(Loc, diag::err_pp_double_begin_of_arc_cf_code_audited);
1329 PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1335 PP.
Diag(Loc, diag::err_pp_unmatched_end_of_arc_cf_code_audited);
1348 PragmaAssumeNonNullHandler() :
PragmaHandler(
"assume_nonnull") {}
1350 Token &NameTok)
override {
1359 if (BeginEnd && BeginEnd->
isStr(
"begin")) {
1361 }
else if (BeginEnd && BeginEnd->
isStr(
"end")) {
1370 if (Tok.
isNot(tok::eod))
1371 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1382 PP.
Diag(Loc, diag::err_pp_double_begin_of_assume_nonnull);
1383 PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1389 PP.
Diag(Loc, diag::err_pp_unmatched_end_of_assume_nonnull);
1411 PragmaRegionHandler(
const char *pragma) :
PragmaHandler(pragma) { }
1414 Token &NameTok)
override {
1427 void Preprocessor::RegisterBuiltinPragmas() {
1457 if (LangOpts.MicrosoftExt) {
1473 if (
PragmaHandler *NS = PragmaHandlers->FindHandler(
"STDC")) {
1478 assert(STDCNamespace &&
1479 "Invalid namespace, registered as a regular pragma handler!");
StringRef getName() const
bool isPoisoned() const
Return true if this token has been poisoned.
llvm::BumpPtrAllocator & getPreprocessorAllocator()
virtual void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace)
Callback invoked when a #pragma gcc dianostic pop directive is read.
bool ConcatenateIncludeName(SmallString< 128 > &FilenameBuffer, SourceLocation &End)
Handle cases where the #include name is expanded from a macro as multiple tokens, which need to be gl...
void setChangedSinceDeserialization()
Note that this identifier has changed since it was loaded from an AST file.
void pushMappings(SourceLocation Loc)
Copies the current DiagMappings and pushes the new copy onto the top of the stack.
Defines the clang::FileManager interface and associated types.
void AddPragmaHandler(StringRef Namespace, PragmaHandler *Handler)
Add the specified pragma handler to this preprocessor.
#pragma GCC error has been invoked.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
Defines the SourceManager interface.
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, Token &FirstToken)=0
void dumpMacroInfo(const IdentifierInfo *II)
Defines the clang::MacroInfo and clang::MacroDirective classes.
The pragma was introduced via the Microsoft __pragma(token-string).
void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID)
Add a line note to the line table for the FileID and offset specified by Loc.
virtual void PragmaWarningPush(SourceLocation Loc, int Level)
Callback invoked when a #pragma warning(push) directive is read.
virtual void PragmaWarningPop(SourceLocation Loc)
Callback invoked when a #pragma warning(pop) directive is read.
bool parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value)
Parses a simple integer literal to get its numeric value. Floating point literals and user defined li...
void EnterToken(const Token &Tok)
Enters a token in the token stream to be lexed next.
void IgnorePragmas()
Install empty handlers for all pragmas (making them ignored).
bool isStringLiteral(TokenKind K)
Return true if this is a C or C++ string-literal (or C++11 user-defined-string-literal) token...
The pragma was introduced via the C99 _Pragma(string-literal).
bool isInPrimaryFile() const
Return true if we're in the top-level file, not in a #include.
static Lexer * Create_PragmaLexer(SourceLocation SpellingLoc, SourceLocation ExpansionLocStart, SourceLocation ExpansionLocEnd, unsigned TokLen, Preprocessor &PP)
This interface provides a way to observe the actions of the preprocessor as it does its thing...
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
SourceLocation getPragmaAssumeNonNullLoc() const
The location of the currently-active #pragma clang assume_nonnull begin.
DefMacroDirective * appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI, SourceLocation Loc)
virtual void PragmaDebug(SourceLocation Loc, StringRef DebugType)
Callback invoked when a #pragma clang __debug directive is read.
bool ParsingPreprocessorDirective
True when parsing #XXX; turns '\n' into a tok::eod token.
bool isFromAST() const
Return true if the identifier in its current state was loaded from an AST file.
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, Token &FirstToken) override
void AddPragma(PragmaHandler *Handler)
void HandlePragmaPushMacro(Token &Tok)
Handle #pragma push_macro.
const MacroInfo * getMacroInfo(const IdentifierInfo *II) const
void setKind(tok::TokenKind K)
void CheckEndOfDirective(const char *Directive, bool EnableMacros=false)
Ensure that the next token is a tok::eod token.
void setIsAllowRedefinitionsWithoutWarning(bool Val)
Set the value of the IsAllowRedefinitionsWithoutWarning flag.
HeaderSearch & getHeaderSearchInfo() const
bool setSeverityForGroup(diag::Flavor Flavor, StringRef Group, diag::Severity Map, SourceLocation Loc=SourceLocation())
Change an entire diagnostic group (e.g. "unknown-pragmas") to have the specified mapping.
void CommitBacktrackedTokens()
Disable the last EnableBacktrackAtThisPos call.
Present this diagnostic as an error.
tok::TokenKind getKind() const
unsigned getLine() const
Return the presumed line number of this location.
const FileEntry * getFileEntry() const
PragmaIntroducerKind
Describes how the pragma was introduced, e.g., with #pragma, _Pragma, or __pragma.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD)
Add a directive to the macro directive history for this identifier.
void LexUnexpandedToken(Token &Result)
Just like Lex, but disables macro expansion of identifier tokens.
PragmaMessageKind
Determines the kind of #pragma invoking a call to PragmaMessage.
void HandlePragmaIncludeAlias(Token &Tok)
#pragma GCC warning has been invoked.
void Backtrack()
Make Preprocessor re-lex the tokens that were lexed since EnableBacktrackAtThisPos() was previously c...
virtual void PragmaWarning(SourceLocation Loc, StringRef WarningSpec, ArrayRef< int > Ids)
Callback invoked when a #pragma warning directive is read.
void setAnnotationRange(SourceRange R)
void HandlePragmaOnce(Token &OnceTok)
bool LexingRawMode
True if in raw mode.
StringRef getName() const
Return the actual identifier string.
PragmaNamespace * getIfNamespace() override
void EnableBacktrackAtThisPos()
bool LexOnOffSwitch(tok::OnOffSwitch &OOS)
Lex an on-off-switch (C99 6.10.6p2) and verify that it is followed by EOD. Return true if the token i...
Defines the clang::Preprocessor interface.
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix. ...
void setIsPoisoned(bool Value=true)
void RemovePragmaHandler(StringRef Namespace, PragmaHandler *Handler)
Remove the specific pragma handler from this preprocessor.
void setPragmaAssumeNonNullLoc(SourceLocation Loc)
Set the location of the currently-active #pragma clang assume_nonnull begin. An invalid location ends...
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
void HandlePragmaDependency(Token &DependencyTok)
bool isNot(tok::TokenKind K) const
Represents an unpacked "presumed" location which can be presented to the user.
PragmaHandler * FindHandler(StringRef Name, bool IgnoreNull=true) const
const char * getFilename() const
Return the presumed filename of this location.
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
void setPragmaARCCFCodeAuditedLoc(SourceLocation Loc)
Set the location of the currently-active #pragma clang arc_cf_code_audited begin. An invalid location...
#pragma message has been invoked.
bool isValid() const
Return true if this is a valid SourceLocation object.
Cached information about one file (either on disk or in the virtual file system). ...
void EnterTokenStream(const Token *Toks, unsigned NumToks, bool DisableMacroExpansion, bool OwnsTokens)
Add a "macro" context to the top of the include stack, which will cause the lexer to start returning ...
void Lex(Token &Result)
Lex the next token for this preprocessor.
PPCallbacks * getPPCallbacks() const
Accessors for preprocessor callbacks.
bool is(tok::TokenKind K) const
virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace, PragmaMessageKind Kind, StringRef Str)
Callback invoked when a #pragma message directive is read.
DiagnosticsEngine & getDiagnostics() const
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
bool isMacroDefined(StringRef Id)
~PragmaNamespace() override
unsigned getLineTableFilenameID(StringRef Str)
Return the uniqued ID for the specified filename.
void HandlePragmaPopMacro(Token &Tok)
Handle #pragma pop_macro.
virtual PragmaNamespace * getIfNamespace()
PreprocessorLexer * getCurrentFileLexer() const
Return the current file lexer being lexed from.
void RemovePragmaHandler(PragmaHandler *Handler)
Encapsulates the data about a macro definition (e.g. its tokens).
OnOffSwitch
Defines the possible values of an on-off-switch (C99 6.10.6p2).
time_t getModificationTime() const
bool GetIncludeFilenameSpelling(SourceLocation Loc, StringRef &Filename)
Turn the specified lexer token into a fully checked and spelled filename, e.g. as an operand of #incl...
bool FinishLexStringLiteral(Token &Result, std::string &String, const char *DiagnosticTag, bool AllowMacroExpansion)
Complete the lexing of a string literal where the first token has already been lexed (see LexStringLi...
void CreateString(StringRef Str, Token &Tok, SourceLocation ExpansionLocStart=SourceLocation(), SourceLocation ExpansionLocEnd=SourceLocation())
Plop the specified string into a scratch buffer and set the specified token's location and length to ...
bool popMappings(SourceLocation Loc)
Pops the current DiagMappings off the top of the stack, causing the new top of the stack to be the ac...
IdentifierInfo * ParsePragmaPushOrPopMacro(Token &Tok)
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, Token &FirstToken) override
void LexIncludeFilename(Token &Result)
After the preprocessor has parsed a #include, lex and (potentially) macro expand the filename...
const FileEntry * LookupFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled, const DirectoryLookup *FromDir, const FileEntry *FromFile, const DirectoryLookup *&CurDir, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, ModuleMap::KnownHeader *SuggestedModule, bool SkipCache=false)
Given a "foo" or <foo> reference, look up the indicated file.
Do not present this diagnostic, ignore it.
void HandlePragmaPoison(Token &PoisonTok)
virtual void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace)
Callback invoked when a #pragma gcc dianostic push directive is read.
IdentifierInfo * LookUpIdentifierInfo(Token &Identifier) const
void HandlePragmaSystemHeader(Token &SysHeaderTok)
void DiscardUntilEndOfDirective()
Read and discard all tokens remaining on the current line until the tok::eod token is found...
bool isPreprocessedOutput() const
Present this diagnostic as a fatal error.
virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace, diag::Severity mapping, StringRef Str)
Callback invoked when a #pragma gcc dianostic directive is read.
void setLocation(SourceLocation L)
A trivial tuple used to represent a source range.
Present this diagnostic as a warning.
SourceLocation getPragmaARCCFCodeAuditedLoc() const
The location of the currently-active #pragma clang arc_cf_code_audited begin.
void startToken()
Reset all flags to cleared.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
IdentifierInfo * getIdentifierInfo() const
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.