39#include "llvm/ADT/ArrayRef.h"
40#include "llvm/ADT/STLExtras.h"
41#include "llvm/ADT/ScopeExit.h"
42#include "llvm/ADT/SmallVector.h"
43#include "llvm/ADT/StringExtras.h"
44#include "llvm/ADT/StringRef.h"
45#include "llvm/ADT/StringSwitch.h"
46#include "llvm/Support/ErrorHandling.h"
47#include "llvm/Support/Path.h"
48#include "llvm/Support/SaveAndRestore.h"
64 static_assert(std::is_trivially_destructible_v<MacroInfo>,
"");
74Preprocessor::AllocateUndefMacroDirective(
SourceLocation UndefLoc) {
81 return new (BP) VisibilityMacroDirective(Loc, isPublic);
89 auto ReadNextTok = [&]() {
91 if (DiscardedToks && Tmp.
isNot(tok::eod))
92 DiscardedToks->push_back(Tmp);
96 while (Tmp.
isNot(tok::eod)) {
97 assert(Tmp.
isNot(tok::eof) &&
"EOF seen while discarding directive tokens");
126 static constexpr StringRef ReservedMacro[] = {
129 "_CRT_NONSTDC_NO_WARNINGS",
130 "_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES",
131 "_CRT_SECURE_NO_WARNINGS",
134 "_GLIBCXX_ASSERTIONS",
135 "_GLIBCXX_CONCEPT_CHECKS",
137 "_GLIBCXX_DEBUG_PEDANTIC",
139 "_GLIBCXX_PARALLEL_ASSERTIONS",
140 "_GLIBCXX_SANITIZE_VECTOR",
141 "_GLIBCXX_USE_CXX11_ABI",
142 "_GLIBCXX_USE_DEPRECATED",
147 "_LARGEFILE64_SOURCE",
153 "_XOPEN_SOURCE_EXTENDED",
154 "__STDCPP_WANT_MATH_SPEC_FUNCS__",
155 "__STDC_FORMAT_MACROS",
157 return llvm::binary_search(ReservedMacro, MacroName);
162 const StringRef MacroName) {
172 if (MacroName.starts_with(
"__STDC"))
175 if (MacroName ==
"__cplusplus")
178 if (MacroName.starts_with(
"__cpp"))
186 if (Lang.CPlusPlus &&
207 if (Lang.CPlusPlus11 && (
Text ==
"override" ||
Text ==
"final"))
232 if (::llvm::sys::path::begin(Include)->equals_insensitive(
"boost"))
237 static const size_t MaxStdHeaderNameLen = 18u;
238 if (Include.size() > MaxStdHeaderNameLen)
243 for (
char &Ch : LowerInclude) {
245 if (
static_cast<unsigned char>(Ch) > 0x7f)
248 if (Ch >=
'A' && Ch <=
'Z')
251 else if (::llvm::sys::path::is_separator(Ch))
256 return llvm::StringSwitch<bool>(LowerInclude)
258 .Cases({
"assert.h",
"complex.h",
"ctype.h",
"errno.h",
"fenv.h"},
true)
259 .Cases({
"float.h",
"inttypes.h",
"iso646.h",
"limits.h",
"locale.h"},
261 .Cases({
"math.h",
"setjmp.h",
"signal.h",
"stdalign.h",
"stdarg.h"},
true)
262 .Cases({
"stdatomic.h",
"stdbool.h",
"stdckdint.h",
"stdcountof.h"},
true)
263 .Cases({
"stddef.h",
"stdint.h",
"stdio.h",
"stdlib.h",
"stdnoreturn.h"},
265 .Cases({
"string.h",
"tgmath.h",
"threads.h",
"time.h",
"uchar.h"},
true)
266 .Cases({
"wchar.h",
"wctype.h"},
true)
269 .Cases({
"cassert",
"ccomplex",
"cctype",
"cerrno",
"cfenv"},
true)
270 .Cases({
"cfloat",
"cinttypes",
"ciso646",
"climits",
"clocale"},
true)
271 .Cases({
"cmath",
"csetjmp",
"csignal",
"cstdalign",
"cstdarg"},
true)
272 .Cases({
"cstdbool",
"cstddef",
"cstdint",
"cstdio",
"cstdlib"},
true)
273 .Cases({
"cstring",
"ctgmath",
"ctime",
"cuchar",
"cwchar"},
true)
274 .Case(
"cwctype",
true)
277 .Cases({
"algorithm",
"fstream",
"list",
"regex",
"thread"},
true)
278 .Cases({
"array",
"functional",
"locale",
"scoped_allocator",
"tuple"},
280 .Cases({
"atomic",
"future",
"map",
"set",
"type_traits"},
true)
282 {
"bitset",
"initializer_list",
"memory",
"shared_mutex",
"typeindex"},
284 .Cases({
"chrono",
"iomanip",
"mutex",
"sstream",
"typeinfo"},
true)
285 .Cases({
"codecvt",
"ios",
"new",
"stack",
"unordered_map"},
true)
286 .Cases({
"complex",
"iosfwd",
"numeric",
"stdexcept",
"unordered_set"},
289 {
"condition_variable",
"iostream",
"ostream",
"streambuf",
"utility"},
291 .Cases({
"deque",
"istream",
"queue",
"string",
"valarray"},
true)
292 .Cases({
"exception",
"iterator",
"random",
"strstream",
"vector"},
true)
293 .Cases({
"forward_list",
"limits",
"ratio",
"system_error"},
true)
296 .Cases({
"aio.h",
"arpa/inet.h",
"cpio.h",
"dirent.h",
"dlfcn.h"},
true)
297 .Cases({
"fcntl.h",
"fmtmsg.h",
"fnmatch.h",
"ftw.h",
"glob.h"},
true)
298 .Cases({
"grp.h",
"iconv.h",
"langinfo.h",
"libgen.h",
"monetary.h"},
true)
299 .Cases({
"mqueue.h",
"ndbm.h",
"net/if.h",
"netdb.h",
"netinet/in.h"},
301 .Cases({
"netinet/tcp.h",
"nl_types.h",
"poll.h",
"pthread.h",
"pwd.h"},
303 .Cases({
"regex.h",
"sched.h",
"search.h",
"semaphore.h",
"spawn.h"},
true)
304 .Cases({
"strings.h",
"stropts.h",
"sys/ipc.h",
"sys/mman.h",
"sys/msg.h"},
306 .Cases({
"sys/resource.h",
"sys/select.h",
"sys/sem.h",
"sys/shm.h",
309 .Cases({
"sys/stat.h",
"sys/statvfs.h",
"sys/time.h",
"sys/times.h",
313 {
"sys/uio.h",
"sys/un.h",
"sys/utsname.h",
"sys/wait.h",
"syslog.h"},
315 .Cases({
"tar.h",
"termios.h",
"trace.h",
"ulimit.h"},
true)
316 .Cases({
"unistd.h",
"utime.h",
"utmpx.h",
"wordexp.h"},
true)
328static std::optional<StringRef>
332 for (StringRef
C : Candidates) {
333 if (LHS.equals_insensitive(
C)) {
341 size_t Length = LHS.size();
342 size_t MaxDist = Length < 3 ? Length - 1 : Length / 3;
344 std::optional<std::pair<StringRef, size_t>> SimilarStr;
345 for (StringRef
C : Candidates) {
346 size_t CurDist = LHS.edit_distance(
C,
true);
347 if (CurDist <= MaxDist) {
350 SimilarStr = {
C, CurDist};
351 }
else if (CurDist < SimilarStr->second) {
353 SimilarStr = {
C, CurDist};
359 return SimilarStr->first;
368 if (MacroNameTok.
is(tok::eod))
369 return Diag(MacroNameTok, diag::err_pp_missing_macro_name);
373 return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
379 ? diag::ext_pp_operator_used_as_macro_name
380 : diag::err_pp_operator_used_as_macro_name)
381 << II << MacroNameTok.
getKind();
388 return Diag(MacroNameTok, diag::err_defined_macro_name);
404 }
else if (isDefineUndef ==
MU_Undef)
406 if (D !=
MD_NoWarn && !SourceMgr.isInSystemHeader(MacroNameLoc) &&
407 !SourceMgr.isInPredefinedFile(MacroNameLoc)) {
416 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id);
418 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_attribute_id)
435void Preprocessor::ReadMacroName(
Token &MacroNameTok,
MacroUse isDefineUndef,
440 if (MacroNameTok.
is(tok::code_completion)) {
452 if (MacroNameTok.
isNot(tok::eod)) {
453 MacroNameTok.
setKind(tok::eod);
471 auto ReadNextTok = [
this, ExtraToks, &Tmp](
auto &&LexFn) {
472 std::invoke(LexFn,
this, Tmp);
473 if (ExtraToks && Tmp.
isNot(tok::eod))
474 ExtraToks->push_back(Tmp);
486 while (Tmp.
is(tok::comment))
489 if (Tmp.
is(tok::eod))
497 if ((LangOpts.GNUMode || LangOpts.C99 || LangOpts.CPlusPlus) &&
501 unsigned DiagID = diag::ext_pp_extra_tokens_at_eol;
504 (DirType ==
"import" || DirType ==
"module"))
505 DiagID = diag::warn_pp_extra_tokens_at_module_directive_eol;
507 Diag(Tmp, DiagID) << DirType << Hint;
511void Preprocessor::SuggestTypoedDirective(
const Token &
Tok,
512 StringRef Directive)
const {
517 std::vector<StringRef> Candidates = {
518 "if",
"ifdef",
"ifndef",
"elif",
"else",
"endif"
520 if (LangOpts.C23 || LangOpts.CPlusPlus23)
521 Candidates.insert(Candidates.end(), {
"elifdef",
"elifndef"});
525 assert(
Tok.getLocation().isFileID());
529 StringRef SuggValue = *Sugg;
532 Diag(
Tok, diag::warn_pp_invalid_directive) << 1 << SuggValue << Hint;
544void Preprocessor::SkipExcludedConditionalBlock(
SourceLocation HashTokenLoc,
546 bool FoundNonSkipPortion,
557 assert(!SkippingExcludedConditionalBlock &&
558 "calling SkipExcludedConditionalBlock recursively");
559 llvm::SaveAndRestore SARSkipping(SkippingExcludedConditionalBlock,
true);
562 assert(!CurTokenLexer &&
"Conditional PP block cannot appear in a macro!");
563 assert(CurPPLexer &&
"Conditional PP block must be in a file!");
564 assert(CurLexer &&
"Conditional PP block but no current lexer set!");
566 if (PreambleConditionalStack.reachedEOFWhileSkipping())
567 PreambleConditionalStack.clearSkipInfo();
569 CurPPLexer->pushConditionalLevel(IfTokenLoc,
false,
570 FoundNonSkipPortion, FoundElse);
574 CurPPLexer->LexingRawMode =
true;
576 SourceLocation endLoc;
580 struct SkippingRangeStateTy {
583 const char *BeginPtr =
nullptr;
584 unsigned *SkipRangePtr =
nullptr;
586 SkippingRangeStateTy(Preprocessor &PP) : PP(PP) {}
588 void beginLexPass() {
594 BeginPtr = PP.CurLexer->getBufferLocation();
595 SkipRangePtr = &PP.RecordedSkippedRanges[BeginPtr];
597 PP.CurLexer->seek(PP.CurLexer->getCurrentBufferOffset() + *SkipRangePtr,
602 void endLexPass(
const char *Hashptr) {
605 assert(PP.CurLexer->isDependencyDirectivesLexer());
610 if (!*SkipRangePtr) {
611 *SkipRangePtr = Hashptr - BeginPtr;
613 assert(*SkipRangePtr ==
unsigned(Hashptr - BeginPtr));
615 SkipRangePtr =
nullptr;
617 } SkippingRangeState(*
this);
620 if (CurLexer->isDependencyDirectivesLexer()) {
621 CurLexer->LexDependencyDirectiveTokenWhileSkipping(
Tok);
623 SkippingRangeState.beginLexPass();
627 if (
Tok.
is(tok::code_completion)) {
630 CodeComplete->CodeCompleteInConditionalExclusion();
643 Tok.
is(tok::raw_identifier) &&
646 llvm::SaveAndRestore ModuleDirectiveSkipping(LastExportKeyword);
647 LastExportKeyword.startToken();
654 if (
Tok.
is(tok::raw_identifier)) {
663 llvm::SaveAndRestore RestoreLexingRawMode(CurPPLexer->LexingRawMode,
670 CurPPLexer->ParsingPreprocessorDirective =
true;
673 Diag(StartLoc, diag::err_pp_cond_span_module_decl)
674 << SourceRange(StartLoc, End);
675 CurPPLexer->ParsingPreprocessorDirective =
false;
678 CurLexer->resetExtendedTokenMode();
685 if (
Tok.
is(tok::eof)) {
689 if (PreambleConditionalStack.isRecording())
690 PreambleConditionalStack.SkipInfo.emplace(HashTokenLoc, IfTokenLoc,
703 if (
Tok.
is(tok::eof))
709 CurPPLexer->ParsingPreprocessorDirective =
true;
710 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
712 assert(
Tok.
is(tok::hash));
713 const char *Hashptr = CurLexer->getBufferLocation() -
Tok.
getLength();
714 assert(CurLexer->getSourceLocation(Hashptr) ==
Tok.
getLocation());
721 if (
Tok.
isNot(tok::raw_identifier)) {
722 CurPPLexer->ParsingPreprocessorDirective =
false;
724 if (CurLexer) CurLexer->resetExtendedTokenMode();
735 char FirstChar = RI[0];
736 if (FirstChar >=
'a' && FirstChar <=
'z' &&
737 FirstChar !=
'i' && FirstChar !=
'e') {
738 CurPPLexer->ParsingPreprocessorDirective =
false;
740 if (CurLexer) CurLexer->resetExtendedTokenMode();
747 char DirectiveBuf[20];
753 size_t IdLen = DirectiveStr.size();
755 CurPPLexer->ParsingPreprocessorDirective =
false;
757 if (CurLexer) CurLexer->resetExtendedTokenMode();
760 memcpy(DirectiveBuf, &DirectiveStr[0], IdLen);
761 Directive = StringRef(DirectiveBuf, IdLen);
781 PPConditionalInfo CondInfo;
783 bool InCond = CurPPLexer->popConditionalLevel(CondInfo);
785 assert(!InCond &&
"Can't be skipping if not in a conditional!");
789 SkippingRangeState.endLexPass(Hashptr);
792 CurPPLexer->LexingRawMode =
false;
794 CurPPLexer->LexingRawMode =
true;
801 }
else if (Sub ==
"lse") {
805 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
808 SkippingRangeState.endLexPass(Hashptr);
812 Diag(
Tok, diag::pp_err_else_after_else);
823 CurPPLexer->LexingRawMode =
false;
825 CurPPLexer->LexingRawMode =
true;
832 }
else if (Sub ==
"lif") {
833 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
836 SkippingRangeState.endLexPass(Hashptr);
853 assert(CurPPLexer->LexingRawMode &&
"We have to be skipping here!");
854 CurPPLexer->LexingRawMode =
false;
855 IdentifierInfo *IfNDefMacro =
nullptr;
856 DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
860 const bool CondValue = DER.Conditional;
861 CurPPLexer->LexingRawMode =
true;
874 }
else if (Sub ==
"lifdef" ||
876 bool IsElifDef =
Sub ==
"lifdef";
877 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
878 Token DirectiveToken =
Tok;
881 SkippingRangeState.endLexPass(Hashptr);
885 unsigned DiagID = LangOpts.CPlusPlus ? diag_compat::cxx23_pp_directive
886 : diag_compat::c23_pp_directive;
891 Diag(
Tok, diag::pp_err_elif_after_else)
905 assert(CurPPLexer->LexingRawMode &&
"We have to be skipping here!");
906 CurPPLexer->LexingRawMode =
false;
908 ReadMacroName(MacroNameTok);
909 CurPPLexer->LexingRawMode =
true;
913 if (MacroNameTok.
is(tok::eod)) {
925 MacroInfo *MI = MD.getMacroInfo();
929 Callbacks->Elifdef(DirectiveToken.
getLocation(), MacroNameTok,
932 Callbacks->Elifndef(DirectiveToken.
getLocation(), MacroNameTok,
937 if (
static_cast<bool>(MI) == IsElifDef) {
949 CurPPLexer->ParsingPreprocessorDirective =
false;
951 if (CurLexer) CurLexer->resetExtendedTokenMode();
957 CurPPLexer->LexingRawMode =
false;
962 Callbacks->SourceRangeSkipped(
963 SourceRange(HashTokenLoc, endLoc.
isValid()
965 : CurPPLexer->getSourceLocation()),
971 if (!SourceMgr.isInMainFile(Loc)) {
974 FileID IDOfIncl = SourceMgr.getFileID(SourceMgr.getExpansionLoc(Loc));
975 if (
auto EntryOfIncl = SourceMgr.getFileEntryRefForID(IDOfIncl)) {
977 return HeaderInfo.getModuleMap()
978 .findModuleForHeader(*EntryOfIncl, AllowTextual)
987 : HeaderInfo.lookupModule(
getLangOpts().CurrentModule, Loc);
994 IncLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
1001 while (!Loc.
isInvalid() && !SM.isInMainFile(Loc)) {
1002 auto ID = SM.getFileID(SM.getExpansionLoc(Loc));
1003 auto FE = SM.getFileEntryRefForID(ID);
1009 HeaderInfo.hasModuleMap(FE->getName(),
nullptr,
1010 SourceMgr.isInSystemHeader(Loc));
1012 bool InPrivateHeader =
false;
1013 for (
auto Header : HeaderInfo.findAllModulesForHeader(*FE)) {
1014 if (!Header.isAccessibleFrom(IncM)) {
1019 InPrivateHeader =
true;
1036 return std::nullopt;
1046 if (InPrivateHeader)
1047 return std::nullopt;
1055 Loc = SM.getIncludeLoc(ID);
1058 return std::nullopt;
1067 bool *IsFrameworkFound,
bool SkipCache,
bool OpenFile,
bool CacheFailures) {
1072 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
1077 bool BuildSystemModule =
false;
1078 if (!FromDir && !FromFile) {
1095 if (FID == SourceMgr.getMainFileID() && MainFileDir) {
1097 HeaderInfo.getModuleMap().shouldImportRelativeToBuiltinIncludeDir(
1099 ? HeaderInfo.getModuleMap().getBuiltinDir()
1101 Includers.push_back(std::make_pair(std::nullopt, *IncludeDir));
1103 }
else if ((FileEnt = SourceMgr.getFileEntryRefForID(
1104 SourceMgr.getMainFileID()))) {
1105 auto CWD = FileMgr.getOptionalDirectoryRef(
".");
1106 Includers.push_back(std::make_pair(*FileEnt, *CWD));
1109 Includers.push_back(std::make_pair(*FileEnt, FileEnt->
getDir()));
1115 if (LangOpts.MSVCCompat && !isAngled) {
1116 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1117 if (IsFileLexer(ISEntry))
1119 Includers.push_back(std::make_pair(*FileEnt, FileEnt->
getDir()));
1124 CurDir = CurDirLookup;
1132 Filename, FilenameLoc, isAngled, TmpFromDir, &TmpCurDir,
1133 Includers, SearchPath, RelativePath, RequestingModule,
1134 SuggestedModule,
nullptr,
1135 nullptr, SkipCache)) {
1137 TmpFromDir = TmpCurDir;
1139 if (&FE->getFileEntry() == FromFile) {
1141 FromDir = TmpFromDir;
1150 Filename, FilenameLoc, isAngled, FromDir, &CurDir, Includers, SearchPath,
1151 RelativePath, RequestingModule, SuggestedModule, IsMapped,
1152 IsFrameworkFound, SkipCache, BuildSystemModule, OpenFile, CacheFailures);
1160 if (IsFileLexer()) {
1163 Filename, *CurFileEnt, SearchPath, RelativePath, RequestingModule,
1170 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1171 if (IsFileLexer(ISEntry)) {
1172 if ((CurFileEnt = ISEntry.ThePPLexer->
getFileEntry())) {
1174 Filename, *CurFileEnt, SearchPath, RelativePath,
1175 RequestingModule, SuggestedModule)) {
1183 return std::nullopt;
1190 if (llvm::sys::path::is_absolute(Filename)) {
1197 StringRef StartingFrom, StringRef
FileName,
1198 bool RemoveInitialFileComponentFromLookupPath) {
1199 llvm::sys::path::native(StartingFrom, LookupPath);
1200 if (RemoveInitialFileComponentFromLookupPath)
1201 llvm::sys::path::remove_filename(LookupPath);
1202 if (!LookupPath.empty() &&
1203 !llvm::sys::path::is_separator(LookupPath.back())) {
1204 LookupPath.push_back(llvm::sys::path::get_separator().front());
1214 if (LookupFromFile) {
1218 llvm::sys::path::append(TmpDir, Filename);
1219 if (!TmpDir.empty()) {
1221 TmpDir, OpenFile,
true,
false);
1223 return ShouldBeEntry;
1230 if (MaybeWorkingDirEntry) {
1232 StringRef WorkingDir = WorkingDirEntry.
getName();
1233 if (!WorkingDir.empty()) {
1234 SeparateComponents(LookupPath, WorkingDir, Filename,
false);
1236 LookupPath, OpenFile,
true,
false);
1238 return ShouldBeEntry;
1243 for (
const auto &Entry : PPOpts.EmbedEntries) {
1245 SeparateComponents(LookupPath, Entry, Filename,
false);
1247 LookupPath, OpenFile,
true,
false);
1249 return ShouldBeEntry;
1251 return std::nullopt;
1261 : PP(pp), save(pp->DisableMacroExpansion) {
1262 if (pp->MacroExpansionInDirectivesOverride)
1263 pp->DisableMacroExpansion =
false;
1267 PP->DisableMacroExpansion = save;
1285 return HandleDefineDirective(
Result,
1288 if (SkippingUntilPCHThroughHeader &&
1290 return HandleIncludeDirective(HashLoc,
Result);
1292 if (SkippingUntilPragmaHdrStop && II->
getPPKeywordID() == tok::pp_pragma) {
1294 auto *II =
Result.getIdentifierInfo();
1295 if (II && II->
getName() ==
"hdrstop")
1312 CurPPLexer->ParsingPreprocessorDirective =
true;
1313 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
1315 bool ImmediatelyAfterTopLevelIfndef =
1316 CurPPLexer->MIOpt.getImmediatelyAfterTopLevelIfndef();
1317 CurPPLexer->MIOpt.resetImmediatelyAfterTopLevelIfndef();
1324 bool ReadAnyTokensBeforeDirective =CurPPLexer->MIOpt.getHasReadAnyTokensVal();
1332 if (Introducer.
isOneOf(tok::hash, tok::at))
1346 case tok::pp_include:
1347 case tok::pp_import:
1348 case tok::pp_include_next:
1349 case tok::pp___include_macros:
1350 case tok::pp_pragma:
1352 case tok::pp_module:
1353 case tok::pp___preprocessed_module:
1354 case tok::pp___preprocessed_import:
1356 << Introducer.
is(tok::hash) << II->
getName();
1357 Diag(*ArgMacro, diag::note_macro_expansion_here)
1358 << ArgMacro->getIdentifierInfo();
1372 if (SkippingUntilPCHThroughHeader || SkippingUntilPragmaHdrStop)
1376 switch (
Result.getKind()) {
1381 CurPPLexer->MIOpt.SetReadToken(ReadAnyTokensBeforeDirective);
1383 case tok::code_completion:
1386 CodeComplete->CodeCompleteDirective(
1387 CurPPLexer->getConditionalStackDepth() > 0);
1389 case tok::numeric_constant:
1396 return HandleDigitDirective(
Result);
1406 return HandleIfDirective(
Result, Introducer,
1407 ReadAnyTokensBeforeDirective);
1409 return HandleIfdefDirective(
Result, Introducer,
false,
1411 case tok::pp_ifndef:
1412 return HandleIfdefDirective(
Result, Introducer,
true,
1413 ReadAnyTokensBeforeDirective);
1415 case tok::pp_elifdef:
1416 case tok::pp_elifndef:
1417 return HandleElifFamilyDirective(
Result, Introducer,
1421 return HandleElseDirective(
Result, Introducer);
1423 return HandleEndifDirective(
Result);
1426 case tok::pp_include:
1429 case tok::pp___include_macros:
1434 case tok::pp_define:
1435 return HandleDefineDirective(
Result, ImmediatelyAfterTopLevelIfndef);
1437 return HandleUndefDirective();
1441 return HandleLineDirective();
1445 return HandleUserDiagnosticDirective(
Result,
false);
1448 case tok::pp_pragma:
1450 case tok::pp_module:
1451 case tok::pp___preprocessed_module:
1455 case tok::pp___preprocessed_import:
1457 case tok::pp_import:
1458 switch (Introducer.
getKind()) {
1462 return HandleObjCImportDirective(Introducer,
Result);
1463 case tok::kw_import:
1466 llvm_unreachable(
"not a valid import directive");
1470 case tok::pp_include_next:
1473 case tok::pp_warning:
1474 if (LangOpts.CPlusPlus)
1476 ? diag::warn_cxx23_compat_warning_directive
1477 : diag::ext_pp_warning_directive)
1480 Diag(
Result, LangOpts.C23 ? diag::warn_c23_compat_warning_directive
1481 : diag::ext_pp_warning_directive)
1484 return HandleUserDiagnosticDirective(
Result,
true);
1486 return HandleIdentSCCSDirective(
Result);
1488 return HandleIdentSCCSDirective(
Result);
1491 case tok::pp_assert:
1494 case tok::pp_unassert:
1498 case tok::pp___public_macro:
1500 return HandleMacroPublicDirective(
Result);
1503 case tok::pp___private_macro:
1505 return HandleMacroPrivateDirective();
1516 auto Toks = std::make_unique<Token[]>(2);
1518 Toks[0] = Introducer;
1523 if (
Result.is(tok::hashhash))
1524 Toks[1].setKind(tok::unknown);
1529 EnterTokenStream(std::move(Toks), 2,
false,
false);
1535 Diag(
Result, diag::err_pp_invalid_directive) << 0;
1547 bool IsGNULineDirective=
false) {
1548 if (DigitTok.
isNot(tok::numeric_constant)) {
1549 PP.
Diag(DigitTok, DiagID);
1551 if (DigitTok.
isNot(tok::eod))
1557 IntegerBuffer.resize(DigitTok.
getLength());
1558 const char *DigitTokBegin = &IntegerBuffer[0];
1568 for (
unsigned i = 0; i != ActualLength; ++i) {
1571 if (DigitTokBegin[i] ==
'\'')
1574 if (!
isDigit(DigitTokBegin[i])) {
1576 diag::err_pp_line_digit_sequence) << IsGNULineDirective;
1581 unsigned NextVal = Val*10+(DigitTokBegin[i]-
'0');
1582 if (NextVal < Val) {
1583 PP.
Diag(DigitTok, DiagID);
1590 if (DigitTokBegin[0] ==
'0' && Val)
1592 << IsGNULineDirective;
1604void Preprocessor::HandleLineDirective() {
1612 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*
this))
1616 Diag(DigitTok, diag::ext_pp_line_zero);
1620 unsigned LineLimit = 32768U;
1621 if (LangOpts.C99 || LangOpts.CPlusPlus11)
1622 LineLimit = 2147483648U;
1623 if (LineNo >= LineLimit)
1624 Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
1625 else if (LangOpts.CPlusPlus11 && LineNo >= 32768U)
1626 Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
1628 int FilenameID = -1;
1634 if (StrTok.
is(tok::eod))
1636 else if (StrTok.
isNot(tok::header_name)) {
1637 Diag(StrTok, diag::err_pp_line_invalid_filename);
1641 SmallString<128> FilenameBuffer;
1642 StringRef Filename =
getSpelling(StrTok, FilenameBuffer);
1644 FilenameID = SourceMgr.getLineTableFilenameID(Filename);
1657 SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1659 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID,
false,
1663 Callbacks->FileChanged(CurPPLexer->getSourceLocation(),
1675 if (FlagTok.
is(tok::eod))
return false;
1676 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1683 if (FlagTok.
is(tok::eod))
return false;
1684 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1686 }
else if (FlagVal == 2) {
1703 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);
1709 if (FlagTok.
is(tok::eod))
return false;
1710 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1716 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1724 if (FlagTok.
is(tok::eod))
return false;
1725 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1730 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1738 if (FlagTok.
is(tok::eod))
return false;
1741 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1753void Preprocessor::HandleDigitDirective(
Token &DigitTok) {
1757 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
1764 bool IsFileEntry =
false, IsFileExit =
false;
1765 int FilenameID = -1;
1770 if (StrTok.
is(tok::eod)) {
1771 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1773 FileKind = SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1774 }
else if (StrTok.
isNot(tok::header_name)) {
1775 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1779 SmallString<128> FilenameBuffer;
1780 StringRef Filename =
getSpelling(StrTok, FilenameBuffer);
1785 if (!SourceMgr.isInPredefinedFile(DigitTok.
getLocation()))
1786 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1790 if (!(IsFileExit && Filename.empty()))
1791 FilenameID = SourceMgr.getLineTableFilenameID(Filename);
1795 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID, IsFileEntry,
1796 IsFileExit, FileKind);
1805 else if (IsFileExit)
1808 Callbacks->FileChanged(CurPPLexer->getSourceLocation(), Reason, FileKind);
1814void Preprocessor::HandleUserDiagnosticDirective(
Token &
Tok,
1822 CurLexer->ReadToEndOfLine(&Message);
1826 StringRef Msg =
Message.str().ltrim(
' ');
1829 Diag(
Tok, diag::pp_hash_warning) << Msg;
1831 Diag(
Tok, diag::err_pp_hash_error) << Msg;
1836void Preprocessor::HandleIdentSCCSDirective(
Token &
Tok) {
1838 Diag(
Tok, diag::ext_pp_ident_directive);
1845 if (StrTok.
isNot(tok::string_literal) &&
1846 StrTok.
isNot(tok::wide_string_literal)) {
1847 Diag(StrTok, diag::err_pp_malformed_ident);
1848 if (StrTok.
isNot(tok::eod))
1854 Diag(StrTok, diag::err_invalid_string_udl);
1871void Preprocessor::HandleMacroPublicDirective(
Token &
Tok) {
1873 ReadMacroName(MacroNameTok,
MU_Undef);
1876 if (MacroNameTok.
is(tok::eod))
1888 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1898void Preprocessor::HandleMacroPrivateDirective() {
1900 ReadMacroName(MacroNameTok,
MU_Undef);
1903 if (MacroNameTok.
is(tok::eod))
1915 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1935 StringRef &Buffer) {
1937 assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1949 if (Buffer[0] ==
'<') {
1950 if (Buffer.back() !=
'>') {
1951 Diag(Loc, diag::err_pp_expects_filename);
1952 Buffer = StringRef();
1956 }
else if (Buffer[0] ==
'"') {
1957 if (Buffer.back() !=
'"') {
1958 Diag(Loc, diag::err_pp_expects_filename);
1959 Buffer = StringRef();
1964 Diag(Loc, diag::err_pp_expects_filename);
1965 Buffer = StringRef();
1970 if (Buffer.size() <= 2) {
1971 Diag(Loc, diag::err_pp_empty_filename);
1972 Buffer = StringRef();
1977 Buffer = Buffer.substr(1, Buffer.size()-2);
1982 StringRef &Buffer) {
1984 assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1985 if (Buffer.size() < 2 || Buffer.front() !=
'"' || Buffer.back() !=
'"') {
1986 Diag(Loc, diag::err_pp_line_invalid_filename);
1987 Buffer = StringRef();
1990 Buffer = Buffer.substr(1, Buffer.size() - 2);
1996 void *AnnotationVal) {
1999 auto Tok = std::make_unique<Token[]>(1);
2000 Tok[0].startToken();
2001 Tok[0].setKind(Kind);
2002 Tok[0].setLocation(Range.getBegin());
2003 Tok[0].setAnnotationEndLoc(Range.getEnd());
2004 Tok[0].setAnnotationValue(AnnotationVal);
2005 EnterTokenStream(std::move(
Tok), 1,
true,
false);
2015 for (
size_t I = 0, N = Path.size(); I != N; ++I) {
2018 PathString += Path[I].getIdentifierInfo()->getName();
2021 int IncludeKind = 0;
2023 case tok::pp_include:
2027 case tok::pp_import:
2031 case tok::pp_include_next:
2035 case tok::pp___include_macros:
2040 llvm_unreachable(
"unknown include directive kind");
2043 PP.
Diag(HashLoc, diag::remark_pp_include_directive_modular_translation)
2044 << IncludeKind << PathString;
2051 StringRef RealPathName,
2052 llvm::sys::path::Style Separator) {
2053 auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName);
2054 auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName);
2056 bool SuggestReplacement =
false;
2058 auto IsSep = [Separator](StringRef Component) {
2059 return Component.size() == 1 &&
2060 llvm::sys::path::is_separator(Component[0], Separator);
2065 for (
auto &Component : llvm::reverse(Components)) {
2066 if (
"." == Component) {
2067 }
else if (
".." == Component) {
2071 }
else if (RealPathComponentIter != RealPathComponentEnd) {
2072 if (!IsSep(Component) && !IsSep(*RealPathComponentIter) &&
2073 Component != *RealPathComponentIter) {
2077 SuggestReplacement =
2078 RealPathComponentIter->equals_insensitive(Component);
2079 if (!SuggestReplacement)
2081 Component = *RealPathComponentIter;
2083 ++RealPathComponentIter;
2086 return SuggestReplacement;
2095 Module *ShadowingModule =
nullptr;
2101 Diags.Report(MissingHeader.
FileNameLoc, diag::err_module_header_missing)
2103 }
else if (ShadowingModule) {
2106 diag::note_previous_definition);
2117std::pair<ConstSearchDirIterator, const FileEntry *>
2118Preprocessor::getIncludeNextStart(
const Token &IncludeNextTok)
const {
2123 const FileEntry *LookupFromFile =
nullptr;
2131 Diag(IncludeNextTok, diag::pp_include_next_in_primary);
2132 }
else if (CurLexerSubmodule) {
2135 assert(CurPPLexer &&
"#include_next directive in macro?");
2136 if (
auto FE = CurPPLexer->getFileEntry())
2137 LookupFromFile = *FE;
2139 }
else if (!Lookup) {
2144 Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
2150 return {Lookup, LookupFromFile};
2166 if (FilenameTok.
isNot(tok::header_name)) {
2167 if (FilenameTok.
is(tok::identifier) &&
2168 (PPOpts.SingleFileParseMode || PPOpts.SingleModuleParseMode)) {
2178 if (FilenameTok.
isNot(tok::eod))
2187 SourceLocation EndLoc =
2190 auto Action = HandleHeaderIncludeOrImport(HashLoc, IncludeTok, FilenameTok,
2191 EndLoc, LookupFrom, LookupFromFile);
2192 switch (Action.Kind) {
2193 case ImportAction::None:
2194 case ImportAction::SkippedModuleImport:
2196 case ImportAction::ModuleBegin:
2198 tok::annot_module_begin, Action.ModuleForHeader);
2200 case ImportAction::HeaderUnitImport:
2202 Action.ModuleForHeader);
2204 case ImportAction::ModuleImport:
2206 tok::annot_module_include, Action.ModuleForHeader);
2208 case ImportAction::Failure:
2209 assert(TheModuleLoader.HadFatalFailure &&
2210 "This should be an early exit only to a fatal error");
2211 TheModuleLoader.HadFatalFailure =
true;
2213 CurLexer->cutOffLexing();
2221 const Token &FilenameTok,
bool &IsFrameworkFound,
bool IsImportDecl,
2223 const FileEntry *LookupFromFile, StringRef &LookupFilename,
2226 auto DiagnoseHeaderInclusion = [&](FileEntryRef FE) {
2227 if (LangOpts.AsmPreprocessor)
2231 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
2232 bool RequestingModuleIsModuleInterface =
2233 !SourceMgr.isInMainFile(FilenameLoc);
2235 HeaderInfo.getModuleMap().diagnoseHeaderInclusion(
2236 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
2241 FilenameLoc, LookupFilename, isAngled, LookupFrom, LookupFromFile, CurDir,
2242 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2243 &SuggestedModule, &IsMapped, &IsFrameworkFound);
2245 DiagnoseHeaderInclusion(*
File);
2250 if (Callbacks && Callbacks->FileNotFound(Filename))
2251 return std::nullopt;
2253 if (SuppressIncludeNotFoundError)
2254 return std::nullopt;
2261 FilenameLoc, LookupFilename,
false, LookupFrom, LookupFromFile, CurDir,
2262 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2263 &SuggestedModule, &IsMapped,
2266 DiagnoseHeaderInclusion(*
File);
2267 Diag(FilenameTok, diag::err_pp_file_not_found_angled_include_not_fatal)
2268 << Filename << IsImportDecl
2270 "\"" + Filename.str() +
"\"");
2277 StringRef OriginalFilename = Filename;
2278 if (LangOpts.SpellChecking) {
2281 auto CorrectTypoFilename = [](llvm::StringRef Filename) {
2284 Filename = Filename.drop_back();
2288 StringRef TypoCorrectionName = CorrectTypoFilename(Filename);
2289 StringRef TypoCorrectionLookupName = CorrectTypoFilename(LookupFilename);
2292 FilenameLoc, TypoCorrectionLookupName, isAngled, LookupFrom,
2293 LookupFromFile, CurDir, Callbacks ? &SearchPath :
nullptr,
2294 Callbacks ? &RelativePath :
nullptr, &SuggestedModule, &IsMapped,
2297 DiagnoseHeaderInclusion(*
File);
2300 FilenameRange,
"<" + TypoCorrectionName.str() +
">")
2301 : FixItHint::CreateReplacement(
2302 FilenameRange,
"\"" + TypoCorrectionName.str() +
"\"");
2303 Diag(FilenameTok, diag::err_pp_file_not_found_typo_not_fatal)
2304 << OriginalFilename << TypoCorrectionName << Hint;
2307 Filename = TypoCorrectionName;
2308 LookupFilename = TypoCorrectionLookupName;
2314 assert(!
File &&
"expected missing file");
2315 Diag(FilenameTok, diag::err_pp_file_not_found)
2316 << OriginalFilename << FilenameRange;
2317 if (IsFrameworkFound) {
2318 size_t SlashPos = OriginalFilename.find(
'/');
2319 assert(SlashPos != StringRef::npos &&
2320 "Include with framework name should have '/' in the filename");
2321 StringRef FrameworkName = OriginalFilename.substr(0, SlashPos);
2322 FrameworkCacheEntry &CacheEntry =
2323 HeaderInfo.LookupFrameworkCache(FrameworkName);
2324 assert(CacheEntry.
Directory &&
"Found framework should be in cache");
2325 Diag(FilenameTok, diag::note_pp_framework_without_header)
2326 << OriginalFilename.substr(SlashPos + 1) << FrameworkName
2330 return std::nullopt;
2345Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
2349 SmallString<128> FilenameBuffer;
2350 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
2351 SourceLocation CharEnd = FilenameTok.
getEndLoc();
2353 CharSourceRange FilenameRange
2355 StringRef OriginalFilename = Filename;
2361 if (Filename.empty())
2362 return {ImportAction::None};
2363 if (Filename.ends_with(
' ') || Filename.ends_with(
'.')) {
2364 unsigned Selection = Filename.ends_with(
'.') ? 1 : 0;
2365 Diag(FilenameTok, diag::pp_nonportable_path_trailing)
2366 << Filename << Selection;
2369 bool IsImportDecl = HashLoc.
isInvalid();
2370 SourceLocation StartLoc = IsImportDecl ? IncludeTok.
getLocation() : HashLoc;
2373 if (PragmaARCCFCodeAuditedInfo.getLoc().isValid()) {
2374 Diag(StartLoc, diag::err_pp_include_in_arc_cf_code_audited) << IsImportDecl;
2375 Diag(PragmaARCCFCodeAuditedInfo.getLoc(), diag::note_pragma_entered_here);
2378 PragmaARCCFCodeAuditedInfo = IdentifierLoc();
2382 if (PragmaAssumeNonNullLoc.isValid()) {
2383 Diag(StartLoc, diag::err_pp_include_in_assume_nonnull) << IsImportDecl;
2384 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
2387 PragmaAssumeNonNullLoc = SourceLocation();
2390 if (HeaderInfo.HasIncludeAliasMap()) {
2394 StringRef NewName = HeaderInfo.MapHeaderToIncludeAlias(OriginalFilename);
2395 if (!NewName.empty())
2400 bool IsMapped =
false;
2401 bool IsFrameworkFound =
false;
2403 SmallString<1024> SearchPath;
2404 SmallString<1024> RelativePath;
2407 ModuleMap::KnownHeader SuggestedModule;
2408 SourceLocation FilenameLoc = FilenameTok.
getLocation();
2409 StringRef LookupFilename = Filename;
2413 SmallString<128> NormalizedPath;
2414 llvm::sys::path::Style BackslashStyle = llvm::sys::path::Style::native;
2415 if (is_style_posix(BackslashStyle) && LangOpts.MicrosoftExt) {
2416 NormalizedPath = Filename.str();
2417 llvm::sys::path::native(NormalizedPath);
2418 LookupFilename = NormalizedPath;
2419 BackslashStyle = llvm::sys::path::Style::windows;
2423 &CurDir, Filename, FilenameLoc, FilenameRange, FilenameTok,
2424 IsFrameworkFound, IsImportDecl, IsMapped, LookupFrom, LookupFromFile,
2425 LookupFilename, RelativePath, SearchPath, SuggestedModule, isAngled);
2429 SkippingUntilPCHThroughHeader =
false;
2430 return {ImportAction::None};
2448 enum { Enter,
Import,
Skip, IncludeLimitReached } Action = Enter;
2449 bool DependencyScanModuleImport =
false;
2451 if (PPOpts.SingleFileParseMode)
2452 Action = IncludeLimitReached;
2457 if (Action == Enter && HasReachedMaxIncludeDepth &&
File &&
2459 Action = IncludeLimitReached;
2466 bool MaybeTranslateInclude = Action == Enter &&
File && ModuleToImport &&
2470 bool UsableHeaderUnit =
false;
2471 if (
getLangOpts().CPlusPlusModules && ModuleToImport &&
2473 if (TrackGMFState.inGMF() || IsImportDecl)
2474 UsableHeaderUnit =
true;
2475 else if (!IsImportDecl) {
2477 ModuleToImport =
nullptr;
2481 bool UsableClangHeaderModule =
2488 if (MaybeTranslateInclude && (UsableHeaderUnit || UsableClangHeaderModule)) {
2496 diag::note_implicit_top_level_module_import_here)
2498 return {ImportAction::None};
2504 SmallVector<IdentifierLoc, 2> Path;
2505 for (
Module *Mod = ModuleToImport; Mod; Mod = Mod->Parent)
2508 std::reverse(Path.begin(), Path.end());
2514 if (PPOpts.DependencyScanningModuleMapImports &&
2519 DependencyScanModuleImport =
true;
2525 ModuleLoadResult Imported = TheModuleLoader.loadModule(
2528 assert((Imported ==
nullptr || Imported == ModuleToImport) &&
2529 "the imported module is different than the suggested one");
2535 static_cast<Module *
>(Imported)->getTopLevelModule());
2540 ModuleToImport =
nullptr;
2541 UsableClangHeaderModule =
false;
2549 Token &
Result = IncludeTok;
2550 assert(CurLexer &&
"#include but no current lexer set!");
2552 CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
2553 CurLexer->cutOffLexing();
2555 return {ImportAction::None};
2564 SourceMgr.getFileCharacteristic(FilenameTok.
getLocation());
2566 FileCharacter = std::max(HeaderInfo.getFileDirFlavor(*
File), FileCharacter);
2577 bool IsFirstIncludeOfFile =
false;
2581 if (Action == Enter &&
File &&
2582 !HeaderInfo.ShouldEnterIncludeFile(*
this, *
File, EnterOnce,
2584 IsFirstIncludeOfFile)) {
2595 if (UsableHeaderUnit && !
getLangOpts().CompilingPCH)
2596 Action = TrackGMFState.inGMF() ?
Import :
Skip;
2598 Action = (UsableClangHeaderModule && !
getLangOpts().CompilingPCH) ? Import
2607 if (Action == Enter &&
File && PreambleConditionalStack.isRecording() &&
2608 SourceMgr.isMainFile(
File->getFileEntry())) {
2610 diag::err_pp_including_mainfile_in_preamble);
2611 return {ImportAction::None};
2614 if (Callbacks && !IsImportDecl) {
2617 Callbacks->InclusionDirective(
2618 HashLoc, IncludeTok, LookupFilename, isAngled, FilenameRange,
File,
2619 SearchPath, RelativePath, SuggestedModule.
getModule(),
2620 Action == Import || DependencyScanModuleImport, FileCharacter);
2622 Callbacks->FileSkipped(*
File, FilenameTok, FileCharacter);
2626 return {ImportAction::None};
2630 if (IsImportDecl && !ModuleToImport) {
2631 Diag(FilenameTok, diag::err_header_import_not_header_unit)
2632 << OriginalFilename <<
File->getName();
2633 return {ImportAction::None};
2638 const bool CheckIncludePathPortability =
2639 !IsMapped && !
File->getFileEntry().tryGetRealPathName().empty();
2641 if (CheckIncludePathPortability) {
2642 StringRef Name = LookupFilename;
2643 StringRef NameWithoriginalSlashes = Filename;
2647 bool NameWasUNC = Name.consume_front(
"\\\\?\\");
2648 NameWithoriginalSlashes.consume_front(
"\\\\?\\");
2650 StringRef RealPathName =
File->getFileEntry().tryGetRealPathName();
2651 SmallVector<StringRef, 16> Components(llvm::sys::path::begin(Name),
2652 llvm::sys::path::end(Name));
2664 SmallString<128> FixedDriveRealPath;
2665 if (llvm::sys::path::is_absolute(Name) &&
2666 llvm::sys::path::is_absolute(RealPathName) &&
2669 assert(Components.size() >= 3 &&
"should have drive, backslash, name");
2670 assert(Components[0].size() == 2 &&
"should start with drive");
2671 assert(Components[0][1] ==
':' &&
"should have colon");
2672 FixedDriveRealPath = (Name.substr(0, 1) + RealPathName.substr(1)).str();
2673 RealPathName = FixedDriveRealPath;
2678 SmallString<128> Path;
2679 Path.reserve(Name.size()+2);
2680 Path.push_back(isAngled ?
'<' :
'"');
2682 const auto IsSep = [BackslashStyle](
char c) {
2683 return llvm::sys::path::is_separator(c, BackslashStyle);
2686 for (
auto Component : Components) {
2698 if (!(Component.size() == 1 && IsSep(Component[0])))
2699 Path.append(Component);
2700 else if (Path.size() != 1)
2704 if (Path.size() > NameWithoriginalSlashes.size()) {
2705 Path.push_back(isAngled ?
'>' :
'"');
2708 assert(IsSep(NameWithoriginalSlashes[Path.size()-1]));
2710 Path.push_back(NameWithoriginalSlashes[Path.size()-1]);
2711 while (Path.size() <= NameWithoriginalSlashes.size() &&
2712 IsSep(NameWithoriginalSlashes[Path.size()-1]));
2718 Path = (Path.substr(0, 1) +
"\\\\?\\" + Path.substr(1)).str();
2725 ? diag::pp_nonportable_path
2726 : diag::pp_nonportable_system_path;
2727 Diag(FilenameTok, DiagId) << Path <<
2731 bool SuppressBackslashDiag =
2733 Diags->isIgnored(diag::pp_nonportable_path_separator, FilenameLoc) ||
2736 SourceMgr.isWrittenInBuiltinFile(FilenameLoc) ||
2737 SourceMgr.isWrittenInModuleIncludes(FilenameLoc);
2738 if (!SuppressBackslashDiag && OriginalFilename.contains(
'\\')) {
2739 std::string SuggestedPath = OriginalFilename.str();
2740 llvm::replace(SuggestedPath,
'\\',
'/');
2741 Diag(FilenameTok, diag::pp_nonportable_path_separator)
2750 return {ImportAction::SkippedModuleImport, ModuleToImport};
2751 return {ImportAction::None};
2753 case IncludeLimitReached:
2756 return {ImportAction::None};
2760 assert(ModuleToImport &&
"no module to import");
2765 tok::pp___include_macros)
2766 return {ImportAction::None};
2768 return {ImportAction::ModuleImport, ModuleToImport};
2776 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
2777 Diag(FilenameTok, diag::err_pp_include_too_deep);
2778 HasReachedMaxIncludeDepth =
true;
2779 return {ImportAction::None};
2783 Diag(FilenameTok, diag::warn_pp_include_angled_in_module_purview)
2787 SourceLocation IncludePos = FilenameTok.
getLocation();
2791 IncludePos = SourceMgr.getExpansionRange(IncludePos).getEnd();
2792 FileID FID = SourceMgr.createFileID(*
File, IncludePos, FileCharacter);
2794 TheModuleLoader.HadFatalFailure =
true;
2795 return ImportAction::Failure;
2800 IsFirstIncludeOfFile))
2801 return {ImportAction::None};
2805 if (ModuleToImport && !ModuleToImport->
isHeaderUnit()) {
2810 diag::err_module_build_shadowed_submodule)
2813 diag::note_previous_definition);
2814 return {ImportAction::None};
2826 return {ImportAction::None};
2828 assert(!CurLexerSubmodule &&
"should not have marked this as a module yet");
2829 CurLexerSubmodule = ModuleToImport;
2839 return {ImportAction::ModuleBegin, ModuleToImport};
2842 assert(!IsImportDecl &&
"failed to diagnose missing module for import decl");
2843 return {ImportAction::None};
2848void Preprocessor::HandleIncludeNextDirective(
SourceLocation HashLoc,
2849 Token &IncludeNextTok) {
2850 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
2853 const FileEntry *LookupFromFile;
2854 std::tie(Lookup, LookupFromFile) = getIncludeNextStart(IncludeNextTok);
2856 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
2861void Preprocessor::HandleMicrosoftImportDirective(
Token &
Tok) {
2867 Diag(
Tok, diag::err_pp_import_directive_ms );
2878 if (!LangOpts.ObjC) {
2879 if (LangOpts.MSVCCompat)
2880 return HandleMicrosoftImportDirective(ImportTok);
2881 Diag(ImportTok, diag::ext_pp_import_directive);
2883 return HandleIncludeDirective(HashLoc, ImportTok);
2890void Preprocessor::HandleIncludeMacrosDirective(
SourceLocation HashLoc,
2891 Token &IncludeMacrosTok) {
2895 SourceLocation Loc = IncludeMacrosTok.
getLocation();
2896 FileID FID = SourceMgr.getFileID(Loc);
2899 diag::pp_include_macros_out_of_predefines);
2906 HandleIncludeDirective(HashLoc, IncludeMacrosTok);
2911 assert(TmpTok.
isNot(tok::eof) &&
"Didn't find end of -imacros!");
2912 }
while (TmpTok.
isNot(tok::hashhash));
2934 Diag(
Tok, diag::err_pp_expected_ident_in_arg_list);
2938 Diag(
Tok, LangOpts.CPlusPlus11 ?
2939 diag::warn_cxx98_compat_variadic_macro :
2940 diag::ext_variadic_macro);
2943 if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus) {
2944 Diag(
Tok, diag::ext_pp_opencl_variadic_macros);
2950 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2959 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2967 Diag(
Tok, diag::err_pp_invalid_tok_in_arg_list);
2973 if (llvm::is_contained(Parameters, II)) {
2974 Diag(
Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
2986 Diag(
Tok, diag::err_pp_expected_comma_in_arg_list);
2995 Diag(
Tok, diag::ext_named_variadic_macro);
3000 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
3030 StringRef ValueText = II->
getName();
3031 StringRef TrimmedValue = ValueText;
3032 if (!ValueText.starts_with(
"__")) {
3033 if (ValueText.starts_with(
"_"))
3034 TrimmedValue = TrimmedValue.drop_front(1);
3038 TrimmedValue = TrimmedValue.drop_front(2);
3039 if (TrimmedValue.ends_with(
"__"))
3040 TrimmedValue = TrimmedValue.drop_back(2);
3042 return TrimmedValue == MacroText;
3049 return MacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
3062MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
3063 const Token &MacroNameTok,
const bool ImmediatelyAfterHeaderGuard) {
3065 Token LastTok = MacroNameTok;
3073 llvm::scope_exit _([&]() {
3075 if (CurLexer->ParsingPreprocessorDirective)
3086 if (
Tok.
is(tok::eod)) {
3087 if (ImmediatelyAfterHeaderGuard) {
3097 }
else if (
Tok.
is(tok::l_paren)) {
3100 if (ReadMacroParameterList(MI, LastTok))
3114 }
else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
3117 Diag(
Tok, diag::ext_c99_whitespace_required_after_macro_name);
3126 if (
Tok.
is(tok::at))
3128 else if (
Tok.
is(tok::unknown)) {
3135 Diag(
Tok, diag::ext_missing_whitespace_after_macro_name);
3137 Diag(
Tok, diag::warn_missing_whitespace_after_macro_name);
3140 if (!
Tok.
is(tok::eod))
3143 SmallVector<Token, 16> Tokens;
3150 Tokens.push_back(
Tok);
3164 if (!
Tok.
isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
3165 Tokens.push_back(
Tok);
3167 if (VAOCtx.isVAOptToken(
Tok)) {
3169 if (VAOCtx.isInVAOpt()) {
3170 Diag(
Tok, diag::err_pp_vaopt_nested_use);
3176 Diag(
Tok, diag::err_pp_missing_lparen_in_vaopt_use);
3179 Tokens.push_back(
Tok);
3182 if (
Tok.
is(tok::hashhash)) {
3183 Diag(
Tok, diag::err_vaopt_paste_at_start);
3187 }
else if (VAOCtx.isInVAOpt()) {
3188 if (
Tok.
is(tok::r_paren)) {
3189 if (VAOCtx.sawClosingParen()) {
3190 assert(Tokens.size() >= 3 &&
3191 "Must have seen at least __VA_OPT__( "
3192 "and a subsequent tok::r_paren");
3193 if (Tokens[Tokens.size() - 2].is(tok::hashhash)) {
3194 Diag(
Tok, diag::err_vaopt_paste_at_end);
3198 }
else if (
Tok.
is(tok::l_paren)) {
3212 Tokens.push_back(
Tok);
3219 if (
Tok.
is(tok::hashhash)) {
3227 if (
Tok.
is(tok::eod)) {
3228 Tokens.push_back(LastTok);
3233 Tokens[Tokens.size() - 1].is(tok::comma))
3237 Tokens.push_back(LastTok);
3246 if (!VAOCtx.isVAOptToken(
Tok) &&
3255 LastTok.
setKind(tok::unknown);
3256 Tokens.push_back(LastTok);
3259 Diag(
Tok, diag::err_pp_stringize_not_parameter)
3260 << LastTok.
is(tok::hashat);
3266 Tokens.push_back(LastTok);
3271 if (!VAOCtx.isVAOptToken(
Tok)) {
3272 Tokens.push_back(
Tok);
3279 if (VAOCtx.isInVAOpt()) {
3280 assert(
Tok.
is(tok::eod) &&
"Must be at End Of preprocessing Directive");
3281 Diag(
Tok, diag::err_pp_expected_after)
3282 << LastTok.
getKind() << tok::r_paren;
3283 Diag(VAOCtx.getUnmatchedOpeningParenLoc(), diag::note_matching) << tok::l_paren;
3294 return II->
isStr(
"__strong") || II->
isStr(
"__weak") ||
3295 II->
isStr(
"__unsafe_unretained") || II->
isStr(
"__autoreleasing");
3300void Preprocessor::HandleDefineDirective(
3301 Token &DefineTok,
const bool ImmediatelyAfterHeaderGuard) {
3305 bool MacroShadowsKeyword;
3306 ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
3309 if (MacroNameTok.
is(tok::eod))
3316 emitFinalMacroWarning(MacroNameTok,
false);
3320 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
3322 MacroInfo *
const MI = ReadOptionalMacroParameterListAndBody(
3323 MacroNameTok, ImmediatelyAfterHeaderGuard);
3327 if (MacroShadowsKeyword &&
3329 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
3334 if (NumTokens != 0) {
3346 if (SkippingUntilPCHThroughHeader) {
3349 LangOpts.MicrosoftExt))
3353 if (!LangOpts.MicrosoftExt)
3364 emitFinalMacroWarning(MacroNameTok,
false);
3375 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) &&
3377 LangOpts.MicrosoftExt)) {
3388 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) {
3396 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
3400 !MI->
isIdenticalTo(*OtherMI, *
this, LangOpts.MicrosoftExt)) {
3410 DefMacroDirective *MD =
3418 !MacroExpansionInDirectivesOverride &&
3427 Callbacks->MacroDefined(MacroNameTok, MD);
3432void Preprocessor::HandleUndefDirective() {
3436 ReadMacroName(MacroNameTok,
MU_Undef);
3439 if (MacroNameTok.
is(tok::eod))
3448 UndefMacroDirective *Undef =
nullptr;
3451 emitFinalMacroWarning(MacroNameTok,
true);
3461 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
3466 Undef = AllocateUndefMacroDirective(MacroNameTok.
getLocation());
3472 Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
3487void Preprocessor::HandleIfdefDirective(
Token &
Result,
3488 const Token &HashToken,
3490 bool ReadAnyTokensBeforeDirective) {
3492 Token DirectiveTok =
Result;
3495 ReadMacroName(MacroNameTok);
3498 if (MacroNameTok.
is(tok::eod)) {
3501 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3516 if (CurPPLexer->getConditionalStackDepth() == 0) {
3521 if (!ReadAnyTokensBeforeDirective && !MI) {
3522 assert(isIfndef &&
"#ifdef shouldn't reach here");
3523 CurPPLexer->MIOpt.EnterTopLevelIfndef(MII, MacroNameTok.
getLocation());
3525 CurPPLexer->MIOpt.EnterTopLevelConditional();
3534 Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3536 Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3539 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3543 if (PPOpts.SingleFileParseMode && !MI) {
3546 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3549 }
else if (PPOpts.SingleModuleParseMode && !MI) {
3553 SkipExcludedConditionalBlock(
3556 }
else if (!MI == isIfndef || RetainExcludedCB) {
3558 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3563 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3572void Preprocessor::HandleIfDirective(
Token &IfToken,
3573 const Token &HashToken,
3574 bool ReadAnyTokensBeforeDirective) {
3578 IdentifierInfo *IfNDefMacro =
nullptr;
3579 const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
3580 const bool ConditionalTrue = DER.Conditional;
3588 if (CurPPLexer->getConditionalStackDepth() == 0) {
3589 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
3591 CurPPLexer->MIOpt.EnterTopLevelIfndef(IfNDefMacro, IfToken.
getLocation());
3593 CurPPLexer->MIOpt.EnterTopLevelConditional();
3601 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3605 if (PPOpts.SingleFileParseMode && DER.IncludedUndefinedIds) {
3608 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3610 }
else if (PPOpts.SingleModuleParseMode && DER.IncludedUndefinedIds) {
3617 }
else if (ConditionalTrue || RetainExcludedCB) {
3619 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3631void Preprocessor::HandleEndifDirective(
Token &EndifToken) {
3637 PPConditionalInfo CondInfo;
3638 if (CurPPLexer->popConditionalLevel(CondInfo)) {
3640 Diag(EndifToken, diag::err_pp_endif_without_if);
3645 if (CurPPLexer->getConditionalStackDepth() == 0)
3646 CurPPLexer->MIOpt.ExitTopLevelConditional();
3648 assert(!CondInfo.
WasSkipping && !CurPPLexer->LexingRawMode &&
3649 "This code should only be reachable in the non-skipping case!");
3657void Preprocessor::HandleElseDirective(
Token &
Result,
const Token &HashToken) {
3663 PPConditionalInfo CI;
3664 if (CurPPLexer->popConditionalLevel(CI)) {
3670 if (CurPPLexer->getConditionalStackDepth() == 0)
3671 CurPPLexer->MIOpt.EnterTopLevelConditional();
3679 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3682 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3685 CurPPLexer->pushConditionalLevel(CI.
IfLoc,
false,
3693 true,
Result.getLocation());
3697void Preprocessor::HandleElifFamilyDirective(
Token &ElifToken,
3698 const Token &HashToken,
3709 DiagCompat(ElifToken, LangOpts.CPlusPlus ? diag_compat::cxx23_pp_directive
3710 : diag_compat::c23_pp_directive)
3722 PPConditionalInfo CI;
3723 if (CurPPLexer->popConditionalLevel(CI)) {
3724 Diag(ElifToken, diag::pp_err_elif_without_if) << DirKind;
3729 if (CurPPLexer->getConditionalStackDepth() == 0)
3730 CurPPLexer->MIOpt.EnterTopLevelConditional();
3734 Diag(ElifToken, diag::pp_err_elif_after_else) << DirKind;
3739 Callbacks->Elif(ElifToken.
getLocation(), ConditionRange,
3742 case tok::pp_elifdef:
3745 case tok::pp_elifndef:
3749 assert(
false &&
"unexpected directive kind");
3754 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3757 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3760 CurPPLexer->pushConditionalLevel(ElifToken.
getLocation(),
false,
3766 SkipExcludedConditionalBlock(
3771std::optional<LexEmbedParametersResult>
3774 tok::TokenKind EndTokenKind = ForHasEmbed ? tok::r_paren : tok::eod;
3776 auto DiagMismatchedBracesAndSkipToEOD =
3778 std::pair<tok::TokenKind, SourceLocation> Matches) {
3780 Diag(Matches.second, diag::note_matching) << Matches.first;
3781 if (CurTok.
isNot(tok::eod))
3786 if (CurTok.
isNot(Kind)) {
3787 Diag(CurTok, diag::err_expected) << Kind;
3788 if (CurTok.
isNot(tok::eod))
3805 auto LexPPParameterName = [&]() -> std::optional<std::string> {
3808 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3809 return std::nullopt;
3816 if (CurTok.
is(tok::coloncolon)) {
3819 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3820 return std::nullopt;
3826 return (llvm::Twine(Prefix->
getName()) +
"::" + Suffix->
getName()).str();
3828 return Prefix->
getName().str();
3835 auto NormalizeParameterName = [](StringRef Name) {
3836 if (Name.size() > 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
3837 return Name.substr(2, Name.size() - 4);
3841 auto LexParenthesizedIntegerExpr = [&]() -> std::optional<size_t> {
3844 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3845 return std::nullopt;
3850 bool EvaluatedDefined;
3851 DirectiveEvalResult LimitEvalResult = EvaluateDirectiveExpression(
3852 ParameterIfNDef, CurTok, EvaluatedDefined,
false);
3854 if (!LimitEvalResult.Value) {
3857 assert(CurTok.
is(tok::eod) &&
"expect to be at the end of directive");
3858 return std::nullopt;
3861 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3862 return std::nullopt;
3869 if (EvaluatedDefined) {
3870 Diag(CurTok, diag::err_defined_in_pp_embed);
3871 return std::nullopt;
3874 if (LimitEvalResult.Value) {
3875 const llvm::APSInt &
Result = *LimitEvalResult.Value;
3876 if (
Result.isNegative()) {
3877 Diag(CurTok, diag::err_requires_positive_value)
3879 if (CurTok.
isNot(EndTokenKind))
3881 return std::nullopt;
3883 return Result.getLimitedValue();
3885 return std::nullopt;
3891 return tok::r_paren;
3893 return tok::r_brace;
3895 return tok::r_square;
3897 llvm_unreachable(
"should not get here");
3901 auto LexParenthesizedBalancedTokenSoup =
3903 std::vector<std::pair<tok::TokenKind, SourceLocation>> BracketStack;
3906 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3910 bool WaitingForInnerCloseParen =
false;
3911 while (CurTok.
isNot(tok::eod) &&
3912 (WaitingForInnerCloseParen || CurTok.
isNot(tok::r_paren))) {
3917 WaitingForInnerCloseParen =
true;
3924 WaitingForInnerCloseParen =
false;
3927 case tok::r_square: {
3928 if (BracketStack.empty()) {
3929 ExpectOrDiagAndSkipToEOD(tok::r_paren);
3933 GetMatchingCloseBracket(BracketStack.back().first);
3934 if (CurTok.
getKind() != Matching) {
3935 DiagMismatchedBracesAndSkipToEOD(Matching, BracketStack.back());
3938 BracketStack.pop_back();
3941 Tokens.push_back(CurTok);
3946 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3954 while (!CurTok.
isOneOf(EndTokenKind, tok::eod)) {
3956 std::optional<std::string> ParamName = LexPPParameterName();
3958 return std::nullopt;
3959 StringRef
Parameter = NormalizeParameterName(*ParamName);
3966 if (
Result.MaybeLimitParam)
3969 std::optional<size_t> Limit = LexParenthesizedIntegerExpr();
3971 return std::nullopt;
3974 }
else if (
Parameter ==
"clang::offset") {
3975 if (
Result.MaybeOffsetParam)
3978 std::optional<size_t> Offset = LexParenthesizedIntegerExpr();
3980 return std::nullopt;
3984 if (
Result.MaybePrefixParam)
3988 if (!LexParenthesizedBalancedTokenSoup(Soup))
3989 return std::nullopt;
3991 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
3993 if (
Result.MaybeSuffixParam)
3997 if (!LexParenthesizedBalancedTokenSoup(Soup))
3998 return std::nullopt;
4000 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
4002 if (
Result.MaybeIfEmptyParam)
4006 if (!LexParenthesizedBalancedTokenSoup(Soup))
4007 return std::nullopt;
4009 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
4011 ++
Result.UnrecognizedParams;
4015 if (CurTok.
is(tok::l_paren)) {
4017 if (!LexParenthesizedBalancedTokenSoup(Soup))
4018 return std::nullopt;
4021 Diag(ParamStartLoc, diag::err_pp_unknown_parameter) << 1 <<
Parameter;
4022 if (CurTok.
isNot(EndTokenKind))
4024 return std::nullopt;
4031void Preprocessor::HandleEmbedDirectiveImpl(
4033 StringRef BinaryContents, StringRef
FileName) {
4034 if (BinaryContents.empty()) {
4042 size_t TokCount = Toks.size();
4043 auto NewToks = std::make_unique<Token[]>(TokCount);
4044 llvm::copy(Toks, NewToks.get());
4045 EnterTokenStream(std::move(NewToks), TokCount,
true,
true);
4052 size_t TotalNumToks = 1 + NumPrefixToks + NumSuffixToks;
4054 auto Toks = std::make_unique<Token[]>(TotalNumToks);
4059 CurIdx += NumPrefixToks;
4062 EmbedAnnotationData *
Data =
new (BP) EmbedAnnotationData;
4063 Data->BinaryData = BinaryContents;
4066 Toks[CurIdx].startToken();
4067 Toks[CurIdx].setKind(tok::annot_embed);
4068 Toks[CurIdx].setAnnotationRange(HashLoc);
4069 Toks[CurIdx++].setAnnotationValue(
Data);
4074 CurIdx += NumSuffixToks;
4077 assert(CurIdx == TotalNumToks &&
"Calculated the incorrect number of tokens");
4078 EnterTokenStream(std::move(Toks), TotalNumToks,
true,
true);
4085 Diag(EmbedTok, diag::warn_compat_pp_embed_directive);
4087 Diag(EmbedTok, diag::ext_pp_embed_directive)
4088 << (LangOpts.CPlusPlus ? 1 : 0);
4095 if (FilenameTok.
isNot(tok::header_name)) {
4097 if (FilenameTok.
isNot(tok::eod))
4110 std::optional<LexEmbedParametersResult> Params =
4113 assert((Params || CurTok.
is(tok::eod)) &&
4114 "expected success or to be at the end of the directive");
4119 SmallString<128> FilenameBuffer;
4120 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
4121 StringRef OriginalFilename = Filename;
4127 if (Filename.empty())
4132 if (!MaybeFileRef) {
4134 if (Callbacks && Callbacks->EmbedFileNotFound(Filename)) {
4137 Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
4142 Diag(FilenameTok, diag::err_pp_embed_device_file) << Filename;
4146 std::optional<llvm::MemoryBufferRef> MaybeFile =
4150 Diag(FilenameTok, diag::err_cannot_open_file)
4151 << Filename <<
"a buffer to the contents could not be created";
4154 StringRef BinaryContents = MaybeFile->getBuffer();
4159 if (Params->MaybeOffsetParam) {
4164 BinaryContents = BinaryContents.substr(Params->MaybeOffsetParam->Offset);
4167 if (Params->MaybeLimitParam) {
4171 BinaryContents = BinaryContents.substr(0, Params->MaybeLimitParam->Limit);
4175 Callbacks->EmbedDirective(HashLoc, Filename, isAngled, MaybeFileRef,
4184 void *Mem = BP.Allocate(OriginalFilename.size(),
alignof(
char *));
4185 memcpy(Mem, OriginalFilename.data(), OriginalFilename.size());
4186 StringRef FilenameToGo =
4187 StringRef(
static_cast<char *
>(Mem), OriginalFilename.size());
4188 HandleEmbedDirectiveImpl(HashLoc, *Params, BinaryContents, FilenameToGo);
4201 assert(
getLangOpts().CPlusPlusModules && ImportTok.
is(tok::kw_import));
4203 this->ImportingCXXNamedModules,
true);
4207 if (
Tok.isNot(tok::eod))
4215 bool ImportingHeader =
false;
4216 bool IsPartition =
false;
4218 switch (
Tok.getKind()) {
4219 case tok::header_name:
4220 ImportingHeader =
true;
4221 DirToks.push_back(
Tok);
4222 Lex(DirToks.emplace_back());
4226 DirToks.push_back(
Tok);
4227 UseLoc =
Tok.getLocation();
4230 case tok::code_completion:
4231 case tok::identifier: {
4233 Path, DirToks,
true,
4237 std::string FlatName;
4239 (IsPartition && ModuleDeclState.isNamedModule()) || !IsPartition;
4240 if (Callbacks && IsValid) {
4241 if (IsPartition && ModuleDeclState.isNamedModule()) {
4242 FlatName += ModuleDeclState.getPrimaryName();
4247 SourceLocation StartLoc = IsPartition ? UseLoc : Path[0].getLoc();
4259 DirToks.push_back(
Tok);
4265 if (!DirToks.back().isOneOf(tok::semi, tok::eod))
4268 if (DirToks.back().isNot(tok::eod))
4274 if (DirToks.back().isNot(tok::semi)) {
4279 if (ImportingHeader) {
4285 Diag(SemiLoc, diag::err_header_import_semi_in_macro);
4287 auto Action = HandleHeaderIncludeOrImport(
4289 switch (Action.Kind) {
4290 case ImportAction::None:
4293 case ImportAction::ModuleBegin:
4295 DirToks.emplace_back();
4296 DirToks.back().startToken();
4297 DirToks.back().setKind(tok::annot_module_begin);
4298 DirToks.back().setLocation(SemiLoc);
4299 DirToks.back().setAnnotationEndLoc(SemiLoc);
4300 DirToks.back().setAnnotationValue(Action.ModuleForHeader);
4303 case ImportAction::ModuleImport:
4304 case ImportAction::HeaderUnitImport:
4305 case ImportAction::SkippedModuleImport:
4308 DirToks[1].setKind(tok::annot_header_unit);
4309 DirToks[1].setAnnotationEndLoc(DirToks[0].getLocation());
4310 DirToks[1].setAnnotationValue(Action.ModuleForHeader);
4313 case ImportAction::Failure:
4314 assert(TheModuleLoader.HadFatalFailure &&
4315 "This should be an early exit only to a fatal error");
4316 CurLexer->cutOffLexing();
4345 assert(
getLangOpts().CPlusPlusModules && ModuleTok.
is(tok::kw_module));
4354 switch (
Tok.getKind()) {
4357 DirToks.push_back(
Tok);
4360 DirToks.push_back(
Tok);
4362 if (
Tok.isNot(tok::kw_private)) {
4363 if (
Tok.isNot(tok::eod))
4369 DirToks.push_back(
Tok);
4371 case tok::identifier: {
4373 Path, DirToks,
false,
4380 if (
Tok.is(tok::colon)) {
4383 Tok, Partition, DirToks,
4394 if (
Tok.is(tok::identifier) &&
4396 std::unique_ptr<Token[]> TokCopy = std::make_unique<Token[]>(1);
4398 EnterTokenStream(std::move(TokCopy), 1,
4401 DirToks.back() =
Tok;
4406 DirToks.push_back(
Tok);
4410 if (!DirToks.back().isOneOf(tok::semi, tok::eod)) {
4417 DirToks.back().isNot(tok::eod)
4421 : DirToks.pop_back_val().getLocation();
4423 bool IsGMFIntroducer = DirToks.size() == 2 && DirToks[0].is(tok::kw_module) &&
4424 DirToks[1].is(tok::semi);
4425 bool IsSynthesizedGMF = IsGMFIntroducer && HasSynthesizedGMF &&
4428 if (!IncludeMacroStack.empty() && !IsSynthesizedGMF) {
4429 Diag(StartLoc, diag::err_pp_module_decl_in_header)
4433 if (CurPPLexer->getConditionalStackDepth() != 0) {
4434 Diag(StartLoc, diag::err_pp_cond_span_module_decl)
4443 if (IsGMFIntroducer)
4444 EnterDeferredGMFInputs(End);
4461void Preprocessor::HandleObjCImportDirective(
Token &AtTok,
Token &ImportTok) {
4464 ImportTok.
setKind(tok::kw_import);
4479 if (!DirToks.back().isOneOf(tok::semi, tok::eod))
4483 DirToks.back().isNot(tok::eod)
4487 : DirToks.pop_back_val().getLocation();
4489 Module *Imported =
nullptr;
4498 Callbacks->moduleImport(ModuleImportLoc, Path, Imported);
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 void diagnoseAutoModuleImport(Preprocessor &PP, SourceLocation HashLoc, Token &IncludeTok, ArrayRef< IdentifierLoc > Path, SourceLocation PathEnd)
Produce a diagnostic informing the user that a include or similar was implicitly treated as a module ...
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 bool warnByDefaultOnWrongCase(StringRef Include)
MacroDiag
Enumerates possible cases of define/undef a reserved identifier.
@ MD_ReservedAttributeIdentifier
static bool isFeatureTestMacro(StringRef MacroName)
static bool GetLineValue(Token &DigitTok, unsigned &Val, unsigned DiagID, Preprocessor &PP, bool IsGNULineDirective=false)
GetLineValue - Convert a numeric token into an unsigned value, emitting Diagnostic DiagID if it is in...
PPElifDiag
Enumerates possible select values for the pp_err_elif_after_else and pp_err_elif_without_if diagnosti...
static bool isReservedCXXAttributeName(Preprocessor &PP, IdentifierInfo *II)
static MacroDiag shouldWarnOnMacroUndef(Preprocessor &PP, IdentifierInfo *II)
static bool isObjCProtectedMacro(const IdentifierInfo *II)
static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II)
Defines the clang::Preprocessor interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines the clang::SourceLocation class and associated facilities.
static bool isInvalid(LocType Loc, bool *Invalid)
Defines the SourceManager interface.
Defines the clang::TokenKind enum and support functions.
VerifyDiagnosticConsumer::Directive Directive
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
ResetMacroExpansionHelper(Preprocessor *pp)
~ResetMacroExpansionHelper()
static AttrArgsInfo getCXX11AttrArgsInfo(const IdentifierInfo *Name)
Represents a byte-granular source range.
static CharSourceRange getCharRange(SourceRange R)
virtual void CodeCompleteMacroName(bool IsDefinition)
Callback invoked when performing code completion in a context where the name of a macro is expected.
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.
A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...
StringRef getName() const
bool isDeviceFile() const
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...
Implements support for file system lookup, file system caching, and directory search management.
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true, bool IsText=true)
Get a FileEntryRef if it exists, without doing anything on error.
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.
A simple pair of identifier info and location.
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.
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.
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.
static std::string getFlatNameFromPath(ModuleIdPath Path)
@ 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.
ModuleKind Kind
The kind 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.
@ ModuleMapModule
This is a module that was defined by a module map and built out of header files.
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.
Preprocessor standard embed parameter "if_empty" if_empty( balanced-token-seq )
Preprocessor standard embed parameter "limit" limit( constant-expression )
Preprocessor extension embed parameter "clang::offset" clang::offset( constant-expression )
Preprocessor standard embed parameter "prefix" prefix( balanced-token-seq )
Preprocessor standard embed parameter "suffix" suffix( balanced-token-seq )
OptionalFileEntryRef getFileEntry() const
getFileEntry - Return the FileEntry corresponding to this FileID.
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 EnterModuleSuffixTokenStream(ArrayRef< Token > Toks)
void markClangModuleAsAffecting(Module *M)
Mark the given clang module as affecting the current clang module or translation unit.
void HandleCXXImportDirective(Token Import)
HandleCXXImportDirective - Handle the C++ modules import directives.
SourceRange DiscardUntilEndOfDirective(SmallVectorImpl< Token > *DiscardedToks=nullptr)
Read and discard all tokens remaining on the current line until the tok::eod token is found.
const MacroInfo * getMacroInfo(const IdentifierInfo *II) const
bool isRecordingPreamble() const
DiagnosticBuilder DiagCompat(SourceLocation Loc, unsigned CompatDiagID) 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)
IdentifierInfo * LookUpIdentifierInfo(Token &Identifier) const
Given a tok::raw_identifier token, look up the identifier information for the token and install it in...
void setCodeCompletionReached()
Note that we hit the code-completion point.
StringRef getNamedModuleName() const
Get the named module name we're preprocessing.
void Lex(Token &Result)
Lex the next token for this preprocessor.
bool EnterSourceFile(FileID FID, ConstSearchDirIterator Dir, SourceLocation Loc, bool IsFirstIncludeOfFile=true)
Add a source file to the top of the include stack and start lexing tokens from it instead of the curr...
void LexNonComment(Token &Result)
Lex a token.
friend class VAOptDefinitionContext
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)
SourceLocation CheckEndOfDirective(StringRef DirType, bool EnableMacros=false, SmallVectorImpl< Token > *ExtraToks=nullptr)
Ensure that the next token is a tok::eod token.
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.
OptionalFileEntryRef LookupEmbedFile(StringRef Filename, bool isAngled, bool OpenFile)
Given a "Filename" or <Filename> reference, look up the indicated embed resource.
void makeModuleVisible(Module *M, SourceLocation Loc, bool IncludeExports=true)
bool hadModuleLoaderFatalFailure() const
bool HandleModuleContextualKeyword(Token &Result)
Callback invoked when the lexer sees one of export, import or module token at the start of a line.
const TargetInfo & getTargetInfo() const
FileManager & getFileManager() const
bool LexHeaderName(Token &Result, bool AllowMacroExpansion=true)
Lex a token, forming a header-name token if possible.
bool isPCHThroughHeader(const FileEntry *FE)
Returns true if the FileEntry is the PCH through header.
friend class VariadicMacroScopeGuard
MacroInfo * AllocateMacroInfo(SourceLocation L)
Allocate a new MacroInfo object with the provided SourceLocation.
void LexUnexpandedToken(Token &Result)
Just like Lex, but disables macro expansion of identifier tokens.
bool alreadyIncluded(FileEntryRef File) const
Return true if this header has already been included.
FileID getPredefinesFileID() const
Returns the FileID for the preprocessor predefines.
void LexUnexpandedNonComment(Token &Result)
Like LexNonComment, but this disables macro expansion of identifier tokens.
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
bool GetIncludeFilenameSpelling(SourceLocation Loc, StringRef &Buffer)
Turn the specified lexer token into a fully checked and spelled filename, e.g.
PreprocessorLexer * getCurrentFileLexer() const
Return the current file lexer being lexed from.
HeaderSearch & getHeaderSearchInfo() const
void emitMacroExpansionWarnings(const Token &Identifier, bool IsIfnDef=false) const
void GetLineDirectiveFilenameSpelling(SourceLocation Loc, StringRef &Buffer)
Turn the specified lexer token into a fully checked and spelled filename, e.g.
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 ...
bool isNextPPTokenOneOf(Ts... Ks) const
isNextPPTokenOneOf - Check whether the next pp-token is one of the specificed token kind.
DefMacroDirective * appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI, SourceLocation Loc)
void CollectPPImportSuffix(SmallVectorImpl< Token > &Toks, bool StopUntilEOD=false)
Collect the tokens of a C++20 pp-import-suffix.
void HandlePragmaHdrstop(Token &Tok)
DiagnosticsEngine & getDiagnostics() const
void HandleCXXModuleDirective(Token Module)
HandleCXXModuleDirective - Handle C++ module declaration directives.
std::optional< LexEmbedParametersResult > LexEmbedParameters(Token &Current, bool ForHasEmbed)
Lex the parameters for an embed directive, returns nullopt on error.
Module * getModuleForLocation(SourceLocation Loc, bool AllowTextual)
Find the module that owns the source or header file that Loc points to.
bool HandleModuleName(StringRef DirType, SourceLocation UseLoc, Token &Tok, SmallVectorImpl< IdentifierLoc > &Path, SmallVectorImpl< Token > &DirToks, bool AllowMacroExpansion, bool IsPartition)
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
bool usingPCHWithThroughHeader()
True if using a PCH with a through header.
Preprocessor(const PreprocessorOptions &PPOpts, DiagnosticsEngine &diags, const LangOptions &LangOpts, SourceManager &SM, HeaderSearch &Headers, ModuleLoader &TheModuleLoader, IdentifierInfoLookup *IILookup=nullptr, bool OwnsHeaderSearch=false, TranslationUnitKind TUKind=TU_Complete)
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.
This class handles loading and caching of source files into memory.
FileIDAndOffset getDecomposedExpansionLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
bool isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
std::optional< llvm::MemoryBufferRef > getMemoryBufferForFileOrNone(FileEntryRef File)
Retrieve the memory buffer associated with the given file.
A trivial tuple used to represent a source range.
void setBegin(SourceLocation b)
SourceLocation getEnd() const
void setEnd(SourceLocation e)
Exposes information about the current target.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getEndLoc() const
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 isOneOf(Ts... Ks) const
bool isModuleContextualKeyword(bool AllowExport=true) const
Return true if we have a C++20 modules contextual keyword(export, importor module).
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
bool isNot(tok::TokenKind K) const
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix.
bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const
Return true if we have an ObjC keyword identifier.
void startToken()
Reset all flags to cleared.
bool needsCleaning() const
Return true if this token has trigraphs or escaped newlines in it.
StringRef getRawIdentifier() const
getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode),...
A directive for an undefined macro.
A directive for setting the module visibility of a macro.
Defines the clang::TargetInfo interface.
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
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.
Top level wrappers for InstallAPI frontend operations.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
bool isReservedInAllContexts(ReservedIdentifierStatus Status)
Determine whether an identifier is reserved in all contexts.
int hasAttribute(AttributeCommonInfo::Syntax Syntax, llvm::StringRef ScopeName, llvm::StringRef AttrName, const TargetInfo &Target, const LangOptions &LangOpts, bool CheckPlugins)
Return the version number associated with the attribute if we recognize and implement the attribute s...
ArrayRef< IdentifierLoc > ModuleIdPath
A sequence of identifier/location pairs used to describe a particular module or submodule,...
LLVM_READONLY char toLowercase(char c)
Converts the given ASCII character to its lowercase equivalent.
detail::SearchDirIteratorImpl< true > ConstSearchDirIterator
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
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].
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Default
Set to the current date and time.
@ Parameter
The parameter type of a method or function.
@ Result
The result type of a method or function.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
LLVM_READONLY bool isLowercase(unsigned char c)
Return true if this character is a lowercase ASCII letter: [a-z].
@ PIK_HashPragma
The pragma was introduced via #pragma.
OptionalDirectoryEntryRef Directory
The directory entry which should be used for the cached framework.
std::optional< PPEmbedParameterIfEmpty > MaybeIfEmptyParam
size_t SuffixTokenCount() const
std::optional< PPEmbedParameterSuffix > MaybeSuffixParam
std::optional< PPEmbedParameterPrefix > MaybePrefixParam
size_t PrefixTokenCount() const
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.