;
63 static_assert(std::is_trivially_destructible_v<MacroInfo>,
"");
73Preprocessor::AllocateUndefMacroDirective(
SourceLocationUndefLoc) {
90 while(Tmp.
isNot(tok::eod)) {
91assert(Tmp.
isNot(tok::eof) &&
"EOF seen while discarding directive tokens");
120 static constexprStringRef ReservedMacro[] = {
123 "_CRT_NONSTDC_NO_WARNINGS",
124 "_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES",
125 "_CRT_SECURE_NO_WARNINGS",
126 "_FILE_OFFSET_BITS",
128 "_GLIBCXX_ASSERTIONS",
129 "_GLIBCXX_CONCEPT_CHECKS",
131 "_GLIBCXX_DEBUG_PEDANTIC",
132 "_GLIBCXX_PARALLEL",
133 "_GLIBCXX_PARALLEL_ASSERTIONS",
134 "_GLIBCXX_SANITIZE_VECTOR",
135 "_GLIBCXX_USE_CXX11_ABI",
136 "_GLIBCXX_USE_DEPRECATED",
141 "_LARGEFILE64_SOURCE",
147 "_XOPEN_SOURCE_EXTENDED",
148 "__STDCPP_WANT_MATH_SPEC_FUNCS__",
149 "__STDC_FORMAT_MACROS",
151 returnstd::binary_search(std::begin(ReservedMacro), std::end(ReservedMacro),
157 constStringRef MacroName) {
167 if(MacroName.starts_with(
"__STDC"))
170 if(MacroName ==
"__cplusplus")
173 if(MacroName.starts_with(
"__cpp"))
181 if(Lang.CPlusPlus &&
202 if(Lang.CPlusPlus11 && (
Text==
"override"||
Text==
"final"))
227 if(::llvm::sys::path::begin(Include)->equals_insensitive(
"boost"))
232 static const size_tMaxStdHeaderNameLen = 18u;
233 if(Include.size() > MaxStdHeaderNameLen)
238 for(
char&Ch : LowerInclude) {
240 if(
static_cast<unsigned char>(Ch) > 0x7f)
243 if(Ch >=
'A'&& Ch <=
'Z')
246 else if(::llvm::sys::path::is_separator(Ch))
251 returnllvm::StringSwitch<bool>(LowerInclude)
253.Cases(
"assert.h",
"complex.h",
"ctype.h",
"errno.h",
"fenv.h",
true)
254.Cases(
"float.h",
"inttypes.h",
"iso646.h",
"limits.h",
"locale.h",
true)
255.Cases(
"math.h",
"setjmp.h",
"signal.h",
"stdalign.h",
"stdarg.h",
true)
256.Cases(
"stdatomic.h",
"stdbool.h",
"stdckdint.h",
"stddef.h",
true)
257.Cases(
"stdint.h",
"stdio.h",
"stdlib.h",
"stdnoreturn.h",
true)
258.Cases(
"string.h",
"tgmath.h",
"threads.h",
"time.h",
"uchar.h",
true)
259.Cases(
"wchar.h",
"wctype.h",
true)
262.Cases(
"cassert",
"ccomplex",
"cctype",
"cerrno",
"cfenv",
true)
263.Cases(
"cfloat",
"cinttypes",
"ciso646",
"climits",
"clocale",
true)
264.Cases(
"cmath",
"csetjmp",
"csignal",
"cstdalign",
"cstdarg",
true)
265.Cases(
"cstdbool",
"cstddef",
"cstdint",
"cstdio",
"cstdlib",
true)
266.Cases(
"cstring",
"ctgmath",
"ctime",
"cuchar",
"cwchar",
true)
267.Case(
"cwctype",
true)
270.Cases(
"algorithm",
"fstream",
"list",
"regex",
"thread",
true)
271.Cases(
"array",
"functional",
"locale",
"scoped_allocator",
"tuple",
true)
272.Cases(
"atomic",
"future",
"map",
"set",
"type_traits",
true)
273.Cases(
"bitset",
"initializer_list",
"memory",
"shared_mutex",
"typeindex",
true)
274.Cases(
"chrono",
"iomanip",
"mutex",
"sstream",
"typeinfo",
true)
275.Cases(
"codecvt",
"ios",
"new",
"stack",
"unordered_map",
true)
276.Cases(
"complex",
"iosfwd",
"numeric",
"stdexcept",
"unordered_set",
true)
277.Cases(
"condition_variable",
"iostream",
"ostream",
"streambuf",
"utility",
true)
278.Cases(
"deque",
"istream",
"queue",
"string",
"valarray",
true)
279.Cases(
"exception",
"iterator",
"random",
"strstream",
"vector",
true)
280.Cases(
"forward_list",
"limits",
"ratio",
"system_error",
true)
283.Cases(
"aio.h",
"arpa/inet.h",
"cpio.h",
"dirent.h",
"dlfcn.h",
true)
284.Cases(
"fcntl.h",
"fmtmsg.h",
"fnmatch.h",
"ftw.h",
"glob.h",
true)
285.Cases(
"grp.h",
"iconv.h",
"langinfo.h",
"libgen.h",
"monetary.h",
true)
286.Cases(
"mqueue.h",
"ndbm.h",
"net/if.h",
"netdb.h",
"netinet/in.h",
true)
287.Cases(
"netinet/tcp.h",
"nl_types.h",
"poll.h",
"pthread.h",
"pwd.h",
true)
288.Cases(
"regex.h",
"sched.h",
"search.h",
"semaphore.h",
"spawn.h",
true)
289.Cases(
"strings.h",
"stropts.h",
"sys/ipc.h",
"sys/mman.h",
"sys/msg.h",
true)
290.Cases(
"sys/resource.h",
"sys/select.h",
"sys/sem.h",
"sys/shm.h",
"sys/socket.h",
true)
291.Cases(
"sys/stat.h",
"sys/statvfs.h",
"sys/time.h",
"sys/times.h",
"sys/types.h",
true)
292.Cases(
"sys/uio.h",
"sys/un.h",
"sys/utsname.h",
"sys/wait.h",
"syslog.h",
true)
293.Cases(
"tar.h",
"termios.h",
"trace.h",
"ulimit.h",
true)
294.Cases(
"unistd.h",
"utime.h",
"utmpx.h",
"wordexp.h",
true)
306staticstd::optional<StringRef>
310 for(StringRef
C: Candidates) {
311 if(LHS.equals_insensitive(
C)) {
319 size_tLength = LHS.size();
320 size_tMaxDist = Length < 3 ? Length - 1 : Length / 3;
322std::optional<std::pair<StringRef, size_t>> SimilarStr;
323 for(StringRef
C: Candidates) {
324 size_tCurDist = LHS.edit_distance(
C,
true);
325 if(CurDist <= MaxDist) {
328SimilarStr = {
C, CurDist};
329}
else if(CurDist < SimilarStr->second) {
331SimilarStr = {
C, CurDist};
337 returnSimilarStr->first;
346 if(MacroNameTok.
is(tok::eod))
347 return Diag(MacroNameTok, diag::err_pp_missing_macro_name);
351 return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
357? diag::ext_pp_operator_used_as_macro_name
358: diag::err_pp_operator_used_as_macro_name)
359<< II << MacroNameTok.
getKind();
366 return Diag(MacroNameTok, diag::err_defined_macro_name);
373*ShadowFlag =
false;
375(SourceMgr.
getBufferName(MacroNameLoc) !=
"<built-in>")) {
380 else if(isDefineUndef ==
MU_Undef)
390 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id);
392 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_attribute_id)
409voidPreprocessor::ReadMacroName(
Token&MacroNameTok,
MacroUseisDefineUndef,
414 if(MacroNameTok.
is(tok::code_completion)) {
426 if(MacroNameTok.
isNot(tok::eod)) {
427MacroNameTok.
setKind(tok::eod);
451 while(Tmp.
is(tok::comment))
454 if(Tmp.
is(tok::eod))
462 if((LangOpts.GNUMode || LangOpts.C99 || LangOpts.CPlusPlus) &&
465 Diag(Tmp, diag::ext_pp_extra_tokens_at_eol) << DirType << Hint;
469voidPreprocessor::SuggestTypoedDirective(
const Token&Tok,
475std::vector<StringRef> Candidates = {
476 "if",
"ifdef",
"ifndef",
"elif",
"else",
"endif" 478 if(LangOpts.C23 || LangOpts.CPlusPlus23)
479Candidates.insert(Candidates.end(), {
"elifdef",
"elifndef"});
487StringRef SuggValue = *Sugg;
490 Diag(Tok, diag::warn_pp_invalid_directive) << 1 << SuggValue << Hint;
502voidPreprocessor::SkipExcludedConditionalBlock(
SourceLocationHashTokenLoc,
504 boolFoundNonSkipPortion,
515assert(!SkippingExcludedConditionalBlock &&
516 "calling SkipExcludedConditionalBlock recursively");
520assert(!CurTokenLexer &&
"Conditional PP block cannot appear in a macro!");
521assert(CurPPLexer &&
"Conditional PP block must be in a file!");
522assert(CurLexer &&
"Conditional PP block but no current lexer set!");
524 if(PreambleConditionalStack.reachedEOFWhileSkipping())
525PreambleConditionalStack.clearSkipInfo();
528FoundNonSkipPortion, FoundElse);
538 structSkippingRangeStateTy {
541 const char*BeginPtr =
nullptr;
542 unsigned*SkipRangePtr =
nullptr;
546 voidbeginLexPass() {
552BeginPtr = PP.CurLexer->getBufferLocation();
553SkipRangePtr = &PP.RecordedSkippedRanges[BeginPtr];
555PP.CurLexer->seek(PP.CurLexer->getCurrentBufferOffset() + *SkipRangePtr,
560 voidendLexPass(
const char*Hashptr) {
563assert(PP.CurLexer->isDependencyDirectivesLexer());
568 if(!*SkipRangePtr) {
569*SkipRangePtr = Hashptr - BeginPtr;
571assert(*SkipRangePtr ==
unsigned(Hashptr - BeginPtr));
573SkipRangePtr =
nullptr;
575} SkippingRangeState(*
this);
578 if(CurLexer->isDependencyDirectivesLexer()) {
579CurLexer->LexDependencyDirectiveTokenWhileSkipping(Tok);
581SkippingRangeState.beginLexPass();
585 if(Tok.
is(tok::code_completion)) {
593 if(Tok.
is(tok::eof)) {
597 if(PreambleConditionalStack.isRecording())
598PreambleConditionalStack.SkipInfo.emplace(HashTokenLoc, IfTokenLoc,
611 if(Tok.
is(tok::eof))
618 if(CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
620assert(Tok.
is(tok::hash));
621 const char*Hashptr = CurLexer->getBufferLocation() - Tok.
getLength();
622assert(CurLexer->getSourceLocation(Hashptr) == Tok.
getLocation());
629 if(Tok.
isNot(tok::raw_identifier)) {
632 if(CurLexer) CurLexer->resetExtendedTokenMode();
643 charFirstChar = RI[0];
644 if(FirstChar >=
'a'&& FirstChar <=
'z'&&
645FirstChar !=
'i'&& FirstChar !=
'e') {
648 if(CurLexer) CurLexer->resetExtendedTokenMode();
655 charDirectiveBuf[20];
661 size_tIdLen = DirectiveStr.size();
665 if(CurLexer) CurLexer->resetExtendedTokenMode();
668 memcpy(DirectiveBuf, &DirectiveStr[0], IdLen);
669 Directive= StringRef(DirectiveBuf, IdLen);
688 if(Sub ==
"ndif") {
693assert(!InCond &&
"Can't be skipping if not in a conditional!");
697SkippingRangeState.endLexPass(Hashptr);
709}
else if(Sub ==
"lse") {
716SkippingRangeState.endLexPass(Hashptr);
720 Diag(Tok, diag::pp_err_else_after_else);
740}
else if(Sub ==
"lif") {
744SkippingRangeState.endLexPass(Hashptr);
761assert(CurPPLexer->
LexingRawMode&&
"We have to be skipping here!");
764DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
768 const boolCondValue = DER.Conditional;
782}
else if(Sub ==
"lifdef"||
784 boolIsElifDef =
Sub==
"lifdef";
786 TokenDirectiveToken = Tok;
789SkippingRangeState.endLexPass(Hashptr);
794 if(LangOpts.CPlusPlus)
795DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
796: diag::ext_cxx23_pp_directive;
798DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
799: diag::ext_c23_pp_directive;
804 Diag(Tok, diag::pp_err_elif_after_else)
818assert(CurPPLexer->
LexingRawMode&&
"We have to be skipping here!");
821ReadMacroName(MacroNameTok);
826 if(MacroNameTok.
is(tok::eod)) {
842Callbacks->Elifdef(DirectiveToken.
getLocation(), MacroNameTok,
845Callbacks->Elifndef(DirectiveToken.
getLocation(), MacroNameTok,
850 if(
static_cast<bool>(MI) == IsElifDef) {
864 if(CurLexer) CurLexer->resetExtendedTokenMode();
875Callbacks->SourceRangeSkipped(
907IncLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
915 autoID =
SM.getFileID(
SM.getExpansionLoc(
Loc));
916 autoFE =
SM.getFileEntryRefForID(ID);
925 boolInPrivateHeader =
false;
927 if(!Header.isAccessibleFrom(IncM)) {
932InPrivateHeader =
true;
968 Loc=
SM.getIncludeLoc(ID);
980 bool*IsFrameworkFound,
boolSkipCache,
boolOpenFile,
boolCacheFailures) {
985FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
990 boolBuildSystemModule =
false;
991 if(!FromDir && !FromFile) {
1014Includers.push_back(std::make_pair(std::nullopt, *IncludeDir));
1019Includers.push_back(std::make_pair(*FileEnt, *CWD));
1022Includers.push_back(std::make_pair(*FileEnt, FileEnt->
getDir()));
1028 if(LangOpts.MSVCCompat && !isAngled) {
1029 for(IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1030 if(IsFileLexer(ISEntry))
1032Includers.push_back(std::make_pair(*FileEnt, FileEnt->
getDir()));
1037CurDir = CurDirLookup;
1045 Filename, FilenameLoc, isAngled, TmpFromDir, &TmpCurDir,
1046Includers, SearchPath, RelativePath, RequestingModule,
1047SuggestedModule,
nullptr,
1048 nullptr, SkipCache)) {
1050TmpFromDir = TmpCurDir;
1052 if(&FE->getFileEntry() == FromFile) {
1054FromDir = TmpFromDir;
1063 Filename, FilenameLoc, isAngled, FromDir, &CurDir, Includers, SearchPath,
1064RelativePath, RequestingModule, SuggestedModule, IsMapped,
1065IsFrameworkFound, SkipCache, BuildSystemModule, OpenFile, CacheFailures);
1073 if(IsFileLexer()) {
1076 Filename, *CurFileEnt, SearchPath, RelativePath, RequestingModule,
1083 for(IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1084 if(IsFileLexer(ISEntry)) {
1085 if((CurFileEnt = ISEntry.ThePPLexer->
getFileEntry())) {
1087 Filename, *CurFileEnt, SearchPath, RelativePath,
1088RequestingModule, SuggestedModule)) {
1096 returnstd::nullopt;
1103 if(llvm::sys::path::is_absolute(
Filename)) {
1106 Filename, OpenFile,
true,
false);
1107 returnllvm::expectedToOptional(std::move(ShouldBeEntry));
1111StringRef StartingFrom, StringRef
FileName,
1112 boolRemoveInitialFileComponentFromLookupPath) {
1113llvm::sys::path::native(StartingFrom, LookupPath);
1114 if(RemoveInitialFileComponentFromLookupPath)
1115llvm::sys::path::remove_filename(LookupPath);
1116 if(!LookupPath.empty() &&
1117!llvm::sys::path::is_separator(LookupPath.back())) {
1118LookupPath.push_back(llvm::sys::path::get_separator().front());
1127 if(LookupFromFile) {
1130 if(!FullFileDir.empty()) {
1131SeparateComponents(LookupPath, FullFileDir,
Filename,
true);
1133LookupPath, OpenFile,
true,
false);
1135 returnllvm::expectedToOptional(std::move(ShouldBeEntry));
1136llvm::consumeError(ShouldBeEntry.takeError());
1143 if(MaybeWorkingDirEntry) {
1145StringRef WorkingDir = WorkingDirEntry.
getName();
1146 if(!WorkingDir.empty()) {
1147SeparateComponents(LookupPath, WorkingDir,
Filename,
false);
1149LookupPath, OpenFile,
true,
false);
1151 returnllvm::expectedToOptional(std::move(ShouldBeEntry));
1152llvm::consumeError(ShouldBeEntry.takeError());
1157 for(
const auto&Entry : PPOpts->EmbedEntries) {
1159SeparateComponents(LookupPath, Entry,
Filename,
false);
1161LookupPath, OpenFile,
true,
false);
1163 returnllvm::expectedToOptional(std::move(ShouldBeEntry));
1164llvm::consumeError(ShouldBeEntry.takeError());
1166 returnstd::nullopt;
1176: PP(pp), save(pp->DisableMacroExpansion) {
1177 if(pp->MacroExpansionInDirectivesOverride)
1178pp->DisableMacroExpansion =
false;
1182PP->DisableMacroExpansion = save;
1199 if(II->getPPKeywordID() == tok::pp_define) {
1200 returnHandleDefineDirective(
Result,
1203 if(SkippingUntilPCHThroughHeader &&
1204II->getPPKeywordID() == tok::pp_include) {
1205 returnHandleIncludeDirective(HashLoc,
Result);
1207 if(SkippingUntilPragmaHdrStop && II->getPPKeywordID() == tok::pp_pragma) {
1209 auto*II =
Result.getIdentifierInfo();
1210 if(II && II->getName() ==
"hdrstop")
1228 if(CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
1230 boolImmediatelyAfterTopLevelIfndef =
1258 switch(II->getPPKeywordID()) {
1259 casetok::pp_include:
1260 casetok::pp_import:
1261 casetok::pp_include_next:
1262 casetok::pp___include_macros:
1263 casetok::pp_pragma:
1265 Diag(
Result, diag::err_embedded_directive) << II->getName();
1266 Diag(*ArgMacro, diag::note_macro_expansion_here)
1274 Diag(
Result, diag::ext_embedded_directive);
1281 if(SkippingUntilPCHThroughHeader || SkippingUntilPragmaHdrStop)
1284 switch(
Result.getKind()) {
1291 casetok::code_completion:
1297 casetok::numeric_constant:
1304 returnHandleDigitDirective(
Result);
1314 returnHandleIfDirective(
Result, SavedHash, ReadAnyTokensBeforeDirective);
1316 returnHandleIfdefDirective(
Result, SavedHash,
false,
1318 casetok::pp_ifndef:
1319 returnHandleIfdefDirective(
Result, SavedHash,
true,
1320ReadAnyTokensBeforeDirective);
1322 casetok::pp_elifdef:
1323 casetok::pp_elifndef:
1327 returnHandleElseDirective(
Result, SavedHash);
1329 returnHandleEndifDirective(
Result);
1332 casetok::pp_include:
1335 casetok::pp___include_macros:
1340 casetok::pp_define:
1341 returnHandleDefineDirective(
Result, ImmediatelyAfterTopLevelIfndef);
1343 returnHandleUndefDirective();
1347 returnHandleLineDirective();
1351 returnHandleUserDiagnosticDirective(
Result,
false);
1354 casetok::pp_pragma:
1358 casetok::pp_import:
1360 casetok::pp_include_next:
1363 casetok::pp_warning:
1364 if(LangOpts.CPlusPlus)
1366? diag::warn_cxx23_compat_warning_directive
1367: diag::ext_pp_warning_directive)
1370 Diag(
Result, LangOpts.C23 ? diag::warn_c23_compat_warning_directive
1371: diag::ext_pp_warning_directive)
1374 returnHandleUserDiagnosticDirective(
Result,
true);
1376 returnHandleIdentSCCSDirective(
Result);
1378 returnHandleIdentSCCSDirective(
Result);
1383:
static_cast<FileEntry*
>(
nullptr));
1384 casetok::pp_assert:
1387 casetok::pp_unassert:
1391 casetok::pp___public_macro:
1393 returnHandleMacroPublicDirective(
Result);
1396 casetok::pp___private_macro:
1398 returnHandleMacroPrivateDirective();
1409 autoToks = std::make_unique<Token[]>(2);
1411Toks[0] = SavedHash;
1416 if(
Result.is(tok::hashhash))
1417Toks[1].setKind(tok::unknown);
1422EnterTokenStream(std::move(Toks), 2,
false,
false);
1428 Diag(
Result, diag::err_pp_invalid_directive) << 0;
1440 boolIsGNULineDirective=
false) {
1441 if(DigitTok.
isNot(tok::numeric_constant)) {
1442PP.
Diag(DigitTok, DiagID);
1444 if(DigitTok.
isNot(tok::eod))
1450IntegerBuffer.resize(DigitTok.
getLength());
1451 const char*DigitTokBegin = &IntegerBuffer[0];
1461 for(
unsignedi = 0; i != ActualLength; ++i) {
1464 if(DigitTokBegin[i] ==
'\'')
1467 if(!
isDigit(DigitTokBegin[i])) {
1469diag::err_pp_line_digit_sequence) << IsGNULineDirective;
1474 unsignedNextVal = Val*10+(DigitTokBegin[i]-
'0');
1475 if(NextVal < Val) {
1476PP.
Diag(DigitTok, DiagID);
1483 if(DigitTokBegin[0] ==
'0'&& Val)
1485<< IsGNULineDirective;
1497voidPreprocessor::HandleLineDirective() {
1505 if(
GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*
this))
1509 Diag(DigitTok, diag::ext_pp_line_zero);
1513 unsignedLineLimit = 32768U;
1514 if(LangOpts.C99 || LangOpts.CPlusPlus11)
1515LineLimit = 2147483648U;
1516 if(LineNo >= LineLimit)
1517 Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
1518 else if(LangOpts.CPlusPlus11 && LineNo >= 32768U)
1519 Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
1521 intFilenameID = -1;
1527 if(StrTok.
is(tok::eod))
1529 else if(StrTok.
isNot(tok::string_literal)) {
1530 Diag(StrTok, diag::err_pp_line_invalid_filename);
1534 Diag(StrTok, diag::err_invalid_string_udl);
1540assert(
Literal.isOrdinary() &&
"Didn't allow wide strings in");
1546 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1581 if(FlagTok.
is(tok::eod))
return false;
1582 if(
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1586IsFileEntry =
true;
1589 if(FlagTok.
is(tok::eod))
return false;
1590 if(
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1592}
else if(FlagVal == 2) {
1599 SM.getDecomposedExpansionLoc(FlagTok.
getLocation()).first;
1608 SM.getDecomposedExpansionLoc(IncLoc).first != CurFileID) {
1609PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);
1615 if(FlagTok.
is(tok::eod))
return false;
1616 if(
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1622PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1630 if(FlagTok.
is(tok::eod))
return false;
1631 if(
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1636PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1644 if(FlagTok.
is(tok::eod))
return false;
1647PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1659voidPreprocessor::HandleDigitDirective(
Token&DigitTok) {
1663 if(
GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
1670 boolIsFileEntry =
false, IsFileExit =
false;
1671 intFilenameID = -1;
1676 if(StrTok.
is(tok::eod)) {
1677 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1680}
else if(StrTok.
isNot(tok::string_literal)) {
1681 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1685 Diag(StrTok, diag::err_invalid_string_udl);
1691assert(
Literal.isOrdinary() &&
"Didn't allow wide strings in");
1697 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1707 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1711 if(!(IsFileExit &&
Literal.GetString().empty()))
1717IsFileExit, FileKind);
1726 else if(IsFileExit)
1735voidPreprocessor::HandleUserDiagnosticDirective(
Token&Tok,
1743CurLexer->ReadToEndOfLine(&Message);
1747StringRef Msg = Message.str().ltrim(
' ');
1750 Diag(Tok, diag::pp_hash_warning) << Msg;
1752 Diag(Tok, diag::err_pp_hash_error) << Msg;
1757voidPreprocessor::HandleIdentSCCSDirective(
Token&Tok) {
1759 Diag(Tok, diag::ext_pp_ident_directive);
1766 if(StrTok.
isNot(tok::string_literal) &&
1767StrTok.
isNot(tok::wide_string_literal)) {
1768 Diag(StrTok, diag::err_pp_malformed_ident);
1769 if(StrTok.
isNot(tok::eod))
1775 Diag(StrTok, diag::err_invalid_string_udl);
1792voidPreprocessor::HandleMacroPublicDirective(
Token&Tok) {
1794ReadMacroName(MacroNameTok,
MU_Undef);
1797 if(MacroNameTok.
is(tok::eod))
1809 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1819voidPreprocessor::HandleMacroPrivateDirective() {
1821ReadMacroName(MacroNameTok,
MU_Undef);
1824 if(MacroNameTok.
is(tok::eod))
1836 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1856StringRef &Buffer) {
1858assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1870 if(Buffer[0] ==
'<') {
1871 if(Buffer.back() !=
'>') {
1872 Diag(
Loc, diag::err_pp_expects_filename);
1873Buffer = StringRef();
1877}
else if(Buffer[0] ==
'"') {
1878 if(Buffer.back() !=
'"') {
1879 Diag(
Loc, diag::err_pp_expects_filename);
1880Buffer = StringRef();
1885 Diag(
Loc, diag::err_pp_expects_filename);
1886Buffer = StringRef();
1891 if(Buffer.size() <= 2) {
1892 Diag(
Loc, diag::err_pp_empty_filename);
1893Buffer = StringRef();
1898Buffer = Buffer.substr(1, Buffer.size()-2);
1905 void*AnnotationVal) {
1908 autoTok = std::make_unique<Token[]>(1);
1914EnterTokenStream(std::move(Tok), 1,
true,
false);
1921 ArrayRef<std::pair<IdentifierInfo *, SourceLocation>>
Path,
1924 for(
size_tI = 0, N =
Path.size(); I != N; ++I) {
1927PathString +=
Path[I].first->getName();
1930 intIncludeKind = 0;
1932 casetok::pp_include:
1936 casetok::pp_import:
1940 casetok::pp_include_next:
1944 casetok::pp___include_macros:
1949llvm_unreachable(
"unknown include directive kind");
1952PP.
Diag(HashLoc, diag::remark_pp_include_directive_modular_translation)
1953<< IncludeKind << PathString;
1960StringRef RealPathName,
1961llvm::sys::path::Style Separator) {
1962 autoRealPathComponentIter = llvm::sys::path::rbegin(RealPathName);
1963 autoRealPathComponentEnd = llvm::sys::path::rend(RealPathName);
1965 boolSuggestReplacement =
false;
1967 autoIsSep = [Separator](StringRef Component) {
1968 returnComponent.size() == 1 &&
1969llvm::sys::path::is_separator(Component[0], Separator);
1974 for(
auto&Component : llvm::reverse(Components)) {
1975 if(
"."== Component) {
1976}
else if(
".."== Component) {
1980}
else if(RealPathComponentIter != RealPathComponentEnd) {
1981 if(!IsSep(Component) && !IsSep(*RealPathComponentIter) &&
1982Component != *RealPathComponentIter) {
1986SuggestReplacement =
1987RealPathComponentIter->equals_insensitive(Component);
1988 if(!SuggestReplacement)
1990Component = *RealPathComponentIter;
1992++RealPathComponentIter;
1995 returnSuggestReplacement;
2004 Module*ShadowingModule =
nullptr;
2012}
else if(ShadowingModule) {
2015diag::note_previous_definition);
2026std::pair<ConstSearchDirIterator, const FileEntry *>
2027Preprocessor::getIncludeNextStart(
const Token&IncludeNextTok)
const{
2032 const FileEntry*LookupFromFile =
nullptr;
2040 Diag(IncludeNextTok, diag::pp_include_next_in_primary);
2041}
else if(CurLexerSubmodule) {
2044assert(CurPPLexer &&
"#include_next directive in macro?");
2046LookupFromFile = *FE;
2048}
else if(!Lookup) {
2053 Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
2059 return{Lookup, LookupFromFile};
2067voidPreprocessor::HandleIncludeDirective(
SourceLocationHashLoc,
2075 if(FilenameTok.
isNot(tok::header_name)) {
2077 if(FilenameTok.
isNot(tok::eod))
2089 autoAction = HandleHeaderIncludeOrImport(HashLoc, IncludeTok, FilenameTok,
2090EndLoc, LookupFrom, LookupFromFile);
2091 switch(Action.Kind) {
2092 caseImportAction::None:
2093 caseImportAction::SkippedModuleImport:
2095 caseImportAction::ModuleBegin:
2097tok::annot_module_begin, Action.ModuleForHeader);
2099 caseImportAction::HeaderUnitImport:
2101Action.ModuleForHeader);
2103 caseImportAction::ModuleImport:
2105tok::annot_module_include, Action.ModuleForHeader);
2107 caseImportAction::Failure:
2109 "This should be an early exit only to a fatal error");
2111IncludeTok.
setKind(tok::eof);
2112CurLexer->cutOffLexing();
2120 const Token&FilenameTok,
bool&IsFrameworkFound,
boolIsImportDecl,
2122 const FileEntry*LookupFromFile, StringRef &LookupFilename,
2126 if(LangOpts.AsmPreprocessor)
2130FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
2131 boolRequestingModuleIsModuleInterface =
2135RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
2140FilenameLoc, LookupFilename, isAngled, LookupFrom, LookupFromFile, CurDir,
2141Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2142&SuggestedModule, &IsMapped, &IsFrameworkFound);
2144DiagnoseHeaderInclusion(*
File);
2149 if(Callbacks && Callbacks->FileNotFound(
Filename))
2150 returnstd::nullopt;
2152 if(SuppressIncludeNotFoundError)
2153 returnstd::nullopt;
2160FilenameLoc, LookupFilename,
false, LookupFrom, LookupFromFile, CurDir,
2161Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2162&SuggestedModule, &IsMapped,
2165DiagnoseHeaderInclusion(*
File);
2166 Diag(FilenameTok, diag::err_pp_file_not_found_angled_include_not_fatal)
2176StringRef OriginalFilename =
Filename;
2177 if(LangOpts.SpellChecking) {
2180 autoCorrectTypoFilename = [](llvm::StringRef
Filename) {
2187StringRef TypoCorrectionName = CorrectTypoFilename(
Filename);
2188StringRef TypoCorrectionLookupName = CorrectTypoFilename(LookupFilename);
2191FilenameLoc, TypoCorrectionLookupName, isAngled, LookupFrom,
2192LookupFromFile, CurDir, Callbacks ? &SearchPath :
nullptr,
2193Callbacks ? &RelativePath :
nullptr, &SuggestedModule, &IsMapped,
2196DiagnoseHeaderInclusion(*
File);
2199FilenameRange,
"<"+ TypoCorrectionName.str() +
">")
2201FilenameRange,
"\""+ TypoCorrectionName.str() +
"\"");
2202 Diag(FilenameTok, diag::err_pp_file_not_found_typo_not_fatal)
2203<< OriginalFilename << TypoCorrectionName << Hint;
2207LookupFilename = TypoCorrectionLookupName;
2213assert(!
File&&
"expected missing file");
2214 Diag(FilenameTok, diag::err_pp_file_not_found)
2215<< OriginalFilename << FilenameRange;
2216 if(IsFrameworkFound) {
2217 size_tSlashPos = OriginalFilename.find(
'/');
2218assert(SlashPos != StringRef::npos &&
2219 "Include with framework name should have '/' in the filename");
2220StringRef FrameworkName = OriginalFilename.substr(0, SlashPos);
2223assert(CacheEntry.
Directory&&
"Found framework should be in cache");
2224 Diag(FilenameTok, diag::note_pp_framework_without_header)
2225<< OriginalFilename.substr(SlashPos + 1) << FrameworkName
2229 returnstd::nullopt;
2244Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
2254StringRef OriginalFilename =
Filename;
2261 return{ImportAction::None};
2263 boolIsImportDecl = HashLoc.
isInvalid();
2267 if(PragmaARCCFCodeAuditedInfo.second.isValid()) {
2268 Diag(StartLoc, diag::err_pp_include_in_arc_cf_code_audited) << IsImportDecl;
2269 Diag(PragmaARCCFCodeAuditedInfo.second, diag::note_pragma_entered_here);
2276 if(PragmaAssumeNonNullLoc.
isValid()) {
2277 Diag(StartLoc, diag::err_pp_include_in_assume_nonnull) << IsImportDecl;
2278 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
2289 if(!NewName.empty())
2294 boolIsMapped =
false;
2295 boolIsFrameworkFound =
false;
2303StringRef LookupFilename =
Filename;
2308llvm::sys::path::Style BackslashStyle = llvm::sys::path::Style::native;
2309 if(is_style_posix(BackslashStyle) && LangOpts.MicrosoftExt) {
2311llvm::sys::path::native(NormalizedPath);
2312LookupFilename = NormalizedPath;
2313BackslashStyle = llvm::sys::path::Style::windows;
2317&CurDir,
Filename, FilenameLoc, FilenameRange, FilenameTok,
2318IsFrameworkFound, IsImportDecl, IsMapped, LookupFrom, LookupFromFile,
2319LookupFilename, RelativePath, SearchPath, SuggestedModule, isAngled);
2323SkippingUntilPCHThroughHeader =
false;
2324 return{ImportAction::None};
2342 enum{ Enter,
Import,
Skip, IncludeLimitReached } Action = Enter;
2344 if(PPOpts->SingleFileParseMode)
2345Action = IncludeLimitReached;
2350 if(Action == Enter && HasReachedMaxIncludeDepth &&
File&&
2352Action = IncludeLimitReached;
2359 boolMaybeTranslateInclude = Action == Enter &&
File&& ModuleToImport &&
2363 boolUsableHeaderUnit =
false;
2364 if(
getLangOpts().CPlusPlusModules && ModuleToImport &&
2366 if(TrackGMFState.inGMF() || IsImportDecl)
2367UsableHeaderUnit =
true;
2368 else if(!IsImportDecl) {
2370ModuleToImport =
nullptr;
2374 boolUsableClangHeaderModule =
2381 if(MaybeTranslateInclude && (UsableHeaderUnit || UsableClangHeaderModule)) {
2389diag::note_implicit_top_level_module_import_here)
2391 return{ImportAction::None};
2398 for(
Module*Mod = ModuleToImport; Mod; Mod = Mod->
Parent)
2401std::reverse(
Path.begin(),
Path.end());
2414assert((Imported ==
nullptr|| Imported == ModuleToImport) &&
2415 "the imported module is different than the suggested one");
2421 static_cast<Module*
>(Imported)->getTopLevelModule());
2426ModuleToImport =
nullptr;
2435assert(CurLexer &&
"#include but no current lexer set!");
2437CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
2438CurLexer->cutOffLexing();
2440 return{ImportAction::None};
2461 boolIsFirstIncludeOfFile =
false;
2465 if(Action == Enter &&
File&&
2468IsFirstIncludeOfFile)) {
2479 if(UsableHeaderUnit && !
getLangOpts().CompilingPCH)
2480Action = TrackGMFState.inGMF() ?
Import:
Skip;
2482Action = (ModuleToImport && !
getLangOpts().CompilingPCH) ? Import :
Skip;
2490 if(Action == Enter &&
File&& PreambleConditionalStack.isRecording() &&
2493diag::err_pp_including_mainfile_in_preamble);
2494 return{ImportAction::None};
2497 if(Callbacks && !IsImportDecl) {
2500Callbacks->InclusionDirective(HashLoc, IncludeTok, LookupFilename, isAngled,
2501FilenameRange,
File, SearchPath, RelativePath,
2502SuggestedModule.
getModule(), Action == Import,
2505Callbacks->FileSkipped(*
File, FilenameTok, FileCharacter);
2509 return{ImportAction::None};
2513 if(IsImportDecl && !ModuleToImport) {
2514 Diag(FilenameTok, diag::err_header_import_not_header_unit)
2515<< OriginalFilename <<
File->getName();
2516 return{ImportAction::None};
2521 const boolCheckIncludePathPortability =
2522!IsMapped && !
File->getFileEntry().tryGetRealPathName().empty();
2524 if(CheckIncludePathPortability) {
2525StringRef Name = LookupFilename;
2526StringRef NameWithoriginalSlashes =
Filename;
2530 boolNameWasUNC = Name.consume_front(
"\\\\?\\");
2531NameWithoriginalSlashes.consume_front(
"\\\\?\\");
2533StringRef RealPathName =
File->getFileEntry().tryGetRealPathName();
2535llvm::sys::path::end(Name));
2548 if(llvm::sys::path::is_absolute(Name) &&
2549llvm::sys::path::is_absolute(RealPathName) &&
2552assert(Components.size() >= 3 &&
"should have drive, backslash, name");
2553assert(Components[0].size() == 2 &&
"should start with drive");
2554assert(Components[0][1] ==
':'&&
"should have colon");
2555FixedDriveRealPath = (Name.substr(0, 1) + RealPathName.substr(1)).str();
2556RealPathName = FixedDriveRealPath;
2562 Path.reserve(Name.size()+2);
2563 Path.push_back(isAngled ?
'<':
'"');
2565 const autoIsSep = [BackslashStyle](
char c) {
2566 returnllvm::sys::path::is_separator(
c, BackslashStyle);
2569 for(
autoComponent : Components) {
2581 if(!(Component.size() == 1 && IsSep(Component[0])))
2582 Path.append(Component);
2583 else if(
Path.size() != 1)
2587 if(
Path.size() > NameWithoriginalSlashes.size()) {
2588 Path.push_back(isAngled ?
'>':
'"');
2591assert(IsSep(NameWithoriginalSlashes[
Path.size()-1]));
2593 Path.push_back(NameWithoriginalSlashes[
Path.size()-1]);
2594 while(
Path.size() <= NameWithoriginalSlashes.size() &&
2595IsSep(NameWithoriginalSlashes[
Path.size()-1]));
2601 Path= (
Path.substr(0, 1) +
"\\\\?\\"+
Path.substr(1)).str();
2608? diag::pp_nonportable_path
2609: diag::pp_nonportable_system_path;
2610 Diag(FilenameTok, DiagId) <<
Path<<
2619 return{ImportAction::SkippedModuleImport, ModuleToImport};
2620 return{ImportAction::None};
2622 caseIncludeLimitReached:
2625 return{ImportAction::None};
2629assert(ModuleToImport &&
"no module to import");
2634tok::pp___include_macros)
2635 return{ImportAction::None};
2637 return{ImportAction::ModuleImport, ModuleToImport};
2645 if(IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
2646 Diag(FilenameTok, diag::err_pp_include_too_deep);
2647HasReachedMaxIncludeDepth =
true;
2648 return{ImportAction::None};
2652 Diag(FilenameTok, diag::warn_pp_include_angled_in_module_purview)
2664 returnImportAction::Failure;
2669IsFirstIncludeOfFile))
2670 return{ImportAction::None};
2674 if(ModuleToImport && !ModuleToImport->
isHeaderUnit()) {
2679diag::err_module_build_shadowed_submodule)
2682diag::note_previous_definition);
2683 return{ImportAction::None};
2695 return{ImportAction::None};
2697assert(!CurLexerSubmodule &&
"should not have marked this as a module yet");
2698CurLexerSubmodule = ModuleToImport;
2708 return{ImportAction::ModuleBegin, ModuleToImport};
2711assert(!IsImportDecl &&
"failed to diagnose missing module for import decl");
2712 return{ImportAction::None};
2717voidPreprocessor::HandleIncludeNextDirective(
SourceLocationHashLoc,
2718 Token&IncludeNextTok) {
2719 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
2723std::tie(Lookup, LookupFromFile) = getIncludeNextStart(IncludeNextTok);
2725 returnHandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
2730voidPreprocessor::HandleMicrosoftImportDirective(
Token&Tok) {
2736 Diag(Tok, diag::err_pp_import_directive_ms );
2747 if(!LangOpts.ObjC) {
2748 if(LangOpts.MSVCCompat)
2749 returnHandleMicrosoftImportDirective(ImportTok);
2750 Diag(ImportTok, diag::ext_pp_import_directive);
2752 returnHandleIncludeDirective(HashLoc, ImportTok);
2759voidPreprocessor::HandleIncludeMacrosDirective(
SourceLocationHashLoc,
2760 Token&IncludeMacrosTok) {
2766diag::pp_include_macros_out_of_predefines);
2773HandleIncludeDirective(HashLoc, IncludeMacrosTok);
2778assert(TmpTok.
isNot(tok::eof) &&
"Didn't find end of -imacros!");
2779}
while(TmpTok.
isNot(tok::hashhash));
2790boolPreprocessor::ReadMacroParameterList(
MacroInfo*MI,
Token&Tok) {
2801 Diag(Tok, diag::err_pp_expected_ident_in_arg_list);
2805 Diag(Tok, LangOpts.CPlusPlus11 ?
2806diag::warn_cxx98_compat_variadic_macro :
2807diag::ext_variadic_macro);
2810 if(LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus) {
2811 Diag(Tok, diag::ext_pp_opencl_variadic_macros);
2816 if(Tok.
isNot(tok::r_paren)) {
2817 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2826 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2834 Diag(Tok, diag::err_pp_invalid_tok_in_arg_list);
2840 if(llvm::is_contained(Parameters, II)) {
2841 Diag(Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
2853 Diag(Tok, diag::err_pp_expected_comma_in_arg_list);
2862 Diag(Tok, diag::ext_named_variadic_macro);
2866 if(Tok.
isNot(tok::r_paren)) {
2867 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2897StringRef ValueText = II->
getName();
2898StringRef TrimmedValue = ValueText;
2899 if(!ValueText.starts_with(
"__")) {
2900 if(ValueText.starts_with(
"_"))
2901TrimmedValue = TrimmedValue.drop_front(1);
2905TrimmedValue = TrimmedValue.drop_front(2);
2906 if(TrimmedValue.ends_with(
"__"))
2907TrimmedValue = TrimmedValue.drop_back(2);
2909 returnTrimmedValue == MacroText;
2916 returnMacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
2929MacroInfo*Preprocessor::ReadOptionalMacroParameterListAndBody(
2930 const Token&MacroNameTok,
const boolImmediatelyAfterHeaderGuard) {
2932 TokenLastTok = MacroNameTok;
2940 auto_ = llvm::make_scope_exit([&]() {
2942 if(CurLexer->ParsingPreprocessorDirective)
2953 if(Tok.
is(tok::eod)) {
2954 if(ImmediatelyAfterHeaderGuard) {
2964}
else if(Tok.
is(tok::l_paren)) {
2967 if(ReadMacroParameterList(MI, LastTok))
2981}
else if(LangOpts.C99 || LangOpts.CPlusPlus11) {
2984 Diag(Tok, diag::ext_c99_whitespace_required_after_macro_name);
2993 if(Tok.
is(tok::at))
2995 else if(Tok.
is(tok::unknown)) {
3002 Diag(Tok, diag::ext_missing_whitespace_after_macro_name);
3004 Diag(Tok, diag::warn_missing_whitespace_after_macro_name);
3007 if(!Tok.
is(tok::eod))
3015 while(Tok.
isNot(tok::eod)) {
3017Tokens.push_back(Tok);
3028 while(Tok.
isNot(tok::eod)) {
3031 if(!Tok.
isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
3032Tokens.push_back(Tok);
3034 if(VAOCtx.isVAOptToken(Tok)) {
3036 if(VAOCtx.isInVAOpt()) {
3037 Diag(Tok, diag::err_pp_vaopt_nested_use);
3042 if(Tok.
isNot(tok::l_paren)) {
3043 Diag(Tok, diag::err_pp_missing_lparen_in_vaopt_use);
3046Tokens.push_back(Tok);
3047VAOCtx.sawVAOptFollowedByOpeningParens(Tok.
getLocation());
3049 if(Tok.
is(tok::hashhash)) {
3050 Diag(Tok, diag::err_vaopt_paste_at_start);
3054}
else if(VAOCtx.isInVAOpt()) {
3055 if(Tok.
is(tok::r_paren)) {
3056 if(VAOCtx.sawClosingParen()) {
3057assert(Tokens.size() >= 3 &&
3058 "Must have seen at least __VA_OPT__( " 3059 "and a subsequent tok::r_paren");
3060 if(Tokens[Tokens.size() - 2].is(tok::hashhash)) {
3061 Diag(Tok, diag::err_vaopt_paste_at_end);
3065}
else if(Tok.
is(tok::l_paren)) {
3079Tokens.push_back(Tok);
3086 if(Tok.
is(tok::hashhash)) {
3094 if(Tok.
is(tok::eod)) {
3095Tokens.push_back(LastTok);
3100Tokens[Tokens.size() - 1].is(tok::comma))
3104Tokens.push_back(LastTok);
3113 if(!VAOCtx.isVAOptToken(Tok) &&
3122LastTok.
setKind(tok::unknown);
3123Tokens.push_back(LastTok);
3126 Diag(Tok, diag::err_pp_stringize_not_parameter)
3127<< LastTok.
is(tok::hashat);
3133Tokens.push_back(LastTok);
3138 if(!VAOCtx.isVAOptToken(Tok)) {
3139Tokens.push_back(Tok);
3146 if(VAOCtx.isInVAOpt()) {
3147assert(Tok.
is(tok::eod) &&
"Must be at End Of preprocessing Directive");
3148 Diag(Tok, diag::err_pp_expected_after)
3149<< LastTok.
getKind() << tok::r_paren;
3150 Diag(VAOCtx.getUnmatchedOpeningParenLoc(), diag::note_matching) << tok::l_paren;
3161 returnII->
isStr(
"__strong") || II->
isStr(
"__weak") ||
3162II->
isStr(
"__unsafe_unretained") || II->
isStr(
"__autoreleasing");
3167voidPreprocessor::HandleDefineDirective(
3168 Token&DefineTok,
const boolImmediatelyAfterHeaderGuard) {
3172 boolMacroShadowsKeyword;
3173ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
3176 if(MacroNameTok.
is(tok::eod))
3183emitFinalMacroWarning(MacroNameTok,
false);
3187 if(CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
3189 MacroInfo*
constMI = ReadOptionalMacroParameterListAndBody(
3190MacroNameTok, ImmediatelyAfterHeaderGuard);
3194 if(MacroShadowsKeyword &&
3196 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
3201 if(NumTokens != 0) {
3213 if(SkippingUntilPCHThroughHeader) {
3216LangOpts.MicrosoftExt))
3220 if(!LangOpts.MicrosoftExt)
3231emitFinalMacroWarning(MacroNameTok,
false);
3244LangOpts.MicrosoftExt)) {
3263 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
3267!MI->
isIdenticalTo(*OtherMI, *
this,
LangOpts.MicrosoftExt)) {
3285!MacroExpansionInDirectivesOverride &&
3294Callbacks->MacroDefined(MacroNameTok, MD);
3307Tok.
setKind(tok::kw__Static_assert);
3316voidPreprocessor::HandleUndefDirective() {
3320ReadMacroName(MacroNameTok,
MU_Undef);
3323 if(MacroNameTok.
is(tok::eod))
3335emitFinalMacroWarning(MacroNameTok,
true);
3345 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
3350Undef = AllocateUndefMacroDirective(MacroNameTok.
getLocation());
3356Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
3371voidPreprocessor::HandleIfdefDirective(
Token&
Result,
3372 const Token&HashToken,
3374 boolReadAnyTokensBeforeDirective) {
3379ReadMacroName(MacroNameTok);
3382 if(MacroNameTok.
is(tok::eod)) {
3385SkipExcludedConditionalBlock(HashToken.
getLocation(),
3405 if(!ReadAnyTokensBeforeDirective && !MI) {
3406assert(isIfndef &&
"#ifdef shouldn't reach here");
3418Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3420Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3423 boolRetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3427 if(PPOpts->SingleFileParseMode && !MI) {
3433}
else if(!MI == isIfndef || RetainExcludedCB) {
3440SkipExcludedConditionalBlock(HashToken.
getLocation(),
3449voidPreprocessor::HandleIfDirective(
Token&IfToken,
3450 const Token&HashToken,
3451 boolReadAnyTokensBeforeDirective) {
3456 constDirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
3457 const boolConditionalTrue = DER.Conditional;
3466 if(!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
3478 boolRetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3482 if(PPOpts->SingleFileParseMode && DER.IncludedUndefinedIds) {
3487}
else if(ConditionalTrue || RetainExcludedCB) {
3501voidPreprocessor::HandleEndifDirective(
Token&EndifToken) {
3510 Diag(EndifToken, diag::err_pp_endif_without_if);
3519 "This code should only be reachable in the non-skipping case!");
3527voidPreprocessor::HandleElseDirective(
Token&
Result,
const Token&HashToken) {
3535 Diag(
Result, diag::pp_err_else_without_if);
3547Callbacks->Else(
Result.getLocation(), CI.
IfLoc);
3549 boolRetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3552 if((PPOpts->SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3563 true,
Result.getLocation());
3567voidPreprocessor::HandleElifFamilyDirective(
Token&ElifToken,
3568 const Token&HashToken,
3580 if(LangOpts.CPlusPlus)
3581DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
3582: diag::ext_cxx23_pp_directive;
3584DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
3585: diag::ext_c23_pp_directive;
3586 Diag(ElifToken, DiagID) << DirKind;
3599 Diag(ElifToken, diag::pp_err_elif_without_if) << DirKind;
3609 Diag(ElifToken, diag::pp_err_elif_after_else) << DirKind;
3614Callbacks->Elif(ElifToken.
getLocation(), ConditionRange,
3617 casetok::pp_elifdef:
3620 casetok::pp_elifndef:
3621Callbacks->Elifndef(ElifToken.
getLocation(), ConditionRange, CI.
IfLoc);
3624assert(
false&&
"unexpected directive kind");
3629 boolRetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3632 if((PPOpts->SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3641SkipExcludedConditionalBlock(
3646std::optional<LexEmbedParametersResult>
3650 tok::TokenKindEndTokenKind = ForHasEmbed ? tok::r_paren : tok::eod;
3652 autoDiagMismatchedBracesAndSkipToEOD =
3654std::pair<tok::TokenKind, SourceLocation> Matches) {
3656 Diag(Matches.second, diag::note_matching) << Matches.first;
3657 if(CurTok.
isNot(tok::eod))
3662 if(CurTok.
isNot(Kind)) {
3663 Diag(CurTok, diag::err_expected) << Kind;
3664 if(CurTok.
isNot(tok::eod))
3681 autoLexPPParameterName = [&]() -> std::optional<std::string> {
3684 if(!ExpectOrDiagAndSkipToEOD(tok::identifier))
3685 returnstd::nullopt;
3692 if(CurTok.
is(tok::coloncolon)) {
3695 if(!ExpectOrDiagAndSkipToEOD(tok::identifier))
3696 returnstd::nullopt;
3702 return(llvm::Twine(Prefix->
getName()) +
"::"+ Suffix->
getName()).str();
3704 returnPrefix->
getName().str();
3711 autoNormalizeParameterName = [](StringRef Name) {
3712 if(Name.size() > 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
3713 returnName.substr(2, Name.size() - 4);
3717 autoLexParenthesizedIntegerExpr = [&]() -> std::optional<size_t> {
3720 if(!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3721 returnstd::nullopt;
3726 boolEvaluatedDefined;
3727DirectiveEvalResult LimitEvalResult = EvaluateDirectiveExpression(
3728ParameterIfNDef, CurTok, EvaluatedDefined,
false);
3730 if(!LimitEvalResult.Value) {
3733assert(CurTok.
is(tok::eod) &&
"expect to be at the end of directive");
3734 returnstd::nullopt;
3737 if(!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3738 returnstd::nullopt;
3745 if(EvaluatedDefined) {
3746 Diag(CurTok, diag::err_defined_in_pp_embed);
3747 returnstd::nullopt;
3750 if(LimitEvalResult.Value) {
3751 constllvm::APSInt &
Result= *LimitEvalResult.Value;
3752 if(
Result.isNegative()) {
3753 Diag(CurTok, diag::err_requires_positive_value)
3755 returnstd::nullopt;
3757 return Result.getLimitedValue();
3759 returnstd::nullopt;
3765 returntok::r_paren;
3767 returntok::r_brace;
3769 returntok::r_square;
3771llvm_unreachable(
"should not get here");
3775 autoLexParenthesizedBalancedTokenSoup =
3777std::vector<std::pair<tok::TokenKind, SourceLocation>> BracketStack;
3780 if(!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3784 boolWaitingForInnerCloseParen =
false;
3785 while(CurTok.
isNot(tok::eod) &&
3786(WaitingForInnerCloseParen || CurTok.
isNot(tok::r_paren))) {
3791WaitingForInnerCloseParen =
true;
3798WaitingForInnerCloseParen =
false;
3801 casetok::r_square: {
3803GetMatchingCloseBracket(BracketStack.back().first);
3804 if(BracketStack.empty() || CurTok.
getKind() != Matching) {
3805DiagMismatchedBracesAndSkipToEOD(Matching, BracketStack.back());
3808BracketStack.pop_back();
3811Tokens.push_back(CurTok);
3816 if(!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3824 while(!CurTok.
isOneOf(EndTokenKind, tok::eod)) {
3826std::optional<std::string> ParamName = LexPPParameterName();
3828 returnstd::nullopt;
3829StringRef
Parameter= NormalizeParameterName(*ParamName);
3836 if(
Result.MaybeLimitParam)
3839std::optional<size_t> Limit = LexParenthesizedIntegerExpr();
3841 returnstd::nullopt;
3842 Result.MaybeLimitParam =
3844}
else if(
Parameter==
"clang::offset") {
3845 if(
Result.MaybeOffsetParam)
3848std::optional<size_t> Offset = LexParenthesizedIntegerExpr();
3850 returnstd::nullopt;
3852*Offset, {ParamStartLoc, CurTok.
getLocation()}};
3854 if(
Result.MaybePrefixParam)
3858 if(!LexParenthesizedBalancedTokenSoup(Soup))
3859 returnstd::nullopt;
3861std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
3863 if(
Result.MaybeSuffixParam)
3867 if(!LexParenthesizedBalancedTokenSoup(Soup))
3868 returnstd::nullopt;
3870std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
3872 if(
Result.MaybeIfEmptyParam)
3876 if(!LexParenthesizedBalancedTokenSoup(Soup))
3877 returnstd::nullopt;
3879std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
3881++
Result.UnrecognizedParams;
3885 if(CurTok.
is(tok::l_paren)) {
3887 if(!LexParenthesizedBalancedTokenSoup(Soup))
3888 returnstd::nullopt;
3891 Diag(CurTok, diag::err_pp_unknown_parameter) << 1 <<
Parameter;
3892 returnstd::nullopt;
3899voidPreprocessor::HandleEmbedDirectiveImpl(
3901StringRef BinaryContents) {
3902 if(BinaryContents.empty()) {
3910 size_tTokCount = Toks.size();
3911 autoNewToks = std::make_unique<Token[]>(TokCount);
3912llvm::copy(Toks, NewToks.get());
3913EnterTokenStream(std::move(NewToks), TokCount,
true,
true);
3920 size_tTotalNumToks = 1 + NumPrefixToks + NumSuffixToks;
3922 autoToks = std::make_unique<Token[]>(TotalNumToks);
3927CurIdx += NumPrefixToks;
3931 Data->BinaryData = BinaryContents;
3933Toks[CurIdx].startToken();
3934Toks[CurIdx].setKind(tok::annot_embed);
3935Toks[CurIdx].setAnnotationRange(HashLoc);
3936Toks[CurIdx++].setAnnotationValue(
Data);
3941CurIdx += NumSuffixToks;
3944assert(CurIdx == TotalNumToks &&
"Calculated the incorrect number of tokens");
3945EnterTokenStream(std::move(Toks), TotalNumToks,
true,
true);
3952 Diag(EmbedTok, diag::warn_compat_pp_embed_directive);
3954 Diag(EmbedTok, diag::ext_pp_embed_directive)
3955<< (LangOpts.CPlusPlus ?
1 :
0);
3962 if(FilenameTok.
isNot(tok::header_name)) {
3964 if(FilenameTok.
isNot(tok::eod))
3977std::optional<LexEmbedParametersResult> Params =
3980assert((Params || CurTok.
is(tok::eod)) &&
3981 "expected success or to be at the end of the directive");
3988StringRef OriginalFilename =
Filename;
3996 if(!MaybeFileRef) {
3998 if(Callbacks && Callbacks->EmbedFileNotFound(OriginalFilename)) {
4001 Diag(FilenameTok, diag::err_pp_file_not_found) <<
Filename;
4004std::optional<llvm::MemoryBufferRef> MaybeFile =
4008 Diag(FilenameTok, diag::err_cannot_open_file)
4009<<
Filename<<
"a buffer to the contents could not be created";
4012StringRef BinaryContents = MaybeFile->getBuffer();
4017 if(Params->MaybeOffsetParam) {
4022BinaryContents = BinaryContents.substr(Params->MaybeOffsetParam->Offset);
4025 if(Params->MaybeLimitParam) {
4029BinaryContents = BinaryContents.substr(0, Params->MaybeLimitParam->Limit);
4033Callbacks->EmbedDirective(HashLoc,
Filename, isAngled, MaybeFileRef,
4035HandleEmbedDirectiveImpl(HashLoc, *Params, BinaryContents);
static bool isInMainFile(const clang::Diagnostic &D)
Defines interfaces for clang::DirectoryEntry and clang::DirectoryEntryRef.
Defines the clang::FileManager interface and associated types.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
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 ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit, SrcMgr::CharacteristicKind &FileKind, Preprocessor &PP)
ReadLineMarkerFlags - Parse and validate any flags at the end of a GNU line marker directive.
static bool isConfigurationPattern(Token &MacroName, MacroInfo *MI, const LangOptions &LOptions)
static std::optional< StringRef > findSimilarStr(StringRef LHS, const std::vector< StringRef > &Candidates)
Find a similar string in Candidates.
static bool isLanguageDefinedBuiltin(const SourceManager &SourceMgr, const MacroInfo *MI, const StringRef MacroName)
static bool trySimplifyPath(SmallVectorImpl< StringRef > &Components, StringRef RealPathName, llvm::sys::path::Style Separator)
static void diagnoseAutoModuleImport(Preprocessor &PP, SourceLocation HashLoc, Token &IncludeTok, ArrayRef< std::pair< IdentifierInfo *, SourceLocation > > Path, SourceLocation PathEnd)
Produce a diagnostic informing the user that a #include or similar was implicitly treated as a module...
static bool warnByDefaultOnWrongCase(StringRef Include)
MacroDiag
Enumerates possible cases of #define/#undef a reserved identifier.
@ MD_ReservedAttributeIdentifier
static bool isFeatureTestMacro(StringRef MacroName)
static bool GetLineValue(Token &DigitTok, unsigned &Val, unsigned DiagID, Preprocessor &PP, bool IsGNULineDirective=false)
GetLineValue - Convert a numeric token into an unsigned value, emitting Diagnostic DiagID if it is in...
PPElifDiag
Enumerates possible select values for the pp_err_elif_after_else and pp_err_elif_without_if diagnosti...
static bool isReservedCXXAttributeName(Preprocessor &PP, IdentifierInfo *II)
static MacroDiag shouldWarnOnMacroUndef(Preprocessor &PP, IdentifierInfo *II)
static bool isObjCProtectedMacro(const IdentifierInfo *II)
static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II)
Defines the clang::Preprocessor interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines the clang::SourceLocation class and associated facilities.
static bool isInvalid(LocType Loc, bool *Invalid)
Defines the SourceManager interface.
Defines the clang::TokenKind enum and support functions.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
__device__ __2f16 float c
ResetMacroExpansionHelper(Preprocessor *pp)
~ResetMacroExpansionHelper()
static AttrArgsInfo getCXX11AttrArgsInfo(const IdentifierInfo *Name)
Represents a character-granular source range.
static CharSourceRange getCharRange(SourceRange R)
SourceLocation getEnd() const
virtual void CodeCompleteMacroName(bool IsDefinition)
Callback invoked when performing code completion in a context where the name of a macro is expected.
virtual void CodeCompleteInConditionalExclusion()
Callback invoked when performing code completion within a block of code that was excluded due to prep...
virtual void CodeCompleteDirective(bool InConditional)
Callback invoked when performing code completion for a preprocessor directive.
A directive for a defined macro or a macro imported from a module.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...
StringRef getName() const
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
const FileEntry & getFileEntry() const
DirectoryEntryRef getDir() const
Cached information about one file (either on disk or in the virtual file system).
StringRef tryGetRealPathName() const
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements support for file system lookup, file system caching, and directory search management.
llvm::Expected< DirectoryEntryRef > getDirectoryRef(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
LLVM_DEPRECATED("Functions returning DirectoryEntry are deprecated.", "getOptionalDirectoryRef()") llvm LLVM_DEPRECATED("Functions returning FileEntry are deprecated.", "getOptionalFileRef()") llvm llvm::Expected< FileEntryRef > getFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true, bool IsText=true)
Lookup, cache, and verify the specified directory (real or virtual).
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
One of these records is kept for each identifier that is lexed.
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.
bool isCPlusPlusOperatorKeyword() const
bool hadMacroDefinition() const
Returns true if this identifier was #defined to some value at any moment.
bool hasMacroDefinition() const
Return true if this identifier is #defined to some other value.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
bool isKeyword(const LangOptions &LangOpts) const
Return true if this token is a keyword in the specified language.
ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const
Determine whether this is a name reserved for the implementation (C99 7.1.3, C++ [lib....
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool IsHeaderFile
Indicates whether the front-end is explicitly told that the input is a header file (i....
std::string CurrentModule
The name of the current module, of which the main source file is a part.
Encapsulates changes to the "macros namespace" (the location where the macro name became active,...
const MacroInfo * getMacroInfo() const
Encapsulates the data about a macro definition (e.g.
bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP, bool Syntactically) const
Return true if the specified macro definition is equal to this macro in spelling, arguments,...
bool isUsed() const
Return false if this macro is defined in the main file and has not yet been used.
bool isC99Varargs() const
bool isAllowRedefinitionsWithoutWarning() const
Return true if this macro can be redefined without warning.
void setHasCommaPasting()
unsigned getNumTokens() const
Return the number of tokens that this macro expands to.
const Token & getReplacementToken(unsigned Tok) const
void setDefinitionEndLoc(SourceLocation EndLoc)
Set the location of the last token in the macro.
bool isBuiltinMacro() const
Return true if this macro requires processing before expansion.
void setTokens(ArrayRef< Token > Tokens, llvm::BumpPtrAllocator &PPAllocator)
void setParameterList(ArrayRef< IdentifierInfo * > List, llvm::BumpPtrAllocator &PPAllocator)
Set the specified list of identifiers as the parameter list for this macro.
SourceLocation getDefinitionLoc() const
Return the location that the macro was defined at.
void setIsFunctionLike()
Function/Object-likeness.
bool isObjectLike() const
void setIsWarnIfUnused(bool val)
Set the value of the IsWarnIfUnused flag.
int getParameterNum(const IdentifierInfo *Arg) const
Return the parameter number of the specified identifier, or -1 if the identifier is not a formal para...
bool isWarnIfUnused() const
Return true if we should emit a warning if the macro is unused.
void setIsC99Varargs()
Varargs querying methods. This can only be set for function-like macros.
Describes the result of attempting to load a module.
bool isMissingExpected() const
Determines whether the module, which failed to load, was actually a submodule that we expected to see...
bool isConfigMismatch() const
Determines whether the module failed to load due to a configuration mismatch with an explicitly-named...
virtual ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective)=0
Attempt to load the given module.
void diagnoseHeaderInclusion(Module *RequestingModule, bool RequestingModuleIsModuleInterface, SourceLocation FilenameLoc, StringRef Filename, FileEntryRef File)
Reports errors if a module must not include a specific file.
KnownHeader findModuleForHeader(FileEntryRef File, bool AllowTextual=false, bool AllowExcluded=false)
Retrieve the module that owns the given header file, if any.
bool shouldImportRelativeToBuiltinIncludeDir(StringRef FileName, Module *Module) const
OptionalDirectoryEntryRef getBuiltinDir() const
Get the directory that contains Clang-supplied include files.
@ ExcludedHeader
This header is explicitly excluded from the module.
@ TextualHeader
This header is part of the module (for layering purposes) but should be textually included.
Describes a module or submodule.
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
bool isForBuilding(const LangOptions &LangOpts) const
Determine whether this module can be built in this compilation.
@ Hidden
All of the names in this module are hidden.
SourceLocation DefinitionLoc
The location of the module definition.
Module * Parent
The parent of this module.
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers).
std::string Name
The name of this module.
bool isAvailable() const
Determine whether this module is available for use within the current translation unit.
bool isHeaderUnit() const
Is this module a header unit.
Module * ShadowingModule
A module with the same name that shadows this module.
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
bool getHasReadAnyTokensVal() const
getHasReadAnyTokensVal - This is used for the #ifndef handshake at the top of the file when reading p...
void ExitTopLevelConditional()
Called when the lexer exits the top-level conditional.
void SetDefinedMacro(IdentifierInfo *M, SourceLocation Loc)
void SetReadToken(bool Value)
SetReadToken - Set whether the value of 'ReadAnyTokens'.
bool getImmediatelyAfterTopLevelIfndef() const
getImmediatelyAfterTopLevelIfndef - returns true if the last directive was an #ifndef at the beginnin...
void EnterTopLevelConditional()
Invoked when a top level conditional (except #ifndef) is found.
void resetImmediatelyAfterTopLevelIfndef()
void EnterTopLevelIfndef(const IdentifierInfo *M, SourceLocation Loc)
Called when entering a top-level #ifndef directive (or the "\#if !defined" equivalent) without any pr...
Preprocessor standard embed parameter "if_empty" if_empty( balanced-token-seq )
Preprocessor standard embed parameter "limit" limit( constant-expression )
Preprocessor extension embed parameter "clang::offset" clang::offset( constant-expression )
Preprocessor standard embed parameter "prefix" prefix( balanced-token-seq )
Preprocessor standard embed parameter "suffix" suffix( balanced-token-seq )
void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping, bool FoundNonSkip, bool FoundElse)
pushConditionalLevel - When we enter a #if directive, this keeps track of what we are currently in fo...
unsigned getConditionalStackDepth() const
bool LexingRawMode
True if in raw mode.
bool ParsingPreprocessorDirective
True when parsing #XXX; turns '\n' into a tok::eod token.
MultipleIncludeOpt MIOpt
A state machine that detects the #ifndef-wrapping a file idiom for the multiple-include optimization.
bool popConditionalLevel(PPConditionalInfo &CI)
popConditionalLevel - Remove an entry off the top of the conditional stack, returning information abo...
OptionalFileEntryRef getFileEntry() const
getFileEntry - Return the FileEntry corresponding to this FileID.
PPConditionalInfo & peekConditionalLevel()
Return the top of the conditional stack.
virtual SourceLocation getSourceLocation()=0
Return the source location for the next observable location.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
MacroDirective * getLocalMacroDirective(const IdentifierInfo *II) const
Given an identifier, return its latest non-imported MacroDirective if it is #define'd and not #undef'...
void markClangModuleAsAffecting(Module *M)
Mark the given clang module as affecting the current clang module or translation unit.
OptionalFileEntryRef LookupEmbedFile(StringRef Filename, bool isAngled, bool OpenFile, const FileEntry *LookupFromFile=nullptr)
Given a "Filename" or <Filename> reference, look up the indicated embed resource.
const MacroInfo * getMacroInfo(const IdentifierInfo *II) const
bool isRecordingPreamble() const
void HandleSkippedDirectiveWhileUsingPCH(Token &Result, SourceLocation HashLoc)
Process directives while skipping until the through header or #pragma hdrstop is found.
bool isInPrimaryFile() const
Return true if we're in the top-level file, not in a #include.
void markMacroAsUsed(MacroInfo *MI)
A macro is used, update information about macros that need unused warnings.
void EnterSubmodule(Module *M, SourceLocation ImportLoc, bool ForPragma)
void setCodeCompletionReached()
Note that we hit the code-completion point.
StringRef getNamedModuleName() const
Get the named module name we're preprocessing.
void makeModuleVisible(Module *M, SourceLocation Loc)
void Lex(Token &Result)
Lex the next token for this preprocessor.
bool EnterSourceFile(FileID FID, ConstSearchDirIterator Dir, SourceLocation Loc, bool IsFirstIncludeOfFile=true)
Add a source file to the top of the include stack and start lexing tokens from it instead of the curr...
void LexNonComment(Token &Result)
Lex a token.
SourceRange DiscardUntilEndOfDirective()
Read and discard all tokens remaining on the current line until the tok::eod token is found.
SourceLocation CheckEndOfDirective(const char *DirType, bool EnableMacros=false)
Ensure that the next token is a tok::eod token.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
SourceManager & getSourceManager() const
MacroDefinition getMacroDefinition(const IdentifierInfo *II)
bool CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef, bool *ShadowFlag=nullptr)
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 AdvanceToTokenCharacter(SourceLocation TokStart, unsigned Char) const
Given a location that specifies the start of a token, return a new location that specifies a characte...
Module * getCurrentModule()
Retrieves the module that we're currently building, if any.
bool hadModuleLoaderFatalFailure() const
const TargetInfo & getTargetInfo() const
FileManager & getFileManager() const
bool LexHeaderName(Token &Result, bool AllowMacroExpansion=true)
Lex a token, forming a header-name token if possible.
bool isPCHThroughHeader(const FileEntry *FE)
Returns true if the FileEntry is the PCH through header.
friend class VariadicMacroScopeGuard
MacroInfo * AllocateMacroInfo(SourceLocation L)
Allocate a new MacroInfo object with the provided SourceLocation.
void LexUnexpandedToken(Token &Result)
Just like Lex, but disables macro expansion of identifier tokens.
bool alreadyIncluded(FileEntryRef File) const
Return true if this header has already been included.
FileID getPredefinesFileID() const
Returns the FileID for the preprocessor predefines.
void LexUnexpandedNonComment(Token &Result)
Like LexNonComment, but this disables macro expansion of identifier tokens.
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 emitMacroExpansionWarnings(const Token &Identifier, bool IsIfnDef=false) const
bool isNextPPTokenLParen()
Determine whether the next preprocessor token to be lexed is a '('.
void HandleDirective(Token &Result)
Callback invoked when the lexer sees a # token at the start of a line.
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
bool isInNamedModule() const
If we are preprocessing a named module.
OptionalFileEntryRef getHeaderToIncludeForDiagnostics(SourceLocation IncLoc, SourceLocation MLoc)
We want to produce a diagnostic at location IncLoc concerning an unreachable effect at location MLoc ...
DefMacroDirective * appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI, SourceLocation Loc)
void HandlePragmaHdrstop(Token &Tok)
DiagnosticsEngine & getDiagnostics() const
std::optional< LexEmbedParametersResult > LexEmbedParameters(Token &Current, bool ForHasEmbed)
Lex the parameters for an #embed directive, returns nullopt on error.
Module * getModuleForLocation(SourceLocation Loc, bool AllowTextual)
Find the module that owns the source or header file that Loc points to.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
bool usingPCHWithThroughHeader()
True if using a PCH with a through header.
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.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
SourceLocation getIncludeLoc() const
Return the presumed include location of this location.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
bool isWrittenInBuiltinFile(SourceLocation Loc) const
Returns whether Loc is located in a <built-in> file.
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.
bool isWrittenInCommandLineFile(SourceLocation Loc) const
Returns whether Loc is located in a <command line> file.
OptionalFileEntryRef getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
StringRef getBufferName(SourceLocation Loc, bool *Invalid=nullptr) const
Return the filename or buffer identifier of the buffer the location is in.
FileID createFileID(FileEntryRef SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, int LoadedID=0, SourceLocation::UIntTy LoadedOffset=0)
Create a new FileID that represents the specified file being #included from the specified IncludePosi...
bool isMainFile(const FileEntry &SourceFile)
Returns true when the given FileEntry corresponds to the main file.
FileID getMainFileID() const
Returns the FileID of the main source file.
CharSourceRange getExpansionRange(SourceLocation Loc) const
Given a SourceLocation object, return the range of tokens covered by the expansion in the ultimate fi...
unsigned getLineTableFilenameID(StringRef Str)
Return the uniqued ID for the specified filename.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const
Return the file characteristic of the specified source location, indicating whether this is a normal ...
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID.
std::optional< llvm::MemoryBufferRef > getMemoryBufferForFileOrNone(FileEntryRef File)
Retrieve the memory buffer associated with the given file.
A trivial tuple used to represent a source range.
void setBegin(SourceLocation b)
SourceLocation getEnd() const
SourceLocation getBegin() const
void setEnd(SourceLocation e)
StringLiteralParser - This decodes string escape characters and performs wide string analysis and Tra...
Exposes information about the current target.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getEndLoc() const
void setAnnotationEndLoc(SourceLocation L)
void clearFlag(TokenFlags Flag)
Unset the specified flag.
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 hasLeadingSpace() const
Return true if this token has whitespace before it.
void setLocation(SourceLocation L)
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
bool isNot(tok::TokenKind K) const
void setAnnotationValue(void *val)
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix.
void startToken()
Reset all flags to cleared.
bool needsCleaning() const
Return true if this token has trigraphs or escaped newlines in it.
void setIdentifierInfo(IdentifierInfo *II)
StringRef getRawIdentifier() const
getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode),...
A directive for an undefined macro.
A class for tracking whether we're inside a VA_OPT during a traversal of the tokens of a variadic mac...
An RAII class that tracks when the Preprocessor starts and stops lexing the definition of a (ISO C/C+...
void enterScope()
Client code should call this function just before the Preprocessor is about to Lex tokens from the de...
Directive - Abstract class representing a parsed verify directive.
A directive for setting the module visibility of a macro.
Defines the clang::TargetInfo interface.
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
uint32_t Literal
Literals are represented as positive integers.
bool Sub(InterpState &S, CodePtr OpPC)
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
PPKeywordKind
Provides a namespace for preprocessor keywords which start with a '#' at the beginning of the line.
The JSON file list parser is used to communicate input to InstallAPI.
bool isReservedInAllContexts(ReservedIdentifierStatus Status)
Determine whether an identifier is reserved in all contexts.
LLVM_READONLY char toLowercase(char c)
Converts the given ASCII character to its lowercase equivalent.
MacroUse
Context in which macro name is used.
LLVM_READONLY bool isAlphanumeric(unsigned char c)
Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].
@ Parameter
The parameter type of a method or function.
@ Result
The result type of a method or function.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
LLVM_READONLY bool isLowercase(unsigned char c)
Return true if this character is a lowercase ASCII letter: [a-z].
int hasAttribute(AttributeCommonInfo::Syntax Syntax, const IdentifierInfo *Scope, const IdentifierInfo *Attr, const TargetInfo &Target, const LangOptions &LangOpts)
Return the version number associated with the attribute if we recognize and implement the attribute s...
@ PIK_HashPragma
The pragma was introduced via #pragma.
Helper class to shuttle information about #embed directives from the preprocessor to the parser throu...
This structure is used to record entries in our framework cache.
OptionalDirectoryEntryRef Directory
The directory entry which should be used for the cached framework.
std::optional< PPEmbedParameterIfEmpty > MaybeIfEmptyParam
size_t SuffixTokenCount() const
std::optional< PPEmbedParameterSuffix > MaybeSuffixParam
std::optional< PPEmbedParameterPrefix > MaybePrefixParam
size_t PrefixTokenCount() const
Information about the conditional stack (#if directives) currently active.
bool FoundNonSkip
True if we have emitted tokens already, and now we're in an #else block or something.
SourceLocation IfLoc
Location where the conditional started.
bool WasSkipping
True if this was contained in a skipping directive, e.g., in a "\#if 0" block.
bool FoundElse
True if we've seen a #else in this block.
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