36 #include "llvm/ADT/ArrayRef.h" 37 #include "llvm/ADT/DenseMap.h" 38 #include "llvm/ADT/STLExtras.h" 39 #include "llvm/ADT/SmallString.h" 40 #include "llvm/ADT/SmallVector.h" 41 #include "llvm/ADT/StringSwitch.h" 42 #include "llvm/ADT/StringRef.h" 43 #include "llvm/Support/CrashRecoveryContext.h" 44 #include "llvm/Support/Compiler.h" 45 #include "llvm/Support/ErrorHandling.h" 55 using namespace clang;
75 llvm::DeleteContainerSeconds(Handlers);
83 bool IgnoreNull)
const {
86 return IgnoreNull ? nullptr : Handlers.lookup(StringRef());
90 assert(!Handlers.lookup(Handler->
getName()) &&
91 "A handler with this name is already registered in this namespace");
92 Handlers[Handler->
getName()] = Handler;
96 assert(Handlers.lookup(Handler->
getName()) &&
97 "Handler not registered in this namespace");
98 Handlers.erase(Handler->
getName());
114 PP.
Diag(Tok, diag::warn_pragma_ignored);
128 void Preprocessor::HandlePragmaDirective(
SourceLocation IntroducerLoc,
131 Callbacks->PragmaDirective(IntroducerLoc, Introducer);
140 PragmaHandlers->HandlePragma(*
this, Introducer, Tok);
143 if ((CurTokenLexer && CurTokenLexer->isParsingPreprocessorDirective())
144 || (CurPPLexer && CurPPLexer->ParsingPreprocessorDirective))
145 DiscardUntilEndOfDirective();
151 class LexingFor_PragmaRAII {
153 bool InMacroArgPreExpansion;
159 LexingFor_PragmaRAII(
Preprocessor &PP,
bool InMacroArgPreExpansion,
161 : PP(PP), InMacroArgPreExpansion(InMacroArgPreExpansion), OutTok(Tok) {
162 if (InMacroArgPreExpansion) {
168 ~LexingFor_PragmaRAII() {
169 if (InMacroArgPreExpansion) {
200 void Preprocessor::Handle_Pragma(
Token &
Tok) {
212 LexingFor_PragmaRAII _PragmaLexing(*
this, InMacroArgPreExpansion, Tok);
219 if (Tok.
isNot(tok::l_paren)) {
220 Diag(PragmaLoc, diag::err__Pragma_malformed);
221 return _PragmaLexing.failed();
227 Diag(PragmaLoc, diag::err__Pragma_malformed);
231 while (Tok.
isNot(tok::r_paren) &&
235 if (Tok.
is(tok::r_paren))
237 return _PragmaLexing.failed();
241 Diag(Tok, diag::err_invalid_string_udl);
244 if (Tok.
is(tok::r_paren))
246 return _PragmaLexing.failed();
254 if (Tok.
isNot(tok::r_paren)) {
255 Diag(PragmaLoc, diag::err__Pragma_malformed);
256 return _PragmaLexing.failed();
259 if (InMacroArgPreExpansion)
263 std::string StrVal = getSpelling(StrTok);
270 if (StrVal[0] ==
'L' || StrVal[0] ==
'U' ||
271 (StrVal[0] ==
'u' && StrVal[1] !=
'8'))
272 StrVal.erase(StrVal.begin());
273 else if (StrVal[0] ==
'u')
274 StrVal.erase(StrVal.begin(), StrVal.begin() + 2);
276 if (StrVal[0] ==
'R') {
279 assert(StrVal[1] ==
'"' && StrVal[StrVal.size() - 1] ==
'"' &&
280 "Invalid raw string token!");
283 unsigned NumDChars = 0;
284 while (StrVal[2 + NumDChars] !=
'(') {
285 assert(NumDChars < (StrVal.size() - 5) / 2 &&
286 "Invalid raw string token!");
289 assert(StrVal[StrVal.size() - 2 - NumDChars] ==
')');
293 StrVal.erase(0, 2 + NumDChars);
294 StrVal.erase(StrVal.size() - 1 - NumDChars);
296 assert(StrVal[0] ==
'"' && StrVal[StrVal.size()-1] ==
'"' &&
297 "Invalid string token!");
300 unsigned ResultPos = 1;
301 for (
size_t i = 1, e = StrVal.size() - 1; i != e; ++i) {
303 if (StrVal[i] ==
'\\' && i + 1 < e &&
304 (StrVal[i + 1] ==
'\\' || StrVal[i + 1] ==
'"'))
306 StrVal[ResultPos++] = StrVal[i];
308 StrVal.erase(StrVal.begin() + ResultPos, StrVal.end() - 1);
316 StrVal[StrVal.size()-1] =
'\n';
322 CreateString(StrVal, TmpTok);
328 StrVal.size(), *
this);
330 EnterSourceFileWithLexer(TL,
nullptr);
341 void Preprocessor::HandleMicrosoft__pragma(
Token &Tok) {
347 if (Tok.
isNot(tok::l_paren)) {
348 Diag(PragmaLoc, diag::err__Pragma_malformed);
357 PragmaToks.push_back(Tok);
358 if (Tok.
is(tok::l_paren))
360 else if (Tok.
is(tok::r_paren) && NumParens-- == 0)
366 Diag(PragmaLoc, diag::err_unterminated___pragma);
373 PragmaToks.back().setKind(tok::eod);
375 Token *TokArray =
new Token[PragmaToks.size()];
376 std::copy(PragmaToks.begin(), PragmaToks.end(), TokArray);
379 EnterTokenStream(TokArray, PragmaToks.size(),
true,
true);
395 Diag(OnceTok, diag::pp_pragma_once_in_main_file);
401 HeaderInfo.MarkFileIncludeOnce(getCurrentFileLexer()->getFileEntry());
405 assert(CurPPLexer &&
"No current lexer?");
406 CurLexer->ReadToEndOfLine();
419 if (CurPPLexer) CurPPLexer->LexingRawMode =
true;
420 LexUnexpandedToken(Tok);
421 if (CurPPLexer) CurPPLexer->LexingRawMode =
false;
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);
453 if (isInPrimaryFile()) {
454 Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
462 HeaderInfo.MarkFileSystemHeader(TheLexer->
getFileEntry());
468 unsigned FilenameID = SourceMgr.getLineTableFilenameID(PLoc.
getFilename());
479 FilenameID,
false,
false,
486 CurPPLexer->LexIncludeFilename(FilenameTok);
489 if (FilenameTok.
is(tok::eod))
494 bool Invalid =
false;
495 StringRef
Filename = getSpelling(FilenameTok, FilenameBuffer, &Invalid);
503 if (Filename.empty())
510 nullptr, CurDir,
nullptr,
nullptr,
nullptr,
nullptr);
512 if (!SuppressIncludeNotFoundError)
513 Diag(FilenameTok, diag::err_pp_file_not_found) <<
Filename;
517 const FileEntry *CurFile = getCurrentFileLexer()->getFileEntry();
524 while (DependencyTok.
isNot(tok::eod)) {
525 Message += getSpelling(DependencyTok) +
" ";
530 if (!Message.empty())
531 Message.erase(Message.end()-1);
532 Diag(FilenameTok, diag::pp_out_of_date_dependency) << Message;
544 if (Tok.
isNot(tok::l_paren)) {
545 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
546 << getSpelling(PragmaTok);
552 if (Tok.
isNot(tok::string_literal)) {
553 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
554 << getSpelling(PragmaTok);
559 Diag(Tok, diag::err_invalid_string_udl);
564 std::string StrVal = getSpelling(Tok);
568 if (Tok.
isNot(tok::r_paren)) {
569 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
570 << getSpelling(PragmaTok);
574 assert(StrVal[0] ==
'"' && StrVal[StrVal.size()-1] ==
'"' &&
575 "Invalid string token!");
580 MacroTok.setKind(tok::raw_identifier);
581 CreateString(StringRef(&StrVal[1], StrVal.size() - 2), MacroTok);
584 return LookUpIdentifierInfo(MacroTok);
595 IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PushMacroTok);
596 if (!IdentInfo)
return;
607 PragmaPushMacroInfo[IdentInfo].push_back(MI);
620 IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PopMacroTok);
621 if (!IdentInfo)
return;
624 llvm::DenseMap<IdentifierInfo *, std::vector<MacroInfo *>>::iterator iter =
625 PragmaPushMacroInfo.find(IdentInfo);
626 if (iter != PragmaPushMacroInfo.end()) {
628 if (
MacroInfo *MI = getMacroInfo(IdentInfo)) {
629 if (MI->isWarnIfUnused())
630 WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
631 appendMacroDirective(IdentInfo, AllocateUndefMacroDirective(MessageLoc));
635 MacroInfo *MacroToReInstall = iter->second.back();
637 if (MacroToReInstall)
639 appendDefMacroDirective(IdentInfo, MacroToReInstall, MessageLoc);
642 iter->second.pop_back();
643 if (iter->second.empty())
644 PragmaPushMacroInfo.erase(iter);
646 Diag(MessageLoc, diag::warn_pragma_pop_macro_no_push)
659 if (Tok.
isNot(tok::l_paren)) {
660 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
"(";
665 Token SourceFilenameTok;
666 CurPPLexer->LexIncludeFilename(SourceFilenameTok);
667 if (SourceFilenameTok.
is(tok::eod)) {
672 StringRef SourceFileName;
674 if (SourceFilenameTok.
is(tok::string_literal) ||
675 SourceFilenameTok.
is(tok::angle_string_literal)) {
676 SourceFileName = getSpelling(SourceFilenameTok, FileNameBuffer);
677 }
else if (SourceFilenameTok.
is(tok::less)) {
679 FileNameBuffer.push_back(
'<');
681 if (ConcatenateIncludeName(FileNameBuffer, End))
683 SourceFileName = FileNameBuffer;
685 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
688 FileNameBuffer.clear();
692 if (Tok.
isNot(tok::comma)) {
693 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
",";
697 Token ReplaceFilenameTok;
698 CurPPLexer->LexIncludeFilename(ReplaceFilenameTok);
699 if (ReplaceFilenameTok.
is(tok::eod)) {
704 StringRef ReplaceFileName;
705 if (ReplaceFilenameTok.
is(tok::string_literal) ||
706 ReplaceFilenameTok.
is(tok::angle_string_literal)) {
707 ReplaceFileName = getSpelling(ReplaceFilenameTok, FileNameBuffer);
708 }
else if (ReplaceFilenameTok.
is(tok::less)) {
710 FileNameBuffer.push_back(
'<');
712 if (ConcatenateIncludeName(FileNameBuffer, End))
714 ReplaceFileName = FileNameBuffer;
716 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
722 if (Tok.
isNot(tok::r_paren)) {
723 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
")";
729 StringRef OriginalSource = SourceFileName;
731 bool SourceIsAngled =
732 GetIncludeFilenameSpelling(SourceFilenameTok.
getLocation(),
734 bool ReplaceIsAngled =
735 GetIncludeFilenameSpelling(ReplaceFilenameTok.
getLocation(),
737 if (!SourceFileName.empty() && !ReplaceFileName.empty() &&
738 (SourceIsAngled != ReplaceIsAngled)) {
741 DiagID = diag::warn_pragma_include_alias_mismatch_angle;
743 DiagID = diag::warn_pragma_include_alias_mismatch_quote;
753 getHeaderSearchInfo().AddIncludeAlias(OriginalSource, ReplaceFileName);
760 std::pair<IdentifierInfo *, SourceLocation> &ModuleNameComponent,
767 ModuleNameComponent = std::make_pair(
770 ModuleNameComponent =
773 PP.
Diag(Tok.
getLocation(), diag::err_pp_expected_module_name) << First;
784 std::pair<IdentifierInfo*, SourceLocation> NameComponent;
787 ModuleName.push_back(NameComponent);
790 if (Tok.
isNot(tok::period))
798 std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc;
803 LexUnexpandedToken(Tok);
804 if (Tok.
isNot(tok::eod)) {
805 Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
806 DiscardUntilEndOfDirective();
809 CurLexer->LexingRawMode =
true;
811 auto TryConsumeIdentifier = [&](StringRef Ident) ->
bool {
812 if (Tok.
getKind() != tok::raw_identifier ||
820 const char *Start = CurLexer->getBufferLocation();
821 const char *
End =
nullptr;
822 unsigned NestingLevel = 1;
824 End = CurLexer->getBufferLocation();
828 Diag(Loc, diag::err_pp_module_build_missing_end);
839 CurLexer->ParsingPreprocessorDirective =
true;
841 if (TryConsumeIdentifier(
"pragma") && TryConsumeIdentifier(
"clang") &&
842 TryConsumeIdentifier(
"module")) {
843 if (TryConsumeIdentifier(
"build"))
846 else if (TryConsumeIdentifier(
"endbuild")) {
848 if (--NestingLevel == 0)
857 CurLexer->LexingRawMode =
false;
860 assert(CurLexer->getBuffer().begin() <= Start &&
861 Start <= CurLexer->getBuffer().end() &&
862 CurLexer->getBuffer().begin() <= End &&
863 End <= CurLexer->getBuffer().end() &&
864 "module source range not contained within same file buffer");
865 TheModuleLoader.loadModuleFromSource(Loc, ModuleName->
getName(),
866 StringRef(Start, End - Start));
871 if (Tok.
is(tok::l_paren)) {
874 std::string FileName;
875 if (!LexStringLiteral(Tok, FileName,
"pragma hdrstop",
false))
878 if (Tok.
isNot(tok::r_paren)) {
879 Diag(Tok, diag::err_expected) << tok::r_paren;
884 if (Tok.
isNot(tok::eod))
888 if (creatingPCHWithPragmaHdrStop() &&
890 assert(CurLexer &&
"no lexer for #pragma hdrstop processing");
893 CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd,
tok::eof);
894 CurLexer->cutOffLexing();
896 if (usingPCHWithPragmaHdrStop())
897 SkippingUntilPragmaHdrStop =
false;
908 if (!Namespace.empty()) {
912 if (
PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace)) {
914 assert(InsertNS !=
nullptr &&
"Cannot have a pragma namespace and pragma" 915 " handler with the same name!");
920 PragmaHandlers->AddPragma(InsertNS);
926 "Pragma handler already exists for this identifier!");
939 if (!Namespace.empty()) {
940 PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace);
941 assert(Existing &&
"Namespace containing handler does not exist!");
944 assert(NS &&
"Invalid namespace, registered as a regular pragma handler!");
950 if (NS != PragmaHandlers.get() && NS->
IsEmpty()) {
951 PragmaHandlers->RemovePragmaHandler(NS);
958 LexUnexpandedToken(Tok);
960 if (Tok.
isNot(tok::identifier)) {
961 Diag(Tok, diag::ext_on_off_switch_syntax);
967 else if (II->
isStr(
"OFF"))
969 else if (II->
isStr(
"DEFAULT"))
972 Diag(Tok, diag::ext_on_off_switch_syntax);
977 LexUnexpandedToken(Tok);
978 if (Tok.
isNot(tok::eod))
979 Diag(Tok, diag::ext_pragma_syntax_eod);
990 Token &OnceTok)
override {
1002 Token &MarkTok)
override {
1012 Token &PoisonTok)
override {
1020 PragmaSystemHeaderHandler() :
PragmaHandler(
"system_header") {}
1023 Token &SHToken)
override {
1033 Token &DepToken)
override {
1042 Token &DepToken)
override {
1045 if (Tok.
isNot(tok::identifier)) {
1046 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1051 if (II->
isStr(
"assert")) {
1052 llvm_unreachable(
"This is an assertion!");
1053 }
else if (II->
isStr(
"crash")) {
1055 }
else if (II->
isStr(
"parser_crash")) {
1058 Crasher.
setKind(tok::annot_pragma_parser_crash);
1061 }
else if (II->
isStr(
"dump")) {
1067 DumpAnnot.
setKind(tok::annot_pragma_dump);
1074 PP.
Diag(Identifier, diag::warn_pragma_debug_missing_argument)
1077 }
else if (II->
isStr(
"diag_mapping")) {
1080 if (DiagName.
is(tok::eod))
1082 else if (DiagName.
is(tok::string_literal) && !DiagName.
hasUDSuffix()) {
1088 PP.
Diag(DiagName, diag::warn_pragma_debug_missing_argument)
1091 }
else if (II->
isStr(
"llvm_fatal_error")) {
1092 llvm::report_fatal_error(
"#pragma clang __debug llvm_fatal_error");
1093 }
else if (II->
isStr(
"llvm_unreachable")) {
1094 llvm_unreachable(
"#pragma clang __debug llvm_unreachable");
1095 }
else if (II->
isStr(
"macro")) {
1102 PP.
Diag(MacroName, diag::warn_pragma_debug_missing_argument)
1104 }
else if (II->
isStr(
"overflow_stack")) {
1105 DebugOverflowStack();
1106 }
else if (II->
isStr(
"handle_crash")) {
1107 llvm::CrashRecoveryContext *CRC =llvm::CrashRecoveryContext::GetCurrent();
1110 }
else if (II->
isStr(
"captured")) {
1113 PP.
Diag(Tok, diag::warn_pragma_debug_unexpected_command)
1126 if (Tok.
isNot(tok::eod)) {
1127 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol)
1128 <<
"pragma clang __debug captured";
1135 Toks[0].startToken();
1136 Toks[0].setKind(tok::annot_pragma_captured);
1137 Toks[0].setLocation(NameLoc);
1139 PP.EnterTokenStream(Toks,
true);
1144 #pragma warning(disable : 4717) 1146 static void DebugOverflowStack(
void (*
P)() =
nullptr) {
1147 void (*
volatile Self)(void(*
P)()) = DebugOverflowStack;
1148 Self(
reinterpret_cast<void(*)()
>(Self));
1151 #pragma warning(default : 4717) 1158 const char *Namespace;
1161 explicit PragmaDiagnosticHandler(
const char *NS)
1165 Token &DiagToken)
override {
1169 if (Tok.
isNot(tok::identifier)) {
1170 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1176 if (II->
isStr(
"pop")) {
1178 PP.
Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
1182 }
else if (II->
isStr(
"push")) {
1197 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1204 std::string WarningName;
1209 if (Tok.
isNot(tok::eod)) {
1210 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_diagnostic_invalid_token);
1214 if (WarningName.size() < 3 || WarningName[0] !=
'-' ||
1215 (WarningName[1] !=
'W' && WarningName[1] !=
'R')) {
1216 PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_invalid_option);
1222 StringRef Group = StringRef(WarningName).substr(2);
1223 bool unknownDiag =
false;
1224 if (Group ==
"everything") {
1233 PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_unknown_warning)
1244 Token &DepToken)
override {
1256 Token &Tok)
override {
1265 if (Tok.
isNot(tok::l_paren)) {
1266 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
"(";
1273 if (II && II->
isStr(
"push")) {
1277 if (Tok.
is(tok::comma)) {
1280 if (Tok.
is(tok::numeric_constant) &&
1283 if (Level < 0 || Level > 4) {
1284 PP.
Diag(Tok, diag::warn_pragma_warning_push_level);
1290 }
else if (II && II->
isStr(
"pop")) {
1300 if (!II && !Tok.
is(tok::numeric_constant)) {
1301 PP.
Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1306 bool SpecifierValid;
1311 SpecifierValid = llvm::StringSwitch<bool>(
Specifier)
1312 .Cases(
"default",
"disable",
"error",
"once",
1324 SpecifierValid = (Value >= 1) && (Value <= 4);
1326 SpecifierValid =
false;
1330 if (!SpecifierValid) {
1331 PP.
Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1334 if (Tok.
isNot(tok::colon)) {
1335 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
":";
1342 while (Tok.
is(tok::numeric_constant)) {
1346 PP.
Diag(Tok, diag::warn_pragma_warning_expected_number);
1349 Ids.push_back(
int(Value));
1355 if (Tok.
isNot(tok::semi))
1361 if (Tok.
isNot(tok::r_paren)) {
1362 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
")";
1367 if (Tok.
isNot(tok::eod))
1368 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma warning";
1374 PragmaIncludeAliasHandler() :
PragmaHandler(
"include_alias") {}
1377 Token &IncludeAliasTok)
override {
1398 const StringRef Namespace;
1401 bool PragmaNameOnly =
false) {
1404 return PragmaNameOnly ?
"message" :
"pragma message";
1406 return PragmaNameOnly ?
"warning" :
"pragma warning";
1408 return PragmaNameOnly ?
"error" :
"pragma error";
1410 llvm_unreachable(
"Unknown PragmaMessageKind!");
1415 StringRef Namespace = StringRef())
1417 Namespace(Namespace) {}
1420 Token &Tok)
override {
1423 bool ExpectClosingParen =
false;
1427 ExpectClosingParen =
true;
1431 case tok::string_literal:
1435 PP.
Diag(MessageLoc, diag::err_pragma_message_malformed) <<
Kind;
1439 std::string MessageString;
1444 if (ExpectClosingParen) {
1445 if (Tok.
isNot(tok::r_paren)) {
1446 PP.
Diag(Tok.
getLocation(), diag::err_pragma_message_malformed) << Kind;
1452 if (Tok.
isNot(tok::eod)) {
1453 PP.
Diag(Tok.
getLocation(), diag::err_pragma_message_malformed) << Kind;
1459 ? diag::err_pragma_message
1460 : diag::warn_pragma_message) << MessageString;
1464 Callbacks->PragmaMessage(MessageLoc, Namespace, Kind, MessageString);
1476 Token &Tok)
override {
1485 if (Tok.
isNot(tok::eod))
1486 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1497 tok::annot_module_include, Imported);
1499 CB->moduleImport(ImportLoc, ModuleName, Imported);
1513 Token &Tok)
override {
1522 if (Tok.
isNot(tok::eod))
1523 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1527 if (ModuleName.front().first->getName() != Current) {
1528 PP.
Diag(ModuleName.front().second, diag::err_pp_module_begin_wrong_module)
1529 << ModuleName.front().first << (ModuleName.size() > 1)
1530 << Current.empty() << Current;
1540 PP.
Diag(ModuleName.front().second,
1541 diag::err_pp_module_begin_no_module_map) << Current;
1544 for (
unsigned I = 1; I != ModuleName.size(); ++I) {
1545 auto *NewM = M->
findSubmodule(ModuleName[I].first->getName());
1547 PP.
Diag(ModuleName[I].second, diag::err_pp_module_begin_no_submodule)
1557 PP.
Diag(BeginLoc, diag::note_pp_module_begin_here)
1565 tok::annot_module_begin, M);
1574 Token &Tok)
override {
1578 if (Tok.
isNot(tok::eod))
1579 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1585 PP.
Diag(Loc, diag::err_pp_module_end_without_module_begin);
1594 Token &Tok)
override {
1604 Token &Tok)
override {
1613 if (Tok.
isNot(tok::eod))
1614 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1628 Token &PushMacroTok)
override {
1639 Token &PopMacroTok)
override {
1646 struct PragmaARCCFCodeAuditedHandler :
public PragmaHandler {
1647 PragmaARCCFCodeAuditedHandler() :
PragmaHandler(
"arc_cf_code_audited") {}
1650 Token &NameTok)
override {
1659 if (BeginEnd && BeginEnd->
isStr(
"begin")) {
1661 }
else if (BeginEnd && BeginEnd->
isStr(
"end")) {
1670 if (Tok.
isNot(tok::eod))
1671 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1682 PP.
Diag(Loc, diag::err_pp_double_begin_of_arc_cf_code_audited);
1683 PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1689 PP.
Diag(Loc, diag::err_pp_unmatched_end_of_arc_cf_code_audited);
1702 PragmaAssumeNonNullHandler() :
PragmaHandler(
"assume_nonnull") {}
1705 Token &NameTok)
override {
1714 if (BeginEnd && BeginEnd->
isStr(
"begin")) {
1716 }
else if (BeginEnd && BeginEnd->
isStr(
"end")) {
1725 if (Tok.
isNot(tok::eod))
1726 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1738 PP.
Diag(Loc, diag::err_pp_double_begin_of_assume_nonnull);
1739 PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1747 PP.
Diag(Loc, diag::err_pp_unmatched_end_of_assume_nonnull);
1771 PragmaRegionHandler(
const char *pragma) :
PragmaHandler(pragma) {}
1774 Token &NameTok)
override {
1786 void Preprocessor::RegisterBuiltinPragmas() {
1787 AddPragmaHandler(
new PragmaOnceHandler());
1788 AddPragmaHandler(
new PragmaMarkHandler());
1789 AddPragmaHandler(
new PragmaPushMacroHandler());
1790 AddPragmaHandler(
new PragmaPopMacroHandler());
1794 AddPragmaHandler(
"GCC",
new PragmaPoisonHandler());
1795 AddPragmaHandler(
"GCC",
new PragmaSystemHeaderHandler());
1796 AddPragmaHandler(
"GCC",
new PragmaDependencyHandler());
1797 AddPragmaHandler(
"GCC",
new PragmaDiagnosticHandler(
"GCC"));
1803 AddPragmaHandler(
"clang",
new PragmaPoisonHandler());
1804 AddPragmaHandler(
"clang",
new PragmaSystemHeaderHandler());
1805 AddPragmaHandler(
"clang",
new PragmaDebugHandler());
1806 AddPragmaHandler(
"clang",
new PragmaDependencyHandler());
1807 AddPragmaHandler(
"clang",
new PragmaDiagnosticHandler(
"clang"));
1808 AddPragmaHandler(
"clang",
new PragmaARCCFCodeAuditedHandler());
1809 AddPragmaHandler(
"clang",
new PragmaAssumeNonNullHandler());
1813 AddPragmaHandler(
"clang", ModuleHandler);
1814 ModuleHandler->AddPragma(
new PragmaModuleImportHandler());
1815 ModuleHandler->AddPragma(
new PragmaModuleBeginHandler());
1816 ModuleHandler->AddPragma(
new PragmaModuleEndHandler());
1817 ModuleHandler->AddPragma(
new PragmaModuleBuildHandler());
1818 ModuleHandler->AddPragma(
new PragmaModuleLoadHandler());
1821 AddPragmaHandler(
new PragmaRegionHandler(
"region"));
1822 AddPragmaHandler(
new PragmaRegionHandler(
"endregion"));
1825 if (LangOpts.MicrosoftExt) {
1826 AddPragmaHandler(
new PragmaWarningHandler());
1827 AddPragmaHandler(
new PragmaIncludeAliasHandler());
1828 AddPragmaHandler(
new PragmaHdrstopHandler());
1832 for (PragmaHandlerRegistry::iterator it = PragmaHandlerRegistry::begin(),
1833 ie = PragmaHandlerRegistry::end();
1835 AddPragmaHandler(it->instantiate().release());
A diagnostic that indicates a problem or potential problem.
void setSeverityForAll(diag::Flavor Flavor, diag::Severity Map, SourceLocation Loc=SourceLocation())
Add the specified mapping to all diagnostics of the specified flavor.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
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.
void setChangedSinceDeserialization()
Note that this identifier has changed since it was loaded from an AST file.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
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.
time_t getModificationTime() const
void AddPragmaHandler(StringRef Namespace, PragmaHandler *Handler)
Add the specified pragma handler to this preprocessor.
#pragma GCC error has been invoked.
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)) {...
Defines the SourceManager interface.
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, Token &FirstToken)=0
Defines the clang::Module class, which describes a module in the source code.
void dumpMacroInfo(const IdentifierInfo *II)
SourceLocation getPragmaARCCFCodeAuditedLoc() const
The location of the currently-active #pragma clang arc_cf_code_audited begin.
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.
bool isFromAST() const
Return true if the identifier in its current state was loaded from an AST file.
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).
PragmaHandler * FindHandler(StringRef Name, bool IgnoreNull=true) const
FindHandler - Check to see if there is already a handler for the specified name.
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...
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
tok::TokenKind getKind() const
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.
LLVM_DUMP_METHOD void dump() const
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
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 TargetInfo & getTargetInfo() const
Token - This structure provides full information about a lexed token.
void setKind(tok::TokenKind K)
const LangOptions & getLangOpts() const
Describes a module or submodule.
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
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 ...
HeaderSearch & getHeaderSearchInfo() const
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix. ...
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
void setIsAllowRedefinitionsWithoutWarning(bool Val)
Set the value of the IsAllowRedefinitionsWithoutWarning flag.
bool setSeverityForGroup(diag::Flavor Flavor, StringRef Group, diag::Severity Map, SourceLocation Loc=SourceLocation())
Change an entire diagnostic group (e.g.
Defines the Diagnostic-related interfaces.
void CommitBacktrackedTokens()
Disable the last EnableBacktrackAtThisPos call.
Present this diagnostic as an error.
PragmaIntroducerKind
Describes how the pragma was introduced, e.g., with #pragma, _Pragma, or __pragma.
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)
void HandlePragmaPoison()
HandlePragmaPoison - Handle #pragma GCC poison. PoisonTok is the 'poison'.
PragmaMessageKind
Determines the kind of #pragma invoking a call to PragmaMessage.
void HandlePragmaIncludeAlias(Token &Tok)
std::string CurrentModule
The name of the current module, of which the main source file is a part.
Module * findSubmodule(StringRef Name) const
Find the submodule with the given name.
virtual void PragmaAssumeNonNullBegin(SourceLocation Loc)
Callback invoked when a #pragma clang assume_nonnull begin directive is read.
#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...
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. OnceTok is the 'once'.
void setAnnotationValue(void *val)
Defines the clang::LangOptions interface.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
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...
unsigned getLine() const
Return the presumed line number of this location.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
Defines the clang::Preprocessor interface.
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.
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.
void HandlePragmaDependency(Token &DependencyTok)
HandlePragmaDependency - Handle #pragma GCC dependency "foo" blah.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Represents an unpacked "presumed" location which can be presented to the user.
PPCallbacks * getPPCallbacks() const
The result type of a method or function.
static bool LexModuleNameComponent(Preprocessor &PP, Token &Tok, std::pair< IdentifierInfo *, SourceLocation > &ModuleNameComponent, bool First)
StringRef GetString() const
DirectoryLookup - This class represents one entry in the search list that specifies the search order ...
const char * getFilename() const
Return the presumed filename of this location.
Encodes a location in the source.
void setPragmaARCCFCodeAuditedLoc(SourceLocation Loc)
Set the location of the currently-active #pragma clang arc_cf_code_audited begin. ...
#pragma message has been invoked.
All of the names in this module are hidden.
IdentifierInfo * getIdentifierInfo() const
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.
bool isPoisoned() const
Return true if this token has been poisoned.
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
Flavor
Flavors of diagnostics we can emit.
SourceLocation getPragmaAssumeNonNullLoc() const
The location of the currently-active #pragma clang assume_nonnull begin.
void HandlePragmaHdrstop(Token &Tok)
StringRef getName() const
Return the actual identifier string.
bool isNot(tok::TokenKind K) const
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
~PragmaNamespace() override
const FileEntry * getFileEntry() const
getFileEntry - Return the FileEntry corresponding to this FileID.
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...
virtual ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective)=0
Attempt to load the given module.
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, Token &Tok) override
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).
PragmaNamespace - This PragmaHandler subdivides the namespace of pragmas, allowing hierarchical pragm...
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...
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...
ModuleLoader & getModuleLoader() const
Retrieve the module loader associated with this preprocessor.
IdentifierInfo * ParsePragmaPushOrPopMacro(Token &Tok)
ParsePragmaPushOrPopMacro - Handle parsing of pragma push_macro/pop_macro.
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, Token &FirstToken) override
void CheckEndOfDirective(const char *DirType, bool EnableMacros=false)
Ensure that the next token is a tok::eod token.
Defines the PPCallbacks interface.
Defines the clang::TokenKind enum and support functions.
void EraseCachedTokens(CachedTokensRange TokenRange)
Erase the range of cached tokens that were lexed since EnableBacktrackAtThisPos() was previously call...
virtual void PragmaAssumeNonNullEnd(SourceLocation Loc)
Callback invoked when a #pragma clang assume_nonnull end directive is read.
Defines the clang::SourceLocation class and associated facilities.
bool LexOnOffSwitch(tok::OnOffSwitch &Result)
Lex an on-off-switch (C99 6.10.6p2) and verify that it is followed by EOD.
DiagnosticsEngine & getDiagnostics() const
CachedTokensRange LastCachedTokenRange()
Returns the range of cached tokens that were lexed since EnableBacktrackAtThisPos() was previously ca...
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.
static bool isMacroDefined(const Sema &S, SourceLocation Loc, StringRef Name)
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.
__DEVICE__ int max(int __a, int __b)
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...
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.
StringRef getName() const
void EnterAnnotationToken(SourceRange Range, tok::TokenKind Kind, void *AnnotationVal)
Enter an annotation token into the token stream.
Defines the PreprocessorLexer interface.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
void startToken()
Reset all flags to cleared.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.