36#include "llvm/ADT/ArrayRef.h"
37#include "llvm/ADT/DenseMap.h"
38#include "llvm/ADT/SmallVector.h"
39#include "llvm/ADT/StringRef.h"
40#include "llvm/Support/Compiler.h"
41#include "llvm/Support/ErrorHandling.h"
42#include "llvm/Support/Timer.h"
77 bool IgnoreNull)
const {
78 auto I = Handlers.find(Name);
79 if (I != Handlers.end())
80 return I->getValue().get();
83 I = Handlers.find(StringRef());
84 if (I != Handlers.end())
85 return I->getValue().get();
90 assert(!Handlers.count(Handler->
getName()) &&
91 "A handler with this name is already registered in this namespace");
92 Handlers[Handler->
getName()].reset(Handler);
96 auto I = Handlers.find(Handler->
getName());
97 assert(I != Handlers.end() &&
98 "Handler not registered in this namespace");
100 I->getValue().release();
116 PP.
Diag(
Tok, diag::warn_pragma_ignored);
132struct TokenCollector {
140 Tokens.push_back(
Tok);
145 assert(Collect &&
"did not collect tokens");
146 assert(!Tokens.empty() &&
"collected unexpected number of tokens");
149 auto Toks = std::make_unique<Token[]>(Tokens.size());
150 std::copy(Tokens.begin() + 1, Tokens.end(), Toks.get());
151 Toks[Tokens.size() - 1] =
Tok;
152 Self.EnterTokenStream(std::move(Toks), Tokens.size(),
157 Tok = *Tokens.begin();
166 Callbacks->PragmaDirective(Introducer.
Loc, Introducer.
Kind);
175 PragmaHandlers->HandlePragma(*
this, Introducer,
Tok);
178 if ((CurTokenLexer && CurTokenLexer->isParsingPreprocessorDirective())
179 || (CurPPLexer && CurPPLexer->ParsingPreprocessorDirective))
186void Preprocessor::Handle_Pragma(
Token &
Tok) {
207 TokenCollector Toks = {*
this, InMacroArgPreExpansion, {},
Tok};
215 Diag(PragmaLoc, diag::err__Pragma_malformed);
222 Diag(PragmaLoc, diag::err__Pragma_malformed);
230 if (
Tok.
is(tok::r_paren))
236 Diag(
Tok, diag::err_invalid_string_udl);
239 if (
Tok.
is(tok::r_paren))
250 Diag(PragmaLoc, diag::err__Pragma_malformed);
255 if (InMacroArgPreExpansion) {
262 SmallString<64> StrVal;
266 Diag(PragmaLoc, diag::err__Pragma_malformed);
270 assert(StrValRef.size() <= StrVal.size());
273 if (StrValRef.begin() != StrVal.begin())
274 StrVal.assign(StrValRef);
276 else if (StrValRef.size() != StrVal.size())
277 StrVal.resize(StrValRef.size());
292 TokLoc, PragmaLoc, RParenLoc, StrVal.size(), *
this);
294 EnterSourceFileWithLexer(std::move(TL),
nullptr);
304 if (StrVal[0] ==
'L' || StrVal[0] ==
'U' ||
305 (StrVal[0] ==
'u' && StrVal[1] !=
'8'))
306 StrVal.erase(StrVal.begin());
307 else if (StrVal[0] ==
'u')
308 StrVal.erase(StrVal.begin(), StrVal.begin() + 2);
310 if (StrVal[0] ==
'R') {
313 assert(StrVal[1] ==
'"' && StrVal[StrVal.size() - 1] ==
'"' &&
314 "Invalid raw string token!");
317 unsigned NumDChars = 0;
318 while (StrVal[2 + NumDChars] !=
'(') {
319 assert(NumDChars < (StrVal.size() - 5) / 2 &&
320 "Invalid raw string token!");
323 assert(StrVal[StrVal.size() - 2 - NumDChars] ==
')');
327 StrVal.erase(StrVal.begin(), StrVal.begin() + 2 + NumDChars);
328 StrVal.erase(StrVal.end() - 1 - NumDChars, StrVal.end());
330 assert(StrVal[0] ==
'"' && StrVal[StrVal.size()-1] ==
'"' &&
331 "Invalid string token!");
334 unsigned ResultPos = 1;
335 for (
size_t i = 1, e = StrVal.size() - 1; i != e; ++i) {
337 if (StrVal[i] ==
'\\' && i + 1 < e &&
338 (StrVal[i + 1] ==
'\\' || StrVal[i + 1] ==
'"'))
340 StrVal[ResultPos++] = StrVal[i];
342 StrVal.erase(StrVal.begin() + ResultPos, StrVal.end() - 1);
350 StrVal[StrVal.size() - 1] =
'\n';
355void Preprocessor::HandleMicrosoft__pragma(
Token &
Tok) {
358 TokenCollector Toks = {*
this, InMacroArgPreExpansion, {},
Tok};
366 Diag(PragmaLoc, diag::err__Pragma_malformed);
371 SmallVector<Token, 32> PragmaToks;
375 PragmaToks.push_back(
Tok);
376 if (
Tok.
is(tok::l_paren))
378 else if (
Tok.
is(tok::r_paren) && NumParens-- == 0)
383 if (
Tok.
is(tok::eof)) {
384 Diag(PragmaLoc, diag::err_unterminated___pragma);
389 if (InMacroArgPreExpansion) {
397 PragmaToks.back().setKind(tok::eod);
399 Token *TokArray =
new Token[PragmaToks.size()];
400 std::copy(PragmaToks.begin(), PragmaToks.end(), TokArray);
403 EnterTokenStream(TokArray, PragmaToks.size(),
true,
true,
420 Diag(OnceTok, diag::pp_pragma_once_in_main_file);
430 assert(CurPPLexer &&
"No current lexer?");
433 CurLexer->ReadToEndOfLine(&Buffer);
435 Callbacks->PragmaMark(MarkTok.
getLocation(), Buffer);
448 if (CurPPLexer) CurPPLexer->LexingRawMode =
true;
450 if (CurPPLexer) CurPPLexer->LexingRawMode =
false;
453 if (
Tok.is(tok::eod))
return;
456 if (
Tok.isNot(tok::raw_identifier)) {
457 Diag(
Tok, diag::err_pp_invalid_poison);
470 Diag(
Tok, diag::pp_poisoning_existing_macro);
483 Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
491 HeaderInfo.MarkFileSystemHeader(*TheLexer->
getFileEntry());
497 unsigned FilenameID = SourceMgr.getLineTableFilenameID(PLoc.
getFilename());
508 FilenameID,
false,
false,
519 if (FilenameTok.
isNot(tok::header_name)) {
535 if (Filename.empty())
541 nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr);
543 if (!SuppressIncludeNotFoundError)
544 Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
555 while (DependencyTok.
isNot(tok::eod)) {
561 if (!Message.empty())
562 Message.erase(Message.end()-1);
563 Diag(FilenameTok, diag::pp_out_of_date_dependency) << Message;
575 if (
Tok.isNot(tok::l_paren)) {
576 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
583 if (
Tok.isNot(tok::string_literal)) {
584 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
589 if (
Tok.hasUDSuffix()) {
590 Diag(
Tok, diag::err_invalid_string_udl);
600 if (
Tok.isNot(tok::r_paren)) {
601 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
606 assert(StrVal[0] ==
'"' && StrVal[StrVal.size()-1] ==
'"' &&
607 "Invalid string token!");
609 if (StrVal.size() <= 2) {
610 Diag(StrTok.
getLocation(), diag::warn_pargma_push_pop_macro_empty_string)
621 MacroTok.
setKind(tok::raw_identifier);
622 CreateString(StringRef(&StrVal[1], StrVal.size() - 2), MacroTok);
637 if (!IdentInfo)
return;
648 PragmaPushMacroInfo[IdentInfo].push_back(MI);
662 if (!IdentInfo)
return;
665 llvm::DenseMap<IdentifierInfo *, std::vector<MacroInfo *>>
::iterator iter =
666 PragmaPushMacroInfo.find(IdentInfo);
667 if (iter != PragmaPushMacroInfo.end()) {
670 if (MI->isWarnIfUnused())
671 WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
676 MacroInfo *MacroToReInstall = iter->second.back();
678 if (MacroToReInstall)
683 iter->second.pop_back();
684 if (iter->second.empty())
685 PragmaPushMacroInfo.erase(iter);
687 Diag(MessageLoc, diag::warn_pragma_pop_macro_no_push)
700 if (
Tok.isNot(tok::l_paren)) {
701 Diag(
Tok, diag::warn_pragma_include_alias_expected) <<
"(";
706 Token SourceFilenameTok;
710 StringRef SourceFileName;
712 if (SourceFilenameTok.
is(tok::header_name)) {
713 SourceFileName =
getSpelling(SourceFilenameTok, FileNameBuffer);
715 Diag(
Tok, diag::warn_pragma_include_alias_expected_filename);
718 FileNameBuffer.clear();
722 if (
Tok.isNot(tok::comma)) {
723 Diag(
Tok, diag::warn_pragma_include_alias_expected) <<
",";
727 Token ReplaceFilenameTok;
731 StringRef ReplaceFileName;
732 if (ReplaceFilenameTok.
is(tok::header_name)) {
733 ReplaceFileName =
getSpelling(ReplaceFilenameTok, FileNameBuffer);
735 Diag(
Tok, diag::warn_pragma_include_alias_expected_filename);
741 if (
Tok.isNot(tok::r_paren)) {
742 Diag(
Tok, diag::warn_pragma_include_alias_expected) <<
")";
748 StringRef OriginalSource = SourceFileName;
750 bool SourceIsAngled =
753 bool ReplaceIsAngled =
756 if (!SourceFileName.empty() && !ReplaceFileName.empty() &&
757 (SourceIsAngled != ReplaceIsAngled)) {
760 DiagID = diag::warn_pragma_include_alias_mismatch_angle;
762 DiagID = diag::warn_pragma_include_alias_mismatch_quote;
781 if (
Tok.is(tok::string_literal) && !
Tok.hasUDSuffix()) {
783 if (Literal.hadError)
787 }
else if (!
Tok.isAnnotation() &&
Tok.getIdentifierInfo()) {
788 ModuleNameComponent =
791 PP.
Diag(
Tok.getLocation(), diag::err_pp_expected_module_name) <<
First;
803 ModuleName.push_back(NameComponent);
806 if (
Tok.isNot(tok::period))
820 if (
Tok.isNot(tok::eod)) {
821 Diag(
Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
825 CurLexer->LexingRawMode =
true;
827 auto TryConsumeIdentifier = [&](StringRef Ident) ->
bool {
828 if (
Tok.getKind() != tok::raw_identifier ||
829 Tok.getRawIdentifier() != Ident)
836 const char *Start = CurLexer->getBufferLocation();
837 const char *End =
nullptr;
840 End = CurLexer->getBufferLocation();
843 if (
Tok.is(tok::eof)) {
844 Diag(Loc, diag::err_pp_module_build_missing_end);
848 if (
Tok.isNot(tok::hash) || !
Tok.isAtStartOfLine()) {
855 CurLexer->ParsingPreprocessorDirective =
true;
857 if (TryConsumeIdentifier(
"pragma") && TryConsumeIdentifier(
"clang") &&
858 TryConsumeIdentifier(
"module")) {
859 if (TryConsumeIdentifier(
"build"))
862 else if (TryConsumeIdentifier(
"endbuild")) {
869 assert(
Tok.getKind() != tok::eof &&
"missing EOD before EOF");
873 CurLexer->LexingRawMode =
false;
876 assert(CurLexer->getBuffer().begin() <= Start &&
877 Start <= CurLexer->getBuffer().end() &&
878 CurLexer->getBuffer().begin() <= End &&
879 End <= CurLexer->getBuffer().end() &&
880 "module source range not contained within same file buffer");
881 TheModuleLoader.createModuleFromSource(Loc, ModuleName->
getName(),
882 StringRef(Start, End - Start));
887 if (
Tok.is(tok::l_paren)) {
888 Diag(
Tok.getLocation(), diag::warn_pp_hdrstop_filename_ignored);
894 if (
Tok.isNot(tok::r_paren)) {
895 Diag(
Tok, diag::err_expected) << tok::r_paren;
900 if (
Tok.isNot(tok::eod))
901 Diag(
Tok.getLocation(), diag::ext_pp_extra_tokens_at_eol)
905 SourceMgr.isInMainFile(
Tok.getLocation())) {
906 assert(CurLexer &&
"no lexer for #pragma hdrstop processing");
909 CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
910 CurLexer->cutOffLexing();
913 SkippingUntilPragmaHdrStop =
false;
917 return MacroName == Ident__GLIBCXX__;
924 if (!
Tok.getIdentifierInfo()) {
925 Diag(
Tok.getLocation(), diag::err_pp_pragma_set_pp_state_expected_name);
931 Diag(
Tok.getLocation(), diag::err_pp_pragma_set_pp_state_invalid_arg)
939 if (!
Tok.is(tok::numeric_constant) ||
941 Diag(
Tok.getLocation(), diag::err_pp_pragma_set_pp_state_expected_int_after)
948 if (MacroName->
getName() ==
"__GLIBCXX__")
951 llvm_unreachable(
"forgot to handle a possible argument to __set_pp_state");
954 Callbacks->PragmaSetPPState(Introducer.
Loc, MacroName,
Value);
965 if (!Namespace.empty()) {
969 if (
PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace)) {
971 assert(InsertNS !=
nullptr &&
"Cannot have a pragma namespace and pragma"
972 " handler with the same name!");
977 PragmaHandlers->AddPragma(InsertNS);
983 "Pragma handler already exists for this identifier!");
996 if (!Namespace.empty()) {
997 PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace);
998 assert(Existing &&
"Namespace containing handler does not exist!");
1001 assert(NS &&
"Invalid namespace, registered as a regular pragma handler!");
1007 if (NS != PragmaHandlers.get() && NS->
IsEmpty()) {
1008 PragmaHandlers->RemovePragmaHandler(NS);
1017 if (
Tok.isNot(tok::identifier)) {
1018 Diag(
Tok, diag::ext_on_off_switch_syntax);
1022 if (II->
isStr(
"ON"))
1024 else if (II->
isStr(
"OFF"))
1026 else if (II->
isStr(
"DEFAULT"))
1029 Diag(
Tok, diag::ext_on_off_switch_syntax);
1035 if (
Tok.isNot(tok::eod))
1036 Diag(
Tok, diag::ext_pragma_syntax_eod);
1047 Token &OnceTok)
override {
1056 PragmaMarkHandler() : PragmaHandler(
"mark") {}
1058 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1059 Token &MarkTok)
override {
1066 PragmaPoisonHandler() : PragmaHandler(
"poison") {}
1068 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1069 Token &PoisonTok)
override {
1077 PragmaSystemHeaderHandler() : PragmaHandler(
"system_header") {}
1079 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1080 Token &SHToken)
override {
1087 PragmaDependencyHandler() : PragmaHandler(
"dependency") {}
1089 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1090 Token &DepToken)
override {
1096 PragmaDebugHandler() : PragmaHandler(
"__debug") {}
1098 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1099 Token &DebugToken)
override {
1103 PP.
Diag(
Tok, diag::warn_pragma_debug_missing_command);
1108 if (II->
isStr(
"assert")) {
1110 llvm_unreachable(
"This is an assertion!");
1111 }
else if (II->
isStr(
"crash")) {
1112 llvm::Timer
T(
"crash",
"pragma crash");
1113 llvm::TimeRegion
R(&
T);
1116 }
else if (II->
isStr(
"parser_crash")) {
1122 }
else if (II->
isStr(
"sleep")) {
1123 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1124 }
else if (II->
isStr(
"dump")) {
1128 }
else if (II->
isStr(
"diag_mapping")) {
1131 if (DiagName.
is(tok::eod))
1133 else if (DiagName.
is(tok::string_literal) && !DiagName.
hasUDSuffix()) {
1134 StringLiteralParser
Literal(DiagName, PP,
1135 StringLiteralEvalMethod::Unevaluated);
1140 PP.
Diag(DiagName, diag::warn_pragma_debug_missing_argument)
1143 }
else if (II->
isStr(
"llvm_fatal_error")) {
1145 llvm::report_fatal_error(
"#pragma clang __debug llvm_fatal_error");
1146 }
else if (II->
isStr(
"llvm_unreachable")) {
1148 llvm_unreachable(
"#pragma clang __debug llvm_unreachable");
1149 }
else if (II->
isStr(
"macro")) {
1156 PP.
Diag(MacroName, diag::warn_pragma_debug_missing_argument)
1158 }
else if (II->
isStr(
"module_map")) {
1159 llvm::SmallVector<IdentifierLoc, 8> ModuleName;
1164 for (
auto IIAndLoc : ModuleName) {
1168 PP.
Diag(IIAndLoc.getLoc(), diag::warn_pragma_debug_unknown_module)
1169 << IIAndLoc.getIdentifierInfo()->getName();
1174 }
else if (II->
isStr(
"module_lookup")) {
1179 PP.
Diag(MName, diag::warn_pragma_debug_missing_argument)
1185 PP.
Diag(MName, diag::warn_pragma_debug_unable_to_find_module)
1186 << MNameII->getName();
1190 }
else if (II->
isStr(
"overflow_stack")) {
1192 DebugOverflowStack();
1193 }
else if (II->
isStr(
"captured")) {
1195 }
else if (II->
isStr(
"modules")) {
1196 struct ModuleVisitor {
1198 void visit(
Module *M,
bool VisibleOnly) {
1200 if (!VisibleOnly || ImportLoc.
isValid()) {
1203 llvm::errs() << M <<
" visible ";
1206 llvm::errs() <<
"\n";
1209 if (!VisibleOnly || ImportLoc.
isInvalid() ||
Sub->IsExplicit)
1210 visit(Sub, VisibleOnly);
1213 void visitAll(
bool VisibleOnly) {
1214 for (
auto &NameAndMod :
1216 visit(NameAndMod.second, VisibleOnly);
1222 auto *DumpII =
Kind.getIdentifierInfo();
1224 PP.
Diag(Kind, diag::warn_pragma_debug_missing_argument)
1226 }
else if (DumpII->isStr(
"all")) {
1227 Visitor.visitAll(
false);
1228 }
else if (DumpII->isStr(
"visible")) {
1229 Visitor.visitAll(
true);
1230 }
else if (DumpII->isStr(
"building")) {
1232 llvm::errs() <<
"in " << Building.M->getFullModuleName();
1233 if (Building.ImportLoc.isValid()) {
1234 llvm::errs() <<
" imported ";
1235 if (Building.IsPragma)
1236 llvm::errs() <<
"via pragma ";
1237 llvm::errs() <<
"at ";
1239 llvm::errs() <<
"\n";
1243 PP.
Diag(
Tok, diag::warn_pragma_debug_unexpected_command)
1244 << DumpII->getName();
1246 }
else if (II->
isStr(
"sloc_usage")) {
1249 std::optional<unsigned> MaxNotes;
1253 if (ArgToken.
is(tok::numeric_constant) &&
1256 }
else if (ArgToken.
isNot(tok::eod)) {
1257 PP.
Diag(ArgToken, diag::warn_pragma_debug_unexpected_argument);
1260 PP.
Diag(
Tok, diag::remark_sloc_usage);
1264 PP.
Diag(
Tok, diag::warn_pragma_debug_unexpected_command)
1273 void HandleCaptured(Preprocessor &PP) {
1278 PP.
Diag(
Tok, diag::ext_pp_extra_tokens_at_eol)
1279 <<
"pragma clang __debug captured";
1284 MutableArrayRef<Token> Toks(
1288 PP.EnterTokenStream(Toks,
true,
1294 #pragma warning(disable : 4717)
1296 static void DebugOverflowStack(
void (*P)() =
nullptr) {
1297 void (*
volatile Self)(void(*P)()) = DebugOverflowStack;
1298 Self(
reinterpret_cast<void(*)()
>(
Self));
1301 #pragma warning(default : 4717)
1305struct PragmaUnsafeBufferUsageHandler :
public PragmaHandler {
1306 PragmaUnsafeBufferUsageHandler() : PragmaHandler(
"unsafe_buffer_usage") {}
1307 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1308 Token &FirstToken)
override {
1313 PP.
Diag(
Tok, diag::err_pp_pragma_unsafe_buffer_usage_syntax);
1320 if (II->
isStr(
"begin")) {
1322 PP.
Diag(Loc, diag::err_pp_double_begin_pragma_unsafe_buffer_usage);
1323 }
else if (II->
isStr(
"end")) {
1325 PP.
Diag(Loc, diag::err_pp_unmatched_end_begin_pragma_unsafe_buffer_usage);
1327 PP.
Diag(
Tok, diag::err_pp_pragma_unsafe_buffer_usage_syntax);
1337 explicit PragmaDiagnosticHandler(
const char *NS)
1338 : PragmaHandler(
"diagnostic"),
Namespace(NS) {}
1340 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1341 Token &DiagToken)
override {
1346 PP.
Diag(
Tok, diag::warn_pragma_diagnostic_invalid);
1356 if (II->
isStr(
"pop")) {
1358 PP.
Diag(
Tok, diag::warn_pragma_diagnostic_cannot_pop);
1365 }
else if (II->
isStr(
"push")) {
1376 .Case(
"ignored", diag::Severity::Ignored)
1377 .Case(
"warning", diag::Severity::Warning)
1378 .Case(
"error", diag::Severity::Error)
1379 .Case(
"fatal", diag::Severity::Fatal)
1383 PP.
Diag(
Tok, diag::warn_pragma_diagnostic_invalid);
1389 std::string WarningName;
1399 if (WarningName.size() < 3 || WarningName[0] !=
'-' ||
1400 (WarningName[1] !=
'W' && WarningName[1] !=
'R')) {
1401 PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_invalid_option);
1406 : diag::Flavor::Remark;
1407 StringRef
Group = StringRef(WarningName).substr(2);
1408 bool unknownDiag =
false;
1409 if (Group ==
"everything") {
1418 PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_unknown_warning)
1427 PragmaHdrstopHandler() : PragmaHandler(
"hdrstop") {}
1428 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1429 Token &DepToken)
override {
1438 PragmaWarningHandler() : PragmaHandler(
"warning") {}
1440 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1441 Token &
Tok)
override {
1451 PP.
Diag(
Tok, diag::warn_pragma_warning_expected) <<
"(";
1458 if (II && II->
isStr(
"push")) {
1462 if (
Tok.
is(tok::comma)) {
1465 if (
Tok.
is(tok::numeric_constant) &&
1469 PP.
Diag(
Tok, diag::warn_pragma_warning_push_level);
1476 }
else if (II && II->
isStr(
"pop")) {
1480 PP.
Diag(
Tok, diag::warn_pragma_diagnostic_cannot_pop);
1488 if (!II && !
Tok.
is(tok::numeric_constant)) {
1489 PP.
Diag(
Tok, diag::warn_pragma_warning_spec_invalid);
1494 bool SpecifierValid;
1497 int SpecifierInt = llvm::StringSwitch<int>(II->
getName())
1504 SpecifierValid = SpecifierInt != -1;
1517 if ((SpecifierValid = (
Value >= 1) && (
Value <= 4)))
1521 SpecifierValid =
false;
1525 if (!SpecifierValid) {
1526 PP.
Diag(
Tok, diag::warn_pragma_warning_spec_invalid);
1530 PP.
Diag(
Tok, diag::warn_pragma_warning_expected) <<
":";
1535 SmallVector<int, 4> Ids;
1537 while (
Tok.
is(tok::numeric_constant)) {
1541 PP.
Diag(
Tok, diag::warn_pragma_warning_expected_number);
1544 Ids.push_back(
int(
Value));
1550 SV = diag::Severity::Ignored;
1552 for (
int Id : Ids) {
1555 diag::Flavor::WarningOrError, *Group, SV, DiagLoc);
1556 assert(!unknownDiag &&
1557 "wd table should only contain known diags");
1573 PP.
Diag(
Tok, diag::warn_pragma_warning_expected) <<
")";
1579 PP.
Diag(
Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma warning";
1587 PragmaExecCharsetHandler() : PragmaHandler(
"execution_character_set") {}
1589 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1590 Token &
Tok)
override {
1599 PP.
Diag(
Tok, diag::warn_pragma_exec_charset_expected) <<
"(";
1606 if (II && II->
isStr(
"push")) {
1609 if (
Tok.
is(tok::comma)) {
1612 std::string ExecCharset;
1614 "pragma execution_character_set",
1619 if (ExecCharset !=
"UTF-8" && ExecCharset !=
"utf-8") {
1620 PP.
Diag(
Tok, diag::warn_pragma_exec_charset_push_invalid) << ExecCharset;
1626 }
else if (II && II->
isStr(
"pop")) {
1632 PP.
Diag(
Tok, diag::warn_pragma_exec_charset_spec_invalid);
1637 PP.
Diag(
Tok, diag::warn_pragma_exec_charset_expected) <<
")";
1643 PP.
Diag(
Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma execution_character_set";
1649 PragmaIncludeAliasHandler() : PragmaHandler(
"include_alias") {}
1651 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1652 Token &IncludeAliasTok)
override {
1676 bool PragmaNameOnly =
false) {
1679 return PragmaNameOnly ?
"message" :
"pragma message";
1681 return PragmaNameOnly ?
"warning" :
"pragma warning";
1683 return PragmaNameOnly ?
"error" :
"pragma error";
1685 llvm_unreachable(
"Unknown PragmaMessageKind!");
1690 StringRef Namespace = StringRef())
1694 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1695 Token &
Tok)
override {
1698 bool ExpectClosingParen =
false;
1702 ExpectClosingParen =
true;
1706 case tok::string_literal:
1710 PP.
Diag(MessageLoc, diag::err_pragma_message_malformed) <<
Kind;
1714 std::string MessageString;
1719 if (ExpectClosingParen) {
1734 ? diag::err_pragma_message
1735 : diag::warn_pragma_message) << MessageString;
1739 Callbacks->
PragmaMessage(MessageLoc, Namespace, Kind, MessageString);
1748 PragmaModuleImportHandler() : PragmaHandler(
"import") {}
1750 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1751 Token &
Tok)
override {
1755 llvm::SmallVector<IdentifierLoc, 8> ModuleName;
1760 PP.
Diag(
Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1771 tok::annot_module_include, Imported);
1773 CB->moduleImport(ImportLoc, ModuleName, Imported);
1784 PragmaModuleBeginHandler() : PragmaHandler(
"begin") {}
1786 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1787 Token &
Tok)
override {
1791 llvm::SmallVector<IdentifierLoc, 8> ModuleName;
1796 PP.
Diag(
Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1800 if (ModuleName.front().getIdentifierInfo()->getName() != Current) {
1801 PP.
Diag(ModuleName.front().getLoc(),
1802 diag::err_pp_module_begin_wrong_module)
1803 << ModuleName.front().getIdentifierInfo() << (ModuleName.size() > 1)
1804 << Current.empty() << Current;
1811 auto &MM = HSI.getModuleMap();
1812 Module *M = HSI.lookupModule(Current, ModuleName.front().getLoc());
1814 PP.
Diag(ModuleName.front().getLoc(),
1815 diag::err_pp_module_begin_no_module_map)
1819 for (
unsigned I = 1; I != ModuleName.size(); ++I) {
1821 M, ModuleName[I].getIdentifierInfo()->
getName());
1823 PP.
Diag(ModuleName[I].getLoc(), diag::err_pp_module_begin_no_submodule)
1833 PP.
Diag(BeginLoc, diag::note_pp_module_begin_here)
1841 tok::annot_module_begin, M);
1847 PragmaModuleEndHandler() : PragmaHandler(
"end") {}
1849 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1850 Token &
Tok)
override {
1855 PP.
Diag(
Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1861 PP.
Diag(Loc, diag::err_pp_module_end_without_module_begin);
1867 PragmaModuleBuildHandler() : PragmaHandler(
"build") {}
1869 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1870 Token &
Tok)
override {
1877 PragmaModuleLoadHandler() : PragmaHandler(
"load") {}
1879 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1880 Token &
Tok)
override {
1884 llvm::SmallVector<IdentifierLoc, 8> ModuleName;
1889 PP.
Diag(
Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1900 PragmaPushMacroHandler() : PragmaHandler(
"push_macro") {}
1902 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1903 Token &PushMacroTok)
override {
1911 PragmaPopMacroHandler() : PragmaHandler(
"pop_macro") {}
1913 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1914 Token &PopMacroTok)
override {
1921struct PragmaARCCFCodeAuditedHandler :
public PragmaHandler {
1922 PragmaARCCFCodeAuditedHandler() : PragmaHandler(
"arc_cf_code_audited") {}
1924 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1925 Token &NameTok)
override {
1934 if (BeginEnd && BeginEnd->
isStr(
"begin")) {
1936 }
else if (BeginEnd && BeginEnd->
isStr(
"end")) {
1946 PP.
Diag(
Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1952 SourceLocation NewLoc;
1957 PP.
Diag(Loc, diag::err_pp_double_begin_of_arc_cf_code_audited);
1958 PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1964 PP.
Diag(Loc, diag::err_pp_unmatched_end_of_arc_cf_code_audited);
1967 NewLoc = SourceLocation();
1977 PragmaAssumeNonNullHandler() : PragmaHandler(
"assume_nonnull") {}
1979 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1980 Token &NameTok)
override {
1989 if (BeginEnd && BeginEnd->
isStr(
"begin")) {
1991 }
else if (BeginEnd && BeginEnd->
isStr(
"end")) {
2001 PP.
Diag(
Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
2007 SourceLocation NewLoc;
2013 PP.
Diag(Loc, diag::err_pp_double_begin_of_assume_nonnull);
2014 PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
2022 PP.
Diag(Loc, diag::err_pp_unmatched_end_of_assume_nonnull);
2025 NewLoc = SourceLocation();
2046 PragmaRegionHandler(
const char *pragma) : PragmaHandler(pragma) {}
2048 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
2049 Token &NameTok)
override {
2063 PragmaManagedHandler(
const char *pragma) : EmptyPragmaHandler(pragma) {}
2069 std::string &MessageString) {
2072 PP.
Diag(
Tok, diag::err_expected) <<
"(";
2077 if (!
Tok.
is(tok::identifier)) {
2078 PP.
Diag(
Tok, diag::err_expected) << tok::identifier;
2084 PP.
Diag(
Tok, diag::err_pp_visibility_non_macro) << II;
2089 if (
Tok.
is(tok::comma)) {
2097 PP.
Diag(
Tok, diag::err_expected) <<
")";
2110 PragmaDeprecatedHandler() : PragmaHandler(
"deprecated") {}
2112 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
2113 Token &
Tok)
override {
2114 std::string MessageString;
2116 if (IdentifierInfo *II = HandleMacroAnnotationPragma(
2117 PP,
Tok,
"#pragma clang deprecated", MessageString)) {
2131struct PragmaRestrictExpansionHandler :
public PragmaHandler {
2132 PragmaRestrictExpansionHandler() : PragmaHandler(
"restrict_expansion") {}
2134 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
2135 Token &
Tok)
override {
2136 std::string MessageString;
2138 if (IdentifierInfo *II = HandleMacroAnnotationPragma(
2139 PP,
Tok,
"#pragma clang restrict_expansion", MessageString)) {
2154 PragmaFinalHandler() : PragmaHandler(
"final") {}
2156 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
2157 Token &
Tok)
override {
2160 PP.
Diag(
Tok, diag::err_expected) <<
"(";
2165 if (!
Tok.
is(tok::identifier)) {
2166 PP.
Diag(
Tok, diag::err_expected) << tok::identifier;
2172 PP.
Diag(
Tok, diag::err_pp_visibility_non_macro) << II;
2178 PP.
Diag(
Tok, diag::err_expected) <<
")";
2199 PragmaSetPPStateHandler() : PragmaHandler(
"__set_pp_state") {}
2200 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
2201 Token &
Tok)
override {
2209void Preprocessor::RegisterBuiltinPragmas() {
2239 auto *ModuleHandler =
new PragmaNamespace(
"module");
2241 ModuleHandler->AddPragma(
new PragmaModuleImportHandler());
2242 ModuleHandler->AddPragma(
new PragmaModuleBeginHandler());
2243 ModuleHandler->AddPragma(
new PragmaModuleEndHandler());
2244 ModuleHandler->AddPragma(
new PragmaModuleBuildHandler());
2245 ModuleHandler->AddPragma(
new PragmaModuleLoadHandler());
2255 if (LangOpts.MicrosoftExt) {
2266 for (
const PragmaHandlerRegistry::entry &handler :
2267 PragmaHandlerRegistry::entries()) {
Defines the Diagnostic-related interfaces.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
Defines the clang::MacroInfo and clang::MacroDirective classes.
Defines the clang::Module class, which describes a module in the source code.
Defines the PPCallbacks interface.
static bool LexModuleName(Preprocessor &PP, Token &Tok, llvm::SmallVectorImpl< IdentifierLoc > &ModuleName)
static bool LexModuleNameComponent(Preprocessor &PP, Token &Tok, IdentifierLoc &ModuleNameComponent, bool First)
Defines the PreprocessorLexer interface.
Defines the clang::Preprocessor interface.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines the clang::TokenKind enum and support functions.
void setSeverityForAll(diag::Flavor Flavor, diag::Severity Map, SourceLocation Loc=SourceLocation())
Add the specified mapping to all diagnostics of the specified flavor.
LLVM_DUMP_METHOD void dump() const
void pushMappings(SourceLocation Loc)
Copies the current DiagMappings and pushes the new copy onto the top of the stack.
bool setSeverityForGroup(diag::Flavor Flavor, StringRef Group, diag::Severity Map, SourceLocation Loc=SourceLocation())
Change an entire diagnostic group (e.g.
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...
EmptyPragmaHandler - A pragma handler which takes no action, which can be used to ignore particular p...
void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, Token &FirstToken) override
EmptyPragmaHandler(StringRef Name=StringRef())
time_t getModificationTime() const
One of these records is kept for each identifier that is lexed.
void setIsRestrictExpansion(bool Val)
void setIsDeprecatedMacro(bool Val)
void setIsPoisoned(bool Value=true)
setIsPoisoned - Mark this identifier as poisoned.
void setIsFinal(bool Val)
bool hasMacroDefinition() const
Return true if this identifier is #defined to some other value.
bool isFromAST() const
Return true if the identifier in its current state was loaded from an AST file.
bool isPoisoned() const
Return true if this token has been poisoned.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
void setChangedSinceDeserialization()
Note that this identifier has changed since it was loaded from an AST file.
StringRef getName() const
Return the actual identifier string.
A simple pair of identifier info and location.
SourceLocation getLoc() const
std::string CurrentModule
The name of the current module, of which the main source file is a part.
static std::unique_ptr< 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.
Encapsulates the data about a macro definition (e.g.
void setIsAllowRedefinitionsWithoutWarning(bool Val)
Set the value of the IsAllowRedefinitionsWithoutWarning flag.
virtual ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective)=0
Attempt to load the given module.
ModuleRef lookupModuleQualified(StringRef Name, Module *Context) const
Retrieve a module with the given name within the given context, using direct (qualified) name lookup.
Module * findOrInferSubmodule(Module *Parent, StringRef Name)
llvm::iterator_range< module_iterator > modules() const
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
llvm::iterator_range< submodule_iterator > submodules()
void dump() const
Dump the contents of this module to the given output stream.
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
virtual void PragmaExecCharsetPop(SourceLocation Loc)
Callback invoked when a #pragma execution_character_set(pop) directive is read.
virtual void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace)
Callback invoked when a #pragma gcc diagnostic push directive is read.
virtual void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier WarningSpec, ArrayRef< int > Ids)
virtual void PragmaDebug(SourceLocation Loc, StringRef DebugType)
Callback invoked when a #pragma clang __debug directive is read.
virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace, diag::Severity mapping, StringRef Str)
Callback invoked when a #pragma gcc diagnostic directive is read.
PragmaWarningSpecifier
Callback invoked when a #pragma warning directive is read.
virtual void PragmaAssumeNonNullEnd(SourceLocation Loc)
Callback invoked when a #pragma clang assume_nonnull end directive is read.
virtual void PragmaAssumeNonNullBegin(SourceLocation Loc)
Callback invoked when a #pragma clang assume_nonnull begin directive is read.
virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace, PragmaMessageKind Kind, StringRef Str)
Callback invoked when a #pragma message directive is read.
virtual void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str)
Callback invoked when a #pragma execution_character_set(push) directive is read.
virtual void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace)
Callback invoked when a #pragma gcc diagnostic pop directive is read.
virtual void PragmaWarningPop(SourceLocation Loc)
Callback invoked when a #pragma warning(pop) directive is read.
PragmaMessageKind
Determines the kind of #pragma invoking a call to PragmaMessage.
@ PMK_Warning
#pragma GCC warning has been invoked.
@ PMK_Error
#pragma GCC error has been invoked.
@ PMK_Message
#pragma message has been invoked.
virtual void PragmaWarningPush(SourceLocation Loc, int Level)
Callback invoked when a #pragma warning(push) directive is read.
PragmaHandler - Instances of this interface defined to handle the various pragmas that the language f...
StringRef getName() const
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, Token &FirstToken)=0
virtual PragmaNamespace * getIfNamespace()
getIfNamespace - If this is a namespace, return it.
PragmaNamespace - This PragmaHandler subdivides the namespace of pragmas, allowing hierarchical pragm...
void AddPragma(PragmaHandler *Handler)
AddPragma - Add a pragma to this namespace.
PragmaHandler * FindHandler(StringRef Name, bool IgnoreNull=true) const
FindHandler - Check to see if there is already a handler for the specified name.
void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, Token &Tok) override
void RemovePragmaHandler(PragmaHandler *Handler)
RemovePragmaHandler - Remove the given handler from the namespace.
PragmaNamespace * getIfNamespace() override
getIfNamespace - If this is a namespace, return it.
OptionalFileEntryRef getFileEntry() const
getFileEntry - Return the FileEntry corresponding to this FileID.
bool DisablePragmaDebugCrash
Prevents intended crashes when using pragma clang __debug. For testing.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
bool isPragmaSetPPStateMacro(IdentifierInfo *II)
Check whether this is a macro name that can be used as an argument to 'pragma clang __set_pp_state'.
void HandlePragmaPushMacro(Token &Tok)
Handle #pragma push_macro.
void setStdLibCxxVersion(std::uint64_t Version)
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...
void HandlePragmaPoison()
HandlePragmaPoison - Handle #pragma GCC poison. PoisonTok is the 'poison'.
void dumpMacroInfo(const IdentifierInfo *II)
void HandlePragmaSystemHeader(Token &SysHeaderTok)
HandlePragmaSystemHeader - Implement #pragma GCC system_header.
void setPragmaARCCFCodeAuditedInfo(IdentifierInfo *Ident, SourceLocation Loc)
Set the location of the currently-active #pragma clang arc_cf_code_audited begin.
void HandlePragmaModuleBuild(Token &Tok)
void EnterToken(const Token &Tok, bool IsReinject)
Enters a token in the token stream to be lexed next.
void IgnorePragmas()
Install empty handlers for all pragmas (making them ignored).
PPCallbacks * getPPCallbacks() const
SourceRange DiscardUntilEndOfDirective(SmallVectorImpl< Token > *DiscardedToks=nullptr)
Read and discard all tokens remaining on the current line until the tok::eod token is found.
const MacroInfo * getMacroInfo(const IdentifierInfo *II) const
ArrayRef< BuildingSubmoduleInfo > getBuildingSubmodules() const
Get the list of submodules that we're currently building.
SourceLocation getModuleImportLoc(Module *M) const
void setPragmaAssumeNonNullLoc(SourceLocation Loc)
Set the location of the currently-active #pragma clang assume_nonnull begin.
bool isInPrimaryFile() const
Return true if we're in the top-level file, not in a #include.
void CreateString(StringRef Str, Token &Tok, SourceLocation ExpansionLocStart=SourceLocation(), SourceLocation ExpansionLocEnd=SourceLocation())
Plop the specified string into a scratch buffer and set the specified token's location and length to ...
void EnterSubmodule(Module *M, SourceLocation ImportLoc, bool ForPragma)
void addMacroDeprecationMsg(const IdentifierInfo *II, std::string Msg, SourceLocation AnnotationLoc)
void addRestrictExpansionMsg(const IdentifierInfo *II, std::string Msg, SourceLocation AnnotationLoc)
IdentifierInfo * LookUpIdentifierInfo(Token &Identifier) const
Given a tok::raw_identifier token, look up the identifier information for the token and install it in...
void addFinalLoc(const IdentifierInfo *II, SourceLocation AnnotationLoc)
void Lex(Token &Result)
Lex the next token for this preprocessor.
const TranslationUnitKind TUKind
The kind of translation unit we are processing.
ModuleLoader & getModuleLoader() const
Retrieve the module loader associated with this preprocessor.
bool LexOnOffSwitch(tok::OnOffSwitch &Result)
Lex an on-off-switch (C99 6.10.6p2) and verify that it is followed by EOD.
void HandlePragmaDependency(Token &DependencyTok)
HandlePragmaDependency - Handle #pragma GCC dependency "foo" blah.
bool enterOrExitSafeBufferOptOutRegion(bool isEnter, const SourceLocation &Loc)
Alter the state of whether this PP currently is in a "-Wunsafe-buffer-usage" opt-out region.
IdentifierLoc getPragmaARCCFCodeAuditedInfo() const
The location of the currently-active #pragma clang arc_cf_code_audited begin.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
SourceManager & getSourceManager() const
void HandlePragmaOnce(Token &OnceTok)
HandlePragmaOnce - Handle #pragma once. OnceTok is the 'once'.
SourceLocation CheckEndOfDirective(StringRef DirType, bool EnableMacros=false, SmallVectorImpl< Token > *ExtraToks=nullptr)
Ensure that the next token is a tok::eod token.
bool isMacroDefined(StringRef Id)
static bool checkModuleIsAvailable(const LangOptions &LangOpts, const TargetInfo &TargetInfo, const Module &M, DiagnosticsEngine &Diags)
Check that the given module is available, producing a diagnostic if not.
SourceLocation getPragmaAssumeNonNullLoc() const
The location of the currently-active #pragma clang assume_nonnull begin.
void makeModuleVisible(Module *M, SourceLocation Loc, bool IncludeExports=true)
const TargetInfo & getTargetInfo() const
bool LexHeaderName(Token &Result, bool AllowMacroExpansion=true)
Lex a token, forming a header-name token if possible.
bool parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value)
Parses a simple integer literal to get its numeric value.
void LexUnexpandedToken(Token &Result)
Just like Lex, but disables macro expansion of identifier tokens.
bool creatingPCHWithPragmaHdrStop()
True if creating a PCH with a pragma hdrstop.
void AddPragmaHandler(StringRef Namespace, PragmaHandler *Handler)
Add the specified pragma handler to this preprocessor.
llvm::BumpPtrAllocator & getPreprocessorAllocator()
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 ...
bool GetIncludeFilenameSpelling(SourceLocation Loc, StringRef &Buffer)
Turn the specified lexer token into a fully checked and spelled filename, e.g.
PreprocessorLexer * getCurrentFileLexer() const
Return the current file lexer being lexed from.
HeaderSearch & getHeaderSearchInfo() const
void HandlePragmaPopMacro(Token &Tok)
Handle #pragma pop_macro.
Module * LeaveSubmodule(bool ForPragma)
void EnterAnnotationToken(SourceRange Range, tok::TokenKind Kind, void *AnnotationVal)
Enter an annotation token into the token stream.
OptionalFileEntryRef LookupFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled, ConstSearchDirIterator FromDir, const FileEntry *FromFile, ConstSearchDirIterator *CurDir, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool *IsFrameworkFound, bool SkipCache=false, bool OpenFile=true, bool CacheFailures=true)
Given a "foo" or <foo> reference, look up the indicated file.
const PreprocessorOptions & getPreprocessorOpts() const
Retrieve the preprocessor options used to initialize this preprocessor.
const LangOptions & getLangOpts() const
void HandlePragmaSetPPState(PragmaIntroducer Introducer, Token &Tok)
IdentifierInfo * ParsePragmaPushOrPopMacro(Token &Tok)
ParsePragmaPushOrPopMacro - Handle parsing of pragma push_macro/pop_macro.
bool usingPCHWithPragmaHdrStop()
True if using a PCH with a pragma hdrstop.
DefMacroDirective * appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI, SourceLocation Loc)
void HandlePragmaMark(Token &MarkTok)
void HandlePragmaHdrstop(Token &Tok)
DiagnosticsEngine & getDiagnostics() const
void RemovePragmaHandler(StringRef Namespace, PragmaHandler *Handler)
Remove the specific pragma handler from this preprocessor.
void HandlePragmaIncludeAlias(Token &Tok)
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
bool LexStringLiteral(Token &Result, std::string &String, const char *DiagnosticTag, bool AllowMacroExpansion)
Lex a string literal, which may be the concatenation of multiple string literals and may even come fr...
void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD)
Add a directive to the macro directive history for this identifier.
Represents an unpacked "presumed" location which can be presented to the user.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
void print(raw_ostream &OS, const SourceManager &SM) const
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
void noteSLocAddressSpaceUsage(DiagnosticsEngine &Diag, std::optional< unsigned > MaxNotes=32) const
A trivial tuple used to represent a source range.
StringLiteralParser - This decodes string escape characters and performs wide string analysis and Tra...
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
unsigned getLength() const
void setKind(tok::TokenKind K)
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)) {....
tok::TokenKind getKind() const
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
static Token createAnnotation(tok::TokenKind Kind, SourceRange Range, void *Value=nullptr)
bool isNot(tok::TokenKind K) const
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix.
void startToken()
Reset all flags to cleared.
uint32_t Literal
Literals are represented as positive integers.
Flavor
Flavors of diagnostics we can emit.
Severity
Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs to either Ignore (nothing),...
StringRef getName(const HeaderType T)
bool Sub(InterpState &S, CodePtr OpPC)
bool isStringLiteral(TokenKind K)
Return true if this is a C or C++ string-literal (or C++11 user-defined-string-literal) token.
OnOffSwitch
Defines the possible values of an on-off-switch (C99 6.10.6p2).
Top level wrappers for InstallAPI frontend operations.
std::optional< diag::Group > diagGroupFromCLWarningID(unsigned)
For cl.exe warning IDs that cleany map to clang diagnostic groups, returns the corresponding group.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Result
The result type of a method or function.
const FunctionProtoType * T
@ TU_Prefix
The translation unit is a prefix to a translation unit, and is not complete.
@ PIK__Pragma
The pragma was introduced via the C99 _Pragma(string-literal).
@ PIK___pragma
The pragma was introduced via the Microsoft __pragma(token-string).
void prepare_PragmaString(SmallVectorImpl< char > &StrVal)
Destringize a _Pragma("") string according to C11 6.10.9.1: "The string literal is destringized by de...
Describes how and where the pragma was introduced.
PragmaIntroducerKind Kind