37 #include "llvm/ADT/ArrayRef.h" 38 #include "llvm/ADT/DenseMap.h" 39 #include "llvm/ADT/STLExtras.h" 40 #include "llvm/ADT/SmallString.h" 41 #include "llvm/ADT/SmallVector.h" 42 #include "llvm/ADT/StringSwitch.h" 43 #include "llvm/ADT/StringRef.h" 44 #include "llvm/Support/CrashRecoveryContext.h" 45 #include "llvm/Support/Compiler.h" 46 #include "llvm/Support/ErrorHandling.h" 56 using namespace clang;
76 llvm::DeleteContainerSeconds(Handlers);
84 bool IgnoreNull)
const {
87 return IgnoreNull ? nullptr : Handlers.lookup(StringRef());
91 assert(!Handlers.lookup(Handler->
getName()) &&
92 "A handler with this name is already registered in this namespace");
93 Handlers[Handler->
getName()] = Handler;
97 assert(Handlers.lookup(Handler->
getName()) &&
98 "Handler not registered in this namespace");
99 Handlers.erase(Handler->
getName());
115 PP.
Diag(Tok, diag::warn_pragma_ignored);
129 void Preprocessor::HandlePragmaDirective(
SourceLocation IntroducerLoc,
132 Callbacks->PragmaDirective(IntroducerLoc, Introducer);
141 PragmaHandlers->HandlePragma(*
this, Introducer, Tok);
144 if ((CurTokenLexer && CurTokenLexer->isParsingPreprocessorDirective())
145 || (CurPPLexer && CurPPLexer->ParsingPreprocessorDirective))
146 DiscardUntilEndOfDirective();
152 class LexingFor_PragmaRAII {
154 bool InMacroArgPreExpansion;
160 LexingFor_PragmaRAII(
Preprocessor &PP,
bool InMacroArgPreExpansion,
162 : PP(PP), InMacroArgPreExpansion(InMacroArgPreExpansion), OutTok(Tok) {
163 if (InMacroArgPreExpansion) {
169 ~LexingFor_PragmaRAII() {
170 if (InMacroArgPreExpansion) {
201 void Preprocessor::Handle_Pragma(
Token &
Tok) {
213 LexingFor_PragmaRAII _PragmaLexing(*
this, InMacroArgPreExpansion, Tok);
220 if (Tok.
isNot(tok::l_paren)) {
221 Diag(PragmaLoc, diag::err__Pragma_malformed);
222 return _PragmaLexing.failed();
228 Diag(PragmaLoc, diag::err__Pragma_malformed);
232 while (Tok.
isNot(tok::r_paren) &&
236 if (Tok.
is(tok::r_paren))
238 return _PragmaLexing.failed();
242 Diag(Tok, diag::err_invalid_string_udl);
245 if (Tok.
is(tok::r_paren))
247 return _PragmaLexing.failed();
255 if (Tok.
isNot(tok::r_paren)) {
256 Diag(PragmaLoc, diag::err__Pragma_malformed);
257 return _PragmaLexing.failed();
260 if (InMacroArgPreExpansion)
264 std::string StrVal = getSpelling(StrTok);
271 if (StrVal[0] ==
'L' || StrVal[0] ==
'U' ||
272 (StrVal[0] ==
'u' && StrVal[1] !=
'8'))
273 StrVal.erase(StrVal.begin());
274 else if (StrVal[0] ==
'u')
275 StrVal.erase(StrVal.begin(), StrVal.begin() + 2);
277 if (StrVal[0] ==
'R') {
280 assert(StrVal[1] ==
'"' && StrVal[StrVal.size() - 1] ==
'"' &&
281 "Invalid raw string token!");
284 unsigned NumDChars = 0;
285 while (StrVal[2 + NumDChars] !=
'(') {
286 assert(NumDChars < (StrVal.size() - 5) / 2 &&
287 "Invalid raw string token!");
290 assert(StrVal[StrVal.size() - 2 - NumDChars] ==
')');
294 StrVal.erase(0, 2 + NumDChars);
295 StrVal.erase(StrVal.size() - 1 - NumDChars);
297 assert(StrVal[0] ==
'"' && StrVal[StrVal.size()-1] ==
'"' &&
298 "Invalid string token!");
301 unsigned ResultPos = 1;
302 for (
size_t i = 1, e = StrVal.size() - 1; i != e; ++i) {
304 if (StrVal[i] ==
'\\' && i + 1 < e &&
305 (StrVal[i + 1] ==
'\\' || StrVal[i + 1] ==
'"'))
307 StrVal[ResultPos++] = StrVal[i];
309 StrVal.erase(StrVal.begin() + ResultPos, StrVal.end() - 1);
317 StrVal[StrVal.size()-1] =
'\n';
323 CreateString(StrVal, TmpTok);
329 StrVal.size(), *
this);
331 EnterSourceFileWithLexer(TL,
nullptr);
342 void Preprocessor::HandleMicrosoft__pragma(
Token &Tok) {
348 if (Tok.
isNot(tok::l_paren)) {
349 Diag(PragmaLoc, diag::err__Pragma_malformed);
358 PragmaToks.push_back(Tok);
359 if (Tok.
is(tok::l_paren))
361 else if (Tok.
is(tok::r_paren) && NumParens-- == 0)
367 Diag(PragmaLoc, diag::err_unterminated___pragma);
374 PragmaToks.back().setKind(tok::eod);
376 Token *TokArray =
new Token[PragmaToks.size()];
377 std::copy(PragmaToks.begin(), PragmaToks.end(), TokArray);
380 EnterTokenStream(TokArray, PragmaToks.size(),
true,
true);
396 Diag(OnceTok, diag::pp_pragma_once_in_main_file);
402 HeaderInfo.MarkFileIncludeOnce(getCurrentFileLexer()->getFileEntry());
406 assert(CurPPLexer &&
"No current lexer?");
408 CurLexer->ReadToEndOfLine();
410 CurPTHLexer->DiscardToEndOfLine();
423 if (CurPPLexer) CurPPLexer->LexingRawMode =
true;
424 LexUnexpandedToken(Tok);
425 if (CurPPLexer) CurPPLexer->LexingRawMode =
false;
428 if (Tok.
is(tok::eod))
return;
431 if (Tok.
isNot(tok::raw_identifier)) {
432 Diag(Tok, diag::err_pp_invalid_poison);
445 Diag(Tok, diag::pp_poisoning_existing_macro);
457 if (isInPrimaryFile()) {
458 Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
466 HeaderInfo.MarkFileSystemHeader(TheLexer->
getFileEntry());
472 unsigned FilenameID = SourceMgr.getLineTableFilenameID(PLoc.
getFilename());
483 FilenameID,
false,
false,
490 CurPPLexer->LexIncludeFilename(FilenameTok);
493 if (FilenameTok.
is(tok::eod))
498 bool Invalid =
false;
499 StringRef
Filename = getSpelling(FilenameTok, FilenameBuffer, &Invalid);
507 if (Filename.empty())
514 nullptr, CurDir,
nullptr,
nullptr,
nullptr,
nullptr);
516 if (!SuppressIncludeNotFoundError)
517 Diag(FilenameTok, diag::err_pp_file_not_found) <<
Filename;
521 const FileEntry *CurFile = getCurrentFileLexer()->getFileEntry();
528 while (DependencyTok.
isNot(tok::eod)) {
529 Message += getSpelling(DependencyTok) +
" ";
534 if (!Message.empty())
535 Message.erase(Message.end()-1);
536 Diag(FilenameTok, diag::pp_out_of_date_dependency) << Message;
548 if (Tok.
isNot(tok::l_paren)) {
549 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
550 << getSpelling(PragmaTok);
556 if (Tok.
isNot(tok::string_literal)) {
557 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
558 << getSpelling(PragmaTok);
563 Diag(Tok, diag::err_invalid_string_udl);
568 std::string StrVal = getSpelling(Tok);
572 if (Tok.
isNot(tok::r_paren)) {
573 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
574 << getSpelling(PragmaTok);
578 assert(StrVal[0] ==
'"' && StrVal[StrVal.size()-1] ==
'"' &&
579 "Invalid string token!");
584 MacroTok.setKind(tok::raw_identifier);
585 CreateString(StringRef(&StrVal[1], StrVal.size() - 2), MacroTok);
588 return LookUpIdentifierInfo(MacroTok);
599 IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PushMacroTok);
600 if (!IdentInfo)
return;
611 PragmaPushMacroInfo[IdentInfo].push_back(MI);
624 IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PopMacroTok);
625 if (!IdentInfo)
return;
628 llvm::DenseMap<IdentifierInfo *, std::vector<MacroInfo *>>::iterator iter =
629 PragmaPushMacroInfo.find(IdentInfo);
630 if (iter != PragmaPushMacroInfo.end()) {
632 if (
MacroInfo *MI = getMacroInfo(IdentInfo)) {
633 if (MI->isWarnIfUnused())
634 WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
635 appendMacroDirective(IdentInfo, AllocateUndefMacroDirective(MessageLoc));
639 MacroInfo *MacroToReInstall = iter->second.back();
641 if (MacroToReInstall)
643 appendDefMacroDirective(IdentInfo, MacroToReInstall, MessageLoc);
646 iter->second.pop_back();
647 if (iter->second.empty())
648 PragmaPushMacroInfo.erase(iter);
650 Diag(MessageLoc, diag::warn_pragma_pop_macro_no_push)
663 if (Tok.
isNot(tok::l_paren)) {
664 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
"(";
669 Token SourceFilenameTok;
670 CurPPLexer->LexIncludeFilename(SourceFilenameTok);
671 if (SourceFilenameTok.
is(tok::eod)) {
676 StringRef SourceFileName;
678 if (SourceFilenameTok.
is(tok::string_literal) ||
679 SourceFilenameTok.
is(tok::angle_string_literal)) {
680 SourceFileName = getSpelling(SourceFilenameTok, FileNameBuffer);
681 }
else if (SourceFilenameTok.
is(tok::less)) {
683 FileNameBuffer.push_back(
'<');
685 if (ConcatenateIncludeName(FileNameBuffer, End))
687 SourceFileName = FileNameBuffer;
689 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
692 FileNameBuffer.clear();
696 if (Tok.
isNot(tok::comma)) {
697 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
",";
701 Token ReplaceFilenameTok;
702 CurPPLexer->LexIncludeFilename(ReplaceFilenameTok);
703 if (ReplaceFilenameTok.
is(tok::eod)) {
708 StringRef ReplaceFileName;
709 if (ReplaceFilenameTok.
is(tok::string_literal) ||
710 ReplaceFilenameTok.
is(tok::angle_string_literal)) {
711 ReplaceFileName = getSpelling(ReplaceFilenameTok, FileNameBuffer);
712 }
else if (ReplaceFilenameTok.
is(tok::less)) {
714 FileNameBuffer.push_back(
'<');
716 if (ConcatenateIncludeName(FileNameBuffer, End))
718 ReplaceFileName = FileNameBuffer;
720 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
726 if (Tok.
isNot(tok::r_paren)) {
727 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
")";
733 StringRef OriginalSource = SourceFileName;
735 bool SourceIsAngled =
736 GetIncludeFilenameSpelling(SourceFilenameTok.
getLocation(),
738 bool ReplaceIsAngled =
739 GetIncludeFilenameSpelling(ReplaceFilenameTok.
getLocation(),
741 if (!SourceFileName.empty() && !ReplaceFileName.empty() &&
742 (SourceIsAngled != ReplaceIsAngled)) {
745 DiagID = diag::warn_pragma_include_alias_mismatch_angle;
747 DiagID = diag::warn_pragma_include_alias_mismatch_quote;
757 getHeaderSearchInfo().AddIncludeAlias(OriginalSource, ReplaceFileName);
764 std::pair<IdentifierInfo *, SourceLocation> &ModuleNameComponent,
771 ModuleNameComponent = std::make_pair(
774 ModuleNameComponent =
777 PP.
Diag(Tok.
getLocation(), diag::err_pp_expected_module_name) << First;
788 std::pair<IdentifierInfo*, SourceLocation> NameComponent;
791 ModuleName.push_back(NameComponent);
794 if (Tok.
isNot(tok::period))
802 std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc;
807 LexUnexpandedToken(Tok);
808 if (Tok.
isNot(tok::eod)) {
809 Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
810 DiscardUntilEndOfDirective();
815 Diag(Loc, diag::err_pp_module_build_pth);
819 CurLexer->LexingRawMode =
true;
821 auto TryConsumeIdentifier = [&](StringRef Ident) ->
bool {
822 if (Tok.
getKind() != tok::raw_identifier ||
830 const char *Start = CurLexer->getBufferLocation();
831 const char *
End =
nullptr;
832 unsigned NestingLevel = 1;
834 End = CurLexer->getBufferLocation();
838 Diag(Loc, diag::err_pp_module_build_missing_end);
849 CurLexer->ParsingPreprocessorDirective =
true;
851 if (TryConsumeIdentifier(
"pragma") && TryConsumeIdentifier(
"clang") &&
852 TryConsumeIdentifier(
"module")) {
853 if (TryConsumeIdentifier(
"build"))
856 else if (TryConsumeIdentifier(
"endbuild")) {
858 if (--NestingLevel == 0)
867 CurLexer->LexingRawMode =
false;
870 assert(CurLexer->getBuffer().begin() <= Start &&
871 Start <= CurLexer->getBuffer().end() &&
872 CurLexer->getBuffer().begin() <= End &&
873 End <= CurLexer->getBuffer().end() &&
874 "module source range not contained within same file buffer");
875 TheModuleLoader.loadModuleFromSource(Loc, ModuleName->
getName(),
876 StringRef(Start, End - Start));
887 if (!Namespace.empty()) {
891 if (
PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace)) {
893 assert(InsertNS !=
nullptr &&
"Cannot have a pragma namespace and pragma" 894 " handler with the same name!");
899 PragmaHandlers->AddPragma(InsertNS);
905 "Pragma handler already exists for this identifier!");
918 if (!Namespace.empty()) {
919 PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace);
920 assert(Existing &&
"Namespace containing handler does not exist!");
923 assert(NS &&
"Invalid namespace, registered as a regular pragma handler!");
929 if (NS != PragmaHandlers.get() && NS->
IsEmpty()) {
930 PragmaHandlers->RemovePragmaHandler(NS);
937 LexUnexpandedToken(Tok);
939 if (Tok.
isNot(tok::identifier)) {
940 Diag(Tok, diag::ext_on_off_switch_syntax);
946 else if (II->
isStr(
"OFF"))
948 else if (II->
isStr(
"DEFAULT"))
951 Diag(Tok, diag::ext_on_off_switch_syntax);
956 LexUnexpandedToken(Tok);
957 if (Tok.
isNot(tok::eod))
958 Diag(Tok, diag::ext_pragma_syntax_eod);
969 Token &OnceTok)
override {
981 Token &MarkTok)
override {
991 Token &PoisonTok)
override {
999 PragmaSystemHeaderHandler() :
PragmaHandler(
"system_header") {}
1002 Token &SHToken)
override {
1012 Token &DepToken)
override {
1021 Token &DepToken)
override {
1024 if (Tok.
isNot(tok::identifier)) {
1025 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1030 if (II->
isStr(
"assert")) {
1031 llvm_unreachable(
"This is an assertion!");
1032 }
else if (II->
isStr(
"crash")) {
1034 }
else if (II->
isStr(
"parser_crash")) {
1037 Crasher.
setKind(tok::annot_pragma_parser_crash);
1040 }
else if (II->
isStr(
"dump")) {
1046 DumpAnnot.
setKind(tok::annot_pragma_dump);
1053 PP.
Diag(Identifier, diag::warn_pragma_debug_missing_argument)
1056 }
else if (II->
isStr(
"diag_mapping")) {
1059 if (DiagName.
is(tok::eod))
1061 else if (DiagName.
is(tok::string_literal) && !DiagName.
hasUDSuffix()) {
1067 PP.
Diag(DiagName, diag::warn_pragma_debug_missing_argument)
1070 }
else if (II->
isStr(
"llvm_fatal_error")) {
1071 llvm::report_fatal_error(
"#pragma clang __debug llvm_fatal_error");
1072 }
else if (II->
isStr(
"llvm_unreachable")) {
1073 llvm_unreachable(
"#pragma clang __debug llvm_unreachable");
1074 }
else if (II->
isStr(
"macro")) {
1081 PP.
Diag(MacroName, diag::warn_pragma_debug_missing_argument)
1083 }
else if (II->
isStr(
"overflow_stack")) {
1084 DebugOverflowStack();
1085 }
else if (II->
isStr(
"handle_crash")) {
1086 llvm::CrashRecoveryContext *CRC =llvm::CrashRecoveryContext::GetCurrent();
1089 }
else if (II->
isStr(
"captured")) {
1092 PP.
Diag(Tok, diag::warn_pragma_debug_unexpected_command)
1109 if (Tok.
isNot(tok::eod)) {
1110 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol)
1111 <<
"pragma clang __debug captured";
1118 Toks[0].startToken();
1119 Toks[0].setKind(tok::annot_pragma_captured);
1120 Toks[0].setLocation(NameLoc);
1122 PP.EnterTokenStream(Toks,
true);
1127 #pragma warning(disable : 4717) 1129 static void DebugOverflowStack(
void (*
P)() =
nullptr) {
1130 void (*
volatile Self)(void(*
P)()) = DebugOverflowStack;
1131 Self(
reinterpret_cast<void(*)()
>(Self));
1134 #pragma warning(default : 4717) 1141 const char *Namespace;
1144 explicit PragmaDiagnosticHandler(
const char *NS)
1148 Token &DiagToken)
override {
1152 if (Tok.
isNot(tok::identifier)) {
1153 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1159 if (II->
isStr(
"pop")) {
1161 PP.
Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
1165 }
else if (II->
isStr(
"push")) {
1180 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1187 std::string WarningName;
1192 if (Tok.
isNot(tok::eod)) {
1193 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_diagnostic_invalid_token);
1197 if (WarningName.size() < 3 || WarningName[0] !=
'-' ||
1198 (WarningName[1] !=
'W' && WarningName[1] !=
'R')) {
1199 PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_invalid_option);
1205 StringRef Group = StringRef(WarningName).substr(2);
1206 bool unknownDiag =
false;
1207 if (Group ==
"everything") {
1216 PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_unknown_warning)
1230 Token &Tok)
override {
1239 if (Tok.
isNot(tok::l_paren)) {
1240 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
"(";
1247 if (II && II->
isStr(
"push")) {
1251 if (Tok.
is(tok::comma)) {
1254 if (Tok.
is(tok::numeric_constant) &&
1257 if (Level < 0 || Level > 4) {
1258 PP.
Diag(Tok, diag::warn_pragma_warning_push_level);
1264 }
else if (II && II->
isStr(
"pop")) {
1274 if (!II && !Tok.
is(tok::numeric_constant)) {
1275 PP.
Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1280 bool SpecifierValid;
1285 SpecifierValid = llvm::StringSwitch<bool>(
Specifier)
1286 .Cases(
"default",
"disable",
"error",
"once",
1298 SpecifierValid = (Value >= 1) && (Value <= 4);
1300 SpecifierValid =
false;
1304 if (!SpecifierValid) {
1305 PP.
Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1308 if (Tok.
isNot(tok::colon)) {
1309 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
":";
1316 while (Tok.
is(tok::numeric_constant)) {
1320 PP.
Diag(Tok, diag::warn_pragma_warning_expected_number);
1323 Ids.push_back(
int(Value));
1329 if (Tok.
isNot(tok::semi))
1335 if (Tok.
isNot(tok::r_paren)) {
1336 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
")";
1341 if (Tok.
isNot(tok::eod))
1342 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma warning";
1348 PragmaIncludeAliasHandler() :
PragmaHandler(
"include_alias") {}
1351 Token &IncludeAliasTok)
override {
1372 const StringRef Namespace;
1375 bool PragmaNameOnly =
false) {
1378 return PragmaNameOnly ?
"message" :
"pragma message";
1380 return PragmaNameOnly ?
"warning" :
"pragma warning";
1382 return PragmaNameOnly ?
"error" :
"pragma error";
1384 llvm_unreachable(
"Unknown PragmaMessageKind!");
1389 StringRef Namespace = StringRef())
1391 Namespace(Namespace) {}
1394 Token &Tok)
override {
1397 bool ExpectClosingParen =
false;
1401 ExpectClosingParen =
true;
1405 case tok::string_literal:
1409 PP.
Diag(MessageLoc, diag::err_pragma_message_malformed) <<
Kind;
1413 std::string MessageString;
1418 if (ExpectClosingParen) {
1419 if (Tok.
isNot(tok::r_paren)) {
1420 PP.
Diag(Tok.
getLocation(), diag::err_pragma_message_malformed) << Kind;
1426 if (Tok.
isNot(tok::eod)) {
1427 PP.
Diag(Tok.
getLocation(), diag::err_pragma_message_malformed) << Kind;
1433 ? diag::err_pragma_message
1434 : diag::warn_pragma_message) << MessageString;
1438 Callbacks->PragmaMessage(MessageLoc, Namespace, Kind, MessageString);
1450 Token &Tok)
override {
1459 if (Tok.
isNot(tok::eod))
1460 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1471 tok::annot_module_include, Imported);
1473 CB->moduleImport(ImportLoc, ModuleName, Imported);
1487 Token &Tok)
override {
1496 if (Tok.
isNot(tok::eod))
1497 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1501 if (ModuleName.front().first->getName() != Current) {
1502 PP.
Diag(ModuleName.front().second, diag::err_pp_module_begin_wrong_module)
1503 << ModuleName.front().first << (ModuleName.size() > 1)
1504 << Current.empty() << Current;
1514 PP.
Diag(ModuleName.front().second,
1515 diag::err_pp_module_begin_no_module_map) << Current;
1518 for (
unsigned I = 1; I != ModuleName.size(); ++I) {
1519 auto *NewM = M->
findSubmodule(ModuleName[I].first->getName());
1521 PP.
Diag(ModuleName[I].second, diag::err_pp_module_begin_no_submodule)
1531 PP.
Diag(BeginLoc, diag::note_pp_module_begin_here)
1539 tok::annot_module_begin, M);
1548 Token &Tok)
override {
1552 if (Tok.
isNot(tok::eod))
1553 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1559 PP.
Diag(Loc, diag::err_pp_module_end_without_module_begin);
1568 Token &Tok)
override {
1578 Token &Tok)
override {
1587 if (Tok.
isNot(tok::eod))
1588 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1602 Token &PushMacroTok)
override {
1613 Token &PopMacroTok)
override {
1620 struct PragmaARCCFCodeAuditedHandler :
public PragmaHandler {
1621 PragmaARCCFCodeAuditedHandler() :
PragmaHandler(
"arc_cf_code_audited") {}
1624 Token &NameTok)
override {
1633 if (BeginEnd && BeginEnd->
isStr(
"begin")) {
1635 }
else if (BeginEnd && BeginEnd->
isStr(
"end")) {
1644 if (Tok.
isNot(tok::eod))
1645 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1656 PP.
Diag(Loc, diag::err_pp_double_begin_of_arc_cf_code_audited);
1657 PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1663 PP.
Diag(Loc, diag::err_pp_unmatched_end_of_arc_cf_code_audited);
1676 PragmaAssumeNonNullHandler() :
PragmaHandler(
"assume_nonnull") {}
1679 Token &NameTok)
override {
1688 if (BeginEnd && BeginEnd->
isStr(
"begin")) {
1690 }
else if (BeginEnd && BeginEnd->
isStr(
"end")) {
1699 if (Tok.
isNot(tok::eod))
1700 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1712 PP.
Diag(Loc, diag::err_pp_double_begin_of_assume_nonnull);
1713 PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1721 PP.
Diag(Loc, diag::err_pp_unmatched_end_of_assume_nonnull);
1745 PragmaRegionHandler(
const char *pragma) :
PragmaHandler(pragma) {}
1748 Token &NameTok)
override {
1760 void Preprocessor::RegisterBuiltinPragmas() {
1761 AddPragmaHandler(
new PragmaOnceHandler());
1762 AddPragmaHandler(
new PragmaMarkHandler());
1763 AddPragmaHandler(
new PragmaPushMacroHandler());
1764 AddPragmaHandler(
new PragmaPopMacroHandler());
1768 AddPragmaHandler(
"GCC",
new PragmaPoisonHandler());
1769 AddPragmaHandler(
"GCC",
new PragmaSystemHeaderHandler());
1770 AddPragmaHandler(
"GCC",
new PragmaDependencyHandler());
1771 AddPragmaHandler(
"GCC",
new PragmaDiagnosticHandler(
"GCC"));
1777 AddPragmaHandler(
"clang",
new PragmaPoisonHandler());
1778 AddPragmaHandler(
"clang",
new PragmaSystemHeaderHandler());
1779 AddPragmaHandler(
"clang",
new PragmaDebugHandler());
1780 AddPragmaHandler(
"clang",
new PragmaDependencyHandler());
1781 AddPragmaHandler(
"clang",
new PragmaDiagnosticHandler(
"clang"));
1782 AddPragmaHandler(
"clang",
new PragmaARCCFCodeAuditedHandler());
1783 AddPragmaHandler(
"clang",
new PragmaAssumeNonNullHandler());
1787 AddPragmaHandler(
"clang", ModuleHandler);
1788 ModuleHandler->AddPragma(
new PragmaModuleImportHandler());
1789 ModuleHandler->AddPragma(
new PragmaModuleBeginHandler());
1790 ModuleHandler->AddPragma(
new PragmaModuleEndHandler());
1791 ModuleHandler->AddPragma(
new PragmaModuleBuildHandler());
1792 ModuleHandler->AddPragma(
new PragmaModuleLoadHandler());
1795 AddPragmaHandler(
new PragmaRegionHandler(
"region"));
1796 AddPragmaHandler(
new PragmaRegionHandler(
"endregion"));
1799 if (LangOpts.MicrosoftExt) {
1800 AddPragmaHandler(
new PragmaWarningHandler());
1801 AddPragmaHandler(
new PragmaIncludeAliasHandler());
1805 for (PragmaHandlerRegistry::iterator it = PragmaHandlerRegistry::begin(),
1806 ie = PragmaHandlerRegistry::end();
1808 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.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
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 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.
void CheckEndOfDirective(const char *Directive, bool EnableMacros=false)
Ensure that the next token is a tok::eod token.
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...
bool LexOnOffSwitch(tok::OnOffSwitch &OOS)
Lex an on-off-switch (C99 6.10.6p2) and verify that it is followed by EOD.
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.
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 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
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.
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.
bool isPreprocessedOutput() const
Returns true if the preprocessor is responsible for generating output, false if it is producing token...
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
LLVM_DUMP_METHOD void dump() const
void startToken()
Reset all flags to cleared.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.