35 #include "llvm/ADT/ArrayRef.h" 36 #include "llvm/ADT/DenseMap.h" 37 #include "llvm/ADT/STLExtras.h" 38 #include "llvm/ADT/SmallString.h" 39 #include "llvm/ADT/SmallVector.h" 40 #include "llvm/ADT/StringSwitch.h" 41 #include "llvm/ADT/StringRef.h" 42 #include "llvm/Support/CrashRecoveryContext.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 Callbacks->PragmaDirective(Introducer.
Loc, Introducer.
Kind);
137 PragmaHandlers->HandlePragma(*
this, Introducer, Tok);
140 if ((CurTokenLexer && CurTokenLexer->isParsingPreprocessorDirective())
141 || (CurPPLexer && CurPPLexer->ParsingPreprocessorDirective))
142 DiscardUntilEndOfDirective();
148 void Preprocessor::Handle_Pragma(
Token &
Tok) {
169 struct TokenCollector {
177 Tokens.push_back(Tok);
182 assert(Collect &&
"did not collect tokens");
183 assert(!Tokens.empty() &&
"collected unexpected number of tokens");
186 auto Toks = llvm::make_unique<Token[]>(Tokens.size());
187 std::copy(Tokens.begin() + 1, Tokens.end(), Toks.get());
188 Toks[Tokens.size() - 1] =
Tok;
189 Self.EnterTokenStream(std::move(Toks), Tokens.size(),
194 Tok = *Tokens.begin();
198 TokenCollector Toks = {*
this, InMacroArgPreExpansion, {}, Tok};
205 if (Tok.
isNot(tok::l_paren)) {
206 Diag(PragmaLoc, diag::err__Pragma_malformed);
213 Diag(PragmaLoc, diag::err__Pragma_malformed);
217 while (Tok.
isNot(tok::r_paren) &&
221 if (Tok.
is(tok::r_paren))
227 Diag(Tok, diag::err_invalid_string_udl);
230 if (Tok.
is(tok::r_paren))
240 if (Tok.
isNot(tok::r_paren)) {
241 Diag(PragmaLoc, diag::err__Pragma_malformed);
246 if (InMacroArgPreExpansion) {
252 std::string StrVal = getSpelling(StrTok);
259 if (StrVal[0] ==
'L' || StrVal[0] ==
'U' ||
260 (StrVal[0] ==
'u' && StrVal[1] !=
'8'))
261 StrVal.erase(StrVal.begin());
262 else if (StrVal[0] ==
'u')
263 StrVal.erase(StrVal.begin(), StrVal.begin() + 2);
265 if (StrVal[0] ==
'R') {
268 assert(StrVal[1] ==
'"' && StrVal[StrVal.size() - 1] ==
'"' &&
269 "Invalid raw string token!");
272 unsigned NumDChars = 0;
273 while (StrVal[2 + NumDChars] !=
'(') {
274 assert(NumDChars < (StrVal.size() - 5) / 2 &&
275 "Invalid raw string token!");
278 assert(StrVal[StrVal.size() - 2 - NumDChars] ==
')');
282 StrVal.erase(0, 2 + NumDChars);
283 StrVal.erase(StrVal.size() - 1 - NumDChars);
285 assert(StrVal[0] ==
'"' && StrVal[StrVal.size()-1] ==
'"' &&
286 "Invalid string token!");
289 unsigned ResultPos = 1;
290 for (
size_t i = 1, e = StrVal.size() - 1;
i != e; ++
i) {
292 if (StrVal[
i] ==
'\\' &&
i + 1 < e &&
293 (StrVal[
i + 1] ==
'\\' || StrVal[
i + 1] ==
'"'))
295 StrVal[ResultPos++] = StrVal[
i];
297 StrVal.erase(StrVal.begin() + ResultPos, StrVal.end() - 1);
305 StrVal[StrVal.size()-1] =
'\n';
311 CreateString(StrVal, TmpTok);
317 StrVal.size(), *
this);
319 EnterSourceFileWithLexer(TL,
nullptr);
330 void Preprocessor::HandleMicrosoft__pragma(
Token &Tok) {
336 if (Tok.
isNot(tok::l_paren)) {
337 Diag(PragmaLoc, diag::err__Pragma_malformed);
346 PragmaToks.push_back(Tok);
347 if (Tok.
is(tok::l_paren))
349 else if (Tok.
is(tok::r_paren) && NumParens-- == 0)
355 Diag(PragmaLoc, diag::err_unterminated___pragma);
362 PragmaToks.back().setKind(tok::eod);
364 Token *TokArray =
new Token[PragmaToks.size()];
365 std::copy(PragmaToks.begin(), PragmaToks.end(), TokArray);
368 EnterTokenStream(TokArray, PragmaToks.size(),
true,
true,
385 Diag(OnceTok, diag::pp_pragma_once_in_main_file);
391 HeaderInfo.MarkFileIncludeOnce(getCurrentFileLexer()->getFileEntry());
395 assert(CurPPLexer &&
"No current lexer?");
396 CurLexer->ReadToEndOfLine();
409 if (CurPPLexer) CurPPLexer->LexingRawMode =
true;
410 LexUnexpandedToken(Tok);
411 if (CurPPLexer) CurPPLexer->LexingRawMode =
false;
414 if (Tok.
is(tok::eod))
return;
417 if (Tok.
isNot(tok::raw_identifier)) {
418 Diag(Tok, diag::err_pp_invalid_poison);
431 Diag(Tok, diag::pp_poisoning_existing_macro);
443 if (isInPrimaryFile()) {
444 Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
452 HeaderInfo.MarkFileSystemHeader(TheLexer->
getFileEntry());
458 unsigned FilenameID = SourceMgr.getLineTableFilenameID(PLoc.
getFilename());
469 FilenameID,
false,
false,
476 if (LexHeaderName(FilenameTok,
false))
480 if (FilenameTok.
isNot(tok::header_name)) {
487 bool Invalid =
false;
488 StringRef
Filename = getSpelling(FilenameTok, FilenameBuffer, &Invalid);
496 if (Filename.empty())
503 nullptr, CurDir,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr);
505 if (!SuppressIncludeNotFoundError)
506 Diag(FilenameTok, diag::err_pp_file_not_found) <<
Filename;
510 const FileEntry *CurFile = getCurrentFileLexer()->getFileEntry();
517 while (DependencyTok.
isNot(tok::eod)) {
518 Message += getSpelling(DependencyTok) +
" ";
523 if (!Message.empty())
524 Message.erase(Message.end()-1);
525 Diag(FilenameTok, diag::pp_out_of_date_dependency) << Message;
537 if (Tok.
isNot(tok::l_paren)) {
538 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
539 << getSpelling(PragmaTok);
545 if (Tok.
isNot(tok::string_literal)) {
546 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
547 << getSpelling(PragmaTok);
552 Diag(Tok, diag::err_invalid_string_udl);
557 std::string StrVal = getSpelling(Tok);
561 if (Tok.
isNot(tok::r_paren)) {
562 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
563 << getSpelling(PragmaTok);
567 assert(StrVal[0] ==
'"' && StrVal[StrVal.size()-1] ==
'"' &&
568 "Invalid string token!");
573 MacroTok.setKind(tok::raw_identifier);
574 CreateString(StringRef(&StrVal[1], StrVal.size() - 2), MacroTok);
577 return LookUpIdentifierInfo(MacroTok);
588 IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PushMacroTok);
589 if (!IdentInfo)
return;
600 PragmaPushMacroInfo[IdentInfo].push_back(MI);
613 IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PopMacroTok);
614 if (!IdentInfo)
return;
617 llvm::DenseMap<IdentifierInfo *, std::vector<MacroInfo *>>::iterator iter =
618 PragmaPushMacroInfo.find(IdentInfo);
619 if (iter != PragmaPushMacroInfo.end()) {
621 if (
MacroInfo *MI = getMacroInfo(IdentInfo)) {
622 if (MI->isWarnIfUnused())
623 WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
624 appendMacroDirective(IdentInfo, AllocateUndefMacroDirective(MessageLoc));
628 MacroInfo *MacroToReInstall = iter->second.back();
630 if (MacroToReInstall)
632 appendDefMacroDirective(IdentInfo, MacroToReInstall, MessageLoc);
635 iter->second.pop_back();
636 if (iter->second.empty())
637 PragmaPushMacroInfo.erase(iter);
639 Diag(MessageLoc, diag::warn_pragma_pop_macro_no_push)
652 if (Tok.
isNot(tok::l_paren)) {
653 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
"(";
658 Token SourceFilenameTok;
659 if (LexHeaderName(SourceFilenameTok))
662 StringRef SourceFileName;
664 if (SourceFilenameTok.
is(tok::header_name)) {
665 SourceFileName = getSpelling(SourceFilenameTok, FileNameBuffer);
667 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
670 FileNameBuffer.clear();
674 if (Tok.
isNot(tok::comma)) {
675 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
",";
679 Token ReplaceFilenameTok;
680 if (LexHeaderName(ReplaceFilenameTok))
683 StringRef ReplaceFileName;
684 if (ReplaceFilenameTok.
is(tok::header_name)) {
685 ReplaceFileName = getSpelling(ReplaceFilenameTok, FileNameBuffer);
687 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
693 if (Tok.
isNot(tok::r_paren)) {
694 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
")";
700 StringRef OriginalSource = SourceFileName;
702 bool SourceIsAngled =
703 GetIncludeFilenameSpelling(SourceFilenameTok.
getLocation(),
705 bool ReplaceIsAngled =
706 GetIncludeFilenameSpelling(ReplaceFilenameTok.
getLocation(),
708 if (!SourceFileName.empty() && !ReplaceFileName.empty() &&
709 (SourceIsAngled != ReplaceIsAngled)) {
712 DiagID = diag::warn_pragma_include_alias_mismatch_angle;
714 DiagID = diag::warn_pragma_include_alias_mismatch_quote;
724 getHeaderSearchInfo().AddIncludeAlias(OriginalSource, ReplaceFileName);
731 std::pair<IdentifierInfo *, SourceLocation> &ModuleNameComponent,
738 ModuleNameComponent = std::make_pair(
741 ModuleNameComponent =
744 PP.
Diag(Tok.
getLocation(), diag::err_pp_expected_module_name) << First;
755 std::pair<IdentifierInfo*, SourceLocation> NameComponent;
758 ModuleName.push_back(NameComponent);
761 if (Tok.
isNot(tok::period))
769 std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc;
774 LexUnexpandedToken(Tok);
775 if (Tok.
isNot(tok::eod)) {
776 Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
777 DiscardUntilEndOfDirective();
780 CurLexer->LexingRawMode =
true;
782 auto TryConsumeIdentifier = [&](StringRef Ident) ->
bool {
783 if (Tok.
getKind() != tok::raw_identifier ||
791 const char *Start = CurLexer->getBufferLocation();
792 const char *
End =
nullptr;
793 unsigned NestingLevel = 1;
795 End = CurLexer->getBufferLocation();
799 Diag(Loc, diag::err_pp_module_build_missing_end);
810 CurLexer->ParsingPreprocessorDirective =
true;
812 if (TryConsumeIdentifier(
"pragma") && TryConsumeIdentifier(
"clang") &&
813 TryConsumeIdentifier(
"module")) {
814 if (TryConsumeIdentifier(
"build"))
817 else if (TryConsumeIdentifier(
"endbuild")) {
819 if (--NestingLevel == 0)
828 CurLexer->LexingRawMode =
false;
831 assert(CurLexer->getBuffer().begin() <= Start &&
832 Start <= CurLexer->getBuffer().end() &&
833 CurLexer->getBuffer().begin() <= End &&
834 End <= CurLexer->getBuffer().end() &&
835 "module source range not contained within same file buffer");
836 TheModuleLoader.loadModuleFromSource(Loc, ModuleName->
getName(),
837 StringRef(Start, End - Start));
842 if (Tok.
is(tok::l_paren)) {
845 std::string FileName;
846 if (!LexStringLiteral(Tok, FileName,
"pragma hdrstop",
false))
849 if (Tok.
isNot(tok::r_paren)) {
850 Diag(Tok, diag::err_expected) << tok::r_paren;
855 if (Tok.
isNot(tok::eod))
859 if (creatingPCHWithPragmaHdrStop() &&
861 assert(CurLexer &&
"no lexer for #pragma hdrstop processing");
864 CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd,
tok::eof);
865 CurLexer->cutOffLexing();
867 if (usingPCHWithPragmaHdrStop())
868 SkippingUntilPragmaHdrStop =
false;
879 if (!Namespace.empty()) {
883 if (
PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace)) {
885 assert(InsertNS !=
nullptr &&
"Cannot have a pragma namespace and pragma" 886 " handler with the same name!");
891 PragmaHandlers->AddPragma(InsertNS);
897 "Pragma handler already exists for this identifier!");
910 if (!Namespace.empty()) {
911 PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace);
912 assert(Existing &&
"Namespace containing handler does not exist!");
915 assert(NS &&
"Invalid namespace, registered as a regular pragma handler!");
921 if (NS != PragmaHandlers.get() && NS->
IsEmpty()) {
922 PragmaHandlers->RemovePragmaHandler(NS);
929 LexUnexpandedToken(Tok);
931 if (Tok.
isNot(tok::identifier)) {
932 Diag(Tok, diag::ext_on_off_switch_syntax);
938 else if (II->
isStr(
"OFF"))
940 else if (II->
isStr(
"DEFAULT"))
943 Diag(Tok, diag::ext_on_off_switch_syntax);
948 LexUnexpandedToken(Tok);
949 if (Tok.
isNot(tok::eod))
950 Diag(Tok, diag::ext_pragma_syntax_eod);
961 Token &OnceTok)
override {
973 Token &MarkTok)
override {
983 Token &PoisonTok)
override {
991 PragmaSystemHeaderHandler() :
PragmaHandler(
"system_header") {}
994 Token &SHToken)
override {
1004 Token &DepToken)
override {
1013 Token &DebugToken)
override {
1016 if (Tok.
isNot(tok::identifier)) {
1017 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1022 if (II->
isStr(
"assert")) {
1023 llvm_unreachable(
"This is an assertion!");
1024 }
else if (II->
isStr(
"crash")) {
1026 }
else if (II->
isStr(
"parser_crash")) {
1029 Crasher.
setKind(tok::annot_pragma_parser_crash);
1032 }
else if (II->
isStr(
"dump")) {
1038 DumpAnnot.
setKind(tok::annot_pragma_dump);
1045 PP.
Diag(Identifier, diag::warn_pragma_debug_missing_argument)
1048 }
else if (II->
isStr(
"diag_mapping")) {
1051 if (DiagName.
is(tok::eod))
1053 else if (DiagName.
is(tok::string_literal) && !DiagName.
hasUDSuffix()) {
1059 PP.
Diag(DiagName, diag::warn_pragma_debug_missing_argument)
1062 }
else if (II->
isStr(
"llvm_fatal_error")) {
1063 llvm::report_fatal_error(
"#pragma clang __debug llvm_fatal_error");
1064 }
else if (II->
isStr(
"llvm_unreachable")) {
1065 llvm_unreachable(
"#pragma clang __debug llvm_unreachable");
1066 }
else if (II->
isStr(
"macro")) {
1073 PP.
Diag(MacroName, diag::warn_pragma_debug_missing_argument)
1075 }
else if (II->
isStr(
"module_map")) {
1082 for (
auto IIAndLoc : ModuleName) {
1085 PP.
Diag(IIAndLoc.second, diag::warn_pragma_debug_unknown_module)
1091 }
else if (II->
isStr(
"overflow_stack")) {
1092 DebugOverflowStack();
1093 }
else if (II->
isStr(
"handle_crash")) {
1094 llvm::CrashRecoveryContext *CRC =llvm::CrashRecoveryContext::GetCurrent();
1097 }
else if (II->
isStr(
"captured")) {
1100 PP.
Diag(Tok, diag::warn_pragma_debug_unexpected_command)
1113 if (Tok.
isNot(tok::eod)) {
1114 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol)
1115 <<
"pragma clang __debug captured";
1122 Toks[0].startToken();
1123 Toks[0].setKind(tok::annot_pragma_captured);
1124 Toks[0].setLocation(NameLoc);
1126 PP.EnterTokenStream(Toks,
true,
1132 #pragma warning(disable : 4717) 1134 static void DebugOverflowStack(
void (*
P)() =
nullptr) {
1135 void (*
volatile Self)(void(*
P)()) = DebugOverflowStack;
1136 Self(
reinterpret_cast<void(*)()
>(Self));
1139 #pragma warning(default : 4717) 1146 const char *Namespace;
1149 explicit PragmaDiagnosticHandler(
const char *NS)
1153 Token &DiagToken)
override {
1157 if (Tok.
isNot(tok::identifier)) {
1158 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1164 if (II->
isStr(
"pop")) {
1166 PP.
Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
1170 }
else if (II->
isStr(
"push")) {
1185 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1192 std::string WarningName;
1197 if (Tok.
isNot(tok::eod)) {
1198 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_diagnostic_invalid_token);
1202 if (WarningName.size() < 3 || WarningName[0] !=
'-' ||
1203 (WarningName[1] !=
'W' && WarningName[1] !=
'R')) {
1204 PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_invalid_option);
1210 StringRef Group = StringRef(WarningName).substr(2);
1211 bool unknownDiag =
false;
1212 if (Group ==
"everything") {
1221 PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_unknown_warning)
1232 Token &DepToken)
override {
1244 Token &Tok)
override {
1253 if (Tok.
isNot(tok::l_paren)) {
1254 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
"(";
1261 if (II && II->
isStr(
"push")) {
1265 if (Tok.
is(tok::comma)) {
1268 if (Tok.
is(tok::numeric_constant) &&
1271 if (Level < 0 || Level > 4) {
1272 PP.
Diag(Tok, diag::warn_pragma_warning_push_level);
1278 }
else if (II && II->
isStr(
"pop")) {
1288 if (!II && !Tok.
is(tok::numeric_constant)) {
1289 PP.
Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1294 bool SpecifierValid;
1299 SpecifierValid = llvm::StringSwitch<bool>(
Specifier)
1300 .Cases(
"default",
"disable",
"error",
"once",
1312 SpecifierValid = (Value >= 1) && (Value <= 4);
1314 SpecifierValid =
false;
1318 if (!SpecifierValid) {
1319 PP.
Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1322 if (Tok.
isNot(tok::colon)) {
1323 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
":";
1330 while (Tok.
is(tok::numeric_constant)) {
1334 PP.
Diag(Tok, diag::warn_pragma_warning_expected_number);
1337 Ids.push_back(
int(Value));
1343 if (Tok.
isNot(tok::semi))
1349 if (Tok.
isNot(tok::r_paren)) {
1350 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
")";
1355 if (Tok.
isNot(tok::eod))
1356 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma warning";
1364 PragmaExecCharsetHandler() :
PragmaHandler(
"execution_character_set") {}
1367 Token &Tok)
override {
1375 if (Tok.
isNot(tok::l_paren)) {
1376 PP.
Diag(Tok, diag::warn_pragma_exec_charset_expected) <<
"(";
1383 if (II && II->
isStr(
"push")) {
1386 if (Tok.
is(tok::comma)) {
1389 std::string ExecCharset;
1391 "pragma execution_character_set",
1396 if (ExecCharset !=
"UTF-8" && ExecCharset !=
"utf-8") {
1397 PP.
Diag(Tok, diag::warn_pragma_exec_charset_push_invalid) << ExecCharset;
1403 }
else if (II && II->
isStr(
"pop")) {
1409 PP.
Diag(Tok, diag::warn_pragma_exec_charset_spec_invalid);
1413 if (Tok.
isNot(tok::r_paren)) {
1414 PP.
Diag(Tok, diag::warn_pragma_exec_charset_expected) <<
")";
1419 if (Tok.
isNot(tok::eod))
1420 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma execution_character_set";
1426 PragmaIncludeAliasHandler() :
PragmaHandler(
"include_alias") {}
1429 Token &IncludeAliasTok)
override {
1450 const StringRef Namespace;
1453 bool PragmaNameOnly =
false) {
1456 return PragmaNameOnly ?
"message" :
"pragma message";
1458 return PragmaNameOnly ?
"warning" :
"pragma warning";
1460 return PragmaNameOnly ?
"error" :
"pragma error";
1462 llvm_unreachable(
"Unknown PragmaMessageKind!");
1467 StringRef Namespace = StringRef())
1469 Namespace(Namespace) {}
1472 Token &Tok)
override {
1475 bool ExpectClosingParen =
false;
1479 ExpectClosingParen =
true;
1483 case tok::string_literal:
1487 PP.
Diag(MessageLoc, diag::err_pragma_message_malformed) <<
Kind;
1491 std::string MessageString;
1496 if (ExpectClosingParen) {
1497 if (Tok.
isNot(tok::r_paren)) {
1498 PP.
Diag(Tok.
getLocation(), diag::err_pragma_message_malformed) << Kind;
1504 if (Tok.
isNot(tok::eod)) {
1505 PP.
Diag(Tok.
getLocation(), diag::err_pragma_message_malformed) << Kind;
1511 ? diag::err_pragma_message
1512 : diag::warn_pragma_message) << MessageString;
1516 Callbacks->PragmaMessage(MessageLoc, Namespace, Kind, MessageString);
1528 Token &Tok)
override {
1537 if (Tok.
isNot(tok::eod))
1538 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1549 tok::annot_module_include, Imported);
1551 CB->moduleImport(ImportLoc, ModuleName, Imported);
1565 Token &Tok)
override {
1574 if (Tok.
isNot(tok::eod))
1575 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1579 if (ModuleName.front().first->getName() != Current) {
1580 PP.
Diag(ModuleName.front().second, diag::err_pp_module_begin_wrong_module)
1581 << ModuleName.front().first << (ModuleName.size() > 1)
1582 << Current.empty() << Current;
1589 Module *M = HSI.lookupModule(Current);
1591 PP.
Diag(ModuleName.front().second,
1592 diag::err_pp_module_begin_no_module_map) << Current;
1595 for (
unsigned I = 1; I != ModuleName.size(); ++I) {
1598 PP.
Diag(ModuleName[I].second, diag::err_pp_module_begin_no_submodule)
1608 PP.
Diag(BeginLoc, diag::note_pp_module_begin_here)
1616 tok::annot_module_begin, M);
1625 Token &Tok)
override {
1629 if (Tok.
isNot(tok::eod))
1630 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1636 PP.
Diag(Loc, diag::err_pp_module_end_without_module_begin);
1645 Token &Tok)
override {
1655 Token &Tok)
override {
1664 if (Tok.
isNot(tok::eod))
1665 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1679 Token &PushMacroTok)
override {
1690 Token &PopMacroTok)
override {
1697 struct PragmaARCCFCodeAuditedHandler :
public PragmaHandler {
1698 PragmaARCCFCodeAuditedHandler() :
PragmaHandler(
"arc_cf_code_audited") {}
1701 Token &NameTok)
override {
1710 if (BeginEnd && BeginEnd->
isStr(
"begin")) {
1712 }
else if (BeginEnd && BeginEnd->
isStr(
"end")) {
1721 if (Tok.
isNot(tok::eod))
1722 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1733 PP.
Diag(Loc, diag::err_pp_double_begin_of_arc_cf_code_audited);
1734 PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1740 PP.
Diag(Loc, diag::err_pp_unmatched_end_of_arc_cf_code_audited);
1753 PragmaAssumeNonNullHandler() :
PragmaHandler(
"assume_nonnull") {}
1756 Token &NameTok)
override {
1765 if (BeginEnd && BeginEnd->
isStr(
"begin")) {
1767 }
else if (BeginEnd && BeginEnd->
isStr(
"end")) {
1776 if (Tok.
isNot(tok::eod))
1777 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1789 PP.
Diag(Loc, diag::err_pp_double_begin_of_assume_nonnull);
1790 PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1798 PP.
Diag(Loc, diag::err_pp_unmatched_end_of_assume_nonnull);
1822 PragmaRegionHandler(
const char *pragma) :
PragmaHandler(pragma) {}
1825 Token &NameTok)
override {
1837 void Preprocessor::RegisterBuiltinPragmas() {
1838 AddPragmaHandler(
new PragmaOnceHandler());
1839 AddPragmaHandler(
new PragmaMarkHandler());
1840 AddPragmaHandler(
new PragmaPushMacroHandler());
1841 AddPragmaHandler(
new PragmaPopMacroHandler());
1845 AddPragmaHandler(
"GCC",
new PragmaPoisonHandler());
1846 AddPragmaHandler(
"GCC",
new PragmaSystemHeaderHandler());
1847 AddPragmaHandler(
"GCC",
new PragmaDependencyHandler());
1848 AddPragmaHandler(
"GCC",
new PragmaDiagnosticHandler(
"GCC"));
1854 AddPragmaHandler(
"clang",
new PragmaPoisonHandler());
1855 AddPragmaHandler(
"clang",
new PragmaSystemHeaderHandler());
1856 AddPragmaHandler(
"clang",
new PragmaDebugHandler());
1857 AddPragmaHandler(
"clang",
new PragmaDependencyHandler());
1858 AddPragmaHandler(
"clang",
new PragmaDiagnosticHandler(
"clang"));
1859 AddPragmaHandler(
"clang",
new PragmaARCCFCodeAuditedHandler());
1860 AddPragmaHandler(
"clang",
new PragmaAssumeNonNullHandler());
1864 AddPragmaHandler(
"clang", ModuleHandler);
1865 ModuleHandler->AddPragma(
new PragmaModuleImportHandler());
1866 ModuleHandler->AddPragma(
new PragmaModuleBeginHandler());
1867 ModuleHandler->AddPragma(
new PragmaModuleEndHandler());
1868 ModuleHandler->AddPragma(
new PragmaModuleBuildHandler());
1869 ModuleHandler->AddPragma(
new PragmaModuleLoadHandler());
1872 AddPragmaHandler(
new PragmaRegionHandler(
"region"));
1873 AddPragmaHandler(
new PragmaRegionHandler(
"endregion"));
1876 if (LangOpts.MicrosoftExt) {
1877 AddPragmaHandler(
new PragmaWarningHandler());
1878 AddPragmaHandler(
new PragmaExecCharsetHandler());
1879 AddPragmaHandler(
new PragmaIncludeAliasHandler());
1880 AddPragmaHandler(
new PragmaHdrstopHandler());
1884 for (PragmaHandlerRegistry::iterator it = PragmaHandlerRegistry::begin(),
1885 ie = PragmaHandlerRegistry::end();
1887 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.
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).
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.
void setPragmaARCCFCodeAuditedLoc(SourceLocation Loc)
Set the location of the currently-active #pragma clang arc_cf_code_audited begin. ...
#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.
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.
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...
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.
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.