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.equals(
"override") ||
Text.equals(
"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);
891 while (!Loc.
isInvalid() && !
SM.isInMainFile(Loc)) {
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);
1926std::pair<ConstSearchDirIterator, const FileEntry *>
1927Preprocessor::getIncludeNextStart(
const Token &IncludeNextTok)
const {
1932 const FileEntry *LookupFromFile =
nullptr;
1940 Diag(IncludeNextTok, diag::pp_include_next_in_primary);
1941 }
else if (CurLexerSubmodule) {
1944 assert(CurPPLexer &&
"#include_next directive in macro?");
1946 LookupFromFile = *FE;
1948 }
else if (!Lookup) {
1953 Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
1959 return {Lookup, LookupFromFile};
1975 if (FilenameTok.
isNot(tok::header_name)) {
1977 if (FilenameTok.
isNot(tok::eod))
1989 auto Action = HandleHeaderIncludeOrImport(HashLoc, IncludeTok, FilenameTok,
1990 EndLoc, LookupFrom, LookupFromFile);
1991 switch (Action.Kind) {
1992 case ImportAction::None:
1993 case ImportAction::SkippedModuleImport:
1995 case ImportAction::ModuleBegin:
1997 tok::annot_module_begin, Action.ModuleForHeader);
1999 case ImportAction::HeaderUnitImport:
2001 Action.ModuleForHeader);
2003 case ImportAction::ModuleImport:
2005 tok::annot_module_include, Action.ModuleForHeader);
2007 case ImportAction::Failure:
2009 "This should be an early exit only to a fatal error");
2012 CurLexer->cutOffLexing();
2020 const Token &FilenameTok,
bool &IsFrameworkFound,
bool IsImportDecl,
2022 const FileEntry *LookupFromFile, StringRef &LookupFilename,
2026 if (LangOpts.AsmPreprocessor)
2030 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
2031 bool RequestingModuleIsModuleInterface =
2035 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
2040 FilenameLoc, LookupFilename, isAngled, LookupFrom, LookupFromFile, CurDir,
2041 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2042 &SuggestedModule, &IsMapped, &IsFrameworkFound);
2044 DiagnoseHeaderInclusion(*
File);
2049 if (Callbacks && Callbacks->FileNotFound(
Filename))
2050 return std::nullopt;
2052 if (SuppressIncludeNotFoundError)
2053 return std::nullopt;
2060 FilenameLoc, LookupFilename,
false, LookupFrom, LookupFromFile, CurDir,
2061 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2062 &SuggestedModule, &IsMapped,
2065 DiagnoseHeaderInclusion(*
File);
2066 Diag(FilenameTok, diag::err_pp_file_not_found_angled_include_not_fatal)
2076 StringRef OriginalFilename =
Filename;
2077 if (LangOpts.SpellChecking) {
2080 auto CorrectTypoFilename = [](llvm::StringRef
Filename) {
2087 StringRef TypoCorrectionName = CorrectTypoFilename(
Filename);
2088 StringRef TypoCorrectionLookupName = CorrectTypoFilename(LookupFilename);
2091 FilenameLoc, TypoCorrectionLookupName, isAngled, LookupFrom,
2092 LookupFromFile, CurDir, Callbacks ? &SearchPath :
nullptr,
2093 Callbacks ? &RelativePath :
nullptr, &SuggestedModule, &IsMapped,
2096 DiagnoseHeaderInclusion(*
File);
2099 FilenameRange,
"<" + TypoCorrectionName.str() +
">")
2101 FilenameRange,
"\"" + TypoCorrectionName.str() +
"\"");
2102 Diag(FilenameTok, diag::err_pp_file_not_found_typo_not_fatal)
2103 << OriginalFilename << TypoCorrectionName << Hint;
2107 LookupFilename = TypoCorrectionLookupName;
2113 assert(!
File &&
"expected missing file");
2114 Diag(FilenameTok, diag::err_pp_file_not_found)
2115 << OriginalFilename << FilenameRange;
2116 if (IsFrameworkFound) {
2117 size_t SlashPos = OriginalFilename.find(
'/');
2118 assert(SlashPos != StringRef::npos &&
2119 "Include with framework name should have '/' in the filename");
2120 StringRef FrameworkName = OriginalFilename.substr(0, SlashPos);
2123 assert(CacheEntry.
Directory &&
"Found framework should be in cache");
2124 Diag(FilenameTok, diag::note_pp_framework_without_header)
2125 << OriginalFilename.substr(SlashPos + 1) << FrameworkName
2129 return std::nullopt;
2144Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
2154 StringRef OriginalFilename =
Filename;
2161 return {ImportAction::None};
2163 bool IsImportDecl = HashLoc.
isInvalid();
2167 if (PragmaARCCFCodeAuditedInfo.second.isValid()) {
2168 Diag(StartLoc, diag::err_pp_include_in_arc_cf_code_audited) << IsImportDecl;
2169 Diag(PragmaARCCFCodeAuditedInfo.second, diag::note_pragma_entered_here);
2176 if (PragmaAssumeNonNullLoc.
isValid()) {
2177 Diag(StartLoc, diag::err_pp_include_in_assume_nonnull) << IsImportDecl;
2178 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
2189 if (!NewName.empty())
2194 bool IsMapped =
false;
2195 bool IsFrameworkFound =
false;
2203 StringRef LookupFilename =
Filename;
2208 llvm::sys::path::Style BackslashStyle = llvm::sys::path::Style::native;
2209 if (is_style_posix(BackslashStyle) && LangOpts.MicrosoftExt) {
2211 llvm::sys::path::native(NormalizedPath);
2212 LookupFilename = NormalizedPath;
2213 BackslashStyle = llvm::sys::path::Style::windows;
2217 &CurDir,
Filename, FilenameLoc, FilenameRange, FilenameTok,
2218 IsFrameworkFound, IsImportDecl, IsMapped, LookupFrom, LookupFromFile,
2219 LookupFilename, RelativePath, SearchPath, SuggestedModule, isAngled);
2223 SkippingUntilPCHThroughHeader =
false;
2224 return {ImportAction::None};
2242 enum { Enter,
Import, Skip, IncludeLimitReached } Action = Enter;
2244 if (PPOpts->SingleFileParseMode)
2245 Action = IncludeLimitReached;
2250 if (Action == Enter && HasReachedMaxIncludeDepth &&
File &&
2252 Action = IncludeLimitReached;
2259 bool MaybeTranslateInclude = Action == Enter &&
File && ModuleToImport &&
2263 bool UsableHeaderUnit =
false;
2264 if (
getLangOpts().CPlusPlusModules && ModuleToImport &&
2266 if (TrackGMFState.inGMF() || IsImportDecl)
2267 UsableHeaderUnit =
true;
2268 else if (!IsImportDecl) {
2270 ModuleToImport =
nullptr;
2274 bool UsableClangHeaderModule =
2281 if (MaybeTranslateInclude && (UsableHeaderUnit || UsableClangHeaderModule)) {
2289 diag::note_implicit_top_level_module_import_here)
2291 return {ImportAction::None};
2298 for (
Module *Mod = ModuleToImport; Mod; Mod = Mod->
Parent)
2301 std::reverse(Path.begin(), Path.end());
2314 assert((Imported ==
nullptr || Imported == ModuleToImport) &&
2315 "the imported module is different than the suggested one");
2321 static_cast<Module *
>(Imported)->getTopLevelModule());
2326 ModuleToImport =
nullptr;
2335 assert(CurLexer &&
"#include but no current lexer set!");
2337 CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
2338 CurLexer->cutOffLexing();
2340 return {ImportAction::None};
2361 bool IsFirstIncludeOfFile =
false;
2365 if (Action == Enter &&
File &&
2368 IsFirstIncludeOfFile)) {
2379 if (UsableHeaderUnit && !
getLangOpts().CompilingPCH)
2380 Action = TrackGMFState.inGMF() ?
Import : Skip;
2382 Action = (ModuleToImport && !
getLangOpts().CompilingPCH) ? Import : Skip;
2390 if (Action == Enter &&
File && PreambleConditionalStack.isRecording() &&
2393 diag::err_pp_including_mainfile_in_preamble);
2394 return {ImportAction::None};
2397 if (Callbacks && !IsImportDecl) {
2400 Callbacks->InclusionDirective(HashLoc, IncludeTok, LookupFilename, isAngled,
2401 FilenameRange,
File, SearchPath, RelativePath,
2402 SuggestedModule.
getModule(), Action == Import,
2404 if (Action == Skip &&
File)
2405 Callbacks->FileSkipped(*
File, FilenameTok, FileCharacter);
2409 return {ImportAction::None};
2413 if (IsImportDecl && !ModuleToImport) {
2414 Diag(FilenameTok, diag::err_header_import_not_header_unit)
2415 << OriginalFilename <<
File->getName();
2416 return {ImportAction::None};
2421 const bool CheckIncludePathPortability =
2422 !IsMapped && !
File->getFileEntry().tryGetRealPathName().empty();
2424 if (CheckIncludePathPortability) {
2425 StringRef Name = LookupFilename;
2426 StringRef NameWithoriginalSlashes =
Filename;
2430 bool NameWasUNC = Name.consume_front(
"\\\\?\\");
2431 NameWithoriginalSlashes.consume_front(
"\\\\?\\");
2433 StringRef RealPathName =
File->getFileEntry().tryGetRealPathName();
2435 llvm::sys::path::end(Name));
2448 if (llvm::sys::path::is_absolute(Name) &&
2449 llvm::sys::path::is_absolute(RealPathName) &&
2452 assert(Components.size() >= 3 &&
"should have drive, backslash, name");
2453 assert(Components[0].size() == 2 &&
"should start with drive");
2454 assert(Components[0][1] ==
':' &&
"should have colon");
2455 FixedDriveRealPath = (Name.substr(0, 1) + RealPathName.substr(1)).str();
2456 RealPathName = FixedDriveRealPath;
2462 Path.reserve(Name.size()+2);
2463 Path.push_back(isAngled ?
'<' :
'"');
2465 const auto IsSep = [BackslashStyle](
char c) {
2466 return llvm::sys::path::is_separator(
c, BackslashStyle);
2469 for (
auto Component : Components) {
2481 if (!(Component.size() == 1 && IsSep(Component[0])))
2482 Path.append(Component);
2483 else if (Path.size() != 1)
2487 if (Path.size() > NameWithoriginalSlashes.size()) {
2488 Path.push_back(isAngled ?
'>' :
'"');
2491 assert(IsSep(NameWithoriginalSlashes[Path.size()-1]));
2493 Path.push_back(NameWithoriginalSlashes[Path.size()-1]);
2494 while (Path.size() <= NameWithoriginalSlashes.size() &&
2495 IsSep(NameWithoriginalSlashes[Path.size()-1]));
2501 Path = (Path.substr(0, 1) +
"\\\\?\\" + Path.substr(1)).str();
2508 ? diag::pp_nonportable_path
2509 : diag::pp_nonportable_system_path;
2510 Diag(FilenameTok, DiagId) << Path <<
2519 return {ImportAction::SkippedModuleImport, ModuleToImport};
2520 return {ImportAction::None};
2522 case IncludeLimitReached:
2525 return {ImportAction::None};
2529 assert(ModuleToImport &&
"no module to import");
2534 tok::pp___include_macros)
2535 return {ImportAction::None};
2537 return {ImportAction::ModuleImport, ModuleToImport};
2545 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
2546 Diag(FilenameTok, diag::err_pp_include_too_deep);
2547 HasReachedMaxIncludeDepth =
true;
2548 return {ImportAction::None};
2552 Diag(FilenameTok, diag::warn_pp_include_angled_in_module_purview)
2564 return ImportAction::Failure;
2569 IsFirstIncludeOfFile))
2570 return {ImportAction::None};
2574 if (ModuleToImport && !ModuleToImport->
isHeaderUnit()) {
2579 diag::err_module_build_shadowed_submodule)
2582 diag::note_previous_definition);
2583 return {ImportAction::None};
2595 return {ImportAction::None};
2597 assert(!CurLexerSubmodule &&
"should not have marked this as a module yet");
2598 CurLexerSubmodule = ModuleToImport;
2608 return {ImportAction::ModuleBegin, ModuleToImport};
2611 assert(!IsImportDecl &&
"failed to diagnose missing module for import decl");
2612 return {ImportAction::None};
2617void Preprocessor::HandleIncludeNextDirective(
SourceLocation HashLoc,
2618 Token &IncludeNextTok) {
2619 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
2623 std::tie(Lookup, LookupFromFile) = getIncludeNextStart(IncludeNextTok);
2625 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
2630void Preprocessor::HandleMicrosoftImportDirective(
Token &Tok) {
2636 Diag(Tok, diag::err_pp_import_directive_ms );
2647 if (!LangOpts.ObjC) {
2648 if (LangOpts.MSVCCompat)
2649 return HandleMicrosoftImportDirective(ImportTok);
2650 Diag(ImportTok, diag::ext_pp_import_directive);
2652 return HandleIncludeDirective(HashLoc, ImportTok);
2659void Preprocessor::HandleIncludeMacrosDirective(
SourceLocation HashLoc,
2660 Token &IncludeMacrosTok) {
2666 diag::pp_include_macros_out_of_predefines);
2673 HandleIncludeDirective(HashLoc, IncludeMacrosTok);
2678 assert(TmpTok.
isNot(tok::eof) &&
"Didn't find end of -imacros!");
2679 }
while (TmpTok.
isNot(tok::hashhash));
2690bool Preprocessor::ReadMacroParameterList(
MacroInfo *MI,
Token &Tok) {
2701 Diag(Tok, diag::err_pp_expected_ident_in_arg_list);
2705 Diag(Tok, LangOpts.CPlusPlus11 ?
2706 diag::warn_cxx98_compat_variadic_macro :
2707 diag::ext_variadic_macro);
2710 if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus) {
2711 Diag(Tok, diag::ext_pp_opencl_variadic_macros);
2716 if (Tok.
isNot(tok::r_paren)) {
2717 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2726 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2734 Diag(Tok, diag::err_pp_invalid_tok_in_arg_list);
2740 if (llvm::is_contained(Parameters, II)) {
2741 Diag(Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
2753 Diag(Tok, diag::err_pp_expected_comma_in_arg_list);
2762 Diag(Tok, diag::ext_named_variadic_macro);
2766 if (Tok.
isNot(tok::r_paren)) {
2767 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2797 StringRef ValueText = II->
getName();
2798 StringRef TrimmedValue = ValueText;
2799 if (!ValueText.starts_with(
"__")) {
2800 if (ValueText.starts_with(
"_"))
2801 TrimmedValue = TrimmedValue.drop_front(1);
2805 TrimmedValue = TrimmedValue.drop_front(2);
2806 if (TrimmedValue.ends_with(
"__"))
2807 TrimmedValue = TrimmedValue.drop_back(2);
2809 return TrimmedValue.equals(MacroText);
2816 return MacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
2829MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
2830 const Token &MacroNameTok,
const bool ImmediatelyAfterHeaderGuard) {
2832 Token LastTok = MacroNameTok;
2840 auto _ = llvm::make_scope_exit([&]() {
2842 if (CurLexer->ParsingPreprocessorDirective)
2853 if (Tok.
is(tok::eod)) {
2854 if (ImmediatelyAfterHeaderGuard) {
2864 }
else if (Tok.
is(tok::l_paren)) {
2867 if (ReadMacroParameterList(MI, LastTok))
2881 }
else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
2884 Diag(Tok, diag::ext_c99_whitespace_required_after_macro_name);
2893 if (Tok.
is(tok::at))
2895 else if (Tok.
is(tok::unknown)) {
2902 Diag(Tok, diag::ext_missing_whitespace_after_macro_name);
2904 Diag(Tok, diag::warn_missing_whitespace_after_macro_name);
2907 if (!Tok.
is(tok::eod))
2915 while (Tok.
isNot(tok::eod)) {
2917 Tokens.push_back(Tok);
2928 while (Tok.
isNot(tok::eod)) {
2931 if (!Tok.
isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
2932 Tokens.push_back(Tok);
2934 if (VAOCtx.isVAOptToken(Tok)) {
2936 if (VAOCtx.isInVAOpt()) {
2937 Diag(Tok, diag::err_pp_vaopt_nested_use);
2942 if (Tok.
isNot(tok::l_paren)) {
2943 Diag(Tok, diag::err_pp_missing_lparen_in_vaopt_use);
2946 Tokens.push_back(Tok);
2947 VAOCtx.sawVAOptFollowedByOpeningParens(Tok.
getLocation());
2949 if (Tok.
is(tok::hashhash)) {
2950 Diag(Tok, diag::err_vaopt_paste_at_start);
2954 }
else if (VAOCtx.isInVAOpt()) {
2955 if (Tok.
is(tok::r_paren)) {
2956 if (VAOCtx.sawClosingParen()) {
2957 assert(Tokens.size() >= 3 &&
2958 "Must have seen at least __VA_OPT__( "
2959 "and a subsequent tok::r_paren");
2960 if (Tokens[Tokens.size() - 2].is(tok::hashhash)) {
2961 Diag(Tok, diag::err_vaopt_paste_at_end);
2965 }
else if (Tok.
is(tok::l_paren)) {
2979 Tokens.push_back(Tok);
2986 if (Tok.
is(tok::hashhash)) {
2994 if (Tok.
is(tok::eod)) {
2995 Tokens.push_back(LastTok);
3000 Tokens[Tokens.size() - 1].is(tok::comma))
3004 Tokens.push_back(LastTok);
3013 if (!VAOCtx.isVAOptToken(Tok) &&
3022 LastTok.
setKind(tok::unknown);
3023 Tokens.push_back(LastTok);
3026 Diag(Tok, diag::err_pp_stringize_not_parameter)
3027 << LastTok.
is(tok::hashat);
3033 Tokens.push_back(LastTok);
3038 if (!VAOCtx.isVAOptToken(Tok)) {
3039 Tokens.push_back(Tok);
3046 if (VAOCtx.isInVAOpt()) {
3047 assert(Tok.
is(tok::eod) &&
"Must be at End Of preprocessing Directive");
3048 Diag(Tok, diag::err_pp_expected_after)
3049 << LastTok.
getKind() << tok::r_paren;
3050 Diag(VAOCtx.getUnmatchedOpeningParenLoc(), diag::note_matching) << tok::l_paren;
3061 return II->
isStr(
"__strong") || II->
isStr(
"__weak") ||
3062 II->
isStr(
"__unsafe_unretained") || II->
isStr(
"__autoreleasing");
3067void Preprocessor::HandleDefineDirective(
3068 Token &DefineTok,
const bool ImmediatelyAfterHeaderGuard) {
3072 bool MacroShadowsKeyword;
3073 ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
3076 if (MacroNameTok.
is(tok::eod))
3083 emitFinalMacroWarning(MacroNameTok,
false);
3087 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
3089 MacroInfo *
const MI = ReadOptionalMacroParameterListAndBody(
3090 MacroNameTok, ImmediatelyAfterHeaderGuard);
3094 if (MacroShadowsKeyword &&
3096 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
3101 if (NumTokens != 0) {
3113 if (SkippingUntilPCHThroughHeader) {
3116 LangOpts.MicrosoftExt))
3120 if (!LangOpts.MicrosoftExt)
3131 emitFinalMacroWarning(MacroNameTok,
false);
3144 LangOpts.MicrosoftExt)) {
3163 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
3167 !MI->
isIdenticalTo(*OtherMI, *
this, LangOpts.MicrosoftExt)) {
3185 !MacroExpansionInDirectivesOverride &&
3194 Callbacks->MacroDefined(MacroNameTok, MD);
3207 Tok.
setKind(tok::kw__Static_assert);
3216void Preprocessor::HandleUndefDirective() {
3220 ReadMacroName(MacroNameTok,
MU_Undef);
3223 if (MacroNameTok.
is(tok::eod))
3235 emitFinalMacroWarning(MacroNameTok,
true);
3245 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
3250 Undef = AllocateUndefMacroDirective(MacroNameTok.
getLocation());
3256 Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
3271void Preprocessor::HandleIfdefDirective(
Token &
Result,
3272 const Token &HashToken,
3274 bool ReadAnyTokensBeforeDirective) {
3279 ReadMacroName(MacroNameTok);
3282 if (MacroNameTok.
is(tok::eod)) {
3285 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3305 if (!ReadAnyTokensBeforeDirective && !MI) {
3306 assert(isIfndef &&
"#ifdef shouldn't reach here");
3318 Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3320 Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3323 bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3327 if (PPOpts->SingleFileParseMode && !MI) {
3333 }
else if (!MI == isIfndef || RetainExcludedCB) {
3340 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3349void Preprocessor::HandleIfDirective(
Token &IfToken,
3350 const Token &HashToken,
3351 bool ReadAnyTokensBeforeDirective) {
3356 const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
3357 const bool ConditionalTrue = DER.Conditional;
3366 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
3378 bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3382 if (PPOpts->SingleFileParseMode && DER.IncludedUndefinedIds) {
3387 }
else if (ConditionalTrue || RetainExcludedCB) {
3401void Preprocessor::HandleEndifDirective(
Token &EndifToken) {
3410 Diag(EndifToken, diag::err_pp_endif_without_if);
3419 "This code should only be reachable in the non-skipping case!");
3427void Preprocessor::HandleElseDirective(
Token &
Result,
const Token &HashToken) {
3449 bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3452 if ((PPOpts->SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3463 true,
Result.getLocation());
3467void Preprocessor::HandleElifFamilyDirective(
Token &ElifToken,
3468 const Token &HashToken,
3480 if (LangOpts.CPlusPlus)
3481 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
3482 : diag::ext_cxx23_pp_directive;
3484 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
3485 : diag::ext_c23_pp_directive;
3486 Diag(ElifToken, DiagID) << DirKind;
3499 Diag(ElifToken, diag::pp_err_elif_without_if) << DirKind;
3509 Diag(ElifToken, diag::pp_err_elif_after_else) << DirKind;
3514 Callbacks->Elif(ElifToken.
getLocation(), ConditionRange,
3517 case tok::pp_elifdef:
3520 case tok::pp_elifndef:
3524 assert(
false &&
"unexpected directive kind");
3529 bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3532 if ((PPOpts->SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3541 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.
std::pair< std::string, bool > Requirement
An individual requirement: a feature name and a flag indicating the required state of that feature.
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
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.