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/Compiler.h" 44 #include "llvm/Support/ErrorHandling.h" 54 using namespace clang;
74 llvm::DeleteContainerSeconds(Handlers);
82 bool IgnoreNull)
const {
85 return IgnoreNull ? nullptr : Handlers.lookup(StringRef());
89 assert(!Handlers.lookup(Handler->
getName()) &&
90 "A handler with this name is already registered in this namespace");
91 Handlers[Handler->
getName()] = Handler;
95 assert(Handlers.lookup(Handler->
getName()) &&
96 "Handler not registered in this namespace");
97 Handlers.erase(Handler->
getName());
112 PP.
Diag(Tok, diag::warn_pragma_ignored);
128 struct TokenCollector {
136 Tokens.push_back(Tok);
141 assert(Collect &&
"did not collect tokens");
142 assert(!Tokens.empty() &&
"collected unexpected number of tokens");
145 auto Toks = std::make_unique<Token[]>(Tokens.size());
146 std::copy(Tokens.begin() + 1, Tokens.end(), Toks.get());
147 Toks[Tokens.size() - 1] =
Tok;
148 Self.EnterTokenStream(std::move(Toks), Tokens.size(),
153 Tok = *Tokens.begin();
162 Callbacks->PragmaDirective(Introducer.
Loc, Introducer.
Kind);
171 PragmaHandlers->HandlePragma(*
this, Introducer, Tok);
174 if ((CurTokenLexer && CurTokenLexer->isParsingPreprocessorDirective())
175 || (CurPPLexer && CurPPLexer->ParsingPreprocessorDirective))
176 DiscardUntilEndOfDirective();
182 void Preprocessor::Handle_Pragma(
Token &
Tok) {
203 TokenCollector Toks = {*
this, InMacroArgPreExpansion, {}, Tok};
210 if (Tok.
isNot(tok::l_paren)) {
211 Diag(PragmaLoc, diag::err__Pragma_malformed);
218 Diag(PragmaLoc, diag::err__Pragma_malformed);
222 while (Tok.
isNot(tok::r_paren) &&
226 if (Tok.
is(tok::r_paren))
232 Diag(Tok, diag::err_invalid_string_udl);
235 if (Tok.
is(tok::r_paren))
245 if (Tok.
isNot(tok::r_paren)) {
246 Diag(PragmaLoc, diag::err__Pragma_malformed);
251 if (InMacroArgPreExpansion) {
257 std::string StrVal = getSpelling(StrTok);
264 if (StrVal[0] ==
'L' || StrVal[0] ==
'U' ||
265 (StrVal[0] ==
'u' && StrVal[1] !=
'8'))
266 StrVal.erase(StrVal.begin());
267 else if (StrVal[0] ==
'u')
268 StrVal.erase(StrVal.begin(), StrVal.begin() + 2);
270 if (StrVal[0] ==
'R') {
273 assert(StrVal[1] ==
'"' && StrVal[StrVal.size() - 1] ==
'"' &&
274 "Invalid raw string token!");
277 unsigned NumDChars = 0;
278 while (StrVal[2 + NumDChars] !=
'(') {
279 assert(NumDChars < (StrVal.size() - 5) / 2 &&
280 "Invalid raw string token!");
283 assert(StrVal[StrVal.size() - 2 - NumDChars] ==
')');
287 StrVal.erase(0, 2 + NumDChars);
288 StrVal.erase(StrVal.size() - 1 - NumDChars);
290 assert(StrVal[0] ==
'"' && StrVal[StrVal.size()-1] ==
'"' &&
291 "Invalid string token!");
294 unsigned ResultPos = 1;
295 for (
size_t i = 1, e = StrVal.size() - 1; i != e; ++i) {
297 if (StrVal[i] ==
'\\' && i + 1 < e &&
298 (StrVal[i + 1] ==
'\\' || StrVal[i + 1] ==
'"'))
300 StrVal[ResultPos++] = StrVal[i];
302 StrVal.erase(StrVal.begin() + ResultPos, StrVal.end() - 1);
310 StrVal[StrVal.size()-1] =
'\n';
316 CreateString(StrVal, TmpTok);
322 StrVal.size(), *
this);
324 EnterSourceFileWithLexer(TL,
nullptr);
335 void Preprocessor::HandleMicrosoft__pragma(
Token &Tok) {
338 TokenCollector Toks = {*
this, InMacroArgPreExpansion, {}, Tok};
345 if (Tok.
isNot(tok::l_paren)) {
346 Diag(PragmaLoc, diag::err__Pragma_malformed);
355 PragmaToks.push_back(Tok);
356 if (Tok.
is(tok::l_paren))
358 else if (Tok.
is(tok::r_paren) && NumParens-- == 0)
364 Diag(PragmaLoc, diag::err_unterminated___pragma);
369 if (InMacroArgPreExpansion) {
377 PragmaToks.back().setKind(tok::eod);
379 Token *TokArray =
new Token[PragmaToks.size()];
380 std::copy(PragmaToks.begin(), PragmaToks.end(), TokArray);
383 EnterTokenStream(TokArray, PragmaToks.size(),
true,
true,
400 Diag(OnceTok, diag::pp_pragma_once_in_main_file);
406 HeaderInfo.MarkFileIncludeOnce(getCurrentFileLexer()->getFileEntry());
410 assert(CurPPLexer &&
"No current lexer?");
411 CurLexer->ReadToEndOfLine();
424 if (CurPPLexer) CurPPLexer->LexingRawMode =
true;
425 LexUnexpandedToken(Tok);
426 if (CurPPLexer) CurPPLexer->LexingRawMode =
false;
429 if (Tok.
is(tok::eod))
return;
432 if (Tok.
isNot(tok::raw_identifier)) {
433 Diag(Tok, diag::err_pp_invalid_poison);
446 Diag(Tok, diag::pp_poisoning_existing_macro);
458 if (isInPrimaryFile()) {
459 Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
467 HeaderInfo.MarkFileSystemHeader(TheLexer->
getFileEntry());
473 unsigned FilenameID = SourceMgr.getLineTableFilenameID(PLoc.
getFilename());
484 FilenameID,
false,
false,
491 if (LexHeaderName(FilenameTok,
false))
495 if (FilenameTok.
isNot(tok::header_name)) {
502 bool Invalid =
false;
503 StringRef
Filename = getSpelling(FilenameTok, FilenameBuffer, &Invalid);
511 if (Filename.empty())
518 nullptr, CurDir,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr);
520 if (!SuppressIncludeNotFoundError)
521 Diag(FilenameTok, diag::err_pp_file_not_found) <<
Filename;
525 const FileEntry *CurFile = getCurrentFileLexer()->getFileEntry();
532 while (DependencyTok.
isNot(tok::eod)) {
533 Message += getSpelling(DependencyTok) +
" ";
538 if (!Message.empty())
539 Message.erase(Message.end()-1);
540 Diag(FilenameTok, diag::pp_out_of_date_dependency) << Message;
552 if (Tok.
isNot(tok::l_paren)) {
553 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
554 << getSpelling(PragmaTok);
560 if (Tok.
isNot(tok::string_literal)) {
561 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
562 << getSpelling(PragmaTok);
567 Diag(Tok, diag::err_invalid_string_udl);
572 std::string StrVal = getSpelling(Tok);
576 if (Tok.
isNot(tok::r_paren)) {
577 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
578 << getSpelling(PragmaTok);
582 assert(StrVal[0] ==
'"' && StrVal[StrVal.size()-1] ==
'"' &&
583 "Invalid string token!");
588 MacroTok.setKind(tok::raw_identifier);
589 CreateString(StringRef(&StrVal[1], StrVal.size() - 2), MacroTok);
592 return LookUpIdentifierInfo(MacroTok);
603 IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PushMacroTok);
604 if (!IdentInfo)
return;
615 PragmaPushMacroInfo[IdentInfo].push_back(MI);
628 IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PopMacroTok);
629 if (!IdentInfo)
return;
632 llvm::DenseMap<IdentifierInfo *, std::vector<MacroInfo *>>::iterator iter =
633 PragmaPushMacroInfo.find(IdentInfo);
634 if (iter != PragmaPushMacroInfo.end()) {
636 if (
MacroInfo *MI = getMacroInfo(IdentInfo)) {
637 if (MI->isWarnIfUnused())
638 WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
639 appendMacroDirective(IdentInfo, AllocateUndefMacroDirective(MessageLoc));
643 MacroInfo *MacroToReInstall = iter->second.back();
645 if (MacroToReInstall)
647 appendDefMacroDirective(IdentInfo, MacroToReInstall, MessageLoc);
650 iter->second.pop_back();
651 if (iter->second.empty())
652 PragmaPushMacroInfo.erase(iter);
654 Diag(MessageLoc, diag::warn_pragma_pop_macro_no_push)
667 if (Tok.
isNot(tok::l_paren)) {
668 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
"(";
673 Token SourceFilenameTok;
674 if (LexHeaderName(SourceFilenameTok))
677 StringRef SourceFileName;
679 if (SourceFilenameTok.
is(tok::header_name)) {
680 SourceFileName = getSpelling(SourceFilenameTok, FileNameBuffer);
682 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
685 FileNameBuffer.clear();
689 if (Tok.
isNot(tok::comma)) {
690 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
",";
694 Token ReplaceFilenameTok;
695 if (LexHeaderName(ReplaceFilenameTok))
698 StringRef ReplaceFileName;
699 if (ReplaceFilenameTok.
is(tok::header_name)) {
700 ReplaceFileName = getSpelling(ReplaceFilenameTok, FileNameBuffer);
702 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
708 if (Tok.
isNot(tok::r_paren)) {
709 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
")";
715 StringRef OriginalSource = SourceFileName;
717 bool SourceIsAngled =
718 GetIncludeFilenameSpelling(SourceFilenameTok.
getLocation(),
720 bool ReplaceIsAngled =
721 GetIncludeFilenameSpelling(ReplaceFilenameTok.
getLocation(),
723 if (!SourceFileName.empty() && !ReplaceFileName.empty() &&
724 (SourceIsAngled != ReplaceIsAngled)) {
727 DiagID = diag::warn_pragma_include_alias_mismatch_angle;
729 DiagID = diag::warn_pragma_include_alias_mismatch_quote;
739 getHeaderSearchInfo().AddIncludeAlias(OriginalSource, ReplaceFileName);
746 std::pair<IdentifierInfo *, SourceLocation> &ModuleNameComponent,
753 ModuleNameComponent = std::make_pair(
756 ModuleNameComponent =
759 PP.
Diag(Tok.
getLocation(), diag::err_pp_expected_module_name) << First;
770 std::pair<IdentifierInfo*, SourceLocation> NameComponent;
773 ModuleName.push_back(NameComponent);
776 if (Tok.
isNot(tok::period))
784 std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc;
789 LexUnexpandedToken(Tok);
790 if (Tok.
isNot(tok::eod)) {
791 Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
792 DiscardUntilEndOfDirective();
795 CurLexer->LexingRawMode =
true;
797 auto TryConsumeIdentifier = [&](StringRef Ident) ->
bool {
798 if (Tok.
getKind() != tok::raw_identifier ||
806 const char *Start = CurLexer->getBufferLocation();
807 const char *
End =
nullptr;
808 unsigned NestingLevel = 1;
810 End = CurLexer->getBufferLocation();
814 Diag(Loc, diag::err_pp_module_build_missing_end);
825 CurLexer->ParsingPreprocessorDirective =
true;
827 if (TryConsumeIdentifier(
"pragma") && TryConsumeIdentifier(
"clang") &&
828 TryConsumeIdentifier(
"module")) {
829 if (TryConsumeIdentifier(
"build"))
832 else if (TryConsumeIdentifier(
"endbuild")) {
834 if (--NestingLevel == 0)
843 CurLexer->LexingRawMode =
false;
846 assert(CurLexer->getBuffer().begin() <= Start &&
847 Start <= CurLexer->getBuffer().end() &&
848 CurLexer->getBuffer().begin() <= End &&
849 End <= CurLexer->getBuffer().end() &&
850 "module source range not contained within same file buffer");
851 TheModuleLoader.createModuleFromSource(Loc, ModuleName->
getName(),
852 StringRef(Start, End - Start));
857 if (Tok.
is(tok::l_paren)) {
860 std::string FileName;
861 if (!LexStringLiteral(Tok, FileName,
"pragma hdrstop",
false))
864 if (Tok.
isNot(tok::r_paren)) {
865 Diag(Tok, diag::err_expected) << tok::r_paren;
870 if (Tok.
isNot(tok::eod))
874 if (creatingPCHWithPragmaHdrStop() &&
876 assert(CurLexer &&
"no lexer for #pragma hdrstop processing");
879 CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd,
tok::eof);
880 CurLexer->cutOffLexing();
882 if (usingPCHWithPragmaHdrStop())
883 SkippingUntilPragmaHdrStop =
false;
894 if (!Namespace.empty()) {
898 if (
PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace)) {
900 assert(InsertNS !=
nullptr &&
"Cannot have a pragma namespace and pragma" 901 " handler with the same name!");
906 PragmaHandlers->AddPragma(InsertNS);
912 "Pragma handler already exists for this identifier!");
925 if (!Namespace.empty()) {
926 PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace);
927 assert(Existing &&
"Namespace containing handler does not exist!");
930 assert(NS &&
"Invalid namespace, registered as a regular pragma handler!");
936 if (NS != PragmaHandlers.get() && NS->
IsEmpty()) {
937 PragmaHandlers->RemovePragmaHandler(NS);
944 LexUnexpandedToken(Tok);
946 if (Tok.
isNot(tok::identifier)) {
947 Diag(Tok, diag::ext_on_off_switch_syntax);
953 else if (II->
isStr(
"OFF"))
955 else if (II->
isStr(
"DEFAULT"))
958 Diag(Tok, diag::ext_on_off_switch_syntax);
963 LexUnexpandedToken(Tok);
964 if (Tok.
isNot(tok::eod))
965 Diag(Tok, diag::ext_pragma_syntax_eod);
976 Token &OnceTok)
override {
988 Token &MarkTok)
override {
998 Token &PoisonTok)
override {
1006 PragmaSystemHeaderHandler() :
PragmaHandler(
"system_header") {}
1009 Token &SHToken)
override {
1019 Token &DepToken)
override {
1028 Token &DebugToken)
override {
1031 if (Tok.
isNot(tok::identifier)) {
1032 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1037 if (II->
isStr(
"assert")) {
1039 llvm_unreachable(
"This is an assertion!");
1040 }
else if (II->
isStr(
"crash")) {
1043 }
else if (II->
isStr(
"parser_crash")) {
1047 Crasher.
setKind(tok::annot_pragma_parser_crash);
1051 }
else if (II->
isStr(
"dump")) {
1057 DumpAnnot.
setKind(tok::annot_pragma_dump);
1064 PP.
Diag(Identifier, diag::warn_pragma_debug_missing_argument)
1067 }
else if (II->
isStr(
"diag_mapping")) {
1070 if (DiagName.
is(tok::eod))
1072 else if (DiagName.
is(tok::string_literal) && !DiagName.
hasUDSuffix()) {
1078 PP.
Diag(DiagName, diag::warn_pragma_debug_missing_argument)
1081 }
else if (II->
isStr(
"llvm_fatal_error")) {
1083 llvm::report_fatal_error(
"#pragma clang __debug llvm_fatal_error");
1084 }
else if (II->
isStr(
"llvm_unreachable")) {
1086 llvm_unreachable(
"#pragma clang __debug llvm_unreachable");
1087 }
else if (II->
isStr(
"macro")) {
1094 PP.
Diag(MacroName, diag::warn_pragma_debug_missing_argument)
1096 }
else if (II->
isStr(
"module_map")) {
1103 for (
auto IIAndLoc : ModuleName) {
1106 PP.
Diag(IIAndLoc.second, diag::warn_pragma_debug_unknown_module)
1112 }
else if (II->
isStr(
"overflow_stack")) {
1114 DebugOverflowStack();
1115 }
else if (II->
isStr(
"captured")) {
1118 PP.
Diag(Tok, diag::warn_pragma_debug_unexpected_command)
1131 if (Tok.
isNot(tok::eod)) {
1132 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol)
1133 <<
"pragma clang __debug captured";
1140 Toks[0].startToken();
1141 Toks[0].setKind(tok::annot_pragma_captured);
1142 Toks[0].setLocation(NameLoc);
1144 PP.EnterTokenStream(Toks,
true,
1150 #pragma warning(disable : 4717) 1152 static void DebugOverflowStack(
void (*
P)() =
nullptr) {
1153 void (*
volatile Self)(void(*
P)()) = DebugOverflowStack;
1154 Self(
reinterpret_cast<void(*)()
>(Self));
1157 #pragma warning(default : 4717) 1164 const char *Namespace;
1167 explicit PragmaDiagnosticHandler(
const char *NS)
1171 Token &DiagToken)
override {
1175 if (Tok.
isNot(tok::identifier)) {
1176 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1182 if (II->
isStr(
"pop")) {
1184 PP.
Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
1188 }
else if (II->
isStr(
"push")) {
1203 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1210 std::string WarningName;
1215 if (Tok.
isNot(tok::eod)) {
1216 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_diagnostic_invalid_token);
1220 if (WarningName.size() < 3 || WarningName[0] !=
'-' ||
1221 (WarningName[1] !=
'W' && WarningName[1] !=
'R')) {
1222 PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_invalid_option);
1228 StringRef Group = StringRef(WarningName).substr(2);
1229 bool unknownDiag =
false;
1230 if (Group ==
"everything") {
1239 PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_unknown_warning)
1250 Token &DepToken)
override {
1262 Token &Tok)
override {
1271 if (Tok.
isNot(tok::l_paren)) {
1272 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
"(";
1279 if (II && II->
isStr(
"push")) {
1283 if (Tok.
is(tok::comma)) {
1286 if (Tok.
is(tok::numeric_constant) &&
1289 if (Level < 0 || Level > 4) {
1290 PP.
Diag(Tok, diag::warn_pragma_warning_push_level);
1296 }
else if (II && II->
isStr(
"pop")) {
1306 if (!II && !Tok.
is(tok::numeric_constant)) {
1307 PP.
Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1312 bool SpecifierValid;
1317 SpecifierValid = llvm::StringSwitch<bool>(
Specifier)
1318 .Cases(
"default",
"disable",
"error",
"once",
1330 SpecifierValid = (Value >= 1) && (Value <= 4);
1332 SpecifierValid =
false;
1336 if (!SpecifierValid) {
1337 PP.
Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1340 if (Tok.
isNot(tok::colon)) {
1341 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
":";
1348 while (Tok.
is(tok::numeric_constant)) {
1352 PP.
Diag(Tok, diag::warn_pragma_warning_expected_number);
1355 Ids.push_back(
int(Value));
1361 if (Tok.
isNot(tok::semi))
1367 if (Tok.
isNot(tok::r_paren)) {
1368 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
")";
1373 if (Tok.
isNot(tok::eod))
1374 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma warning";
1382 PragmaExecCharsetHandler() :
PragmaHandler(
"execution_character_set") {}
1385 Token &Tok)
override {
1393 if (Tok.
isNot(tok::l_paren)) {
1394 PP.
Diag(Tok, diag::warn_pragma_exec_charset_expected) <<
"(";
1401 if (II && II->
isStr(
"push")) {
1404 if (Tok.
is(tok::comma)) {
1407 std::string ExecCharset;
1409 "pragma execution_character_set",
1414 if (ExecCharset !=
"UTF-8" && ExecCharset !=
"utf-8") {
1415 PP.
Diag(Tok, diag::warn_pragma_exec_charset_push_invalid) << ExecCharset;
1421 }
else if (II && II->
isStr(
"pop")) {
1427 PP.
Diag(Tok, diag::warn_pragma_exec_charset_spec_invalid);
1431 if (Tok.
isNot(tok::r_paren)) {
1432 PP.
Diag(Tok, diag::warn_pragma_exec_charset_expected) <<
")";
1437 if (Tok.
isNot(tok::eod))
1438 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma execution_character_set";
1444 PragmaIncludeAliasHandler() :
PragmaHandler(
"include_alias") {}
1447 Token &IncludeAliasTok)
override {
1468 const StringRef Namespace;
1471 bool PragmaNameOnly =
false) {
1474 return PragmaNameOnly ?
"message" :
"pragma message";
1476 return PragmaNameOnly ?
"warning" :
"pragma warning";
1478 return PragmaNameOnly ?
"error" :
"pragma error";
1480 llvm_unreachable(
"Unknown PragmaMessageKind!");
1485 StringRef Namespace = StringRef())
1487 Namespace(Namespace) {}
1490 Token &Tok)
override {
1493 bool ExpectClosingParen =
false;
1497 ExpectClosingParen =
true;
1501 case tok::string_literal:
1505 PP.
Diag(MessageLoc, diag::err_pragma_message_malformed) <<
Kind;
1509 std::string MessageString;
1514 if (ExpectClosingParen) {
1515 if (Tok.
isNot(tok::r_paren)) {
1516 PP.
Diag(Tok.
getLocation(), diag::err_pragma_message_malformed) << Kind;
1522 if (Tok.
isNot(tok::eod)) {
1523 PP.
Diag(Tok.
getLocation(), diag::err_pragma_message_malformed) << Kind;
1529 ? diag::err_pragma_message
1530 : diag::warn_pragma_message) << MessageString;
1534 Callbacks->PragmaMessage(MessageLoc, Namespace, Kind, MessageString);
1546 Token &Tok)
override {
1555 if (Tok.
isNot(tok::eod))
1556 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1567 tok::annot_module_include, Imported);
1569 CB->moduleImport(ImportLoc, ModuleName, Imported);
1583 Token &Tok)
override {
1592 if (Tok.
isNot(tok::eod))
1593 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1597 if (ModuleName.front().first->getName() != Current) {
1598 PP.
Diag(ModuleName.front().second, diag::err_pp_module_begin_wrong_module)
1599 << ModuleName.front().first << (ModuleName.size() > 1)
1600 << Current.empty() << Current;
1607 Module *M = HSI.lookupModule(Current);
1609 PP.
Diag(ModuleName.front().second,
1610 diag::err_pp_module_begin_no_module_map) << Current;
1613 for (
unsigned I = 1; I != ModuleName.size(); ++I) {
1616 PP.
Diag(ModuleName[I].second, diag::err_pp_module_begin_no_submodule)
1626 PP.
Diag(BeginLoc, diag::note_pp_module_begin_here)
1634 tok::annot_module_begin, M);
1643 Token &Tok)
override {
1647 if (Tok.
isNot(tok::eod))
1648 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1654 PP.
Diag(Loc, diag::err_pp_module_end_without_module_begin);
1663 Token &Tok)
override {
1673 Token &Tok)
override {
1682 if (Tok.
isNot(tok::eod))
1683 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1697 Token &PushMacroTok)
override {
1708 Token &PopMacroTok)
override {
1715 struct PragmaARCCFCodeAuditedHandler :
public PragmaHandler {
1716 PragmaARCCFCodeAuditedHandler() :
PragmaHandler(
"arc_cf_code_audited") {}
1719 Token &NameTok)
override {
1728 if (BeginEnd && BeginEnd->
isStr(
"begin")) {
1730 }
else if (BeginEnd && BeginEnd->
isStr(
"end")) {
1739 if (Tok.
isNot(tok::eod))
1740 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1751 PP.
Diag(Loc, diag::err_pp_double_begin_of_arc_cf_code_audited);
1752 PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1758 PP.
Diag(Loc, diag::err_pp_unmatched_end_of_arc_cf_code_audited);
1771 PragmaAssumeNonNullHandler() :
PragmaHandler(
"assume_nonnull") {}
1774 Token &NameTok)
override {
1783 if (BeginEnd && BeginEnd->
isStr(
"begin")) {
1785 }
else if (BeginEnd && BeginEnd->
isStr(
"end")) {
1794 if (Tok.
isNot(tok::eod))
1795 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1807 PP.
Diag(Loc, diag::err_pp_double_begin_of_assume_nonnull);
1808 PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1816 PP.
Diag(Loc, diag::err_pp_unmatched_end_of_assume_nonnull);
1840 PragmaRegionHandler(
const char *pragma) :
PragmaHandler(pragma) {}
1843 Token &NameTok)
override {
1855 void Preprocessor::RegisterBuiltinPragmas() {
1856 AddPragmaHandler(
new PragmaOnceHandler());
1857 AddPragmaHandler(
new PragmaMarkHandler());
1858 AddPragmaHandler(
new PragmaPushMacroHandler());
1859 AddPragmaHandler(
new PragmaPopMacroHandler());
1863 AddPragmaHandler(
"GCC",
new PragmaPoisonHandler());
1864 AddPragmaHandler(
"GCC",
new PragmaSystemHeaderHandler());
1865 AddPragmaHandler(
"GCC",
new PragmaDependencyHandler());
1866 AddPragmaHandler(
"GCC",
new PragmaDiagnosticHandler(
"GCC"));
1872 AddPragmaHandler(
"clang",
new PragmaPoisonHandler());
1873 AddPragmaHandler(
"clang",
new PragmaSystemHeaderHandler());
1874 AddPragmaHandler(
"clang",
new PragmaDebugHandler());
1875 AddPragmaHandler(
"clang",
new PragmaDependencyHandler());
1876 AddPragmaHandler(
"clang",
new PragmaDiagnosticHandler(
"clang"));
1877 AddPragmaHandler(
"clang",
new PragmaARCCFCodeAuditedHandler());
1878 AddPragmaHandler(
"clang",
new PragmaAssumeNonNullHandler());
1882 AddPragmaHandler(
"clang", ModuleHandler);
1883 ModuleHandler->AddPragma(
new PragmaModuleImportHandler());
1884 ModuleHandler->AddPragma(
new PragmaModuleBeginHandler());
1885 ModuleHandler->AddPragma(
new PragmaModuleEndHandler());
1886 ModuleHandler->AddPragma(
new PragmaModuleBuildHandler());
1887 ModuleHandler->AddPragma(
new PragmaModuleLoadHandler());
1890 AddPragmaHandler(
new PragmaRegionHandler(
"region"));
1891 AddPragmaHandler(
new PragmaRegionHandler(
"endregion"));
1894 if (LangOpts.MicrosoftExt) {
1895 AddPragmaHandler(
new PragmaWarningHandler());
1896 AddPragmaHandler(
new PragmaExecCharsetHandler());
1897 AddPragmaHandler(
new PragmaIncludeAliasHandler());
1898 AddPragmaHandler(
new PragmaHdrstopHandler());
1902 for (PragmaHandlerRegistry::iterator it = PragmaHandlerRegistry::begin(),
1903 ie = PragmaHandlerRegistry::end();
1905 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.
void dumpMacroInfo(const IdentifierInfo *II)
The translation unit is a prefix to a translation unit, and is not complete.
Defines the clang::MacroInfo and clang::MacroDirective classes.
The pragma was introduced via the Microsoft __pragma(token-string).
PragmaIntroducerKind Kind
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 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).
Module * lookupModuleQualified(StringRef Name, Module *Context) const
Retrieve a module with the given name within the given context, using direct (qualified) name lookup...
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
void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, Token &Tok) override
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)
virtual void PragmaExecCharsetPop(SourceLocation Loc)
Callback invoked when a #pragma execution_character_set(pop) directive is read.
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)
__DEVICE__ int max(int __a, int __b)
const LangOptions & getLangOpts() const
Describes a module or submodule.
SourceRange DiscardUntilEndOfDirective()
Read and discard all tokens remaining on the current line until the tok::eod token is found...
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.
virtual void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str)
Callback invoked when a #pragma execution_character_set(push) directive is read.
Defines the Diagnostic-related interfaces.
Present this diagnostic as an error.
void LexUnexpandedToken(Token &Result)
Just like Lex, but disables macro expansion of identifier tokens.
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, Token &FirstToken)=0
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.
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)
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.
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.
#pragma message has been invoked.
Module * findOrInferSubmodule(StringRef Name)
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.
Defines the clang::Module class, which describes a module in the source code.
void EnterToken(const Token &Tok, bool IsReinject)
Enters a token in the token stream to be lexed next.
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.
std::pair< IdentifierInfo *, SourceLocation > getPragmaARCCFCodeAuditedInfo() const
The location of the currently-active #pragma clang arc_cf_code_audited begin.
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).
void setPragmaARCCFCodeAuditedInfo(IdentifierInfo *Ident, SourceLocation Loc)
Set the location of the currently-active #pragma clang arc_cf_code_audited begin. ...
PragmaNamespace - This PragmaHandler subdivides the namespace of pragmas, allowing hierarchical pragm...
bool DisablePragmaDebugCrash
Prevents intended crashes when using #pragma clang __debug. For testing.
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...
void dump() const
Dump the contents of this module to the given output stream.
ModuleLoader & getModuleLoader() const
Retrieve the module loader associated with this preprocessor.
IdentifierInfo * ParsePragmaPushOrPopMacro(Token &Tok)
ParsePragmaPushOrPopMacro - Handle parsing of pragma push_macro/pop_macro.
PreprocessorOptions & getPreprocessorOpts() const
Retrieve the preprocessor options used to initialize this preprocessor.
Defines the PPCallbacks interface.
Defines the clang::TokenKind enum and support functions.
SourceLocation CheckEndOfDirective(const char *DirType, bool EnableMacros=false)
Ensure that the next token is a tok::eod token.
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
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.
Present this diagnostic as a fatal error.
Describes how and where the pragma was introduced.
virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace, diag::Severity mapping, StringRef Str)
Callback invoked when a #pragma gcc diagnostic directive is read.
void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, Token &FirstToken) override
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.