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::string_literal)) {
1642 Diag(StrTok, diag::err_pp_line_invalid_filename);
1646 Diag(StrTok, diag::err_invalid_string_udl);
1651 StringLiteralParser
Literal(StrTok, *
this,
1653 assert(
Literal.isOrdinary() &&
"Didn't allow wide strings in");
1659 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1663 FilenameID = SourceMgr.getLineTableFilenameID(
Literal.GetString());
1676 SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1678 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID,
false,
1682 Callbacks->FileChanged(CurPPLexer->getSourceLocation(),
1694 if (FlagTok.
is(tok::eod))
return false;
1695 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1702 if (FlagTok.
is(tok::eod))
return false;
1703 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1705 }
else if (FlagVal == 2) {
1721 SM.getDecomposedExpansionLoc(IncLoc).first != CurFileID) {
1722 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);
1728 if (FlagTok.
is(tok::eod))
return false;
1729 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;
1744 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1749 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1757 if (FlagTok.
is(tok::eod))
return false;
1760 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1772void Preprocessor::HandleDigitDirective(
Token &DigitTok) {
1776 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
1783 bool IsFileEntry =
false, IsFileExit =
false;
1784 int FilenameID = -1;
1789 if (StrTok.
is(tok::eod)) {
1790 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1792 FileKind = SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1793 }
else if (StrTok.
isNot(tok::string_literal)) {
1794 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1798 Diag(StrTok, diag::err_invalid_string_udl);
1803 StringLiteralParser
Literal(StrTok, *
this,
1805 assert(
Literal.isOrdinary() &&
"Didn't allow wide strings in");
1811 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1819 if (!SourceMgr.isInPredefinedFile(DigitTok.
getLocation()))
1820 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1824 if (!(IsFileExit &&
Literal.GetString().empty()))
1825 FilenameID = SourceMgr.getLineTableFilenameID(
Literal.GetString());
1829 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID, IsFileEntry,
1830 IsFileExit, FileKind);
1839 else if (IsFileExit)
1842 Callbacks->FileChanged(CurPPLexer->getSourceLocation(), Reason, FileKind);
1848void Preprocessor::HandleUserDiagnosticDirective(
Token &
Tok,
1856 CurLexer->ReadToEndOfLine(&Message);
1860 StringRef Msg =
Message.str().ltrim(
' ');
1863 Diag(
Tok, diag::pp_hash_warning) << Msg;
1865 Diag(
Tok, diag::err_pp_hash_error) << Msg;
1870void Preprocessor::HandleIdentSCCSDirective(
Token &
Tok) {
1872 Diag(
Tok, diag::ext_pp_ident_directive);
1879 if (StrTok.
isNot(tok::string_literal) &&
1880 StrTok.
isNot(tok::wide_string_literal)) {
1881 Diag(StrTok, diag::err_pp_malformed_ident);
1882 if (StrTok.
isNot(tok::eod))
1888 Diag(StrTok, diag::err_invalid_string_udl);
1905void Preprocessor::HandleMacroPublicDirective(
Token &
Tok) {
1907 ReadMacroName(MacroNameTok,
MU_Undef);
1910 if (MacroNameTok.
is(tok::eod))
1922 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1932void Preprocessor::HandleMacroPrivateDirective() {
1934 ReadMacroName(MacroNameTok,
MU_Undef);
1937 if (MacroNameTok.
is(tok::eod))
1949 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1969 StringRef &Buffer) {
1971 assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1983 if (Buffer[0] ==
'<') {
1984 if (Buffer.back() !=
'>') {
1985 Diag(Loc, diag::err_pp_expects_filename);
1986 Buffer = StringRef();
1990 }
else if (Buffer[0] ==
'"') {
1991 if (Buffer.back() !=
'"') {
1992 Diag(Loc, diag::err_pp_expects_filename);
1993 Buffer = StringRef();
1998 Diag(Loc, diag::err_pp_expects_filename);
1999 Buffer = StringRef();
2004 if (Buffer.size() <= 2) {
2005 Diag(Loc, diag::err_pp_empty_filename);
2006 Buffer = StringRef();
2011 Buffer = Buffer.substr(1, Buffer.size()-2);
2018 void *AnnotationVal) {
2021 auto Tok = std::make_unique<Token[]>(1);
2022 Tok[0].startToken();
2023 Tok[0].setKind(Kind);
2024 Tok[0].setLocation(Range.getBegin());
2025 Tok[0].setAnnotationEndLoc(Range.getEnd());
2026 Tok[0].setAnnotationValue(AnnotationVal);
2027 EnterTokenStream(std::move(
Tok), 1,
true,
false);
2037 for (
size_t I = 0, N = Path.size(); I != N; ++I) {
2040 PathString += Path[I].getIdentifierInfo()->getName();
2043 int IncludeKind = 0;
2045 case tok::pp_include:
2049 case tok::pp_import:
2053 case tok::pp_include_next:
2057 case tok::pp___include_macros:
2062 llvm_unreachable(
"unknown include directive kind");
2065 PP.
Diag(HashLoc, diag::remark_pp_include_directive_modular_translation)
2066 << IncludeKind << PathString;
2073 StringRef RealPathName,
2074 llvm::sys::path::Style Separator) {
2075 auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName);
2076 auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName);
2078 bool SuggestReplacement =
false;
2080 auto IsSep = [Separator](StringRef Component) {
2081 return Component.size() == 1 &&
2082 llvm::sys::path::is_separator(Component[0], Separator);
2087 for (
auto &Component : llvm::reverse(Components)) {
2088 if (
"." == Component) {
2089 }
else if (
".." == Component) {
2093 }
else if (RealPathComponentIter != RealPathComponentEnd) {
2094 if (!IsSep(Component) && !IsSep(*RealPathComponentIter) &&
2095 Component != *RealPathComponentIter) {
2099 SuggestReplacement =
2100 RealPathComponentIter->equals_insensitive(Component);
2101 if (!SuggestReplacement)
2103 Component = *RealPathComponentIter;
2105 ++RealPathComponentIter;
2108 return SuggestReplacement;
2117 Module *ShadowingModule =
nullptr;
2123 Diags.Report(MissingHeader.
FileNameLoc, diag::err_module_header_missing)
2125 }
else if (ShadowingModule) {
2128 diag::note_previous_definition);
2139std::pair<ConstSearchDirIterator, const FileEntry *>
2140Preprocessor::getIncludeNextStart(
const Token &IncludeNextTok)
const {
2145 const FileEntry *LookupFromFile =
nullptr;
2153 Diag(IncludeNextTok, diag::pp_include_next_in_primary);
2154 }
else if (CurLexerSubmodule) {
2157 assert(CurPPLexer &&
"#include_next directive in macro?");
2158 if (
auto FE = CurPPLexer->getFileEntry())
2159 LookupFromFile = *FE;
2161 }
else if (!Lookup) {
2166 Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
2172 return {Lookup, LookupFromFile};
2188 if (FilenameTok.
isNot(tok::header_name)) {
2189 if (FilenameTok.
is(tok::identifier) &&
2190 (PPOpts.SingleFileParseMode || PPOpts.SingleModuleParseMode)) {
2200 if (FilenameTok.
isNot(tok::eod))
2209 SourceLocation EndLoc =
2212 auto Action = HandleHeaderIncludeOrImport(HashLoc, IncludeTok, FilenameTok,
2213 EndLoc, LookupFrom, LookupFromFile);
2214 switch (Action.Kind) {
2215 case ImportAction::None:
2216 case ImportAction::SkippedModuleImport:
2218 case ImportAction::ModuleBegin:
2220 tok::annot_module_begin, Action.ModuleForHeader);
2222 case ImportAction::HeaderUnitImport:
2224 Action.ModuleForHeader);
2226 case ImportAction::ModuleImport:
2228 tok::annot_module_include, Action.ModuleForHeader);
2230 case ImportAction::Failure:
2231 assert(TheModuleLoader.HadFatalFailure &&
2232 "This should be an early exit only to a fatal error");
2233 TheModuleLoader.HadFatalFailure =
true;
2235 CurLexer->cutOffLexing();
2243 const Token &FilenameTok,
bool &IsFrameworkFound,
bool IsImportDecl,
2245 const FileEntry *LookupFromFile, StringRef &LookupFilename,
2248 auto DiagnoseHeaderInclusion = [&](FileEntryRef FE) {
2249 if (LangOpts.AsmPreprocessor)
2253 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
2254 bool RequestingModuleIsModuleInterface =
2255 !SourceMgr.isInMainFile(FilenameLoc);
2257 HeaderInfo.getModuleMap().diagnoseHeaderInclusion(
2258 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
2263 FilenameLoc, LookupFilename, isAngled, LookupFrom, LookupFromFile, CurDir,
2264 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2265 &SuggestedModule, &IsMapped, &IsFrameworkFound);
2267 DiagnoseHeaderInclusion(*
File);
2272 if (Callbacks && Callbacks->FileNotFound(Filename))
2273 return std::nullopt;
2275 if (SuppressIncludeNotFoundError)
2276 return std::nullopt;
2283 FilenameLoc, LookupFilename,
false, LookupFrom, LookupFromFile, CurDir,
2284 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2285 &SuggestedModule, &IsMapped,
2288 DiagnoseHeaderInclusion(*
File);
2289 Diag(FilenameTok, diag::err_pp_file_not_found_angled_include_not_fatal)
2290 << Filename << IsImportDecl
2292 "\"" + Filename.str() +
"\"");
2299 StringRef OriginalFilename = Filename;
2300 if (LangOpts.SpellChecking) {
2303 auto CorrectTypoFilename = [](llvm::StringRef Filename) {
2306 Filename = Filename.drop_back();
2310 StringRef TypoCorrectionName = CorrectTypoFilename(Filename);
2311 StringRef TypoCorrectionLookupName = CorrectTypoFilename(LookupFilename);
2314 FilenameLoc, TypoCorrectionLookupName, isAngled, LookupFrom,
2315 LookupFromFile, CurDir, Callbacks ? &SearchPath :
nullptr,
2316 Callbacks ? &RelativePath :
nullptr, &SuggestedModule, &IsMapped,
2319 DiagnoseHeaderInclusion(*
File);
2322 FilenameRange,
"<" + TypoCorrectionName.str() +
">")
2323 : FixItHint::CreateReplacement(
2324 FilenameRange,
"\"" + TypoCorrectionName.str() +
"\"");
2325 Diag(FilenameTok, diag::err_pp_file_not_found_typo_not_fatal)
2326 << OriginalFilename << TypoCorrectionName << Hint;
2329 Filename = TypoCorrectionName;
2330 LookupFilename = TypoCorrectionLookupName;
2336 assert(!
File &&
"expected missing file");
2337 Diag(FilenameTok, diag::err_pp_file_not_found)
2338 << OriginalFilename << FilenameRange;
2339 if (IsFrameworkFound) {
2340 size_t SlashPos = OriginalFilename.find(
'/');
2341 assert(SlashPos != StringRef::npos &&
2342 "Include with framework name should have '/' in the filename");
2343 StringRef FrameworkName = OriginalFilename.substr(0, SlashPos);
2344 FrameworkCacheEntry &CacheEntry =
2345 HeaderInfo.LookupFrameworkCache(FrameworkName);
2346 assert(CacheEntry.
Directory &&
"Found framework should be in cache");
2347 Diag(FilenameTok, diag::note_pp_framework_without_header)
2348 << OriginalFilename.substr(SlashPos + 1) << FrameworkName
2352 return std::nullopt;
2367Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
2371 SmallString<128> FilenameBuffer;
2372 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
2373 SourceLocation CharEnd = FilenameTok.
getEndLoc();
2375 CharSourceRange FilenameRange
2377 StringRef OriginalFilename = Filename;
2383 if (Filename.empty())
2384 return {ImportAction::None};
2385 if (Filename.ends_with(
' ') || Filename.ends_with(
'.')) {
2386 unsigned Selection = Filename.ends_with(
'.') ? 1 : 0;
2387 Diag(FilenameTok, diag::pp_nonportable_path_trailing)
2388 << Filename << Selection;
2391 bool IsImportDecl = HashLoc.
isInvalid();
2392 SourceLocation StartLoc = IsImportDecl ? IncludeTok.
getLocation() : HashLoc;
2395 if (PragmaARCCFCodeAuditedInfo.getLoc().isValid()) {
2396 Diag(StartLoc, diag::err_pp_include_in_arc_cf_code_audited) << IsImportDecl;
2397 Diag(PragmaARCCFCodeAuditedInfo.getLoc(), diag::note_pragma_entered_here);
2400 PragmaARCCFCodeAuditedInfo = IdentifierLoc();
2404 if (PragmaAssumeNonNullLoc.isValid()) {
2405 Diag(StartLoc, diag::err_pp_include_in_assume_nonnull) << IsImportDecl;
2406 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
2409 PragmaAssumeNonNullLoc = SourceLocation();
2412 if (HeaderInfo.HasIncludeAliasMap()) {
2416 StringRef NewName = HeaderInfo.MapHeaderToIncludeAlias(OriginalFilename);
2417 if (!NewName.empty())
2422 bool IsMapped =
false;
2423 bool IsFrameworkFound =
false;
2425 SmallString<1024> SearchPath;
2426 SmallString<1024> RelativePath;
2429 ModuleMap::KnownHeader SuggestedModule;
2430 SourceLocation FilenameLoc = FilenameTok.
getLocation();
2431 StringRef LookupFilename = Filename;
2435 SmallString<128> NormalizedPath;
2436 llvm::sys::path::Style BackslashStyle = llvm::sys::path::Style::native;
2437 if (is_style_posix(BackslashStyle) && LangOpts.MicrosoftExt) {
2438 NormalizedPath = Filename.str();
2439 llvm::sys::path::native(NormalizedPath);
2440 LookupFilename = NormalizedPath;
2441 BackslashStyle = llvm::sys::path::Style::windows;
2445 &CurDir, Filename, FilenameLoc, FilenameRange, FilenameTok,
2446 IsFrameworkFound, IsImportDecl, IsMapped, LookupFrom, LookupFromFile,
2447 LookupFilename, RelativePath, SearchPath, SuggestedModule, isAngled);
2451 SkippingUntilPCHThroughHeader =
false;
2452 return {ImportAction::None};
2470 enum { Enter,
Import,
Skip, IncludeLimitReached } Action = Enter;
2472 if (PPOpts.SingleFileParseMode)
2473 Action = IncludeLimitReached;
2478 if (Action == Enter && HasReachedMaxIncludeDepth &&
File &&
2480 Action = IncludeLimitReached;
2487 bool MaybeTranslateInclude = Action == Enter &&
File && ModuleToImport &&
2491 bool UsableHeaderUnit =
false;
2492 if (
getLangOpts().CPlusPlusModules && ModuleToImport &&
2494 if (TrackGMFState.inGMF() || IsImportDecl)
2495 UsableHeaderUnit =
true;
2496 else if (!IsImportDecl) {
2498 ModuleToImport =
nullptr;
2502 bool UsableClangHeaderModule =
2509 if (MaybeTranslateInclude && (UsableHeaderUnit || UsableClangHeaderModule)) {
2517 diag::note_implicit_top_level_module_import_here)
2519 return {ImportAction::None};
2525 SmallVector<IdentifierLoc, 2> Path;
2526 for (
Module *Mod = ModuleToImport; Mod; Mod = Mod->Parent)
2529 std::reverse(Path.begin(), Path.end());
2539 ModuleLoadResult Imported = TheModuleLoader.loadModule(
2542 assert((Imported ==
nullptr || Imported == ModuleToImport) &&
2543 "the imported module is different than the suggested one");
2549 static_cast<Module *
>(Imported)->getTopLevelModule());
2554 ModuleToImport =
nullptr;
2562 Token &
Result = IncludeTok;
2563 assert(CurLexer &&
"#include but no current lexer set!");
2565 CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
2566 CurLexer->cutOffLexing();
2568 return {ImportAction::None};
2576 SourceMgr.getFileCharacteristic(FilenameTok.
getLocation());
2578 FileCharacter = std::max(HeaderInfo.getFileDirFlavor(*
File), FileCharacter);
2589 bool IsFirstIncludeOfFile =
false;
2593 if (Action == Enter &&
File &&
2594 !HeaderInfo.ShouldEnterIncludeFile(*
this, *
File, EnterOnce,
2596 IsFirstIncludeOfFile)) {
2607 if (UsableHeaderUnit && !
getLangOpts().CompilingPCH)
2608 Action = TrackGMFState.inGMF() ?
Import :
Skip;
2610 Action = (ModuleToImport && !
getLangOpts().CompilingPCH) ? Import :
Skip;
2618 if (Action == Enter &&
File && PreambleConditionalStack.isRecording() &&
2619 SourceMgr.isMainFile(
File->getFileEntry())) {
2621 diag::err_pp_including_mainfile_in_preamble);
2622 return {ImportAction::None};
2625 if (Callbacks && !IsImportDecl) {
2628 Callbacks->InclusionDirective(HashLoc, IncludeTok, LookupFilename, isAngled,
2629 FilenameRange,
File, SearchPath, RelativePath,
2630 SuggestedModule.
getModule(), Action == Import,
2633 Callbacks->FileSkipped(*
File, FilenameTok, FileCharacter);
2637 return {ImportAction::None};
2641 if (IsImportDecl && !ModuleToImport) {
2642 Diag(FilenameTok, diag::err_header_import_not_header_unit)
2643 << OriginalFilename <<
File->getName();
2644 return {ImportAction::None};
2649 const bool CheckIncludePathPortability =
2650 !IsMapped && !
File->getFileEntry().tryGetRealPathName().empty();
2652 if (CheckIncludePathPortability) {
2653 StringRef Name = LookupFilename;
2654 StringRef NameWithoriginalSlashes = Filename;
2658 bool NameWasUNC = Name.consume_front(
"\\\\?\\");
2659 NameWithoriginalSlashes.consume_front(
"\\\\?\\");
2661 StringRef RealPathName =
File->getFileEntry().tryGetRealPathName();
2662 SmallVector<StringRef, 16> Components(llvm::sys::path::begin(Name),
2663 llvm::sys::path::end(Name));
2675 SmallString<128> FixedDriveRealPath;
2676 if (llvm::sys::path::is_absolute(Name) &&
2677 llvm::sys::path::is_absolute(RealPathName) &&
2680 assert(Components.size() >= 3 &&
"should have drive, backslash, name");
2681 assert(Components[0].size() == 2 &&
"should start with drive");
2682 assert(Components[0][1] ==
':' &&
"should have colon");
2683 FixedDriveRealPath = (Name.substr(0, 1) + RealPathName.substr(1)).str();
2684 RealPathName = FixedDriveRealPath;
2689 SmallString<128> Path;
2690 Path.reserve(Name.size()+2);
2691 Path.push_back(isAngled ?
'<' :
'"');
2693 const auto IsSep = [BackslashStyle](
char c) {
2694 return llvm::sys::path::is_separator(c, BackslashStyle);
2697 for (
auto Component : Components) {
2709 if (!(Component.size() == 1 && IsSep(Component[0])))
2710 Path.append(Component);
2711 else if (Path.size() != 1)
2715 if (Path.size() > NameWithoriginalSlashes.size()) {
2716 Path.push_back(isAngled ?
'>' :
'"');
2719 assert(IsSep(NameWithoriginalSlashes[Path.size()-1]));
2721 Path.push_back(NameWithoriginalSlashes[Path.size()-1]);
2722 while (Path.size() <= NameWithoriginalSlashes.size() &&
2723 IsSep(NameWithoriginalSlashes[Path.size()-1]));
2729 Path = (Path.substr(0, 1) +
"\\\\?\\" + Path.substr(1)).str();
2736 ? diag::pp_nonportable_path
2737 : diag::pp_nonportable_system_path;
2738 Diag(FilenameTok, DiagId) << Path <<
2742 bool SuppressBackslashDiag =
2744 Diags->isIgnored(diag::pp_nonportable_path_separator, FilenameLoc) ||
2747 SourceMgr.isWrittenInBuiltinFile(FilenameLoc) ||
2748 SourceMgr.isWrittenInModuleIncludes(FilenameLoc);
2749 if (!SuppressBackslashDiag && OriginalFilename.contains(
'\\')) {
2750 std::string SuggestedPath = OriginalFilename.str();
2751 llvm::replace(SuggestedPath,
'\\',
'/');
2752 Diag(FilenameTok, diag::pp_nonportable_path_separator)
2761 return {ImportAction::SkippedModuleImport, ModuleToImport};
2762 return {ImportAction::None};
2764 case IncludeLimitReached:
2767 return {ImportAction::None};
2771 assert(ModuleToImport &&
"no module to import");
2776 tok::pp___include_macros)
2777 return {ImportAction::None};
2779 return {ImportAction::ModuleImport, ModuleToImport};
2787 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
2788 Diag(FilenameTok, diag::err_pp_include_too_deep);
2789 HasReachedMaxIncludeDepth =
true;
2790 return {ImportAction::None};
2794 Diag(FilenameTok, diag::warn_pp_include_angled_in_module_purview)
2798 SourceLocation IncludePos = FilenameTok.
getLocation();
2802 IncludePos = SourceMgr.getExpansionRange(IncludePos).getEnd();
2803 FileID FID = SourceMgr.createFileID(*
File, IncludePos, FileCharacter);
2805 TheModuleLoader.HadFatalFailure =
true;
2806 return ImportAction::Failure;
2811 IsFirstIncludeOfFile))
2812 return {ImportAction::None};
2816 if (ModuleToImport && !ModuleToImport->
isHeaderUnit()) {
2821 diag::err_module_build_shadowed_submodule)
2824 diag::note_previous_definition);
2825 return {ImportAction::None};
2837 return {ImportAction::None};
2839 assert(!CurLexerSubmodule &&
"should not have marked this as a module yet");
2840 CurLexerSubmodule = ModuleToImport;
2850 return {ImportAction::ModuleBegin, ModuleToImport};
2853 assert(!IsImportDecl &&
"failed to diagnose missing module for import decl");
2854 return {ImportAction::None};
2859void Preprocessor::HandleIncludeNextDirective(
SourceLocation HashLoc,
2860 Token &IncludeNextTok) {
2861 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
2864 const FileEntry *LookupFromFile;
2865 std::tie(Lookup, LookupFromFile) = getIncludeNextStart(IncludeNextTok);
2867 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
2872void Preprocessor::HandleMicrosoftImportDirective(
Token &
Tok) {
2878 Diag(
Tok, diag::err_pp_import_directive_ms );
2889 if (!LangOpts.ObjC) {
2890 if (LangOpts.MSVCCompat)
2891 return HandleMicrosoftImportDirective(ImportTok);
2892 Diag(ImportTok, diag::ext_pp_import_directive);
2894 return HandleIncludeDirective(HashLoc, ImportTok);
2901void Preprocessor::HandleIncludeMacrosDirective(
SourceLocation HashLoc,
2902 Token &IncludeMacrosTok) {
2905 SourceLocation Loc = IncludeMacrosTok.
getLocation();
2906 if (SourceMgr.getBufferName(Loc) !=
"<built-in>") {
2908 diag::pp_include_macros_out_of_predefines);
2915 HandleIncludeDirective(HashLoc, IncludeMacrosTok);
2920 assert(TmpTok.
isNot(tok::eof) &&
"Didn't find end of -imacros!");
2921 }
while (TmpTok.
isNot(tok::hashhash));
2943 Diag(
Tok, diag::err_pp_expected_ident_in_arg_list);
2947 Diag(
Tok, LangOpts.CPlusPlus11 ?
2948 diag::warn_cxx98_compat_variadic_macro :
2949 diag::ext_variadic_macro);
2952 if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus) {
2953 Diag(
Tok, diag::ext_pp_opencl_variadic_macros);
2959 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2968 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2976 Diag(
Tok, diag::err_pp_invalid_tok_in_arg_list);
2982 if (llvm::is_contained(Parameters, II)) {
2983 Diag(
Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
2995 Diag(
Tok, diag::err_pp_expected_comma_in_arg_list);
3004 Diag(
Tok, diag::ext_named_variadic_macro);
3009 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
3039 StringRef ValueText = II->
getName();
3040 StringRef TrimmedValue = ValueText;
3041 if (!ValueText.starts_with(
"__")) {
3042 if (ValueText.starts_with(
"_"))
3043 TrimmedValue = TrimmedValue.drop_front(1);
3047 TrimmedValue = TrimmedValue.drop_front(2);
3048 if (TrimmedValue.ends_with(
"__"))
3049 TrimmedValue = TrimmedValue.drop_back(2);
3051 return TrimmedValue == MacroText;
3058 return MacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
3071MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
3072 const Token &MacroNameTok,
const bool ImmediatelyAfterHeaderGuard) {
3074 Token LastTok = MacroNameTok;
3082 llvm::scope_exit _([&]() {
3084 if (CurLexer->ParsingPreprocessorDirective)
3095 if (
Tok.
is(tok::eod)) {
3096 if (ImmediatelyAfterHeaderGuard) {
3106 }
else if (
Tok.
is(tok::l_paren)) {
3109 if (ReadMacroParameterList(MI, LastTok))
3123 }
else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
3126 Diag(
Tok, diag::ext_c99_whitespace_required_after_macro_name);
3135 if (
Tok.
is(tok::at))
3137 else if (
Tok.
is(tok::unknown)) {
3144 Diag(
Tok, diag::ext_missing_whitespace_after_macro_name);
3146 Diag(
Tok, diag::warn_missing_whitespace_after_macro_name);
3149 if (!
Tok.
is(tok::eod))
3152 SmallVector<Token, 16> Tokens;
3159 Tokens.push_back(
Tok);
3173 if (!
Tok.
isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
3174 Tokens.push_back(
Tok);
3176 if (VAOCtx.isVAOptToken(
Tok)) {
3178 if (VAOCtx.isInVAOpt()) {
3179 Diag(
Tok, diag::err_pp_vaopt_nested_use);
3185 Diag(
Tok, diag::err_pp_missing_lparen_in_vaopt_use);
3188 Tokens.push_back(
Tok);
3191 if (
Tok.
is(tok::hashhash)) {
3192 Diag(
Tok, diag::err_vaopt_paste_at_start);
3196 }
else if (VAOCtx.isInVAOpt()) {
3197 if (
Tok.
is(tok::r_paren)) {
3198 if (VAOCtx.sawClosingParen()) {
3199 assert(Tokens.size() >= 3 &&
3200 "Must have seen at least __VA_OPT__( "
3201 "and a subsequent tok::r_paren");
3202 if (Tokens[Tokens.size() - 2].is(tok::hashhash)) {
3203 Diag(
Tok, diag::err_vaopt_paste_at_end);
3207 }
else if (
Tok.
is(tok::l_paren)) {
3221 Tokens.push_back(
Tok);
3228 if (
Tok.
is(tok::hashhash)) {
3236 if (
Tok.
is(tok::eod)) {
3237 Tokens.push_back(LastTok);
3242 Tokens[Tokens.size() - 1].is(tok::comma))
3246 Tokens.push_back(LastTok);
3255 if (!VAOCtx.isVAOptToken(
Tok) &&
3264 LastTok.
setKind(tok::unknown);
3265 Tokens.push_back(LastTok);
3268 Diag(
Tok, diag::err_pp_stringize_not_parameter)
3269 << LastTok.
is(tok::hashat);
3275 Tokens.push_back(LastTok);
3280 if (!VAOCtx.isVAOptToken(
Tok)) {
3281 Tokens.push_back(
Tok);
3288 if (VAOCtx.isInVAOpt()) {
3289 assert(
Tok.
is(tok::eod) &&
"Must be at End Of preprocessing Directive");
3290 Diag(
Tok, diag::err_pp_expected_after)
3291 << LastTok.
getKind() << tok::r_paren;
3292 Diag(VAOCtx.getUnmatchedOpeningParenLoc(), diag::note_matching) << tok::l_paren;
3303 return II->
isStr(
"__strong") || II->
isStr(
"__weak") ||
3304 II->
isStr(
"__unsafe_unretained") || II->
isStr(
"__autoreleasing");
3309void Preprocessor::HandleDefineDirective(
3310 Token &DefineTok,
const bool ImmediatelyAfterHeaderGuard) {
3314 bool MacroShadowsKeyword;
3315 ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
3318 if (MacroNameTok.
is(tok::eod))
3325 emitFinalMacroWarning(MacroNameTok,
false);
3329 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
3331 MacroInfo *
const MI = ReadOptionalMacroParameterListAndBody(
3332 MacroNameTok, ImmediatelyAfterHeaderGuard);
3336 if (MacroShadowsKeyword &&
3338 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
3343 if (NumTokens != 0) {
3355 if (SkippingUntilPCHThroughHeader) {
3358 LangOpts.MicrosoftExt))
3362 if (!LangOpts.MicrosoftExt)
3373 emitFinalMacroWarning(MacroNameTok,
false);
3384 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) &&
3386 LangOpts.MicrosoftExt)) {
3397 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) {
3405 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
3409 !MI->
isIdenticalTo(*OtherMI, *
this, LangOpts.MicrosoftExt)) {
3419 DefMacroDirective *MD =
3427 !MacroExpansionInDirectivesOverride &&
3436 Callbacks->MacroDefined(MacroNameTok, MD);
3441void Preprocessor::HandleUndefDirective() {
3445 ReadMacroName(MacroNameTok,
MU_Undef);
3448 if (MacroNameTok.
is(tok::eod))
3457 UndefMacroDirective *Undef =
nullptr;
3460 emitFinalMacroWarning(MacroNameTok,
true);
3470 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
3475 Undef = AllocateUndefMacroDirective(MacroNameTok.
getLocation());
3481 Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
3496void Preprocessor::HandleIfdefDirective(
Token &
Result,
3497 const Token &HashToken,
3499 bool ReadAnyTokensBeforeDirective) {
3501 Token DirectiveTok =
Result;
3504 ReadMacroName(MacroNameTok);
3507 if (MacroNameTok.
is(tok::eod)) {
3510 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3525 if (CurPPLexer->getConditionalStackDepth() == 0) {
3530 if (!ReadAnyTokensBeforeDirective && !MI) {
3531 assert(isIfndef &&
"#ifdef shouldn't reach here");
3532 CurPPLexer->MIOpt.EnterTopLevelIfndef(MII, MacroNameTok.
getLocation());
3534 CurPPLexer->MIOpt.EnterTopLevelConditional();
3543 Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3545 Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3548 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3552 if (PPOpts.SingleFileParseMode && !MI) {
3555 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3558 }
else if (PPOpts.SingleModuleParseMode && !MI) {
3562 SkipExcludedConditionalBlock(
3565 }
else if (!MI == isIfndef || RetainExcludedCB) {
3567 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3572 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3581void Preprocessor::HandleIfDirective(
Token &IfToken,
3582 const Token &HashToken,
3583 bool ReadAnyTokensBeforeDirective) {
3587 IdentifierInfo *IfNDefMacro =
nullptr;
3588 const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
3589 const bool ConditionalTrue = DER.Conditional;
3597 if (CurPPLexer->getConditionalStackDepth() == 0) {
3598 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
3600 CurPPLexer->MIOpt.EnterTopLevelIfndef(IfNDefMacro, IfToken.
getLocation());
3602 CurPPLexer->MIOpt.EnterTopLevelConditional();
3610 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3614 if (PPOpts.SingleFileParseMode && DER.IncludedUndefinedIds) {
3617 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3619 }
else if (PPOpts.SingleModuleParseMode && DER.IncludedUndefinedIds) {
3626 }
else if (ConditionalTrue || RetainExcludedCB) {
3628 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3640void Preprocessor::HandleEndifDirective(
Token &EndifToken) {
3646 PPConditionalInfo CondInfo;
3647 if (CurPPLexer->popConditionalLevel(CondInfo)) {
3649 Diag(EndifToken, diag::err_pp_endif_without_if);
3654 if (CurPPLexer->getConditionalStackDepth() == 0)
3655 CurPPLexer->MIOpt.ExitTopLevelConditional();
3657 assert(!CondInfo.
WasSkipping && !CurPPLexer->LexingRawMode &&
3658 "This code should only be reachable in the non-skipping case!");
3666void Preprocessor::HandleElseDirective(
Token &
Result,
const Token &HashToken) {
3672 PPConditionalInfo CI;
3673 if (CurPPLexer->popConditionalLevel(CI)) {
3679 if (CurPPLexer->getConditionalStackDepth() == 0)
3680 CurPPLexer->MIOpt.EnterTopLevelConditional();
3688 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3691 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3694 CurPPLexer->pushConditionalLevel(CI.
IfLoc,
false,
3702 true,
Result.getLocation());
3706void Preprocessor::HandleElifFamilyDirective(
Token &ElifToken,
3707 const Token &HashToken,
3719 if (LangOpts.CPlusPlus)
3720 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
3721 : diag::ext_cxx23_pp_directive;
3723 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
3724 : diag::ext_c23_pp_directive;
3725 Diag(ElifToken, DiagID) << DirKind;
3736 PPConditionalInfo CI;
3737 if (CurPPLexer->popConditionalLevel(CI)) {
3738 Diag(ElifToken, diag::pp_err_elif_without_if) << DirKind;
3743 if (CurPPLexer->getConditionalStackDepth() == 0)
3744 CurPPLexer->MIOpt.EnterTopLevelConditional();
3748 Diag(ElifToken, diag::pp_err_elif_after_else) << DirKind;
3753 Callbacks->Elif(ElifToken.
getLocation(), ConditionRange,
3756 case tok::pp_elifdef:
3759 case tok::pp_elifndef:
3763 assert(
false &&
"unexpected directive kind");
3768 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3771 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3774 CurPPLexer->pushConditionalLevel(ElifToken.
getLocation(),
false,
3780 SkipExcludedConditionalBlock(
3785std::optional<LexEmbedParametersResult>
3788 tok::TokenKind EndTokenKind = ForHasEmbed ? tok::r_paren : tok::eod;
3790 auto DiagMismatchedBracesAndSkipToEOD =
3792 std::pair<tok::TokenKind, SourceLocation> Matches) {
3794 Diag(Matches.second, diag::note_matching) << Matches.first;
3795 if (CurTok.
isNot(tok::eod))
3800 if (CurTok.
isNot(Kind)) {
3801 Diag(CurTok, diag::err_expected) << Kind;
3802 if (CurTok.
isNot(tok::eod))
3819 auto LexPPParameterName = [&]() -> std::optional<std::string> {
3822 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3823 return std::nullopt;
3830 if (CurTok.
is(tok::coloncolon)) {
3833 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3834 return std::nullopt;
3840 return (llvm::Twine(Prefix->
getName()) +
"::" + Suffix->
getName()).str();
3842 return Prefix->
getName().str();
3849 auto NormalizeParameterName = [](StringRef Name) {
3850 if (Name.size() > 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
3851 return Name.substr(2, Name.size() - 4);
3855 auto LexParenthesizedIntegerExpr = [&]() -> std::optional<size_t> {
3858 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3859 return std::nullopt;
3864 bool EvaluatedDefined;
3865 DirectiveEvalResult LimitEvalResult = EvaluateDirectiveExpression(
3866 ParameterIfNDef, CurTok, EvaluatedDefined,
false);
3868 if (!LimitEvalResult.Value) {
3871 assert(CurTok.
is(tok::eod) &&
"expect to be at the end of directive");
3872 return std::nullopt;
3875 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3876 return std::nullopt;
3883 if (EvaluatedDefined) {
3884 Diag(CurTok, diag::err_defined_in_pp_embed);
3885 return std::nullopt;
3888 if (LimitEvalResult.Value) {
3889 const llvm::APSInt &
Result = *LimitEvalResult.Value;
3890 if (
Result.isNegative()) {
3891 Diag(CurTok, diag::err_requires_positive_value)
3893 if (CurTok.
isNot(EndTokenKind))
3895 return std::nullopt;
3897 return Result.getLimitedValue();
3899 return std::nullopt;
3905 return tok::r_paren;
3907 return tok::r_brace;
3909 return tok::r_square;
3911 llvm_unreachable(
"should not get here");
3915 auto LexParenthesizedBalancedTokenSoup =
3917 std::vector<std::pair<tok::TokenKind, SourceLocation>> BracketStack;
3920 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3924 bool WaitingForInnerCloseParen =
false;
3925 while (CurTok.
isNot(tok::eod) &&
3926 (WaitingForInnerCloseParen || CurTok.
isNot(tok::r_paren))) {
3931 WaitingForInnerCloseParen =
true;
3938 WaitingForInnerCloseParen =
false;
3941 case tok::r_square: {
3942 if (BracketStack.empty()) {
3943 ExpectOrDiagAndSkipToEOD(tok::r_paren);
3947 GetMatchingCloseBracket(BracketStack.back().first);
3948 if (CurTok.
getKind() != Matching) {
3949 DiagMismatchedBracesAndSkipToEOD(Matching, BracketStack.back());
3952 BracketStack.pop_back();
3955 Tokens.push_back(CurTok);
3960 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3968 while (!CurTok.
isOneOf(EndTokenKind, tok::eod)) {
3970 std::optional<std::string> ParamName = LexPPParameterName();
3972 return std::nullopt;
3973 StringRef
Parameter = NormalizeParameterName(*ParamName);
3980 if (
Result.MaybeLimitParam)
3983 std::optional<size_t> Limit = LexParenthesizedIntegerExpr();
3985 return std::nullopt;
3988 }
else if (
Parameter ==
"clang::offset") {
3989 if (
Result.MaybeOffsetParam)
3992 std::optional<size_t> Offset = LexParenthesizedIntegerExpr();
3994 return std::nullopt;
3998 if (
Result.MaybePrefixParam)
4002 if (!LexParenthesizedBalancedTokenSoup(Soup))
4003 return std::nullopt;
4005 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
4007 if (
Result.MaybeSuffixParam)
4011 if (!LexParenthesizedBalancedTokenSoup(Soup))
4012 return std::nullopt;
4014 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
4016 if (
Result.MaybeIfEmptyParam)
4020 if (!LexParenthesizedBalancedTokenSoup(Soup))
4021 return std::nullopt;
4023 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
4025 ++
Result.UnrecognizedParams;
4029 if (CurTok.
is(tok::l_paren)) {
4031 if (!LexParenthesizedBalancedTokenSoup(Soup))
4032 return std::nullopt;
4035 Diag(ParamStartLoc, diag::err_pp_unknown_parameter) << 1 <<
Parameter;
4036 if (CurTok.
isNot(EndTokenKind))
4038 return std::nullopt;
4045void Preprocessor::HandleEmbedDirectiveImpl(
4047 StringRef BinaryContents, StringRef
FileName) {
4048 if (BinaryContents.empty()) {
4056 size_t TokCount = Toks.size();
4057 auto NewToks = std::make_unique<Token[]>(TokCount);
4058 llvm::copy(Toks, NewToks.get());
4059 EnterTokenStream(std::move(NewToks), TokCount,
true,
true);
4066 size_t TotalNumToks = 1 + NumPrefixToks + NumSuffixToks;
4068 auto Toks = std::make_unique<Token[]>(TotalNumToks);
4073 CurIdx += NumPrefixToks;
4076 EmbedAnnotationData *
Data =
new (BP) EmbedAnnotationData;
4077 Data->BinaryData = BinaryContents;
4080 Toks[CurIdx].startToken();
4081 Toks[CurIdx].setKind(tok::annot_embed);
4082 Toks[CurIdx].setAnnotationRange(HashLoc);
4083 Toks[CurIdx++].setAnnotationValue(
Data);
4088 CurIdx += NumSuffixToks;
4091 assert(CurIdx == TotalNumToks &&
"Calculated the incorrect number of tokens");
4092 EnterTokenStream(std::move(Toks), TotalNumToks,
true,
true);
4099 Diag(EmbedTok, diag::warn_compat_pp_embed_directive);
4101 Diag(EmbedTok, diag::ext_pp_embed_directive)
4102 << (LangOpts.CPlusPlus ? 1 : 0);
4109 if (FilenameTok.
isNot(tok::header_name)) {
4111 if (FilenameTok.
isNot(tok::eod))
4124 std::optional<LexEmbedParametersResult> Params =
4127 assert((Params || CurTok.
is(tok::eod)) &&
4128 "expected success or to be at the end of the directive");
4133 SmallString<128> FilenameBuffer;
4134 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
4135 StringRef OriginalFilename = Filename;
4141 if (Filename.empty())
4146 if (!MaybeFileRef) {
4148 if (Callbacks && Callbacks->EmbedFileNotFound(Filename)) {
4151 Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
4156 Diag(FilenameTok, diag::err_pp_embed_device_file) << Filename;
4160 std::optional<llvm::MemoryBufferRef> MaybeFile =
4164 Diag(FilenameTok, diag::err_cannot_open_file)
4165 << Filename <<
"a buffer to the contents could not be created";
4168 StringRef BinaryContents = MaybeFile->getBuffer();
4173 if (Params->MaybeOffsetParam) {
4178 BinaryContents = BinaryContents.substr(Params->MaybeOffsetParam->Offset);
4181 if (Params->MaybeLimitParam) {
4185 BinaryContents = BinaryContents.substr(0, Params->MaybeLimitParam->Limit);
4189 Callbacks->EmbedDirective(HashLoc, Filename, isAngled, MaybeFileRef,
4198 void *Mem = BP.Allocate(OriginalFilename.size(),
alignof(
char *));
4199 memcpy(Mem, OriginalFilename.data(), OriginalFilename.size());
4200 StringRef FilenameToGo =
4201 StringRef(
static_cast<char *
>(Mem), OriginalFilename.size());
4202 HandleEmbedDirectiveImpl(HashLoc, *Params, BinaryContents, FilenameToGo);
4215 assert(
getLangOpts().CPlusPlusModules && ImportTok.
is(tok::kw_import));
4217 this->ImportingCXXNamedModules,
true);
4221 if (
Tok.isNot(tok::eod))
4229 bool ImportingHeader =
false;
4230 bool IsPartition =
false;
4232 switch (
Tok.getKind()) {
4233 case tok::header_name:
4234 ImportingHeader =
true;
4235 DirToks.push_back(
Tok);
4236 Lex(DirToks.emplace_back());
4240 DirToks.push_back(
Tok);
4241 UseLoc =
Tok.getLocation();
4244 case tok::identifier: {
4246 Path, DirToks,
true,
4250 std::string FlatName;
4252 (IsPartition && ModuleDeclState.isNamedModule()) || !IsPartition;
4253 if (Callbacks && IsValid) {
4254 if (IsPartition && ModuleDeclState.isNamedModule()) {
4255 FlatName += ModuleDeclState.getPrimaryName();
4260 SourceLocation StartLoc = IsPartition ? UseLoc : Path[0].getLoc();
4272 DirToks.push_back(
Tok);
4278 if (!DirToks.back().isOneOf(tok::semi, tok::eod))
4281 if (DirToks.back().isNot(tok::eod))
4287 if (DirToks.back().isNot(tok::semi)) {
4292 if (ImportingHeader) {
4298 Diag(SemiLoc, diag::err_header_import_semi_in_macro);
4300 auto Action = HandleHeaderIncludeOrImport(
4302 switch (Action.Kind) {
4303 case ImportAction::None:
4306 case ImportAction::ModuleBegin:
4308 DirToks.emplace_back();
4309 DirToks.back().startToken();
4310 DirToks.back().setKind(tok::annot_module_begin);
4311 DirToks.back().setLocation(SemiLoc);
4312 DirToks.back().setAnnotationEndLoc(SemiLoc);
4313 DirToks.back().setAnnotationValue(Action.ModuleForHeader);
4316 case ImportAction::ModuleImport:
4317 case ImportAction::HeaderUnitImport:
4318 case ImportAction::SkippedModuleImport:
4321 DirToks[1].setKind(tok::annot_header_unit);
4322 DirToks[1].setAnnotationEndLoc(DirToks[0].getLocation());
4323 DirToks[1].setAnnotationValue(Action.ModuleForHeader);
4326 case ImportAction::Failure:
4327 assert(TheModuleLoader.HadFatalFailure &&
4328 "This should be an early exit only to a fatal error");
4329 CurLexer->cutOffLexing();
4358 assert(
getLangOpts().CPlusPlusModules && ModuleTok.
is(tok::kw_module));
4367 switch (
Tok.getKind()) {
4370 DirToks.push_back(
Tok);
4373 DirToks.push_back(
Tok);
4375 if (
Tok.isNot(tok::kw_private)) {
4376 if (
Tok.isNot(tok::eod))
4382 DirToks.push_back(
Tok);
4384 case tok::identifier: {
4386 Path, DirToks,
false,
4393 if (
Tok.is(tok::colon)) {
4396 Tok, Partition, DirToks,
4407 if (
Tok.is(tok::identifier) &&
4409 std::unique_ptr<Token[]> TokCopy = std::make_unique<Token[]>(1);
4411 EnterTokenStream(std::move(TokCopy), 1,
4414 DirToks.back() =
Tok;
4419 DirToks.push_back(
Tok);
4425 std::optional<Token> NextPPTok =
4426 DirToks.back().is(tok::eod) ? peekNextPPToken() : DirToks.back();
4431 if (NextPPTok->is(tok::raw_identifier))
4433 if (!NextPPTok->isOneOf(tok::semi, tok::eod, tok::l_square,
4435 Diag(*NextPPTok, diag::err_pp_unexpected_tok_after_module_name)
4439 if (!DirToks.back().isOneOf(tok::semi, tok::eod)) {
4446 DirToks.back().isNot(tok::eod)
4450 : DirToks.pop_back_val().getLocation();
4452 if (!IncludeMacroStack.empty()) {
4453 Diag(StartLoc, diag::err_pp_module_decl_in_header)
4457 if (CurPPLexer->getConditionalStackDepth() != 0) {
4458 Diag(StartLoc, diag::err_pp_cond_span_module_decl)
4476void Preprocessor::HandleObjCImportDirective(
Token &AtTok,
Token &ImportTok) {
4479 ImportTok.
setKind(tok::kw_import);
4494 if (!DirToks.back().isOneOf(tok::semi, tok::eod))
4498 DirToks.back().isNot(tok::eod)
4502 : DirToks.pop_back_val().getLocation();
4504 Module *Imported =
nullptr;
4513 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 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.
bool isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
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...
uint32_t Literal
Literals are represented as positive integers.
bool Sub(InterpState &S, CodePtr OpPC)
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
PPKeywordKind
Provides a namespace for preprocessor keywords which start with a '#' at the beginning of the line.
The JSON file list parser is used to communicate input to InstallAPI.
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.