37#include "llvm/ADT/ArrayRef.h"
38#include "llvm/ADT/STLExtras.h"
39#include "llvm/ADT/ScopeExit.h"
40#include "llvm/ADT/SmallString.h"
41#include "llvm/ADT/SmallVector.h"
42#include "llvm/ADT/StringRef.h"
43#include "llvm/ADT/StringSwitch.h"
44#include "llvm/Support/AlignOf.h"
45#include "llvm/Support/ErrorHandling.h"
46#include "llvm/Support/Path.h"
47#include "llvm/Support/SaveAndRestore.h"
63 static_assert(std::is_trivially_destructible_v<MacroInfo>,
"");
73Preprocessor::AllocateUndefMacroDirective(
SourceLocation UndefLoc) {
91 while (Tmp.
isNot(tok::eod)) {
92 assert(Tmp.
isNot(tok::eof) &&
"EOF seen while discarding directive tokens");
120 static constexpr StringRef ReservedMacro[] = {
123 "_CRT_NONSTDC_NO_WARNINGS",
124 "_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES",
125 "_CRT_SECURE_NO_WARNINGS",
128 "_GLIBCXX_ASSERTIONS",
129 "_GLIBCXX_CONCEPT_CHECKS",
131 "_GLIBCXX_DEBUG_PEDANTIC",
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 return std::binary_search(std::begin(ReservedMacro), std::end(ReservedMacro),
157 const StringRef MacroName) {
167 if (MacroName.starts_with(
"__STDC"))
170 if (MacroName ==
"__cplusplus")
173 if (MacroName.starts_with(
"__cpp"))
186 if (Lang.CPlusPlus11 && (
Text ==
"override" ||
Text ==
"final"))
207 if (::llvm::sys::path::begin(Include)->equals_insensitive(
"boost"))
212 static const size_t MaxStdHeaderNameLen = 18u;
213 if (Include.size() > MaxStdHeaderNameLen)
218 for (
char &Ch : LowerInclude) {
220 if (
static_cast<unsigned char>(Ch) > 0x7f)
223 if (Ch >=
'A' && Ch <=
'Z')
226 else if (::llvm::sys::path::is_separator(Ch))
231 return llvm::StringSwitch<bool>(LowerInclude)
233 .Cases(
"assert.h",
"complex.h",
"ctype.h",
"errno.h",
"fenv.h",
true)
234 .Cases(
"float.h",
"inttypes.h",
"iso646.h",
"limits.h",
"locale.h",
true)
235 .Cases(
"math.h",
"setjmp.h",
"signal.h",
"stdalign.h",
"stdarg.h",
true)
236 .Cases(
"stdatomic.h",
"stdbool.h",
"stdckdint.h",
"stddef.h",
true)
237 .Cases(
"stdint.h",
"stdio.h",
"stdlib.h",
"stdnoreturn.h",
true)
238 .Cases(
"string.h",
"tgmath.h",
"threads.h",
"time.h",
"uchar.h",
true)
239 .Cases(
"wchar.h",
"wctype.h",
true)
242 .Cases(
"cassert",
"ccomplex",
"cctype",
"cerrno",
"cfenv",
true)
243 .Cases(
"cfloat",
"cinttypes",
"ciso646",
"climits",
"clocale",
true)
244 .Cases(
"cmath",
"csetjmp",
"csignal",
"cstdalign",
"cstdarg",
true)
245 .Cases(
"cstdbool",
"cstddef",
"cstdint",
"cstdio",
"cstdlib",
true)
246 .Cases(
"cstring",
"ctgmath",
"ctime",
"cuchar",
"cwchar",
true)
247 .Case(
"cwctype",
true)
250 .Cases(
"algorithm",
"fstream",
"list",
"regex",
"thread",
true)
251 .Cases(
"array",
"functional",
"locale",
"scoped_allocator",
"tuple",
true)
252 .Cases(
"atomic",
"future",
"map",
"set",
"type_traits",
true)
253 .Cases(
"bitset",
"initializer_list",
"memory",
"shared_mutex",
"typeindex",
true)
254 .Cases(
"chrono",
"iomanip",
"mutex",
"sstream",
"typeinfo",
true)
255 .Cases(
"codecvt",
"ios",
"new",
"stack",
"unordered_map",
true)
256 .Cases(
"complex",
"iosfwd",
"numeric",
"stdexcept",
"unordered_set",
true)
257 .Cases(
"condition_variable",
"iostream",
"ostream",
"streambuf",
"utility",
true)
258 .Cases(
"deque",
"istream",
"queue",
"string",
"valarray",
true)
259 .Cases(
"exception",
"iterator",
"random",
"strstream",
"vector",
true)
260 .Cases(
"forward_list",
"limits",
"ratio",
"system_error",
true)
263 .Cases(
"aio.h",
"arpa/inet.h",
"cpio.h",
"dirent.h",
"dlfcn.h",
true)
264 .Cases(
"fcntl.h",
"fmtmsg.h",
"fnmatch.h",
"ftw.h",
"glob.h",
true)
265 .Cases(
"grp.h",
"iconv.h",
"langinfo.h",
"libgen.h",
"monetary.h",
true)
266 .Cases(
"mqueue.h",
"ndbm.h",
"net/if.h",
"netdb.h",
"netinet/in.h",
true)
267 .Cases(
"netinet/tcp.h",
"nl_types.h",
"poll.h",
"pthread.h",
"pwd.h",
true)
268 .Cases(
"regex.h",
"sched.h",
"search.h",
"semaphore.h",
"spawn.h",
true)
269 .Cases(
"strings.h",
"stropts.h",
"sys/ipc.h",
"sys/mman.h",
"sys/msg.h",
true)
270 .Cases(
"sys/resource.h",
"sys/select.h",
"sys/sem.h",
"sys/shm.h",
"sys/socket.h",
true)
271 .Cases(
"sys/stat.h",
"sys/statvfs.h",
"sys/time.h",
"sys/times.h",
"sys/types.h",
true)
272 .Cases(
"sys/uio.h",
"sys/un.h",
"sys/utsname.h",
"sys/wait.h",
"syslog.h",
true)
273 .Cases(
"tar.h",
"termios.h",
"trace.h",
"ulimit.h",
true)
274 .Cases(
"unistd.h",
"utime.h",
"utmpx.h",
"wordexp.h",
true)
286static std::optional<StringRef>
290 for (StringRef
C : Candidates) {
291 if (LHS.equals_insensitive(
C)) {
299 size_t Length = LHS.size();
300 size_t MaxDist = Length < 3 ? Length - 1 : Length / 3;
302 std::optional<std::pair<StringRef, size_t>> SimilarStr;
303 for (StringRef
C : Candidates) {
304 size_t CurDist = LHS.edit_distance(
C,
true);
305 if (CurDist <= MaxDist) {
308 SimilarStr = {
C, CurDist};
309 }
else if (CurDist < SimilarStr->second) {
311 SimilarStr = {
C, CurDist};
317 return SimilarStr->first;
326 if (MacroNameTok.
is(tok::eod))
327 return Diag(MacroNameTok, diag::err_pp_missing_macro_name);
331 return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
337 ? diag::ext_pp_operator_used_as_macro_name
338 : diag::err_pp_operator_used_as_macro_name)
339 << II << MacroNameTok.
getKind();
346 return Diag(MacroNameTok, diag::err_defined_macro_name);
370 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id);
386void Preprocessor::ReadMacroName(
Token &MacroNameTok,
MacroUse isDefineUndef,
391 if (MacroNameTok.
is(tok::code_completion)) {
403 if (MacroNameTok.
isNot(tok::eod)) {
404 MacroNameTok.
setKind(tok::eod);
428 while (Tmp.
is(tok::comment))
431 if (Tmp.
is(tok::eod))
439 if ((LangOpts.GNUMode || LangOpts.C99 || LangOpts.CPlusPlus) &&
442 Diag(Tmp, diag::ext_pp_extra_tokens_at_eol) << DirType << Hint;
446void Preprocessor::SuggestTypoedDirective(
const Token &Tok,
452 std::vector<StringRef> Candidates = {
453 "if",
"ifdef",
"ifndef",
"elif",
"else",
"endif"
455 if (LangOpts.C23 || LangOpts.CPlusPlus23)
456 Candidates.insert(Candidates.end(), {
"elifdef",
"elifndef"});
464 StringRef SuggValue = *Sugg;
467 Diag(Tok, diag::warn_pp_invalid_directive) << 1 << SuggValue << Hint;
479void Preprocessor::SkipExcludedConditionalBlock(
SourceLocation HashTokenLoc,
481 bool FoundNonSkipPortion,
492 assert(!SkippingExcludedConditionalBlock &&
493 "calling SkipExcludedConditionalBlock recursively");
497 assert(!CurTokenLexer &&
"Conditional PP block cannot appear in a macro!");
498 assert(CurPPLexer &&
"Conditional PP block must be in a file!");
499 assert(CurLexer &&
"Conditional PP block but no current lexer set!");
501 if (PreambleConditionalStack.reachedEOFWhileSkipping())
502 PreambleConditionalStack.clearSkipInfo();
505 FoundNonSkipPortion, FoundElse);
515 struct SkippingRangeStateTy {
518 const char *BeginPtr =
nullptr;
519 unsigned *SkipRangePtr =
nullptr;
523 void beginLexPass() {
529 BeginPtr = PP.CurLexer->getBufferLocation();
530 SkipRangePtr = &PP.RecordedSkippedRanges[BeginPtr];
532 PP.CurLexer->seek(PP.CurLexer->getCurrentBufferOffset() + *SkipRangePtr,
537 void endLexPass(
const char *Hashptr) {
540 assert(PP.CurLexer->isDependencyDirectivesLexer());
545 if (!*SkipRangePtr) {
546 *SkipRangePtr = Hashptr - BeginPtr;
548 assert(*SkipRangePtr == Hashptr - BeginPtr);
550 SkipRangePtr =
nullptr;
552 } SkippingRangeState(*
this);
555 if (CurLexer->isDependencyDirectivesLexer()) {
556 CurLexer->LexDependencyDirectiveTokenWhileSkipping(Tok);
558 SkippingRangeState.beginLexPass();
562 if (Tok.
is(tok::code_completion)) {
570 if (Tok.
is(tok::eof)) {
574 if (PreambleConditionalStack.isRecording())
575 PreambleConditionalStack.SkipInfo.emplace(HashTokenLoc, IfTokenLoc,
588 if (Tok.
is(tok::eof))
595 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
597 assert(Tok.
is(tok::hash));
598 const char *Hashptr = CurLexer->getBufferLocation() - Tok.
getLength();
599 assert(CurLexer->getSourceLocation(Hashptr) == Tok.
getLocation());
606 if (Tok.
isNot(tok::raw_identifier)) {
609 if (CurLexer) CurLexer->resetExtendedTokenMode();
620 char FirstChar = RI[0];
621 if (FirstChar >=
'a' && FirstChar <=
'z' &&
622 FirstChar !=
'i' && FirstChar !=
'e') {
625 if (CurLexer) CurLexer->resetExtendedTokenMode();
632 char DirectiveBuf[20];
638 size_t IdLen = DirectiveStr.size();
642 if (CurLexer) CurLexer->resetExtendedTokenMode();
645 memcpy(DirectiveBuf, &DirectiveStr[0], IdLen);
646 Directive = StringRef(DirectiveBuf, IdLen);
670 assert(!InCond &&
"Can't be skipping if not in a conditional!");
674 SkippingRangeState.endLexPass(Hashptr);
686 }
else if (Sub ==
"lse") {
693 SkippingRangeState.endLexPass(Hashptr);
697 Diag(Tok, diag::pp_err_else_after_else);
717 }
else if (Sub ==
"lif") {
721 SkippingRangeState.endLexPass(Hashptr);
738 assert(CurPPLexer->
LexingRawMode &&
"We have to be skipping here!");
741 DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
745 const bool CondValue = DER.Conditional;
759 }
else if (Sub ==
"lifdef" ||
761 bool IsElifDef =
Sub ==
"lifdef";
763 Token DirectiveToken = Tok;
766 SkippingRangeState.endLexPass(Hashptr);
771 if (LangOpts.CPlusPlus)
772 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
773 : diag::ext_cxx23_pp_directive;
775 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
776 : diag::ext_c23_pp_directive;
781 Diag(Tok, diag::pp_err_elif_after_else)
795 assert(CurPPLexer->
LexingRawMode &&
"We have to be skipping here!");
798 ReadMacroName(MacroNameTok);
803 if (MacroNameTok.
is(tok::eod)) {
819 Callbacks->Elifdef(DirectiveToken.
getLocation(), MacroNameTok,
822 Callbacks->Elifndef(DirectiveToken.
getLocation(), MacroNameTok,
827 if (
static_cast<bool>(MI) == IsElifDef) {
841 if (CurLexer) CurLexer->resetExtendedTokenMode();
852 Callbacks->SourceRangeSkipped(
884 IncLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
892 auto ID =
SM.getFileID(
SM.getExpansionLoc(
Loc));
893 auto FE =
SM.getFileEntryRefForID(ID);
902 bool InPrivateHeader =
false;
904 if (!Header.isAccessibleFrom(IncM)) {
909 InPrivateHeader =
true;
945 Loc =
SM.getIncludeLoc(ID);
957 bool *IsFrameworkFound,
bool SkipCache,
bool OpenFile,
bool CacheFailures) {
962 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
967 bool BuildSystemModule =
false;
968 if (!FromDir && !FromFile) {
991 Includers.push_back(std::make_pair(std::nullopt, *IncludeDir));
996 Includers.push_back(std::make_pair(*FileEnt, *CWD));
999 Includers.push_back(std::make_pair(*FileEnt, FileEnt->
getDir()));
1005 if (LangOpts.MSVCCompat && !isAngled) {
1006 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1007 if (IsFileLexer(ISEntry))
1009 Includers.push_back(std::make_pair(*FileEnt, FileEnt->
getDir()));
1014 CurDir = CurDirLookup;
1022 Filename, FilenameLoc, isAngled, TmpFromDir, &TmpCurDir,
1023 Includers, SearchPath, RelativePath, RequestingModule,
1024 SuggestedModule,
nullptr,
1025 nullptr, SkipCache)) {
1027 TmpFromDir = TmpCurDir;
1029 if (&FE->getFileEntry() == FromFile) {
1031 FromDir = TmpFromDir;
1040 Filename, FilenameLoc, isAngled, FromDir, &CurDir, Includers, SearchPath,
1041 RelativePath, RequestingModule, SuggestedModule, IsMapped,
1042 IsFrameworkFound, SkipCache, BuildSystemModule, OpenFile, CacheFailures);
1050 if (IsFileLexer()) {
1053 Filename, *CurFileEnt, SearchPath, RelativePath, RequestingModule,
1060 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1061 if (IsFileLexer(ISEntry)) {
1062 if ((CurFileEnt = ISEntry.ThePPLexer->
getFileEntry())) {
1064 Filename, *CurFileEnt, SearchPath, RelativePath,
1065 RequestingModule, SuggestedModule)) {
1073 return std::nullopt;
1083 : PP(pp), save(pp->DisableMacroExpansion) {
1084 if (pp->MacroExpansionInDirectivesOverride)
1085 pp->DisableMacroExpansion =
false;
1089 PP->DisableMacroExpansion = save;
1106 if (II->getPPKeywordID() == tok::pp_define) {
1107 return HandleDefineDirective(
Result,
1110 if (SkippingUntilPCHThroughHeader &&
1111 II->getPPKeywordID() == tok::pp_include) {
1112 return HandleIncludeDirective(HashLoc,
Result);
1114 if (SkippingUntilPragmaHdrStop && II->getPPKeywordID() == tok::pp_pragma) {
1116 auto *II =
Result.getIdentifierInfo();
1117 if (II && II->getName() ==
"hdrstop")
1135 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
1137 bool ImmediatelyAfterTopLevelIfndef =
1165 switch (II->getPPKeywordID()) {
1166 case tok::pp_include:
1167 case tok::pp_import:
1168 case tok::pp_include_next:
1169 case tok::pp___include_macros:
1170 case tok::pp_pragma:
1171 Diag(
Result, diag::err_embedded_directive) << II->getName();
1172 Diag(*ArgMacro, diag::note_macro_expansion_here)
1187 if (SkippingUntilPCHThroughHeader || SkippingUntilPragmaHdrStop)
1190 switch (
Result.getKind()) {
1197 case tok::code_completion:
1203 case tok::numeric_constant:
1210 return HandleDigitDirective(
Result);
1220 return HandleIfDirective(
Result, SavedHash, ReadAnyTokensBeforeDirective);
1222 return HandleIfdefDirective(
Result, SavedHash,
false,
1224 case tok::pp_ifndef:
1225 return HandleIfdefDirective(
Result, SavedHash,
true,
1226 ReadAnyTokensBeforeDirective);
1228 case tok::pp_elifdef:
1229 case tok::pp_elifndef:
1233 return HandleElseDirective(
Result, SavedHash);
1235 return HandleEndifDirective(
Result);
1238 case tok::pp_include:
1241 case tok::pp___include_macros:
1246 case tok::pp_define:
1247 return HandleDefineDirective(
Result, ImmediatelyAfterTopLevelIfndef);
1249 return HandleUndefDirective();
1253 return HandleLineDirective();
1257 return HandleUserDiagnosticDirective(
Result,
false);
1260 case tok::pp_pragma:
1264 case tok::pp_import:
1266 case tok::pp_include_next:
1269 case tok::pp_warning:
1270 if (LangOpts.CPlusPlus)
1272 ? diag::warn_cxx23_compat_warning_directive
1273 : diag::ext_pp_warning_directive)
1276 Diag(
Result, LangOpts.C23 ? diag::warn_c23_compat_warning_directive
1277 : diag::ext_pp_warning_directive)
1280 return HandleUserDiagnosticDirective(
Result,
true);
1282 return HandleIdentSCCSDirective(
Result);
1284 return HandleIdentSCCSDirective(
Result);
1285 case tok::pp_assert:
1288 case tok::pp_unassert:
1292 case tok::pp___public_macro:
1294 return HandleMacroPublicDirective(
Result);
1297 case tok::pp___private_macro:
1299 return HandleMacroPrivateDirective();
1310 auto Toks = std::make_unique<Token[]>(2);
1312 Toks[0] = SavedHash;
1317 if (
Result.is(tok::hashhash))
1318 Toks[1].setKind(tok::unknown);
1323 EnterTokenStream(std::move(Toks), 2,
false,
false);
1329 Diag(
Result, diag::err_pp_invalid_directive) << 0;
1341 bool IsGNULineDirective=
false) {
1342 if (DigitTok.
isNot(tok::numeric_constant)) {
1343 PP.
Diag(DigitTok, DiagID);
1345 if (DigitTok.
isNot(tok::eod))
1351 IntegerBuffer.resize(DigitTok.
getLength());
1352 const char *DigitTokBegin = &IntegerBuffer[0];
1362 for (
unsigned i = 0; i != ActualLength; ++i) {
1365 if (DigitTokBegin[i] ==
'\'')
1368 if (!
isDigit(DigitTokBegin[i])) {
1370 diag::err_pp_line_digit_sequence) << IsGNULineDirective;
1375 unsigned NextVal = Val*10+(DigitTokBegin[i]-
'0');
1376 if (NextVal < Val) {
1377 PP.
Diag(DigitTok, DiagID);
1384 if (DigitTokBegin[0] ==
'0' && Val)
1386 << IsGNULineDirective;
1398void Preprocessor::HandleLineDirective() {
1406 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*
this))
1410 Diag(DigitTok, diag::ext_pp_line_zero);
1414 unsigned LineLimit = 32768U;
1415 if (LangOpts.C99 || LangOpts.CPlusPlus11)
1416 LineLimit = 2147483648U;
1417 if (LineNo >= LineLimit)
1418 Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
1419 else if (LangOpts.CPlusPlus11 && LineNo >= 32768U)
1420 Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
1422 int FilenameID = -1;
1428 if (StrTok.
is(tok::eod))
1430 else if (StrTok.
isNot(tok::string_literal)) {
1431 Diag(StrTok, diag::err_pp_line_invalid_filename);
1435 Diag(StrTok, diag::err_invalid_string_udl);
1441 assert(
Literal.isOrdinary() &&
"Didn't allow wide strings in");
1447 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1482 if (FlagTok.
is(tok::eod))
return false;
1483 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1490 if (FlagTok.
is(tok::eod))
return false;
1491 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1493 }
else if (FlagVal == 2) {
1509 SM.getDecomposedExpansionLoc(IncLoc).first != CurFileID) {
1510 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);
1516 if (FlagTok.
is(tok::eod))
return false;
1517 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1523 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1531 if (FlagTok.
is(tok::eod))
return false;
1532 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1537 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1545 if (FlagTok.
is(tok::eod))
return false;
1548 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1560void Preprocessor::HandleDigitDirective(
Token &DigitTok) {
1564 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
1571 bool IsFileEntry =
false, IsFileExit =
false;
1572 int FilenameID = -1;
1577 if (StrTok.
is(tok::eod)) {
1578 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1581 }
else if (StrTok.
isNot(tok::string_literal)) {
1582 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1586 Diag(StrTok, diag::err_invalid_string_udl);
1592 assert(
Literal.isOrdinary() &&
"Didn't allow wide strings in");
1598 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1608 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1612 if (!(IsFileExit &&
Literal.GetString().empty()))
1618 IsFileExit, FileKind);
1627 else if (IsFileExit)
1636void Preprocessor::HandleUserDiagnosticDirective(
Token &Tok,
1644 CurLexer->ReadToEndOfLine(&Message);
1648 StringRef Msg = Message.str().ltrim(
' ');
1651 Diag(Tok, diag::pp_hash_warning) << Msg;
1653 Diag(Tok, diag::err_pp_hash_error) << Msg;
1658void Preprocessor::HandleIdentSCCSDirective(
Token &Tok) {
1660 Diag(Tok, diag::ext_pp_ident_directive);
1667 if (StrTok.
isNot(tok::string_literal) &&
1668 StrTok.
isNot(tok::wide_string_literal)) {
1669 Diag(StrTok, diag::err_pp_malformed_ident);
1670 if (StrTok.
isNot(tok::eod))
1676 Diag(StrTok, diag::err_invalid_string_udl);
1693void Preprocessor::HandleMacroPublicDirective(
Token &Tok) {
1695 ReadMacroName(MacroNameTok,
MU_Undef);
1698 if (MacroNameTok.
is(tok::eod))
1710 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1720void Preprocessor::HandleMacroPrivateDirective() {
1722 ReadMacroName(MacroNameTok,
MU_Undef);
1725 if (MacroNameTok.
is(tok::eod))
1737 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1757 StringRef &Buffer) {
1759 assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1771 if (Buffer[0] ==
'<') {
1772 if (Buffer.back() !=
'>') {
1773 Diag(
Loc, diag::err_pp_expects_filename);
1774 Buffer = StringRef();
1778 }
else if (Buffer[0] ==
'"') {
1779 if (Buffer.back() !=
'"') {
1780 Diag(
Loc, diag::err_pp_expects_filename);
1781 Buffer = StringRef();
1786 Diag(
Loc, diag::err_pp_expects_filename);
1787 Buffer = StringRef();
1792 if (Buffer.size() <= 2) {
1793 Diag(
Loc, diag::err_pp_empty_filename);
1794 Buffer = StringRef();
1799 Buffer = Buffer.substr(1, Buffer.size()-2);
1806 void *AnnotationVal) {
1809 auto Tok = std::make_unique<Token[]>(1);
1815 EnterTokenStream(std::move(Tok), 1,
true,
false);
1822 ArrayRef<std::pair<IdentifierInfo *, SourceLocation>> Path,
1825 for (
size_t I = 0, N = Path.size(); I != N; ++I) {
1828 PathString += Path[I].first->getName();
1831 int IncludeKind = 0;
1833 case tok::pp_include:
1837 case tok::pp_import:
1841 case tok::pp_include_next:
1845 case tok::pp___include_macros:
1850 llvm_unreachable(
"unknown include directive kind");
1853 PP.
Diag(HashLoc, diag::remark_pp_include_directive_modular_translation)
1854 << IncludeKind << PathString;
1861 StringRef RealPathName,
1862 llvm::sys::path::Style Separator) {
1863 auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName);
1864 auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName);
1866 bool SuggestReplacement =
false;
1868 auto IsSep = [Separator](StringRef Component) {
1869 return Component.size() == 1 &&
1870 llvm::sys::path::is_separator(Component[0], Separator);
1875 for (
auto &Component : llvm::reverse(Components)) {
1876 if (
"." == Component) {
1877 }
else if (
".." == Component) {
1881 }
else if (RealPathComponentIter != RealPathComponentEnd) {
1882 if (!IsSep(Component) && !IsSep(*RealPathComponentIter) &&
1883 Component != *RealPathComponentIter) {
1887 SuggestReplacement =
1888 RealPathComponentIter->equals_insensitive(Component);
1889 if (!SuggestReplacement)
1891 Component = *RealPathComponentIter;
1893 ++RealPathComponentIter;
1896 return SuggestReplacement;
1905 Module *ShadowingModule =
nullptr;
1913 }
else if (ShadowingModule) {
1916 diag::note_previous_definition);
1927std::pair<ConstSearchDirIterator, const FileEntry *>
1928Preprocessor::getIncludeNextStart(
const Token &IncludeNextTok)
const {
1933 const FileEntry *LookupFromFile =
nullptr;
1941 Diag(IncludeNextTok, diag::pp_include_next_in_primary);
1942 }
else if (CurLexerSubmodule) {
1945 assert(CurPPLexer &&
"#include_next directive in macro?");
1947 LookupFromFile = *FE;
1949 }
else if (!Lookup) {
1954 Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
1960 return {Lookup, LookupFromFile};
1976 if (FilenameTok.
isNot(tok::header_name)) {
1978 if (FilenameTok.
isNot(tok::eod))
1990 auto Action = HandleHeaderIncludeOrImport(HashLoc, IncludeTok, FilenameTok,
1991 EndLoc, LookupFrom, LookupFromFile);
1992 switch (Action.Kind) {
1993 case ImportAction::None:
1994 case ImportAction::SkippedModuleImport:
1996 case ImportAction::ModuleBegin:
1998 tok::annot_module_begin, Action.ModuleForHeader);
2000 case ImportAction::HeaderUnitImport:
2002 Action.ModuleForHeader);
2004 case ImportAction::ModuleImport:
2006 tok::annot_module_include, Action.ModuleForHeader);
2008 case ImportAction::Failure:
2010 "This should be an early exit only to a fatal error");
2013 CurLexer->cutOffLexing();
2021 const Token &FilenameTok,
bool &IsFrameworkFound,
bool IsImportDecl,
2023 const FileEntry *LookupFromFile, StringRef &LookupFilename,
2027 if (LangOpts.AsmPreprocessor)
2031 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
2032 bool RequestingModuleIsModuleInterface =
2036 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
2041 FilenameLoc, LookupFilename, isAngled, LookupFrom, LookupFromFile, CurDir,
2042 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2043 &SuggestedModule, &IsMapped, &IsFrameworkFound);
2045 DiagnoseHeaderInclusion(*
File);
2050 if (Callbacks && Callbacks->FileNotFound(
Filename))
2051 return std::nullopt;
2053 if (SuppressIncludeNotFoundError)
2054 return std::nullopt;
2061 FilenameLoc, LookupFilename,
false, LookupFrom, LookupFromFile, CurDir,
2062 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2063 &SuggestedModule, &IsMapped,
2066 DiagnoseHeaderInclusion(*
File);
2067 Diag(FilenameTok, diag::err_pp_file_not_found_angled_include_not_fatal)
2077 StringRef OriginalFilename =
Filename;
2078 if (LangOpts.SpellChecking) {
2081 auto CorrectTypoFilename = [](llvm::StringRef
Filename) {
2088 StringRef TypoCorrectionName = CorrectTypoFilename(
Filename);
2089 StringRef TypoCorrectionLookupName = CorrectTypoFilename(LookupFilename);
2092 FilenameLoc, TypoCorrectionLookupName, isAngled, LookupFrom,
2093 LookupFromFile, CurDir, Callbacks ? &SearchPath :
nullptr,
2094 Callbacks ? &RelativePath :
nullptr, &SuggestedModule, &IsMapped,
2097 DiagnoseHeaderInclusion(*
File);
2100 FilenameRange,
"<" + TypoCorrectionName.str() +
">")
2102 FilenameRange,
"\"" + TypoCorrectionName.str() +
"\"");
2103 Diag(FilenameTok, diag::err_pp_file_not_found_typo_not_fatal)
2104 << OriginalFilename << TypoCorrectionName << Hint;
2108 LookupFilename = TypoCorrectionLookupName;
2114 assert(!
File &&
"expected missing file");
2115 Diag(FilenameTok, diag::err_pp_file_not_found)
2116 << OriginalFilename << FilenameRange;
2117 if (IsFrameworkFound) {
2118 size_t SlashPos = OriginalFilename.find(
'/');
2119 assert(SlashPos != StringRef::npos &&
2120 "Include with framework name should have '/' in the filename");
2121 StringRef FrameworkName = OriginalFilename.substr(0, SlashPos);
2124 assert(CacheEntry.
Directory &&
"Found framework should be in cache");
2125 Diag(FilenameTok, diag::note_pp_framework_without_header)
2126 << OriginalFilename.substr(SlashPos + 1) << FrameworkName
2130 return std::nullopt;
2145Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
2155 StringRef OriginalFilename =
Filename;
2162 return {ImportAction::None};
2164 bool IsImportDecl = HashLoc.
isInvalid();
2168 if (PragmaARCCFCodeAuditedInfo.second.isValid()) {
2169 Diag(StartLoc, diag::err_pp_include_in_arc_cf_code_audited) << IsImportDecl;
2170 Diag(PragmaARCCFCodeAuditedInfo.second, diag::note_pragma_entered_here);
2177 if (PragmaAssumeNonNullLoc.
isValid()) {
2178 Diag(StartLoc, diag::err_pp_include_in_assume_nonnull) << IsImportDecl;
2179 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
2190 if (!NewName.empty())
2195 bool IsMapped =
false;
2196 bool IsFrameworkFound =
false;
2204 StringRef LookupFilename =
Filename;
2209 llvm::sys::path::Style BackslashStyle = llvm::sys::path::Style::native;
2210 if (is_style_posix(BackslashStyle) && LangOpts.MicrosoftExt) {
2212 llvm::sys::path::native(NormalizedPath);
2213 LookupFilename = NormalizedPath;
2214 BackslashStyle = llvm::sys::path::Style::windows;
2218 &CurDir,
Filename, FilenameLoc, FilenameRange, FilenameTok,
2219 IsFrameworkFound, IsImportDecl, IsMapped, LookupFrom, LookupFromFile,
2220 LookupFilename, RelativePath, SearchPath, SuggestedModule, isAngled);
2224 SkippingUntilPCHThroughHeader =
false;
2225 return {ImportAction::None};
2243 enum { Enter,
Import, Skip, IncludeLimitReached } Action = Enter;
2245 if (PPOpts->SingleFileParseMode)
2246 Action = IncludeLimitReached;
2251 if (Action == Enter && HasReachedMaxIncludeDepth &&
File &&
2253 Action = IncludeLimitReached;
2260 bool MaybeTranslateInclude = Action == Enter &&
File && ModuleToImport &&
2264 bool UsableHeaderUnit =
false;
2265 if (
getLangOpts().CPlusPlusModules && ModuleToImport &&
2267 if (TrackGMFState.inGMF() || IsImportDecl)
2268 UsableHeaderUnit =
true;
2269 else if (!IsImportDecl) {
2271 ModuleToImport =
nullptr;
2275 bool UsableClangHeaderModule =
2282 if (MaybeTranslateInclude && (UsableHeaderUnit || UsableClangHeaderModule)) {
2290 diag::note_implicit_top_level_module_import_here)
2292 return {ImportAction::None};
2299 for (
Module *Mod = ModuleToImport; Mod; Mod = Mod->
Parent)
2302 std::reverse(Path.begin(), Path.end());
2315 assert((Imported ==
nullptr || Imported == ModuleToImport) &&
2316 "the imported module is different than the suggested one");
2322 static_cast<Module *
>(Imported)->getTopLevelModule());
2327 ModuleToImport =
nullptr;
2336 assert(CurLexer &&
"#include but no current lexer set!");
2338 CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
2339 CurLexer->cutOffLexing();
2341 return {ImportAction::None};
2362 bool IsFirstIncludeOfFile =
false;
2366 if (Action == Enter &&
File &&
2369 IsFirstIncludeOfFile)) {
2380 if (UsableHeaderUnit && !
getLangOpts().CompilingPCH)
2381 Action = TrackGMFState.inGMF() ?
Import : Skip;
2383 Action = (ModuleToImport && !
getLangOpts().CompilingPCH) ? Import : Skip;
2391 if (Action == Enter &&
File && PreambleConditionalStack.isRecording() &&
2394 diag::err_pp_including_mainfile_in_preamble);
2395 return {ImportAction::None};
2398 if (Callbacks && !IsImportDecl) {
2401 Callbacks->InclusionDirective(HashLoc, IncludeTok, LookupFilename, isAngled,
2402 FilenameRange,
File, SearchPath, RelativePath,
2403 SuggestedModule.
getModule(), Action == Import,
2405 if (Action == Skip &&
File)
2406 Callbacks->FileSkipped(*
File, FilenameTok, FileCharacter);
2410 return {ImportAction::None};
2414 if (IsImportDecl && !ModuleToImport) {
2415 Diag(FilenameTok, diag::err_header_import_not_header_unit)
2416 << OriginalFilename <<
File->getName();
2417 return {ImportAction::None};
2422 const bool CheckIncludePathPortability =
2423 !IsMapped && !
File->getFileEntry().tryGetRealPathName().empty();
2425 if (CheckIncludePathPortability) {
2426 StringRef Name = LookupFilename;
2427 StringRef NameWithoriginalSlashes =
Filename;
2431 bool NameWasUNC = Name.consume_front(
"\\\\?\\");
2432 NameWithoriginalSlashes.consume_front(
"\\\\?\\");
2434 StringRef RealPathName =
File->getFileEntry().tryGetRealPathName();
2436 llvm::sys::path::end(Name));
2449 if (llvm::sys::path::is_absolute(Name) &&
2450 llvm::sys::path::is_absolute(RealPathName) &&
2453 assert(Components.size() >= 3 &&
"should have drive, backslash, name");
2454 assert(Components[0].size() == 2 &&
"should start with drive");
2455 assert(Components[0][1] ==
':' &&
"should have colon");
2456 FixedDriveRealPath = (Name.substr(0, 1) + RealPathName.substr(1)).str();
2457 RealPathName = FixedDriveRealPath;
2463 Path.reserve(Name.size()+2);
2464 Path.push_back(isAngled ?
'<' :
'"');
2466 const auto IsSep = [BackslashStyle](
char c) {
2467 return llvm::sys::path::is_separator(
c, BackslashStyle);
2470 for (
auto Component : Components) {
2482 if (!(Component.size() == 1 && IsSep(Component[0])))
2483 Path.append(Component);
2484 else if (Path.size() != 1)
2488 if (Path.size() > NameWithoriginalSlashes.size()) {
2489 Path.push_back(isAngled ?
'>' :
'"');
2492 assert(IsSep(NameWithoriginalSlashes[Path.size()-1]));
2494 Path.push_back(NameWithoriginalSlashes[Path.size()-1]);
2495 while (Path.size() <= NameWithoriginalSlashes.size() &&
2496 IsSep(NameWithoriginalSlashes[Path.size()-1]));
2502 Path = (Path.substr(0, 1) +
"\\\\?\\" + Path.substr(1)).str();
2509 ? diag::pp_nonportable_path
2510 : diag::pp_nonportable_system_path;
2511 Diag(FilenameTok, DiagId) << Path <<
2520 return {ImportAction::SkippedModuleImport, ModuleToImport};
2521 return {ImportAction::None};
2523 case IncludeLimitReached:
2526 return {ImportAction::None};
2530 assert(ModuleToImport &&
"no module to import");
2535 tok::pp___include_macros)
2536 return {ImportAction::None};
2538 return {ImportAction::ModuleImport, ModuleToImport};
2546 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
2547 Diag(FilenameTok, diag::err_pp_include_too_deep);
2548 HasReachedMaxIncludeDepth =
true;
2549 return {ImportAction::None};
2553 Diag(FilenameTok, diag::warn_pp_include_angled_in_module_purview)
2565 return ImportAction::Failure;
2570 IsFirstIncludeOfFile))
2571 return {ImportAction::None};
2575 if (ModuleToImport && !ModuleToImport->
isHeaderUnit()) {
2580 diag::err_module_build_shadowed_submodule)
2583 diag::note_previous_definition);
2584 return {ImportAction::None};
2596 return {ImportAction::None};
2598 assert(!CurLexerSubmodule &&
"should not have marked this as a module yet");
2599 CurLexerSubmodule = ModuleToImport;
2609 return {ImportAction::ModuleBegin, ModuleToImport};
2612 assert(!IsImportDecl &&
"failed to diagnose missing module for import decl");
2613 return {ImportAction::None};
2618void Preprocessor::HandleIncludeNextDirective(
SourceLocation HashLoc,
2619 Token &IncludeNextTok) {
2620 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
2624 std::tie(Lookup, LookupFromFile) = getIncludeNextStart(IncludeNextTok);
2626 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
2631void Preprocessor::HandleMicrosoftImportDirective(
Token &Tok) {
2637 Diag(Tok, diag::err_pp_import_directive_ms );
2648 if (!LangOpts.ObjC) {
2649 if (LangOpts.MSVCCompat)
2650 return HandleMicrosoftImportDirective(ImportTok);
2651 Diag(ImportTok, diag::ext_pp_import_directive);
2653 return HandleIncludeDirective(HashLoc, ImportTok);
2660void Preprocessor::HandleIncludeMacrosDirective(
SourceLocation HashLoc,
2661 Token &IncludeMacrosTok) {
2667 diag::pp_include_macros_out_of_predefines);
2674 HandleIncludeDirective(HashLoc, IncludeMacrosTok);
2679 assert(TmpTok.
isNot(tok::eof) &&
"Didn't find end of -imacros!");
2680 }
while (TmpTok.
isNot(tok::hashhash));
2691bool Preprocessor::ReadMacroParameterList(
MacroInfo *MI,
Token &Tok) {
2702 Diag(Tok, diag::err_pp_expected_ident_in_arg_list);
2706 Diag(Tok, LangOpts.CPlusPlus11 ?
2707 diag::warn_cxx98_compat_variadic_macro :
2708 diag::ext_variadic_macro);
2711 if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus) {
2712 Diag(Tok, diag::ext_pp_opencl_variadic_macros);
2717 if (Tok.
isNot(tok::r_paren)) {
2718 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2727 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2735 Diag(Tok, diag::err_pp_invalid_tok_in_arg_list);
2741 if (llvm::is_contained(Parameters, II)) {
2742 Diag(Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
2754 Diag(Tok, diag::err_pp_expected_comma_in_arg_list);
2763 Diag(Tok, diag::ext_named_variadic_macro);
2767 if (Tok.
isNot(tok::r_paren)) {
2768 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2798 StringRef ValueText = II->
getName();
2799 StringRef TrimmedValue = ValueText;
2800 if (!ValueText.starts_with(
"__")) {
2801 if (ValueText.starts_with(
"_"))
2802 TrimmedValue = TrimmedValue.drop_front(1);
2806 TrimmedValue = TrimmedValue.drop_front(2);
2807 if (TrimmedValue.ends_with(
"__"))
2808 TrimmedValue = TrimmedValue.drop_back(2);
2810 return TrimmedValue == MacroText;
2817 return MacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
2830MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
2831 const Token &MacroNameTok,
const bool ImmediatelyAfterHeaderGuard) {
2833 Token LastTok = MacroNameTok;
2841 auto _ = llvm::make_scope_exit([&]() {
2843 if (CurLexer->ParsingPreprocessorDirective)
2854 if (Tok.
is(tok::eod)) {
2855 if (ImmediatelyAfterHeaderGuard) {
2865 }
else if (Tok.
is(tok::l_paren)) {
2868 if (ReadMacroParameterList(MI, LastTok))
2882 }
else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
2885 Diag(Tok, diag::ext_c99_whitespace_required_after_macro_name);
2894 if (Tok.
is(tok::at))
2896 else if (Tok.
is(tok::unknown)) {
2903 Diag(Tok, diag::ext_missing_whitespace_after_macro_name);
2905 Diag(Tok, diag::warn_missing_whitespace_after_macro_name);
2908 if (!Tok.
is(tok::eod))
2916 while (Tok.
isNot(tok::eod)) {
2918 Tokens.push_back(Tok);
2929 while (Tok.
isNot(tok::eod)) {
2932 if (!Tok.
isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
2933 Tokens.push_back(Tok);
2935 if (VAOCtx.isVAOptToken(Tok)) {
2937 if (VAOCtx.isInVAOpt()) {
2938 Diag(Tok, diag::err_pp_vaopt_nested_use);
2943 if (Tok.
isNot(tok::l_paren)) {
2944 Diag(Tok, diag::err_pp_missing_lparen_in_vaopt_use);
2947 Tokens.push_back(Tok);
2948 VAOCtx.sawVAOptFollowedByOpeningParens(Tok.
getLocation());
2950 if (Tok.
is(tok::hashhash)) {
2951 Diag(Tok, diag::err_vaopt_paste_at_start);
2955 }
else if (VAOCtx.isInVAOpt()) {
2956 if (Tok.
is(tok::r_paren)) {
2957 if (VAOCtx.sawClosingParen()) {
2958 assert(Tokens.size() >= 3 &&
2959 "Must have seen at least __VA_OPT__( "
2960 "and a subsequent tok::r_paren");
2961 if (Tokens[Tokens.size() - 2].is(tok::hashhash)) {
2962 Diag(Tok, diag::err_vaopt_paste_at_end);
2966 }
else if (Tok.
is(tok::l_paren)) {
2980 Tokens.push_back(Tok);
2987 if (Tok.
is(tok::hashhash)) {
2995 if (Tok.
is(tok::eod)) {
2996 Tokens.push_back(LastTok);
3001 Tokens[Tokens.size() - 1].is(tok::comma))
3005 Tokens.push_back(LastTok);
3014 if (!VAOCtx.isVAOptToken(Tok) &&
3023 LastTok.
setKind(tok::unknown);
3024 Tokens.push_back(LastTok);
3027 Diag(Tok, diag::err_pp_stringize_not_parameter)
3028 << LastTok.
is(tok::hashat);
3034 Tokens.push_back(LastTok);
3039 if (!VAOCtx.isVAOptToken(Tok)) {
3040 Tokens.push_back(Tok);
3047 if (VAOCtx.isInVAOpt()) {
3048 assert(Tok.
is(tok::eod) &&
"Must be at End Of preprocessing Directive");
3049 Diag(Tok, diag::err_pp_expected_after)
3050 << LastTok.
getKind() << tok::r_paren;
3051 Diag(VAOCtx.getUnmatchedOpeningParenLoc(), diag::note_matching) << tok::l_paren;
3062 return II->
isStr(
"__strong") || II->
isStr(
"__weak") ||
3063 II->
isStr(
"__unsafe_unretained") || II->
isStr(
"__autoreleasing");
3068void Preprocessor::HandleDefineDirective(
3069 Token &DefineTok,
const bool ImmediatelyAfterHeaderGuard) {
3073 bool MacroShadowsKeyword;
3074 ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
3077 if (MacroNameTok.
is(tok::eod))
3084 emitFinalMacroWarning(MacroNameTok,
false);
3088 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
3090 MacroInfo *
const MI = ReadOptionalMacroParameterListAndBody(
3091 MacroNameTok, ImmediatelyAfterHeaderGuard);
3095 if (MacroShadowsKeyword &&
3097 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
3102 if (NumTokens != 0) {
3114 if (SkippingUntilPCHThroughHeader) {
3117 LangOpts.MicrosoftExt))
3121 if (!LangOpts.MicrosoftExt)
3132 emitFinalMacroWarning(MacroNameTok,
false);
3145 LangOpts.MicrosoftExt)) {
3164 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
3168 !MI->
isIdenticalTo(*OtherMI, *
this, LangOpts.MicrosoftExt)) {
3186 !MacroExpansionInDirectivesOverride &&
3195 Callbacks->MacroDefined(MacroNameTok, MD);
3208 Tok.
setKind(tok::kw__Static_assert);
3217void Preprocessor::HandleUndefDirective() {
3221 ReadMacroName(MacroNameTok,
MU_Undef);
3224 if (MacroNameTok.
is(tok::eod))
3236 emitFinalMacroWarning(MacroNameTok,
true);
3246 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
3251 Undef = AllocateUndefMacroDirective(MacroNameTok.
getLocation());
3257 Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
3272void Preprocessor::HandleIfdefDirective(
Token &
Result,
3273 const Token &HashToken,
3275 bool ReadAnyTokensBeforeDirective) {
3280 ReadMacroName(MacroNameTok);
3283 if (MacroNameTok.
is(tok::eod)) {
3286 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3306 if (!ReadAnyTokensBeforeDirective && !MI) {
3307 assert(isIfndef &&
"#ifdef shouldn't reach here");
3319 Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3321 Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3324 bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3328 if (PPOpts->SingleFileParseMode && !MI) {
3334 }
else if (!MI == isIfndef || RetainExcludedCB) {
3341 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3350void Preprocessor::HandleIfDirective(
Token &IfToken,
3351 const Token &HashToken,
3352 bool ReadAnyTokensBeforeDirective) {
3357 const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
3358 const bool ConditionalTrue = DER.Conditional;
3367 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
3379 bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3383 if (PPOpts->SingleFileParseMode && DER.IncludedUndefinedIds) {
3388 }
else if (ConditionalTrue || RetainExcludedCB) {
3402void Preprocessor::HandleEndifDirective(
Token &EndifToken) {
3411 Diag(EndifToken, diag::err_pp_endif_without_if);
3420 "This code should only be reachable in the non-skipping case!");
3428void Preprocessor::HandleElseDirective(
Token &
Result,
const Token &HashToken) {
3450 bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3453 if ((PPOpts->SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3464 true,
Result.getLocation());
3468void Preprocessor::HandleElifFamilyDirective(
Token &ElifToken,
3469 const Token &HashToken,
3481 if (LangOpts.CPlusPlus)
3482 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
3483 : diag::ext_cxx23_pp_directive;
3485 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
3486 : diag::ext_c23_pp_directive;
3487 Diag(ElifToken, DiagID) << DirKind;
3500 Diag(ElifToken, diag::pp_err_elif_without_if) << DirKind;
3510 Diag(ElifToken, diag::pp_err_elif_after_else) << DirKind;
3515 Callbacks->Elif(ElifToken.
getLocation(), ConditionRange,
3518 case tok::pp_elifdef:
3521 case tok::pp_elifndef:
3525 assert(
false &&
"unexpected directive kind");
3530 bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3533 if ((PPOpts->SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3542 SkipExcludedConditionalBlock(
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.
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.
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).
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
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...
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.
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...
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
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
SourceRange DiscardUntilEndOfDirective()
Read and discard all tokens remaining on the current line until the tok::eod token is found.
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
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.
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.
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].
@ 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.
This structure is used to record entries in our framework cache.
OptionalDirectoryEntryRef Directory
The directory entry which should be used for the cached framework.
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.