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))
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);
598 if (Tok.
isNot(tok::r_paren)) {
599 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
604 assert(StrVal[0] ==
'"' && StrVal[StrVal.size()-1] ==
'"' &&
605 "Invalid string token!");
610 MacroTok.
setKind(tok::raw_identifier);
611 CreateString(StringRef(&StrVal[1], StrVal.size() - 2), MacroTok);
626 if (!IdentInfo)
return;
637 PragmaPushMacroInfo[IdentInfo].push_back(MI);
651 if (!IdentInfo)
return;
654 llvm::DenseMap<IdentifierInfo *, std::vector<MacroInfo *>>::iterator iter =
655 PragmaPushMacroInfo.find(IdentInfo);
656 if (iter != PragmaPushMacroInfo.end()) {
659 if (MI->isWarnIfUnused())
660 WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
665 MacroInfo *MacroToReInstall = iter->second.back();
667 if (MacroToReInstall)
672 iter->second.pop_back();
673 if (iter->second.empty())
674 PragmaPushMacroInfo.erase(iter);
676 Diag(MessageLoc, diag::warn_pragma_pop_macro_no_push)
689 if (Tok.
isNot(tok::l_paren)) {
690 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
"(";
695 Token SourceFilenameTok;
699 StringRef SourceFileName;
701 if (SourceFilenameTok.
is(tok::header_name)) {
702 SourceFileName =
getSpelling(SourceFilenameTok, FileNameBuffer);
704 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
707 FileNameBuffer.clear();
711 if (Tok.
isNot(tok::comma)) {
712 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
",";
716 Token ReplaceFilenameTok;
720 StringRef ReplaceFileName;
721 if (ReplaceFilenameTok.
is(tok::header_name)) {
722 ReplaceFileName =
getSpelling(ReplaceFilenameTok, FileNameBuffer);
724 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
730 if (Tok.
isNot(tok::r_paren)) {
731 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
")";
737 StringRef OriginalSource = SourceFileName;
739 bool SourceIsAngled =
742 bool ReplaceIsAngled =
745 if (!SourceFileName.empty() && !ReplaceFileName.empty() &&
746 (SourceIsAngled != ReplaceIsAngled)) {
749 DiagID = diag::warn_pragma_include_alias_mismatch_angle;
751 DiagID = diag::warn_pragma_include_alias_mismatch_quote;
768 std::pair<IdentifierInfo *, SourceLocation> &ModuleNameComponent,
773 if (Literal.hadError)
775 ModuleNameComponent = std::make_pair(
778 ModuleNameComponent =
792 std::pair<IdentifierInfo*, SourceLocation> NameComponent;
795 ModuleName.push_back(NameComponent);
798 if (Tok.
isNot(tok::period))
806 std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc;
812 if (Tok.
isNot(tok::eod)) {
813 Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
817 CurLexer->LexingRawMode =
true;
819 auto TryConsumeIdentifier = [&](StringRef Ident) ->
bool {
820 if (Tok.
getKind() != tok::raw_identifier ||
828 const char *Start = CurLexer->getBufferLocation();
829 const char *End =
nullptr;
830 unsigned NestingLevel = 1;
832 End = CurLexer->getBufferLocation();
835 if (Tok.
is(tok::eof)) {
836 Diag(
Loc, diag::err_pp_module_build_missing_end);
847 CurLexer->ParsingPreprocessorDirective =
true;
849 if (TryConsumeIdentifier(
"pragma") && TryConsumeIdentifier(
"clang") &&
850 TryConsumeIdentifier(
"module")) {
851 if (TryConsumeIdentifier(
"build"))
854 else if (TryConsumeIdentifier(
"endbuild")) {
856 if (--NestingLevel == 0)
861 assert(Tok.
getKind() != tok::eof &&
"missing EOD before EOF");
865 CurLexer->LexingRawMode =
false;
868 assert(CurLexer->getBuffer().begin() <= Start &&
869 Start <= CurLexer->getBuffer().end() &&
870 CurLexer->getBuffer().begin() <= End &&
871 End <= CurLexer->getBuffer().end() &&
872 "module source range not contained within same file buffer");
874 StringRef(Start, End - Start));
879 if (Tok.
is(tok::l_paren)) {
886 if (Tok.
isNot(tok::r_paren)) {
887 Diag(Tok, diag::err_expected) << tok::r_paren;
892 if (Tok.
isNot(tok::eod))
898 assert(CurLexer &&
"no lexer for #pragma hdrstop processing");
901 CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
902 CurLexer->cutOffLexing();
905 SkippingUntilPragmaHdrStop =
false;
916 if (!Namespace.empty()) {
920 if (
PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace)) {
922 assert(InsertNS !=
nullptr &&
"Cannot have a pragma namespace and pragma"
923 " handler with the same name!");
928 PragmaHandlers->AddPragma(InsertNS);
934 "Pragma handler already exists for this identifier!");
947 if (!Namespace.empty()) {
948 PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace);
949 assert(Existing &&
"Namespace containing handler does not exist!");
952 assert(NS &&
"Invalid namespace, registered as a regular pragma handler!");
958 if (NS != PragmaHandlers.get() && NS->
IsEmpty()) {
959 PragmaHandlers->RemovePragmaHandler(NS);
968 if (Tok.
isNot(tok::identifier)) {
969 Diag(Tok, diag::ext_on_off_switch_syntax);
975 else if (II->
isStr(
"OFF"))
977 else if (II->
isStr(
"DEFAULT"))
980 Diag(Tok, diag::ext_on_off_switch_syntax);
986 if (Tok.
isNot(tok::eod))
987 Diag(Tok, diag::ext_pragma_syntax_eod);
998 Token &OnceTok)
override {
1010 Token &MarkTok)
override {
1020 Token &PoisonTok)
override {
1028 PragmaSystemHeaderHandler() :
PragmaHandler(
"system_header") {}
1031 Token &SHToken)
override {
1041 Token &DepToken)
override {
1050 Token &DebugToken)
override {
1053 if (Tok.
isNot(tok::identifier)) {
1054 PP.
Diag(Tok, diag::warn_pragma_debug_missing_command);
1059 if (II->
isStr(
"assert")) {
1061 llvm_unreachable(
"This is an assertion!");
1062 }
else if (II->
isStr(
"crash")) {
1063 llvm::Timer
T(
"crash",
"pragma crash");
1064 llvm::TimeRegion R(&
T);
1067 }
else if (II->
isStr(
"parser_crash")) {
1071 Crasher.
setKind(tok::annot_pragma_parser_crash);
1075 }
else if (II->
isStr(
"dump")) {
1078 DumpAnnot.
setKind(tok::annot_pragma_dump);
1081 }
else if (II->
isStr(
"diag_mapping")) {
1084 if (DiagName.
is(tok::eod))
1086 else if (DiagName.
is(tok::string_literal) && !DiagName.
hasUDSuffix()) {
1088 StringLiteralEvalMethod::Unevaluated);
1093 PP.
Diag(DiagName, diag::warn_pragma_debug_missing_argument)
1096 }
else if (II->
isStr(
"llvm_fatal_error")) {
1098 llvm::report_fatal_error(
"#pragma clang __debug llvm_fatal_error");
1099 }
else if (II->
isStr(
"llvm_unreachable")) {
1101 llvm_unreachable(
"#pragma clang __debug llvm_unreachable");
1102 }
else if (II->
isStr(
"macro")) {
1109 PP.
Diag(MacroName, diag::warn_pragma_debug_missing_argument)
1111 }
else if (II->
isStr(
"module_map")) {
1118 for (
auto IIAndLoc : ModuleName) {
1121 PP.
Diag(IIAndLoc.second, diag::warn_pragma_debug_unknown_module)
1127 }
else if (II->
isStr(
"overflow_stack")) {
1129 DebugOverflowStack();
1130 }
else if (II->
isStr(
"captured")) {
1132 }
else if (II->
isStr(
"modules")) {
1133 struct ModuleVisitor {
1135 void visit(
Module *M,
bool VisibleOnly) {
1137 if (!VisibleOnly || ImportLoc.
isValid()) {
1140 llvm::errs() << M <<
" visible ";
1143 llvm::errs() <<
"\n";
1146 if (!VisibleOnly || ImportLoc.
isInvalid() ||
Sub->IsExplicit)
1147 visit(Sub, VisibleOnly);
1150 void visitAll(
bool VisibleOnly) {
1151 for (
auto &NameAndMod :
1153 visit(NameAndMod.second, VisibleOnly);
1159 auto *DumpII =
Kind.getIdentifierInfo();
1161 PP.
Diag(
Kind, diag::warn_pragma_debug_missing_argument)
1163 }
else if (DumpII->isStr(
"all")) {
1164 Visitor.visitAll(
false);
1165 }
else if (DumpII->isStr(
"visible")) {
1166 Visitor.visitAll(
true);
1167 }
else if (DumpII->isStr(
"building")) {
1169 llvm::errs() <<
"in " << Building.M->getFullModuleName();
1170 if (Building.ImportLoc.isValid()) {
1171 llvm::errs() <<
" imported ";
1172 if (Building.IsPragma)
1173 llvm::errs() <<
"via pragma ";
1174 llvm::errs() <<
"at ";
1176 llvm::errs() <<
"\n";
1180 PP.
Diag(Tok, diag::warn_pragma_debug_unexpected_command)
1181 << DumpII->getName();
1183 }
else if (II->
isStr(
"sloc_usage")) {
1186 std::optional<unsigned> MaxNotes;
1190 if (ArgToken.
is(tok::numeric_constant) &&
1193 }
else if (ArgToken.
isNot(tok::eod)) {
1194 PP.
Diag(ArgToken, diag::warn_pragma_debug_unexpected_argument);
1197 PP.
Diag(Tok, diag::remark_sloc_usage);
1201 PP.
Diag(Tok, diag::warn_pragma_debug_unexpected_command)
1214 if (Tok.
isNot(tok::eod)) {
1215 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol)
1216 <<
"pragma clang __debug captured";
1223 Toks[0].startToken();
1224 Toks[0].setKind(tok::annot_pragma_captured);
1225 Toks[0].setLocation(NameLoc);
1227 PP.EnterTokenStream(Toks,
true,
1233 #pragma warning(disable : 4717)
1235 static void DebugOverflowStack(
void (*
P)() =
nullptr) {
1236 void (*
volatile Self)(void(*
P)()) = DebugOverflowStack;
1237 Self(
reinterpret_cast<void(*)()
>(Self));
1240 #pragma warning(default : 4717)
1244struct PragmaUnsafeBufferUsageHandler :
public PragmaHandler {
1245 PragmaUnsafeBufferUsageHandler() :
PragmaHandler(
"unsafe_buffer_usage") {}
1247 Token &FirstToken)
override {
1251 if (Tok.
isNot(tok::identifier)) {
1252 PP.
Diag(Tok, diag::err_pp_pragma_unsafe_buffer_usage_syntax);
1259 if (II->
isStr(
"begin")) {
1261 PP.
Diag(
Loc, diag::err_pp_double_begin_pragma_unsafe_buffer_usage);
1262 }
else if (II->
isStr(
"end")) {
1264 PP.
Diag(
Loc, diag::err_pp_unmatched_end_begin_pragma_unsafe_buffer_usage);
1266 PP.
Diag(Tok, diag::err_pp_pragma_unsafe_buffer_usage_syntax);
1276 explicit PragmaDiagnosticHandler(
const char *NS)
1280 Token &DiagToken)
override {
1284 if (Tok.
isNot(tok::identifier)) {
1285 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1295 if (II->
isStr(
"pop")) {
1297 PP.
Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
1301 if (Tok.
isNot(tok::eod))
1302 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_diagnostic_invalid_token);
1304 }
else if (II->
isStr(
"push")) {
1309 if (Tok.
isNot(tok::eod))
1310 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_diagnostic_invalid_token);
1315 .Case(
"ignored", diag::Severity::Ignored)
1316 .Case(
"warning", diag::Severity::Warning)
1317 .Case(
"error", diag::Severity::Error)
1318 .Case(
"fatal", diag::Severity::Fatal)
1322 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1328 std::string WarningName;
1333 if (Tok.
isNot(tok::eod)) {
1334 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_diagnostic_invalid_token);
1338 if (WarningName.size() < 3 || WarningName[0] !=
'-' ||
1339 (WarningName[1] !=
'W' && WarningName[1] !=
'R')) {
1340 PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_invalid_option);
1345 : diag::Flavor::Remark;
1346 StringRef
Group = StringRef(WarningName).substr(2);
1347 bool unknownDiag =
false;
1348 if (Group ==
"everything") {
1357 PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_unknown_warning)
1368 Token &DepToken)
override {
1380 Token &Tok)
override {
1389 if (Tok.
isNot(tok::l_paren)) {
1390 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
"(";
1397 if (II && II->
isStr(
"push")) {
1401 if (Tok.
is(tok::comma)) {
1404 if (Tok.
is(tok::numeric_constant) &&
1407 if (Level < 0 || Level > 4) {
1408 PP.
Diag(Tok, diag::warn_pragma_warning_push_level);
1415 }
else if (II && II->
isStr(
"pop")) {
1419 PP.
Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
1427 if (!II && !Tok.
is(tok::numeric_constant)) {
1428 PP.
Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1433 bool SpecifierValid;
1436 int SpecifierInt = llvm::StringSwitch<int>(II->
getName())
1443 SpecifierValid = SpecifierInt != -1;
1456 if ((SpecifierValid = (
Value >= 1) && (
Value <= 4)))
1460 SpecifierValid =
false;
1464 if (!SpecifierValid) {
1465 PP.
Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1468 if (Tok.
isNot(tok::colon)) {
1469 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
":";
1476 while (Tok.
is(tok::numeric_constant)) {
1480 PP.
Diag(Tok, diag::warn_pragma_warning_expected_number);
1483 Ids.push_back(
int(
Value));
1489 SV = diag::Severity::Ignored;
1491 for (
int Id : Ids) {
1494 diag::Flavor::WarningOrError, *Group, SV, DiagLoc);
1495 assert(!unknownDiag &&
1496 "wd table should only contain known diags");
1505 if (Tok.
isNot(tok::semi))
1511 if (Tok.
isNot(tok::r_paren)) {
1512 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
")";
1517 if (Tok.
isNot(tok::eod))
1518 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma warning";
1526 PragmaExecCharsetHandler() :
PragmaHandler(
"execution_character_set") {}
1529 Token &Tok)
override {
1537 if (Tok.
isNot(tok::l_paren)) {
1538 PP.
Diag(Tok, diag::warn_pragma_exec_charset_expected) <<
"(";
1545 if (II && II->
isStr(
"push")) {
1548 if (Tok.
is(tok::comma)) {
1551 std::string ExecCharset;
1553 "pragma execution_character_set",
1558 if (ExecCharset !=
"UTF-8" && ExecCharset !=
"utf-8") {
1559 PP.
Diag(Tok, diag::warn_pragma_exec_charset_push_invalid) << ExecCharset;
1565 }
else if (II && II->
isStr(
"pop")) {
1571 PP.
Diag(Tok, diag::warn_pragma_exec_charset_spec_invalid);
1575 if (Tok.
isNot(tok::r_paren)) {
1576 PP.
Diag(Tok, diag::warn_pragma_exec_charset_expected) <<
")";
1581 if (Tok.
isNot(tok::eod))
1582 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma execution_character_set";
1588 PragmaIncludeAliasHandler() :
PragmaHandler(
"include_alias") {}
1591 Token &IncludeAliasTok)
override {
1615 bool PragmaNameOnly =
false) {
1618 return PragmaNameOnly ?
"message" :
"pragma message";
1620 return PragmaNameOnly ?
"warning" :
"pragma warning";
1622 return PragmaNameOnly ?
"error" :
"pragma error";
1624 llvm_unreachable(
"Unknown PragmaMessageKind!");
1629 StringRef Namespace = StringRef())
1634 Token &Tok)
override {
1637 bool ExpectClosingParen =
false;
1641 ExpectClosingParen =
true;
1645 case tok::string_literal:
1649 PP.
Diag(MessageLoc, diag::err_pragma_message_malformed) <<
Kind;
1653 std::string MessageString;
1658 if (ExpectClosingParen) {
1659 if (Tok.
isNot(tok::r_paren)) {
1666 if (Tok.
isNot(tok::eod)) {
1673 ? diag::err_pragma_message
1674 : diag::warn_pragma_message) << MessageString;
1690 Token &Tok)
override {
1699 if (Tok.
isNot(tok::eod))
1700 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1711 tok::annot_module_include, Imported);
1713 CB->moduleImport(ImportLoc, ModuleName, Imported);
1727 Token &Tok)
override {
1736 if (Tok.
isNot(tok::eod))
1737 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1741 if (ModuleName.front().first->getName() != Current) {
1742 PP.
Diag(ModuleName.front().second, diag::err_pp_module_begin_wrong_module)
1743 << ModuleName.front().first << (ModuleName.size() > 1)
1744 << Current.empty() << Current;
1751 auto &MM = HSI.getModuleMap();
1752 Module *M = HSI.lookupModule(Current, ModuleName.front().second);
1754 PP.
Diag(ModuleName.front().second,
1755 diag::err_pp_module_begin_no_module_map) << Current;
1758 for (
unsigned I = 1; I != ModuleName.size(); ++I) {
1761 PP.
Diag(ModuleName[I].second, diag::err_pp_module_begin_no_submodule)
1771 PP.
Diag(BeginLoc, diag::note_pp_module_begin_here)
1779 tok::annot_module_begin, M);
1788 Token &Tok)
override {
1792 if (Tok.
isNot(tok::eod))
1793 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1799 PP.
Diag(
Loc, diag::err_pp_module_end_without_module_begin);
1808 Token &Tok)
override {
1818 Token &Tok)
override {
1827 if (Tok.
isNot(tok::eod))
1828 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1842 Token &PushMacroTok)
override {
1853 Token &PopMacroTok)
override {
1860struct PragmaARCCFCodeAuditedHandler :
public PragmaHandler {
1861 PragmaARCCFCodeAuditedHandler() :
PragmaHandler(
"arc_cf_code_audited") {}
1864 Token &NameTok)
override {
1873 if (BeginEnd && BeginEnd->
isStr(
"begin")) {
1875 }
else if (BeginEnd && BeginEnd->
isStr(
"end")) {
1884 if (Tok.
isNot(tok::eod))
1885 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1896 PP.
Diag(
Loc, diag::err_pp_double_begin_of_arc_cf_code_audited);
1897 PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1903 PP.
Diag(
Loc, diag::err_pp_unmatched_end_of_arc_cf_code_audited);
1916 PragmaAssumeNonNullHandler() :
PragmaHandler(
"assume_nonnull") {}
1919 Token &NameTok)
override {
1928 if (BeginEnd && BeginEnd->
isStr(
"begin")) {
1930 }
else if (BeginEnd && BeginEnd->
isStr(
"end")) {
1939 if (Tok.
isNot(tok::eod))
1940 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1952 PP.
Diag(
Loc, diag::err_pp_double_begin_of_assume_nonnull);
1953 PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1961 PP.
Diag(
Loc, diag::err_pp_unmatched_end_of_assume_nonnull);
1985 PragmaRegionHandler(
const char *pragma) :
PragmaHandler(pragma) {}
1988 Token &NameTok)
override {
2008 std::string &MessageString) {
2010 if (Tok.
isNot(tok::l_paren)) {
2011 PP.
Diag(Tok, diag::err_expected) <<
"(";
2016 if (!Tok.
is(tok::identifier)) {
2017 PP.
Diag(Tok, diag::err_expected) << tok::identifier;
2023 PP.
Diag(Tok, diag::err_pp_visibility_non_macro) << II;
2028 if (Tok.
is(tok::comma)) {
2035 if (Tok.
isNot(tok::r_paren)) {
2036 PP.
Diag(Tok, diag::err_expected) <<
")";
2052 Token &Tok)
override {
2053 std::string MessageString;
2056 PP, Tok,
"#pragma clang deprecated", MessageString)) {
2070struct PragmaRestrictExpansionHandler :
public PragmaHandler {
2071 PragmaRestrictExpansionHandler() :
PragmaHandler(
"restrict_expansion") {}
2074 Token &Tok)
override {
2075 std::string MessageString;
2078 PP, Tok,
"#pragma clang restrict_expansion", MessageString)) {
2096 Token &Tok)
override {
2098 if (Tok.
isNot(tok::l_paren)) {
2099 PP.
Diag(Tok, diag::err_expected) <<
"(";
2104 if (!Tok.
is(tok::identifier)) {
2105 PP.
Diag(Tok, diag::err_expected) << tok::identifier;
2111 PP.
Diag(Tok, diag::err_pp_visibility_non_macro) << II;
2116 if (Tok.
isNot(tok::r_paren)) {
2117 PP.
Diag(Tok, diag::err_expected) <<
")";
2129void Preprocessor::RegisterBuiltinPragmas() {
2160 ModuleHandler->AddPragma(
new PragmaModuleImportHandler());
2161 ModuleHandler->AddPragma(
new PragmaModuleBeginHandler());
2162 ModuleHandler->AddPragma(
new PragmaModuleEndHandler());
2163 ModuleHandler->AddPragma(
new PragmaModuleBuildHandler());
2164 ModuleHandler->AddPragma(
new PragmaModuleLoadHandler());
2174 if (LangOpts.MicrosoftExt) {
2185 for (
const PragmaHandlerRegistry::entry &handler :
2186 PragmaHandlerRegistry::entries()) {
Defines the Diagnostic-related interfaces.
enum clang::sema::@1712::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< std::pair< IdentifierInfo *, SourceLocation > > &ModuleName)
static bool LexModuleNameComponent(Preprocessor &PP, Token &Tok, std::pair< IdentifierInfo *, SourceLocation > &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.
const 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.
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)
std::pair< IdentifierInfo *, SourceLocation > getPragmaARCCFCodeAuditedInfo() const
The location of the currently-active #pragma clang arc_cf_code_audited begin.
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 makeModuleVisible(Module *M, SourceLocation Loc)
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.
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.
const TargetInfo & getTargetInfo() const
bool LexHeaderName(Token &Result, bool AllowMacroExpansion=true)
Lex a token, forming a header-name token if possible.
PreprocessorOptions & getPreprocessorOpts() const
Retrieve the preprocessor options used to initialize this preprocessor.
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 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
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.
Severity
Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs to either Ignore (nothing),...
Flavor
Flavors of diagnostics we can emit.
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