37#include "llvm/ADT/ArrayRef.h"
38#include "llvm/ADT/DenseMap.h"
39#include "llvm/ADT/STLExtras.h"
40#include "llvm/ADT/SmallString.h"
41#include "llvm/ADT/SmallVector.h"
42#include "llvm/ADT/StringRef.h"
43#include "llvm/Support/Compiler.h"
44#include "llvm/Support/ErrorHandling.h"
45#include "llvm/Support/Timer.h"
80 bool IgnoreNull)
const {
81 auto I = Handlers.find(Name);
82 if (I != Handlers.end())
83 return I->getValue().get();
86 I = Handlers.find(StringRef());
87 if (I != Handlers.end())
88 return I->getValue().get();
93 assert(!Handlers.count(Handler->
getName()) &&
94 "A handler with this name is already registered in this namespace");
95 Handlers[Handler->
getName()].reset(Handler);
99 auto I = Handlers.find(Handler->
getName());
100 assert(I != Handlers.end() &&
101 "Handler not registered in this namespace");
103 I->getValue().release();
119 PP.
Diag(Tok, diag::warn_pragma_ignored);
135struct TokenCollector {
143 Tokens.push_back(Tok);
148 assert(Collect &&
"did not collect tokens");
149 assert(!Tokens.empty() &&
"collected unexpected number of tokens");
152 auto Toks = std::make_unique<Token[]>(Tokens.size());
153 std::copy(Tokens.begin() + 1, Tokens.end(), Toks.get());
154 Toks[Tokens.size() - 1] = Tok;
155 Self.EnterTokenStream(std::move(Toks), Tokens.size(),
160 Tok = *Tokens.begin();
169 Callbacks->PragmaDirective(Introducer.
Loc, Introducer.
Kind);
178 PragmaHandlers->HandlePragma(*
this, Introducer, Tok);
181 if ((CurTokenLexer && CurTokenLexer->isParsingPreprocessorDirective())
189void Preprocessor::Handle_Pragma(
Token &Tok) {
210 TokenCollector Toks = {*
this, InMacroArgPreExpansion, {}, Tok};
217 if (Tok.
isNot(tok::l_paren)) {
218 Diag(PragmaLoc, diag::err__Pragma_malformed);
225 Diag(PragmaLoc, diag::err__Pragma_malformed);
227 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::eof))
229 while (Tok.
isNot(tok::r_paren) &&
233 if (Tok.
is(tok::r_paren))
239 Diag(Tok, diag::err_invalid_string_udl);
242 if (Tok.
is(tok::r_paren))
252 if (Tok.
isNot(tok::r_paren)) {
253 Diag(PragmaLoc, diag::err__Pragma_malformed);
258 if (InMacroArgPreExpansion) {
269 Diag(PragmaLoc, diag::err__Pragma_malformed);
273 assert(StrValRef.size() <= StrVal.size());
276 if (StrValRef.begin() != StrVal.begin())
277 StrVal.assign(StrValRef);
279 else if (StrValRef.size() != StrVal.size())
280 StrVal.resize(StrValRef.size());
295 StrVal.size(), *
this);
297 EnterSourceFileWithLexer(TL,
nullptr);
307 if (StrVal[0] ==
'L' || StrVal[0] ==
'U' ||
308 (StrVal[0] ==
'u' && StrVal[1] !=
'8'))
309 StrVal.erase(StrVal.begin());
310 else if (StrVal[0] ==
'u')
311 StrVal.erase(StrVal.begin(), StrVal.begin() + 2);
313 if (StrVal[0] ==
'R') {
316 assert(StrVal[1] ==
'"' && StrVal[StrVal.size() - 1] ==
'"' &&
317 "Invalid raw string token!");
320 unsigned NumDChars = 0;
321 while (StrVal[2 + NumDChars] !=
'(') {
322 assert(NumDChars < (StrVal.size() - 5) / 2 &&
323 "Invalid raw string token!");
326 assert(StrVal[StrVal.size() - 2 - NumDChars] ==
')');
330 StrVal.erase(StrVal.begin(), StrVal.begin() + 2 + NumDChars);
331 StrVal.erase(StrVal.end() - 1 - NumDChars, StrVal.end());
333 assert(StrVal[0] ==
'"' && StrVal[StrVal.size()-1] ==
'"' &&
334 "Invalid string token!");
337 unsigned ResultPos = 1;
338 for (
size_t i = 1, e = StrVal.size() - 1; i != e; ++i) {
340 if (StrVal[i] ==
'\\' && i + 1 < e &&
341 (StrVal[i + 1] ==
'\\' || StrVal[i + 1] ==
'"'))
343 StrVal[ResultPos++] = StrVal[i];
345 StrVal.erase(StrVal.begin() + ResultPos, StrVal.end() - 1);
353 StrVal[StrVal.size() - 1] =
'\n';
358void Preprocessor::HandleMicrosoft__pragma(
Token &Tok) {
361 TokenCollector Toks = {*
this, InMacroArgPreExpansion, {}, Tok};
368 if (Tok.
isNot(tok::l_paren)) {
369 Diag(PragmaLoc, diag::err__Pragma_malformed);
377 while (Tok.
isNot(tok::eof)) {
378 PragmaToks.push_back(Tok);
379 if (Tok.
is(tok::l_paren))
381 else if (Tok.
is(tok::r_paren) && NumParens-- == 0)
386 if (Tok.
is(tok::eof)) {
387 Diag(PragmaLoc, diag::err_unterminated___pragma);
392 if (InMacroArgPreExpansion) {
400 PragmaToks.back().setKind(tok::eod);
402 Token *TokArray =
new Token[PragmaToks.size()];
403 std::copy(PragmaToks.begin(), PragmaToks.end(), TokArray);
406 EnterTokenStream(TokArray, PragmaToks.size(),
true,
true,
423 Diag(OnceTok, diag::pp_pragma_once_in_main_file);
433 assert(CurPPLexer &&
"No current lexer?");
436 CurLexer->ReadToEndOfLine(&Buffer);
438 Callbacks->PragmaMark(MarkTok.
getLocation(), Buffer);
456 if (Tok.
is(tok::eod))
return;
459 if (Tok.
isNot(tok::raw_identifier)) {
460 Diag(Tok, diag::err_pp_invalid_poison);
473 Diag(Tok, diag::pp_poisoning_existing_macro);
486 Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
511 FilenameID,
false,
false,
522 if (FilenameTok.
isNot(tok::header_name)) {
544 nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr);
546 if (!SuppressIncludeNotFoundError)
547 Diag(FilenameTok, diag::err_pp_file_not_found) <<
Filename;
558 while (DependencyTok.
isNot(tok::eod)) {
564 if (!Message.empty())
565 Message.erase(Message.end()-1);
566 Diag(FilenameTok, diag::pp_out_of_date_dependency) << Message;
574 Token PragmaTok = Tok;
578 if (Tok.
isNot(tok::l_paren)) {
579 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
586 if (Tok.
isNot(tok::string_literal)) {
587 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
593 Diag(Tok, diag::err_invalid_string_udl);
602 if (Tok.
isNot(tok::r_paren)) {
603 Diag(PragmaTok.
getLocation(), diag::err_pragma_push_pop_macro_malformed)
608 assert(StrVal[0] ==
'"' && StrVal[StrVal.size()-1] ==
'"' &&
609 "Invalid string token!");
614 MacroTok.
setKind(tok::raw_identifier);
615 CreateString(StringRef(&StrVal[1], StrVal.size() - 2), MacroTok);
630 if (!IdentInfo)
return;
641 PragmaPushMacroInfo[IdentInfo].push_back(MI);
655 if (!IdentInfo)
return;
658 llvm::DenseMap<IdentifierInfo *, std::vector<MacroInfo *>>::iterator iter =
659 PragmaPushMacroInfo.find(IdentInfo);
660 if (iter != PragmaPushMacroInfo.end()) {
663 if (MI->isWarnIfUnused())
664 WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
669 MacroInfo *MacroToReInstall = iter->second.back();
671 if (MacroToReInstall)
676 iter->second.pop_back();
677 if (iter->second.empty())
678 PragmaPushMacroInfo.erase(iter);
680 Diag(MessageLoc, diag::warn_pragma_pop_macro_no_push)
693 if (Tok.
isNot(tok::l_paren)) {
694 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
"(";
699 Token SourceFilenameTok;
703 StringRef SourceFileName;
705 if (SourceFilenameTok.
is(tok::header_name)) {
706 SourceFileName =
getSpelling(SourceFilenameTok, FileNameBuffer);
708 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
711 FileNameBuffer.clear();
715 if (Tok.
isNot(tok::comma)) {
716 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
",";
720 Token ReplaceFilenameTok;
724 StringRef ReplaceFileName;
725 if (ReplaceFilenameTok.
is(tok::header_name)) {
726 ReplaceFileName =
getSpelling(ReplaceFilenameTok, FileNameBuffer);
728 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
734 if (Tok.
isNot(tok::r_paren)) {
735 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
")";
741 StringRef OriginalSource = SourceFileName;
743 bool SourceIsAngled =
746 bool ReplaceIsAngled =
749 if (!SourceFileName.empty() && !ReplaceFileName.empty() &&
750 (SourceIsAngled != ReplaceIsAngled)) {
753 DiagID = diag::warn_pragma_include_alias_mismatch_angle;
755 DiagID = diag::warn_pragma_include_alias_mismatch_quote;
772 std::pair<IdentifierInfo *, SourceLocation> &ModuleNameComponent,
777 if (Literal.hadError)
779 ModuleNameComponent = std::make_pair(
782 ModuleNameComponent =
796 std::pair<IdentifierInfo*, SourceLocation> NameComponent;
799 ModuleName.push_back(NameComponent);
802 if (Tok.
isNot(tok::period))
810 std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc;
816 if (Tok.
isNot(tok::eod)) {
817 Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
821 CurLexer->LexingRawMode =
true;
823 auto TryConsumeIdentifier = [&](StringRef Ident) ->
bool {
824 if (Tok.
getKind() != tok::raw_identifier ||
832 const char *Start = CurLexer->getBufferLocation();
833 const char *End =
nullptr;
834 unsigned NestingLevel = 1;
836 End = CurLexer->getBufferLocation();
839 if (Tok.
is(tok::eof)) {
840 Diag(
Loc, diag::err_pp_module_build_missing_end);
851 CurLexer->ParsingPreprocessorDirective =
true;
853 if (TryConsumeIdentifier(
"pragma") && TryConsumeIdentifier(
"clang") &&
854 TryConsumeIdentifier(
"module")) {
855 if (TryConsumeIdentifier(
"build"))
858 else if (TryConsumeIdentifier(
"endbuild")) {
860 if (--NestingLevel == 0)
865 assert(Tok.
getKind() != tok::eof &&
"missing EOD before EOF");
869 CurLexer->LexingRawMode =
false;
872 assert(CurLexer->getBuffer().begin() <= Start &&
873 Start <= CurLexer->getBuffer().end() &&
874 CurLexer->getBuffer().begin() <= End &&
875 End <= CurLexer->getBuffer().end() &&
876 "module source range not contained within same file buffer");
878 StringRef(Start, End - Start));
883 if (Tok.
is(tok::l_paren)) {
890 if (Tok.
isNot(tok::r_paren)) {
891 Diag(Tok, diag::err_expected) << tok::r_paren;
896 if (Tok.
isNot(tok::eod))
902 assert(CurLexer &&
"no lexer for #pragma hdrstop processing");
905 CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
906 CurLexer->cutOffLexing();
909 SkippingUntilPragmaHdrStop =
false;
920 if (!Namespace.empty()) {
924 if (
PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace)) {
926 assert(InsertNS !=
nullptr &&
"Cannot have a pragma namespace and pragma"
927 " handler with the same name!");
932 PragmaHandlers->AddPragma(InsertNS);
938 "Pragma handler already exists for this identifier!");
951 if (!Namespace.empty()) {
952 PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace);
953 assert(Existing &&
"Namespace containing handler does not exist!");
956 assert(NS &&
"Invalid namespace, registered as a regular pragma handler!");
962 if (NS != PragmaHandlers.get() && NS->
IsEmpty()) {
963 PragmaHandlers->RemovePragmaHandler(NS);
972 if (Tok.
isNot(tok::identifier)) {
973 Diag(Tok, diag::ext_on_off_switch_syntax);
979 else if (II->
isStr(
"OFF"))
981 else if (II->
isStr(
"DEFAULT"))
984 Diag(Tok, diag::ext_on_off_switch_syntax);
990 if (Tok.
isNot(tok::eod))
991 Diag(Tok, diag::ext_pragma_syntax_eod);
1002 Token &OnceTok)
override {
1014 Token &MarkTok)
override {
1024 Token &PoisonTok)
override {
1032 PragmaSystemHeaderHandler() :
PragmaHandler(
"system_header") {}
1035 Token &SHToken)
override {
1045 Token &DepToken)
override {
1054 Token &DebugToken)
override {
1057 if (Tok.
isNot(tok::identifier)) {
1058 PP.
Diag(Tok, diag::warn_pragma_debug_missing_command);
1063 if (II->
isStr(
"assert")) {
1065 llvm_unreachable(
"This is an assertion!");
1066 }
else if (II->
isStr(
"crash")) {
1067 llvm::Timer
T(
"crash",
"pragma crash");
1068 llvm::TimeRegion R(&
T);
1071 }
else if (II->
isStr(
"parser_crash")) {
1075 Crasher.
setKind(tok::annot_pragma_parser_crash);
1079 }
else if (II->
isStr(
"dump")) {
1082 DumpAnnot.
setKind(tok::annot_pragma_dump);
1085 }
else if (II->
isStr(
"diag_mapping")) {
1088 if (DiagName.
is(tok::eod))
1090 else if (DiagName.
is(tok::string_literal) && !DiagName.
hasUDSuffix()) {
1092 StringLiteralEvalMethod::Unevaluated);
1097 PP.
Diag(DiagName, diag::warn_pragma_debug_missing_argument)
1100 }
else if (II->
isStr(
"llvm_fatal_error")) {
1102 llvm::report_fatal_error(
"#pragma clang __debug llvm_fatal_error");
1103 }
else if (II->
isStr(
"llvm_unreachable")) {
1105 llvm_unreachable(
"#pragma clang __debug llvm_unreachable");
1106 }
else if (II->
isStr(
"macro")) {
1113 PP.
Diag(MacroName, diag::warn_pragma_debug_missing_argument)
1115 }
else if (II->
isStr(
"module_map")) {
1122 for (
auto IIAndLoc : ModuleName) {
1125 PP.
Diag(IIAndLoc.second, diag::warn_pragma_debug_unknown_module)
1131 }
else if (II->
isStr(
"overflow_stack")) {
1133 DebugOverflowStack();
1134 }
else if (II->
isStr(
"captured")) {
1136 }
else if (II->
isStr(
"modules")) {
1137 struct ModuleVisitor {
1139 void visit(
Module *M,
bool VisibleOnly) {
1141 if (!VisibleOnly || ImportLoc.
isValid()) {
1144 llvm::errs() << M <<
" visible ";
1147 llvm::errs() <<
"\n";
1150 if (!VisibleOnly || ImportLoc.
isInvalid() ||
Sub->IsExplicit)
1151 visit(Sub, VisibleOnly);
1154 void visitAll(
bool VisibleOnly) {
1155 for (
auto &NameAndMod :
1157 visit(NameAndMod.second, VisibleOnly);
1163 auto *DumpII =
Kind.getIdentifierInfo();
1165 PP.
Diag(
Kind, diag::warn_pragma_debug_missing_argument)
1167 }
else if (DumpII->isStr(
"all")) {
1168 Visitor.visitAll(
false);
1169 }
else if (DumpII->isStr(
"visible")) {
1170 Visitor.visitAll(
true);
1171 }
else if (DumpII->isStr(
"building")) {
1173 llvm::errs() <<
"in " << Building.M->getFullModuleName();
1174 if (Building.ImportLoc.isValid()) {
1175 llvm::errs() <<
" imported ";
1176 if (Building.IsPragma)
1177 llvm::errs() <<
"via pragma ";
1178 llvm::errs() <<
"at ";
1180 llvm::errs() <<
"\n";
1184 PP.
Diag(Tok, diag::warn_pragma_debug_unexpected_command)
1185 << DumpII->getName();
1187 }
else if (II->
isStr(
"sloc_usage")) {
1190 std::optional<unsigned> MaxNotes;
1194 if (ArgToken.
is(tok::numeric_constant) &&
1197 }
else if (ArgToken.
isNot(tok::eod)) {
1198 PP.
Diag(ArgToken, diag::warn_pragma_debug_unexpected_argument);
1201 PP.
Diag(Tok, diag::remark_sloc_usage);
1205 PP.
Diag(Tok, diag::warn_pragma_debug_unexpected_command)
1218 if (Tok.
isNot(tok::eod)) {
1219 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol)
1220 <<
"pragma clang __debug captured";
1227 Toks[0].startToken();
1228 Toks[0].setKind(tok::annot_pragma_captured);
1229 Toks[0].setLocation(NameLoc);
1231 PP.EnterTokenStream(Toks,
true,
1237 #pragma warning(disable : 4717)
1239 static void DebugOverflowStack(
void (*
P)() =
nullptr) {
1240 void (*
volatile Self)(void(*
P)()) = DebugOverflowStack;
1241 Self(
reinterpret_cast<void(*)()
>(Self));
1244 #pragma warning(default : 4717)
1248struct PragmaUnsafeBufferUsageHandler :
public PragmaHandler {
1249 PragmaUnsafeBufferUsageHandler() :
PragmaHandler(
"unsafe_buffer_usage") {}
1251 Token &FirstToken)
override {
1255 if (Tok.
isNot(tok::identifier)) {
1256 PP.
Diag(Tok, diag::err_pp_pragma_unsafe_buffer_usage_syntax);
1263 if (II->
isStr(
"begin")) {
1265 PP.
Diag(
Loc, diag::err_pp_double_begin_pragma_unsafe_buffer_usage);
1266 }
else if (II->
isStr(
"end")) {
1268 PP.
Diag(
Loc, diag::err_pp_unmatched_end_begin_pragma_unsafe_buffer_usage);
1270 PP.
Diag(Tok, diag::err_pp_pragma_unsafe_buffer_usage_syntax);
1280 explicit PragmaDiagnosticHandler(
const char *NS)
1284 Token &DiagToken)
override {
1288 if (Tok.
isNot(tok::identifier)) {
1289 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1299 if (II->
isStr(
"pop")) {
1301 PP.
Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
1305 if (Tok.
isNot(tok::eod))
1306 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_diagnostic_invalid_token);
1308 }
else if (II->
isStr(
"push")) {
1313 if (Tok.
isNot(tok::eod))
1314 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_diagnostic_invalid_token);
1319 .Case(
"ignored", diag::Severity::Ignored)
1320 .Case(
"warning", diag::Severity::Warning)
1321 .Case(
"error", diag::Severity::Error)
1322 .Case(
"fatal", diag::Severity::Fatal)
1326 PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1332 std::string WarningName;
1337 if (Tok.
isNot(tok::eod)) {
1338 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_diagnostic_invalid_token);
1342 if (WarningName.size() < 3 || WarningName[0] !=
'-' ||
1343 (WarningName[1] !=
'W' && WarningName[1] !=
'R')) {
1344 PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_invalid_option);
1349 : diag::Flavor::Remark;
1350 StringRef
Group = StringRef(WarningName).substr(2);
1351 bool unknownDiag =
false;
1352 if (Group ==
"everything") {
1361 PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_unknown_warning)
1372 Token &DepToken)
override {
1384 Token &Tok)
override {
1393 if (Tok.
isNot(tok::l_paren)) {
1394 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
"(";
1401 if (II && II->
isStr(
"push")) {
1405 if (Tok.
is(tok::comma)) {
1408 if (Tok.
is(tok::numeric_constant) &&
1411 if (Level < 0 || Level > 4) {
1412 PP.
Diag(Tok, diag::warn_pragma_warning_push_level);
1419 }
else if (II && II->
isStr(
"pop")) {
1423 PP.
Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
1431 if (!II && !Tok.
is(tok::numeric_constant)) {
1432 PP.
Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1437 bool SpecifierValid;
1440 int SpecifierInt = llvm::StringSwitch<int>(II->
getName())
1447 SpecifierValid = SpecifierInt != -1;
1460 if ((SpecifierValid = (
Value >= 1) && (
Value <= 4)))
1464 SpecifierValid =
false;
1468 if (!SpecifierValid) {
1469 PP.
Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1472 if (Tok.
isNot(tok::colon)) {
1473 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
":";
1480 while (Tok.
is(tok::numeric_constant)) {
1484 PP.
Diag(Tok, diag::warn_pragma_warning_expected_number);
1487 Ids.push_back(
int(
Value));
1493 SV = diag::Severity::Ignored;
1495 for (
int Id : Ids) {
1498 diag::Flavor::WarningOrError, *Group, SV, DiagLoc);
1499 assert(!unknownDiag &&
1500 "wd table should only contain known diags");
1509 if (Tok.
isNot(tok::semi))
1515 if (Tok.
isNot(tok::r_paren)) {
1516 PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
")";
1521 if (Tok.
isNot(tok::eod))
1522 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma warning";
1530 PragmaExecCharsetHandler() :
PragmaHandler(
"execution_character_set") {}
1533 Token &Tok)
override {
1541 if (Tok.
isNot(tok::l_paren)) {
1542 PP.
Diag(Tok, diag::warn_pragma_exec_charset_expected) <<
"(";
1549 if (II && II->
isStr(
"push")) {
1552 if (Tok.
is(tok::comma)) {
1555 std::string ExecCharset;
1557 "pragma execution_character_set",
1562 if (ExecCharset !=
"UTF-8" && ExecCharset !=
"utf-8") {
1563 PP.
Diag(Tok, diag::warn_pragma_exec_charset_push_invalid) << ExecCharset;
1569 }
else if (II && II->
isStr(
"pop")) {
1575 PP.
Diag(Tok, diag::warn_pragma_exec_charset_spec_invalid);
1579 if (Tok.
isNot(tok::r_paren)) {
1580 PP.
Diag(Tok, diag::warn_pragma_exec_charset_expected) <<
")";
1585 if (Tok.
isNot(tok::eod))
1586 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma execution_character_set";
1592 PragmaIncludeAliasHandler() :
PragmaHandler(
"include_alias") {}
1595 Token &IncludeAliasTok)
override {
1619 bool PragmaNameOnly =
false) {
1622 return PragmaNameOnly ?
"message" :
"pragma message";
1624 return PragmaNameOnly ?
"warning" :
"pragma warning";
1626 return PragmaNameOnly ?
"error" :
"pragma error";
1628 llvm_unreachable(
"Unknown PragmaMessageKind!");
1633 StringRef Namespace = StringRef())
1638 Token &Tok)
override {
1641 bool ExpectClosingParen =
false;
1645 ExpectClosingParen =
true;
1649 case tok::string_literal:
1653 PP.
Diag(MessageLoc, diag::err_pragma_message_malformed) <<
Kind;
1657 std::string MessageString;
1662 if (ExpectClosingParen) {
1663 if (Tok.
isNot(tok::r_paren)) {
1670 if (Tok.
isNot(tok::eod)) {
1677 ? diag::err_pragma_message
1678 : diag::warn_pragma_message) << MessageString;
1694 Token &Tok)
override {
1703 if (Tok.
isNot(tok::eod))
1704 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1715 tok::annot_module_include, Imported);
1717 CB->moduleImport(ImportLoc, ModuleName, Imported);
1731 Token &Tok)
override {
1740 if (Tok.
isNot(tok::eod))
1741 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1745 if (ModuleName.front().first->getName() != Current) {
1746 PP.
Diag(ModuleName.front().second, diag::err_pp_module_begin_wrong_module)
1747 << ModuleName.front().first << (ModuleName.size() > 1)
1748 << Current.empty() << Current;
1755 Module *M = HSI.lookupModule(Current, ModuleName.front().second);
1757 PP.
Diag(ModuleName.front().second,
1758 diag::err_pp_module_begin_no_module_map) << Current;
1761 for (
unsigned I = 1; I != ModuleName.size(); ++I) {
1764 PP.
Diag(ModuleName[I].second, diag::err_pp_module_begin_no_submodule)
1774 PP.
Diag(BeginLoc, diag::note_pp_module_begin_here)
1782 tok::annot_module_begin, M);
1791 Token &Tok)
override {
1795 if (Tok.
isNot(tok::eod))
1796 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1802 PP.
Diag(
Loc, diag::err_pp_module_end_without_module_begin);
1811 Token &Tok)
override {
1821 Token &Tok)
override {
1830 if (Tok.
isNot(tok::eod))
1831 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1845 Token &PushMacroTok)
override {
1856 Token &PopMacroTok)
override {
1863struct PragmaARCCFCodeAuditedHandler :
public PragmaHandler {
1864 PragmaARCCFCodeAuditedHandler() :
PragmaHandler(
"arc_cf_code_audited") {}
1867 Token &NameTok)
override {
1876 if (BeginEnd && BeginEnd->
isStr(
"begin")) {
1878 }
else if (BeginEnd && BeginEnd->
isStr(
"end")) {
1887 if (Tok.
isNot(tok::eod))
1888 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1899 PP.
Diag(
Loc, diag::err_pp_double_begin_of_arc_cf_code_audited);
1900 PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1906 PP.
Diag(
Loc, diag::err_pp_unmatched_end_of_arc_cf_code_audited);
1919 PragmaAssumeNonNullHandler() :
PragmaHandler(
"assume_nonnull") {}
1922 Token &NameTok)
override {
1931 if (BeginEnd && BeginEnd->
isStr(
"begin")) {
1933 }
else if (BeginEnd && BeginEnd->
isStr(
"end")) {
1942 if (Tok.
isNot(tok::eod))
1943 PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1955 PP.
Diag(
Loc, diag::err_pp_double_begin_of_assume_nonnull);
1956 PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1964 PP.
Diag(
Loc, diag::err_pp_unmatched_end_of_assume_nonnull);
1988 PragmaRegionHandler(
const char *pragma) :
PragmaHandler(pragma) {}
1991 Token &NameTok)
override {
2011 std::string &MessageString) {
2013 if (Tok.
isNot(tok::l_paren)) {
2014 PP.
Diag(Tok, diag::err_expected) <<
"(";
2019 if (!Tok.
is(tok::identifier)) {
2020 PP.
Diag(Tok, diag::err_expected) << tok::identifier;
2026 PP.
Diag(Tok, diag::err_pp_visibility_non_macro) << II;
2031 if (Tok.
is(tok::comma)) {
2038 if (Tok.
isNot(tok::r_paren)) {
2039 PP.
Diag(Tok, diag::err_expected) <<
")";
2055 Token &Tok)
override {
2056 std::string MessageString;
2059 PP, Tok,
"#pragma clang deprecated", MessageString)) {
2073struct PragmaRestrictExpansionHandler :
public PragmaHandler {
2074 PragmaRestrictExpansionHandler() :
PragmaHandler(
"restrict_expansion") {}
2077 Token &Tok)
override {
2078 std::string MessageString;
2081 PP, Tok,
"#pragma clang restrict_expansion", MessageString)) {
2099 Token &Tok)
override {
2101 if (Tok.
isNot(tok::l_paren)) {
2102 PP.
Diag(Tok, diag::err_expected) <<
"(";
2107 if (!Tok.
is(tok::identifier)) {
2108 PP.
Diag(Tok, diag::err_expected) << tok::identifier;
2114 PP.
Diag(Tok, diag::err_pp_visibility_non_macro) << II;
2119 if (Tok.
isNot(tok::r_paren)) {
2120 PP.
Diag(Tok, diag::err_expected) <<
")";
2132void Preprocessor::RegisterBuiltinPragmas() {
2163 ModuleHandler->AddPragma(
new PragmaModuleImportHandler());
2164 ModuleHandler->AddPragma(
new PragmaModuleBeginHandler());
2165 ModuleHandler->AddPragma(
new PragmaModuleEndHandler());
2166 ModuleHandler->AddPragma(
new PragmaModuleBuildHandler());
2167 ModuleHandler->AddPragma(
new PragmaModuleLoadHandler());
2177 if (LangOpts.MicrosoftExt) {
2188 for (
const PragmaHandlerRegistry::entry &handler :
2189 PragmaHandlerRegistry::entries()) {
Defines the Diagnostic-related interfaces.
enum clang::sema::@1655::IndirectLocalPathEntry::EntryKind Kind
Defines the clang::FileManager interface and associated types.
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.
llvm::iterator_range< module_iterator > modules() const
Describes a module or submodule.
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
Module * findOrInferSubmodule(StringRef Name)
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