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);
401 if (!SourceMgr.isInSystemHeader(MacroNameLoc) &&
402 !SourceMgr.isInPredefinedFile(MacroNameLoc)) {
417 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id);
419 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_attribute_id)
436void Preprocessor::ReadMacroName(
Token &MacroNameTok,
MacroUse isDefineUndef,
441 if (MacroNameTok.
is(tok::code_completion)) {
453 if (MacroNameTok.
isNot(tok::eod)) {
454 MacroNameTok.
setKind(tok::eod);
472 auto ReadNextTok = [
this, ExtraToks, &Tmp](
auto &&LexFn) {
473 std::invoke(LexFn,
this, Tmp);
474 if (ExtraToks && Tmp.
isNot(tok::eod))
475 ExtraToks->push_back(Tmp);
487 while (Tmp.
is(tok::comment))
490 if (Tmp.
is(tok::eod))
498 if ((LangOpts.GNUMode || LangOpts.C99 || LangOpts.CPlusPlus) &&
502 unsigned DiagID = diag::ext_pp_extra_tokens_at_eol;
505 (DirType ==
"import" || DirType ==
"module"))
506 DiagID = diag::warn_pp_extra_tokens_at_module_directive_eol;
508 Diag(Tmp, DiagID) << DirType << Hint;
512void Preprocessor::SuggestTypoedDirective(
const Token &
Tok,
513 StringRef Directive)
const {
518 std::vector<StringRef> Candidates = {
519 "if",
"ifdef",
"ifndef",
"elif",
"else",
"endif"
521 if (LangOpts.C23 || LangOpts.CPlusPlus23)
522 Candidates.insert(Candidates.end(), {
"elifdef",
"elifndef"});
526 assert(
Tok.getLocation().isFileID());
530 StringRef SuggValue = *Sugg;
533 Diag(
Tok, diag::warn_pp_invalid_directive) << 1 << SuggValue << Hint;
545void Preprocessor::SkipExcludedConditionalBlock(
SourceLocation HashTokenLoc,
547 bool FoundNonSkipPortion,
558 assert(!SkippingExcludedConditionalBlock &&
559 "calling SkipExcludedConditionalBlock recursively");
560 llvm::SaveAndRestore SARSkipping(SkippingExcludedConditionalBlock,
true);
563 assert(!CurTokenLexer &&
"Conditional PP block cannot appear in a macro!");
564 assert(CurPPLexer &&
"Conditional PP block must be in a file!");
565 assert(CurLexer &&
"Conditional PP block but no current lexer set!");
567 if (PreambleConditionalStack.reachedEOFWhileSkipping())
568 PreambleConditionalStack.clearSkipInfo();
570 CurPPLexer->pushConditionalLevel(IfTokenLoc,
false,
571 FoundNonSkipPortion, FoundElse);
575 CurPPLexer->LexingRawMode =
true;
577 SourceLocation endLoc;
581 struct SkippingRangeStateTy {
584 const char *BeginPtr =
nullptr;
585 unsigned *SkipRangePtr =
nullptr;
587 SkippingRangeStateTy(Preprocessor &PP) : PP(PP) {}
589 void beginLexPass() {
595 BeginPtr = PP.CurLexer->getBufferLocation();
596 SkipRangePtr = &PP.RecordedSkippedRanges[BeginPtr];
598 PP.CurLexer->seek(PP.CurLexer->getCurrentBufferOffset() + *SkipRangePtr,
603 void endLexPass(
const char *Hashptr) {
606 assert(PP.CurLexer->isDependencyDirectivesLexer());
611 if (!*SkipRangePtr) {
612 *SkipRangePtr = Hashptr - BeginPtr;
614 assert(*SkipRangePtr ==
unsigned(Hashptr - BeginPtr));
616 SkipRangePtr =
nullptr;
618 } SkippingRangeState(*
this);
621 if (CurLexer->isDependencyDirectivesLexer()) {
622 CurLexer->LexDependencyDirectiveTokenWhileSkipping(
Tok);
624 SkippingRangeState.beginLexPass();
628 if (
Tok.
is(tok::code_completion)) {
631 CodeComplete->CodeCompleteInConditionalExclusion();
644 Tok.
is(tok::raw_identifier) &&
647 llvm::SaveAndRestore ModuleDirectiveSkipping(LastExportKeyword);
648 LastExportKeyword.startToken();
655 if (
Tok.
is(tok::raw_identifier)) {
664 llvm::SaveAndRestore RestoreLexingRawMode(CurPPLexer->LexingRawMode,
671 CurPPLexer->ParsingPreprocessorDirective =
true;
674 Diag(StartLoc, diag::err_pp_cond_span_module_decl)
675 << SourceRange(StartLoc, End);
676 CurPPLexer->ParsingPreprocessorDirective =
false;
679 CurLexer->resetExtendedTokenMode();
686 if (
Tok.
is(tok::eof)) {
690 if (PreambleConditionalStack.isRecording())
691 PreambleConditionalStack.SkipInfo.emplace(HashTokenLoc, IfTokenLoc,
704 if (
Tok.
is(tok::eof))
710 CurPPLexer->ParsingPreprocessorDirective =
true;
711 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
713 assert(
Tok.
is(tok::hash));
714 const char *Hashptr = CurLexer->getBufferLocation() -
Tok.
getLength();
715 assert(CurLexer->getSourceLocation(Hashptr) ==
Tok.
getLocation());
722 if (
Tok.
isNot(tok::raw_identifier)) {
723 CurPPLexer->ParsingPreprocessorDirective =
false;
725 if (CurLexer) CurLexer->resetExtendedTokenMode();
736 char FirstChar = RI[0];
737 if (FirstChar >=
'a' && FirstChar <=
'z' &&
738 FirstChar !=
'i' && FirstChar !=
'e') {
739 CurPPLexer->ParsingPreprocessorDirective =
false;
741 if (CurLexer) CurLexer->resetExtendedTokenMode();
748 char DirectiveBuf[20];
754 size_t IdLen = DirectiveStr.size();
756 CurPPLexer->ParsingPreprocessorDirective =
false;
758 if (CurLexer) CurLexer->resetExtendedTokenMode();
761 memcpy(DirectiveBuf, &DirectiveStr[0], IdLen);
762 Directive = StringRef(DirectiveBuf, IdLen);
782 PPConditionalInfo CondInfo;
784 bool InCond = CurPPLexer->popConditionalLevel(CondInfo);
786 assert(!InCond &&
"Can't be skipping if not in a conditional!");
790 SkippingRangeState.endLexPass(Hashptr);
793 CurPPLexer->LexingRawMode =
false;
795 CurPPLexer->LexingRawMode =
true;
802 }
else if (Sub ==
"lse") {
806 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
809 SkippingRangeState.endLexPass(Hashptr);
813 Diag(
Tok, diag::pp_err_else_after_else);
824 CurPPLexer->LexingRawMode =
false;
826 CurPPLexer->LexingRawMode =
true;
833 }
else if (Sub ==
"lif") {
834 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
837 SkippingRangeState.endLexPass(Hashptr);
854 assert(CurPPLexer->LexingRawMode &&
"We have to be skipping here!");
855 CurPPLexer->LexingRawMode =
false;
856 IdentifierInfo *IfNDefMacro =
nullptr;
857 DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
861 const bool CondValue = DER.Conditional;
862 CurPPLexer->LexingRawMode =
true;
875 }
else if (Sub ==
"lifdef" ||
877 bool IsElifDef =
Sub ==
"lifdef";
878 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
879 Token DirectiveToken =
Tok;
882 SkippingRangeState.endLexPass(Hashptr);
887 if (LangOpts.CPlusPlus)
888 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
889 : diag::ext_cxx23_pp_directive;
891 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
892 : diag::ext_c23_pp_directive;
897 Diag(
Tok, diag::pp_err_elif_after_else)
911 assert(CurPPLexer->LexingRawMode &&
"We have to be skipping here!");
912 CurPPLexer->LexingRawMode =
false;
914 ReadMacroName(MacroNameTok);
915 CurPPLexer->LexingRawMode =
true;
919 if (MacroNameTok.
is(tok::eod)) {
931 MacroInfo *MI = MD.getMacroInfo();
935 Callbacks->Elifdef(DirectiveToken.
getLocation(), MacroNameTok,
938 Callbacks->Elifndef(DirectiveToken.
getLocation(), MacroNameTok,
943 if (
static_cast<bool>(MI) == IsElifDef) {
955 CurPPLexer->ParsingPreprocessorDirective =
false;
957 if (CurLexer) CurLexer->resetExtendedTokenMode();
963 CurPPLexer->LexingRawMode =
false;
968 Callbacks->SourceRangeSkipped(
969 SourceRange(HashTokenLoc, endLoc.
isValid()
971 : CurPPLexer->getSourceLocation()),
977 if (!SourceMgr.isInMainFile(Loc)) {
980 FileID IDOfIncl = SourceMgr.getFileID(SourceMgr.getExpansionLoc(Loc));
981 if (
auto EntryOfIncl = SourceMgr.getFileEntryRefForID(IDOfIncl)) {
983 return HeaderInfo.getModuleMap()
984 .findModuleForHeader(*EntryOfIncl, AllowTextual)
993 : HeaderInfo.lookupModule(
getLangOpts().CurrentModule, Loc);
1000 IncLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
1007 while (!Loc.
isInvalid() && !
SM.isInMainFile(Loc)) {
1008 auto ID =
SM.getFileID(
SM.getExpansionLoc(Loc));
1009 auto FE =
SM.getFileEntryRefForID(ID);
1015 HeaderInfo.hasModuleMap(FE->getName(),
nullptr,
1016 SourceMgr.isInSystemHeader(Loc));
1018 bool InPrivateHeader =
false;
1019 for (
auto Header : HeaderInfo.findAllModulesForHeader(*FE)) {
1020 if (!Header.isAccessibleFrom(IncM)) {
1025 InPrivateHeader =
true;
1042 return std::nullopt;
1052 if (InPrivateHeader)
1053 return std::nullopt;
1061 Loc =
SM.getIncludeLoc(ID);
1064 return std::nullopt;
1073 bool *IsFrameworkFound,
bool SkipCache,
bool OpenFile,
bool CacheFailures) {
1078 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
1083 bool BuildSystemModule =
false;
1084 if (!FromDir && !FromFile) {
1101 if (FID == SourceMgr.getMainFileID() && MainFileDir) {
1103 HeaderInfo.getModuleMap().shouldImportRelativeToBuiltinIncludeDir(
1105 ? HeaderInfo.getModuleMap().getBuiltinDir()
1107 Includers.push_back(std::make_pair(std::nullopt, *IncludeDir));
1109 }
else if ((FileEnt = SourceMgr.getFileEntryRefForID(
1110 SourceMgr.getMainFileID()))) {
1111 auto CWD = FileMgr.getOptionalDirectoryRef(
".");
1112 Includers.push_back(std::make_pair(*FileEnt, *CWD));
1115 Includers.push_back(std::make_pair(*FileEnt, FileEnt->
getDir()));
1121 if (LangOpts.MSVCCompat && !isAngled) {
1122 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1123 if (IsFileLexer(ISEntry))
1125 Includers.push_back(std::make_pair(*FileEnt, FileEnt->
getDir()));
1130 CurDir = CurDirLookup;
1138 Filename, FilenameLoc, isAngled, TmpFromDir, &TmpCurDir,
1139 Includers, SearchPath, RelativePath, RequestingModule,
1140 SuggestedModule,
nullptr,
1141 nullptr, SkipCache)) {
1143 TmpFromDir = TmpCurDir;
1145 if (&FE->getFileEntry() == FromFile) {
1147 FromDir = TmpFromDir;
1156 Filename, FilenameLoc, isAngled, FromDir, &CurDir, Includers, SearchPath,
1157 RelativePath, RequestingModule, SuggestedModule, IsMapped,
1158 IsFrameworkFound, SkipCache, BuildSystemModule, OpenFile, CacheFailures);
1166 if (IsFileLexer()) {
1169 Filename, *CurFileEnt, SearchPath, RelativePath, RequestingModule,
1176 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1177 if (IsFileLexer(ISEntry)) {
1178 if ((CurFileEnt = ISEntry.ThePPLexer->
getFileEntry())) {
1180 Filename, *CurFileEnt, SearchPath, RelativePath,
1181 RequestingModule, SuggestedModule)) {
1189 return std::nullopt;
1196 if (llvm::sys::path::is_absolute(Filename)) {
1199 Filename, OpenFile,
true,
false);
1200 return llvm::expectedToOptional(std::move(ShouldBeEntry));
1204 StringRef StartingFrom, StringRef
FileName,
1205 bool RemoveInitialFileComponentFromLookupPath) {
1206 llvm::sys::path::native(StartingFrom, LookupPath);
1207 if (RemoveInitialFileComponentFromLookupPath)
1208 llvm::sys::path::remove_filename(LookupPath);
1209 if (!LookupPath.empty() &&
1210 !llvm::sys::path::is_separator(LookupPath.back())) {
1211 LookupPath.push_back(llvm::sys::path::get_separator().front());
1221 if (LookupFromFile) {
1225 llvm::sys::path::append(TmpDir, Filename);
1226 if (!TmpDir.empty()) {
1228 TmpDir, OpenFile,
true,
false);
1230 return llvm::expectedToOptional(std::move(ShouldBeEntry));
1231 llvm::consumeError(ShouldBeEntry.takeError());
1238 if (MaybeWorkingDirEntry) {
1240 StringRef WorkingDir = WorkingDirEntry.
getName();
1241 if (!WorkingDir.empty()) {
1242 SeparateComponents(LookupPath, WorkingDir, Filename,
false);
1244 LookupPath, OpenFile,
true,
false);
1246 return llvm::expectedToOptional(std::move(ShouldBeEntry));
1247 llvm::consumeError(ShouldBeEntry.takeError());
1252 for (
const auto &Entry : PPOpts.EmbedEntries) {
1254 SeparateComponents(LookupPath, Entry, Filename,
false);
1256 LookupPath, OpenFile,
true,
false);
1258 return llvm::expectedToOptional(std::move(ShouldBeEntry));
1259 llvm::consumeError(ShouldBeEntry.takeError());
1261 return std::nullopt;
1271 : PP(pp), save(pp->DisableMacroExpansion) {
1272 if (pp->MacroExpansionInDirectivesOverride)
1273 pp->DisableMacroExpansion =
false;
1277 PP->DisableMacroExpansion = save;
1295 return HandleDefineDirective(
Result,
1298 if (SkippingUntilPCHThroughHeader &&
1300 return HandleIncludeDirective(HashLoc,
Result);
1302 if (SkippingUntilPragmaHdrStop && II->
getPPKeywordID() == tok::pp_pragma) {
1304 auto *II =
Result.getIdentifierInfo();
1305 if (II && II->
getName() ==
"hdrstop")
1322 CurPPLexer->ParsingPreprocessorDirective =
true;
1323 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
1325 bool ImmediatelyAfterTopLevelIfndef =
1326 CurPPLexer->MIOpt.getImmediatelyAfterTopLevelIfndef();
1327 CurPPLexer->MIOpt.resetImmediatelyAfterTopLevelIfndef();
1334 bool ReadAnyTokensBeforeDirective =CurPPLexer->MIOpt.getHasReadAnyTokensVal();
1342 if (Introducer.
isOneOf(tok::hash, tok::at))
1356 case tok::pp_include:
1357 case tok::pp_import:
1358 case tok::pp_include_next:
1359 case tok::pp___include_macros:
1360 case tok::pp_pragma:
1362 case tok::pp_module:
1363 case tok::pp___preprocessed_module:
1364 case tok::pp___preprocessed_import:
1366 << Introducer.
is(tok::hash) << II->
getName();
1367 Diag(*ArgMacro, diag::note_macro_expansion_here)
1368 << ArgMacro->getIdentifierInfo();
1382 if (SkippingUntilPCHThroughHeader || SkippingUntilPragmaHdrStop)
1386 switch (
Result.getKind()) {
1391 CurPPLexer->MIOpt.SetReadToken(ReadAnyTokensBeforeDirective);
1393 case tok::code_completion:
1396 CodeComplete->CodeCompleteDirective(
1397 CurPPLexer->getConditionalStackDepth() > 0);
1399 case tok::numeric_constant:
1406 return HandleDigitDirective(
Result);
1416 return HandleIfDirective(
Result, Introducer,
1417 ReadAnyTokensBeforeDirective);
1419 return HandleIfdefDirective(
Result, Introducer,
false,
1421 case tok::pp_ifndef:
1422 return HandleIfdefDirective(
Result, Introducer,
true,
1423 ReadAnyTokensBeforeDirective);
1425 case tok::pp_elifdef:
1426 case tok::pp_elifndef:
1427 return HandleElifFamilyDirective(
Result, Introducer,
1431 return HandleElseDirective(
Result, Introducer);
1433 return HandleEndifDirective(
Result);
1436 case tok::pp_include:
1439 case tok::pp___include_macros:
1444 case tok::pp_define:
1445 return HandleDefineDirective(
Result, ImmediatelyAfterTopLevelIfndef);
1447 return HandleUndefDirective();
1451 return HandleLineDirective();
1455 return HandleUserDiagnosticDirective(
Result,
false);
1458 case tok::pp_pragma:
1460 case tok::pp_module:
1461 case tok::pp___preprocessed_module:
1463 case tok::pp___preprocessed_import:
1466 case tok::pp_import:
1467 switch (Introducer.
getKind()) {
1471 return HandleObjCImportDirective(Introducer,
Result);
1472 case tok::kw_import:
1475 llvm_unreachable(
"not a valid import directive");
1477 case tok::pp_include_next:
1480 case tok::pp_warning:
1481 if (LangOpts.CPlusPlus)
1483 ? diag::warn_cxx23_compat_warning_directive
1484 : diag::ext_pp_warning_directive)
1487 Diag(
Result, LangOpts.C23 ? diag::warn_c23_compat_warning_directive
1488 : diag::ext_pp_warning_directive)
1491 return HandleUserDiagnosticDirective(
Result,
true);
1493 return HandleIdentSCCSDirective(
Result);
1495 return HandleIdentSCCSDirective(
Result);
1498 case tok::pp_assert:
1501 case tok::pp_unassert:
1505 case tok::pp___public_macro:
1507 return HandleMacroPublicDirective(
Result);
1510 case tok::pp___private_macro:
1512 return HandleMacroPrivateDirective();
1523 auto Toks = std::make_unique<Token[]>(2);
1525 Toks[0] = Introducer;
1530 if (
Result.is(tok::hashhash))
1531 Toks[1].setKind(tok::unknown);
1536 EnterTokenStream(std::move(Toks), 2,
false,
false);
1542 Diag(
Result, diag::err_pp_invalid_directive) << 0;
1554 bool IsGNULineDirective=
false) {
1555 if (DigitTok.
isNot(tok::numeric_constant)) {
1556 PP.
Diag(DigitTok, DiagID);
1558 if (DigitTok.
isNot(tok::eod))
1564 IntegerBuffer.resize(DigitTok.
getLength());
1565 const char *DigitTokBegin = &IntegerBuffer[0];
1575 for (
unsigned i = 0; i != ActualLength; ++i) {
1578 if (DigitTokBegin[i] ==
'\'')
1581 if (!
isDigit(DigitTokBegin[i])) {
1583 diag::err_pp_line_digit_sequence) << IsGNULineDirective;
1588 unsigned NextVal = Val*10+(DigitTokBegin[i]-
'0');
1589 if (NextVal < Val) {
1590 PP.
Diag(DigitTok, DiagID);
1597 if (DigitTokBegin[0] ==
'0' && Val)
1599 << IsGNULineDirective;
1611void Preprocessor::HandleLineDirective() {
1619 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*
this))
1623 Diag(DigitTok, diag::ext_pp_line_zero);
1627 unsigned LineLimit = 32768U;
1628 if (LangOpts.C99 || LangOpts.CPlusPlus11)
1629 LineLimit = 2147483648U;
1630 if (LineNo >= LineLimit)
1631 Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
1632 else if (LangOpts.CPlusPlus11 && LineNo >= 32768U)
1633 Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
1635 int FilenameID = -1;
1641 if (StrTok.
is(tok::eod))
1643 else if (StrTok.
isNot(tok::string_literal)) {
1644 Diag(StrTok, diag::err_pp_line_invalid_filename);
1648 Diag(StrTok, diag::err_invalid_string_udl);
1653 StringLiteralParser
Literal(StrTok, *
this);
1654 assert(
Literal.isOrdinary() &&
"Didn't allow wide strings in");
1660 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1664 FilenameID = SourceMgr.getLineTableFilenameID(
Literal.GetString());
1677 SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1679 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID,
false,
1683 Callbacks->FileChanged(CurPPLexer->getSourceLocation(),
1695 if (FlagTok.
is(tok::eod))
return false;
1696 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1703 if (FlagTok.
is(tok::eod))
return false;
1704 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1706 }
else if (FlagVal == 2) {
1722 SM.getDecomposedExpansionLoc(IncLoc).first != CurFileID) {
1723 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);
1729 if (FlagTok.
is(tok::eod))
return false;
1730 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1736 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1744 if (FlagTok.
is(tok::eod))
return false;
1745 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1750 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1758 if (FlagTok.
is(tok::eod))
return false;
1761 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1773void Preprocessor::HandleDigitDirective(
Token &DigitTok) {
1777 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
1784 bool IsFileEntry =
false, IsFileExit =
false;
1785 int FilenameID = -1;
1790 if (StrTok.
is(tok::eod)) {
1791 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1793 FileKind = SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1794 }
else if (StrTok.
isNot(tok::string_literal)) {
1795 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1799 Diag(StrTok, diag::err_invalid_string_udl);
1804 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};
2386 bool IsImportDecl = HashLoc.
isInvalid();
2387 SourceLocation StartLoc = IsImportDecl ? IncludeTok.
getLocation() : HashLoc;
2390 if (PragmaARCCFCodeAuditedInfo.getLoc().isValid()) {
2391 Diag(StartLoc, diag::err_pp_include_in_arc_cf_code_audited) << IsImportDecl;
2392 Diag(PragmaARCCFCodeAuditedInfo.getLoc(), diag::note_pragma_entered_here);
2395 PragmaARCCFCodeAuditedInfo = IdentifierLoc();
2399 if (PragmaAssumeNonNullLoc.isValid()) {
2400 Diag(StartLoc, diag::err_pp_include_in_assume_nonnull) << IsImportDecl;
2401 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
2404 PragmaAssumeNonNullLoc = SourceLocation();
2407 if (HeaderInfo.HasIncludeAliasMap()) {
2411 StringRef NewName = HeaderInfo.MapHeaderToIncludeAlias(OriginalFilename);
2412 if (!NewName.empty())
2417 bool IsMapped =
false;
2418 bool IsFrameworkFound =
false;
2420 SmallString<1024> SearchPath;
2421 SmallString<1024> RelativePath;
2424 ModuleMap::KnownHeader SuggestedModule;
2425 SourceLocation FilenameLoc = FilenameTok.
getLocation();
2426 StringRef LookupFilename = Filename;
2430 SmallString<128> NormalizedPath;
2431 llvm::sys::path::Style BackslashStyle = llvm::sys::path::Style::native;
2432 if (is_style_posix(BackslashStyle) && LangOpts.MicrosoftExt) {
2433 NormalizedPath = Filename.str();
2434 llvm::sys::path::native(NormalizedPath);
2435 LookupFilename = NormalizedPath;
2436 BackslashStyle = llvm::sys::path::Style::windows;
2440 &CurDir, Filename, FilenameLoc, FilenameRange, FilenameTok,
2441 IsFrameworkFound, IsImportDecl, IsMapped, LookupFrom, LookupFromFile,
2442 LookupFilename, RelativePath, SearchPath, SuggestedModule, isAngled);
2446 SkippingUntilPCHThroughHeader =
false;
2447 return {ImportAction::None};
2465 enum { Enter,
Import,
Skip, IncludeLimitReached } Action = Enter;
2467 if (PPOpts.SingleFileParseMode)
2468 Action = IncludeLimitReached;
2473 if (Action == Enter && HasReachedMaxIncludeDepth &&
File &&
2475 Action = IncludeLimitReached;
2482 bool MaybeTranslateInclude = Action == Enter &&
File && ModuleToImport &&
2486 bool UsableHeaderUnit =
false;
2487 if (
getLangOpts().CPlusPlusModules && ModuleToImport &&
2489 if (TrackGMFState.inGMF() || IsImportDecl)
2490 UsableHeaderUnit =
true;
2491 else if (!IsImportDecl) {
2493 ModuleToImport =
nullptr;
2497 bool UsableClangHeaderModule =
2504 if (MaybeTranslateInclude && (UsableHeaderUnit || UsableClangHeaderModule)) {
2512 diag::note_implicit_top_level_module_import_here)
2514 return {ImportAction::None};
2520 SmallVector<IdentifierLoc, 2> Path;
2521 for (
Module *Mod = ModuleToImport; Mod; Mod = Mod->Parent)
2524 std::reverse(Path.begin(), Path.end());
2534 ModuleLoadResult Imported = TheModuleLoader.loadModule(
2537 assert((Imported ==
nullptr || Imported == ModuleToImport) &&
2538 "the imported module is different than the suggested one");
2544 static_cast<Module *
>(Imported)->getTopLevelModule());
2549 ModuleToImport =
nullptr;
2557 Token &
Result = IncludeTok;
2558 assert(CurLexer &&
"#include but no current lexer set!");
2560 CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
2561 CurLexer->cutOffLexing();
2563 return {ImportAction::None};
2571 SourceMgr.getFileCharacteristic(FilenameTok.
getLocation());
2573 FileCharacter = std::max(HeaderInfo.getFileDirFlavor(*
File), FileCharacter);
2584 bool IsFirstIncludeOfFile =
false;
2588 if (Action == Enter &&
File &&
2589 !HeaderInfo.ShouldEnterIncludeFile(*
this, *
File, EnterOnce,
2591 IsFirstIncludeOfFile)) {
2602 if (UsableHeaderUnit && !
getLangOpts().CompilingPCH)
2603 Action = TrackGMFState.inGMF() ?
Import :
Skip;
2605 Action = (ModuleToImport && !
getLangOpts().CompilingPCH) ? Import :
Skip;
2613 if (Action == Enter &&
File && PreambleConditionalStack.isRecording() &&
2614 SourceMgr.isMainFile(
File->getFileEntry())) {
2616 diag::err_pp_including_mainfile_in_preamble);
2617 return {ImportAction::None};
2620 if (Callbacks && !IsImportDecl) {
2623 Callbacks->InclusionDirective(HashLoc, IncludeTok, LookupFilename, isAngled,
2624 FilenameRange,
File, SearchPath, RelativePath,
2625 SuggestedModule.
getModule(), Action == Import,
2628 Callbacks->FileSkipped(*
File, FilenameTok, FileCharacter);
2632 return {ImportAction::None};
2636 if (IsImportDecl && !ModuleToImport) {
2637 Diag(FilenameTok, diag::err_header_import_not_header_unit)
2638 << OriginalFilename <<
File->getName();
2639 return {ImportAction::None};
2644 const bool CheckIncludePathPortability =
2645 !IsMapped && !
File->getFileEntry().tryGetRealPathName().empty();
2647 if (CheckIncludePathPortability) {
2648 StringRef Name = LookupFilename;
2649 StringRef NameWithoriginalSlashes = Filename;
2653 bool NameWasUNC = Name.consume_front(
"\\\\?\\");
2654 NameWithoriginalSlashes.consume_front(
"\\\\?\\");
2656 StringRef RealPathName =
File->getFileEntry().tryGetRealPathName();
2657 SmallVector<StringRef, 16> Components(llvm::sys::path::begin(Name),
2658 llvm::sys::path::end(Name));
2670 SmallString<128> FixedDriveRealPath;
2671 if (llvm::sys::path::is_absolute(Name) &&
2672 llvm::sys::path::is_absolute(RealPathName) &&
2675 assert(Components.size() >= 3 &&
"should have drive, backslash, name");
2676 assert(Components[0].size() == 2 &&
"should start with drive");
2677 assert(Components[0][1] ==
':' &&
"should have colon");
2678 FixedDriveRealPath = (Name.substr(0, 1) + RealPathName.substr(1)).str();
2679 RealPathName = FixedDriveRealPath;
2684 SmallString<128> Path;
2685 Path.reserve(Name.size()+2);
2686 Path.push_back(isAngled ?
'<' :
'"');
2688 const auto IsSep = [BackslashStyle](
char c) {
2689 return llvm::sys::path::is_separator(
c, BackslashStyle);
2692 for (
auto Component : Components) {
2704 if (!(Component.size() == 1 && IsSep(Component[0])))
2705 Path.append(Component);
2706 else if (Path.size() != 1)
2710 if (Path.size() > NameWithoriginalSlashes.size()) {
2711 Path.push_back(isAngled ?
'>' :
'"');
2714 assert(IsSep(NameWithoriginalSlashes[Path.size()-1]));
2716 Path.push_back(NameWithoriginalSlashes[Path.size()-1]);
2717 while (Path.size() <= NameWithoriginalSlashes.size() &&
2718 IsSep(NameWithoriginalSlashes[Path.size()-1]));
2724 Path = (Path.substr(0, 1) +
"\\\\?\\" + Path.substr(1)).str();
2731 ? diag::pp_nonportable_path
2732 : diag::pp_nonportable_system_path;
2733 Diag(FilenameTok, DiagId) << Path <<
2737 bool SuppressBackslashDiag =
2739 Diags->isIgnored(diag::pp_nonportable_path_separator, FilenameLoc) ||
2742 SourceMgr.isWrittenInBuiltinFile(FilenameLoc) ||
2743 SourceMgr.isWrittenInModuleIncludes(FilenameLoc);
2744 if (!SuppressBackslashDiag && OriginalFilename.contains(
'\\')) {
2745 std::string SuggestedPath = OriginalFilename.str();
2746 llvm::replace(SuggestedPath,
'\\',
'/');
2747 Diag(FilenameTok, diag::pp_nonportable_path_separator)
2756 return {ImportAction::SkippedModuleImport, ModuleToImport};
2757 return {ImportAction::None};
2759 case IncludeLimitReached:
2762 return {ImportAction::None};
2766 assert(ModuleToImport &&
"no module to import");
2771 tok::pp___include_macros)
2772 return {ImportAction::None};
2774 return {ImportAction::ModuleImport, ModuleToImport};
2782 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
2783 Diag(FilenameTok, diag::err_pp_include_too_deep);
2784 HasReachedMaxIncludeDepth =
true;
2785 return {ImportAction::None};
2789 Diag(FilenameTok, diag::warn_pp_include_angled_in_module_purview)
2793 SourceLocation IncludePos = FilenameTok.
getLocation();
2797 IncludePos = SourceMgr.getExpansionRange(IncludePos).getEnd();
2798 FileID FID = SourceMgr.createFileID(*
File, IncludePos, FileCharacter);
2800 TheModuleLoader.HadFatalFailure =
true;
2801 return ImportAction::Failure;
2806 IsFirstIncludeOfFile))
2807 return {ImportAction::None};
2811 if (ModuleToImport && !ModuleToImport->
isHeaderUnit()) {
2816 diag::err_module_build_shadowed_submodule)
2819 diag::note_previous_definition);
2820 return {ImportAction::None};
2832 return {ImportAction::None};
2834 assert(!CurLexerSubmodule &&
"should not have marked this as a module yet");
2835 CurLexerSubmodule = ModuleToImport;
2845 return {ImportAction::ModuleBegin, ModuleToImport};
2848 assert(!IsImportDecl &&
"failed to diagnose missing module for import decl");
2849 return {ImportAction::None};
2854void Preprocessor::HandleIncludeNextDirective(
SourceLocation HashLoc,
2855 Token &IncludeNextTok) {
2856 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
2859 const FileEntry *LookupFromFile;
2860 std::tie(Lookup, LookupFromFile) = getIncludeNextStart(IncludeNextTok);
2862 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
2867void Preprocessor::HandleMicrosoftImportDirective(
Token &
Tok) {
2873 Diag(
Tok, diag::err_pp_import_directive_ms );
2884 if (!LangOpts.ObjC) {
2885 if (LangOpts.MSVCCompat)
2886 return HandleMicrosoftImportDirective(ImportTok);
2887 Diag(ImportTok, diag::ext_pp_import_directive);
2889 return HandleIncludeDirective(HashLoc, ImportTok);
2896void Preprocessor::HandleIncludeMacrosDirective(
SourceLocation HashLoc,
2897 Token &IncludeMacrosTok) {
2900 SourceLocation Loc = IncludeMacrosTok.
getLocation();
2901 if (SourceMgr.getBufferName(Loc) !=
"<built-in>") {
2903 diag::pp_include_macros_out_of_predefines);
2910 HandleIncludeDirective(HashLoc, IncludeMacrosTok);
2915 assert(TmpTok.
isNot(tok::eof) &&
"Didn't find end of -imacros!");
2916 }
while (TmpTok.
isNot(tok::hashhash));
2938 Diag(
Tok, diag::err_pp_expected_ident_in_arg_list);
2942 Diag(
Tok, LangOpts.CPlusPlus11 ?
2943 diag::warn_cxx98_compat_variadic_macro :
2944 diag::ext_variadic_macro);
2947 if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus) {
2948 Diag(
Tok, diag::ext_pp_opencl_variadic_macros);
2954 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2963 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2971 Diag(
Tok, diag::err_pp_invalid_tok_in_arg_list);
2977 if (llvm::is_contained(Parameters, II)) {
2978 Diag(
Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
2990 Diag(
Tok, diag::err_pp_expected_comma_in_arg_list);
2999 Diag(
Tok, diag::ext_named_variadic_macro);
3004 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
3034 StringRef ValueText = II->
getName();
3035 StringRef TrimmedValue = ValueText;
3036 if (!ValueText.starts_with(
"__")) {
3037 if (ValueText.starts_with(
"_"))
3038 TrimmedValue = TrimmedValue.drop_front(1);
3042 TrimmedValue = TrimmedValue.drop_front(2);
3043 if (TrimmedValue.ends_with(
"__"))
3044 TrimmedValue = TrimmedValue.drop_back(2);
3046 return TrimmedValue == MacroText;
3053 return MacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
3066MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
3067 const Token &MacroNameTok,
const bool ImmediatelyAfterHeaderGuard) {
3069 Token LastTok = MacroNameTok;
3077 llvm::scope_exit _([&]() {
3079 if (CurLexer->ParsingPreprocessorDirective)
3090 if (
Tok.
is(tok::eod)) {
3091 if (ImmediatelyAfterHeaderGuard) {
3101 }
else if (
Tok.
is(tok::l_paren)) {
3104 if (ReadMacroParameterList(MI, LastTok))
3118 }
else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
3121 Diag(
Tok, diag::ext_c99_whitespace_required_after_macro_name);
3130 if (
Tok.
is(tok::at))
3132 else if (
Tok.
is(tok::unknown)) {
3139 Diag(
Tok, diag::ext_missing_whitespace_after_macro_name);
3141 Diag(
Tok, diag::warn_missing_whitespace_after_macro_name);
3144 if (!
Tok.
is(tok::eod))
3147 SmallVector<Token, 16> Tokens;
3154 Tokens.push_back(
Tok);
3168 if (!
Tok.
isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
3169 Tokens.push_back(
Tok);
3171 if (VAOCtx.isVAOptToken(
Tok)) {
3173 if (VAOCtx.isInVAOpt()) {
3174 Diag(
Tok, diag::err_pp_vaopt_nested_use);
3180 Diag(
Tok, diag::err_pp_missing_lparen_in_vaopt_use);
3183 Tokens.push_back(
Tok);
3186 if (
Tok.
is(tok::hashhash)) {
3187 Diag(
Tok, diag::err_vaopt_paste_at_start);
3191 }
else if (VAOCtx.isInVAOpt()) {
3192 if (
Tok.
is(tok::r_paren)) {
3193 if (VAOCtx.sawClosingParen()) {
3194 assert(Tokens.size() >= 3 &&
3195 "Must have seen at least __VA_OPT__( "
3196 "and a subsequent tok::r_paren");
3197 if (Tokens[Tokens.size() - 2].is(tok::hashhash)) {
3198 Diag(
Tok, diag::err_vaopt_paste_at_end);
3202 }
else if (
Tok.
is(tok::l_paren)) {
3216 Tokens.push_back(
Tok);
3223 if (
Tok.
is(tok::hashhash)) {
3231 if (
Tok.
is(tok::eod)) {
3232 Tokens.push_back(LastTok);
3237 Tokens[Tokens.size() - 1].is(tok::comma))
3241 Tokens.push_back(LastTok);
3250 if (!VAOCtx.isVAOptToken(
Tok) &&
3259 LastTok.
setKind(tok::unknown);
3260 Tokens.push_back(LastTok);
3263 Diag(
Tok, diag::err_pp_stringize_not_parameter)
3264 << LastTok.
is(tok::hashat);
3270 Tokens.push_back(LastTok);
3275 if (!VAOCtx.isVAOptToken(
Tok)) {
3276 Tokens.push_back(
Tok);
3283 if (VAOCtx.isInVAOpt()) {
3284 assert(
Tok.
is(tok::eod) &&
"Must be at End Of preprocessing Directive");
3285 Diag(
Tok, diag::err_pp_expected_after)
3286 << LastTok.
getKind() << tok::r_paren;
3287 Diag(VAOCtx.getUnmatchedOpeningParenLoc(), diag::note_matching) << tok::l_paren;
3298 return II->
isStr(
"__strong") || II->
isStr(
"__weak") ||
3299 II->
isStr(
"__unsafe_unretained") || II->
isStr(
"__autoreleasing");
3304void Preprocessor::HandleDefineDirective(
3305 Token &DefineTok,
const bool ImmediatelyAfterHeaderGuard) {
3309 bool MacroShadowsKeyword;
3310 ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
3313 if (MacroNameTok.
is(tok::eod))
3320 emitFinalMacroWarning(MacroNameTok,
false);
3324 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
3326 MacroInfo *
const MI = ReadOptionalMacroParameterListAndBody(
3327 MacroNameTok, ImmediatelyAfterHeaderGuard);
3331 if (MacroShadowsKeyword &&
3333 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
3338 if (NumTokens != 0) {
3350 if (SkippingUntilPCHThroughHeader) {
3353 LangOpts.MicrosoftExt))
3357 if (!LangOpts.MicrosoftExt)
3368 emitFinalMacroWarning(MacroNameTok,
false);
3379 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) &&
3381 LangOpts.MicrosoftExt)) {
3392 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) {
3400 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
3404 !MI->
isIdenticalTo(*OtherMI, *
this, LangOpts.MicrosoftExt)) {
3414 DefMacroDirective *MD =
3422 !MacroExpansionInDirectivesOverride &&
3431 Callbacks->MacroDefined(MacroNameTok, MD);
3436void Preprocessor::HandleUndefDirective() {
3440 ReadMacroName(MacroNameTok,
MU_Undef);
3443 if (MacroNameTok.
is(tok::eod))
3452 UndefMacroDirective *Undef =
nullptr;
3455 emitFinalMacroWarning(MacroNameTok,
true);
3465 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
3470 Undef = AllocateUndefMacroDirective(MacroNameTok.
getLocation());
3476 Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
3491void Preprocessor::HandleIfdefDirective(
Token &
Result,
3492 const Token &HashToken,
3494 bool ReadAnyTokensBeforeDirective) {
3496 Token DirectiveTok =
Result;
3499 ReadMacroName(MacroNameTok);
3502 if (MacroNameTok.
is(tok::eod)) {
3505 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3520 if (CurPPLexer->getConditionalStackDepth() == 0) {
3525 if (!ReadAnyTokensBeforeDirective && !MI) {
3526 assert(isIfndef &&
"#ifdef shouldn't reach here");
3527 CurPPLexer->MIOpt.EnterTopLevelIfndef(MII, MacroNameTok.
getLocation());
3529 CurPPLexer->MIOpt.EnterTopLevelConditional();
3538 Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3540 Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3543 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3547 if (PPOpts.SingleFileParseMode && !MI) {
3550 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3553 }
else if (PPOpts.SingleModuleParseMode && !MI) {
3557 SkipExcludedConditionalBlock(
3560 }
else if (!MI == isIfndef || RetainExcludedCB) {
3562 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3567 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3576void Preprocessor::HandleIfDirective(
Token &IfToken,
3577 const Token &HashToken,
3578 bool ReadAnyTokensBeforeDirective) {
3582 IdentifierInfo *IfNDefMacro =
nullptr;
3583 const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
3584 const bool ConditionalTrue = DER.Conditional;
3592 if (CurPPLexer->getConditionalStackDepth() == 0) {
3593 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
3595 CurPPLexer->MIOpt.EnterTopLevelIfndef(IfNDefMacro, IfToken.
getLocation());
3597 CurPPLexer->MIOpt.EnterTopLevelConditional();
3605 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3609 if (PPOpts.SingleFileParseMode && DER.IncludedUndefinedIds) {
3612 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3614 }
else if (PPOpts.SingleModuleParseMode && DER.IncludedUndefinedIds) {
3621 }
else if (ConditionalTrue || RetainExcludedCB) {
3623 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3635void Preprocessor::HandleEndifDirective(
Token &EndifToken) {
3641 PPConditionalInfo CondInfo;
3642 if (CurPPLexer->popConditionalLevel(CondInfo)) {
3644 Diag(EndifToken, diag::err_pp_endif_without_if);
3649 if (CurPPLexer->getConditionalStackDepth() == 0)
3650 CurPPLexer->MIOpt.ExitTopLevelConditional();
3652 assert(!CondInfo.
WasSkipping && !CurPPLexer->LexingRawMode &&
3653 "This code should only be reachable in the non-skipping case!");
3661void Preprocessor::HandleElseDirective(
Token &
Result,
const Token &HashToken) {
3667 PPConditionalInfo CI;
3668 if (CurPPLexer->popConditionalLevel(CI)) {
3674 if (CurPPLexer->getConditionalStackDepth() == 0)
3675 CurPPLexer->MIOpt.EnterTopLevelConditional();
3683 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3686 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3689 CurPPLexer->pushConditionalLevel(CI.
IfLoc,
false,
3697 true,
Result.getLocation());
3701void Preprocessor::HandleElifFamilyDirective(
Token &ElifToken,
3702 const Token &HashToken,
3714 if (LangOpts.CPlusPlus)
3715 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
3716 : diag::ext_cxx23_pp_directive;
3718 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
3719 : diag::ext_c23_pp_directive;
3720 Diag(ElifToken, DiagID) << DirKind;
3731 PPConditionalInfo CI;
3732 if (CurPPLexer->popConditionalLevel(CI)) {
3733 Diag(ElifToken, diag::pp_err_elif_without_if) << DirKind;
3738 if (CurPPLexer->getConditionalStackDepth() == 0)
3739 CurPPLexer->MIOpt.EnterTopLevelConditional();
3743 Diag(ElifToken, diag::pp_err_elif_after_else) << DirKind;
3748 Callbacks->Elif(ElifToken.
getLocation(), ConditionRange,
3751 case tok::pp_elifdef:
3754 case tok::pp_elifndef:
3758 assert(
false &&
"unexpected directive kind");
3763 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3766 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3769 CurPPLexer->pushConditionalLevel(ElifToken.
getLocation(),
false,
3775 SkipExcludedConditionalBlock(
3780std::optional<LexEmbedParametersResult>
3783 tok::TokenKind EndTokenKind = ForHasEmbed ? tok::r_paren : tok::eod;
3785 auto DiagMismatchedBracesAndSkipToEOD =
3787 std::pair<tok::TokenKind, SourceLocation> Matches) {
3789 Diag(Matches.second, diag::note_matching) << Matches.first;
3790 if (CurTok.
isNot(tok::eod))
3795 if (CurTok.
isNot(Kind)) {
3796 Diag(CurTok, diag::err_expected) << Kind;
3797 if (CurTok.
isNot(tok::eod))
3814 auto LexPPParameterName = [&]() -> std::optional<std::string> {
3817 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3818 return std::nullopt;
3825 if (CurTok.
is(tok::coloncolon)) {
3828 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3829 return std::nullopt;
3835 return (llvm::Twine(Prefix->
getName()) +
"::" + Suffix->
getName()).str();
3837 return Prefix->
getName().str();
3844 auto NormalizeParameterName = [](StringRef Name) {
3845 if (Name.size() > 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
3846 return Name.substr(2, Name.size() - 4);
3850 auto LexParenthesizedIntegerExpr = [&]() -> std::optional<size_t> {
3853 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3854 return std::nullopt;
3859 bool EvaluatedDefined;
3860 DirectiveEvalResult LimitEvalResult = EvaluateDirectiveExpression(
3861 ParameterIfNDef, CurTok, EvaluatedDefined,
false);
3863 if (!LimitEvalResult.Value) {
3866 assert(CurTok.
is(tok::eod) &&
"expect to be at the end of directive");
3867 return std::nullopt;
3870 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3871 return std::nullopt;
3878 if (EvaluatedDefined) {
3879 Diag(CurTok, diag::err_defined_in_pp_embed);
3880 return std::nullopt;
3883 if (LimitEvalResult.Value) {
3884 const llvm::APSInt &
Result = *LimitEvalResult.Value;
3885 if (
Result.isNegative()) {
3886 Diag(CurTok, diag::err_requires_positive_value)
3888 if (CurTok.
isNot(EndTokenKind))
3890 return std::nullopt;
3892 return Result.getLimitedValue();
3894 return std::nullopt;
3900 return tok::r_paren;
3902 return tok::r_brace;
3904 return tok::r_square;
3906 llvm_unreachable(
"should not get here");
3910 auto LexParenthesizedBalancedTokenSoup =
3912 std::vector<std::pair<tok::TokenKind, SourceLocation>> BracketStack;
3915 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3919 bool WaitingForInnerCloseParen =
false;
3920 while (CurTok.
isNot(tok::eod) &&
3921 (WaitingForInnerCloseParen || CurTok.
isNot(tok::r_paren))) {
3926 WaitingForInnerCloseParen =
true;
3933 WaitingForInnerCloseParen =
false;
3936 case tok::r_square: {
3937 if (BracketStack.empty()) {
3938 ExpectOrDiagAndSkipToEOD(tok::r_paren);
3942 GetMatchingCloseBracket(BracketStack.back().first);
3943 if (CurTok.
getKind() != Matching) {
3944 DiagMismatchedBracesAndSkipToEOD(Matching, BracketStack.back());
3947 BracketStack.pop_back();
3950 Tokens.push_back(CurTok);
3955 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3963 while (!CurTok.
isOneOf(EndTokenKind, tok::eod)) {
3965 std::optional<std::string> ParamName = LexPPParameterName();
3967 return std::nullopt;
3968 StringRef
Parameter = NormalizeParameterName(*ParamName);
3975 if (
Result.MaybeLimitParam)
3978 std::optional<size_t> Limit = LexParenthesizedIntegerExpr();
3980 return std::nullopt;
3983 }
else if (
Parameter ==
"clang::offset") {
3984 if (
Result.MaybeOffsetParam)
3987 std::optional<size_t> Offset = LexParenthesizedIntegerExpr();
3989 return std::nullopt;
3993 if (
Result.MaybePrefixParam)
3997 if (!LexParenthesizedBalancedTokenSoup(Soup))
3998 return std::nullopt;
4000 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
4002 if (
Result.MaybeSuffixParam)
4006 if (!LexParenthesizedBalancedTokenSoup(Soup))
4007 return std::nullopt;
4009 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
4011 if (
Result.MaybeIfEmptyParam)
4015 if (!LexParenthesizedBalancedTokenSoup(Soup))
4016 return std::nullopt;
4018 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
4020 ++
Result.UnrecognizedParams;
4024 if (CurTok.
is(tok::l_paren)) {
4026 if (!LexParenthesizedBalancedTokenSoup(Soup))
4027 return std::nullopt;
4030 Diag(ParamStartLoc, diag::err_pp_unknown_parameter) << 1 <<
Parameter;
4031 if (CurTok.
isNot(EndTokenKind))
4033 return std::nullopt;
4040void Preprocessor::HandleEmbedDirectiveImpl(
4042 StringRef BinaryContents, StringRef
FileName) {
4043 if (BinaryContents.empty()) {
4051 size_t TokCount = Toks.size();
4052 auto NewToks = std::make_unique<Token[]>(TokCount);
4053 llvm::copy(Toks, NewToks.get());
4054 EnterTokenStream(std::move(NewToks), TokCount,
true,
true);
4061 size_t TotalNumToks = 1 + NumPrefixToks + NumSuffixToks;
4063 auto Toks = std::make_unique<Token[]>(TotalNumToks);
4068 CurIdx += NumPrefixToks;
4071 EmbedAnnotationData *
Data =
new (BP) EmbedAnnotationData;
4072 Data->BinaryData = BinaryContents;
4075 Toks[CurIdx].startToken();
4076 Toks[CurIdx].setKind(tok::annot_embed);
4077 Toks[CurIdx].setAnnotationRange(HashLoc);
4078 Toks[CurIdx++].setAnnotationValue(
Data);
4083 CurIdx += NumSuffixToks;
4086 assert(CurIdx == TotalNumToks &&
"Calculated the incorrect number of tokens");
4087 EnterTokenStream(std::move(Toks), TotalNumToks,
true,
true);
4094 Diag(EmbedTok, diag::warn_compat_pp_embed_directive);
4096 Diag(EmbedTok, diag::ext_pp_embed_directive)
4097 << (LangOpts.CPlusPlus ? 1 : 0);
4104 if (FilenameTok.
isNot(tok::header_name)) {
4106 if (FilenameTok.
isNot(tok::eod))
4119 std::optional<LexEmbedParametersResult> Params =
4122 assert((Params || CurTok.
is(tok::eod)) &&
4123 "expected success or to be at the end of the directive");
4128 SmallString<128> FilenameBuffer;
4129 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
4130 StringRef OriginalFilename = Filename;
4136 if (Filename.empty())
4141 if (!MaybeFileRef) {
4143 if (Callbacks && Callbacks->EmbedFileNotFound(Filename)) {
4146 Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
4151 Diag(FilenameTok, diag::err_pp_embed_device_file) << Filename;
4155 std::optional<llvm::MemoryBufferRef> MaybeFile =
4159 Diag(FilenameTok, diag::err_cannot_open_file)
4160 << Filename <<
"a buffer to the contents could not be created";
4163 StringRef BinaryContents = MaybeFile->getBuffer();
4168 if (Params->MaybeOffsetParam) {
4173 BinaryContents = BinaryContents.substr(Params->MaybeOffsetParam->Offset);
4176 if (Params->MaybeLimitParam) {
4180 BinaryContents = BinaryContents.substr(0, Params->MaybeLimitParam->Limit);
4184 Callbacks->EmbedDirective(HashLoc, Filename, isAngled, MaybeFileRef,
4193 void *Mem = BP.Allocate(OriginalFilename.size(),
alignof(
char *));
4194 memcpy(Mem, OriginalFilename.data(), OriginalFilename.size());
4195 StringRef FilenameToGo =
4196 StringRef(
static_cast<char *
>(Mem), OriginalFilename.size());
4197 HandleEmbedDirectiveImpl(HashLoc, *Params, BinaryContents, FilenameToGo);
4210 assert(
getLangOpts().CPlusPlusModules && ImportTok.
is(tok::kw_import));
4212 this->ImportingCXXNamedModules,
true);
4216 if (
Tok.isNot(tok::eod))
4224 bool ImportingHeader =
false;
4225 bool IsPartition =
false;
4227 switch (
Tok.getKind()) {
4228 case tok::header_name:
4229 ImportingHeader =
true;
4230 DirToks.push_back(
Tok);
4231 Lex(DirToks.emplace_back());
4235 DirToks.push_back(
Tok);
4236 UseLoc =
Tok.getLocation();
4239 case tok::identifier: {
4241 Path, DirToks,
true,
4245 std::string FlatName;
4247 (IsPartition && ModuleDeclState.isNamedModule()) || !IsPartition;
4248 if (Callbacks && IsValid) {
4249 if (IsPartition && ModuleDeclState.isNamedModule()) {
4250 FlatName += ModuleDeclState.getPrimaryName();
4255 SourceLocation StartLoc = IsPartition ? UseLoc : Path[0].getLoc();
4267 DirToks.push_back(
Tok);
4273 if (!DirToks.back().isOneOf(tok::semi, tok::eod))
4276 if (DirToks.back().isNot(tok::eod))
4282 if (DirToks.back().isNot(tok::semi)) {
4287 if (ImportingHeader) {
4293 Diag(SemiLoc, diag::err_header_import_semi_in_macro);
4295 auto Action = HandleHeaderIncludeOrImport(
4297 switch (Action.Kind) {
4298 case ImportAction::None:
4301 case ImportAction::ModuleBegin:
4303 DirToks.emplace_back();
4304 DirToks.back().startToken();
4305 DirToks.back().setKind(tok::annot_module_begin);
4306 DirToks.back().setLocation(SemiLoc);
4307 DirToks.back().setAnnotationEndLoc(SemiLoc);
4308 DirToks.back().setAnnotationValue(Action.ModuleForHeader);
4311 case ImportAction::ModuleImport:
4312 case ImportAction::HeaderUnitImport:
4313 case ImportAction::SkippedModuleImport:
4316 DirToks[1].setKind(tok::annot_header_unit);
4317 DirToks[1].setAnnotationEndLoc(DirToks[0].getLocation());
4318 DirToks[1].setAnnotationValue(Action.ModuleForHeader);
4321 case ImportAction::Failure:
4322 assert(TheModuleLoader.HadFatalFailure &&
4323 "This should be an early exit only to a fatal error");
4324 CurLexer->cutOffLexing();
4353 assert(
getLangOpts().CPlusPlusModules && ModuleTok.
is(tok::kw_module));
4362 switch (
Tok.getKind()) {
4365 DirToks.push_back(
Tok);
4368 DirToks.push_back(
Tok);
4370 if (
Tok.isNot(tok::kw_private)) {
4371 if (
Tok.isNot(tok::eod))
4377 DirToks.push_back(
Tok);
4379 case tok::identifier: {
4381 Path, DirToks,
false,
4388 if (
Tok.is(tok::colon)) {
4391 Tok, Partition, DirToks,
4402 if (
Tok.is(tok::identifier) &&
4404 std::unique_ptr<Token[]> TokCopy = std::make_unique<Token[]>(1);
4406 EnterTokenStream(std::move(TokCopy), 1,
4409 DirToks.back() =
Tok;
4414 DirToks.push_back(
Tok);
4420 std::optional<Token> NextPPTok =
4421 DirToks.back().is(tok::eod) ? peekNextPPToken() : DirToks.back();
4426 if (NextPPTok->is(tok::raw_identifier))
4428 if (!NextPPTok->isOneOf(tok::semi, tok::eod, tok::l_square,
4430 Diag(*NextPPTok, diag::err_pp_unexpected_tok_after_module_name)
4434 if (!DirToks.back().isOneOf(tok::semi, tok::eod)) {
4441 DirToks.back().isNot(tok::eod)
4445 : DirToks.pop_back_val().getLocation();
4447 if (!IncludeMacroStack.empty()) {
4448 Diag(StartLoc, diag::err_pp_module_decl_in_header)
4452 if (CurPPLexer->getConditionalStackDepth() != 0) {
4453 Diag(StartLoc, diag::err_pp_cond_span_module_decl)
4471void Preprocessor::HandleObjCImportDirective(
Token &AtTok,
Token &ImportTok) {
4474 ImportTok.
setKind(tok::kw_import);
4489 if (!DirToks.back().isOneOf(tok::semi, tok::eod))
4493 DirToks.back().isNot(tok::eod)
4497 : DirToks.pop_back_val().getLocation();
4499 Module *Imported =
nullptr;
4508 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)
__device__ __2f16 float 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.
llvm::Expected< DirectoryEntryRef > getDirectoryRef(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
llvm::Expected< FileEntryRef > getFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true, bool IsText=true)
Lookup, cache, and verify the specified file (real or virtual).
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 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...
@ 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.