37#include "llvm/ADT/ArrayRef.h"
38#include "llvm/ADT/STLExtras.h"
39#include "llvm/ADT/ScopeExit.h"
40#include "llvm/ADT/SmallVector.h"
41#include "llvm/ADT/StringExtras.h"
42#include "llvm/ADT/StringRef.h"
43#include "llvm/ADT/StringSwitch.h"
44#include "llvm/Support/ErrorHandling.h"
45#include "llvm/Support/Path.h"
46#include "llvm/Support/SaveAndRestore.h"
61 static_assert(std::is_trivially_destructible_v<MacroInfo>,
"");
71Preprocessor::AllocateUndefMacroDirective(
SourceLocation UndefLoc) {
88 while (Tmp.
isNot(tok::eod)) {
89 assert(Tmp.
isNot(tok::eof) &&
"EOF seen while discarding directive tokens");
117 static constexpr StringRef ReservedMacro[] = {
120 "_CRT_NONSTDC_NO_WARNINGS",
121 "_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES",
122 "_CRT_SECURE_NO_WARNINGS",
125 "_GLIBCXX_ASSERTIONS",
126 "_GLIBCXX_CONCEPT_CHECKS",
128 "_GLIBCXX_DEBUG_PEDANTIC",
130 "_GLIBCXX_PARALLEL_ASSERTIONS",
131 "_GLIBCXX_SANITIZE_VECTOR",
132 "_GLIBCXX_USE_CXX11_ABI",
133 "_GLIBCXX_USE_DEPRECATED",
138 "_LARGEFILE64_SOURCE",
144 "_XOPEN_SOURCE_EXTENDED",
145 "__STDCPP_WANT_MATH_SPEC_FUNCS__",
146 "__STDC_FORMAT_MACROS",
148 return std::binary_search(std::begin(ReservedMacro), std::end(ReservedMacro),
154 const StringRef MacroName) {
164 if (MacroName.starts_with(
"__STDC"))
167 if (MacroName ==
"__cplusplus")
170 if (MacroName.starts_with(
"__cpp"))
183 if (Lang.CPlusPlus11 && (
Text ==
"override" ||
Text ==
"final"))
204 if (::llvm::sys::path::begin(Include)->equals_insensitive(
"boost"))
209 static const size_t MaxStdHeaderNameLen = 18u;
210 if (Include.size() > MaxStdHeaderNameLen)
215 for (
char &Ch : LowerInclude) {
217 if (
static_cast<unsigned char>(Ch) > 0x7f)
220 if (Ch >=
'A' && Ch <=
'Z')
223 else if (::llvm::sys::path::is_separator(Ch))
228 return llvm::StringSwitch<bool>(LowerInclude)
230 .Cases(
"assert.h",
"complex.h",
"ctype.h",
"errno.h",
"fenv.h",
true)
231 .Cases(
"float.h",
"inttypes.h",
"iso646.h",
"limits.h",
"locale.h",
true)
232 .Cases(
"math.h",
"setjmp.h",
"signal.h",
"stdalign.h",
"stdarg.h",
true)
233 .Cases(
"stdatomic.h",
"stdbool.h",
"stdckdint.h",
"stddef.h",
true)
234 .Cases(
"stdint.h",
"stdio.h",
"stdlib.h",
"stdnoreturn.h",
true)
235 .Cases(
"string.h",
"tgmath.h",
"threads.h",
"time.h",
"uchar.h",
true)
236 .Cases(
"wchar.h",
"wctype.h",
true)
239 .Cases(
"cassert",
"ccomplex",
"cctype",
"cerrno",
"cfenv",
true)
240 .Cases(
"cfloat",
"cinttypes",
"ciso646",
"climits",
"clocale",
true)
241 .Cases(
"cmath",
"csetjmp",
"csignal",
"cstdalign",
"cstdarg",
true)
242 .Cases(
"cstdbool",
"cstddef",
"cstdint",
"cstdio",
"cstdlib",
true)
243 .Cases(
"cstring",
"ctgmath",
"ctime",
"cuchar",
"cwchar",
true)
244 .Case(
"cwctype",
true)
247 .Cases(
"algorithm",
"fstream",
"list",
"regex",
"thread",
true)
248 .Cases(
"array",
"functional",
"locale",
"scoped_allocator",
"tuple",
true)
249 .Cases(
"atomic",
"future",
"map",
"set",
"type_traits",
true)
250 .Cases(
"bitset",
"initializer_list",
"memory",
"shared_mutex",
"typeindex",
true)
251 .Cases(
"chrono",
"iomanip",
"mutex",
"sstream",
"typeinfo",
true)
252 .Cases(
"codecvt",
"ios",
"new",
"stack",
"unordered_map",
true)
253 .Cases(
"complex",
"iosfwd",
"numeric",
"stdexcept",
"unordered_set",
true)
254 .Cases(
"condition_variable",
"iostream",
"ostream",
"streambuf",
"utility",
true)
255 .Cases(
"deque",
"istream",
"queue",
"string",
"valarray",
true)
256 .Cases(
"exception",
"iterator",
"random",
"strstream",
"vector",
true)
257 .Cases(
"forward_list",
"limits",
"ratio",
"system_error",
true)
260 .Cases(
"aio.h",
"arpa/inet.h",
"cpio.h",
"dirent.h",
"dlfcn.h",
true)
261 .Cases(
"fcntl.h",
"fmtmsg.h",
"fnmatch.h",
"ftw.h",
"glob.h",
true)
262 .Cases(
"grp.h",
"iconv.h",
"langinfo.h",
"libgen.h",
"monetary.h",
true)
263 .Cases(
"mqueue.h",
"ndbm.h",
"net/if.h",
"netdb.h",
"netinet/in.h",
true)
264 .Cases(
"netinet/tcp.h",
"nl_types.h",
"poll.h",
"pthread.h",
"pwd.h",
true)
265 .Cases(
"regex.h",
"sched.h",
"search.h",
"semaphore.h",
"spawn.h",
true)
266 .Cases(
"strings.h",
"stropts.h",
"sys/ipc.h",
"sys/mman.h",
"sys/msg.h",
true)
267 .Cases(
"sys/resource.h",
"sys/select.h",
"sys/sem.h",
"sys/shm.h",
"sys/socket.h",
true)
268 .Cases(
"sys/stat.h",
"sys/statvfs.h",
"sys/time.h",
"sys/times.h",
"sys/types.h",
true)
269 .Cases(
"sys/uio.h",
"sys/un.h",
"sys/utsname.h",
"sys/wait.h",
"syslog.h",
true)
270 .Cases(
"tar.h",
"termios.h",
"trace.h",
"ulimit.h",
true)
271 .Cases(
"unistd.h",
"utime.h",
"utmpx.h",
"wordexp.h",
true)
283static std::optional<StringRef>
287 for (StringRef
C : Candidates) {
288 if (LHS.equals_insensitive(
C)) {
296 size_t Length = LHS.size();
297 size_t MaxDist = Length < 3 ? Length - 1 : Length / 3;
299 std::optional<std::pair<StringRef, size_t>> SimilarStr;
300 for (StringRef
C : Candidates) {
301 size_t CurDist = LHS.edit_distance(
C,
true);
302 if (CurDist <= MaxDist) {
305 SimilarStr = {
C, CurDist};
306 }
else if (CurDist < SimilarStr->second) {
308 SimilarStr = {
C, CurDist};
314 return SimilarStr->first;
323 if (MacroNameTok.
is(tok::eod))
324 return Diag(MacroNameTok, diag::err_pp_missing_macro_name);
328 return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
334 ? diag::ext_pp_operator_used_as_macro_name
335 : diag::err_pp_operator_used_as_macro_name)
336 << II << MacroNameTok.
getKind();
343 return Diag(MacroNameTok, diag::err_defined_macro_name);
367 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id);
383void Preprocessor::ReadMacroName(
Token &MacroNameTok,
MacroUse isDefineUndef,
388 if (MacroNameTok.
is(tok::code_completion)) {
400 if (MacroNameTok.
isNot(tok::eod)) {
401 MacroNameTok.
setKind(tok::eod);
425 while (Tmp.
is(tok::comment))
428 if (Tmp.
is(tok::eod))
436 if ((LangOpts.GNUMode || LangOpts.C99 || LangOpts.CPlusPlus) &&
439 Diag(Tmp, diag::ext_pp_extra_tokens_at_eol) << DirType << Hint;
443void Preprocessor::SuggestTypoedDirective(
const Token &Tok,
449 std::vector<StringRef> Candidates = {
450 "if",
"ifdef",
"ifndef",
"elif",
"else",
"endif"
452 if (LangOpts.C23 || LangOpts.CPlusPlus23)
453 Candidates.insert(Candidates.end(), {
"elifdef",
"elifndef"});
461 StringRef SuggValue = *Sugg;
464 Diag(Tok, diag::warn_pp_invalid_directive) << 1 << SuggValue << Hint;
476void Preprocessor::SkipExcludedConditionalBlock(
SourceLocation HashTokenLoc,
478 bool FoundNonSkipPortion,
489 assert(!SkippingExcludedConditionalBlock &&
490 "calling SkipExcludedConditionalBlock recursively");
494 assert(!CurTokenLexer &&
"Conditional PP block cannot appear in a macro!");
495 assert(CurPPLexer &&
"Conditional PP block must be in a file!");
496 assert(CurLexer &&
"Conditional PP block but no current lexer set!");
498 if (PreambleConditionalStack.reachedEOFWhileSkipping())
499 PreambleConditionalStack.clearSkipInfo();
502 FoundNonSkipPortion, FoundElse);
512 struct SkippingRangeStateTy {
515 const char *BeginPtr =
nullptr;
516 unsigned *SkipRangePtr =
nullptr;
520 void beginLexPass() {
526 BeginPtr = PP.CurLexer->getBufferLocation();
527 SkipRangePtr = &PP.RecordedSkippedRanges[BeginPtr];
529 PP.CurLexer->seek(PP.CurLexer->getCurrentBufferOffset() + *SkipRangePtr,
534 void endLexPass(
const char *Hashptr) {
537 assert(PP.CurLexer->isDependencyDirectivesLexer());
542 if (!*SkipRangePtr) {
543 *SkipRangePtr = Hashptr - BeginPtr;
545 assert(*SkipRangePtr ==
unsigned(Hashptr - BeginPtr));
547 SkipRangePtr =
nullptr;
549 } SkippingRangeState(*
this);
552 if (CurLexer->isDependencyDirectivesLexer()) {
553 CurLexer->LexDependencyDirectiveTokenWhileSkipping(Tok);
555 SkippingRangeState.beginLexPass();
559 if (Tok.
is(tok::code_completion)) {
567 if (Tok.
is(tok::eof)) {
571 if (PreambleConditionalStack.isRecording())
572 PreambleConditionalStack.SkipInfo.emplace(HashTokenLoc, IfTokenLoc,
585 if (Tok.
is(tok::eof))
592 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
594 assert(Tok.
is(tok::hash));
595 const char *Hashptr = CurLexer->getBufferLocation() - Tok.
getLength();
596 assert(CurLexer->getSourceLocation(Hashptr) == Tok.
getLocation());
603 if (Tok.
isNot(tok::raw_identifier)) {
606 if (CurLexer) CurLexer->resetExtendedTokenMode();
617 char FirstChar = RI[0];
618 if (FirstChar >=
'a' && FirstChar <=
'z' &&
619 FirstChar !=
'i' && FirstChar !=
'e') {
622 if (CurLexer) CurLexer->resetExtendedTokenMode();
629 char DirectiveBuf[20];
635 size_t IdLen = DirectiveStr.size();
639 if (CurLexer) CurLexer->resetExtendedTokenMode();
642 memcpy(DirectiveBuf, &DirectiveStr[0], IdLen);
643 Directive = StringRef(DirectiveBuf, IdLen);
667 assert(!InCond &&
"Can't be skipping if not in a conditional!");
671 SkippingRangeState.endLexPass(Hashptr);
683 }
else if (Sub ==
"lse") {
690 SkippingRangeState.endLexPass(Hashptr);
694 Diag(Tok, diag::pp_err_else_after_else);
714 }
else if (Sub ==
"lif") {
718 SkippingRangeState.endLexPass(Hashptr);
735 assert(CurPPLexer->
LexingRawMode &&
"We have to be skipping here!");
738 DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
742 const bool CondValue = DER.Conditional;
756 }
else if (Sub ==
"lifdef" ||
758 bool IsElifDef =
Sub ==
"lifdef";
760 Token DirectiveToken = Tok;
763 SkippingRangeState.endLexPass(Hashptr);
768 if (LangOpts.CPlusPlus)
769 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
770 : diag::ext_cxx23_pp_directive;
772 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
773 : diag::ext_c23_pp_directive;
778 Diag(Tok, diag::pp_err_elif_after_else)
792 assert(CurPPLexer->
LexingRawMode &&
"We have to be skipping here!");
795 ReadMacroName(MacroNameTok);
800 if (MacroNameTok.
is(tok::eod)) {
816 Callbacks->Elifdef(DirectiveToken.
getLocation(), MacroNameTok,
819 Callbacks->Elifndef(DirectiveToken.
getLocation(), MacroNameTok,
824 if (
static_cast<bool>(MI) == IsElifDef) {
838 if (CurLexer) CurLexer->resetExtendedTokenMode();
849 Callbacks->SourceRangeSkipped(
881 IncLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
889 auto ID =
SM.getFileID(
SM.getExpansionLoc(
Loc));
890 auto FE =
SM.getFileEntryRefForID(ID);
899 bool InPrivateHeader =
false;
901 if (!Header.isAccessibleFrom(IncM)) {
906 InPrivateHeader =
true;
942 Loc =
SM.getIncludeLoc(ID);
954 bool *IsFrameworkFound,
bool SkipCache,
bool OpenFile,
bool CacheFailures) {
959 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
964 bool BuildSystemModule =
false;
965 if (!FromDir && !FromFile) {
988 Includers.push_back(std::make_pair(std::nullopt, *IncludeDir));
993 Includers.push_back(std::make_pair(*FileEnt, *CWD));
996 Includers.push_back(std::make_pair(*FileEnt, FileEnt->
getDir()));
1002 if (LangOpts.MSVCCompat && !isAngled) {
1003 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1004 if (IsFileLexer(ISEntry))
1006 Includers.push_back(std::make_pair(*FileEnt, FileEnt->
getDir()));
1011 CurDir = CurDirLookup;
1019 Filename, FilenameLoc, isAngled, TmpFromDir, &TmpCurDir,
1020 Includers, SearchPath, RelativePath, RequestingModule,
1021 SuggestedModule,
nullptr,
1022 nullptr, SkipCache)) {
1024 TmpFromDir = TmpCurDir;
1026 if (&FE->getFileEntry() == FromFile) {
1028 FromDir = TmpFromDir;
1037 Filename, FilenameLoc, isAngled, FromDir, &CurDir, Includers, SearchPath,
1038 RelativePath, RequestingModule, SuggestedModule, IsMapped,
1039 IsFrameworkFound, SkipCache, BuildSystemModule, OpenFile, CacheFailures);
1047 if (IsFileLexer()) {
1050 Filename, *CurFileEnt, SearchPath, RelativePath, RequestingModule,
1057 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1058 if (IsFileLexer(ISEntry)) {
1059 if ((CurFileEnt = ISEntry.ThePPLexer->
getFileEntry())) {
1061 Filename, *CurFileEnt, SearchPath, RelativePath,
1062 RequestingModule, SuggestedModule)) {
1070 return std::nullopt;
1077 if (llvm::sys::path::is_absolute(
Filename)) {
1081 return llvm::expectedToOptional(std::move(ShouldBeEntry));
1085 StringRef StartingFrom, StringRef
FileName,
1086 bool RemoveInitialFileComponentFromLookupPath) {
1087 llvm::sys::path::native(StartingFrom, LookupPath);
1088 if (RemoveInitialFileComponentFromLookupPath)
1089 llvm::sys::path::remove_filename(LookupPath);
1090 if (!LookupPath.empty() &&
1091 !llvm::sys::path::is_separator(LookupPath.back())) {
1092 LookupPath.push_back(llvm::sys::path::get_separator().front());
1101 if (LookupFromFile) {
1104 if (!FullFileDir.empty()) {
1105 SeparateComponents(LookupPath, FullFileDir,
Filename,
true);
1107 LookupPath, OpenFile,
true,
false);
1109 return llvm::expectedToOptional(std::move(ShouldBeEntry));
1110 llvm::consumeError(ShouldBeEntry.takeError());
1117 if (MaybeWorkingDirEntry) {
1119 StringRef WorkingDir = WorkingDirEntry.
getName();
1120 if (!WorkingDir.empty()) {
1121 SeparateComponents(LookupPath, WorkingDir,
Filename,
false);
1123 LookupPath, OpenFile,
true,
false);
1125 return llvm::expectedToOptional(std::move(ShouldBeEntry));
1126 llvm::consumeError(ShouldBeEntry.takeError());
1131 for (
const auto &Entry : PPOpts->EmbedEntries) {
1133 SeparateComponents(LookupPath, Entry,
Filename,
false);
1135 LookupPath, OpenFile,
true,
false);
1137 return llvm::expectedToOptional(std::move(ShouldBeEntry));
1138 llvm::consumeError(ShouldBeEntry.takeError());
1140 return std::nullopt;
1150 : PP(pp), save(pp->DisableMacroExpansion) {
1151 if (pp->MacroExpansionInDirectivesOverride)
1152 pp->DisableMacroExpansion =
false;
1156 PP->DisableMacroExpansion = save;
1173 if (II->getPPKeywordID() == tok::pp_define) {
1174 return HandleDefineDirective(
Result,
1177 if (SkippingUntilPCHThroughHeader &&
1178 II->getPPKeywordID() == tok::pp_include) {
1179 return HandleIncludeDirective(HashLoc,
Result);
1181 if (SkippingUntilPragmaHdrStop && II->getPPKeywordID() == tok::pp_pragma) {
1183 auto *II =
Result.getIdentifierInfo();
1184 if (II && II->getName() ==
"hdrstop")
1202 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
1204 bool ImmediatelyAfterTopLevelIfndef =
1232 switch (II->getPPKeywordID()) {
1233 case tok::pp_include:
1234 case tok::pp_import:
1235 case tok::pp_include_next:
1236 case tok::pp___include_macros:
1237 case tok::pp_pragma:
1239 Diag(
Result, diag::err_embedded_directive) << II->getName();
1240 Diag(*ArgMacro, diag::note_macro_expansion_here)
1255 if (SkippingUntilPCHThroughHeader || SkippingUntilPragmaHdrStop)
1258 switch (
Result.getKind()) {
1265 case tok::code_completion:
1271 case tok::numeric_constant:
1278 return HandleDigitDirective(
Result);
1288 return HandleIfDirective(
Result, SavedHash, ReadAnyTokensBeforeDirective);
1290 return HandleIfdefDirective(
Result, SavedHash,
false,
1292 case tok::pp_ifndef:
1293 return HandleIfdefDirective(
Result, SavedHash,
true,
1294 ReadAnyTokensBeforeDirective);
1296 case tok::pp_elifdef:
1297 case tok::pp_elifndef:
1301 return HandleElseDirective(
Result, SavedHash);
1303 return HandleEndifDirective(
Result);
1306 case tok::pp_include:
1309 case tok::pp___include_macros:
1314 case tok::pp_define:
1315 return HandleDefineDirective(
Result, ImmediatelyAfterTopLevelIfndef);
1317 return HandleUndefDirective();
1321 return HandleLineDirective();
1325 return HandleUserDiagnosticDirective(
Result,
false);
1328 case tok::pp_pragma:
1332 case tok::pp_import:
1334 case tok::pp_include_next:
1337 case tok::pp_warning:
1338 if (LangOpts.CPlusPlus)
1340 ? diag::warn_cxx23_compat_warning_directive
1341 : diag::ext_pp_warning_directive)
1344 Diag(
Result, LangOpts.C23 ? diag::warn_c23_compat_warning_directive
1345 : diag::ext_pp_warning_directive)
1348 return HandleUserDiagnosticDirective(
Result,
true);
1350 return HandleIdentSCCSDirective(
Result);
1352 return HandleIdentSCCSDirective(
Result);
1358 case tok::pp_assert:
1361 case tok::pp_unassert:
1365 case tok::pp___public_macro:
1367 return HandleMacroPublicDirective(
Result);
1370 case tok::pp___private_macro:
1372 return HandleMacroPrivateDirective();
1383 auto Toks = std::make_unique<Token[]>(2);
1385 Toks[0] = SavedHash;
1390 if (
Result.is(tok::hashhash))
1391 Toks[1].setKind(tok::unknown);
1396 EnterTokenStream(std::move(Toks), 2,
false,
false);
1402 Diag(
Result, diag::err_pp_invalid_directive) << 0;
1414 bool IsGNULineDirective=
false) {
1415 if (DigitTok.
isNot(tok::numeric_constant)) {
1416 PP.
Diag(DigitTok, DiagID);
1418 if (DigitTok.
isNot(tok::eod))
1424 IntegerBuffer.resize(DigitTok.
getLength());
1425 const char *DigitTokBegin = &IntegerBuffer[0];
1435 for (
unsigned i = 0; i != ActualLength; ++i) {
1438 if (DigitTokBegin[i] ==
'\'')
1441 if (!
isDigit(DigitTokBegin[i])) {
1443 diag::err_pp_line_digit_sequence) << IsGNULineDirective;
1448 unsigned NextVal = Val*10+(DigitTokBegin[i]-
'0');
1449 if (NextVal < Val) {
1450 PP.
Diag(DigitTok, DiagID);
1457 if (DigitTokBegin[0] ==
'0' && Val)
1459 << IsGNULineDirective;
1471void Preprocessor::HandleLineDirective() {
1479 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*
this))
1483 Diag(DigitTok, diag::ext_pp_line_zero);
1487 unsigned LineLimit = 32768U;
1488 if (LangOpts.C99 || LangOpts.CPlusPlus11)
1489 LineLimit = 2147483648U;
1490 if (LineNo >= LineLimit)
1491 Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
1492 else if (LangOpts.CPlusPlus11 && LineNo >= 32768U)
1493 Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
1495 int FilenameID = -1;
1501 if (StrTok.
is(tok::eod))
1503 else if (StrTok.
isNot(tok::string_literal)) {
1504 Diag(StrTok, diag::err_pp_line_invalid_filename);
1508 Diag(StrTok, diag::err_invalid_string_udl);
1514 assert(
Literal.isOrdinary() &&
"Didn't allow wide strings in");
1520 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1555 if (FlagTok.
is(tok::eod))
return false;
1556 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1563 if (FlagTok.
is(tok::eod))
return false;
1564 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1566 }
else if (FlagVal == 2) {
1582 SM.getDecomposedExpansionLoc(IncLoc).first != CurFileID) {
1583 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);
1589 if (FlagTok.
is(tok::eod))
return false;
1590 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1596 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1604 if (FlagTok.
is(tok::eod))
return false;
1605 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1610 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1618 if (FlagTok.
is(tok::eod))
return false;
1621 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1633void Preprocessor::HandleDigitDirective(
Token &DigitTok) {
1637 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
1644 bool IsFileEntry =
false, IsFileExit =
false;
1645 int FilenameID = -1;
1650 if (StrTok.
is(tok::eod)) {
1651 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1654 }
else if (StrTok.
isNot(tok::string_literal)) {
1655 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1659 Diag(StrTok, diag::err_invalid_string_udl);
1665 assert(
Literal.isOrdinary() &&
"Didn't allow wide strings in");
1671 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1681 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1685 if (!(IsFileExit &&
Literal.GetString().empty()))
1691 IsFileExit, FileKind);
1700 else if (IsFileExit)
1709void Preprocessor::HandleUserDiagnosticDirective(
Token &Tok,
1717 CurLexer->ReadToEndOfLine(&Message);
1721 StringRef Msg = Message.str().ltrim(
' ');
1724 Diag(Tok, diag::pp_hash_warning) << Msg;
1726 Diag(Tok, diag::err_pp_hash_error) << Msg;
1731void Preprocessor::HandleIdentSCCSDirective(
Token &Tok) {
1733 Diag(Tok, diag::ext_pp_ident_directive);
1740 if (StrTok.
isNot(tok::string_literal) &&
1741 StrTok.
isNot(tok::wide_string_literal)) {
1742 Diag(StrTok, diag::err_pp_malformed_ident);
1743 if (StrTok.
isNot(tok::eod))
1749 Diag(StrTok, diag::err_invalid_string_udl);
1766void Preprocessor::HandleMacroPublicDirective(
Token &Tok) {
1768 ReadMacroName(MacroNameTok,
MU_Undef);
1771 if (MacroNameTok.
is(tok::eod))
1783 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1793void Preprocessor::HandleMacroPrivateDirective() {
1795 ReadMacroName(MacroNameTok,
MU_Undef);
1798 if (MacroNameTok.
is(tok::eod))
1810 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1830 StringRef &Buffer) {
1832 assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1844 if (Buffer[0] ==
'<') {
1845 if (Buffer.back() !=
'>') {
1846 Diag(
Loc, diag::err_pp_expects_filename);
1847 Buffer = StringRef();
1851 }
else if (Buffer[0] ==
'"') {
1852 if (Buffer.back() !=
'"') {
1853 Diag(
Loc, diag::err_pp_expects_filename);
1854 Buffer = StringRef();
1859 Diag(
Loc, diag::err_pp_expects_filename);
1860 Buffer = StringRef();
1865 if (Buffer.size() <= 2) {
1866 Diag(
Loc, diag::err_pp_empty_filename);
1867 Buffer = StringRef();
1872 Buffer = Buffer.substr(1, Buffer.size()-2);
1879 void *AnnotationVal) {
1882 auto Tok = std::make_unique<Token[]>(1);
1888 EnterTokenStream(std::move(Tok), 1,
true,
false);
1895 ArrayRef<std::pair<IdentifierInfo *, SourceLocation>>
Path,
1898 for (
size_t I = 0, N =
Path.size(); I != N; ++I) {
1901 PathString +=
Path[I].first->getName();
1904 int IncludeKind = 0;
1906 case tok::pp_include:
1910 case tok::pp_import:
1914 case tok::pp_include_next:
1918 case tok::pp___include_macros:
1923 llvm_unreachable(
"unknown include directive kind");
1926 PP.
Diag(HashLoc, diag::remark_pp_include_directive_modular_translation)
1927 << IncludeKind << PathString;
1934 StringRef RealPathName,
1935 llvm::sys::path::Style Separator) {
1936 auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName);
1937 auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName);
1939 bool SuggestReplacement =
false;
1941 auto IsSep = [Separator](StringRef Component) {
1942 return Component.size() == 1 &&
1943 llvm::sys::path::is_separator(Component[0], Separator);
1948 for (
auto &Component : llvm::reverse(Components)) {
1949 if (
"." == Component) {
1950 }
else if (
".." == Component) {
1954 }
else if (RealPathComponentIter != RealPathComponentEnd) {
1955 if (!IsSep(Component) && !IsSep(*RealPathComponentIter) &&
1956 Component != *RealPathComponentIter) {
1960 SuggestReplacement =
1961 RealPathComponentIter->equals_insensitive(Component);
1962 if (!SuggestReplacement)
1964 Component = *RealPathComponentIter;
1966 ++RealPathComponentIter;
1969 return SuggestReplacement;
1978 Module *ShadowingModule =
nullptr;
1986 }
else if (ShadowingModule) {
1989 diag::note_previous_definition);
2000std::pair<ConstSearchDirIterator, const FileEntry *>
2001Preprocessor::getIncludeNextStart(
const Token &IncludeNextTok)
const {
2006 const FileEntry *LookupFromFile =
nullptr;
2014 Diag(IncludeNextTok, diag::pp_include_next_in_primary);
2015 }
else if (CurLexerSubmodule) {
2018 assert(CurPPLexer &&
"#include_next directive in macro?");
2020 LookupFromFile = *FE;
2022 }
else if (!Lookup) {
2027 Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
2033 return {Lookup, LookupFromFile};
2049 if (FilenameTok.
isNot(tok::header_name)) {
2051 if (FilenameTok.
isNot(tok::eod))
2063 auto Action = HandleHeaderIncludeOrImport(HashLoc, IncludeTok, FilenameTok,
2064 EndLoc, LookupFrom, LookupFromFile);
2065 switch (Action.Kind) {
2066 case ImportAction::None:
2067 case ImportAction::SkippedModuleImport:
2069 case ImportAction::ModuleBegin:
2071 tok::annot_module_begin, Action.ModuleForHeader);
2073 case ImportAction::HeaderUnitImport:
2075 Action.ModuleForHeader);
2077 case ImportAction::ModuleImport:
2079 tok::annot_module_include, Action.ModuleForHeader);
2081 case ImportAction::Failure:
2083 "This should be an early exit only to a fatal error");
2086 CurLexer->cutOffLexing();
2094 const Token &FilenameTok,
bool &IsFrameworkFound,
bool IsImportDecl,
2096 const FileEntry *LookupFromFile, StringRef &LookupFilename,
2100 if (LangOpts.AsmPreprocessor)
2104 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
2105 bool RequestingModuleIsModuleInterface =
2109 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
2114 FilenameLoc, LookupFilename, isAngled, LookupFrom, LookupFromFile, CurDir,
2115 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2116 &SuggestedModule, &IsMapped, &IsFrameworkFound);
2118 DiagnoseHeaderInclusion(*
File);
2123 if (Callbacks && Callbacks->FileNotFound(
Filename))
2124 return std::nullopt;
2126 if (SuppressIncludeNotFoundError)
2127 return std::nullopt;
2134 FilenameLoc, LookupFilename,
false, LookupFrom, LookupFromFile, CurDir,
2135 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2136 &SuggestedModule, &IsMapped,
2139 DiagnoseHeaderInclusion(*
File);
2140 Diag(FilenameTok, diag::err_pp_file_not_found_angled_include_not_fatal)
2150 StringRef OriginalFilename =
Filename;
2151 if (LangOpts.SpellChecking) {
2154 auto CorrectTypoFilename = [](llvm::StringRef
Filename) {
2161 StringRef TypoCorrectionName = CorrectTypoFilename(
Filename);
2162 StringRef TypoCorrectionLookupName = CorrectTypoFilename(LookupFilename);
2165 FilenameLoc, TypoCorrectionLookupName, isAngled, LookupFrom,
2166 LookupFromFile, CurDir, Callbacks ? &SearchPath :
nullptr,
2167 Callbacks ? &RelativePath :
nullptr, &SuggestedModule, &IsMapped,
2170 DiagnoseHeaderInclusion(*
File);
2173 FilenameRange,
"<" + TypoCorrectionName.str() +
">")
2175 FilenameRange,
"\"" + TypoCorrectionName.str() +
"\"");
2176 Diag(FilenameTok, diag::err_pp_file_not_found_typo_not_fatal)
2177 << OriginalFilename << TypoCorrectionName << Hint;
2181 LookupFilename = TypoCorrectionLookupName;
2187 assert(!
File &&
"expected missing file");
2188 Diag(FilenameTok, diag::err_pp_file_not_found)
2189 << OriginalFilename << FilenameRange;
2190 if (IsFrameworkFound) {
2191 size_t SlashPos = OriginalFilename.find(
'/');
2192 assert(SlashPos != StringRef::npos &&
2193 "Include with framework name should have '/' in the filename");
2194 StringRef FrameworkName = OriginalFilename.substr(0, SlashPos);
2197 assert(CacheEntry.
Directory &&
"Found framework should be in cache");
2198 Diag(FilenameTok, diag::note_pp_framework_without_header)
2199 << OriginalFilename.substr(SlashPos + 1) << FrameworkName
2203 return std::nullopt;
2218Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
2228 StringRef OriginalFilename =
Filename;
2235 return {ImportAction::None};
2237 bool IsImportDecl = HashLoc.
isInvalid();
2241 if (PragmaARCCFCodeAuditedInfo.second.isValid()) {
2242 Diag(StartLoc, diag::err_pp_include_in_arc_cf_code_audited) << IsImportDecl;
2243 Diag(PragmaARCCFCodeAuditedInfo.second, diag::note_pragma_entered_here);
2250 if (PragmaAssumeNonNullLoc.
isValid()) {
2251 Diag(StartLoc, diag::err_pp_include_in_assume_nonnull) << IsImportDecl;
2252 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
2263 if (!NewName.empty())
2268 bool IsMapped =
false;
2269 bool IsFrameworkFound =
false;
2277 StringRef LookupFilename =
Filename;
2282 llvm::sys::path::Style BackslashStyle = llvm::sys::path::Style::native;
2283 if (is_style_posix(BackslashStyle) && LangOpts.MicrosoftExt) {
2285 llvm::sys::path::native(NormalizedPath);
2286 LookupFilename = NormalizedPath;
2287 BackslashStyle = llvm::sys::path::Style::windows;
2291 &CurDir,
Filename, FilenameLoc, FilenameRange, FilenameTok,
2292 IsFrameworkFound, IsImportDecl, IsMapped, LookupFrom, LookupFromFile,
2293 LookupFilename, RelativePath, SearchPath, SuggestedModule, isAngled);
2297 SkippingUntilPCHThroughHeader =
false;
2298 return {ImportAction::None};
2316 enum { Enter,
Import,
Skip, IncludeLimitReached } Action = Enter;
2318 if (PPOpts->SingleFileParseMode)
2319 Action = IncludeLimitReached;
2324 if (Action == Enter && HasReachedMaxIncludeDepth &&
File &&
2326 Action = IncludeLimitReached;
2333 bool MaybeTranslateInclude = Action == Enter &&
File && ModuleToImport &&
2337 bool UsableHeaderUnit =
false;
2338 if (
getLangOpts().CPlusPlusModules && ModuleToImport &&
2340 if (TrackGMFState.inGMF() || IsImportDecl)
2341 UsableHeaderUnit =
true;
2342 else if (!IsImportDecl) {
2344 ModuleToImport =
nullptr;
2348 bool UsableClangHeaderModule =
2355 if (MaybeTranslateInclude && (UsableHeaderUnit || UsableClangHeaderModule)) {
2363 diag::note_implicit_top_level_module_import_here)
2365 return {ImportAction::None};
2372 for (
Module *Mod = ModuleToImport; Mod; Mod = Mod->
Parent)
2375 std::reverse(
Path.begin(),
Path.end());
2388 assert((Imported ==
nullptr || Imported == ModuleToImport) &&
2389 "the imported module is different than the suggested one");
2395 static_cast<Module *
>(Imported)->getTopLevelModule());
2400 ModuleToImport =
nullptr;
2409 assert(CurLexer &&
"#include but no current lexer set!");
2411 CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
2412 CurLexer->cutOffLexing();
2414 return {ImportAction::None};
2435 bool IsFirstIncludeOfFile =
false;
2439 if (Action == Enter &&
File &&
2442 IsFirstIncludeOfFile)) {
2453 if (UsableHeaderUnit && !
getLangOpts().CompilingPCH)
2454 Action = TrackGMFState.inGMF() ?
Import :
Skip;
2456 Action = (ModuleToImport && !
getLangOpts().CompilingPCH) ? Import :
Skip;
2464 if (Action == Enter &&
File && PreambleConditionalStack.isRecording() &&
2467 diag::err_pp_including_mainfile_in_preamble);
2468 return {ImportAction::None};
2471 if (Callbacks && !IsImportDecl) {
2474 Callbacks->InclusionDirective(HashLoc, IncludeTok, LookupFilename, isAngled,
2475 FilenameRange,
File, SearchPath, RelativePath,
2476 SuggestedModule.
getModule(), Action == Import,
2479 Callbacks->FileSkipped(*
File, FilenameTok, FileCharacter);
2483 return {ImportAction::None};
2487 if (IsImportDecl && !ModuleToImport) {
2488 Diag(FilenameTok, diag::err_header_import_not_header_unit)
2489 << OriginalFilename <<
File->getName();
2490 return {ImportAction::None};
2495 const bool CheckIncludePathPortability =
2496 !IsMapped && !
File->getFileEntry().tryGetRealPathName().empty();
2498 if (CheckIncludePathPortability) {
2499 StringRef Name = LookupFilename;
2500 StringRef NameWithoriginalSlashes =
Filename;
2504 bool NameWasUNC = Name.consume_front(
"\\\\?\\");
2505 NameWithoriginalSlashes.consume_front(
"\\\\?\\");
2507 StringRef RealPathName =
File->getFileEntry().tryGetRealPathName();
2509 llvm::sys::path::end(Name));
2522 if (llvm::sys::path::is_absolute(Name) &&
2523 llvm::sys::path::is_absolute(RealPathName) &&
2526 assert(Components.size() >= 3 &&
"should have drive, backslash, name");
2527 assert(Components[0].size() == 2 &&
"should start with drive");
2528 assert(Components[0][1] ==
':' &&
"should have colon");
2529 FixedDriveRealPath = (Name.substr(0, 1) + RealPathName.substr(1)).str();
2530 RealPathName = FixedDriveRealPath;
2536 Path.reserve(Name.size()+2);
2537 Path.push_back(isAngled ?
'<' :
'"');
2539 const auto IsSep = [BackslashStyle](
char c) {
2540 return llvm::sys::path::is_separator(
c, BackslashStyle);
2543 for (
auto Component : Components) {
2555 if (!(Component.size() == 1 && IsSep(Component[0])))
2556 Path.append(Component);
2557 else if (
Path.size() != 1)
2561 if (
Path.size() > NameWithoriginalSlashes.size()) {
2562 Path.push_back(isAngled ?
'>' :
'"');
2565 assert(IsSep(NameWithoriginalSlashes[
Path.size()-1]));
2567 Path.push_back(NameWithoriginalSlashes[
Path.size()-1]);
2568 while (
Path.size() <= NameWithoriginalSlashes.size() &&
2569 IsSep(NameWithoriginalSlashes[
Path.size()-1]));
2575 Path = (
Path.substr(0, 1) +
"\\\\?\\" +
Path.substr(1)).str();
2582 ? diag::pp_nonportable_path
2583 : diag::pp_nonportable_system_path;
2584 Diag(FilenameTok, DiagId) <<
Path <<
2593 return {ImportAction::SkippedModuleImport, ModuleToImport};
2594 return {ImportAction::None};
2596 case IncludeLimitReached:
2599 return {ImportAction::None};
2603 assert(ModuleToImport &&
"no module to import");
2608 tok::pp___include_macros)
2609 return {ImportAction::None};
2611 return {ImportAction::ModuleImport, ModuleToImport};
2619 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
2620 Diag(FilenameTok, diag::err_pp_include_too_deep);
2621 HasReachedMaxIncludeDepth =
true;
2622 return {ImportAction::None};
2626 Diag(FilenameTok, diag::warn_pp_include_angled_in_module_purview)
2638 return ImportAction::Failure;
2643 IsFirstIncludeOfFile))
2644 return {ImportAction::None};
2648 if (ModuleToImport && !ModuleToImport->
isHeaderUnit()) {
2653 diag::err_module_build_shadowed_submodule)
2656 diag::note_previous_definition);
2657 return {ImportAction::None};
2669 return {ImportAction::None};
2671 assert(!CurLexerSubmodule &&
"should not have marked this as a module yet");
2672 CurLexerSubmodule = ModuleToImport;
2682 return {ImportAction::ModuleBegin, ModuleToImport};
2685 assert(!IsImportDecl &&
"failed to diagnose missing module for import decl");
2686 return {ImportAction::None};
2691void Preprocessor::HandleIncludeNextDirective(
SourceLocation HashLoc,
2692 Token &IncludeNextTok) {
2693 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
2697 std::tie(Lookup, LookupFromFile) = getIncludeNextStart(IncludeNextTok);
2699 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
2704void Preprocessor::HandleMicrosoftImportDirective(
Token &Tok) {
2710 Diag(Tok, diag::err_pp_import_directive_ms );
2721 if (!LangOpts.ObjC) {
2722 if (LangOpts.MSVCCompat)
2723 return HandleMicrosoftImportDirective(ImportTok);
2724 Diag(ImportTok, diag::ext_pp_import_directive);
2726 return HandleIncludeDirective(HashLoc, ImportTok);
2733void Preprocessor::HandleIncludeMacrosDirective(
SourceLocation HashLoc,
2734 Token &IncludeMacrosTok) {
2740 diag::pp_include_macros_out_of_predefines);
2747 HandleIncludeDirective(HashLoc, IncludeMacrosTok);
2752 assert(TmpTok.
isNot(tok::eof) &&
"Didn't find end of -imacros!");
2753 }
while (TmpTok.
isNot(tok::hashhash));
2764bool Preprocessor::ReadMacroParameterList(
MacroInfo *MI,
Token &Tok) {
2775 Diag(Tok, diag::err_pp_expected_ident_in_arg_list);
2779 Diag(Tok, LangOpts.CPlusPlus11 ?
2780 diag::warn_cxx98_compat_variadic_macro :
2781 diag::ext_variadic_macro);
2784 if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus) {
2785 Diag(Tok, diag::ext_pp_opencl_variadic_macros);
2790 if (Tok.
isNot(tok::r_paren)) {
2791 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2800 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2808 Diag(Tok, diag::err_pp_invalid_tok_in_arg_list);
2814 if (llvm::is_contained(Parameters, II)) {
2815 Diag(Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
2827 Diag(Tok, diag::err_pp_expected_comma_in_arg_list);
2836 Diag(Tok, diag::ext_named_variadic_macro);
2840 if (Tok.
isNot(tok::r_paren)) {
2841 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2871 StringRef ValueText = II->
getName();
2872 StringRef TrimmedValue = ValueText;
2873 if (!ValueText.starts_with(
"__")) {
2874 if (ValueText.starts_with(
"_"))
2875 TrimmedValue = TrimmedValue.drop_front(1);
2879 TrimmedValue = TrimmedValue.drop_front(2);
2880 if (TrimmedValue.ends_with(
"__"))
2881 TrimmedValue = TrimmedValue.drop_back(2);
2883 return TrimmedValue == MacroText;
2890 return MacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
2903MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
2904 const Token &MacroNameTok,
const bool ImmediatelyAfterHeaderGuard) {
2906 Token LastTok = MacroNameTok;
2914 auto _ = llvm::make_scope_exit([&]() {
2916 if (CurLexer->ParsingPreprocessorDirective)
2927 if (Tok.
is(tok::eod)) {
2928 if (ImmediatelyAfterHeaderGuard) {
2938 }
else if (Tok.
is(tok::l_paren)) {
2941 if (ReadMacroParameterList(MI, LastTok))
2955 }
else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
2958 Diag(Tok, diag::ext_c99_whitespace_required_after_macro_name);
2967 if (Tok.
is(tok::at))
2969 else if (Tok.
is(tok::unknown)) {
2976 Diag(Tok, diag::ext_missing_whitespace_after_macro_name);
2978 Diag(Tok, diag::warn_missing_whitespace_after_macro_name);
2981 if (!Tok.
is(tok::eod))
2989 while (Tok.
isNot(tok::eod)) {
2991 Tokens.push_back(Tok);
3002 while (Tok.
isNot(tok::eod)) {
3005 if (!Tok.
isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
3006 Tokens.push_back(Tok);
3008 if (VAOCtx.isVAOptToken(Tok)) {
3010 if (VAOCtx.isInVAOpt()) {
3011 Diag(Tok, diag::err_pp_vaopt_nested_use);
3016 if (Tok.
isNot(tok::l_paren)) {
3017 Diag(Tok, diag::err_pp_missing_lparen_in_vaopt_use);
3020 Tokens.push_back(Tok);
3021 VAOCtx.sawVAOptFollowedByOpeningParens(Tok.
getLocation());
3023 if (Tok.
is(tok::hashhash)) {
3024 Diag(Tok, diag::err_vaopt_paste_at_start);
3028 }
else if (VAOCtx.isInVAOpt()) {
3029 if (Tok.
is(tok::r_paren)) {
3030 if (VAOCtx.sawClosingParen()) {
3031 assert(Tokens.size() >= 3 &&
3032 "Must have seen at least __VA_OPT__( "
3033 "and a subsequent tok::r_paren");
3034 if (Tokens[Tokens.size() - 2].is(tok::hashhash)) {
3035 Diag(Tok, diag::err_vaopt_paste_at_end);
3039 }
else if (Tok.
is(tok::l_paren)) {
3053 Tokens.push_back(Tok);
3060 if (Tok.
is(tok::hashhash)) {
3068 if (Tok.
is(tok::eod)) {
3069 Tokens.push_back(LastTok);
3074 Tokens[Tokens.size() - 1].is(tok::comma))
3078 Tokens.push_back(LastTok);
3087 if (!VAOCtx.isVAOptToken(Tok) &&
3096 LastTok.
setKind(tok::unknown);
3097 Tokens.push_back(LastTok);
3100 Diag(Tok, diag::err_pp_stringize_not_parameter)
3101 << LastTok.
is(tok::hashat);
3107 Tokens.push_back(LastTok);
3112 if (!VAOCtx.isVAOptToken(Tok)) {
3113 Tokens.push_back(Tok);
3120 if (VAOCtx.isInVAOpt()) {
3121 assert(Tok.
is(tok::eod) &&
"Must be at End Of preprocessing Directive");
3122 Diag(Tok, diag::err_pp_expected_after)
3123 << LastTok.
getKind() << tok::r_paren;
3124 Diag(VAOCtx.getUnmatchedOpeningParenLoc(), diag::note_matching) << tok::l_paren;
3135 return II->
isStr(
"__strong") || II->
isStr(
"__weak") ||
3136 II->
isStr(
"__unsafe_unretained") || II->
isStr(
"__autoreleasing");
3141void Preprocessor::HandleDefineDirective(
3142 Token &DefineTok,
const bool ImmediatelyAfterHeaderGuard) {
3146 bool MacroShadowsKeyword;
3147 ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
3150 if (MacroNameTok.
is(tok::eod))
3157 emitFinalMacroWarning(MacroNameTok,
false);
3161 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
3163 MacroInfo *
const MI = ReadOptionalMacroParameterListAndBody(
3164 MacroNameTok, ImmediatelyAfterHeaderGuard);
3168 if (MacroShadowsKeyword &&
3170 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
3175 if (NumTokens != 0) {
3187 if (SkippingUntilPCHThroughHeader) {
3190 LangOpts.MicrosoftExt))
3194 if (!LangOpts.MicrosoftExt)
3205 emitFinalMacroWarning(MacroNameTok,
false);
3218 LangOpts.MicrosoftExt)) {
3237 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
3241 !MI->
isIdenticalTo(*OtherMI, *
this, LangOpts.MicrosoftExt)) {
3259 !MacroExpansionInDirectivesOverride &&
3268 Callbacks->MacroDefined(MacroNameTok, MD);
3281 Tok.
setKind(tok::kw__Static_assert);
3290void Preprocessor::HandleUndefDirective() {
3294 ReadMacroName(MacroNameTok,
MU_Undef);
3297 if (MacroNameTok.
is(tok::eod))
3309 emitFinalMacroWarning(MacroNameTok,
true);
3319 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
3324 Undef = AllocateUndefMacroDirective(MacroNameTok.
getLocation());
3330 Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
3345void Preprocessor::HandleIfdefDirective(
Token &
Result,
3346 const Token &HashToken,
3348 bool ReadAnyTokensBeforeDirective) {
3353 ReadMacroName(MacroNameTok);
3356 if (MacroNameTok.
is(tok::eod)) {
3359 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3379 if (!ReadAnyTokensBeforeDirective && !MI) {
3380 assert(isIfndef &&
"#ifdef shouldn't reach here");
3392 Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3394 Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3397 bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3401 if (PPOpts->SingleFileParseMode && !MI) {
3407 }
else if (!MI == isIfndef || RetainExcludedCB) {
3414 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3423void Preprocessor::HandleIfDirective(
Token &IfToken,
3424 const Token &HashToken,
3425 bool ReadAnyTokensBeforeDirective) {
3430 const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
3431 const bool ConditionalTrue = DER.Conditional;
3440 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
3452 bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3456 if (PPOpts->SingleFileParseMode && DER.IncludedUndefinedIds) {
3461 }
else if (ConditionalTrue || RetainExcludedCB) {
3475void Preprocessor::HandleEndifDirective(
Token &EndifToken) {
3484 Diag(EndifToken, diag::err_pp_endif_without_if);
3493 "This code should only be reachable in the non-skipping case!");
3501void Preprocessor::HandleElseDirective(
Token &
Result,
const Token &HashToken) {
3523 bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3526 if ((PPOpts->SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3537 true,
Result.getLocation());
3541void Preprocessor::HandleElifFamilyDirective(
Token &ElifToken,
3542 const Token &HashToken,
3554 if (LangOpts.CPlusPlus)
3555 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
3556 : diag::ext_cxx23_pp_directive;
3558 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
3559 : diag::ext_c23_pp_directive;
3560 Diag(ElifToken, DiagID) << DirKind;
3573 Diag(ElifToken, diag::pp_err_elif_without_if) << DirKind;
3583 Diag(ElifToken, diag::pp_err_elif_after_else) << DirKind;
3588 Callbacks->Elif(ElifToken.
getLocation(), ConditionRange,
3591 case tok::pp_elifdef:
3594 case tok::pp_elifndef:
3598 assert(
false &&
"unexpected directive kind");
3603 bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3606 if ((PPOpts->SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3615 SkipExcludedConditionalBlock(
3620std::optional<LexEmbedParametersResult>
3624 tok::TokenKind EndTokenKind = ForHasEmbed ? tok::r_paren : tok::eod;
3626 auto DiagMismatchedBracesAndSkipToEOD =
3628 std::pair<tok::TokenKind, SourceLocation> Matches) {
3630 Diag(Matches.second, diag::note_matching) << Matches.first;
3631 if (CurTok.
isNot(tok::eod))
3636 if (CurTok.
isNot(Kind)) {
3637 Diag(CurTok, diag::err_expected) << Kind;
3638 if (CurTok.
isNot(tok::eod))
3655 auto LexPPParameterName = [&]() -> std::optional<std::string> {
3658 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3659 return std::nullopt;
3666 if (CurTok.
is(tok::coloncolon)) {
3669 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3670 return std::nullopt;
3676 return (llvm::Twine(Prefix->
getName()) +
"::" + Suffix->
getName()).str();
3678 return Prefix->
getName().str();
3685 auto NormalizeParameterName = [](StringRef Name) {
3686 if (Name.size() > 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
3687 return Name.substr(2, Name.size() - 4);
3691 auto LexParenthesizedIntegerExpr = [&]() -> std::optional<size_t> {
3694 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3695 return std::nullopt;
3700 bool EvaluatedDefined;
3701 DirectiveEvalResult LimitEvalResult = EvaluateDirectiveExpression(
3702 ParameterIfNDef, CurTok, EvaluatedDefined,
false);
3704 if (!LimitEvalResult.Value) {
3707 assert(CurTok.
is(tok::eod) &&
"expect to be at the end of directive");
3708 return std::nullopt;
3711 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3712 return std::nullopt;
3719 if (EvaluatedDefined) {
3720 Diag(CurTok, diag::err_defined_in_pp_embed);
3721 return std::nullopt;
3724 if (LimitEvalResult.Value) {
3725 const llvm::APSInt &
Result = *LimitEvalResult.Value;
3726 if (
Result.isNegative()) {
3727 Diag(CurTok, diag::err_requires_positive_value)
3729 return std::nullopt;
3731 return Result.getLimitedValue();
3733 return std::nullopt;
3739 return tok::r_paren;
3741 return tok::r_brace;
3743 return tok::r_square;
3745 llvm_unreachable(
"should not get here");
3749 auto LexParenthesizedBalancedTokenSoup =
3751 std::vector<std::pair<tok::TokenKind, SourceLocation>> BracketStack;
3754 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3758 bool WaitingForInnerCloseParen =
false;
3759 while (CurTok.
isNot(tok::eod) &&
3760 (WaitingForInnerCloseParen || CurTok.
isNot(tok::r_paren))) {
3765 WaitingForInnerCloseParen =
true;
3772 WaitingForInnerCloseParen =
false;
3775 case tok::r_square: {
3777 GetMatchingCloseBracket(BracketStack.back().first);
3778 if (BracketStack.empty() || CurTok.
getKind() != Matching) {
3779 DiagMismatchedBracesAndSkipToEOD(Matching, BracketStack.back());
3782 BracketStack.pop_back();
3785 Tokens.push_back(CurTok);
3790 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3798 while (!CurTok.
isOneOf(EndTokenKind, tok::eod)) {
3800 std::optional<std::string> ParamName = LexPPParameterName();
3802 return std::nullopt;
3803 StringRef
Parameter = NormalizeParameterName(*ParamName);
3810 if (
Result.MaybeLimitParam)
3813 std::optional<size_t> Limit = LexParenthesizedIntegerExpr();
3815 return std::nullopt;
3818 }
else if (
Parameter ==
"clang::offset") {
3819 if (
Result.MaybeOffsetParam)
3822 std::optional<size_t> Offset = LexParenthesizedIntegerExpr();
3824 return std::nullopt;
3828 if (
Result.MaybePrefixParam)
3832 if (!LexParenthesizedBalancedTokenSoup(Soup))
3833 return std::nullopt;
3835 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
3837 if (
Result.MaybeSuffixParam)
3841 if (!LexParenthesizedBalancedTokenSoup(Soup))
3842 return std::nullopt;
3844 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
3846 if (
Result.MaybeIfEmptyParam)
3850 if (!LexParenthesizedBalancedTokenSoup(Soup))
3851 return std::nullopt;
3853 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
3855 ++
Result.UnrecognizedParams;
3859 if (CurTok.
is(tok::l_paren)) {
3861 if (!LexParenthesizedBalancedTokenSoup(Soup))
3862 return std::nullopt;
3865 Diag(CurTok, diag::err_pp_unknown_parameter) << 1 <<
Parameter;
3866 return std::nullopt;
3873void Preprocessor::HandleEmbedDirectiveImpl(
3875 StringRef BinaryContents) {
3876 if (BinaryContents.empty()) {
3884 size_t TokCount = Toks.size();
3885 auto NewToks = std::make_unique<Token[]>(TokCount);
3886 llvm::copy(Toks, NewToks.get());
3887 EnterTokenStream(std::move(NewToks), TokCount,
true,
true);
3894 size_t TotalNumToks = 1 + NumPrefixToks + NumSuffixToks;
3896 auto Toks = std::make_unique<Token[]>(TotalNumToks);
3901 CurIdx += NumPrefixToks;
3905 Data->BinaryData = BinaryContents;
3907 Toks[CurIdx].startToken();
3908 Toks[CurIdx].setKind(tok::annot_embed);
3909 Toks[CurIdx].setAnnotationRange(HashLoc);
3910 Toks[CurIdx++].setAnnotationValue(
Data);
3915 CurIdx += NumSuffixToks;
3918 assert(CurIdx == TotalNumToks &&
"Calculated the incorrect number of tokens");
3919 EnterTokenStream(std::move(Toks), TotalNumToks,
true,
true);
3926 Diag(EmbedTok, diag::warn_compat_pp_embed_directive);
3928 Diag(EmbedTok, diag::ext_pp_embed_directive)
3929 << (LangOpts.CPlusPlus ? 1 : 0);
3936 if (FilenameTok.
isNot(tok::header_name)) {
3938 if (FilenameTok.
isNot(tok::eod))
3951 std::optional<LexEmbedParametersResult> Params =
3954 assert((Params || CurTok.
is(tok::eod)) &&
3955 "expected success or to be at the end of the directive");
3962 StringRef OriginalFilename =
Filename;
3970 if (!MaybeFileRef) {
3972 if (Callbacks && Callbacks->EmbedFileNotFound(OriginalFilename)) {
3975 Diag(FilenameTok, diag::err_pp_file_not_found) <<
Filename;
3978 std::optional<llvm::MemoryBufferRef> MaybeFile =
3982 Diag(FilenameTok, diag::err_cannot_open_file)
3983 <<
Filename <<
"a buffer to the contents could not be created";
3986 StringRef BinaryContents = MaybeFile->getBuffer();
3991 if (Params->MaybeOffsetParam) {
3996 BinaryContents = BinaryContents.substr(Params->MaybeOffsetParam->Offset);
3999 if (Params->MaybeLimitParam) {
4003 BinaryContents = BinaryContents.substr(0, Params->MaybeLimitParam->Limit);
4007 Callbacks->EmbedDirective(HashLoc,
Filename, isAngled, MaybeFileRef,
4009 HandleEmbedDirectiveImpl(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.
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 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()
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
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].
@ 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.