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(
"llvm_fatal_error")) {
1057 llvm::report_fatal_error(
"#pragma clang __debug llvm_fatal_error");
1058 }
else if (II->
isStr(
"llvm_unreachable")) {
1059 llvm_unreachable(
"#pragma clang __debug llvm_unreachable");
1060 }
else if (II->
isStr(
"macro")) {
1067 PP.
Diag(MacroName, diag::warn_pragma_debug_missing_argument)
1069 }
else if (II->
isStr(
"overflow_stack")) {
1070 DebugOverflowStack();
1071 }
else if (II->
isStr(
"handle_crash")) {
1072 llvm::CrashRecoveryContext *CRC =llvm::CrashRecoveryContext::GetCurrent();
1075 }
else if (II->
isStr(
"captured")) {
1078 PP.
Diag(Tok, diag::warn_pragma_debug_unexpected_command)
1095 if (Tok.
isNot(tok::eod)) {
1096 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol)
1097 <<
"pragma clang __debug captured";
1104 Toks[0].startToken();
1105 Toks[0].setKind(tok::annot_pragma_captured);
1106 Toks[0].setLocation(NameLoc);
1108 PP.EnterTokenStream(Toks,
true);
1113 #pragma warning(disable : 4717) 1115 static void DebugOverflowStack(
void (*
P)() =
nullptr) {
1116 void (*
volatile Self)(void(*
P)()) = DebugOverflowStack;
1117 Self(
reinterpret_cast<void(*)()
>(Self));
1120 #pragma warning(default : 4717) 1127 const char *Namespace;
1130 explicit PragmaDiagnosticHandler(
const char *NS)
1134 Token &DiagToken)
override {
1138 if (Tok.
isNot(tok::identifier)) {
1139 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1145 if (II->
isStr(
"pop")) {
1147 PP.
Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
1151 }
else if (II->
isStr(
"push")) {
1166 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1173 std::string WarningName;
1178 if (Tok.
isNot(tok::eod)) {
1179 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_diagnostic_invalid_token);
1183 if (WarningName.size() < 3 || WarningName[0] !=
'-' ||
1184 (WarningName[1] !=
'W' && WarningName[1] !=
'R')) {
1185 PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_invalid_option);
1191 StringRef Group = StringRef(WarningName).substr(2);
1192 bool unknownDiag =
false;
1193 if (Group ==
"everything") {
1202 PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_unknown_warning)
1216 Token &Tok)
override {
1225 if (Tok.
isNot(tok::l_paren)) {
1226 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
"(";
1233 if (II && II->
isStr(
"push")) {
1237 if (Tok.
is(tok::comma)) {
1240 if (Tok.
is(tok::numeric_constant) &&
1243 if (Level < 0 || Level > 4) {
1244 PP.
Diag(Tok, diag::warn_pragma_warning_push_level);
1250 }
else if (II && II->
isStr(
"pop")) {
1260 if (!II && !Tok.
is(tok::numeric_constant)) {
1261 PP.
Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1266 bool SpecifierValid;
1271 SpecifierValid = llvm::StringSwitch<bool>(
Specifier)
1272 .Cases(
"default",
"disable",
"error",
"once",
1284 SpecifierValid = (Value >= 1) && (Value <= 4);
1286 SpecifierValid =
false;
1290 if (!SpecifierValid) {
1291 PP.
Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1294 if (Tok.
isNot(tok::colon)) {
1295 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
":";
1302 while (Tok.
is(tok::numeric_constant)) {
1306 PP.
Diag(Tok, diag::warn_pragma_warning_expected_number);
1309 Ids.push_back(
int(Value));
1315 if (Tok.
isNot(tok::semi))
1321 if (Tok.
isNot(tok::r_paren)) {
1322 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
")";
1327 if (Tok.
isNot(tok::eod))
1328 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma warning";
1334 PragmaIncludeAliasHandler() :
PragmaHandler(
"include_alias") {}
1337 Token &IncludeAliasTok)
override {
1358 const StringRef Namespace;
1361 bool PragmaNameOnly =
false) {
1364 return PragmaNameOnly ?
"message" :
"pragma message";
1366 return PragmaNameOnly ?
"warning" :
"pragma warning";
1368 return PragmaNameOnly ?
"error" :
"pragma error";
1370 llvm_unreachable(
"Unknown PragmaMessageKind!");
1375 StringRef Namespace = StringRef())
1377 Namespace(Namespace) {}
1380 Token &Tok)
override {
1383 bool ExpectClosingParen =
false;
1387 ExpectClosingParen =
true;
1391 case tok::string_literal:
1395 PP.
Diag(MessageLoc, diag::err_pragma_message_malformed) <<
Kind;
1399 std::string MessageString;
1404 if (ExpectClosingParen) {
1405 if (Tok.
isNot(tok::r_paren)) {
1406 PP.
Diag(Tok.
getLocation(), diag::err_pragma_message_malformed) << Kind;
1412 if (Tok.
isNot(tok::eod)) {
1413 PP.
Diag(Tok.
getLocation(), diag::err_pragma_message_malformed) << Kind;
1419 ? diag::err_pragma_message
1420 : diag::warn_pragma_message) << MessageString;
1424 Callbacks->PragmaMessage(MessageLoc, Namespace, Kind, MessageString);
1436 Token &Tok)
override {
1445 if (Tok.
isNot(tok::eod))
1446 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1457 tok::annot_module_include, Imported);
1459 CB->moduleImport(ImportLoc, ModuleName, Imported);
1473 Token &Tok)
override {
1482 if (Tok.
isNot(tok::eod))
1483 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1487 if (ModuleName.front().first->getName() != Current) {
1488 PP.
Diag(ModuleName.front().second, diag::err_pp_module_begin_wrong_module)
1489 << ModuleName.front().first << (ModuleName.size() > 1)
1490 << Current.empty() << Current;
1500 PP.
Diag(ModuleName.front().second,
1501 diag::err_pp_module_begin_no_module_map) << Current;
1504 for (
unsigned I = 1; I != ModuleName.size(); ++I) {
1505 auto *NewM = M->
findSubmodule(ModuleName[I].first->getName());
1507 PP.
Diag(ModuleName[I].second, diag::err_pp_module_begin_no_submodule)
1517 PP.
Diag(BeginLoc, diag::note_pp_module_begin_here)
1525 tok::annot_module_begin, M);
1534 Token &Tok)
override {
1538 if (Tok.
isNot(tok::eod))
1539 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1545 PP.
Diag(Loc, diag::err_pp_module_end_without_module_begin);
1554 Token &Tok)
override {
1564 Token &Tok)
override {
1573 if (Tok.
isNot(tok::eod))
1574 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1588 Token &PushMacroTok)
override {
1599 Token &PopMacroTok)
override {
1607 struct PragmaSTDC_FENV_ACCESSHandler :
public PragmaHandler {
1608 PragmaSTDC_FENV_ACCESSHandler() :
PragmaHandler(
"FENV_ACCESS") {}
1611 Token &Tok)
override {
1616 PP.
Diag(Tok, diag::warn_stdc_fenv_access_not_supported);
1621 struct PragmaSTDC_CX_LIMITED_RANGEHandler :
public PragmaHandler {
1622 PragmaSTDC_CX_LIMITED_RANGEHandler() :
PragmaHandler(
"CX_LIMITED_RANGE") {}
1625 Token &Tok)
override {
1633 PragmaSTDC_UnknownHandler() =
default;
1636 Token &UnknownTok)
override {
1638 PP.
Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
1644 struct PragmaARCCFCodeAuditedHandler :
public PragmaHandler {
1645 PragmaARCCFCodeAuditedHandler() :
PragmaHandler(
"arc_cf_code_audited") {}
1648 Token &NameTok)
override {
1657 if (BeginEnd && BeginEnd->
isStr(
"begin")) {
1659 }
else if (BeginEnd && BeginEnd->
isStr(
"end")) {
1668 if (Tok.
isNot(tok::eod))
1669 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1680 PP.
Diag(Loc, diag::err_pp_double_begin_of_arc_cf_code_audited);
1681 PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1687 PP.
Diag(Loc, diag::err_pp_unmatched_end_of_arc_cf_code_audited);
1700 PragmaAssumeNonNullHandler() :
PragmaHandler(
"assume_nonnull") {}
1703 Token &NameTok)
override {
1712 if (BeginEnd && BeginEnd->
isStr(
"begin")) {
1714 }
else if (BeginEnd && BeginEnd->
isStr(
"end")) {
1723 if (Tok.
isNot(tok::eod))
1724 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1736 PP.
Diag(Loc, diag::err_pp_double_begin_of_assume_nonnull);
1737 PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1745 PP.
Diag(Loc, diag::err_pp_unmatched_end_of_assume_nonnull);
1769 PragmaRegionHandler(
const char *pragma) :
PragmaHandler(pragma) {}
1772 Token &NameTok)
override {
1784 void Preprocessor::RegisterBuiltinPragmas() {
1785 AddPragmaHandler(
new PragmaOnceHandler());
1786 AddPragmaHandler(
new PragmaMarkHandler());
1787 AddPragmaHandler(
new PragmaPushMacroHandler());
1788 AddPragmaHandler(
new PragmaPopMacroHandler());
1792 AddPragmaHandler(
"GCC",
new PragmaPoisonHandler());
1793 AddPragmaHandler(
"GCC",
new PragmaSystemHeaderHandler());
1794 AddPragmaHandler(
"GCC",
new PragmaDependencyHandler());
1795 AddPragmaHandler(
"GCC",
new PragmaDiagnosticHandler(
"GCC"));
1801 AddPragmaHandler(
"clang",
new PragmaPoisonHandler());
1802 AddPragmaHandler(
"clang",
new PragmaSystemHeaderHandler());
1803 AddPragmaHandler(
"clang",
new PragmaDebugHandler());
1804 AddPragmaHandler(
"clang",
new PragmaDependencyHandler());
1805 AddPragmaHandler(
"clang",
new PragmaDiagnosticHandler(
"clang"));
1806 AddPragmaHandler(
"clang",
new PragmaARCCFCodeAuditedHandler());
1807 AddPragmaHandler(
"clang",
new PragmaAssumeNonNullHandler());
1811 AddPragmaHandler(
"clang", ModuleHandler);
1812 ModuleHandler->AddPragma(
new PragmaModuleImportHandler());
1813 ModuleHandler->AddPragma(
new PragmaModuleBeginHandler());
1814 ModuleHandler->AddPragma(
new PragmaModuleEndHandler());
1815 ModuleHandler->AddPragma(
new PragmaModuleBuildHandler());
1816 ModuleHandler->AddPragma(
new PragmaModuleLoadHandler());
1818 AddPragmaHandler(
"STDC",
new PragmaSTDC_FENV_ACCESSHandler());
1819 AddPragmaHandler(
"STDC",
new PragmaSTDC_CX_LIMITED_RANGEHandler());
1820 AddPragmaHandler(
"STDC",
new PragmaSTDC_UnknownHandler());
1823 if (LangOpts.MicrosoftExt) {
1824 AddPragmaHandler(
new PragmaWarningHandler());
1825 AddPragmaHandler(
new PragmaIncludeAliasHandler());
1826 AddPragmaHandler(
new PragmaRegionHandler(
"region"));
1827 AddPragmaHandler(
new PragmaRegionHandler(
"endregion"));
1831 for (PragmaHandlerRegistry::iterator it = PragmaHandlerRegistry::begin(),
1832 ie = PragmaHandlerRegistry::end();
1834 AddPragmaHandler(it->instantiate().release());
1846 if (
PragmaHandler *NS = PragmaHandlers->FindHandler(
"STDC")) {
1851 assert(STDCNamespace &&
1852 "Invalid namespace, registered as a regular pragma handler!");
1854 RemovePragmaHandler(
"STDC", Existing);
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
Accessors for preprocessor callbacks.
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.
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...
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.
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.
void startToken()
Reset all flags to cleared.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.