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 while (Tok.
isNot(tok::r_paren) &&
201 if (Tok.
is(tok::r_paren))
203 return _PragmaLexing.failed();
207 Diag(Tok, diag::err_invalid_string_udl);
210 if (Tok.
is(tok::r_paren))
212 return _PragmaLexing.failed();
220 if (Tok.
isNot(tok::r_paren)) {
221 Diag(PragmaLoc, diag::err__Pragma_malformed);
222 return _PragmaLexing.failed();
225 if (InMacroArgPreExpansion)
236 if (StrVal[0] ==
'L' || StrVal[0] ==
'U' ||
237 (StrVal[0] ==
'u' && StrVal[1] !=
'8'))
238 StrVal.erase(StrVal.begin());
239 else if (StrVal[0] ==
'u')
240 StrVal.erase(StrVal.begin(), StrVal.begin() + 2);
242 if (StrVal[0] ==
'R') {
245 assert(StrVal[1] ==
'"' && StrVal[StrVal.size() - 1] ==
'"' &&
246 "Invalid raw string token!");
249 unsigned NumDChars = 0;
250 while (StrVal[2 + NumDChars] !=
'(') {
251 assert(NumDChars < (StrVal.size() - 5) / 2 &&
252 "Invalid raw string token!");
255 assert(StrVal[StrVal.size() - 2 - NumDChars] ==
')');
259 StrVal.erase(0, 2 + NumDChars);
260 StrVal.erase(StrVal.size() - 1 - NumDChars);
262 assert(StrVal[0] ==
'"' && StrVal[StrVal.size()-1] ==
'"' &&
263 "Invalid string token!");
266 unsigned ResultPos = 1;
267 for (
unsigned i = 1, e = StrVal.size() - 1; i != e; ++i) {
269 if (StrVal[i] ==
'\\' && i + 1 < e &&
270 (StrVal[i + 1] ==
'\\' || StrVal[i + 1] ==
'"'))
272 StrVal[ResultPos++] = StrVal[i];
274 StrVal.erase(StrVal.begin() + ResultPos, StrVal.end() - 1);
282 StrVal[StrVal.size()-1] =
'\n';
294 StrVal.size(), *
this);
296 EnterSourceFileWithLexer(TL,
nullptr);
307 void Preprocessor::HandleMicrosoft__pragma(
Token &Tok) {
313 if (Tok.
isNot(tok::l_paren)) {
314 Diag(PragmaLoc, diag::err__Pragma_malformed);
323 PragmaToks.push_back(Tok);
324 if (Tok.
is(tok::l_paren))
326 else if (Tok.
is(tok::r_paren) && NumParens-- == 0)
332 Diag(PragmaLoc, diag::err_unterminated___pragma);
339 PragmaToks.back().setKind(tok::eod);
341 Token *TokArray =
new Token[PragmaToks.size()];
342 std::copy(PragmaToks.begin(), PragmaToks.end(), TokArray);
345 EnterTokenStream(TokArray, PragmaToks.size(),
true,
true);
360 Diag(OnceTok, diag::pp_pragma_once_in_main_file);
370 assert(CurPPLexer &&
"No current lexer?");
372 CurLexer->ReadToEndOfLine();
374 CurPTHLexer->DiscardToEndOfLine();
394 if (Tok.
is(tok::eod))
return;
397 if (Tok.
isNot(tok::raw_identifier)) {
398 Diag(Tok, diag::err_pp_invalid_poison);
411 Diag(Tok, diag::pp_poisoning_existing_macro);
424 Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
450 FilenameID,
false,
false,
461 if (FilenameTok.
is(tok::eod))
466 bool Invalid =
false;
475 if (Filename.empty())
482 nullptr, CurDir,
nullptr,
nullptr,
nullptr);
484 if (!SuppressIncludeNotFoundError)
485 Diag(FilenameTok, diag::err_pp_file_not_found) <<
Filename;
496 while (DependencyTok.
isNot(tok::eod)) {
502 if (!Message.empty())
503 Message.erase(Message.end()-1);
504 Diag(FilenameTok, diag::pp_out_of_date_dependency) << Message;
512 Token PragmaTok = Tok;
516 if (Tok.
isNot(tok::l_paren)) {
517 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
524 if (Tok.
isNot(tok::string_literal)) {
525 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
531 Diag(Tok, diag::err_invalid_string_udl);
540 if (Tok.
isNot(tok::r_paren)) {
541 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
546 assert(StrVal[0] ==
'"' && StrVal[StrVal.size()-1] ==
'"' &&
547 "Invalid string token!");
552 MacroTok.setKind(tok::raw_identifier);
553 CreateString(StringRef(&StrVal[1], StrVal.size() - 2), MacroTok);
568 if (!IdentInfo)
return;
579 PragmaPushMacroInfo[IdentInfo].push_back(MI);
593 if (!IdentInfo)
return;
596 llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> >
::iterator iter =
597 PragmaPushMacroInfo.find(IdentInfo);
598 if (iter != PragmaPushMacroInfo.end()) {
601 if (MI->isWarnIfUnused())
602 WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
607 MacroInfo *MacroToReInstall = iter->second.back();
609 if (MacroToReInstall)
614 iter->second.pop_back();
615 if (iter->second.size() == 0)
616 PragmaPushMacroInfo.erase(iter);
618 Diag(MessageLoc, diag::warn_pragma_pop_macro_no_push)
631 if (Tok.
isNot(tok::l_paren)) {
632 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
"(";
637 Token SourceFilenameTok;
639 if (SourceFilenameTok.
is(tok::eod)) {
644 StringRef SourceFileName;
646 if (SourceFilenameTok.
is(tok::string_literal) ||
647 SourceFilenameTok.
is(tok::angle_string_literal)) {
648 SourceFileName =
getSpelling(SourceFilenameTok, FileNameBuffer);
649 }
else if (SourceFilenameTok.
is(tok::less)) {
651 FileNameBuffer.push_back(
'<');
655 SourceFileName = FileNameBuffer;
657 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
660 FileNameBuffer.clear();
664 if (Tok.
isNot(tok::comma)) {
665 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
",";
669 Token ReplaceFilenameTok;
671 if (ReplaceFilenameTok.
is(tok::eod)) {
676 StringRef ReplaceFileName;
677 if (ReplaceFilenameTok.
is(tok::string_literal) ||
678 ReplaceFilenameTok.
is(tok::angle_string_literal)) {
679 ReplaceFileName =
getSpelling(ReplaceFilenameTok, FileNameBuffer);
680 }
else if (ReplaceFilenameTok.
is(tok::less)) {
682 FileNameBuffer.push_back(
'<');
686 ReplaceFileName = FileNameBuffer;
688 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
694 if (Tok.
isNot(tok::r_paren)) {
695 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
")";
701 StringRef OriginalSource = SourceFileName;
703 bool SourceIsAngled =
706 bool ReplaceIsAngled =
709 if (!SourceFileName.empty() && !ReplaceFileName.empty() &&
710 (SourceIsAngled != ReplaceIsAngled)) {
713 DiagID = diag::warn_pragma_include_alias_mismatch_angle;
715 DiagID = diag::warn_pragma_include_alias_mismatch_quote;
736 if (!Namespace.empty()) {
740 if (
PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace)) {
742 assert(InsertNS !=
nullptr &&
"Cannot have a pragma namespace and pragma"
743 " handler with the same name!");
748 PragmaHandlers->AddPragma(InsertNS);
754 "Pragma handler already exists for this identifier!");
767 if (!Namespace.empty()) {
768 PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace);
769 assert(Existing &&
"Namespace containing handler does not exist!");
772 assert(NS &&
"Invalid namespace, registered as a regular pragma handler!");
778 if (NS != PragmaHandlers.get() && NS->
IsEmpty()) {
779 PragmaHandlers->RemovePragmaHandler(NS);
788 if (Tok.
isNot(tok::identifier)) {
789 Diag(Tok, diag::ext_on_off_switch_syntax);
795 else if (II->
isStr(
"OFF"))
797 else if (II->
isStr(
"DEFAULT"))
800 Diag(Tok, diag::ext_on_off_switch_syntax);
806 if (Tok.
isNot(tok::eod))
807 Diag(Tok, diag::ext_pragma_syntax_eod);
816 Token &OnceTok)
override {
827 Token &MarkTok)
override {
836 Token &PoisonTok)
override {
844 PragmaSystemHeaderHandler() :
PragmaHandler(
"system_header") {}
846 Token &SHToken)
override {
854 Token &DepToken)
override {
862 Token &DepToken)
override {
865 if (Tok.
isNot(tok::identifier)) {
866 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
871 if (II->
isStr(
"assert")) {
872 llvm_unreachable(
"This is an assertion!");
873 }
else if (II->
isStr(
"crash")) {
875 }
else if (II->
isStr(
"parser_crash")) {
878 Crasher.
setKind(tok::annot_pragma_parser_crash);
881 }
else if (II->
isStr(
"dump")) {
887 DumpAnnot.
setKind(tok::annot_pragma_dump);
894 PP.
Diag(Identifier, diag::warn_pragma_debug_missing_argument)
897 }
else if (II->
isStr(
"llvm_fatal_error")) {
898 llvm::report_fatal_error(
"#pragma clang __debug llvm_fatal_error");
899 }
else if (II->
isStr(
"llvm_unreachable")) {
900 llvm_unreachable(
"#pragma clang __debug llvm_unreachable");
901 }
else if (II->
isStr(
"macro")) {
908 PP.
Diag(MacroName, diag::warn_pragma_debug_missing_argument)
910 }
else if (II->
isStr(
"overflow_stack")) {
911 DebugOverflowStack();
912 }
else if (II->
isStr(
"handle_crash")) {
913 llvm::CrashRecoveryContext *CRC =llvm::CrashRecoveryContext::GetCurrent();
916 }
else if (II->
isStr(
"captured")) {
919 PP.
Diag(Tok, diag::warn_pragma_debug_unexpected_command)
936 if (Tok.
isNot(tok::eod)) {
937 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol)
938 <<
"pragma clang __debug captured";
945 Toks[0].startToken();
946 Toks[0].setKind(tok::annot_pragma_captured);
947 Toks[0].setLocation(NameLoc);
949 PP.EnterTokenStream(Toks,
true);
954 #pragma warning(disable : 4717)
956 static void DebugOverflowStack() {
957 void (*
volatile Self)() = DebugOverflowStack;
961 #pragma warning(default : 4717)
971 explicit PragmaDiagnosticHandler(
const char *NS) :
974 Token &DiagToken)
override {
978 if (Tok.
isNot(tok::identifier)) {
979 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
985 if (II->
isStr(
"pop")) {
987 PP.
Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
991 }
else if (II->
isStr(
"push")) {
1006 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1013 std::string WarningName;
1018 if (Tok.
isNot(tok::eod)) {
1019 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_diagnostic_invalid_token);
1023 if (WarningName.size() < 3 || WarningName[0] !=
'-' ||
1024 (WarningName[1] !=
'W' && WarningName[1] !=
'R')) {
1025 PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_invalid_option);
1031 StringRef Group = StringRef(WarningName).substr(2);
1032 bool unknownDiag =
false;
1033 if (Group ==
"everything") {
1042 PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_unknown_warning)
1056 Token &Tok)
override {
1065 if (Tok.
isNot(tok::l_paren)) {
1066 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
"(";
1073 if (II && II->
isStr(
"push")) {
1077 if (Tok.
is(tok::comma)) {
1080 if (Tok.
is(tok::numeric_constant) &&
1083 if (Level < 0 || Level > 4) {
1084 PP.
Diag(Tok, diag::warn_pragma_warning_push_level);
1090 }
else if (II && II->
isStr(
"pop")) {
1100 if (!II && !Tok.
is(tok::numeric_constant)) {
1101 PP.
Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1106 bool SpecifierValid;
1107 StringRef Specifier;
1111 SpecifierValid = llvm::StringSwitch<bool>(Specifier)
1112 .Cases(
"default",
"disable",
"error",
"once",
1124 SpecifierValid = (Value >= 1) && (Value <= 4);
1126 SpecifierValid =
false;
1130 if (!SpecifierValid) {
1131 PP.
Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1134 if (Tok.
isNot(tok::colon)) {
1135 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
":";
1142 while (Tok.
is(tok::numeric_constant)) {
1146 PP.
Diag(Tok, diag::warn_pragma_warning_expected_number);
1149 Ids.push_back(
int(Value));
1155 if (Tok.
isNot(tok::semi))
1161 if (Tok.
isNot(tok::r_paren)) {
1162 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
")";
1167 if (Tok.
isNot(tok::eod))
1168 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma warning";
1174 PragmaIncludeAliasHandler() :
PragmaHandler(
"include_alias") {}
1176 Token &IncludeAliasTok)
override {
1200 bool PragmaNameOnly =
false) {
1203 return PragmaNameOnly ?
"message" :
"pragma message";
1205 return PragmaNameOnly ?
"warning" :
"pragma warning";
1207 return PragmaNameOnly ?
"error" :
"pragma error";
1209 llvm_unreachable(
"Unknown PragmaMessageKind!");
1214 StringRef Namespace = StringRef())
1218 Token &Tok)
override {
1221 bool ExpectClosingParen =
false;
1225 ExpectClosingParen =
true;
1229 case tok::string_literal:
1233 PP.
Diag(MessageLoc, diag::err_pragma_message_malformed) <<
Kind;
1237 std::string MessageString;
1242 if (ExpectClosingParen) {
1243 if (Tok.
isNot(tok::r_paren)) {
1244 PP.
Diag(Tok.
getLocation(), diag::err_pragma_message_malformed) << Kind;
1250 if (Tok.
isNot(tok::eod)) {
1251 PP.
Diag(Tok.
getLocation(), diag::err_pragma_message_malformed) << Kind;
1257 ? diag::err_pragma_message
1258 : diag::warn_pragma_message) << MessageString;
1262 Callbacks->
PragmaMessage(MessageLoc, Namespace, Kind, MessageString);
1271 Token &PushMacroTok)
override {
1282 Token &PopMacroTok)
override {
1290 struct PragmaSTDC_FENV_ACCESSHandler :
public PragmaHandler {
1291 PragmaSTDC_FENV_ACCESSHandler() :
PragmaHandler(
"FENV_ACCESS") {}
1293 Token &Tok)
override {
1298 PP.
Diag(Tok, diag::warn_stdc_fenv_access_not_supported);
1303 struct PragmaSTDC_CX_LIMITED_RANGEHandler :
public PragmaHandler {
1304 PragmaSTDC_CX_LIMITED_RANGEHandler()
1307 Token &Tok)
override {
1315 PragmaSTDC_UnknownHandler() {}
1317 Token &UnknownTok)
override {
1319 PP.
Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
1325 struct PragmaARCCFCodeAuditedHandler :
public PragmaHandler {
1326 PragmaARCCFCodeAuditedHandler() :
PragmaHandler(
"arc_cf_code_audited") {}
1328 Token &NameTok)
override {
1337 if (BeginEnd && BeginEnd->
isStr(
"begin")) {
1339 }
else if (BeginEnd && BeginEnd->
isStr(
"end")) {
1348 if (Tok.
isNot(tok::eod))
1349 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1360 PP.
Diag(Loc, diag::err_pp_double_begin_of_arc_cf_code_audited);
1361 PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1367 PP.
Diag(Loc, diag::err_pp_unmatched_end_of_arc_cf_code_audited);
1380 PragmaAssumeNonNullHandler() :
PragmaHandler(
"assume_nonnull") {}
1382 Token &NameTok)
override {
1391 if (BeginEnd && BeginEnd->
isStr(
"begin")) {
1393 }
else if (BeginEnd && BeginEnd->
isStr(
"end")) {
1402 if (Tok.
isNot(tok::eod))
1403 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1414 PP.
Diag(Loc, diag::err_pp_double_begin_of_assume_nonnull);
1415 PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1421 PP.
Diag(Loc, diag::err_pp_unmatched_end_of_assume_nonnull);
1443 PragmaRegionHandler(
const char *pragma) :
PragmaHandler(pragma) { }
1446 Token &NameTok)
override {
1459 void Preprocessor::RegisterBuiltinPragmas() {
1489 if (LangOpts.MicrosoftExt) {
1512 if (
PragmaHandler *NS = PragmaHandlers->FindHandler(
"STDC")) {
1517 assert(STDCNamespace &&
1518 "Invalid namespace, registered as a regular pragma handler!");
A diagnostic that indicates a problem or potential problem.
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
StringRef getName() const
bool isPoisoned() const
Return true if this token has been poisoned.
void setSeverityForAll(diag::Flavor Flavor, diag::Severity Map, SourceLocation Loc=SourceLocation())
Add the specified mapping to all diagnostics of the specified flavor.
llvm::BumpPtrAllocator & getPreprocessorAllocator()
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens...
virtual void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace)
Callback invoked when a #pragma gcc diagnostic 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)
The translation unit is a prefix to a translation unit, and is not complete.
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.
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).
Severity
Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs to either Ignore (nothing)...
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)
Create_PragmaLexer: Lexer constructor - Create a new lexer object for _Pragma expansion.
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
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
SourceLocation getPragmaAssumeNonNullLoc() const
The location of the currently-active #pragma clang assume_nonnull begin.
DefMacroDirective * appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI, SourceLocation Loc)
One of these records is kept for each identifier that is lexed.
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.
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
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
EmptyPragmaHandler(StringRef Name=StringRef())
void AddPragma(PragmaHandler *Handler)
AddPragma - Add a pragma to this namespace.
void HandlePragmaPushMacro(Token &Tok)
Handle #pragma push_macro.
const MacroInfo * getMacroInfo(const IdentifierInfo *II) const
Token - This structure provides full information about a lexed token.
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.
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
getFileEntry - Return the FileEntry corresponding to this FileID.
PragmaIntroducerKind
Describes how the pragma was introduced, e.g., with #pragma, _Pragma, or __pragma.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
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...
EmptyPragmaHandler - A pragma handler which takes no action, which can be used to ignore particular p...
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)
HandlePragmaOnce - Handle #pragma once.
void setAnnotationValue(void *val)
bool LexingRawMode
True if in raw mode.
StringRef getName() const
Return the actual identifier string.
PragmaNamespace * getIfNamespace() override
getIfNamespace - If this is a namespace, return it.
void EnableBacktrackAtThisPos()
From the point that this method is called, and until CommitBacktrackedTokens() or Backtrack() is call...
bool LexOnOffSwitch(tok::OnOffSwitch &OOS)
Lex an on-off-switch (C99 6.10.6p2) and verify that it is followed by EOD.
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)
setIsPoisoned - Mark this identifier as poisoned.
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.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
void HandlePragmaDependency(Token &DependencyTok)
HandlePragmaDependency - Handle #pragma GCC dependency "foo" blah.
bool isNot(tok::TokenKind K) const
Represents an unpacked "presumed" location which can be presented to the user.
DirectoryLookup - This class represents one entry in the search list that specifies the search order ...
PragmaHandler * FindHandler(StringRef Name, bool IgnoreNull=true) const
FindHandler - Check to see if there is already a handler for the specified name.
const char * getFilename() const
Return the presumed filename of this location.
Encodes a location in the source.
const TemplateArgument * iterator
void setPragmaARCCFCodeAuditedLoc(SourceLocation Loc)
Set the location of the currently-active #pragma clang arc_cf_code_audited begin. ...
#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 Lex(Token &Result)
Lex the next token for this preprocessor.
PPCallbacks * getPPCallbacks() const
Accessors for preprocessor callbacks.
Flavor
Flavors of diagnostics we can emit.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {...
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)
Represents a template argument.
~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()
getIfNamespace - If this is a namespace, return it.
PragmaHandler - Instances of this interface defined to handle the various pragmas that the language f...
PreprocessorLexer * getCurrentFileLexer() const
Return the current file lexer being lexed from.
void RemovePragmaHandler(PragmaHandler *Handler)
RemovePragmaHandler - Remove the given handler from the namespace.
Encapsulates the data about a macro definition (e.g.
OnOffSwitch
Defines the possible values of an on-off-switch (C99 6.10.6p2).
time_t getModificationTime() const
PragmaNamespace - This PragmaHandler subdivides the namespace of pragmas, allowing hierarchical pragm...
bool GetIncludeFilenameSpelling(SourceLocation Loc, StringRef &Filename)
Turn the specified lexer token into a fully checked and spelled filename, e.g.
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)
ParsePragmaPushOrPopMacro - Handle parsing of pragma push_macro/pop_macro.
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)
HandlePragmaPoison - Handle #pragma GCC poison.
virtual void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace)
Callback invoked when a #pragma gcc diagnostic push directive is read.
A diagnostic that indicates normal progress through compilation.
IdentifierInfo * LookUpIdentifierInfo(Token &Identifier) const
Given a tok::raw_identifier token, look up the identifier information for the token and install it in...
void HandlePragmaSystemHeader(Token &SysHeaderTok)
HandlePragmaSystemHeader - Implement #pragma GCC system_header.
void DiscardUntilEndOfDirective()
Read and discard all tokens remaining on the current line until the tok::eod token is found...
bool isPreprocessedOutput() const
Returns true if the preprocessor is responsible for generating output, false if it is producing token...
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 diagnostic directive is read.
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.