;
76 boolIgnoreNull)
const{
77 autoI = Handlers.find(Name);
78 if(I != Handlers.end())
79 returnI->getValue().get();
82I = Handlers.find(StringRef());
83 if(I != Handlers.end())
84 returnI->getValue().get();
89assert(!Handlers.count(Handler->
getName()) &&
90 "A handler with this name is already registered in this namespace");
91Handlers[Handler->
getName()].reset(Handler);
95 autoI = Handlers.find(Handler->
getName());
96assert(I != Handlers.end() &&
97 "Handler not registered in this namespace");
99I->getValue().release();
115PP.
Diag(Tok, diag::warn_pragma_ignored);
131structTokenCollector {
139Tokens.push_back(Tok);
144assert(Collect &&
"did not collect tokens");
145assert(!Tokens.empty() &&
"collected unexpected number of tokens");
148 autoToks = std::make_unique<Token[]>(Tokens.size());
149std::copy(Tokens.begin() + 1, Tokens.end(), Toks.get());
150Toks[Tokens.size() - 1] = Tok;
151Self.EnterTokenStream(std::move(Toks), Tokens.size(),
156Tok = *Tokens.begin();
165Callbacks->PragmaDirective(Introducer.
Loc, Introducer.
Kind);
174PragmaHandlers->HandlePragma(*
this, Introducer, Tok);
177 if((CurTokenLexer && CurTokenLexer->isParsingPreprocessorDirective())
185voidPreprocessor::Handle_Pragma(
Token&Tok) {
206TokenCollector 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) &&
227Tok.
isNot(tok::eof))
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);
269assert(StrValRef.size() <= StrVal.size());
272 if(StrValRef.begin() != StrVal.begin())
273StrVal.assign(StrValRef);
275 else if(StrValRef.size() != StrVal.size())
276StrVal.resize(StrValRef.size());
291StrVal.size(), *
this);
293EnterSourceFileWithLexer(TL,
nullptr);
303 if(StrVal[0] ==
'L'|| StrVal[0] ==
'U'||
304(StrVal[0] ==
'u'&& StrVal[1] !=
'8'))
305StrVal.erase(StrVal.begin());
306 else if(StrVal[0] ==
'u')
307StrVal.erase(StrVal.begin(), StrVal.begin() + 2);
309 if(StrVal[0] ==
'R') {
312assert(StrVal[1] ==
'"'&& StrVal[StrVal.size() - 1] ==
'"'&&
313 "Invalid raw string token!");
316 unsignedNumDChars = 0;
317 while(StrVal[2 + NumDChars] !=
'(') {
318assert(NumDChars < (StrVal.size() - 5) / 2 &&
319 "Invalid raw string token!");
322assert(StrVal[StrVal.size() - 2 - NumDChars] ==
')');
326StrVal.erase(StrVal.begin(), StrVal.begin() + 2 + NumDChars);
327StrVal.erase(StrVal.end() - 1 - NumDChars, StrVal.end());
329assert(StrVal[0] ==
'"'&& StrVal[StrVal.size()-1] ==
'"'&&
330 "Invalid string token!");
333 unsignedResultPos = 1;
334 for(
size_ti = 1, e = StrVal.size() - 1; i != e; ++i) {
336 if(StrVal[i] ==
'\\'&& i + 1 < e &&
337(StrVal[i + 1] ==
'\\'|| StrVal[i + 1] ==
'"'))
339StrVal[ResultPos++] = StrVal[i];
341StrVal.erase(StrVal.begin() + ResultPos, StrVal.end() - 1);
349StrVal[StrVal.size() - 1] =
'\n';
354voidPreprocessor::HandleMicrosoft__pragma(
Token&Tok) {
357TokenCollector Toks = {*
this, InMacroArgPreExpansion, {}, Tok};
364 if(Tok.
isNot(tok::l_paren)) {
365 Diag(PragmaLoc, diag::err__Pragma_malformed);
373 while(Tok.
isNot(tok::eof)) {
374PragmaToks.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) {
396PragmaToks.back().setKind(tok::eod);
398 Token*TokArray =
new Token[PragmaToks.size()];
399std::copy(PragmaToks.begin(), PragmaToks.end(), TokArray);
402EnterTokenStream(TokArray, PragmaToks.size(),
true,
true,
419 Diag(OnceTok, diag::pp_pragma_once_in_main_file);
429assert(CurPPLexer &&
"No current lexer?");
432CurLexer->ReadToEndOfLine(&Buffer);
434Callbacks->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);
500Callbacks->FileChanged(SysHeaderTok.
getLocation(),
507FilenameID,
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())
561Message.erase(Message.end()-1);
562 Diag(FilenameTok, diag::pp_out_of_date_dependency) << Message;
570 TokenPragmaTok = 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)
604assert(StrVal[0] ==
'"'&& StrVal[StrVal.size()-1] ==
'"'&&
605 "Invalid string token!");
610MacroTok.
setKind(tok::raw_identifier);
611 CreateString(StringRef(&StrVal[1], StrVal.size() - 2), MacroTok);
626 if(!IdentInfo)
return;
637PragmaPushMacroInfo[IdentInfo].push_back(MI);
651 if(!IdentInfo)
return;
654llvm::DenseMap<IdentifierInfo *, std::vector<MacroInfo *>>::iterator iter =
655PragmaPushMacroInfo.find(IdentInfo);
656 if(iter != PragmaPushMacroInfo.end()) {
659 if(MI->isWarnIfUnused())
660WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
665 MacroInfo*MacroToReInstall = iter->second.back();
667 if(MacroToReInstall)
672iter->second.pop_back();
673 if(iter->second.empty())
674PragmaPushMacroInfo.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 TokenSourceFilenameTok;
699StringRef SourceFileName;
701 if(SourceFilenameTok.
is(tok::header_name)) {
702SourceFileName =
getSpelling(SourceFilenameTok, FileNameBuffer);
704 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
707FileNameBuffer.clear();
711 if(Tok.
isNot(tok::comma)) {
712 Diag(Tok, diag::warn_pragma_include_alias_expected) <<
",";
716 TokenReplaceFilenameTok;
720StringRef ReplaceFileName;
721 if(ReplaceFilenameTok.
is(tok::header_name)) {
722ReplaceFileName =
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) <<
")";
737StringRef OriginalSource = SourceFileName;
739 boolSourceIsAngled =
742 boolReplaceIsAngled =
745 if(!SourceFileName.empty() && !ReplaceFileName.empty() &&
746(SourceIsAngled != ReplaceIsAngled)) {
749DiagID = diag::warn_pragma_include_alias_mismatch_angle;
751DiagID = diag::warn_pragma_include_alias_mismatch_quote;
768std::pair<IdentifierInfo *, SourceLocation> &ModuleNameComponent,
773 if(Literal.hadError)
775ModuleNameComponent = std::make_pair(
778ModuleNameComponent =
792std::pair<IdentifierInfo*, SourceLocation> NameComponent;
795ModuleName.push_back(NameComponent);
798 if(Tok.
isNot(tok::period))
806std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc;
812 if(Tok.
isNot(tok::eod)) {
813 Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
817CurLexer->LexingRawMode =
true;
819 autoTryConsumeIdentifier = [&](StringRef Ident) ->
bool{
820 if(Tok.
getKind() != tok::raw_identifier ||
828 const char*Start = CurLexer->getBufferLocation();
829 const char*End =
nullptr;
830 unsignedNestingLevel = 1;
832End = CurLexer->getBufferLocation();
835 if(Tok.
is(tok::eof)) {
836 Diag(
Loc, diag::err_pp_module_build_missing_end);
847CurLexer->ParsingPreprocessorDirective =
true;
849 if(TryConsumeIdentifier(
"pragma") && TryConsumeIdentifier(
"clang") &&
850TryConsumeIdentifier(
"module")) {
851 if(TryConsumeIdentifier(
"build"))
854 else if(TryConsumeIdentifier(
"endbuild")) {
856 if(--NestingLevel == 0)
861assert(Tok.
getKind() != tok::eof &&
"missing EOD before EOF");
865CurLexer->LexingRawMode =
false;
868assert(CurLexer->getBuffer().begin() <= Start &&
869Start <= CurLexer->getBuffer().end() &&
870CurLexer->getBuffer().begin() <= End &&
871End <= CurLexer->getBuffer().end() &&
872 "module source range not contained within same file buffer");
874StringRef(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))
894<<
"pragma hdrstop";
898assert(CurLexer &&
"no lexer for #pragma hdrstop processing");
901CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
902CurLexer->cutOffLexing();
905SkippingUntilPragmaHdrStop =
false;
916 if(!Namespace.empty()) {
920 if(
PragmaHandler*Existing = PragmaHandlers->FindHandler(Namespace)) {
922assert(InsertNS !=
nullptr&&
"Cannot have a pragma namespace and pragma" 923 " handler with the same name!");
928PragmaHandlers->AddPragma(InsertNS);
934 "Pragma handler already exists for this identifier!");
947 if(!Namespace.empty()) {
948 PragmaHandler*Existing = PragmaHandlers->FindHandler(Namespace);
949assert(Existing &&
"Namespace containing handler does not exist!");
952assert(NS &&
"Invalid namespace, registered as a regular pragma handler!");
958 if(NS != PragmaHandlers.get() && NS->
IsEmpty()) {
959PragmaHandlers->RemovePragmaHandler(NS);
968 if(Tok.
isNot(tok::identifier)) {
969 Diag(Tok, diag::ext_on_off_switch_syntax);
973 if(II->
isStr(
"ON"))
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{
1028PragmaSystemHeaderHandler() :
PragmaHandler(
"system_header") {}
1031 Token&SHToken)
override{
1038PragmaDependencyHandler() :
PragmaHandler(
"dependency") {}
1041 Token&DepToken)
override{
1050 Token&DebugToken)
override{
1053 if(Tok.
isNot(tok::identifier)) {
1054PP.
Diag(Tok, diag::warn_pragma_debug_missing_command);
1059 if(II->
isStr(
"assert")) {
1061llvm_unreachable(
"This is an assertion!");
1062}
else if(II->
isStr(
"crash")) {
1063llvm::Timer
T(
"crash",
"pragma crash");
1064llvm::TimeRegion R(&
T);
1067}
else if(II->
isStr(
"parser_crash")) {
1071Crasher.
setKind(tok::annot_pragma_parser_crash);
1075}
else if(II->
isStr(
"dump")) {
1078DumpAnnot.
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()) {
1088StringLiteralEvalMethod::Unevaluated);
1093PP.
Diag(DiagName, diag::warn_pragma_debug_missing_argument)
1096}
else if(II->
isStr(
"llvm_fatal_error")) {
1098llvm::report_fatal_error(
"#pragma clang __debug llvm_fatal_error");
1099}
else if(II->
isStr(
"llvm_unreachable")) {
1101llvm_unreachable(
"#pragma clang __debug llvm_unreachable");
1102}
else if(II->
isStr(
"macro")) {
1109PP.
Diag(MacroName, diag::warn_pragma_debug_missing_argument)
1111}
else if(II->
isStr(
"module_map")) {
1118 for(
autoIIAndLoc : ModuleName) {
1121PP.
Diag(IIAndLoc.second, diag::warn_pragma_debug_unknown_module)
1127}
else if(II->
isStr(
"overflow_stack")) {
1129DebugOverflowStack();
1130}
else if(II->
isStr(
"captured")) {
1132}
else if(II->
isStr(
"modules")) {
1133 structModuleVisitor {
1135 voidvisit(
Module*M,
boolVisibleOnly) {
1137 if(!VisibleOnly || ImportLoc.
isValid()) {
1140llvm::errs() << M <<
" visible ";
1143llvm::errs() <<
"\n";
1146 if(!VisibleOnly || ImportLoc.
isInvalid() ||
Sub->IsExplicit)
1147visit(Sub, VisibleOnly);
1150 voidvisitAll(
boolVisibleOnly) {
1151 for(
auto&NameAndMod :
1153visit(NameAndMod.second, VisibleOnly);
1159 auto*DumpII =
Kind.getIdentifierInfo();
1161PP.
Diag(
Kind, diag::warn_pragma_debug_missing_argument)
1163}
else if(DumpII->isStr(
"all")) {
1164Visitor.visitAll(
false);
1165}
else if(DumpII->isStr(
"visible")) {
1166Visitor.visitAll(
true);
1167}
else if(DumpII->isStr(
"building")) {
1169llvm::errs() <<
"in "<< Building.M->getFullModuleName();
1170 if(Building.ImportLoc.isValid()) {
1171llvm::errs() <<
" imported ";
1172 if(Building.IsPragma)
1173llvm::errs() <<
"via pragma ";
1174llvm::errs() <<
"at ";
1176llvm::errs() <<
"\n";
1180PP.
Diag(Tok, diag::warn_pragma_debug_unexpected_command)
1181<< DumpII->getName();
1183}
else if(II->
isStr(
"sloc_usage")) {
1186std::optional<unsigned> MaxNotes;
1190 if(ArgToken.
is(tok::numeric_constant) &&
1193}
else if(ArgToken.
isNot(tok::eod)) {
1194PP.
Diag(ArgToken, diag::warn_pragma_debug_unexpected_argument);
1197PP.
Diag(Tok, diag::remark_sloc_usage);
1201PP.
Diag(Tok, diag::warn_pragma_debug_unexpected_command)
1214 if(Tok.
isNot(tok::eod)) {
1215PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol)
1216<<
"pragma clang __debug captured";
1223Toks[0].startToken();
1224Toks[0].setKind(tok::annot_pragma_captured);
1225Toks[0].setLocation(NameLoc);
1227PP.EnterTokenStream(Toks,
true,
1233 #pragma warning(disable : 4717) 1235 static voidDebugOverflowStack(
void(*
P)() =
nullptr) {
1236void (*
volatileSelf)(void(*
P)()) = DebugOverflowStack;
1237Self(
reinterpret_cast<void(*)()
>(Self));
1240 #pragma warning(default : 4717) 1244structPragmaUnsafeBufferUsageHandler :
public PragmaHandler{
1245PragmaUnsafeBufferUsageHandler() :
PragmaHandler(
"unsafe_buffer_usage") {}
1247 Token&FirstToken)
override{
1251 if(Tok.
isNot(tok::identifier)) {
1252PP.
Diag(Tok, diag::err_pp_pragma_unsafe_buffer_usage_syntax);
1259 if(II->
isStr(
"begin")) {
1261PP.
Diag(
Loc, diag::err_pp_double_begin_pragma_unsafe_buffer_usage);
1262}
else if(II->
isStr(
"end")) {
1264PP.
Diag(
Loc, diag::err_pp_unmatched_end_begin_pragma_unsafe_buffer_usage);
1266PP.
Diag(Tok, diag::err_pp_pragma_unsafe_buffer_usage_syntax);
1276 explicitPragmaDiagnosticHandler(
const char*NS)
1280 Token&DiagToken)
override{
1284 if(Tok.
isNot(tok::identifier)) {
1285PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1295 if(II->
isStr(
"pop")) {
1297PP.
Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
1301 if(Tok.
isNot(tok::eod))
1302PP.
Diag(Tok.
getLocation(), diag::warn_pragma_diagnostic_invalid_token);
1304}
else if(II->
isStr(
"push")) {
1309 if(Tok.
isNot(tok::eod))
1310PP.
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)
1322PP.
Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1328std::string WarningName;
1333 if(Tok.
isNot(tok::eod)) {
1334PP.
Diag(Tok.
getLocation(), diag::warn_pragma_diagnostic_invalid_token);
1338 if(WarningName.size() < 3 || WarningName[0] !=
'-'||
1339(WarningName[1] !=
'W'&& WarningName[1] !=
'R')) {
1340PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_invalid_option);
1345: diag::Flavor::Remark;
1346StringRef
Group= StringRef(WarningName).substr(2);
1347 boolunknownDiag =
false;
1348 if(Group ==
"everything") {
1357PP.
Diag(StringLoc, diag::warn_pragma_diagnostic_unknown_warning)
1368 Token&DepToken)
override{
1380 Token&Tok)
override{
1389 if(Tok.
isNot(tok::l_paren)) {
1390PP.
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) {
1408PP.
Diag(Tok, diag::warn_pragma_warning_push_level);
1415}
else if(II && II->
isStr(
"pop")) {
1419PP.
Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
1427 if(!II && !Tok.
is(tok::numeric_constant)) {
1428PP.
Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1433 boolSpecifierValid;
1436 intSpecifierInt = llvm::StringSwitch<int>(II->
getName())
1443SpecifierValid = SpecifierInt != -1;
1456 if((SpecifierValid = (
Value>= 1) && (
Value<= 4)))
1460SpecifierValid =
false;
1464 if(!SpecifierValid) {
1465PP.
Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1468 if(Tok.
isNot(tok::colon)) {
1469PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
":";
1476 while(Tok.
is(tok::numeric_constant)) {
1480PP.
Diag(Tok, diag::warn_pragma_warning_expected_number);
1483Ids.push_back(
int(
Value));
1489SV = diag::Severity::Ignored;
1491 for(
int Id: Ids) {
1494diag::Flavor::WarningOrError, *Group, SV, DiagLoc);
1495assert(!unknownDiag &&
1496 "wd table should only contain known diags");
1505 if(Tok.
isNot(tok::semi))
1511 if(Tok.
isNot(tok::r_paren)) {
1512PP.
Diag(Tok, diag::warn_pragma_warning_expected) <<
")";
1517 if(Tok.
isNot(tok::eod))
1518PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma warning";
1526PragmaExecCharsetHandler() :
PragmaHandler(
"execution_character_set") {}
1529 Token&Tok)
override{
1537 if(Tok.
isNot(tok::l_paren)) {
1538PP.
Diag(Tok, diag::warn_pragma_exec_charset_expected) <<
"(";
1545 if(II && II->
isStr(
"push")) {
1548 if(Tok.
is(tok::comma)) {
1551std::string ExecCharset;
1553 "pragma execution_character_set",
1558 if(ExecCharset !=
"UTF-8"&& ExecCharset !=
"utf-8") {
1559PP.
Diag(Tok, diag::warn_pragma_exec_charset_push_invalid) << ExecCharset;
1565}
else if(II && II->
isStr(
"pop")) {
1571PP.
Diag(Tok, diag::warn_pragma_exec_charset_spec_invalid);
1575 if(Tok.
isNot(tok::r_paren)) {
1576PP.
Diag(Tok, diag::warn_pragma_exec_charset_expected) <<
")";
1581 if(Tok.
isNot(tok::eod))
1582PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma execution_character_set";
1588PragmaIncludeAliasHandler() :
PragmaHandler(
"include_alias") {}
1591 Token&IncludeAliasTok)
override{
1615 boolPragmaNameOnly =
false) {
1618 returnPragmaNameOnly ?
"message":
"pragma message";
1620 returnPragmaNameOnly ?
"warning":
"pragma warning";
1622 returnPragmaNameOnly ?
"error":
"pragma error";
1624llvm_unreachable(
"Unknown PragmaMessageKind!");
1629StringRef Namespace = StringRef())
1634 Token&Tok)
override{
1637 boolExpectClosingParen =
false;
1641ExpectClosingParen =
true;
1645 casetok::string_literal:
1649PP.
Diag(MessageLoc, diag::err_pragma_message_malformed) <<
Kind;
1653std::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))
1700PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1711tok::annot_module_include, Imported);
1713CB->moduleImport(ImportLoc, ModuleName, Imported);
1727 Token&Tok)
override{
1736 if(Tok.
isNot(tok::eod))
1737PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1741 if(ModuleName.front().first->getName() != Current) {
1742PP.
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);
1754PP.
Diag(ModuleName.front().second,
1755diag::err_pp_module_begin_no_module_map) << Current;
1758 for(
unsignedI = 1; I != ModuleName.size(); ++I) {
1761PP.
Diag(ModuleName[I].second, diag::err_pp_module_begin_no_submodule)
1771PP.
Diag(BeginLoc, diag::note_pp_module_begin_here)
1779tok::annot_module_begin, M);
1788 Token&Tok)
override{
1792 if(Tok.
isNot(tok::eod))
1793PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1799PP.
Diag(
Loc, diag::err_pp_module_end_without_module_begin);
1808 Token&Tok)
override{
1818 Token&Tok)
override{
1827 if(Tok.
isNot(tok::eod))
1828PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1839PragmaPushMacroHandler() :
PragmaHandler(
"push_macro") {}
1842 Token&PushMacroTok)
override{
1853 Token&PopMacroTok)
override{
1860structPragmaARCCFCodeAuditedHandler :
public PragmaHandler{
1861PragmaARCCFCodeAuditedHandler() :
PragmaHandler(
"arc_cf_code_audited") {}
1864 Token&NameTok)
override{
1873 if(BeginEnd && BeginEnd->
isStr(
"begin")) {
1875}
else if(BeginEnd && BeginEnd->
isStr(
"end")) {
1878PP.
Diag(Tok.
getLocation(), diag::err_pp_arc_cf_code_audited_syntax);
1884 if(Tok.
isNot(tok::eod))
1885PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1896PP.
Diag(
Loc, diag::err_pp_double_begin_of_arc_cf_code_audited);
1897PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1903PP.
Diag(
Loc, diag::err_pp_unmatched_end_of_arc_cf_code_audited);
1916PragmaAssumeNonNullHandler() :
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))
1940PP.
Diag(Tok, diag::ext_pp_extra_tokens_at_eol) <<
"pragma";
1952PP.
Diag(
Loc, diag::err_pp_double_begin_of_assume_nonnull);
1953PP.
Diag(BeginLoc, diag::note_pragma_entered_here);
1961PP.
Diag(
Loc, diag::err_pp_unmatched_end_of_assume_nonnull);
1985PragmaRegionHandler(
const char*pragma) :
PragmaHandler(pragma) {}
1988 Token&NameTok)
override{
2008std::string &MessageString) {
2010 if(Tok.
isNot(tok::l_paren)) {
2011PP.
Diag(Tok, diag::err_expected) <<
"(";
2016 if(!Tok.
is(tok::identifier)) {
2017PP.
Diag(Tok, diag::err_expected) << tok::identifier;
2023PP.
Diag(Tok, diag::err_pp_visibility_non_macro) << II;
2028 if(Tok.
is(tok::comma)) {
2035 if(Tok.
isNot(tok::r_paren)) {
2036PP.
Diag(Tok, diag::err_expected) <<
")";
2049PragmaDeprecatedHandler() :
PragmaHandler(
"deprecated") {}
2052 Token&Tok)
override{
2053std::string MessageString;
2056PP, Tok,
"#pragma clang deprecated", MessageString)) {
2070structPragmaRestrictExpansionHandler :
public PragmaHandler{
2071PragmaRestrictExpansionHandler() :
PragmaHandler(
"restrict_expansion") {}
2074 Token&Tok)
override{
2075std::string MessageString;
2078PP, Tok,
"#pragma clang restrict_expansion", MessageString)) {
2096 Token&Tok)
override{
2098 if(Tok.
isNot(tok::l_paren)) {
2099PP.
Diag(Tok, diag::err_expected) <<
"(";
2104 if(!Tok.
is(tok::identifier)) {
2105PP.
Diag(Tok, diag::err_expected) << tok::identifier;
2111PP.
Diag(Tok, diag::err_pp_visibility_non_macro) << II;
2116 if(Tok.
isNot(tok::r_paren)) {
2117PP.
Diag(Tok, diag::err_expected) <<
")";
2129voidPreprocessor::RegisterBuiltinPragmas() {
2160ModuleHandler->AddPragma(
newPragmaModuleImportHandler());
2161ModuleHandler->AddPragma(
newPragmaModuleBeginHandler());
2162ModuleHandler->AddPragma(
newPragmaModuleEndHandler());
2163ModuleHandler->AddPragma(
newPragmaModuleBuildHandler());
2164ModuleHandler->AddPragma(
newPragmaModuleLoadHandler());
2174 if(LangOpts.MicrosoftExt) {
2185 for(
constPragmaHandlerRegistry::entry &handler :
2186PragmaHandlerRegistry::entries()) {
Defines the Diagnostic-related interfaces.
enum clang::sema::@1704::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.
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
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4