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"
76 bool IgnoreNull)
const {
77 auto I = Handlers.find(Name);
78 if (I != Handlers.end())
79 return I->getValue().get();
82 I = Handlers.find(StringRef());
83 if (I != Handlers.end())
84 return I->getValue().get();
89 assert(!Handlers.count(Handler->
getName()) &&
90 "A handler with this name is already registered in this namespace");
91 Handlers[Handler->
getName()].reset(Handler);
95 auto I = Handlers.find(Handler->
getName());
96 assert(I != Handlers.end() &&
97 "Handler not registered in this namespace");
99 I->getValue().release();
115 PP.
Diag(Tok, diag::warn_pragma_ignored);
131struct TokenCollector {
139 Tokens.push_back(Tok);
144 assert(Collect &&
"did not collect tokens");
145 assert(!Tokens.empty() &&
"collected unexpected number of tokens");
148 auto Toks = std::make_unique<Token[]>(Tokens.size());
149 std::copy(Tokens.begin() + 1, Tokens.end(), Toks.get());
150 Toks[Tokens.size() - 1] = Tok;
151 Self.EnterTokenStream(std::move(Toks), Tokens.size(),
156 Tok = *Tokens.begin();
165 Callbacks->PragmaDirective(Introducer.
Loc, Introducer.
Kind);
174 PragmaHandlers->HandlePragma(*
this, Introducer, Tok);
177 if ((CurTokenLexer && CurTokenLexer->isParsingPreprocessorDirective())
185void Preprocessor::Handle_Pragma(
Token &Tok) {
206 TokenCollector Toks = {*
this, InMacroArgPreExpansion, {}, Tok};
213 if (Tok.
isNot(tok::l_paren)) {
214 Diag(PragmaLoc, diag::err__Pragma_malformed);
221 Diag(PragmaLoc, diag::err__Pragma_malformed);
223 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::eof) && Tok.
isNot(tok::eod))
225 while (Tok.
isNot(tok::r_paren) &&
229 if (Tok.
is(tok::r_paren))
235 Diag(Tok, diag::err_invalid_string_udl);
238 if (Tok.
is(tok::r_paren))
248 if (Tok.
isNot(tok::r_paren)) {
249 Diag(PragmaLoc, diag::err__Pragma_malformed);
254 if (InMacroArgPreExpansion) {
265 Diag(PragmaLoc, diag::err__Pragma_malformed);
269 assert(StrValRef.size() <= StrVal.size());
272 if (StrValRef.begin() != StrVal.begin())
273 StrVal.assign(StrValRef);
275 else if (StrValRef.size() != StrVal.size())
276 StrVal.resize(StrValRef.size());
291 StrVal.size(), *
this);
293 EnterSourceFileWithLexer(TL,
nullptr);
303 if (StrVal[0] ==
'L' || StrVal[0] ==
'U' ||
304 (StrVal[0] ==
'u' && StrVal[1] !=
'8'))
305 StrVal.erase(StrVal.begin());
306 else if (StrVal[0] ==
'u')
307 StrVal.erase(StrVal.begin(), StrVal.begin() + 2);
309 if (StrVal[0] ==
'R') {
312 assert(StrVal[1] ==
'"' && StrVal[StrVal.size() - 1] ==
'"' &&
313 "Invalid raw string token!");
316 unsigned NumDChars = 0;
317 while (StrVal[2 + NumDChars] !=
'(') {
318 assert(NumDChars < (StrVal.size() - 5) / 2 &&
319 "Invalid raw string token!");
322 assert(StrVal[StrVal.size() - 2 - NumDChars] ==
')');
326 StrVal.erase(StrVal.begin(), StrVal.begin() + 2 + NumDChars);
327 StrVal.erase(StrVal.end() - 1 - NumDChars, StrVal.end());
329 assert(StrVal[0] ==
'"' && StrVal[StrVal.size()-1] ==
'"' &&
330 "Invalid string token!");
333 unsigned ResultPos = 1;
334 for (
size_t i = 1, e = StrVal.size() - 1; i != e; ++i) {
336 if (StrVal[i] ==
'\\' && i + 1 < e &&
337 (StrVal[i + 1] ==
'\\' || StrVal[i + 1] ==
'"'))
339 StrVal[ResultPos++] = StrVal[i];
341 StrVal.erase(StrVal.begin() + ResultPos, StrVal.end() - 1);
349 StrVal[StrVal.size() - 1] =
'\n';
354void Preprocessor::HandleMicrosoft__pragma(
Token &Tok) {
357 TokenCollector Toks = {*
this, InMacroArgPreExpansion, {}, Tok};
364 if (Tok.
isNot(tok::l_paren)) {
365 Diag(PragmaLoc, diag::err__Pragma_malformed);
373 while (Tok.
isNot(tok::eof)) {
374 PragmaToks.push_back(Tok);
375 if (Tok.
is(tok::l_paren))
377 else if (Tok.
is(tok::r_paren) && NumParens-- == 0)
382 if (Tok.
is(tok::eof)) {
383 Diag(PragmaLoc, diag::err_unterminated___pragma);
388 if (InMacroArgPreExpansion) {
396 PragmaToks.back().setKind(tok::eod);
398 Token *TokArray =
new Token[PragmaToks.size()];
399 std::copy(PragmaToks.begin(), PragmaToks.end(), TokArray);
402 EnterTokenStream(TokArray, PragmaToks.size(),
true,
true,
419 Diag(OnceTok, diag::pp_pragma_once_in_main_file);
429 assert(CurPPLexer &&
"No current lexer?");
432 CurLexer->ReadToEndOfLine(&Buffer);
434 Callbacks->PragmaMark(MarkTok.
getLocation(), Buffer);
452 if (Tok.
is(tok::eod))
return;
455 if (Tok.
isNot(tok::raw_identifier)) {
456 Diag(Tok, diag::err_pp_invalid_poison);
469 Diag(Tok, diag::pp_poisoning_existing_macro);
482 Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
507 FilenameID,
false,
false,
518 if (FilenameTok.
isNot(tok::header_name)) {
540 nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr);
542 if (!SuppressIncludeNotFoundError)
543 Diag(FilenameTok, diag::err_pp_file_not_found) <<
Filename;
554 while (DependencyTok.
isNot(tok::eod)) {
560 if (!Message.empty())
561 Message.erase(Message.end()-1);
562 Diag(FilenameTok, diag::pp_out_of_date_dependency) << Message;
570 Token PragmaTok = Tok;
574 if (Tok.
isNot(tok::l_paren)) {
575 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
582 if (Tok.
isNot(tok::string_literal)) {
583 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
589 Diag(Tok, diag::err_invalid_string_udl);
599 if (Tok.
isNot(tok::r_paren)) {
600 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
605 assert(StrVal[0] ==
'"' && StrVal[StrVal.size()-1] ==
'"' &&
606 "Invalid string token!");
608 if (StrVal.size() <= 2) {
609 Diag(StrTok.
getLocation(), diag::warn_pargma_push_pop_macro_empty_string)
620 MacroTok.
setKind(tok::raw_identifier);
621 CreateString(StringRef(&StrVal[1], StrVal.size() - 2), MacroTok);
636 if (!IdentInfo)
return;
647 PragmaPushMacroInfo[IdentInfo].push_back(MI);
661 if (!IdentInfo)
return;
664 llvm::DenseMap<IdentifierInfo *, std::vector<MacroInfo *>>::iterator iter =
665 PragmaPushMacroInfo.find(IdentInfo);
666 if (iter != PragmaPushMacroInfo.end()) {
669 if (MI->isWarnIfUnused())
670 WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
675 MacroInfo *MacroToReInstall = iter->second.back();
677 if (MacroToReInstall)
682 iter->second.pop_back();
683 if (iter->second.empty())
684 PragmaPushMacroInfo.erase(iter);
686 Diag(MessageLoc, diag::warn_pragma_pop_macro_no_push)
699 if (Tok.
isNot(tok::l_paren)) {
700 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
"(";
705 Token SourceFilenameTok;
709 StringRef SourceFileName;
711 if (SourceFilenameTok.
is(tok::header_name)) {
712 SourceFileName =
getSpelling(SourceFilenameTok, FileNameBuffer);
714 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
717 FileNameBuffer.clear();
721 if (Tok.
isNot(tok::comma)) {
722 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
",";
726 Token ReplaceFilenameTok;
730 StringRef ReplaceFileName;
731 if (ReplaceFilenameTok.
is(tok::header_name)) {
732 ReplaceFileName =
getSpelling(ReplaceFilenameTok, FileNameBuffer);
734 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
740 if (Tok.
isNot(tok::r_paren)) {
741 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
")";
747 StringRef OriginalSource = SourceFileName;
749 bool SourceIsAngled =
752 bool ReplaceIsAngled =
755 if (!SourceFileName.empty() && !ReplaceFileName.empty() &&
756 (SourceIsAngled != ReplaceIsAngled)) {
759 DiagID = diag::warn_pragma_include_alias_mismatch_angle;
761 DiagID = diag::warn_pragma_include_alias_mismatch_quote;
782 if (Literal.hadError)
787 ModuleNameComponent =
802 ModuleName.push_back(NameComponent);
805 if (Tok.
isNot(tok::period))
819 if (Tok.
isNot(tok::eod)) {
820 Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
824 CurLexer->LexingRawMode =
true;
826 auto TryConsumeIdentifier = [&](StringRef Ident) ->
bool {
827 if (Tok.
getKind() != tok::raw_identifier ||
835 const char *Start = CurLexer->getBufferLocation();
836 const char *End =
nullptr;
837 unsigned NestingLevel = 1;
839 End = CurLexer->getBufferLocation();
842 if (Tok.
is(tok::eof)) {
843 Diag(
Loc, diag::err_pp_module_build_missing_end);
854 CurLexer->ParsingPreprocessorDirective =
true;
856 if (TryConsumeIdentifier(
"pragma") && TryConsumeIdentifier(
"clang") &&
857 TryConsumeIdentifier(
"module")) {
858 if (TryConsumeIdentifier(
"build"))
861 else if (TryConsumeIdentifier(
"endbuild")) {
863 if (--NestingLevel == 0)
868 assert(Tok.
getKind() != tok::eof &&
"missing EOD before EOF");
872 CurLexer->LexingRawMode =
false;
875 assert(CurLexer->getBuffer().begin() <= Start &&
876 Start <= CurLexer->getBuffer().end() &&
877 CurLexer->getBuffer().begin() <= End &&
878 End <= CurLexer->getBuffer().end() &&
879 "module source range not contained within same file buffer");
881 StringRef(Start, End - Start));
886 if (Tok.
is(tok::l_paren)) {
893 if (Tok.
isNot(tok::r_paren)) {
894 Diag(Tok, diag::err_expected) << tok::r_paren;
899 if (Tok.
isNot(tok::eod))
905 assert(CurLexer &&
"no lexer for #pragma hdrstop processing");
908 CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
909 CurLexer->cutOffLexing();
912 SkippingUntilPragmaHdrStop =
false;
923 if (!Namespace.empty()) {
927 if (
PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace)) {
929 assert(InsertNS !=
nullptr &&
"Cannot have a pragma namespace and pragma"
930 " handler with the same name!");
935 PragmaHandlers->AddPragma(InsertNS);
941 "Pragma handler already exists for this identifier!");
954 if (!Namespace.empty()) {
955 PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace);
956 assert(Existing &&
"Namespace containing handler does not exist!");
959 assert(NS &&
"Invalid namespace, registered as a regular pragma handler!");
965 if (NS != PragmaHandlers.get() && NS->
IsEmpty()) {
966 PragmaHandlers->RemovePragmaHandler(NS);
975 if (Tok.
isNot(tok::identifier)) {
976 Diag(Tok, diag::ext_on_off_switch_syntax);
982 else if (II->
isStr(
"OFF"))
984 else if (II->
isStr(
"DEFAULT"))
987 Diag(Tok, diag::ext_on_off_switch_syntax);
993 if (Tok.
isNot(tok::eod))
994 Diag(Tok, diag::ext_pragma_syntax_eod);
1005 Token &OnceTok)
override {
1017 Token &MarkTok)
override {
1027 Token &PoisonTok)
override {
1035 PragmaSystemHeaderHandler() :
PragmaHandler(
"system_header") {}
1038 Token &SHToken)
override {
1048 Token &DepToken)
override {
1057 Token &DebugToken)
override {
1060 if (Tok.
isNot(tok::identifier)) {
1061 PP.
Diag(Tok, diag::warn_pragma_debug_missing_command);
1066 if (II->
isStr(
"assert")) {
1068 llvm_unreachable(
"This is an assertion!");
1069 }
else if (II->
isStr(
"crash")) {
1070 llvm::Timer
T(
"crash",
"pragma crash");
1071 llvm::TimeRegion R(&
T);
1074 }
else if (II->
isStr(
"parser_crash")) {
1078 Crasher.
setKind(tok::annot_pragma_parser_crash);
1082 }
else if (II->
isStr(
"dump")) {
1085 DumpAnnot.
setKind(tok::annot_pragma_dump);
1088 }
else if (II->
isStr(
"diag_mapping")) {
1091 if (DiagName.
is(tok::eod))
1093 else if (DiagName.
is(tok::string_literal) && !DiagName.
hasUDSuffix()) {
1095 StringLiteralEvalMethod::Unevaluated);
1100 PP.
Diag(DiagName, diag::warn_pragma_debug_missing_argument)
1103 }
else if (II->
isStr(
"llvm_fatal_error")) {
1105 llvm::report_fatal_error(
"#pragma clang __debug llvm_fatal_error");
1106 }
else if (II->
isStr(
"llvm_unreachable")) {
1108 llvm_unreachable(
"#pragma clang __debug llvm_unreachable");
1109 }
else if (II->
isStr(
"macro")) {
1116 PP.
Diag(MacroName, diag::warn_pragma_debug_missing_argument)
1118 }
else if (II->
isStr(
"module_map")) {
1124 for (
auto IIAndLoc : ModuleName) {
1128 PP.
Diag(IIAndLoc.getLoc(), diag::warn_pragma_debug_unknown_module)
1129 << IIAndLoc.getIdentifierInfo()->getName();
1134 }
else if (II->
isStr(
"module_lookup")) {
1139 PP.
Diag(MName, diag::warn_pragma_debug_missing_argument)
1145 PP.
Diag(MName, diag::warn_pragma_debug_unable_to_find_module)
1146 << MNameII->getName();
1150 }
else if (II->
isStr(
"overflow_stack")) {
1152 DebugOverflowStack();
1153 }
else if (II->
isStr(
"captured")) {
1155 }
else if (II->
isStr(
"modules")) {
1156 struct ModuleVisitor {
1158 void visit(
Module *M,
bool VisibleOnly) {
1160 if (!VisibleOnly || ImportLoc.
isValid()) {
1163 llvm::errs() << M <<
" visible ";
1166 llvm::errs() <<
"\n";
1169 if (!VisibleOnly || ImportLoc.
isInvalid() ||
Sub->IsExplicit)
1170 visit(Sub, VisibleOnly);
1173 void visitAll(
bool VisibleOnly) {
1174 for (
auto &NameAndMod :
1176 visit(NameAndMod.second, VisibleOnly);
1182 auto *DumpII =
Kind.getIdentifierInfo();
1184 PP.
Diag(
Kind, diag::warn_pragma_debug_missing_argument)
1186 }
else if (DumpII->isStr(
"all")) {
1187 Visitor.visitAll(
false);
1188 }
else if (DumpII->isStr(
"visible")) {
1189 Visitor.visitAll(
true);
1190 }
else if (DumpII->isStr(
"building")) {
1192 llvm::errs() <<
"in " << Building.M->getFullModuleName();
1193 if (Building.ImportLoc.isValid()) {
1194 llvm::errs() <<
" imported ";
1195 if (Building.IsPragma)
1196 llvm::errs() <<
"via pragma ";
1197 llvm::errs() <<
"at ";
1199 llvm::errs() <<
"\n";
1203 PP.
Diag(Tok, diag::warn_pragma_debug_unexpected_command)
1204 << DumpII->getName();
1206 }
else if (II->
isStr(
"sloc_usage")) {
1209 std::optional<unsigned> MaxNotes;
1213 if (ArgToken.
is(tok::numeric_constant) &&
1216 }
else if (ArgToken.
isNot(tok::eod)) {
1217 PP.
Diag(ArgToken, diag::warn_pragma_debug_unexpected_argument);
1220 PP.
Diag(Tok, diag::remark_sloc_usage);
1224 PP.
Diag(Tok, diag::warn_pragma_debug_unexpected_command)
1237 if (Tok.
isNot(tok::eod)) {
1238 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol)
1239 <<
"pragma clang __debug captured";
1246 Toks[0].startToken();
1247 Toks[0].setKind(tok::annot_pragma_captured);
1248 Toks[0].setLocation(NameLoc);
1250 PP.EnterTokenStream(Toks,
true,
1256 #pragma warning(disable : 4717)
1258 static void DebugOverflowStack(
void (*
P)() =
nullptr) {
1259 void (*
volatile Self)(void(*
P)()) = DebugOverflowStack;
1260 Self(
reinterpret_cast<void(*)()
>(Self));
1263 #pragma warning(default : 4717)
1267struct PragmaUnsafeBufferUsageHandler :
public PragmaHandler {
1268 PragmaUnsafeBufferUsageHandler() :
PragmaHandler(
"unsafe_buffer_usage") {}
1270 Token &FirstToken)
override {
1274 if (Tok.
isNot(tok::identifier)) {
1275 PP.
Diag(Tok, diag::err_pp_pragma_unsafe_buffer_usage_syntax);
1282 if (II->
isStr(
"begin")) {
1284 PP.
Diag(
Loc, diag::err_pp_double_begin_pragma_unsafe_buffer_usage);
1285 }
else if (II->
isStr(
"end")) {
1287 PP.
Diag(
Loc, diag::err_pp_unmatched_end_begin_pragma_unsafe_buffer_usage);
1289 PP.
Diag(Tok, diag::err_pp_pragma_unsafe_buffer_usage_syntax);
1299 explicit PragmaDiagnosticHandler(
const char *NS)
1303 Token &DiagToken)
override {
1307 if (Tok.
isNot(tok::identifier)) {
1308 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1318 if (II->
isStr(
"pop")) {
1320 PP.
Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
1324 if (Tok.
isNot(tok::eod))
1325 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_diagnostic_invalid_token);
1327 }
else if (II->
isStr(
"push")) {
1332 if (Tok.
isNot(tok::eod))
1333 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_diagnostic_invalid_token);
1338 .Case(
"ignored", diag::Severity::Ignored)
1339 .Case(
"warning", diag::Severity::Warning)
1340 .Case(
"error", diag::Severity::Error)
1341 .Case(
"fatal", diag::Severity::Fatal)
1345 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1351 std::string WarningName;
1356 if (Tok.
isNot(tok::eod)) {
1357 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_diagnostic_invalid_token);
1361 if (WarningName.size() < 3 || WarningName[0] !=
'-' ||
1362 (WarningName[1] !=
'W' && WarningName[1] !=
'R')) {
1363 PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_invalid_option);
1368 : diag::Flavor::Remark;
1369 StringRef
Group = StringRef(WarningName).substr(2);
1370 bool unknownDiag =
false;
1371 if (Group ==
"everything") {
1380 PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_unknown_warning)
1391 Token &DepToken)
override {
1403 Token &Tok)
override {
1412 if (Tok.
isNot(tok::l_paren)) {
1413 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
"(";
1420 if (II && II->
isStr(
"push")) {
1424 if (Tok.
is(tok::comma)) {
1427 if (Tok.
is(tok::numeric_constant) &&
1430 if (Level < 0 || Level > 4) {
1431 PP.
Diag(Tok, diag::warn_pragma_warning_push_level);
1438 }
else if (II && II->
isStr(
"pop")) {
1442 PP.
Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
1450 if (!II && !Tok.
is(tok::numeric_constant)) {
1451 PP.
Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1456 bool SpecifierValid;
1459 int SpecifierInt = llvm::StringSwitch<int>(II->
getName())
1466 SpecifierValid = SpecifierInt != -1;
1479 if ((SpecifierValid = (
Value >= 1) && (
Value <= 4)))
1483 SpecifierValid =
false;
1487 if (!SpecifierValid) {
1488 PP.
Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1491 if (Tok.
isNot(tok::colon)) {
1492 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
":";
1499 while (Tok.
is(tok::numeric_constant)) {
1503 PP.
Diag(Tok, diag::warn_pragma_warning_expected_number);
1506 Ids.push_back(
int(
Value));
1512 SV = diag::Severity::Ignored;
1514 for (
int Id : Ids) {
1517 diag::Flavor::WarningOrError, *Group, SV, DiagLoc);
1518 assert(!unknownDiag &&
1519 "wd table should only contain known diags");
1528 if (Tok.
isNot(tok::semi))
1534 if (Tok.
isNot(tok::r_paren)) {
1535 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
")";
1540 if (Tok.
isNot(tok::eod))
1541 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma warning";
1549 PragmaExecCharsetHandler() :
PragmaHandler(
"execution_character_set") {}
1552 Token &Tok)
override {
1560 if (Tok.
isNot(tok::l_paren)) {
1561 PP.
Diag(Tok, diag::warn_pragma_exec_charset_expected) <<
"(";
1568 if (II && II->
isStr(
"push")) {
1571 if (Tok.
is(tok::comma)) {
1574 std::string ExecCharset;
1576 "pragma execution_character_set",
1581 if (ExecCharset !=
"UTF-8" && ExecCharset !=
"utf-8") {
1582 PP.
Diag(Tok, diag::warn_pragma_exec_charset_push_invalid) << ExecCharset;
1588 }
else if (II && II->
isStr(
"pop")) {
1594 PP.
Diag(Tok, diag::warn_pragma_exec_charset_spec_invalid);
1598 if (Tok.
isNot(tok::r_paren)) {
1599 PP.
Diag(Tok, diag::warn_pragma_exec_charset_expected) <<
")";
1604 if (Tok.
isNot(tok::eod))
1605 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma execution_character_set";
1611 PragmaIncludeAliasHandler() :
PragmaHandler(
"include_alias") {}
1614 Token &IncludeAliasTok)
override {
1638 bool PragmaNameOnly =
false) {
1641 return PragmaNameOnly ?
"message" :
"pragma message";
1643 return PragmaNameOnly ?
"warning" :
"pragma warning";
1645 return PragmaNameOnly ?
"error" :
"pragma error";
1647 llvm_unreachable(
"Unknown PragmaMessageKind!");
1652 StringRef Namespace = StringRef())
1657 Token &Tok)
override {
1660 bool ExpectClosingParen =
false;
1664 ExpectClosingParen =
true;
1668 case tok::string_literal:
1672 PP.
Diag(MessageLoc, diag::err_pragma_message_malformed) <<
Kind;
1676 std::string MessageString;
1681 if (ExpectClosingParen) {
1682 if (Tok.
isNot(tok::r_paren)) {
1689 if (Tok.
isNot(tok::eod)) {
1696 ? diag::err_pragma_message
1697 : diag::warn_pragma_message) << MessageString;
1713 Token &Tok)
override {
1721 if (Tok.
isNot(tok::eod))
1722 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1733 tok::annot_module_include, Imported);
1735 CB->moduleImport(ImportLoc, ModuleName, Imported);
1749 Token &Tok)
override {
1757 if (Tok.
isNot(tok::eod))
1758 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1762 if (ModuleName.front().getIdentifierInfo()->getName() != Current) {
1763 PP.
Diag(ModuleName.front().getLoc(),
1764 diag::err_pp_module_begin_wrong_module)
1765 << ModuleName.front().getIdentifierInfo() << (ModuleName.size() > 1)
1766 << Current.empty() << Current;
1773 auto &MM = HSI.getModuleMap();
1774 Module *M = HSI.lookupModule(Current, ModuleName.front().getLoc());
1776 PP.
Diag(ModuleName.front().getLoc(),
1777 diag::err_pp_module_begin_no_module_map)
1781 for (
unsigned I = 1; I != ModuleName.size(); ++I) {
1783 M, ModuleName[I].getIdentifierInfo()->getName());
1785 PP.
Diag(ModuleName[I].getLoc(), diag::err_pp_module_begin_no_submodule)
1795 PP.
Diag(BeginLoc, diag::note_pp_module_begin_here)
1803 tok::annot_module_begin, M);
1812 Token &Tok)
override {
1816 if (Tok.
isNot(tok::eod))
1817 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1823 PP.
Diag(
Loc, diag::err_pp_module_end_without_module_begin);
1832 Token &Tok)
override {
1842 Token &Tok)
override {
1850 if (Tok.
isNot(tok::eod))
1851 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1865 Token &PushMacroTok)
override {
1876 Token &PopMacroTok)
override {
1883struct PragmaARCCFCodeAuditedHandler :
public PragmaHandler {
1884 PragmaARCCFCodeAuditedHandler() :
PragmaHandler(
"arc_cf_code_audited") {}
1887 Token &NameTok)
override {
1896 if (BeginEnd && BeginEnd->
isStr(
"begin")) {
1898 }
else if (BeginEnd && BeginEnd->
isStr(
"end")) {
1907 if (Tok.
isNot(tok::eod))
1908 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1919 PP.
Diag(
Loc, diag::err_pp_double_begin_of_arc_cf_code_audited);
1920 PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1926 PP.
Diag(
Loc, diag::err_pp_unmatched_end_of_arc_cf_code_audited);
1939 PragmaAssumeNonNullHandler() :
PragmaHandler(
"assume_nonnull") {}
1942 Token &NameTok)
override {
1951 if (BeginEnd && BeginEnd->
isStr(
"begin")) {
1953 }
else if (BeginEnd && BeginEnd->
isStr(
"end")) {
1962 if (Tok.
isNot(tok::eod))
1963 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1975 PP.
Diag(
Loc, diag::err_pp_double_begin_of_assume_nonnull);
1976 PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1984 PP.
Diag(
Loc, diag::err_pp_unmatched_end_of_assume_nonnull);
2008 PragmaRegionHandler(
const char *pragma) :
PragmaHandler(pragma) {}
2011 Token &NameTok)
override {
2031 std::string &MessageString) {
2033 if (Tok.
isNot(tok::l_paren)) {
2034 PP.
Diag(Tok, diag::err_expected) <<
"(";
2039 if (!Tok.
is(tok::identifier)) {
2040 PP.
Diag(Tok, diag::err_expected) << tok::identifier;
2046 PP.
Diag(Tok, diag::err_pp_visibility_non_macro) << II;
2051 if (Tok.
is(tok::comma)) {
2058 if (Tok.
isNot(tok::r_paren)) {
2059 PP.
Diag(Tok, diag::err_expected) <<
")";
2075 Token &Tok)
override {
2076 std::string MessageString;
2079 PP, Tok,
"#pragma clang deprecated", MessageString)) {
2093struct PragmaRestrictExpansionHandler :
public PragmaHandler {
2094 PragmaRestrictExpansionHandler() :
PragmaHandler(
"restrict_expansion") {}
2097 Token &Tok)
override {
2098 std::string MessageString;
2101 PP, Tok,
"#pragma clang restrict_expansion", MessageString)) {
2119 Token &Tok)
override {
2121 if (Tok.
isNot(tok::l_paren)) {
2122 PP.
Diag(Tok, diag::err_expected) <<
"(";
2127 if (!Tok.
is(tok::identifier)) {
2128 PP.
Diag(Tok, diag::err_expected) << tok::identifier;
2134 PP.
Diag(Tok, diag::err_pp_visibility_non_macro) << II;
2139 if (Tok.
isNot(tok::r_paren)) {
2140 PP.
Diag(Tok, diag::err_expected) <<
")";
2152void Preprocessor::RegisterBuiltinPragmas() {
2183 ModuleHandler->AddPragma(
new PragmaModuleImportHandler());
2184 ModuleHandler->AddPragma(
new PragmaModuleBeginHandler());
2185 ModuleHandler->AddPragma(
new PragmaModuleEndHandler());
2186 ModuleHandler->AddPragma(
new PragmaModuleBuildHandler());
2187 ModuleHandler->AddPragma(
new PragmaModuleLoadHandler());
2197 if (LangOpts.MicrosoftExt) {
2208 for (
const PragmaHandlerRegistry::entry &handler :
2209 PragmaHandlerRegistry::entries()) {
Defines the Diagnostic-related interfaces.
enum clang::sema::@1840::IndirectLocalPathEntry::EntryKind Kind
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.
NestedNameSpecifier Specifier
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
IdentifierInfo * getIdentifierInfo() const
std::string CurrentModule
The name of the current module, of which the main source file is a part.
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
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.
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.
virtual void createModuleFromSource(SourceLocation Loc, StringRef ModuleName, StringRef Source)=0
Attempt to create the given module from the specified source buffer.
Module * 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
Describes a module or submodule.
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.
This interface provides a way to observe the actions of the preprocessor as it does its thing.
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.
bool LexingRawMode
True if in raw mode.
bool ParsingPreprocessorDirective
True when parsing #XXX; turns '\n' into a tok::eod token.
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.
void HandlePragmaPushMacro(Token &Tok)
Handle #pragma push_macro.
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
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.
SourceRange DiscardUntilEndOfDirective()
Read and discard all tokens remaining on the current line until the tok::eod token is found.
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.
SourceLocation CheckEndOfDirective(const char *DirType, bool EnableMacros=false)
Ensure that the next token is a tok::eod token.
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'.
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
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
bool isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID, bool IsFileEntry, bool IsFileExit, SrcMgr::CharacteristicKind FileKind)
Add a line note to the line table for the FileID and offset specified by Loc.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
unsigned getLineTableFilenameID(StringRef Str)
Return the uniqued ID for the specified filename.
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.
bool isNot(tok::TokenKind K) const
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix.
void setAnnotationRange(SourceRange R)
void startToken()
Reset all flags to cleared.
StringRef getRawIdentifier() const
getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode),...
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),...
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).
The JSON file list parser is used to communicate input to InstallAPI.
std::optional< diag::Group > diagGroupFromCLWarningID(unsigned)
For cl.exe warning IDs that cleany map to clang diagnostic groups, returns the corresponding group.
@ Result
The result type of a method or function.
@ 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...
const FunctionProtoType * T
Describes how and where the pragma was introduced.
PragmaIntroducerKind Kind