31 #include "llvm/ADT/ArrayRef.h"
32 #include "llvm/ADT/DenseMap.h"
33 #include "llvm/ADT/SmallString.h"
34 #include "llvm/ADT/SmallVector.h"
35 #include "llvm/ADT/STLExtras.h"
36 #include "llvm/ADT/StringSwitch.h"
37 #include "llvm/Support/CrashRecoveryContext.h"
38 #include "llvm/Support/Compiler.h"
39 #include "llvm/Support/ErrorHandling.h"
47 using namespace clang;
68 llvm::DeleteContainerSeconds(Handlers);
76 bool IgnoreNull)
const {
79 return IgnoreNull ?
nullptr : Handlers.lookup(StringRef());
83 assert(!Handlers.lookup(Handler->
getName()) &&
84 "A handler with this name is already registered in this namespace");
85 Handlers[Handler->
getName()] = Handler;
89 assert(Handlers.lookup(Handler->
getName()) &&
90 "Handler not registered in this namespace");
91 Handlers.erase(Handler->
getName());
107 PP.
Diag(Tok, diag::warn_pragma_ignored);
121 void Preprocessor::HandlePragmaDirective(
SourceLocation IntroducerLoc,
124 Callbacks->PragmaDirective(IntroducerLoc, Introducer);
133 PragmaHandlers->HandlePragma(*
this, Introducer, Tok);
136 if ((CurTokenLexer && CurTokenLexer->isParsingPreprocessorDirective())
144 class LexingFor_PragmaRAII {
146 bool InMacroArgPreExpansion;
152 LexingFor_PragmaRAII(
Preprocessor &PP,
bool InMacroArgPreExpansion,
154 : PP(PP), InMacroArgPreExpansion(InMacroArgPreExpansion),
155 Failed(
false), OutTok(Tok) {
156 if (InMacroArgPreExpansion) {
162 ~LexingFor_PragmaRAII() {
163 if (InMacroArgPreExpansion) {
194 void Preprocessor::Handle_Pragma(
Token &Tok) {
207 LexingFor_PragmaRAII _PragmaLexing(*
this, InMacroArgPreExpansion, Tok);
214 if (Tok.
isNot(tok::l_paren)) {
215 Diag(PragmaLoc, diag::err__Pragma_malformed);
216 return _PragmaLexing.failed();
222 Diag(PragmaLoc, diag::err__Pragma_malformed);
226 while (Tok.
isNot(tok::r_paren) &&
230 if (Tok.
is(tok::r_paren))
232 return _PragmaLexing.failed();
236 Diag(Tok, diag::err_invalid_string_udl);
239 if (Tok.
is(tok::r_paren))
241 return _PragmaLexing.failed();
249 if (Tok.
isNot(tok::r_paren)) {
250 Diag(PragmaLoc, diag::err__Pragma_malformed);
251 return _PragmaLexing.failed();
254 if (InMacroArgPreExpansion)
265 if (StrVal[0] ==
'L' || StrVal[0] ==
'U' ||
266 (StrVal[0] ==
'u' && StrVal[1] !=
'8'))
267 StrVal.erase(StrVal.begin());
268 else if (StrVal[0] ==
'u')
269 StrVal.erase(StrVal.begin(), StrVal.begin() + 2);
271 if (StrVal[0] ==
'R') {
274 assert(StrVal[1] ==
'"' && StrVal[StrVal.size() - 1] ==
'"' &&
275 "Invalid raw string token!");
278 unsigned NumDChars = 0;
279 while (StrVal[2 + NumDChars] !=
'(') {
280 assert(NumDChars < (StrVal.size() - 5) / 2 &&
281 "Invalid raw string token!");
284 assert(StrVal[StrVal.size() - 2 - NumDChars] ==
')');
288 StrVal.erase(0, 2 + NumDChars);
289 StrVal.erase(StrVal.size() - 1 - NumDChars);
291 assert(StrVal[0] ==
'"' && StrVal[StrVal.size()-1] ==
'"' &&
292 "Invalid string token!");
295 unsigned ResultPos = 1;
296 for (
size_t i = 1, e = StrVal.size() - 1; i != e; ++i) {
298 if (StrVal[i] ==
'\\' && i + 1 < e &&
299 (StrVal[i + 1] ==
'\\' || StrVal[i + 1] ==
'"'))
301 StrVal[ResultPos++] = StrVal[i];
303 StrVal.erase(StrVal.begin() + ResultPos, StrVal.end() - 1);
311 StrVal[StrVal.size()-1] =
'\n';
323 StrVal.size(), *
this);
325 EnterSourceFileWithLexer(TL,
nullptr);
336 void Preprocessor::HandleMicrosoft__pragma(
Token &Tok) {
342 if (Tok.
isNot(tok::l_paren)) {
343 Diag(PragmaLoc, diag::err__Pragma_malformed);
352 PragmaToks.push_back(Tok);
353 if (Tok.
is(tok::l_paren))
355 else if (Tok.
is(tok::r_paren) && NumParens-- == 0)
361 Diag(PragmaLoc, diag::err_unterminated___pragma);
368 PragmaToks.back().setKind(tok::eod);
370 Token *TokArray =
new Token[PragmaToks.size()];
371 std::copy(PragmaToks.begin(), PragmaToks.end(), TokArray);
374 EnterTokenStream(TokArray, PragmaToks.size(),
true,
true);
391 Diag(OnceTok, diag::pp_pragma_once_in_main_file);
401 assert(CurPPLexer &&
"No current lexer?");
403 CurLexer->ReadToEndOfLine();
405 CurPTHLexer->DiscardToEndOfLine();
424 if (Tok.
is(tok::eod))
return;
427 if (Tok.
isNot(tok::raw_identifier)) {
428 Diag(Tok, diag::err_pp_invalid_poison);
441 Diag(Tok, diag::pp_poisoning_existing_macro);
454 Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
480 FilenameID,
false,
false,
491 if (FilenameTok.
is(tok::eod))
496 bool Invalid =
false;
505 if (Filename.empty())
512 nullptr, CurDir,
nullptr,
nullptr,
nullptr,
nullptr);
514 if (!SuppressIncludeNotFoundError)
515 Diag(FilenameTok, diag::err_pp_file_not_found) <<
Filename;
526 while (DependencyTok.
isNot(tok::eod)) {
532 if (!Message.empty())
533 Message.erase(Message.end()-1);
534 Diag(FilenameTok, diag::pp_out_of_date_dependency) << Message;
542 Token PragmaTok = Tok;
546 if (Tok.
isNot(tok::l_paren)) {
547 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
554 if (Tok.
isNot(tok::string_literal)) {
555 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
561 Diag(Tok, diag::err_invalid_string_udl);
570 if (Tok.
isNot(tok::r_paren)) {
571 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
576 assert(StrVal[0] ==
'"' && StrVal[StrVal.size()-1] ==
'"' &&
577 "Invalid string token!");
582 MacroTok.setKind(tok::raw_identifier);
583 CreateString(StringRef(&StrVal[1], StrVal.size() - 2), MacroTok);
598 if (!IdentInfo)
return;
609 PragmaPushMacroInfo[IdentInfo].push_back(MI);
623 if (!IdentInfo)
return;
626 llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> >::iterator iter =
627 PragmaPushMacroInfo.find(IdentInfo);
628 if (iter != PragmaPushMacroInfo.end()) {
631 if (MI->isWarnIfUnused())
632 WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
637 MacroInfo *MacroToReInstall = iter->second.back();
639 if (MacroToReInstall)
644 iter->second.pop_back();
645 if (iter->second.empty())
646 PragmaPushMacroInfo.erase(iter);
648 Diag(MessageLoc, diag::warn_pragma_pop_macro_no_push)
661 if (Tok.
isNot(tok::l_paren)) {
662 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
"(";
667 Token SourceFilenameTok;
669 if (SourceFilenameTok.
is(tok::eod)) {
674 StringRef SourceFileName;
676 if (SourceFilenameTok.
is(tok::string_literal) ||
677 SourceFilenameTok.
is(tok::angle_string_literal)) {
678 SourceFileName =
getSpelling(SourceFilenameTok, FileNameBuffer);
679 }
else if (SourceFilenameTok.
is(tok::less)) {
681 FileNameBuffer.push_back(
'<');
685 SourceFileName = FileNameBuffer;
687 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
690 FileNameBuffer.clear();
694 if (Tok.
isNot(tok::comma)) {
695 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
",";
699 Token ReplaceFilenameTok;
701 if (ReplaceFilenameTok.
is(tok::eod)) {
706 StringRef ReplaceFileName;
707 if (ReplaceFilenameTok.
is(tok::string_literal) ||
708 ReplaceFilenameTok.
is(tok::angle_string_literal)) {
709 ReplaceFileName =
getSpelling(ReplaceFilenameTok, FileNameBuffer);
710 }
else if (ReplaceFilenameTok.
is(tok::less)) {
712 FileNameBuffer.push_back(
'<');
716 ReplaceFileName = FileNameBuffer;
718 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
724 if (Tok.
isNot(tok::r_paren)) {
725 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
")";
731 StringRef OriginalSource = SourceFileName;
733 bool SourceIsAngled =
736 bool ReplaceIsAngled =
739 if (!SourceFileName.empty() && !ReplaceFileName.empty() &&
740 (SourceIsAngled != ReplaceIsAngled)) {
743 DiagID = diag::warn_pragma_include_alias_mismatch_angle;
745 DiagID = diag::warn_pragma_include_alias_mismatch_quote;
762 std::pair<IdentifierInfo *, SourceLocation> &ModuleNameComponent,
769 ModuleNameComponent = std::make_pair(
772 ModuleNameComponent =
775 PP.
Diag(Tok.
getLocation(), diag::err_pp_expected_module_name) << First;
786 std::pair<IdentifierInfo*, SourceLocation> NameComponent;
789 ModuleName.push_back(NameComponent);
792 if (Tok.
isNot(tok::period))
800 std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc;
806 if (Tok.
isNot(tok::eod)) {
807 Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
813 Diag(Loc, diag::err_pp_module_build_pth);
817 CurLexer->LexingRawMode =
true;
819 auto TryConsumeIdentifier = [&](StringRef Ident) ->
bool {
820 if (Tok.
getKind() != tok::raw_identifier ||
828 const char *Start = CurLexer->getBufferLocation();
829 const char *
End =
nullptr;
830 unsigned NestingLevel = 1;
832 End = CurLexer->getBufferLocation();
836 Diag(Loc, diag::err_pp_module_build_missing_end);
847 CurLexer->ParsingPreprocessorDirective =
true;
849 if (TryConsumeIdentifier(
"pragma") && TryConsumeIdentifier(
"clang") &&
850 TryConsumeIdentifier(
"module")) {
851 if (TryConsumeIdentifier(
"build"))
854 else if (TryConsumeIdentifier(
"endbuild")) {
856 if (--NestingLevel == 0)
865 CurLexer->LexingRawMode =
false;
868 assert(CurLexer->getBuffer().begin() <= Start &&
869 Start <= CurLexer->getBuffer().end() &&
870 CurLexer->getBuffer().begin() <= End &&
871 End <= CurLexer->getBuffer().end() &&
872 "module source range not contained within same file buffer");
874 StringRef(Start, End - Start));
885 if (!Namespace.empty()) {
889 if (
PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace)) {
891 assert(InsertNS !=
nullptr &&
"Cannot have a pragma namespace and pragma"
892 " handler with the same name!");
897 PragmaHandlers->AddPragma(InsertNS);
903 "Pragma handler already exists for this identifier!");
916 if (!Namespace.empty()) {
917 PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace);
918 assert(Existing &&
"Namespace containing handler does not exist!");
921 assert(NS &&
"Invalid namespace, registered as a regular pragma handler!");
927 if (NS != PragmaHandlers.get() && NS->
IsEmpty()) {
928 PragmaHandlers->RemovePragmaHandler(NS);
937 if (Tok.
isNot(tok::identifier)) {
938 Diag(Tok, diag::ext_on_off_switch_syntax);
944 else if (II->
isStr(
"OFF"))
946 else if (II->
isStr(
"DEFAULT"))
949 Diag(Tok, diag::ext_on_off_switch_syntax);
955 if (Tok.
isNot(tok::eod))
956 Diag(Tok, diag::ext_pragma_syntax_eod);
966 Token &OnceTok)
override {
978 Token &MarkTok)
override {
988 Token &PoisonTok)
override {
996 PragmaSystemHeaderHandler() :
PragmaHandler(
"system_header") {}
999 Token &SHToken)
override {
1009 Token &DepToken)
override {
1018 Token &DepToken)
override {
1021 if (Tok.
isNot(tok::identifier)) {
1022 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1027 if (II->
isStr(
"assert")) {
1028 llvm_unreachable(
"This is an assertion!");
1029 }
else if (II->
isStr(
"crash")) {
1031 }
else if (II->
isStr(
"parser_crash")) {
1034 Crasher.
setKind(tok::annot_pragma_parser_crash);
1037 }
else if (II->
isStr(
"dump")) {
1043 DumpAnnot.
setKind(tok::annot_pragma_dump);
1050 PP.
Diag(Identifier, diag::warn_pragma_debug_missing_argument)
1053 }
else if (II->
isStr(
"llvm_fatal_error")) {
1054 llvm::report_fatal_error(
"#pragma clang __debug llvm_fatal_error");
1055 }
else if (II->
isStr(
"llvm_unreachable")) {
1056 llvm_unreachable(
"#pragma clang __debug llvm_unreachable");
1057 }
else if (II->
isStr(
"macro")) {
1064 PP.
Diag(MacroName, diag::warn_pragma_debug_missing_argument)
1066 }
else if (II->
isStr(
"overflow_stack")) {
1067 DebugOverflowStack();
1068 }
else if (II->
isStr(
"handle_crash")) {
1069 llvm::CrashRecoveryContext *CRC =llvm::CrashRecoveryContext::GetCurrent();
1072 }
else if (II->
isStr(
"captured")) {
1075 PP.
Diag(Tok, diag::warn_pragma_debug_unexpected_command)
1092 if (Tok.
isNot(tok::eod)) {
1093 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol)
1094 <<
"pragma clang __debug captured";
1101 Toks[0].startToken();
1102 Toks[0].setKind(tok::annot_pragma_captured);
1103 Toks[0].setLocation(NameLoc);
1105 PP.EnterTokenStream(Toks,
true);
1110 #pragma warning(disable : 4717)
1112 static void DebugOverflowStack(
void (*
P)() =
nullptr) {
1113 void (*
volatile Self)(void(*
P)()) = DebugOverflowStack;
1114 Self(
reinterpret_cast<void(*)()
>(Self));
1117 #pragma warning(default : 4717)
1128 explicit PragmaDiagnosticHandler(
const char *NS) :
1132 Token &DiagToken)
override {
1136 if (Tok.
isNot(tok::identifier)) {
1137 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1143 if (II->
isStr(
"pop")) {
1145 PP.
Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
1149 }
else if (II->
isStr(
"push")) {
1164 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1171 std::string WarningName;
1176 if (Tok.
isNot(tok::eod)) {
1177 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_diagnostic_invalid_token);
1181 if (WarningName.size() < 3 || WarningName[0] !=
'-' ||
1182 (WarningName[1] !=
'W' && WarningName[1] !=
'R')) {
1183 PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_invalid_option);
1189 StringRef Group = StringRef(WarningName).substr(2);
1190 bool unknownDiag =
false;
1191 if (Group ==
"everything") {
1200 PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_unknown_warning)
1214 Token &Tok)
override {
1223 if (Tok.
isNot(tok::l_paren)) {
1224 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
"(";
1231 if (II && II->
isStr(
"push")) {
1235 if (Tok.
is(tok::comma)) {
1238 if (Tok.
is(tok::numeric_constant) &&
1241 if (Level < 0 || Level > 4) {
1242 PP.
Diag(Tok, diag::warn_pragma_warning_push_level);
1248 }
else if (II && II->
isStr(
"pop")) {
1258 if (!II && !Tok.
is(tok::numeric_constant)) {
1259 PP.
Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1264 bool SpecifierValid;
1269 SpecifierValid = llvm::StringSwitch<bool>(
Specifier)
1270 .Cases(
"default",
"disable",
"error",
"once",
1282 SpecifierValid = (Value >= 1) && (Value <= 4);
1284 SpecifierValid =
false;
1288 if (!SpecifierValid) {
1289 PP.
Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1292 if (Tok.
isNot(tok::colon)) {
1293 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
":";
1300 while (Tok.
is(tok::numeric_constant)) {
1304 PP.
Diag(Tok, diag::warn_pragma_warning_expected_number);
1307 Ids.push_back(
int(Value));
1313 if (Tok.
isNot(tok::semi))
1319 if (Tok.
isNot(tok::r_paren)) {
1320 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
")";
1325 if (Tok.
isNot(tok::eod))
1326 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma warning";
1332 PragmaIncludeAliasHandler() :
PragmaHandler(
"include_alias") {}
1334 Token &IncludeAliasTok)
override {
1358 bool PragmaNameOnly =
false) {
1361 return PragmaNameOnly ?
"message" :
"pragma message";
1363 return PragmaNameOnly ?
"warning" :
"pragma warning";
1365 return PragmaNameOnly ?
"error" :
"pragma error";
1367 llvm_unreachable(
"Unknown PragmaMessageKind!");
1372 StringRef Namespace = StringRef())
1376 Token &Tok)
override {
1379 bool ExpectClosingParen =
false;
1383 ExpectClosingParen =
true;
1387 case tok::string_literal:
1391 PP.
Diag(MessageLoc, diag::err_pragma_message_malformed) <<
Kind;
1395 std::string MessageString;
1400 if (ExpectClosingParen) {
1401 if (Tok.
isNot(tok::r_paren)) {
1402 PP.
Diag(Tok.
getLocation(), diag::err_pragma_message_malformed) << Kind;
1408 if (Tok.
isNot(tok::eod)) {
1409 PP.
Diag(Tok.
getLocation(), diag::err_pragma_message_malformed) << Kind;
1415 ? diag::err_pragma_message
1416 : diag::warn_pragma_message) << MessageString;
1420 Callbacks->
PragmaMessage(MessageLoc, Namespace, Kind, MessageString);
1432 Token &Tok)
override {
1441 if (Tok.
isNot(tok::eod))
1442 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1453 tok::annot_module_include, Imported);
1455 CB->moduleImport(ImportLoc, ModuleName, Imported);
1469 Token &Tok)
override {
1478 if (Tok.
isNot(tok::eod))
1479 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1483 if (ModuleName.front().first->getName() !=
Current) {
1484 PP.
Diag(ModuleName.front().second, diag::err_pp_module_begin_wrong_module)
1485 << ModuleName.front().first << (ModuleName.size() > 1)
1486 << Current.empty() <<
Current;
1496 PP.
Diag(ModuleName.front().second,
1497 diag::err_pp_module_begin_no_module_map) << Current;
1500 for (
unsigned I = 1;
I != ModuleName.size(); ++
I) {
1503 PP.
Diag(ModuleName[
I].second, diag::err_pp_module_begin_no_submodule)
1513 PP.
Diag(BeginLoc, diag::note_pp_module_begin_here)
1521 tok::annot_module_begin, M);
1530 Token &Tok)
override {
1534 if (Tok.
isNot(tok::eod))
1535 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1541 PP.
Diag(Loc, diag::err_pp_module_end_without_module_begin);
1550 Token &Tok)
override {
1560 Token &Tok)
override {
1569 if (Tok.
isNot(tok::eod))
1570 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1584 Token &PushMacroTok)
override {
1595 Token &PopMacroTok)
override {
1603 struct PragmaSTDC_FENV_ACCESSHandler :
public PragmaHandler {
1604 PragmaSTDC_FENV_ACCESSHandler() :
PragmaHandler(
"FENV_ACCESS") {}
1607 Token &Tok)
override {
1612 PP.
Diag(Tok, diag::warn_stdc_fenv_access_not_supported);
1617 struct PragmaSTDC_CX_LIMITED_RANGEHandler :
public PragmaHandler {
1618 PragmaSTDC_CX_LIMITED_RANGEHandler()
1622 Token &Tok)
override {
1630 PragmaSTDC_UnknownHandler() {}
1633 Token &UnknownTok)
override {
1635 PP.
Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
1641 struct PragmaARCCFCodeAuditedHandler :
public PragmaHandler {
1642 PragmaARCCFCodeAuditedHandler() :
PragmaHandler(
"arc_cf_code_audited") {}
1645 Token &NameTok)
override {
1654 if (BeginEnd && BeginEnd->
isStr(
"begin")) {
1656 }
else if (BeginEnd && BeginEnd->
isStr(
"end")) {
1665 if (Tok.
isNot(tok::eod))
1666 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1677 PP.
Diag(Loc, diag::err_pp_double_begin_of_arc_cf_code_audited);
1678 PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1684 PP.
Diag(Loc, diag::err_pp_unmatched_end_of_arc_cf_code_audited);
1697 PragmaAssumeNonNullHandler() :
PragmaHandler(
"assume_nonnull") {}
1700 Token &NameTok)
override {
1709 if (BeginEnd && BeginEnd->
isStr(
"begin")) {
1711 }
else if (BeginEnd && BeginEnd->
isStr(
"end")) {
1720 if (Tok.
isNot(tok::eod))
1721 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1732 PP.
Diag(Loc, diag::err_pp_double_begin_of_assume_nonnull);
1733 PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1739 PP.
Diag(Loc, diag::err_pp_unmatched_end_of_assume_nonnull);
1761 PragmaRegionHandler(
const char *pragma) :
PragmaHandler(pragma) { }
1764 Token &NameTok)
override {
1776 void Preprocessor::RegisterBuiltinPragmas() {
1804 ModuleHandler->AddPragma(
new PragmaModuleImportHandler());
1805 ModuleHandler->AddPragma(
new PragmaModuleBeginHandler());
1806 ModuleHandler->AddPragma(
new PragmaModuleEndHandler());
1807 ModuleHandler->AddPragma(
new PragmaModuleBuildHandler());
1808 ModuleHandler->AddPragma(
new PragmaModuleLoadHandler());
1815 if (LangOpts.MicrosoftExt) {
1823 for (PragmaHandlerRegistry::iterator it = PragmaHandlerRegistry::begin(),
1824 ie = PragmaHandlerRegistry::end();
1838 if (
PragmaHandler *NS = PragmaHandlers->FindHandler(
"STDC")) {
1843 assert(STDCNamespace &&
1844 "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.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
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).
const NestedNameSpecifier * Specifier
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)...
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 *IsMapped, bool SkipCache=false)
Given a "foo" or <foo> reference, look up the indicated file.
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.
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 EnterSubmodule(Module *M, SourceLocation ImportLoc, bool ForPragma)
void AddPragma(PragmaHandler *Handler)
AddPragma - Add a pragma to this namespace.
Module * LeaveSubmodule(bool ForPragma)
void HandlePragmaPushMacro(Token &Tok)
Handle #pragma push_macro.
const MacroInfo * getMacroInfo(const IdentifierInfo *II) const
const LangOptions & getLangOpts() const
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
Token - This structure provides full information about a lexed token.
void setKind(tok::TokenKind K)
Describes a module or submodule.
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
const TargetInfo & getTargetInfo() const
unsigned getLine() const
Return the presumed line number of this location.
const FileEntry * getFileEntry() const
getFileEntry - Return the FileEntry corresponding to this FileID.
detail::InMemoryDirectory::const_iterator I
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.
static bool LexModuleName(Preprocessor &PP, Token &Tok, llvm::SmallVectorImpl< std::pair< IdentifierInfo *, SourceLocation >> &ModuleName)
StringRef getRawIdentifier() const
getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode), returns a reference to the text substring in the buffer if known.
void HandlePragmaPoison()
HandlePragmaPoison - Handle #pragma GCC poison.
PragmaMessageKind
Determines the kind of #pragma invoking a call to PragmaMessage.
Module * findSubmodule(StringRef Name) const
Find the submodule with the given name.
void HandlePragmaIncludeAlias(Token &Tok)
std::string CurrentModule
The name of the current module, of which the main source file is a part.
#pragma GCC warning has been invoked.
static bool IsHeaderFile(const std::string &Filename)
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.
void makeModuleVisible(Module *M, SourceLocation Loc)
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.
ModuleLoader & getModuleLoader() const
Retrieve the module loader associated with this preprocessor.
static bool checkModuleIsAvailable(const LangOptions &LangOpts, const TargetInfo &TargetInfo, DiagnosticsEngine &Diags, Module *M)
Check that the given module is available, producing a diagnostic if not.
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.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
bool isNot(tok::TokenKind K) const
Represents an unpacked "presumed" location which can be presented to the user.
static bool LexModuleNameComponent(Preprocessor &PP, Token &Tok, std::pair< IdentifierInfo *, SourceLocation > &ModuleNameComponent, bool First)
DirectoryLookup - This class represents one entry in the search list that specifies the search order ...
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
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.
StringRef GetString() const
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.
All of the names in this module are hidden.
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)
~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...
void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID, bool IsFileEntry, bool IsFileExit, SrcMgr::CharacteristicKind FileKind)
Add a line note to the line table for the FileID and offset specified by Loc.
virtual ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective)=0
Attempt to load the given module.
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...
virtual void loadModuleFromSource(SourceLocation Loc, StringRef ModuleName, StringRef Source)=0
Attempt to load the given module from the specified source buffer.
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...
Defines the PPCallbacks interface.
Defines the clang::TokenKind enum and support functions.
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
void EraseCachedTokens(CachedTokensRange TokenRange)
Erase the range of cached tokens that were lexed since EnableBacktrackAtThisPos() was previously call...
Defines the clang::SourceLocation class and associated facilities.
CachedTokensRange LastCachedTokenRange()
Returns the range of cached tokens that were lexed since EnableBacktrackAtThisPos() was previously ca...
Do not present this diagnostic, ignore it.
StringLiteralParser - This decodes string escape characters and performs wide string analysis and Tra...
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 HandlePragmaModuleBuild(Token &Tok)
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.
void EnterAnnotationToken(SourceRange Range, tok::TokenKind Kind, void *AnnotationVal)
Enter an annotation token into the token stream.
Defines the PreprocessorLexer interface.
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
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.