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);
886 if (LangOpts.CPlusPlus)
887 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
888 : diag::ext_cxx23_pp_directive;
890 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
891 : diag::ext_c23_pp_directive;
896 Diag(
Tok, diag::pp_err_elif_after_else)
910 assert(CurPPLexer->LexingRawMode &&
"We have to be skipping here!");
911 CurPPLexer->LexingRawMode =
false;
913 ReadMacroName(MacroNameTok);
914 CurPPLexer->LexingRawMode =
true;
918 if (MacroNameTok.
is(tok::eod)) {
930 MacroInfo *MI = MD.getMacroInfo();
934 Callbacks->Elifdef(DirectiveToken.
getLocation(), MacroNameTok,
937 Callbacks->Elifndef(DirectiveToken.
getLocation(), MacroNameTok,
942 if (
static_cast<bool>(MI) == IsElifDef) {
954 CurPPLexer->ParsingPreprocessorDirective =
false;
956 if (CurLexer) CurLexer->resetExtendedTokenMode();
962 CurPPLexer->LexingRawMode =
false;
967 Callbacks->SourceRangeSkipped(
968 SourceRange(HashTokenLoc, endLoc.
isValid()
970 : CurPPLexer->getSourceLocation()),
976 if (!SourceMgr.isInMainFile(Loc)) {
979 FileID IDOfIncl = SourceMgr.getFileID(SourceMgr.getExpansionLoc(Loc));
980 if (
auto EntryOfIncl = SourceMgr.getFileEntryRefForID(IDOfIncl)) {
982 return HeaderInfo.getModuleMap()
983 .findModuleForHeader(*EntryOfIncl, AllowTextual)
992 : HeaderInfo.lookupModule(
getLangOpts().CurrentModule, Loc);
999 IncLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
1006 while (!Loc.
isInvalid() && !SM.isInMainFile(Loc)) {
1007 auto ID = SM.getFileID(SM.getExpansionLoc(Loc));
1008 auto FE = SM.getFileEntryRefForID(ID);
1014 HeaderInfo.hasModuleMap(FE->getName(),
nullptr,
1015 SourceMgr.isInSystemHeader(Loc));
1017 bool InPrivateHeader =
false;
1018 for (
auto Header : HeaderInfo.findAllModulesForHeader(*FE)) {
1019 if (!Header.isAccessibleFrom(IncM)) {
1024 InPrivateHeader =
true;
1041 return std::nullopt;
1051 if (InPrivateHeader)
1052 return std::nullopt;
1060 Loc = SM.getIncludeLoc(ID);
1063 return std::nullopt;
1072 bool *IsFrameworkFound,
bool SkipCache,
bool OpenFile,
bool CacheFailures) {
1077 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
1082 bool BuildSystemModule =
false;
1083 if (!FromDir && !FromFile) {
1100 if (FID == SourceMgr.getMainFileID() && MainFileDir) {
1102 HeaderInfo.getModuleMap().shouldImportRelativeToBuiltinIncludeDir(
1104 ? HeaderInfo.getModuleMap().getBuiltinDir()
1106 Includers.push_back(std::make_pair(std::nullopt, *IncludeDir));
1108 }
else if ((FileEnt = SourceMgr.getFileEntryRefForID(
1109 SourceMgr.getMainFileID()))) {
1110 auto CWD = FileMgr.getOptionalDirectoryRef(
".");
1111 Includers.push_back(std::make_pair(*FileEnt, *CWD));
1114 Includers.push_back(std::make_pair(*FileEnt, FileEnt->
getDir()));
1120 if (LangOpts.MSVCCompat && !isAngled) {
1121 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1122 if (IsFileLexer(ISEntry))
1124 Includers.push_back(std::make_pair(*FileEnt, FileEnt->
getDir()));
1129 CurDir = CurDirLookup;
1137 Filename, FilenameLoc, isAngled, TmpFromDir, &TmpCurDir,
1138 Includers, SearchPath, RelativePath, RequestingModule,
1139 SuggestedModule,
nullptr,
1140 nullptr, SkipCache)) {
1142 TmpFromDir = TmpCurDir;
1144 if (&FE->getFileEntry() == FromFile) {
1146 FromDir = TmpFromDir;
1155 Filename, FilenameLoc, isAngled, FromDir, &CurDir, Includers, SearchPath,
1156 RelativePath, RequestingModule, SuggestedModule, IsMapped,
1157 IsFrameworkFound, SkipCache, BuildSystemModule, OpenFile, CacheFailures);
1165 if (IsFileLexer()) {
1168 Filename, *CurFileEnt, SearchPath, RelativePath, RequestingModule,
1175 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1176 if (IsFileLexer(ISEntry)) {
1177 if ((CurFileEnt = ISEntry.ThePPLexer->
getFileEntry())) {
1179 Filename, *CurFileEnt, SearchPath, RelativePath,
1180 RequestingModule, SuggestedModule)) {
1188 return std::nullopt;
1195 if (llvm::sys::path::is_absolute(Filename)) {
1202 StringRef StartingFrom, StringRef
FileName,
1203 bool RemoveInitialFileComponentFromLookupPath) {
1204 llvm::sys::path::native(StartingFrom, LookupPath);
1205 if (RemoveInitialFileComponentFromLookupPath)
1206 llvm::sys::path::remove_filename(LookupPath);
1207 if (!LookupPath.empty() &&
1208 !llvm::sys::path::is_separator(LookupPath.back())) {
1209 LookupPath.push_back(llvm::sys::path::get_separator().front());
1219 if (LookupFromFile) {
1223 llvm::sys::path::append(TmpDir, Filename);
1224 if (!TmpDir.empty()) {
1226 TmpDir, OpenFile,
true,
false);
1228 return ShouldBeEntry;
1235 if (MaybeWorkingDirEntry) {
1237 StringRef WorkingDir = WorkingDirEntry.
getName();
1238 if (!WorkingDir.empty()) {
1239 SeparateComponents(LookupPath, WorkingDir, Filename,
false);
1241 LookupPath, OpenFile,
true,
false);
1243 return ShouldBeEntry;
1248 for (
const auto &Entry : PPOpts.EmbedEntries) {
1250 SeparateComponents(LookupPath, Entry, Filename,
false);
1252 LookupPath, OpenFile,
true,
false);
1254 return ShouldBeEntry;
1256 return std::nullopt;
1266 : PP(pp), save(pp->DisableMacroExpansion) {
1267 if (pp->MacroExpansionInDirectivesOverride)
1268 pp->DisableMacroExpansion =
false;
1272 PP->DisableMacroExpansion = save;
1290 return HandleDefineDirective(
Result,
1293 if (SkippingUntilPCHThroughHeader &&
1295 return HandleIncludeDirective(HashLoc,
Result);
1297 if (SkippingUntilPragmaHdrStop && II->
getPPKeywordID() == tok::pp_pragma) {
1299 auto *II =
Result.getIdentifierInfo();
1300 if (II && II->
getName() ==
"hdrstop")
1317 CurPPLexer->ParsingPreprocessorDirective =
true;
1318 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
1320 bool ImmediatelyAfterTopLevelIfndef =
1321 CurPPLexer->MIOpt.getImmediatelyAfterTopLevelIfndef();
1322 CurPPLexer->MIOpt.resetImmediatelyAfterTopLevelIfndef();
1329 bool ReadAnyTokensBeforeDirective =CurPPLexer->MIOpt.getHasReadAnyTokensVal();
1337 if (Introducer.
isOneOf(tok::hash, tok::at))
1351 case tok::pp_include:
1352 case tok::pp_import:
1353 case tok::pp_include_next:
1354 case tok::pp___include_macros:
1355 case tok::pp_pragma:
1357 case tok::pp_module:
1358 case tok::pp___preprocessed_module:
1359 case tok::pp___preprocessed_import:
1361 << Introducer.
is(tok::hash) << II->
getName();
1362 Diag(*ArgMacro, diag::note_macro_expansion_here)
1363 << ArgMacro->getIdentifierInfo();
1377 if (SkippingUntilPCHThroughHeader || SkippingUntilPragmaHdrStop)
1381 switch (
Result.getKind()) {
1386 CurPPLexer->MIOpt.SetReadToken(ReadAnyTokensBeforeDirective);
1388 case tok::code_completion:
1391 CodeComplete->CodeCompleteDirective(
1392 CurPPLexer->getConditionalStackDepth() > 0);
1394 case tok::numeric_constant:
1401 return HandleDigitDirective(
Result);
1411 return HandleIfDirective(
Result, Introducer,
1412 ReadAnyTokensBeforeDirective);
1414 return HandleIfdefDirective(
Result, Introducer,
false,
1416 case tok::pp_ifndef:
1417 return HandleIfdefDirective(
Result, Introducer,
true,
1418 ReadAnyTokensBeforeDirective);
1420 case tok::pp_elifdef:
1421 case tok::pp_elifndef:
1422 return HandleElifFamilyDirective(
Result, Introducer,
1426 return HandleElseDirective(
Result, Introducer);
1428 return HandleEndifDirective(
Result);
1431 case tok::pp_include:
1434 case tok::pp___include_macros:
1439 case tok::pp_define:
1440 return HandleDefineDirective(
Result, ImmediatelyAfterTopLevelIfndef);
1442 return HandleUndefDirective();
1446 return HandleLineDirective();
1450 return HandleUserDiagnosticDirective(
Result,
false);
1453 case tok::pp_pragma:
1455 case tok::pp_module:
1456 case tok::pp___preprocessed_module:
1460 case tok::pp___preprocessed_import:
1462 case tok::pp_import:
1463 switch (Introducer.
getKind()) {
1467 return HandleObjCImportDirective(Introducer,
Result);
1468 case tok::kw_import:
1471 llvm_unreachable(
"not a valid import directive");
1475 case tok::pp_include_next:
1478 case tok::pp_warning:
1479 if (LangOpts.CPlusPlus)
1481 ? diag::warn_cxx23_compat_warning_directive
1482 : diag::ext_pp_warning_directive)
1485 Diag(
Result, LangOpts.C23 ? diag::warn_c23_compat_warning_directive
1486 : diag::ext_pp_warning_directive)
1489 return HandleUserDiagnosticDirective(
Result,
true);
1491 return HandleIdentSCCSDirective(
Result);
1493 return HandleIdentSCCSDirective(
Result);
1496 case tok::pp_assert:
1499 case tok::pp_unassert:
1503 case tok::pp___public_macro:
1505 return HandleMacroPublicDirective(
Result);
1508 case tok::pp___private_macro:
1510 return HandleMacroPrivateDirective();
1521 auto Toks = std::make_unique<Token[]>(2);
1523 Toks[0] = Introducer;
1528 if (
Result.is(tok::hashhash))
1529 Toks[1].setKind(tok::unknown);
1534 EnterTokenStream(std::move(Toks), 2,
false,
false);
1540 Diag(
Result, diag::err_pp_invalid_directive) << 0;
1552 bool IsGNULineDirective=
false) {
1553 if (DigitTok.
isNot(tok::numeric_constant)) {
1554 PP.
Diag(DigitTok, DiagID);
1556 if (DigitTok.
isNot(tok::eod))
1562 IntegerBuffer.resize(DigitTok.
getLength());
1563 const char *DigitTokBegin = &IntegerBuffer[0];
1573 for (
unsigned i = 0; i != ActualLength; ++i) {
1576 if (DigitTokBegin[i] ==
'\'')
1579 if (!
isDigit(DigitTokBegin[i])) {
1581 diag::err_pp_line_digit_sequence) << IsGNULineDirective;
1586 unsigned NextVal = Val*10+(DigitTokBegin[i]-
'0');
1587 if (NextVal < Val) {
1588 PP.
Diag(DigitTok, DiagID);
1595 if (DigitTokBegin[0] ==
'0' && Val)
1597 << IsGNULineDirective;
1609void Preprocessor::HandleLineDirective() {
1617 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*
this))
1621 Diag(DigitTok, diag::ext_pp_line_zero);
1625 unsigned LineLimit = 32768U;
1626 if (LangOpts.C99 || LangOpts.CPlusPlus11)
1627 LineLimit = 2147483648U;
1628 if (LineNo >= LineLimit)
1629 Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
1630 else if (LangOpts.CPlusPlus11 && LineNo >= 32768U)
1631 Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
1633 int FilenameID = -1;
1639 if (StrTok.
is(tok::eod))
1641 else if (StrTok.
isNot(tok::header_name)) {
1642 Diag(StrTok, diag::err_pp_line_invalid_filename);
1646 SmallString<128> FilenameBuffer;
1647 StringRef Filename =
getSpelling(StrTok, FilenameBuffer);
1649 FilenameID = SourceMgr.getLineTableFilenameID(Filename);
1662 SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1664 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID,
false,
1668 Callbacks->FileChanged(CurPPLexer->getSourceLocation(),
1680 if (FlagTok.
is(tok::eod))
return false;
1681 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1688 if (FlagTok.
is(tok::eod))
return false;
1689 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1691 }
else if (FlagVal == 2) {
1708 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);
1714 if (FlagTok.
is(tok::eod))
return false;
1715 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1721 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1729 if (FlagTok.
is(tok::eod))
return false;
1730 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1735 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1743 if (FlagTok.
is(tok::eod))
return false;
1746 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1758void Preprocessor::HandleDigitDirective(
Token &DigitTok) {
1762 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
1769 bool IsFileEntry =
false, IsFileExit =
false;
1770 int FilenameID = -1;
1775 if (StrTok.
is(tok::eod)) {
1776 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1778 FileKind = SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1779 }
else if (StrTok.
isNot(tok::header_name)) {
1780 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1784 SmallString<128> FilenameBuffer;
1785 StringRef Filename =
getSpelling(StrTok, FilenameBuffer);
1790 if (!SourceMgr.isInPredefinedFile(DigitTok.
getLocation()))
1791 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1795 if (!(IsFileExit && Filename.empty()))
1796 FilenameID = SourceMgr.getLineTableFilenameID(Filename);
1800 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID, IsFileEntry,
1801 IsFileExit, FileKind);
1810 else if (IsFileExit)
1813 Callbacks->FileChanged(CurPPLexer->getSourceLocation(), Reason, FileKind);
1819void Preprocessor::HandleUserDiagnosticDirective(
Token &
Tok,
1827 CurLexer->ReadToEndOfLine(&Message);
1831 StringRef Msg =
Message.str().ltrim(
' ');
1834 Diag(
Tok, diag::pp_hash_warning) << Msg;
1836 Diag(
Tok, diag::err_pp_hash_error) << Msg;
1841void Preprocessor::HandleIdentSCCSDirective(
Token &
Tok) {
1843 Diag(
Tok, diag::ext_pp_ident_directive);
1850 if (StrTok.
isNot(tok::string_literal) &&
1851 StrTok.
isNot(tok::wide_string_literal)) {
1852 Diag(StrTok, diag::err_pp_malformed_ident);
1853 if (StrTok.
isNot(tok::eod))
1859 Diag(StrTok, diag::err_invalid_string_udl);
1876void Preprocessor::HandleMacroPublicDirective(
Token &
Tok) {
1878 ReadMacroName(MacroNameTok,
MU_Undef);
1881 if (MacroNameTok.
is(tok::eod))
1893 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1903void Preprocessor::HandleMacroPrivateDirective() {
1905 ReadMacroName(MacroNameTok,
MU_Undef);
1908 if (MacroNameTok.
is(tok::eod))
1920 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1940 StringRef &Buffer) {
1942 assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1954 if (Buffer[0] ==
'<') {
1955 if (Buffer.back() !=
'>') {
1956 Diag(Loc, diag::err_pp_expects_filename);
1957 Buffer = StringRef();
1961 }
else if (Buffer[0] ==
'"') {
1962 if (Buffer.back() !=
'"') {
1963 Diag(Loc, diag::err_pp_expects_filename);
1964 Buffer = StringRef();
1969 Diag(Loc, diag::err_pp_expects_filename);
1970 Buffer = StringRef();
1975 if (Buffer.size() <= 2) {
1976 Diag(Loc, diag::err_pp_empty_filename);
1977 Buffer = StringRef();
1982 Buffer = Buffer.substr(1, Buffer.size()-2);
1987 StringRef &Buffer) {
1989 assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1990 if (Buffer.size() < 2 || Buffer.front() !=
'"' || Buffer.back() !=
'"') {
1991 Diag(Loc, diag::err_pp_line_invalid_filename);
1992 Buffer = StringRef();
1995 Buffer = Buffer.substr(1, Buffer.size() - 2);
2001 void *AnnotationVal) {
2004 auto Tok = std::make_unique<Token[]>(1);
2005 Tok[0].startToken();
2006 Tok[0].setKind(Kind);
2007 Tok[0].setLocation(Range.getBegin());
2008 Tok[0].setAnnotationEndLoc(Range.getEnd());
2009 Tok[0].setAnnotationValue(AnnotationVal);
2010 EnterTokenStream(std::move(
Tok), 1,
true,
false);
2020 for (
size_t I = 0, N = Path.size(); I != N; ++I) {
2023 PathString += Path[I].getIdentifierInfo()->getName();
2026 int IncludeKind = 0;
2028 case tok::pp_include:
2032 case tok::pp_import:
2036 case tok::pp_include_next:
2040 case tok::pp___include_macros:
2045 llvm_unreachable(
"unknown include directive kind");
2048 PP.
Diag(HashLoc, diag::remark_pp_include_directive_modular_translation)
2049 << IncludeKind << PathString;
2056 StringRef RealPathName,
2057 llvm::sys::path::Style Separator) {
2058 auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName);
2059 auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName);
2061 bool SuggestReplacement =
false;
2063 auto IsSep = [Separator](StringRef Component) {
2064 return Component.size() == 1 &&
2065 llvm::sys::path::is_separator(Component[0], Separator);
2070 for (
auto &Component : llvm::reverse(Components)) {
2071 if (
"." == Component) {
2072 }
else if (
".." == Component) {
2076 }
else if (RealPathComponentIter != RealPathComponentEnd) {
2077 if (!IsSep(Component) && !IsSep(*RealPathComponentIter) &&
2078 Component != *RealPathComponentIter) {
2082 SuggestReplacement =
2083 RealPathComponentIter->equals_insensitive(Component);
2084 if (!SuggestReplacement)
2086 Component = *RealPathComponentIter;
2088 ++RealPathComponentIter;
2091 return SuggestReplacement;
2100 Module *ShadowingModule =
nullptr;
2106 Diags.Report(MissingHeader.
FileNameLoc, diag::err_module_header_missing)
2108 }
else if (ShadowingModule) {
2111 diag::note_previous_definition);
2122std::pair<ConstSearchDirIterator, const FileEntry *>
2123Preprocessor::getIncludeNextStart(
const Token &IncludeNextTok)
const {
2128 const FileEntry *LookupFromFile =
nullptr;
2136 Diag(IncludeNextTok, diag::pp_include_next_in_primary);
2137 }
else if (CurLexerSubmodule) {
2140 assert(CurPPLexer &&
"#include_next directive in macro?");
2141 if (
auto FE = CurPPLexer->getFileEntry())
2142 LookupFromFile = *FE;
2144 }
else if (!Lookup) {
2149 Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
2155 return {Lookup, LookupFromFile};
2171 if (FilenameTok.
isNot(tok::header_name)) {
2172 if (FilenameTok.
is(tok::identifier) &&
2173 (PPOpts.SingleFileParseMode || PPOpts.SingleModuleParseMode)) {
2183 if (FilenameTok.
isNot(tok::eod))
2192 SourceLocation EndLoc =
2195 auto Action = HandleHeaderIncludeOrImport(HashLoc, IncludeTok, FilenameTok,
2196 EndLoc, LookupFrom, LookupFromFile);
2197 switch (Action.Kind) {
2198 case ImportAction::None:
2199 case ImportAction::SkippedModuleImport:
2201 case ImportAction::ModuleBegin:
2203 tok::annot_module_begin, Action.ModuleForHeader);
2205 case ImportAction::HeaderUnitImport:
2207 Action.ModuleForHeader);
2209 case ImportAction::ModuleImport:
2211 tok::annot_module_include, Action.ModuleForHeader);
2213 case ImportAction::Failure:
2214 assert(TheModuleLoader.HadFatalFailure &&
2215 "This should be an early exit only to a fatal error");
2216 TheModuleLoader.HadFatalFailure =
true;
2218 CurLexer->cutOffLexing();
2226 const Token &FilenameTok,
bool &IsFrameworkFound,
bool IsImportDecl,
2228 const FileEntry *LookupFromFile, StringRef &LookupFilename,
2231 auto DiagnoseHeaderInclusion = [&](FileEntryRef FE) {
2232 if (LangOpts.AsmPreprocessor)
2236 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
2237 bool RequestingModuleIsModuleInterface =
2238 !SourceMgr.isInMainFile(FilenameLoc);
2240 HeaderInfo.getModuleMap().diagnoseHeaderInclusion(
2241 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
2246 FilenameLoc, LookupFilename, isAngled, LookupFrom, LookupFromFile, CurDir,
2247 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2248 &SuggestedModule, &IsMapped, &IsFrameworkFound);
2250 DiagnoseHeaderInclusion(*
File);
2255 if (Callbacks && Callbacks->FileNotFound(Filename))
2256 return std::nullopt;
2258 if (SuppressIncludeNotFoundError)
2259 return std::nullopt;
2266 FilenameLoc, LookupFilename,
false, LookupFrom, LookupFromFile, CurDir,
2267 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2268 &SuggestedModule, &IsMapped,
2271 DiagnoseHeaderInclusion(*
File);
2272 Diag(FilenameTok, diag::err_pp_file_not_found_angled_include_not_fatal)
2273 << Filename << IsImportDecl
2275 "\"" + Filename.str() +
"\"");
2282 StringRef OriginalFilename = Filename;
2283 if (LangOpts.SpellChecking) {
2286 auto CorrectTypoFilename = [](llvm::StringRef Filename) {
2289 Filename = Filename.drop_back();
2293 StringRef TypoCorrectionName = CorrectTypoFilename(Filename);
2294 StringRef TypoCorrectionLookupName = CorrectTypoFilename(LookupFilename);
2297 FilenameLoc, TypoCorrectionLookupName, isAngled, LookupFrom,
2298 LookupFromFile, CurDir, Callbacks ? &SearchPath :
nullptr,
2299 Callbacks ? &RelativePath :
nullptr, &SuggestedModule, &IsMapped,
2302 DiagnoseHeaderInclusion(*
File);
2305 FilenameRange,
"<" + TypoCorrectionName.str() +
">")
2306 : FixItHint::CreateReplacement(
2307 FilenameRange,
"\"" + TypoCorrectionName.str() +
"\"");
2308 Diag(FilenameTok, diag::err_pp_file_not_found_typo_not_fatal)
2309 << OriginalFilename << TypoCorrectionName << Hint;
2312 Filename = TypoCorrectionName;
2313 LookupFilename = TypoCorrectionLookupName;
2319 assert(!
File &&
"expected missing file");
2320 Diag(FilenameTok, diag::err_pp_file_not_found)
2321 << OriginalFilename << FilenameRange;
2322 if (IsFrameworkFound) {
2323 size_t SlashPos = OriginalFilename.find(
'/');
2324 assert(SlashPos != StringRef::npos &&
2325 "Include with framework name should have '/' in the filename");
2326 StringRef FrameworkName = OriginalFilename.substr(0, SlashPos);
2327 FrameworkCacheEntry &CacheEntry =
2328 HeaderInfo.LookupFrameworkCache(FrameworkName);
2329 assert(CacheEntry.
Directory &&
"Found framework should be in cache");
2330 Diag(FilenameTok, diag::note_pp_framework_without_header)
2331 << OriginalFilename.substr(SlashPos + 1) << FrameworkName
2335 return std::nullopt;
2350Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
2354 SmallString<128> FilenameBuffer;
2355 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
2356 SourceLocation CharEnd = FilenameTok.
getEndLoc();
2358 CharSourceRange FilenameRange
2360 StringRef OriginalFilename = Filename;
2366 if (Filename.empty())
2367 return {ImportAction::None};
2368 if (Filename.ends_with(
' ') || Filename.ends_with(
'.')) {
2369 unsigned Selection = Filename.ends_with(
'.') ? 1 : 0;
2370 Diag(FilenameTok, diag::pp_nonportable_path_trailing)
2371 << Filename << Selection;
2374 bool IsImportDecl = HashLoc.
isInvalid();
2375 SourceLocation StartLoc = IsImportDecl ? IncludeTok.
getLocation() : HashLoc;
2378 if (PragmaARCCFCodeAuditedInfo.getLoc().isValid()) {
2379 Diag(StartLoc, diag::err_pp_include_in_arc_cf_code_audited) << IsImportDecl;
2380 Diag(PragmaARCCFCodeAuditedInfo.getLoc(), diag::note_pragma_entered_here);
2383 PragmaARCCFCodeAuditedInfo = IdentifierLoc();
2387 if (PragmaAssumeNonNullLoc.isValid()) {
2388 Diag(StartLoc, diag::err_pp_include_in_assume_nonnull) << IsImportDecl;
2389 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
2392 PragmaAssumeNonNullLoc = SourceLocation();
2395 if (HeaderInfo.HasIncludeAliasMap()) {
2399 StringRef NewName = HeaderInfo.MapHeaderToIncludeAlias(OriginalFilename);
2400 if (!NewName.empty())
2405 bool IsMapped =
false;
2406 bool IsFrameworkFound =
false;
2408 SmallString<1024> SearchPath;
2409 SmallString<1024> RelativePath;
2412 ModuleMap::KnownHeader SuggestedModule;
2413 SourceLocation FilenameLoc = FilenameTok.
getLocation();
2414 StringRef LookupFilename = Filename;
2418 SmallString<128> NormalizedPath;
2419 llvm::sys::path::Style BackslashStyle = llvm::sys::path::Style::native;
2420 if (is_style_posix(BackslashStyle) && LangOpts.MicrosoftExt) {
2421 NormalizedPath = Filename.str();
2422 llvm::sys::path::native(NormalizedPath);
2423 LookupFilename = NormalizedPath;
2424 BackslashStyle = llvm::sys::path::Style::windows;
2428 &CurDir, Filename, FilenameLoc, FilenameRange, FilenameTok,
2429 IsFrameworkFound, IsImportDecl, IsMapped, LookupFrom, LookupFromFile,
2430 LookupFilename, RelativePath, SearchPath, SuggestedModule, isAngled);
2434 SkippingUntilPCHThroughHeader =
false;
2435 return {ImportAction::None};
2453 enum { Enter,
Import,
Skip, IncludeLimitReached } Action = Enter;
2455 if (PPOpts.SingleFileParseMode)
2456 Action = IncludeLimitReached;
2461 if (Action == Enter && HasReachedMaxIncludeDepth &&
File &&
2463 Action = IncludeLimitReached;
2470 bool MaybeTranslateInclude = Action == Enter &&
File && ModuleToImport &&
2474 bool UsableHeaderUnit =
false;
2475 if (
getLangOpts().CPlusPlusModules && ModuleToImport &&
2477 if (TrackGMFState.inGMF() || IsImportDecl)
2478 UsableHeaderUnit =
true;
2479 else if (!IsImportDecl) {
2481 ModuleToImport =
nullptr;
2485 bool UsableClangHeaderModule =
2492 if (MaybeTranslateInclude && (UsableHeaderUnit || UsableClangHeaderModule)) {
2500 diag::note_implicit_top_level_module_import_here)
2502 return {ImportAction::None};
2508 SmallVector<IdentifierLoc, 2> Path;
2509 for (
Module *Mod = ModuleToImport; Mod; Mod = Mod->Parent)
2512 std::reverse(Path.begin(), Path.end());
2522 ModuleLoadResult Imported = TheModuleLoader.loadModule(
2525 assert((Imported ==
nullptr || Imported == ModuleToImport) &&
2526 "the imported module is different than the suggested one");
2532 static_cast<Module *
>(Imported)->getTopLevelModule());
2537 ModuleToImport =
nullptr;
2538 UsableClangHeaderModule =
false;
2546 Token &
Result = IncludeTok;
2547 assert(CurLexer &&
"#include but no current lexer set!");
2549 CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
2550 CurLexer->cutOffLexing();
2552 return {ImportAction::None};
2560 SourceMgr.getFileCharacteristic(FilenameTok.
getLocation());
2562 FileCharacter = std::max(HeaderInfo.getFileDirFlavor(*
File), FileCharacter);
2573 bool IsFirstIncludeOfFile =
false;
2577 if (Action == Enter &&
File &&
2578 !HeaderInfo.ShouldEnterIncludeFile(*
this, *
File, EnterOnce,
2580 IsFirstIncludeOfFile)) {
2591 if (UsableHeaderUnit && !
getLangOpts().CompilingPCH)
2592 Action = TrackGMFState.inGMF() ?
Import :
Skip;
2594 Action = (UsableClangHeaderModule && !
getLangOpts().CompilingPCH) ? Import
2603 if (Action == Enter &&
File && PreambleConditionalStack.isRecording() &&
2604 SourceMgr.isMainFile(
File->getFileEntry())) {
2606 diag::err_pp_including_mainfile_in_preamble);
2607 return {ImportAction::None};
2610 if (Callbacks && !IsImportDecl) {
2613 Callbacks->InclusionDirective(HashLoc, IncludeTok, LookupFilename, isAngled,
2614 FilenameRange,
File, SearchPath, RelativePath,
2615 SuggestedModule.
getModule(), Action == Import,
2618 Callbacks->FileSkipped(*
File, FilenameTok, FileCharacter);
2622 return {ImportAction::None};
2626 if (IsImportDecl && !ModuleToImport) {
2627 Diag(FilenameTok, diag::err_header_import_not_header_unit)
2628 << OriginalFilename <<
File->getName();
2629 return {ImportAction::None};
2634 const bool CheckIncludePathPortability =
2635 !IsMapped && !
File->getFileEntry().tryGetRealPathName().empty();
2637 if (CheckIncludePathPortability) {
2638 StringRef Name = LookupFilename;
2639 StringRef NameWithoriginalSlashes = Filename;
2643 bool NameWasUNC = Name.consume_front(
"\\\\?\\");
2644 NameWithoriginalSlashes.consume_front(
"\\\\?\\");
2646 StringRef RealPathName =
File->getFileEntry().tryGetRealPathName();
2647 SmallVector<StringRef, 16> Components(llvm::sys::path::begin(Name),
2648 llvm::sys::path::end(Name));
2660 SmallString<128> FixedDriveRealPath;
2661 if (llvm::sys::path::is_absolute(Name) &&
2662 llvm::sys::path::is_absolute(RealPathName) &&
2665 assert(Components.size() >= 3 &&
"should have drive, backslash, name");
2666 assert(Components[0].size() == 2 &&
"should start with drive");
2667 assert(Components[0][1] ==
':' &&
"should have colon");
2668 FixedDriveRealPath = (Name.substr(0, 1) + RealPathName.substr(1)).str();
2669 RealPathName = FixedDriveRealPath;
2674 SmallString<128> Path;
2675 Path.reserve(Name.size()+2);
2676 Path.push_back(isAngled ?
'<' :
'"');
2678 const auto IsSep = [BackslashStyle](
char c) {
2679 return llvm::sys::path::is_separator(c, BackslashStyle);
2682 for (
auto Component : Components) {
2694 if (!(Component.size() == 1 && IsSep(Component[0])))
2695 Path.append(Component);
2696 else if (Path.size() != 1)
2700 if (Path.size() > NameWithoriginalSlashes.size()) {
2701 Path.push_back(isAngled ?
'>' :
'"');
2704 assert(IsSep(NameWithoriginalSlashes[Path.size()-1]));
2706 Path.push_back(NameWithoriginalSlashes[Path.size()-1]);
2707 while (Path.size() <= NameWithoriginalSlashes.size() &&
2708 IsSep(NameWithoriginalSlashes[Path.size()-1]));
2714 Path = (Path.substr(0, 1) +
"\\\\?\\" + Path.substr(1)).str();
2721 ? diag::pp_nonportable_path
2722 : diag::pp_nonportable_system_path;
2723 Diag(FilenameTok, DiagId) << Path <<
2727 bool SuppressBackslashDiag =
2729 Diags->isIgnored(diag::pp_nonportable_path_separator, FilenameLoc) ||
2732 SourceMgr.isWrittenInBuiltinFile(FilenameLoc) ||
2733 SourceMgr.isWrittenInModuleIncludes(FilenameLoc);
2734 if (!SuppressBackslashDiag && OriginalFilename.contains(
'\\')) {
2735 std::string SuggestedPath = OriginalFilename.str();
2736 llvm::replace(SuggestedPath,
'\\',
'/');
2737 Diag(FilenameTok, diag::pp_nonportable_path_separator)
2746 return {ImportAction::SkippedModuleImport, ModuleToImport};
2747 return {ImportAction::None};
2749 case IncludeLimitReached:
2752 return {ImportAction::None};
2756 assert(ModuleToImport &&
"no module to import");
2761 tok::pp___include_macros)
2762 return {ImportAction::None};
2764 return {ImportAction::ModuleImport, ModuleToImport};
2772 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
2773 Diag(FilenameTok, diag::err_pp_include_too_deep);
2774 HasReachedMaxIncludeDepth =
true;
2775 return {ImportAction::None};
2779 Diag(FilenameTok, diag::warn_pp_include_angled_in_module_purview)
2783 SourceLocation IncludePos = FilenameTok.
getLocation();
2787 IncludePos = SourceMgr.getExpansionRange(IncludePos).getEnd();
2788 FileID FID = SourceMgr.createFileID(*
File, IncludePos, FileCharacter);
2790 TheModuleLoader.HadFatalFailure =
true;
2791 return ImportAction::Failure;
2796 IsFirstIncludeOfFile))
2797 return {ImportAction::None};
2801 if (ModuleToImport && !ModuleToImport->
isHeaderUnit()) {
2806 diag::err_module_build_shadowed_submodule)
2809 diag::note_previous_definition);
2810 return {ImportAction::None};
2822 return {ImportAction::None};
2824 assert(!CurLexerSubmodule &&
"should not have marked this as a module yet");
2825 CurLexerSubmodule = ModuleToImport;
2835 return {ImportAction::ModuleBegin, ModuleToImport};
2838 assert(!IsImportDecl &&
"failed to diagnose missing module for import decl");
2839 return {ImportAction::None};
2844void Preprocessor::HandleIncludeNextDirective(
SourceLocation HashLoc,
2845 Token &IncludeNextTok) {
2846 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
2849 const FileEntry *LookupFromFile;
2850 std::tie(Lookup, LookupFromFile) = getIncludeNextStart(IncludeNextTok);
2852 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
2857void Preprocessor::HandleMicrosoftImportDirective(
Token &
Tok) {
2863 Diag(
Tok, diag::err_pp_import_directive_ms );
2874 if (!LangOpts.ObjC) {
2875 if (LangOpts.MSVCCompat)
2876 return HandleMicrosoftImportDirective(ImportTok);
2877 Diag(ImportTok, diag::ext_pp_import_directive);
2879 return HandleIncludeDirective(HashLoc, ImportTok);
2886void Preprocessor::HandleIncludeMacrosDirective(
SourceLocation HashLoc,
2887 Token &IncludeMacrosTok) {
2890 SourceLocation Loc = IncludeMacrosTok.
getLocation();
2891 if (SourceMgr.getBufferName(Loc) !=
"<built-in>") {
2893 diag::pp_include_macros_out_of_predefines);
2900 HandleIncludeDirective(HashLoc, IncludeMacrosTok);
2905 assert(TmpTok.
isNot(tok::eof) &&
"Didn't find end of -imacros!");
2906 }
while (TmpTok.
isNot(tok::hashhash));
2928 Diag(
Tok, diag::err_pp_expected_ident_in_arg_list);
2932 Diag(
Tok, LangOpts.CPlusPlus11 ?
2933 diag::warn_cxx98_compat_variadic_macro :
2934 diag::ext_variadic_macro);
2937 if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus) {
2938 Diag(
Tok, diag::ext_pp_opencl_variadic_macros);
2944 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2953 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2961 Diag(
Tok, diag::err_pp_invalid_tok_in_arg_list);
2967 if (llvm::is_contained(Parameters, II)) {
2968 Diag(
Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
2980 Diag(
Tok, diag::err_pp_expected_comma_in_arg_list);
2989 Diag(
Tok, diag::ext_named_variadic_macro);
2994 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
3024 StringRef ValueText = II->
getName();
3025 StringRef TrimmedValue = ValueText;
3026 if (!ValueText.starts_with(
"__")) {
3027 if (ValueText.starts_with(
"_"))
3028 TrimmedValue = TrimmedValue.drop_front(1);
3032 TrimmedValue = TrimmedValue.drop_front(2);
3033 if (TrimmedValue.ends_with(
"__"))
3034 TrimmedValue = TrimmedValue.drop_back(2);
3036 return TrimmedValue == MacroText;
3043 return MacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
3056MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
3057 const Token &MacroNameTok,
const bool ImmediatelyAfterHeaderGuard) {
3059 Token LastTok = MacroNameTok;
3067 llvm::scope_exit _([&]() {
3069 if (CurLexer->ParsingPreprocessorDirective)
3080 if (
Tok.
is(tok::eod)) {
3081 if (ImmediatelyAfterHeaderGuard) {
3091 }
else if (
Tok.
is(tok::l_paren)) {
3094 if (ReadMacroParameterList(MI, LastTok))
3108 }
else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
3111 Diag(
Tok, diag::ext_c99_whitespace_required_after_macro_name);
3120 if (
Tok.
is(tok::at))
3122 else if (
Tok.
is(tok::unknown)) {
3129 Diag(
Tok, diag::ext_missing_whitespace_after_macro_name);
3131 Diag(
Tok, diag::warn_missing_whitespace_after_macro_name);
3134 if (!
Tok.
is(tok::eod))
3137 SmallVector<Token, 16> Tokens;
3144 Tokens.push_back(
Tok);
3158 if (!
Tok.
isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
3159 Tokens.push_back(
Tok);
3161 if (VAOCtx.isVAOptToken(
Tok)) {
3163 if (VAOCtx.isInVAOpt()) {
3164 Diag(
Tok, diag::err_pp_vaopt_nested_use);
3170 Diag(
Tok, diag::err_pp_missing_lparen_in_vaopt_use);
3173 Tokens.push_back(
Tok);
3176 if (
Tok.
is(tok::hashhash)) {
3177 Diag(
Tok, diag::err_vaopt_paste_at_start);
3181 }
else if (VAOCtx.isInVAOpt()) {
3182 if (
Tok.
is(tok::r_paren)) {
3183 if (VAOCtx.sawClosingParen()) {
3184 assert(Tokens.size() >= 3 &&
3185 "Must have seen at least __VA_OPT__( "
3186 "and a subsequent tok::r_paren");
3187 if (Tokens[Tokens.size() - 2].is(tok::hashhash)) {
3188 Diag(
Tok, diag::err_vaopt_paste_at_end);
3192 }
else if (
Tok.
is(tok::l_paren)) {
3206 Tokens.push_back(
Tok);
3213 if (
Tok.
is(tok::hashhash)) {
3221 if (
Tok.
is(tok::eod)) {
3222 Tokens.push_back(LastTok);
3227 Tokens[Tokens.size() - 1].is(tok::comma))
3231 Tokens.push_back(LastTok);
3240 if (!VAOCtx.isVAOptToken(
Tok) &&
3249 LastTok.
setKind(tok::unknown);
3250 Tokens.push_back(LastTok);
3253 Diag(
Tok, diag::err_pp_stringize_not_parameter)
3254 << LastTok.
is(tok::hashat);
3260 Tokens.push_back(LastTok);
3265 if (!VAOCtx.isVAOptToken(
Tok)) {
3266 Tokens.push_back(
Tok);
3273 if (VAOCtx.isInVAOpt()) {
3274 assert(
Tok.
is(tok::eod) &&
"Must be at End Of preprocessing Directive");
3275 Diag(
Tok, diag::err_pp_expected_after)
3276 << LastTok.
getKind() << tok::r_paren;
3277 Diag(VAOCtx.getUnmatchedOpeningParenLoc(), diag::note_matching) << tok::l_paren;
3288 return II->
isStr(
"__strong") || II->
isStr(
"__weak") ||
3289 II->
isStr(
"__unsafe_unretained") || II->
isStr(
"__autoreleasing");
3294void Preprocessor::HandleDefineDirective(
3295 Token &DefineTok,
const bool ImmediatelyAfterHeaderGuard) {
3299 bool MacroShadowsKeyword;
3300 ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
3303 if (MacroNameTok.
is(tok::eod))
3310 emitFinalMacroWarning(MacroNameTok,
false);
3314 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
3316 MacroInfo *
const MI = ReadOptionalMacroParameterListAndBody(
3317 MacroNameTok, ImmediatelyAfterHeaderGuard);
3321 if (MacroShadowsKeyword &&
3323 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
3328 if (NumTokens != 0) {
3340 if (SkippingUntilPCHThroughHeader) {
3343 LangOpts.MicrosoftExt))
3347 if (!LangOpts.MicrosoftExt)
3358 emitFinalMacroWarning(MacroNameTok,
false);
3369 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) &&
3371 LangOpts.MicrosoftExt)) {
3382 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) {
3390 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
3394 !MI->
isIdenticalTo(*OtherMI, *
this, LangOpts.MicrosoftExt)) {
3404 DefMacroDirective *MD =
3412 !MacroExpansionInDirectivesOverride &&
3421 Callbacks->MacroDefined(MacroNameTok, MD);
3426void Preprocessor::HandleUndefDirective() {
3430 ReadMacroName(MacroNameTok,
MU_Undef);
3433 if (MacroNameTok.
is(tok::eod))
3442 UndefMacroDirective *Undef =
nullptr;
3445 emitFinalMacroWarning(MacroNameTok,
true);
3455 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
3460 Undef = AllocateUndefMacroDirective(MacroNameTok.
getLocation());
3466 Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
3481void Preprocessor::HandleIfdefDirective(
Token &
Result,
3482 const Token &HashToken,
3484 bool ReadAnyTokensBeforeDirective) {
3486 Token DirectiveTok =
Result;
3489 ReadMacroName(MacroNameTok);
3492 if (MacroNameTok.
is(tok::eod)) {
3495 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3510 if (CurPPLexer->getConditionalStackDepth() == 0) {
3515 if (!ReadAnyTokensBeforeDirective && !MI) {
3516 assert(isIfndef &&
"#ifdef shouldn't reach here");
3517 CurPPLexer->MIOpt.EnterTopLevelIfndef(MII, MacroNameTok.
getLocation());
3519 CurPPLexer->MIOpt.EnterTopLevelConditional();
3528 Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3530 Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3533 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3537 if (PPOpts.SingleFileParseMode && !MI) {
3540 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3543 }
else if (PPOpts.SingleModuleParseMode && !MI) {
3547 SkipExcludedConditionalBlock(
3550 }
else if (!MI == isIfndef || RetainExcludedCB) {
3552 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3557 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3566void Preprocessor::HandleIfDirective(
Token &IfToken,
3567 const Token &HashToken,
3568 bool ReadAnyTokensBeforeDirective) {
3572 IdentifierInfo *IfNDefMacro =
nullptr;
3573 const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
3574 const bool ConditionalTrue = DER.Conditional;
3582 if (CurPPLexer->getConditionalStackDepth() == 0) {
3583 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
3585 CurPPLexer->MIOpt.EnterTopLevelIfndef(IfNDefMacro, IfToken.
getLocation());
3587 CurPPLexer->MIOpt.EnterTopLevelConditional();
3595 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3599 if (PPOpts.SingleFileParseMode && DER.IncludedUndefinedIds) {
3602 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3604 }
else if (PPOpts.SingleModuleParseMode && DER.IncludedUndefinedIds) {
3611 }
else if (ConditionalTrue || RetainExcludedCB) {
3613 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3625void Preprocessor::HandleEndifDirective(
Token &EndifToken) {
3631 PPConditionalInfo CondInfo;
3632 if (CurPPLexer->popConditionalLevel(CondInfo)) {
3634 Diag(EndifToken, diag::err_pp_endif_without_if);
3639 if (CurPPLexer->getConditionalStackDepth() == 0)
3640 CurPPLexer->MIOpt.ExitTopLevelConditional();
3642 assert(!CondInfo.
WasSkipping && !CurPPLexer->LexingRawMode &&
3643 "This code should only be reachable in the non-skipping case!");
3651void Preprocessor::HandleElseDirective(
Token &
Result,
const Token &HashToken) {
3657 PPConditionalInfo CI;
3658 if (CurPPLexer->popConditionalLevel(CI)) {
3664 if (CurPPLexer->getConditionalStackDepth() == 0)
3665 CurPPLexer->MIOpt.EnterTopLevelConditional();
3673 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3676 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3679 CurPPLexer->pushConditionalLevel(CI.
IfLoc,
false,
3687 true,
Result.getLocation());
3691void Preprocessor::HandleElifFamilyDirective(
Token &ElifToken,
3692 const Token &HashToken,
3704 if (LangOpts.CPlusPlus)
3705 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
3706 : diag::ext_cxx23_pp_directive;
3708 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
3709 : diag::ext_c23_pp_directive;
3710 Diag(ElifToken, DiagID) << DirKind;
3721 PPConditionalInfo CI;
3722 if (CurPPLexer->popConditionalLevel(CI)) {
3723 Diag(ElifToken, diag::pp_err_elif_without_if) << DirKind;
3728 if (CurPPLexer->getConditionalStackDepth() == 0)
3729 CurPPLexer->MIOpt.EnterTopLevelConditional();
3733 Diag(ElifToken, diag::pp_err_elif_after_else) << DirKind;
3738 Callbacks->Elif(ElifToken.
getLocation(), ConditionRange,
3741 case tok::pp_elifdef:
3744 case tok::pp_elifndef:
3748 assert(
false &&
"unexpected directive kind");
3753 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3756 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3759 CurPPLexer->pushConditionalLevel(ElifToken.
getLocation(),
false,
3765 SkipExcludedConditionalBlock(
3770std::optional<LexEmbedParametersResult>
3773 tok::TokenKind EndTokenKind = ForHasEmbed ? tok::r_paren : tok::eod;
3775 auto DiagMismatchedBracesAndSkipToEOD =
3777 std::pair<tok::TokenKind, SourceLocation> Matches) {
3779 Diag(Matches.second, diag::note_matching) << Matches.first;
3780 if (CurTok.
isNot(tok::eod))
3785 if (CurTok.
isNot(Kind)) {
3786 Diag(CurTok, diag::err_expected) << Kind;
3787 if (CurTok.
isNot(tok::eod))
3804 auto LexPPParameterName = [&]() -> std::optional<std::string> {
3807 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3808 return std::nullopt;
3815 if (CurTok.
is(tok::coloncolon)) {
3818 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3819 return std::nullopt;
3825 return (llvm::Twine(Prefix->
getName()) +
"::" + Suffix->
getName()).str();
3827 return Prefix->
getName().str();
3834 auto NormalizeParameterName = [](StringRef Name) {
3835 if (Name.size() > 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
3836 return Name.substr(2, Name.size() - 4);
3840 auto LexParenthesizedIntegerExpr = [&]() -> std::optional<size_t> {
3843 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3844 return std::nullopt;
3849 bool EvaluatedDefined;
3850 DirectiveEvalResult LimitEvalResult = EvaluateDirectiveExpression(
3851 ParameterIfNDef, CurTok, EvaluatedDefined,
false);
3853 if (!LimitEvalResult.Value) {
3856 assert(CurTok.
is(tok::eod) &&
"expect to be at the end of directive");
3857 return std::nullopt;
3860 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3861 return std::nullopt;
3868 if (EvaluatedDefined) {
3869 Diag(CurTok, diag::err_defined_in_pp_embed);
3870 return std::nullopt;
3873 if (LimitEvalResult.Value) {
3874 const llvm::APSInt &
Result = *LimitEvalResult.Value;
3875 if (
Result.isNegative()) {
3876 Diag(CurTok, diag::err_requires_positive_value)
3878 if (CurTok.
isNot(EndTokenKind))
3880 return std::nullopt;
3882 return Result.getLimitedValue();
3884 return std::nullopt;
3890 return tok::r_paren;
3892 return tok::r_brace;
3894 return tok::r_square;
3896 llvm_unreachable(
"should not get here");
3900 auto LexParenthesizedBalancedTokenSoup =
3902 std::vector<std::pair<tok::TokenKind, SourceLocation>> BracketStack;
3905 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3909 bool WaitingForInnerCloseParen =
false;
3910 while (CurTok.
isNot(tok::eod) &&
3911 (WaitingForInnerCloseParen || CurTok.
isNot(tok::r_paren))) {
3916 WaitingForInnerCloseParen =
true;
3923 WaitingForInnerCloseParen =
false;
3926 case tok::r_square: {
3927 if (BracketStack.empty()) {
3928 ExpectOrDiagAndSkipToEOD(tok::r_paren);
3932 GetMatchingCloseBracket(BracketStack.back().first);
3933 if (CurTok.
getKind() != Matching) {
3934 DiagMismatchedBracesAndSkipToEOD(Matching, BracketStack.back());
3937 BracketStack.pop_back();
3940 Tokens.push_back(CurTok);
3945 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3953 while (!CurTok.
isOneOf(EndTokenKind, tok::eod)) {
3955 std::optional<std::string> ParamName = LexPPParameterName();
3957 return std::nullopt;
3958 StringRef
Parameter = NormalizeParameterName(*ParamName);
3965 if (
Result.MaybeLimitParam)
3968 std::optional<size_t> Limit = LexParenthesizedIntegerExpr();
3970 return std::nullopt;
3973 }
else if (
Parameter ==
"clang::offset") {
3974 if (
Result.MaybeOffsetParam)
3977 std::optional<size_t> Offset = LexParenthesizedIntegerExpr();
3979 return std::nullopt;
3983 if (
Result.MaybePrefixParam)
3987 if (!LexParenthesizedBalancedTokenSoup(Soup))
3988 return std::nullopt;
3990 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
3992 if (
Result.MaybeSuffixParam)
3996 if (!LexParenthesizedBalancedTokenSoup(Soup))
3997 return std::nullopt;
3999 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
4001 if (
Result.MaybeIfEmptyParam)
4005 if (!LexParenthesizedBalancedTokenSoup(Soup))
4006 return std::nullopt;
4008 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
4010 ++
Result.UnrecognizedParams;
4014 if (CurTok.
is(tok::l_paren)) {
4016 if (!LexParenthesizedBalancedTokenSoup(Soup))
4017 return std::nullopt;
4020 Diag(ParamStartLoc, diag::err_pp_unknown_parameter) << 1 <<
Parameter;
4021 if (CurTok.
isNot(EndTokenKind))
4023 return std::nullopt;
4030void Preprocessor::HandleEmbedDirectiveImpl(
4032 StringRef BinaryContents, StringRef
FileName) {
4033 if (BinaryContents.empty()) {
4041 size_t TokCount = Toks.size();
4042 auto NewToks = std::make_unique<Token[]>(TokCount);
4043 llvm::copy(Toks, NewToks.get());
4044 EnterTokenStream(std::move(NewToks), TokCount,
true,
true);
4051 size_t TotalNumToks = 1 + NumPrefixToks + NumSuffixToks;
4053 auto Toks = std::make_unique<Token[]>(TotalNumToks);
4058 CurIdx += NumPrefixToks;
4061 EmbedAnnotationData *
Data =
new (BP) EmbedAnnotationData;
4062 Data->BinaryData = BinaryContents;
4065 Toks[CurIdx].startToken();
4066 Toks[CurIdx].setKind(tok::annot_embed);
4067 Toks[CurIdx].setAnnotationRange(HashLoc);
4068 Toks[CurIdx++].setAnnotationValue(
Data);
4073 CurIdx += NumSuffixToks;
4076 assert(CurIdx == TotalNumToks &&
"Calculated the incorrect number of tokens");
4077 EnterTokenStream(std::move(Toks), TotalNumToks,
true,
true);
4084 Diag(EmbedTok, diag::warn_compat_pp_embed_directive);
4086 Diag(EmbedTok, diag::ext_pp_embed_directive)
4087 << (LangOpts.CPlusPlus ? 1 : 0);
4094 if (FilenameTok.
isNot(tok::header_name)) {
4096 if (FilenameTok.
isNot(tok::eod))
4109 std::optional<LexEmbedParametersResult> Params =
4112 assert((Params || CurTok.
is(tok::eod)) &&
4113 "expected success or to be at the end of the directive");
4118 SmallString<128> FilenameBuffer;
4119 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
4120 StringRef OriginalFilename = Filename;
4126 if (Filename.empty())
4131 if (!MaybeFileRef) {
4133 if (Callbacks && Callbacks->EmbedFileNotFound(Filename)) {
4136 Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
4141 Diag(FilenameTok, diag::err_pp_embed_device_file) << Filename;
4145 std::optional<llvm::MemoryBufferRef> MaybeFile =
4149 Diag(FilenameTok, diag::err_cannot_open_file)
4150 << Filename <<
"a buffer to the contents could not be created";
4153 StringRef BinaryContents = MaybeFile->getBuffer();
4158 if (Params->MaybeOffsetParam) {
4163 BinaryContents = BinaryContents.substr(Params->MaybeOffsetParam->Offset);
4166 if (Params->MaybeLimitParam) {
4170 BinaryContents = BinaryContents.substr(0, Params->MaybeLimitParam->Limit);
4174 Callbacks->EmbedDirective(HashLoc, Filename, isAngled, MaybeFileRef,
4183 void *Mem = BP.Allocate(OriginalFilename.size(),
alignof(
char *));
4184 memcpy(Mem, OriginalFilename.data(), OriginalFilename.size());
4185 StringRef FilenameToGo =
4186 StringRef(
static_cast<char *
>(Mem), OriginalFilename.size());
4187 HandleEmbedDirectiveImpl(HashLoc, *Params, BinaryContents, FilenameToGo);
4200 assert(
getLangOpts().CPlusPlusModules && ImportTok.
is(tok::kw_import));
4202 this->ImportingCXXNamedModules,
true);
4206 if (
Tok.isNot(tok::eod))
4214 bool ImportingHeader =
false;
4215 bool IsPartition =
false;
4217 switch (
Tok.getKind()) {
4218 case tok::header_name:
4219 ImportingHeader =
true;
4220 DirToks.push_back(
Tok);
4221 Lex(DirToks.emplace_back());
4225 DirToks.push_back(
Tok);
4226 UseLoc =
Tok.getLocation();
4229 case tok::identifier: {
4231 Path, DirToks,
true,
4235 std::string FlatName;
4237 (IsPartition && ModuleDeclState.isNamedModule()) || !IsPartition;
4238 if (Callbacks && IsValid) {
4239 if (IsPartition && ModuleDeclState.isNamedModule()) {
4240 FlatName += ModuleDeclState.getPrimaryName();
4245 SourceLocation StartLoc = IsPartition ? UseLoc : Path[0].getLoc();
4257 DirToks.push_back(
Tok);
4263 if (!DirToks.back().isOneOf(tok::semi, tok::eod))
4266 if (DirToks.back().isNot(tok::eod))
4272 if (DirToks.back().isNot(tok::semi)) {
4277 if (ImportingHeader) {
4283 Diag(SemiLoc, diag::err_header_import_semi_in_macro);
4285 auto Action = HandleHeaderIncludeOrImport(
4287 switch (Action.Kind) {
4288 case ImportAction::None:
4291 case ImportAction::ModuleBegin:
4293 DirToks.emplace_back();
4294 DirToks.back().startToken();
4295 DirToks.back().setKind(tok::annot_module_begin);
4296 DirToks.back().setLocation(SemiLoc);
4297 DirToks.back().setAnnotationEndLoc(SemiLoc);
4298 DirToks.back().setAnnotationValue(Action.ModuleForHeader);
4301 case ImportAction::ModuleImport:
4302 case ImportAction::HeaderUnitImport:
4303 case ImportAction::SkippedModuleImport:
4306 DirToks[1].setKind(tok::annot_header_unit);
4307 DirToks[1].setAnnotationEndLoc(DirToks[0].getLocation());
4308 DirToks[1].setAnnotationValue(Action.ModuleForHeader);
4311 case ImportAction::Failure:
4312 assert(TheModuleLoader.HadFatalFailure &&
4313 "This should be an early exit only to a fatal error");
4314 CurLexer->cutOffLexing();
4343 assert(
getLangOpts().CPlusPlusModules && ModuleTok.
is(tok::kw_module));
4352 switch (
Tok.getKind()) {
4355 DirToks.push_back(
Tok);
4358 DirToks.push_back(
Tok);
4360 if (
Tok.isNot(tok::kw_private)) {
4361 if (
Tok.isNot(tok::eod))
4367 DirToks.push_back(
Tok);
4369 case tok::identifier: {
4371 Path, DirToks,
false,
4378 if (
Tok.is(tok::colon)) {
4381 Tok, Partition, DirToks,
4392 if (
Tok.is(tok::identifier) &&
4394 std::unique_ptr<Token[]> TokCopy = std::make_unique<Token[]>(1);
4396 EnterTokenStream(std::move(TokCopy), 1,
4399 DirToks.back() =
Tok;
4404 DirToks.push_back(
Tok);
4410 std::optional<Token> NextPPTok =
4411 DirToks.back().is(tok::eod) ? peekNextPPToken() : DirToks.back();
4416 if (NextPPTok->is(tok::raw_identifier))
4418 if (!NextPPTok->isOneOf(tok::semi, tok::eod, tok::l_square,
4420 Diag(*NextPPTok, diag::err_pp_unexpected_tok_after_module_name)
4424 if (!DirToks.back().isOneOf(tok::semi, tok::eod)) {
4431 DirToks.back().isNot(tok::eod)
4435 : DirToks.pop_back_val().getLocation();
4437 if (!IncludeMacroStack.empty()) {
4438 Diag(StartLoc, diag::err_pp_module_decl_in_header)
4442 if (CurPPLexer->getConditionalStackDepth() != 0) {
4443 Diag(StartLoc, diag::err_pp_cond_span_module_decl)
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.
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers).
std::string Name
The name of this module.
bool isAvailable() const
Determine whether this module is available for use within the current translation unit.
bool isHeaderUnit() const
Is this module a header unit.
Module * ShadowingModule
A module with the same name that shadows this module.
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
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
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.