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);
469 auto ReadNextTok = [
this, ExtraToks, &Tmp](
auto &&LexFn) {
470 std::invoke(LexFn,
this, Tmp);
471 if (ExtraToks && Tmp.
isNot(tok::eod))
472 ExtraToks->push_back(Tmp);
484 while (Tmp.
is(tok::comment))
487 if (Tmp.
is(tok::eod))
495 if ((LangOpts.GNUMode || LangOpts.C99 || LangOpts.CPlusPlus) &&
499 unsigned DiagID = diag::ext_pp_extra_tokens_at_eol;
502 (DirType ==
"import" || DirType ==
"module"))
503 DiagID = diag::warn_pp_extra_tokens_at_module_directive_eol;
505 Diag(Tmp, DiagID) << DirType << Hint;
509void Preprocessor::SuggestTypoedDirective(
const Token &
Tok,
510 StringRef Directive)
const {
515 std::vector<StringRef> Candidates = {
516 "if",
"ifdef",
"ifndef",
"elif",
"else",
"endif"
518 if (LangOpts.C23 || LangOpts.CPlusPlus23)
519 Candidates.insert(Candidates.end(), {
"elifdef",
"elifndef"});
523 assert(
Tok.getLocation().isFileID());
527 StringRef SuggValue = *Sugg;
530 Diag(
Tok, diag::warn_pp_invalid_directive) << 1 << SuggValue << Hint;
542void Preprocessor::SkipExcludedConditionalBlock(
SourceLocation HashTokenLoc,
544 bool FoundNonSkipPortion,
555 assert(!SkippingExcludedConditionalBlock &&
556 "calling SkipExcludedConditionalBlock recursively");
557 llvm::SaveAndRestore SARSkipping(SkippingExcludedConditionalBlock,
true);
560 assert(!CurTokenLexer &&
"Conditional PP block cannot appear in a macro!");
561 assert(CurPPLexer &&
"Conditional PP block must be in a file!");
562 assert(CurLexer &&
"Conditional PP block but no current lexer set!");
564 if (PreambleConditionalStack.reachedEOFWhileSkipping())
565 PreambleConditionalStack.clearSkipInfo();
567 CurPPLexer->pushConditionalLevel(IfTokenLoc,
false,
568 FoundNonSkipPortion, FoundElse);
572 CurPPLexer->LexingRawMode =
true;
574 SourceLocation endLoc;
578 struct SkippingRangeStateTy {
581 const char *BeginPtr =
nullptr;
582 unsigned *SkipRangePtr =
nullptr;
584 SkippingRangeStateTy(Preprocessor &PP) : PP(PP) {}
586 void beginLexPass() {
592 BeginPtr = PP.CurLexer->getBufferLocation();
593 SkipRangePtr = &PP.RecordedSkippedRanges[BeginPtr];
595 PP.CurLexer->seek(PP.CurLexer->getCurrentBufferOffset() + *SkipRangePtr,
600 void endLexPass(
const char *Hashptr) {
603 assert(PP.CurLexer->isDependencyDirectivesLexer());
608 if (!*SkipRangePtr) {
609 *SkipRangePtr = Hashptr - BeginPtr;
611 assert(*SkipRangePtr ==
unsigned(Hashptr - BeginPtr));
613 SkipRangePtr =
nullptr;
615 } SkippingRangeState(*
this);
618 if (CurLexer->isDependencyDirectivesLexer()) {
619 CurLexer->LexDependencyDirectiveTokenWhileSkipping(
Tok);
621 SkippingRangeState.beginLexPass();
625 if (
Tok.
is(tok::code_completion)) {
628 CodeComplete->CodeCompleteInConditionalExclusion();
641 Tok.
is(tok::raw_identifier) &&
644 llvm::SaveAndRestore ModuleDirectiveSkipping(LastExportKeyword);
645 LastExportKeyword.startToken();
652 if (
Tok.
is(tok::raw_identifier)) {
661 llvm::SaveAndRestore RestoreLexingRawMode(CurPPLexer->LexingRawMode,
668 CurPPLexer->ParsingPreprocessorDirective =
true;
671 Diag(StartLoc, diag::err_pp_cond_span_module_decl)
672 << SourceRange(StartLoc, End);
673 CurPPLexer->ParsingPreprocessorDirective =
false;
676 CurLexer->resetExtendedTokenMode();
683 if (
Tok.
is(tok::eof)) {
687 if (PreambleConditionalStack.isRecording())
688 PreambleConditionalStack.SkipInfo.emplace(HashTokenLoc, IfTokenLoc,
701 if (
Tok.
is(tok::eof))
707 CurPPLexer->ParsingPreprocessorDirective =
true;
708 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
710 assert(
Tok.
is(tok::hash));
711 const char *Hashptr = CurLexer->getBufferLocation() -
Tok.
getLength();
712 assert(CurLexer->getSourceLocation(Hashptr) ==
Tok.
getLocation());
719 if (
Tok.
isNot(tok::raw_identifier)) {
720 CurPPLexer->ParsingPreprocessorDirective =
false;
722 if (CurLexer) CurLexer->resetExtendedTokenMode();
733 char FirstChar = RI[0];
734 if (FirstChar >=
'a' && FirstChar <=
'z' &&
735 FirstChar !=
'i' && FirstChar !=
'e') {
736 CurPPLexer->ParsingPreprocessorDirective =
false;
738 if (CurLexer) CurLexer->resetExtendedTokenMode();
745 char DirectiveBuf[20];
751 size_t IdLen = DirectiveStr.size();
753 CurPPLexer->ParsingPreprocessorDirective =
false;
755 if (CurLexer) CurLexer->resetExtendedTokenMode();
758 memcpy(DirectiveBuf, &DirectiveStr[0], IdLen);
759 Directive = StringRef(DirectiveBuf, IdLen);
779 PPConditionalInfo CondInfo;
781 bool InCond = CurPPLexer->popConditionalLevel(CondInfo);
783 assert(!InCond &&
"Can't be skipping if not in a conditional!");
787 SkippingRangeState.endLexPass(Hashptr);
790 CurPPLexer->LexingRawMode =
false;
792 CurPPLexer->LexingRawMode =
true;
799 }
else if (Sub ==
"lse") {
803 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
806 SkippingRangeState.endLexPass(Hashptr);
810 Diag(
Tok, diag::pp_err_else_after_else);
821 CurPPLexer->LexingRawMode =
false;
823 CurPPLexer->LexingRawMode =
true;
830 }
else if (Sub ==
"lif") {
831 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
834 SkippingRangeState.endLexPass(Hashptr);
851 assert(CurPPLexer->LexingRawMode &&
"We have to be skipping here!");
852 CurPPLexer->LexingRawMode =
false;
853 IdentifierInfo *IfNDefMacro =
nullptr;
854 DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
858 const bool CondValue = DER.Conditional;
859 CurPPLexer->LexingRawMode =
true;
872 }
else if (Sub ==
"lifdef" ||
874 bool IsElifDef =
Sub ==
"lifdef";
875 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
876 Token DirectiveToken =
Tok;
879 SkippingRangeState.endLexPass(Hashptr);
884 if (LangOpts.CPlusPlus)
885 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
886 : diag::ext_cxx23_pp_directive;
888 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
889 : diag::ext_c23_pp_directive;
894 Diag(
Tok, diag::pp_err_elif_after_else)
908 assert(CurPPLexer->LexingRawMode &&
"We have to be skipping here!");
909 CurPPLexer->LexingRawMode =
false;
911 ReadMacroName(MacroNameTok);
912 CurPPLexer->LexingRawMode =
true;
916 if (MacroNameTok.
is(tok::eod)) {
928 MacroInfo *MI = MD.getMacroInfo();
932 Callbacks->Elifdef(DirectiveToken.
getLocation(), MacroNameTok,
935 Callbacks->Elifndef(DirectiveToken.
getLocation(), MacroNameTok,
940 if (
static_cast<bool>(MI) == IsElifDef) {
952 CurPPLexer->ParsingPreprocessorDirective =
false;
954 if (CurLexer) CurLexer->resetExtendedTokenMode();
960 CurPPLexer->LexingRawMode =
false;
965 Callbacks->SourceRangeSkipped(
966 SourceRange(HashTokenLoc, endLoc.
isValid()
968 : CurPPLexer->getSourceLocation()),
974 if (!SourceMgr.isInMainFile(Loc)) {
977 FileID IDOfIncl = SourceMgr.getFileID(SourceMgr.getExpansionLoc(Loc));
978 if (
auto EntryOfIncl = SourceMgr.getFileEntryRefForID(IDOfIncl)) {
980 return HeaderInfo.getModuleMap()
981 .findModuleForHeader(*EntryOfIncl, AllowTextual)
990 : HeaderInfo.lookupModule(
getLangOpts().CurrentModule, Loc);
997 IncLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
1004 while (!Loc.
isInvalid() && !
SM.isInMainFile(Loc)) {
1005 auto ID =
SM.getFileID(
SM.getExpansionLoc(Loc));
1006 auto FE =
SM.getFileEntryRefForID(ID);
1012 HeaderInfo.hasModuleMap(FE->getName(),
nullptr,
1013 SourceMgr.isInSystemHeader(Loc));
1015 bool InPrivateHeader =
false;
1016 for (
auto Header : HeaderInfo.findAllModulesForHeader(*FE)) {
1017 if (!Header.isAccessibleFrom(IncM)) {
1022 InPrivateHeader =
true;
1039 return std::nullopt;
1049 if (InPrivateHeader)
1050 return std::nullopt;
1058 Loc =
SM.getIncludeLoc(ID);
1061 return std::nullopt;
1070 bool *IsFrameworkFound,
bool SkipCache,
bool OpenFile,
bool CacheFailures) {
1075 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
1080 bool BuildSystemModule =
false;
1081 if (!FromDir && !FromFile) {
1098 if (FID == SourceMgr.getMainFileID() && MainFileDir) {
1100 HeaderInfo.getModuleMap().shouldImportRelativeToBuiltinIncludeDir(
1102 ? HeaderInfo.getModuleMap().getBuiltinDir()
1104 Includers.push_back(std::make_pair(std::nullopt, *IncludeDir));
1106 }
else if ((FileEnt = SourceMgr.getFileEntryRefForID(
1107 SourceMgr.getMainFileID()))) {
1108 auto CWD = FileMgr.getOptionalDirectoryRef(
".");
1109 Includers.push_back(std::make_pair(*FileEnt, *CWD));
1112 Includers.push_back(std::make_pair(*FileEnt, FileEnt->
getDir()));
1118 if (LangOpts.MSVCCompat && !isAngled) {
1119 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1120 if (IsFileLexer(ISEntry))
1122 Includers.push_back(std::make_pair(*FileEnt, FileEnt->
getDir()));
1127 CurDir = CurDirLookup;
1135 Filename, FilenameLoc, isAngled, TmpFromDir, &TmpCurDir,
1136 Includers, SearchPath, RelativePath, RequestingModule,
1137 SuggestedModule,
nullptr,
1138 nullptr, SkipCache)) {
1140 TmpFromDir = TmpCurDir;
1142 if (&FE->getFileEntry() == FromFile) {
1144 FromDir = TmpFromDir;
1153 Filename, FilenameLoc, isAngled, FromDir, &CurDir, Includers, SearchPath,
1154 RelativePath, RequestingModule, SuggestedModule, IsMapped,
1155 IsFrameworkFound, SkipCache, BuildSystemModule, OpenFile, CacheFailures);
1163 if (IsFileLexer()) {
1166 Filename, *CurFileEnt, SearchPath, RelativePath, RequestingModule,
1173 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1174 if (IsFileLexer(ISEntry)) {
1175 if ((CurFileEnt = ISEntry.ThePPLexer->
getFileEntry())) {
1177 Filename, *CurFileEnt, SearchPath, RelativePath,
1178 RequestingModule, SuggestedModule)) {
1186 return std::nullopt;
1193 if (llvm::sys::path::is_absolute(Filename)) {
1196 Filename, OpenFile,
true,
false);
1197 return llvm::expectedToOptional(std::move(ShouldBeEntry));
1201 StringRef StartingFrom, StringRef
FileName,
1202 bool RemoveInitialFileComponentFromLookupPath) {
1203 llvm::sys::path::native(StartingFrom, LookupPath);
1204 if (RemoveInitialFileComponentFromLookupPath)
1205 llvm::sys::path::remove_filename(LookupPath);
1206 if (!LookupPath.empty() &&
1207 !llvm::sys::path::is_separator(LookupPath.back())) {
1208 LookupPath.push_back(llvm::sys::path::get_separator().front());
1218 if (LookupFromFile) {
1222 llvm::sys::path::append(TmpDir, Filename);
1223 if (!TmpDir.empty()) {
1225 TmpDir, OpenFile,
true,
false);
1227 return llvm::expectedToOptional(std::move(ShouldBeEntry));
1228 llvm::consumeError(ShouldBeEntry.takeError());
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 llvm::expectedToOptional(std::move(ShouldBeEntry));
1244 llvm::consumeError(ShouldBeEntry.takeError());
1249 for (
const auto &Entry : PPOpts.EmbedEntries) {
1251 SeparateComponents(LookupPath, Entry, Filename,
false);
1253 LookupPath, OpenFile,
true,
false);
1255 return llvm::expectedToOptional(std::move(ShouldBeEntry));
1256 llvm::consumeError(ShouldBeEntry.takeError());
1258 return std::nullopt;
1268 : PP(pp), save(pp->DisableMacroExpansion) {
1269 if (pp->MacroExpansionInDirectivesOverride)
1270 pp->DisableMacroExpansion =
false;
1274 PP->DisableMacroExpansion = save;
1292 return HandleDefineDirective(
Result,
1295 if (SkippingUntilPCHThroughHeader &&
1297 return HandleIncludeDirective(HashLoc,
Result);
1299 if (SkippingUntilPragmaHdrStop && II->
getPPKeywordID() == tok::pp_pragma) {
1301 auto *II =
Result.getIdentifierInfo();
1302 if (II && II->
getName() ==
"hdrstop")
1319 CurPPLexer->ParsingPreprocessorDirective =
true;
1320 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
1322 bool ImmediatelyAfterTopLevelIfndef =
1323 CurPPLexer->MIOpt.getImmediatelyAfterTopLevelIfndef();
1324 CurPPLexer->MIOpt.resetImmediatelyAfterTopLevelIfndef();
1331 bool ReadAnyTokensBeforeDirective =CurPPLexer->MIOpt.getHasReadAnyTokensVal();
1339 if (Introducer.
is(tok::hash))
1353 case tok::pp_include:
1354 case tok::pp_import:
1355 case tok::pp_include_next:
1356 case tok::pp___include_macros:
1357 case tok::pp_pragma:
1359 case tok::pp_module:
1360 case tok::pp___preprocessed_module:
1361 case tok::pp___preprocessed_import:
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:
1472 case tok::pp_include_next:
1475 case tok::pp_warning:
1476 if (LangOpts.CPlusPlus)
1478 ? diag::warn_cxx23_compat_warning_directive
1479 : diag::ext_pp_warning_directive)
1482 Diag(
Result, LangOpts.C23 ? diag::warn_c23_compat_warning_directive
1483 : diag::ext_pp_warning_directive)
1486 return HandleUserDiagnosticDirective(
Result,
true);
1488 return HandleIdentSCCSDirective(
Result);
1490 return HandleIdentSCCSDirective(
Result);
1493 case tok::pp_assert:
1496 case tok::pp_unassert:
1500 case tok::pp___public_macro:
1502 return HandleMacroPublicDirective(
Result);
1505 case tok::pp___private_macro:
1507 return HandleMacroPrivateDirective();
1518 auto Toks = std::make_unique<Token[]>(2);
1520 Toks[0] = Introducer;
1525 if (
Result.is(tok::hashhash))
1526 Toks[1].setKind(tok::unknown);
1531 EnterTokenStream(std::move(Toks), 2,
false,
false);
1537 Diag(
Result, diag::err_pp_invalid_directive) << 0;
1549 bool IsGNULineDirective=
false) {
1550 if (DigitTok.
isNot(tok::numeric_constant)) {
1551 PP.
Diag(DigitTok, DiagID);
1553 if (DigitTok.
isNot(tok::eod))
1559 IntegerBuffer.resize(DigitTok.
getLength());
1560 const char *DigitTokBegin = &IntegerBuffer[0];
1570 for (
unsigned i = 0; i != ActualLength; ++i) {
1573 if (DigitTokBegin[i] ==
'\'')
1576 if (!
isDigit(DigitTokBegin[i])) {
1578 diag::err_pp_line_digit_sequence) << IsGNULineDirective;
1583 unsigned NextVal = Val*10+(DigitTokBegin[i]-
'0');
1584 if (NextVal < Val) {
1585 PP.
Diag(DigitTok, DiagID);
1592 if (DigitTokBegin[0] ==
'0' && Val)
1594 << IsGNULineDirective;
1606void Preprocessor::HandleLineDirective() {
1614 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*
this))
1618 Diag(DigitTok, diag::ext_pp_line_zero);
1622 unsigned LineLimit = 32768U;
1623 if (LangOpts.C99 || LangOpts.CPlusPlus11)
1624 LineLimit = 2147483648U;
1625 if (LineNo >= LineLimit)
1626 Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
1627 else if (LangOpts.CPlusPlus11 && LineNo >= 32768U)
1628 Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
1630 int FilenameID = -1;
1636 if (StrTok.
is(tok::eod))
1638 else if (StrTok.
isNot(tok::string_literal)) {
1639 Diag(StrTok, diag::err_pp_line_invalid_filename);
1643 Diag(StrTok, diag::err_invalid_string_udl);
1648 StringLiteralParser
Literal(StrTok, *
this);
1649 assert(
Literal.isOrdinary() &&
"Didn't allow wide strings in");
1655 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1659 FilenameID = SourceMgr.getLineTableFilenameID(
Literal.GetString());
1672 SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1674 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID,
false,
1678 Callbacks->FileChanged(CurPPLexer->getSourceLocation(),
1690 if (FlagTok.
is(tok::eod))
return false;
1691 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1698 if (FlagTok.
is(tok::eod))
return false;
1699 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1701 }
else if (FlagVal == 2) {
1717 SM.getDecomposedExpansionLoc(IncLoc).first != CurFileID) {
1718 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);
1724 if (FlagTok.
is(tok::eod))
return false;
1725 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1731 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1739 if (FlagTok.
is(tok::eod))
return false;
1740 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1745 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1753 if (FlagTok.
is(tok::eod))
return false;
1756 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1768void Preprocessor::HandleDigitDirective(
Token &DigitTok) {
1772 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
1779 bool IsFileEntry =
false, IsFileExit =
false;
1780 int FilenameID = -1;
1785 if (StrTok.
is(tok::eod)) {
1786 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1788 FileKind = SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1789 }
else if (StrTok.
isNot(tok::string_literal)) {
1790 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1794 Diag(StrTok, diag::err_invalid_string_udl);
1799 StringLiteralParser
Literal(StrTok, *
this);
1800 assert(
Literal.isOrdinary() &&
"Didn't allow wide strings in");
1806 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1814 if (!SourceMgr.isInPredefinedFile(DigitTok.
getLocation()))
1815 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1819 if (!(IsFileExit &&
Literal.GetString().empty()))
1820 FilenameID = SourceMgr.getLineTableFilenameID(
Literal.GetString());
1824 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID, IsFileEntry,
1825 IsFileExit, FileKind);
1834 else if (IsFileExit)
1837 Callbacks->FileChanged(CurPPLexer->getSourceLocation(), Reason, FileKind);
1843void Preprocessor::HandleUserDiagnosticDirective(
Token &
Tok,
1851 CurLexer->ReadToEndOfLine(&Message);
1855 StringRef Msg =
Message.str().ltrim(
' ');
1858 Diag(
Tok, diag::pp_hash_warning) << Msg;
1860 Diag(
Tok, diag::err_pp_hash_error) << Msg;
1865void Preprocessor::HandleIdentSCCSDirective(
Token &
Tok) {
1867 Diag(
Tok, diag::ext_pp_ident_directive);
1874 if (StrTok.
isNot(tok::string_literal) &&
1875 StrTok.
isNot(tok::wide_string_literal)) {
1876 Diag(StrTok, diag::err_pp_malformed_ident);
1877 if (StrTok.
isNot(tok::eod))
1883 Diag(StrTok, diag::err_invalid_string_udl);
1900void Preprocessor::HandleMacroPublicDirective(
Token &
Tok) {
1902 ReadMacroName(MacroNameTok,
MU_Undef);
1905 if (MacroNameTok.
is(tok::eod))
1917 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1927void Preprocessor::HandleMacroPrivateDirective() {
1929 ReadMacroName(MacroNameTok,
MU_Undef);
1932 if (MacroNameTok.
is(tok::eod))
1944 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1964 StringRef &Buffer) {
1966 assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1978 if (Buffer[0] ==
'<') {
1979 if (Buffer.back() !=
'>') {
1980 Diag(Loc, diag::err_pp_expects_filename);
1981 Buffer = StringRef();
1985 }
else if (Buffer[0] ==
'"') {
1986 if (Buffer.back() !=
'"') {
1987 Diag(Loc, diag::err_pp_expects_filename);
1988 Buffer = StringRef();
1993 Diag(Loc, diag::err_pp_expects_filename);
1994 Buffer = StringRef();
1999 if (Buffer.size() <= 2) {
2000 Diag(Loc, diag::err_pp_empty_filename);
2001 Buffer = StringRef();
2006 Buffer = Buffer.substr(1, Buffer.size()-2);
2013 void *AnnotationVal) {
2016 auto Tok = std::make_unique<Token[]>(1);
2017 Tok[0].startToken();
2018 Tok[0].setKind(Kind);
2019 Tok[0].setLocation(Range.getBegin());
2020 Tok[0].setAnnotationEndLoc(Range.getEnd());
2021 Tok[0].setAnnotationValue(AnnotationVal);
2022 EnterTokenStream(std::move(
Tok), 1,
true,
false);
2032 for (
size_t I = 0, N = Path.size(); I != N; ++I) {
2035 PathString += Path[I].getIdentifierInfo()->getName();
2038 int IncludeKind = 0;
2040 case tok::pp_include:
2044 case tok::pp_import:
2048 case tok::pp_include_next:
2052 case tok::pp___include_macros:
2057 llvm_unreachable(
"unknown include directive kind");
2060 PP.
Diag(HashLoc, diag::remark_pp_include_directive_modular_translation)
2061 << IncludeKind << PathString;
2068 StringRef RealPathName,
2069 llvm::sys::path::Style Separator) {
2070 auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName);
2071 auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName);
2073 bool SuggestReplacement =
false;
2075 auto IsSep = [Separator](StringRef Component) {
2076 return Component.size() == 1 &&
2077 llvm::sys::path::is_separator(Component[0], Separator);
2082 for (
auto &Component : llvm::reverse(Components)) {
2083 if (
"." == Component) {
2084 }
else if (
".." == Component) {
2088 }
else if (RealPathComponentIter != RealPathComponentEnd) {
2089 if (!IsSep(Component) && !IsSep(*RealPathComponentIter) &&
2090 Component != *RealPathComponentIter) {
2094 SuggestReplacement =
2095 RealPathComponentIter->equals_insensitive(Component);
2096 if (!SuggestReplacement)
2098 Component = *RealPathComponentIter;
2100 ++RealPathComponentIter;
2103 return SuggestReplacement;
2112 Module *ShadowingModule =
nullptr;
2118 Diags.Report(MissingHeader.
FileNameLoc, diag::err_module_header_missing)
2120 }
else if (ShadowingModule) {
2123 diag::note_previous_definition);
2134std::pair<ConstSearchDirIterator, const FileEntry *>
2135Preprocessor::getIncludeNextStart(
const Token &IncludeNextTok)
const {
2140 const FileEntry *LookupFromFile =
nullptr;
2148 Diag(IncludeNextTok, diag::pp_include_next_in_primary);
2149 }
else if (CurLexerSubmodule) {
2152 assert(CurPPLexer &&
"#include_next directive in macro?");
2153 if (
auto FE = CurPPLexer->getFileEntry())
2154 LookupFromFile = *FE;
2156 }
else if (!Lookup) {
2161 Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
2167 return {Lookup, LookupFromFile};
2183 if (FilenameTok.
isNot(tok::header_name)) {
2184 if (FilenameTok.
is(tok::identifier) &&
2185 (PPOpts.SingleFileParseMode || PPOpts.SingleModuleParseMode)) {
2195 if (FilenameTok.
isNot(tok::eod))
2204 SourceLocation EndLoc =
2207 auto Action = HandleHeaderIncludeOrImport(HashLoc, IncludeTok, FilenameTok,
2208 EndLoc, LookupFrom, LookupFromFile);
2209 switch (Action.Kind) {
2210 case ImportAction::None:
2211 case ImportAction::SkippedModuleImport:
2213 case ImportAction::ModuleBegin:
2215 tok::annot_module_begin, Action.ModuleForHeader);
2217 case ImportAction::HeaderUnitImport:
2219 Action.ModuleForHeader);
2221 case ImportAction::ModuleImport:
2223 tok::annot_module_include, Action.ModuleForHeader);
2225 case ImportAction::Failure:
2226 assert(TheModuleLoader.HadFatalFailure &&
2227 "This should be an early exit only to a fatal error");
2228 TheModuleLoader.HadFatalFailure =
true;
2230 CurLexer->cutOffLexing();
2238 const Token &FilenameTok,
bool &IsFrameworkFound,
bool IsImportDecl,
2240 const FileEntry *LookupFromFile, StringRef &LookupFilename,
2243 auto DiagnoseHeaderInclusion = [&](FileEntryRef FE) {
2244 if (LangOpts.AsmPreprocessor)
2248 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
2249 bool RequestingModuleIsModuleInterface =
2250 !SourceMgr.isInMainFile(FilenameLoc);
2252 HeaderInfo.getModuleMap().diagnoseHeaderInclusion(
2253 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
2258 FilenameLoc, LookupFilename, isAngled, LookupFrom, LookupFromFile, CurDir,
2259 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2260 &SuggestedModule, &IsMapped, &IsFrameworkFound);
2262 DiagnoseHeaderInclusion(*
File);
2267 if (Callbacks && Callbacks->FileNotFound(Filename))
2268 return std::nullopt;
2270 if (SuppressIncludeNotFoundError)
2271 return std::nullopt;
2278 FilenameLoc, LookupFilename,
false, LookupFrom, LookupFromFile, CurDir,
2279 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2280 &SuggestedModule, &IsMapped,
2283 DiagnoseHeaderInclusion(*
File);
2284 Diag(FilenameTok, diag::err_pp_file_not_found_angled_include_not_fatal)
2285 << Filename << IsImportDecl
2287 "\"" + Filename.str() +
"\"");
2294 StringRef OriginalFilename = Filename;
2295 if (LangOpts.SpellChecking) {
2298 auto CorrectTypoFilename = [](llvm::StringRef Filename) {
2301 Filename = Filename.drop_back();
2305 StringRef TypoCorrectionName = CorrectTypoFilename(Filename);
2306 StringRef TypoCorrectionLookupName = CorrectTypoFilename(LookupFilename);
2309 FilenameLoc, TypoCorrectionLookupName, isAngled, LookupFrom,
2310 LookupFromFile, CurDir, Callbacks ? &SearchPath :
nullptr,
2311 Callbacks ? &RelativePath :
nullptr, &SuggestedModule, &IsMapped,
2314 DiagnoseHeaderInclusion(*
File);
2317 FilenameRange,
"<" + TypoCorrectionName.str() +
">")
2318 : FixItHint::CreateReplacement(
2319 FilenameRange,
"\"" + TypoCorrectionName.str() +
"\"");
2320 Diag(FilenameTok, diag::err_pp_file_not_found_typo_not_fatal)
2321 << OriginalFilename << TypoCorrectionName << Hint;
2324 Filename = TypoCorrectionName;
2325 LookupFilename = TypoCorrectionLookupName;
2331 assert(!
File &&
"expected missing file");
2332 Diag(FilenameTok, diag::err_pp_file_not_found)
2333 << OriginalFilename << FilenameRange;
2334 if (IsFrameworkFound) {
2335 size_t SlashPos = OriginalFilename.find(
'/');
2336 assert(SlashPos != StringRef::npos &&
2337 "Include with framework name should have '/' in the filename");
2338 StringRef FrameworkName = OriginalFilename.substr(0, SlashPos);
2339 FrameworkCacheEntry &CacheEntry =
2340 HeaderInfo.LookupFrameworkCache(FrameworkName);
2341 assert(CacheEntry.
Directory &&
"Found framework should be in cache");
2342 Diag(FilenameTok, diag::note_pp_framework_without_header)
2343 << OriginalFilename.substr(SlashPos + 1) << FrameworkName
2347 return std::nullopt;
2362Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
2366 SmallString<128> FilenameBuffer;
2367 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
2368 SourceLocation CharEnd = FilenameTok.
getEndLoc();
2370 CharSourceRange FilenameRange
2372 StringRef OriginalFilename = Filename;
2378 if (Filename.empty())
2379 return {ImportAction::None};
2381 bool IsImportDecl = HashLoc.
isInvalid();
2382 SourceLocation StartLoc = IsImportDecl ? IncludeTok.
getLocation() : HashLoc;
2385 if (PragmaARCCFCodeAuditedInfo.getLoc().isValid()) {
2386 Diag(StartLoc, diag::err_pp_include_in_arc_cf_code_audited) << IsImportDecl;
2387 Diag(PragmaARCCFCodeAuditedInfo.getLoc(), diag::note_pragma_entered_here);
2390 PragmaARCCFCodeAuditedInfo = IdentifierLoc();
2394 if (PragmaAssumeNonNullLoc.isValid()) {
2395 Diag(StartLoc, diag::err_pp_include_in_assume_nonnull) << IsImportDecl;
2396 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
2399 PragmaAssumeNonNullLoc = SourceLocation();
2402 if (HeaderInfo.HasIncludeAliasMap()) {
2406 StringRef NewName = HeaderInfo.MapHeaderToIncludeAlias(OriginalFilename);
2407 if (!NewName.empty())
2412 bool IsMapped =
false;
2413 bool IsFrameworkFound =
false;
2415 SmallString<1024> SearchPath;
2416 SmallString<1024> RelativePath;
2419 ModuleMap::KnownHeader SuggestedModule;
2420 SourceLocation FilenameLoc = FilenameTok.
getLocation();
2421 StringRef LookupFilename = Filename;
2425 SmallString<128> NormalizedPath;
2426 llvm::sys::path::Style BackslashStyle = llvm::sys::path::Style::native;
2427 if (is_style_posix(BackslashStyle) && LangOpts.MicrosoftExt) {
2428 NormalizedPath = Filename.str();
2429 llvm::sys::path::native(NormalizedPath);
2430 LookupFilename = NormalizedPath;
2431 BackslashStyle = llvm::sys::path::Style::windows;
2435 &CurDir, Filename, FilenameLoc, FilenameRange, FilenameTok,
2436 IsFrameworkFound, IsImportDecl, IsMapped, LookupFrom, LookupFromFile,
2437 LookupFilename, RelativePath, SearchPath, SuggestedModule, isAngled);
2441 SkippingUntilPCHThroughHeader =
false;
2442 return {ImportAction::None};
2460 enum { Enter,
Import,
Skip, IncludeLimitReached } Action = Enter;
2462 if (PPOpts.SingleFileParseMode)
2463 Action = IncludeLimitReached;
2468 if (Action == Enter && HasReachedMaxIncludeDepth &&
File &&
2470 Action = IncludeLimitReached;
2477 bool MaybeTranslateInclude = Action == Enter &&
File && ModuleToImport &&
2481 bool UsableHeaderUnit =
false;
2482 if (
getLangOpts().CPlusPlusModules && ModuleToImport &&
2484 if (TrackGMFState.inGMF() || IsImportDecl)
2485 UsableHeaderUnit =
true;
2486 else if (!IsImportDecl) {
2488 ModuleToImport =
nullptr;
2492 bool UsableClangHeaderModule =
2499 if (MaybeTranslateInclude && (UsableHeaderUnit || UsableClangHeaderModule)) {
2507 diag::note_implicit_top_level_module_import_here)
2509 return {ImportAction::None};
2515 SmallVector<IdentifierLoc, 2> Path;
2516 for (
Module *Mod = ModuleToImport; Mod; Mod = Mod->Parent)
2519 std::reverse(Path.begin(), Path.end());
2529 ModuleLoadResult Imported = TheModuleLoader.loadModule(
2532 assert((Imported ==
nullptr || Imported == ModuleToImport) &&
2533 "the imported module is different than the suggested one");
2539 static_cast<Module *
>(Imported)->getTopLevelModule());
2544 ModuleToImport =
nullptr;
2552 Token &
Result = IncludeTok;
2553 assert(CurLexer &&
"#include but no current lexer set!");
2555 CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
2556 CurLexer->cutOffLexing();
2558 return {ImportAction::None};
2566 SourceMgr.getFileCharacteristic(FilenameTok.
getLocation());
2568 FileCharacter = std::max(HeaderInfo.getFileDirFlavor(*
File), FileCharacter);
2579 bool IsFirstIncludeOfFile =
false;
2583 if (Action == Enter &&
File &&
2584 !HeaderInfo.ShouldEnterIncludeFile(*
this, *
File, EnterOnce,
2586 IsFirstIncludeOfFile)) {
2597 if (UsableHeaderUnit && !
getLangOpts().CompilingPCH)
2598 Action = TrackGMFState.inGMF() ?
Import :
Skip;
2600 Action = (ModuleToImport && !
getLangOpts().CompilingPCH) ? Import :
Skip;
2608 if (Action == Enter &&
File && PreambleConditionalStack.isRecording() &&
2609 SourceMgr.isMainFile(
File->getFileEntry())) {
2611 diag::err_pp_including_mainfile_in_preamble);
2612 return {ImportAction::None};
2615 if (Callbacks && !IsImportDecl) {
2618 Callbacks->InclusionDirective(HashLoc, IncludeTok, LookupFilename, isAngled,
2619 FilenameRange,
File, SearchPath, RelativePath,
2620 SuggestedModule.
getModule(), Action == Import,
2623 Callbacks->FileSkipped(*
File, FilenameTok, FileCharacter);
2627 return {ImportAction::None};
2631 if (IsImportDecl && !ModuleToImport) {
2632 Diag(FilenameTok, diag::err_header_import_not_header_unit)
2633 << OriginalFilename <<
File->getName();
2634 return {ImportAction::None};
2639 const bool CheckIncludePathPortability =
2640 !IsMapped && !
File->getFileEntry().tryGetRealPathName().empty();
2642 if (CheckIncludePathPortability) {
2643 StringRef Name = LookupFilename;
2644 StringRef NameWithoriginalSlashes = Filename;
2648 bool NameWasUNC = Name.consume_front(
"\\\\?\\");
2649 NameWithoriginalSlashes.consume_front(
"\\\\?\\");
2651 StringRef RealPathName =
File->getFileEntry().tryGetRealPathName();
2652 SmallVector<StringRef, 16> Components(llvm::sys::path::begin(Name),
2653 llvm::sys::path::end(Name));
2665 SmallString<128> FixedDriveRealPath;
2666 if (llvm::sys::path::is_absolute(Name) &&
2667 llvm::sys::path::is_absolute(RealPathName) &&
2670 assert(Components.size() >= 3 &&
"should have drive, backslash, name");
2671 assert(Components[0].size() == 2 &&
"should start with drive");
2672 assert(Components[0][1] ==
':' &&
"should have colon");
2673 FixedDriveRealPath = (Name.substr(0, 1) + RealPathName.substr(1)).str();
2674 RealPathName = FixedDriveRealPath;
2679 SmallString<128> Path;
2680 Path.reserve(Name.size()+2);
2681 Path.push_back(isAngled ?
'<' :
'"');
2683 const auto IsSep = [BackslashStyle](
char c) {
2684 return llvm::sys::path::is_separator(
c, BackslashStyle);
2687 for (
auto Component : Components) {
2699 if (!(Component.size() == 1 && IsSep(Component[0])))
2700 Path.append(Component);
2701 else if (Path.size() != 1)
2705 if (Path.size() > NameWithoriginalSlashes.size()) {
2706 Path.push_back(isAngled ?
'>' :
'"');
2709 assert(IsSep(NameWithoriginalSlashes[Path.size()-1]));
2711 Path.push_back(NameWithoriginalSlashes[Path.size()-1]);
2712 while (Path.size() <= NameWithoriginalSlashes.size() &&
2713 IsSep(NameWithoriginalSlashes[Path.size()-1]));
2719 Path = (Path.substr(0, 1) +
"\\\\?\\" + Path.substr(1)).str();
2726 ? diag::pp_nonportable_path
2727 : diag::pp_nonportable_system_path;
2728 Diag(FilenameTok, DiagId) << Path <<
2737 return {ImportAction::SkippedModuleImport, ModuleToImport};
2738 return {ImportAction::None};
2740 case IncludeLimitReached:
2743 return {ImportAction::None};
2747 assert(ModuleToImport &&
"no module to import");
2752 tok::pp___include_macros)
2753 return {ImportAction::None};
2755 return {ImportAction::ModuleImport, ModuleToImport};
2763 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
2764 Diag(FilenameTok, diag::err_pp_include_too_deep);
2765 HasReachedMaxIncludeDepth =
true;
2766 return {ImportAction::None};
2770 Diag(FilenameTok, diag::warn_pp_include_angled_in_module_purview)
2774 SourceLocation IncludePos = FilenameTok.
getLocation();
2778 IncludePos = SourceMgr.getExpansionRange(IncludePos).getEnd();
2779 FileID FID = SourceMgr.createFileID(*
File, IncludePos, FileCharacter);
2781 TheModuleLoader.HadFatalFailure =
true;
2782 return ImportAction::Failure;
2787 IsFirstIncludeOfFile))
2788 return {ImportAction::None};
2792 if (ModuleToImport && !ModuleToImport->
isHeaderUnit()) {
2797 diag::err_module_build_shadowed_submodule)
2800 diag::note_previous_definition);
2801 return {ImportAction::None};
2813 return {ImportAction::None};
2815 assert(!CurLexerSubmodule &&
"should not have marked this as a module yet");
2816 CurLexerSubmodule = ModuleToImport;
2826 return {ImportAction::ModuleBegin, ModuleToImport};
2829 assert(!IsImportDecl &&
"failed to diagnose missing module for import decl");
2830 return {ImportAction::None};
2835void Preprocessor::HandleIncludeNextDirective(
SourceLocation HashLoc,
2836 Token &IncludeNextTok) {
2837 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
2840 const FileEntry *LookupFromFile;
2841 std::tie(Lookup, LookupFromFile) = getIncludeNextStart(IncludeNextTok);
2843 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
2848void Preprocessor::HandleMicrosoftImportDirective(
Token &
Tok) {
2854 Diag(
Tok, diag::err_pp_import_directive_ms );
2865 if (!LangOpts.ObjC) {
2866 if (LangOpts.MSVCCompat)
2867 return HandleMicrosoftImportDirective(ImportTok);
2868 Diag(ImportTok, diag::ext_pp_import_directive);
2870 return HandleIncludeDirective(HashLoc, ImportTok);
2877void Preprocessor::HandleIncludeMacrosDirective(
SourceLocation HashLoc,
2878 Token &IncludeMacrosTok) {
2881 SourceLocation Loc = IncludeMacrosTok.
getLocation();
2882 if (SourceMgr.getBufferName(Loc) !=
"<built-in>") {
2884 diag::pp_include_macros_out_of_predefines);
2891 HandleIncludeDirective(HashLoc, IncludeMacrosTok);
2896 assert(TmpTok.
isNot(tok::eof) &&
"Didn't find end of -imacros!");
2897 }
while (TmpTok.
isNot(tok::hashhash));
2919 Diag(
Tok, diag::err_pp_expected_ident_in_arg_list);
2923 Diag(
Tok, LangOpts.CPlusPlus11 ?
2924 diag::warn_cxx98_compat_variadic_macro :
2925 diag::ext_variadic_macro);
2928 if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus) {
2929 Diag(
Tok, diag::ext_pp_opencl_variadic_macros);
2935 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2944 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2952 Diag(
Tok, diag::err_pp_invalid_tok_in_arg_list);
2958 if (llvm::is_contained(Parameters, II)) {
2959 Diag(
Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
2971 Diag(
Tok, diag::err_pp_expected_comma_in_arg_list);
2980 Diag(
Tok, diag::ext_named_variadic_macro);
2985 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
3015 StringRef ValueText = II->
getName();
3016 StringRef TrimmedValue = ValueText;
3017 if (!ValueText.starts_with(
"__")) {
3018 if (ValueText.starts_with(
"_"))
3019 TrimmedValue = TrimmedValue.drop_front(1);
3023 TrimmedValue = TrimmedValue.drop_front(2);
3024 if (TrimmedValue.ends_with(
"__"))
3025 TrimmedValue = TrimmedValue.drop_back(2);
3027 return TrimmedValue == MacroText;
3034 return MacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
3047MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
3048 const Token &MacroNameTok,
const bool ImmediatelyAfterHeaderGuard) {
3050 Token LastTok = MacroNameTok;
3058 llvm::scope_exit _([&]() {
3060 if (CurLexer->ParsingPreprocessorDirective)
3071 if (
Tok.
is(tok::eod)) {
3072 if (ImmediatelyAfterHeaderGuard) {
3082 }
else if (
Tok.
is(tok::l_paren)) {
3085 if (ReadMacroParameterList(MI, LastTok))
3099 }
else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
3102 Diag(
Tok, diag::ext_c99_whitespace_required_after_macro_name);
3111 if (
Tok.
is(tok::at))
3113 else if (
Tok.
is(tok::unknown)) {
3120 Diag(
Tok, diag::ext_missing_whitespace_after_macro_name);
3122 Diag(
Tok, diag::warn_missing_whitespace_after_macro_name);
3125 if (!
Tok.
is(tok::eod))
3128 SmallVector<Token, 16> Tokens;
3135 Tokens.push_back(
Tok);
3149 if (!
Tok.
isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
3150 Tokens.push_back(
Tok);
3152 if (VAOCtx.isVAOptToken(
Tok)) {
3154 if (VAOCtx.isInVAOpt()) {
3155 Diag(
Tok, diag::err_pp_vaopt_nested_use);
3161 Diag(
Tok, diag::err_pp_missing_lparen_in_vaopt_use);
3164 Tokens.push_back(
Tok);
3167 if (
Tok.
is(tok::hashhash)) {
3168 Diag(
Tok, diag::err_vaopt_paste_at_start);
3172 }
else if (VAOCtx.isInVAOpt()) {
3173 if (
Tok.
is(tok::r_paren)) {
3174 if (VAOCtx.sawClosingParen()) {
3175 assert(Tokens.size() >= 3 &&
3176 "Must have seen at least __VA_OPT__( "
3177 "and a subsequent tok::r_paren");
3178 if (Tokens[Tokens.size() - 2].is(tok::hashhash)) {
3179 Diag(
Tok, diag::err_vaopt_paste_at_end);
3183 }
else if (
Tok.
is(tok::l_paren)) {
3197 Tokens.push_back(
Tok);
3204 if (
Tok.
is(tok::hashhash)) {
3212 if (
Tok.
is(tok::eod)) {
3213 Tokens.push_back(LastTok);
3218 Tokens[Tokens.size() - 1].is(tok::comma))
3222 Tokens.push_back(LastTok);
3231 if (!VAOCtx.isVAOptToken(
Tok) &&
3240 LastTok.
setKind(tok::unknown);
3241 Tokens.push_back(LastTok);
3244 Diag(
Tok, diag::err_pp_stringize_not_parameter)
3245 << LastTok.
is(tok::hashat);
3251 Tokens.push_back(LastTok);
3256 if (!VAOCtx.isVAOptToken(
Tok)) {
3257 Tokens.push_back(
Tok);
3264 if (VAOCtx.isInVAOpt()) {
3265 assert(
Tok.
is(tok::eod) &&
"Must be at End Of preprocessing Directive");
3266 Diag(
Tok, diag::err_pp_expected_after)
3267 << LastTok.
getKind() << tok::r_paren;
3268 Diag(VAOCtx.getUnmatchedOpeningParenLoc(), diag::note_matching) << tok::l_paren;
3279 return II->
isStr(
"__strong") || II->
isStr(
"__weak") ||
3280 II->
isStr(
"__unsafe_unretained") || II->
isStr(
"__autoreleasing");
3285void Preprocessor::HandleDefineDirective(
3286 Token &DefineTok,
const bool ImmediatelyAfterHeaderGuard) {
3290 bool MacroShadowsKeyword;
3291 ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
3294 if (MacroNameTok.
is(tok::eod))
3301 emitFinalMacroWarning(MacroNameTok,
false);
3305 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
3307 MacroInfo *
const MI = ReadOptionalMacroParameterListAndBody(
3308 MacroNameTok, ImmediatelyAfterHeaderGuard);
3312 if (MacroShadowsKeyword &&
3314 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
3319 if (NumTokens != 0) {
3331 if (SkippingUntilPCHThroughHeader) {
3334 LangOpts.MicrosoftExt))
3338 if (!LangOpts.MicrosoftExt)
3349 emitFinalMacroWarning(MacroNameTok,
false);
3360 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) &&
3362 LangOpts.MicrosoftExt)) {
3373 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) {
3381 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
3385 !MI->
isIdenticalTo(*OtherMI, *
this, LangOpts.MicrosoftExt)) {
3395 DefMacroDirective *MD =
3403 !MacroExpansionInDirectivesOverride &&
3412 Callbacks->MacroDefined(MacroNameTok, MD);
3417void Preprocessor::HandleUndefDirective() {
3421 ReadMacroName(MacroNameTok,
MU_Undef);
3424 if (MacroNameTok.
is(tok::eod))
3433 UndefMacroDirective *Undef =
nullptr;
3436 emitFinalMacroWarning(MacroNameTok,
true);
3446 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
3451 Undef = AllocateUndefMacroDirective(MacroNameTok.
getLocation());
3457 Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
3472void Preprocessor::HandleIfdefDirective(
Token &
Result,
3473 const Token &HashToken,
3475 bool ReadAnyTokensBeforeDirective) {
3477 Token DirectiveTok =
Result;
3480 ReadMacroName(MacroNameTok);
3483 if (MacroNameTok.
is(tok::eod)) {
3486 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3501 if (CurPPLexer->getConditionalStackDepth() == 0) {
3506 if (!ReadAnyTokensBeforeDirective && !MI) {
3507 assert(isIfndef &&
"#ifdef shouldn't reach here");
3508 CurPPLexer->MIOpt.EnterTopLevelIfndef(MII, MacroNameTok.
getLocation());
3510 CurPPLexer->MIOpt.EnterTopLevelConditional();
3519 Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3521 Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3524 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3528 if (PPOpts.SingleFileParseMode && !MI) {
3531 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3534 }
else if (PPOpts.SingleModuleParseMode && !MI) {
3538 SkipExcludedConditionalBlock(
3541 }
else if (!MI == isIfndef || RetainExcludedCB) {
3543 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3548 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3557void Preprocessor::HandleIfDirective(
Token &IfToken,
3558 const Token &HashToken,
3559 bool ReadAnyTokensBeforeDirective) {
3563 IdentifierInfo *IfNDefMacro =
nullptr;
3564 const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
3565 const bool ConditionalTrue = DER.Conditional;
3573 if (CurPPLexer->getConditionalStackDepth() == 0) {
3574 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
3576 CurPPLexer->MIOpt.EnterTopLevelIfndef(IfNDefMacro, IfToken.
getLocation());
3578 CurPPLexer->MIOpt.EnterTopLevelConditional();
3586 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3590 if (PPOpts.SingleFileParseMode && DER.IncludedUndefinedIds) {
3593 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3595 }
else if (PPOpts.SingleModuleParseMode && DER.IncludedUndefinedIds) {
3602 }
else if (ConditionalTrue || RetainExcludedCB) {
3604 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3616void Preprocessor::HandleEndifDirective(
Token &EndifToken) {
3622 PPConditionalInfo CondInfo;
3623 if (CurPPLexer->popConditionalLevel(CondInfo)) {
3625 Diag(EndifToken, diag::err_pp_endif_without_if);
3630 if (CurPPLexer->getConditionalStackDepth() == 0)
3631 CurPPLexer->MIOpt.ExitTopLevelConditional();
3633 assert(!CondInfo.
WasSkipping && !CurPPLexer->LexingRawMode &&
3634 "This code should only be reachable in the non-skipping case!");
3642void Preprocessor::HandleElseDirective(
Token &
Result,
const Token &HashToken) {
3648 PPConditionalInfo CI;
3649 if (CurPPLexer->popConditionalLevel(CI)) {
3655 if (CurPPLexer->getConditionalStackDepth() == 0)
3656 CurPPLexer->MIOpt.EnterTopLevelConditional();
3664 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3667 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3670 CurPPLexer->pushConditionalLevel(CI.
IfLoc,
false,
3678 true,
Result.getLocation());
3682void Preprocessor::HandleElifFamilyDirective(
Token &ElifToken,
3683 const Token &HashToken,
3695 if (LangOpts.CPlusPlus)
3696 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
3697 : diag::ext_cxx23_pp_directive;
3699 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
3700 : diag::ext_c23_pp_directive;
3701 Diag(ElifToken, DiagID) << DirKind;
3712 PPConditionalInfo CI;
3713 if (CurPPLexer->popConditionalLevel(CI)) {
3714 Diag(ElifToken, diag::pp_err_elif_without_if) << DirKind;
3719 if (CurPPLexer->getConditionalStackDepth() == 0)
3720 CurPPLexer->MIOpt.EnterTopLevelConditional();
3724 Diag(ElifToken, diag::pp_err_elif_after_else) << DirKind;
3729 Callbacks->Elif(ElifToken.
getLocation(), ConditionRange,
3732 case tok::pp_elifdef:
3735 case tok::pp_elifndef:
3739 assert(
false &&
"unexpected directive kind");
3744 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3747 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3750 CurPPLexer->pushConditionalLevel(ElifToken.
getLocation(),
false,
3756 SkipExcludedConditionalBlock(
3761std::optional<LexEmbedParametersResult>
3764 tok::TokenKind EndTokenKind = ForHasEmbed ? tok::r_paren : tok::eod;
3766 auto DiagMismatchedBracesAndSkipToEOD =
3768 std::pair<tok::TokenKind, SourceLocation> Matches) {
3770 Diag(Matches.second, diag::note_matching) << Matches.first;
3771 if (CurTok.
isNot(tok::eod))
3776 if (CurTok.
isNot(Kind)) {
3777 Diag(CurTok, diag::err_expected) << Kind;
3778 if (CurTok.
isNot(tok::eod))
3795 auto LexPPParameterName = [&]() -> std::optional<std::string> {
3798 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3799 return std::nullopt;
3806 if (CurTok.
is(tok::coloncolon)) {
3809 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3810 return std::nullopt;
3816 return (llvm::Twine(Prefix->
getName()) +
"::" + Suffix->
getName()).str();
3818 return Prefix->
getName().str();
3825 auto NormalizeParameterName = [](StringRef Name) {
3826 if (Name.size() > 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
3827 return Name.substr(2, Name.size() - 4);
3831 auto LexParenthesizedIntegerExpr = [&]() -> std::optional<size_t> {
3834 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3835 return std::nullopt;
3840 bool EvaluatedDefined;
3841 DirectiveEvalResult LimitEvalResult = EvaluateDirectiveExpression(
3842 ParameterIfNDef, CurTok, EvaluatedDefined,
false);
3844 if (!LimitEvalResult.Value) {
3847 assert(CurTok.
is(tok::eod) &&
"expect to be at the end of directive");
3848 return std::nullopt;
3851 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3852 return std::nullopt;
3859 if (EvaluatedDefined) {
3860 Diag(CurTok, diag::err_defined_in_pp_embed);
3861 return std::nullopt;
3864 if (LimitEvalResult.Value) {
3865 const llvm::APSInt &
Result = *LimitEvalResult.Value;
3866 if (
Result.isNegative()) {
3867 Diag(CurTok, diag::err_requires_positive_value)
3869 if (CurTok.
isNot(EndTokenKind))
3871 return std::nullopt;
3873 return Result.getLimitedValue();
3875 return std::nullopt;
3881 return tok::r_paren;
3883 return tok::r_brace;
3885 return tok::r_square;
3887 llvm_unreachable(
"should not get here");
3891 auto LexParenthesizedBalancedTokenSoup =
3893 std::vector<std::pair<tok::TokenKind, SourceLocation>> BracketStack;
3896 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3900 bool WaitingForInnerCloseParen =
false;
3901 while (CurTok.
isNot(tok::eod) &&
3902 (WaitingForInnerCloseParen || CurTok.
isNot(tok::r_paren))) {
3907 WaitingForInnerCloseParen =
true;
3914 WaitingForInnerCloseParen =
false;
3917 case tok::r_square: {
3918 if (BracketStack.empty()) {
3919 ExpectOrDiagAndSkipToEOD(tok::r_paren);
3923 GetMatchingCloseBracket(BracketStack.back().first);
3924 if (CurTok.
getKind() != Matching) {
3925 DiagMismatchedBracesAndSkipToEOD(Matching, BracketStack.back());
3928 BracketStack.pop_back();
3931 Tokens.push_back(CurTok);
3936 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3944 while (!CurTok.
isOneOf(EndTokenKind, tok::eod)) {
3946 std::optional<std::string> ParamName = LexPPParameterName();
3948 return std::nullopt;
3949 StringRef
Parameter = NormalizeParameterName(*ParamName);
3956 if (
Result.MaybeLimitParam)
3959 std::optional<size_t> Limit = LexParenthesizedIntegerExpr();
3961 return std::nullopt;
3964 }
else if (
Parameter ==
"clang::offset") {
3965 if (
Result.MaybeOffsetParam)
3968 std::optional<size_t> Offset = LexParenthesizedIntegerExpr();
3970 return std::nullopt;
3974 if (
Result.MaybePrefixParam)
3978 if (!LexParenthesizedBalancedTokenSoup(Soup))
3979 return std::nullopt;
3981 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
3983 if (
Result.MaybeSuffixParam)
3987 if (!LexParenthesizedBalancedTokenSoup(Soup))
3988 return std::nullopt;
3990 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
3992 if (
Result.MaybeIfEmptyParam)
3996 if (!LexParenthesizedBalancedTokenSoup(Soup))
3997 return std::nullopt;
3999 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
4001 ++
Result.UnrecognizedParams;
4005 if (CurTok.
is(tok::l_paren)) {
4007 if (!LexParenthesizedBalancedTokenSoup(Soup))
4008 return std::nullopt;
4011 Diag(ParamStartLoc, diag::err_pp_unknown_parameter) << 1 <<
Parameter;
4012 if (CurTok.
isNot(EndTokenKind))
4014 return std::nullopt;
4021void Preprocessor::HandleEmbedDirectiveImpl(
4023 StringRef BinaryContents, StringRef
FileName) {
4024 if (BinaryContents.empty()) {
4032 size_t TokCount = Toks.size();
4033 auto NewToks = std::make_unique<Token[]>(TokCount);
4034 llvm::copy(Toks, NewToks.get());
4035 EnterTokenStream(std::move(NewToks), TokCount,
true,
true);
4042 size_t TotalNumToks = 1 + NumPrefixToks + NumSuffixToks;
4044 auto Toks = std::make_unique<Token[]>(TotalNumToks);
4049 CurIdx += NumPrefixToks;
4052 EmbedAnnotationData *
Data =
new (BP) EmbedAnnotationData;
4053 Data->BinaryData = BinaryContents;
4056 Toks[CurIdx].startToken();
4057 Toks[CurIdx].setKind(tok::annot_embed);
4058 Toks[CurIdx].setAnnotationRange(HashLoc);
4059 Toks[CurIdx++].setAnnotationValue(
Data);
4064 CurIdx += NumSuffixToks;
4067 assert(CurIdx == TotalNumToks &&
"Calculated the incorrect number of tokens");
4068 EnterTokenStream(std::move(Toks), TotalNumToks,
true,
true);
4075 Diag(EmbedTok, diag::warn_compat_pp_embed_directive);
4077 Diag(EmbedTok, diag::ext_pp_embed_directive)
4078 << (LangOpts.CPlusPlus ? 1 : 0);
4085 if (FilenameTok.
isNot(tok::header_name)) {
4087 if (FilenameTok.
isNot(tok::eod))
4100 std::optional<LexEmbedParametersResult> Params =
4103 assert((Params || CurTok.
is(tok::eod)) &&
4104 "expected success or to be at the end of the directive");
4109 SmallString<128> FilenameBuffer;
4110 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
4111 StringRef OriginalFilename = Filename;
4117 if (Filename.empty())
4122 if (!MaybeFileRef) {
4124 if (Callbacks && Callbacks->EmbedFileNotFound(Filename)) {
4127 Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
4132 Diag(FilenameTok, diag::err_pp_embed_device_file) << Filename;
4136 std::optional<llvm::MemoryBufferRef> MaybeFile =
4140 Diag(FilenameTok, diag::err_cannot_open_file)
4141 << Filename <<
"a buffer to the contents could not be created";
4144 StringRef BinaryContents = MaybeFile->getBuffer();
4149 if (Params->MaybeOffsetParam) {
4154 BinaryContents = BinaryContents.substr(Params->MaybeOffsetParam->Offset);
4157 if (Params->MaybeLimitParam) {
4161 BinaryContents = BinaryContents.substr(0, Params->MaybeLimitParam->Limit);
4165 Callbacks->EmbedDirective(HashLoc, Filename, isAngled, MaybeFileRef,
4174 void *Mem = BP.Allocate(OriginalFilename.size(),
alignof(
char *));
4175 memcpy(Mem, OriginalFilename.data(), OriginalFilename.size());
4176 StringRef FilenameToGo =
4177 StringRef(
static_cast<char *
>(Mem), OriginalFilename.size());
4178 HandleEmbedDirectiveImpl(HashLoc, *Params, BinaryContents, FilenameToGo);
4191 assert(
getLangOpts().CPlusPlusModules && ImportTok.
is(tok::kw_import));
4193 this->ImportingCXXNamedModules,
true);
4195 if (LastExportKeyword.is(tok::kw_export))
4196 LastExportKeyword.startToken();
4200 if (
Tok.isNot(tok::eod))
4208 bool ImportingHeader =
false;
4209 bool IsPartition =
false;
4210 std::string FlatName;
4211 switch (
Tok.getKind()) {
4212 case tok::header_name:
4213 ImportingHeader =
true;
4214 DirToks.push_back(
Tok);
4215 Lex(DirToks.emplace_back());
4219 DirToks.push_back(
Tok);
4220 UseLoc =
Tok.getLocation();
4223 case tok::identifier: {
4224 bool LeadingSpace =
Tok.hasLeadingSpace();
4225 unsigned NumToksInDirective = DirToks.size();
4227 if (
Tok.isNot(tok::eod))
4236 DirToks.resize(NumToksInDirective);
4238 DirToks.emplace_back();
4239 DirToks.back().setKind(tok::annot_module_name);
4240 DirToks.back().setAnnotationRange(NameLoc->
getRange());
4241 DirToks.back().setAnnotationValue(
static_cast<void *
>(NameLoc));
4243 DirToks.push_back(
Tok);
4246 (IsPartition && ModuleDeclState.isNamedModule()) || !IsPartition;
4247 if (Callbacks && IsValid) {
4248 if (IsPartition && ModuleDeclState.isNamedModule()) {
4249 FlatName += ModuleDeclState.getPrimaryName();
4254 SourceLocation StartLoc = IsPartition ? UseLoc : Path[0].getLoc();
4266 DirToks.push_back(
Tok);
4272 if (!DirToks.back().isOneOf(tok::semi, tok::eod))
4275 if (DirToks.back().isNot(tok::eod))
4281 if (DirToks.back().isNot(tok::semi)) {
4286 if (ImportingHeader) {
4292 Diag(SemiLoc, diag::err_header_import_semi_in_macro);
4294 auto Action = HandleHeaderIncludeOrImport(
4296 switch (Action.Kind) {
4297 case ImportAction::None:
4300 case ImportAction::ModuleBegin:
4302 DirToks.emplace_back();
4303 DirToks.back().startToken();
4304 DirToks.back().setKind(tok::annot_module_begin);
4305 DirToks.back().setLocation(SemiLoc);
4306 DirToks.back().setAnnotationEndLoc(SemiLoc);
4307 DirToks.back().setAnnotationValue(Action.ModuleForHeader);
4310 case ImportAction::ModuleImport:
4311 case ImportAction::HeaderUnitImport:
4312 case ImportAction::SkippedModuleImport:
4315 DirToks[1].setKind(tok::annot_header_unit);
4316 DirToks[1].setAnnotationEndLoc(DirToks[0].getLocation());
4317 DirToks[1].setAnnotationValue(Action.ModuleForHeader);
4320 case ImportAction::Failure:
4321 assert(TheModuleLoader.HadFatalFailure &&
4322 "This should be an early exit only to a fatal error");
4323 CurLexer->cutOffLexing();
4352 assert(
getLangOpts().CPlusPlusModules && ModuleTok.
is(tok::kw_module));
4353 Token Introducer = ModuleTok;
4354 if (LastExportKeyword.is(tok::kw_export)) {
4355 Introducer = LastExportKeyword;
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: {
4385 bool LeadingSpace =
Tok.hasLeadingSpace();
4386 unsigned NumToksInDirective = DirToks.size();
4395 if (
Tok.isNot(tok::eod))
4403 DirToks.resize(NumToksInDirective);
4404 DirToks.emplace_back();
4405 DirToks.back().setKind(tok::annot_module_name);
4406 DirToks.back().setAnnotationRange(NameLoc->
getRange());
4407 DirToks.back().setAnnotationValue(
static_cast<void *
>(NameLoc));
4409 DirToks.push_back(
Tok);
4414 if (
Tok.is(tok::colon)) {
4415 NumToksInDirective = DirToks.size();
4417 LeadingSpace =
Tok.hasLeadingSpace();
4421 if (
Tok.isNot(tok::eod))
4429 DirToks.resize(NumToksInDirective);
4430 DirToks.emplace_back();
4431 DirToks.back().setKind(tok::annot_module_name);
4432 DirToks.back().setAnnotationRange(NameLoc->
getRange());
4433 DirToks.back().setAnnotationValue(
static_cast<void *
>(PartitionLoc));
4435 DirToks.push_back(
Tok);
4444 if (
Tok.is(tok::identifier) &&
4446 std::unique_ptr<Token[]> TokCopy = std::make_unique<Token[]>(1);
4448 EnterTokenStream(std::move(TokCopy), 1,
4451 DirToks.back() =
Tok;
4456 DirToks.push_back(
Tok);
4463 std::optional<Token> NextPPTok = DirToks.back();
4464 if (DirToks.back().is(tok::eod)) {
4465 NextPPTok = peekNextPPToken();
4466 if (NextPPTok && NextPPTok->is(tok::raw_identifier))
4472 if (!NextPPTok->isOneOf(tok::semi, tok::eod, tok::l_square, tok::kw_private))
4473 Diag(*NextPPTok, diag::err_pp_unexpected_tok_after_module_name)
4476 if (!DirToks.back().isOneOf(tok::semi, tok::eod)) {
4480 End = DirToks.back().getLocation();
4483 if (DirToks.back().isNot(tok::eod))
4487 End = DirToks.pop_back_val().getLocation();
4489 if (!IncludeMacroStack.empty()) {
4490 Diag(StartLoc, diag::err_pp_module_decl_in_header)
4494 if (CurPPLexer->getConditionalStackDepth() != 0) {
4495 Diag(StartLoc, diag::err_pp_cond_span_module_decl)
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...
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.
static ModuleNameLoc * Create(Preprocessor &PP, ModuleIdPath Path)
SourceRange getRange() const
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)
bool LexModuleNameContinue(Token &Tok, SourceLocation UseLoc, SmallVectorImpl< Token > &Suffix, SmallVectorImpl< IdentifierLoc > &Path, bool AllowMacroExpansion=true, bool IsPartition=false)
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.
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.
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.