39#include "llvm/ADT/ArrayRef.h"
40#include "llvm/ADT/STLExtras.h"
41#include "llvm/ADT/ScopeExit.h"
42#include "llvm/ADT/SmallVector.h"
43#include "llvm/ADT/StringExtras.h"
44#include "llvm/ADT/StringRef.h"
45#include "llvm/ADT/StringSwitch.h"
46#include "llvm/Support/ErrorHandling.h"
47#include "llvm/Support/Path.h"
48#include "llvm/Support/SaveAndRestore.h"
64 static_assert(std::is_trivially_destructible_v<MacroInfo>,
"");
74Preprocessor::AllocateUndefMacroDirective(
SourceLocation UndefLoc) {
81 return new (BP) VisibilityMacroDirective(Loc, isPublic);
89 auto ReadNextTok = [&]() {
91 if (DiscardedToks && Tmp.
isNot(tok::eod))
92 DiscardedToks->push_back(Tmp);
96 while (Tmp.
isNot(tok::eod)) {
97 assert(Tmp.
isNot(tok::eof) &&
"EOF seen while discarding directive tokens");
126 static constexpr StringRef ReservedMacro[] = {
129 "_CRT_NONSTDC_NO_WARNINGS",
130 "_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES",
131 "_CRT_SECURE_NO_WARNINGS",
134 "_GLIBCXX_ASSERTIONS",
135 "_GLIBCXX_CONCEPT_CHECKS",
137 "_GLIBCXX_DEBUG_PEDANTIC",
139 "_GLIBCXX_PARALLEL_ASSERTIONS",
140 "_GLIBCXX_SANITIZE_VECTOR",
141 "_GLIBCXX_USE_CXX11_ABI",
142 "_GLIBCXX_USE_DEPRECATED",
147 "_LARGEFILE64_SOURCE",
153 "_XOPEN_SOURCE_EXTENDED",
154 "__STDCPP_WANT_MATH_SPEC_FUNCS__",
155 "__STDC_FORMAT_MACROS",
157 return llvm::binary_search(ReservedMacro, MacroName);
162 const StringRef MacroName) {
172 if (MacroName.starts_with(
"__STDC"))
175 if (MacroName ==
"__cplusplus")
178 if (MacroName.starts_with(
"__cpp"))
186 if (Lang.CPlusPlus &&
207 if (Lang.CPlusPlus11 && (
Text ==
"override" ||
Text ==
"final"))
232 if (::llvm::sys::path::begin(Include)->equals_insensitive(
"boost"))
237 static const size_t MaxStdHeaderNameLen = 18u;
238 if (Include.size() > MaxStdHeaderNameLen)
243 for (
char &Ch : LowerInclude) {
245 if (
static_cast<unsigned char>(Ch) > 0x7f)
248 if (Ch >=
'A' && Ch <=
'Z')
251 else if (::llvm::sys::path::is_separator(Ch))
256 return llvm::StringSwitch<bool>(LowerInclude)
258 .Cases({
"assert.h",
"complex.h",
"ctype.h",
"errno.h",
"fenv.h"},
true)
259 .Cases({
"float.h",
"inttypes.h",
"iso646.h",
"limits.h",
"locale.h"},
261 .Cases({
"math.h",
"setjmp.h",
"signal.h",
"stdalign.h",
"stdarg.h"},
true)
262 .Cases({
"stdatomic.h",
"stdbool.h",
"stdckdint.h",
"stdcountof.h"},
true)
263 .Cases({
"stddef.h",
"stdint.h",
"stdio.h",
"stdlib.h",
"stdnoreturn.h"},
265 .Cases({
"string.h",
"tgmath.h",
"threads.h",
"time.h",
"uchar.h"},
true)
266 .Cases({
"wchar.h",
"wctype.h"},
true)
269 .Cases({
"cassert",
"ccomplex",
"cctype",
"cerrno",
"cfenv"},
true)
270 .Cases({
"cfloat",
"cinttypes",
"ciso646",
"climits",
"clocale"},
true)
271 .Cases({
"cmath",
"csetjmp",
"csignal",
"cstdalign",
"cstdarg"},
true)
272 .Cases({
"cstdbool",
"cstddef",
"cstdint",
"cstdio",
"cstdlib"},
true)
273 .Cases({
"cstring",
"ctgmath",
"ctime",
"cuchar",
"cwchar"},
true)
274 .Case(
"cwctype",
true)
277 .Cases({
"algorithm",
"fstream",
"list",
"regex",
"thread"},
true)
278 .Cases({
"array",
"functional",
"locale",
"scoped_allocator",
"tuple"},
280 .Cases({
"atomic",
"future",
"map",
"set",
"type_traits"},
true)
282 {
"bitset",
"initializer_list",
"memory",
"shared_mutex",
"typeindex"},
284 .Cases({
"chrono",
"iomanip",
"mutex",
"sstream",
"typeinfo"},
true)
285 .Cases({
"codecvt",
"ios",
"new",
"stack",
"unordered_map"},
true)
286 .Cases({
"complex",
"iosfwd",
"numeric",
"stdexcept",
"unordered_set"},
289 {
"condition_variable",
"iostream",
"ostream",
"streambuf",
"utility"},
291 .Cases({
"deque",
"istream",
"queue",
"string",
"valarray"},
true)
292 .Cases({
"exception",
"iterator",
"random",
"strstream",
"vector"},
true)
293 .Cases({
"forward_list",
"limits",
"ratio",
"system_error"},
true)
296 .Cases({
"aio.h",
"arpa/inet.h",
"cpio.h",
"dirent.h",
"dlfcn.h"},
true)
297 .Cases({
"fcntl.h",
"fmtmsg.h",
"fnmatch.h",
"ftw.h",
"glob.h"},
true)
298 .Cases({
"grp.h",
"iconv.h",
"langinfo.h",
"libgen.h",
"monetary.h"},
true)
299 .Cases({
"mqueue.h",
"ndbm.h",
"net/if.h",
"netdb.h",
"netinet/in.h"},
301 .Cases({
"netinet/tcp.h",
"nl_types.h",
"poll.h",
"pthread.h",
"pwd.h"},
303 .Cases({
"regex.h",
"sched.h",
"search.h",
"semaphore.h",
"spawn.h"},
true)
304 .Cases({
"strings.h",
"stropts.h",
"sys/ipc.h",
"sys/mman.h",
"sys/msg.h"},
306 .Cases({
"sys/resource.h",
"sys/select.h",
"sys/sem.h",
"sys/shm.h",
309 .Cases({
"sys/stat.h",
"sys/statvfs.h",
"sys/time.h",
"sys/times.h",
313 {
"sys/uio.h",
"sys/un.h",
"sys/utsname.h",
"sys/wait.h",
"syslog.h"},
315 .Cases({
"tar.h",
"termios.h",
"trace.h",
"ulimit.h"},
true)
316 .Cases({
"unistd.h",
"utime.h",
"utmpx.h",
"wordexp.h"},
true)
328static std::optional<StringRef>
332 for (StringRef
C : Candidates) {
333 if (LHS.equals_insensitive(
C)) {
341 size_t Length = LHS.size();
342 size_t MaxDist = Length < 3 ? Length - 1 : Length / 3;
344 std::optional<std::pair<StringRef, size_t>> SimilarStr;
345 for (StringRef
C : Candidates) {
346 size_t CurDist = LHS.edit_distance(
C,
true);
347 if (CurDist <= MaxDist) {
350 SimilarStr = {
C, CurDist};
351 }
else if (CurDist < SimilarStr->second) {
353 SimilarStr = {
C, CurDist};
359 return SimilarStr->first;
368 if (MacroNameTok.
is(tok::eod))
369 return Diag(MacroNameTok, diag::err_pp_missing_macro_name);
373 return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
379 ? diag::ext_pp_operator_used_as_macro_name
380 : diag::err_pp_operator_used_as_macro_name)
381 << II << MacroNameTok.
getKind();
388 return Diag(MacroNameTok, diag::err_defined_macro_name);
404 }
else if (isDefineUndef ==
MU_Undef)
406 if (D !=
MD_NoWarn && !SourceMgr.isInSystemHeader(MacroNameLoc) &&
407 !SourceMgr.isInPredefinedFile(MacroNameLoc)) {
416 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id);
418 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_attribute_id)
435void Preprocessor::ReadMacroName(
Token &MacroNameTok,
MacroUse isDefineUndef,
440 if (MacroNameTok.
is(tok::code_completion)) {
452 if (MacroNameTok.
isNot(tok::eod)) {
453 MacroNameTok.
setKind(tok::eod);
471 auto ReadNextTok = [
this, ExtraToks, &Tmp](
auto &&LexFn) {
472 std::invoke(LexFn,
this, Tmp);
473 if (ExtraToks && Tmp.
isNot(tok::eod))
474 ExtraToks->push_back(Tmp);
486 while (Tmp.
is(tok::comment))
489 if (Tmp.
is(tok::eod))
497 if ((LangOpts.GNUMode || LangOpts.C99 || LangOpts.CPlusPlus) &&
501 unsigned DiagID = diag::ext_pp_extra_tokens_at_eol;
504 (DirType ==
"import" || DirType ==
"module"))
505 DiagID = diag::warn_pp_extra_tokens_at_module_directive_eol;
507 Diag(Tmp, DiagID) << DirType << Hint;
511void Preprocessor::SuggestTypoedDirective(
const Token &
Tok,
512 StringRef Directive)
const {
517 std::vector<StringRef> Candidates = {
518 "if",
"ifdef",
"ifndef",
"elif",
"else",
"endif"
520 if (LangOpts.C23 || LangOpts.CPlusPlus23)
521 Candidates.insert(Candidates.end(), {
"elifdef",
"elifndef"});
525 assert(
Tok.getLocation().isFileID());
529 StringRef SuggValue = *Sugg;
532 Diag(
Tok, diag::warn_pp_invalid_directive) << 1 << SuggValue << Hint;
544void Preprocessor::SkipExcludedConditionalBlock(
SourceLocation HashTokenLoc,
546 bool FoundNonSkipPortion,
557 assert(!SkippingExcludedConditionalBlock &&
558 "calling SkipExcludedConditionalBlock recursively");
559 llvm::SaveAndRestore SARSkipping(SkippingExcludedConditionalBlock,
true);
562 assert(!CurTokenLexer &&
"Conditional PP block cannot appear in a macro!");
563 assert(CurPPLexer &&
"Conditional PP block must be in a file!");
564 assert(CurLexer &&
"Conditional PP block but no current lexer set!");
566 if (PreambleConditionalStack.reachedEOFWhileSkipping())
567 PreambleConditionalStack.clearSkipInfo();
569 CurPPLexer->pushConditionalLevel(IfTokenLoc,
false,
570 FoundNonSkipPortion, FoundElse);
574 CurPPLexer->LexingRawMode =
true;
576 SourceLocation endLoc;
580 struct SkippingRangeStateTy {
583 const char *BeginPtr =
nullptr;
584 unsigned *SkipRangePtr =
nullptr;
586 SkippingRangeStateTy(Preprocessor &PP) : PP(PP) {}
588 void beginLexPass() {
594 BeginPtr = PP.CurLexer->getBufferLocation();
595 SkipRangePtr = &PP.RecordedSkippedRanges[BeginPtr];
597 PP.CurLexer->seek(PP.CurLexer->getCurrentBufferOffset() + *SkipRangePtr,
602 void endLexPass(
const char *Hashptr) {
605 assert(PP.CurLexer->isDependencyDirectivesLexer());
610 if (!*SkipRangePtr) {
611 *SkipRangePtr = Hashptr - BeginPtr;
613 assert(*SkipRangePtr ==
unsigned(Hashptr - BeginPtr));
615 SkipRangePtr =
nullptr;
617 } SkippingRangeState(*
this);
620 if (CurLexer->isDependencyDirectivesLexer()) {
621 CurLexer->LexDependencyDirectiveTokenWhileSkipping(
Tok);
623 SkippingRangeState.beginLexPass();
627 if (
Tok.
is(tok::code_completion)) {
630 CodeComplete->CodeCompleteInConditionalExclusion();
643 Tok.
is(tok::raw_identifier) &&
646 llvm::SaveAndRestore ModuleDirectiveSkipping(LastExportKeyword);
647 LastExportKeyword.startToken();
654 if (
Tok.
is(tok::raw_identifier)) {
663 llvm::SaveAndRestore RestoreLexingRawMode(CurPPLexer->LexingRawMode,
670 CurPPLexer->ParsingPreprocessorDirective =
true;
673 Diag(StartLoc, diag::err_pp_cond_span_module_decl)
674 << SourceRange(StartLoc, End);
675 CurPPLexer->ParsingPreprocessorDirective =
false;
678 CurLexer->resetExtendedTokenMode();
685 if (
Tok.
is(tok::eof)) {
689 if (PreambleConditionalStack.isRecording())
690 PreambleConditionalStack.SkipInfo.emplace(HashTokenLoc, IfTokenLoc,
703 if (
Tok.
is(tok::eof))
709 CurPPLexer->ParsingPreprocessorDirective =
true;
710 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
712 assert(
Tok.
is(tok::hash));
713 const char *Hashptr = CurLexer->getBufferLocation() -
Tok.
getLength();
714 assert(CurLexer->getSourceLocation(Hashptr) ==
Tok.
getLocation());
721 if (
Tok.
isNot(tok::raw_identifier)) {
722 CurPPLexer->ParsingPreprocessorDirective =
false;
724 if (CurLexer) CurLexer->resetExtendedTokenMode();
735 char FirstChar = RI[0];
736 if (FirstChar >=
'a' && FirstChar <=
'z' &&
737 FirstChar !=
'i' && FirstChar !=
'e') {
738 CurPPLexer->ParsingPreprocessorDirective =
false;
740 if (CurLexer) CurLexer->resetExtendedTokenMode();
747 char DirectiveBuf[20];
753 size_t IdLen = DirectiveStr.size();
755 CurPPLexer->ParsingPreprocessorDirective =
false;
757 if (CurLexer) CurLexer->resetExtendedTokenMode();
760 memcpy(DirectiveBuf, &DirectiveStr[0], IdLen);
761 Directive = StringRef(DirectiveBuf, IdLen);
781 PPConditionalInfo CondInfo;
783 bool InCond = CurPPLexer->popConditionalLevel(CondInfo);
785 assert(!InCond &&
"Can't be skipping if not in a conditional!");
789 SkippingRangeState.endLexPass(Hashptr);
792 CurPPLexer->LexingRawMode =
false;
794 CurPPLexer->LexingRawMode =
true;
801 }
else if (Sub ==
"lse") {
805 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
808 SkippingRangeState.endLexPass(Hashptr);
812 Diag(
Tok, diag::pp_err_else_after_else);
823 CurPPLexer->LexingRawMode =
false;
825 CurPPLexer->LexingRawMode =
true;
832 }
else if (Sub ==
"lif") {
833 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
836 SkippingRangeState.endLexPass(Hashptr);
853 assert(CurPPLexer->LexingRawMode &&
"We have to be skipping here!");
854 CurPPLexer->LexingRawMode =
false;
855 IdentifierInfo *IfNDefMacro =
nullptr;
856 DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
860 const bool CondValue = DER.Conditional;
861 CurPPLexer->LexingRawMode =
true;
874 }
else if (Sub ==
"lifdef" ||
876 bool IsElifDef =
Sub ==
"lifdef";
877 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
878 Token DirectiveToken =
Tok;
881 SkippingRangeState.endLexPass(Hashptr);
886 if (LangOpts.CPlusPlus)
887 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
888 : diag::ext_cxx23_pp_directive;
890 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
891 : diag::ext_c23_pp_directive;
896 Diag(
Tok, diag::pp_err_elif_after_else)
910 assert(CurPPLexer->LexingRawMode &&
"We have to be skipping here!");
911 CurPPLexer->LexingRawMode =
false;
913 ReadMacroName(MacroNameTok);
914 CurPPLexer->LexingRawMode =
true;
918 if (MacroNameTok.
is(tok::eod)) {
930 MacroInfo *MI = MD.getMacroInfo();
934 Callbacks->Elifdef(DirectiveToken.
getLocation(), MacroNameTok,
937 Callbacks->Elifndef(DirectiveToken.
getLocation(), MacroNameTok,
942 if (
static_cast<bool>(MI) == IsElifDef) {
954 CurPPLexer->ParsingPreprocessorDirective =
false;
956 if (CurLexer) CurLexer->resetExtendedTokenMode();
962 CurPPLexer->LexingRawMode =
false;
967 Callbacks->SourceRangeSkipped(
968 SourceRange(HashTokenLoc, endLoc.
isValid()
970 : CurPPLexer->getSourceLocation()),
976 if (!SourceMgr.isInMainFile(Loc)) {
979 FileID IDOfIncl = SourceMgr.getFileID(SourceMgr.getExpansionLoc(Loc));
980 if (
auto EntryOfIncl = SourceMgr.getFileEntryRefForID(IDOfIncl)) {
982 return HeaderInfo.getModuleMap()
983 .findModuleForHeader(*EntryOfIncl, AllowTextual)
992 : HeaderInfo.lookupModule(
getLangOpts().CurrentModule, Loc);
999 IncLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
1006 while (!Loc.
isInvalid() && !
SM.isInMainFile(Loc)) {
1007 auto ID =
SM.getFileID(
SM.getExpansionLoc(Loc));
1008 auto FE =
SM.getFileEntryRefForID(ID);
1014 HeaderInfo.hasModuleMap(FE->getName(),
nullptr,
1015 SourceMgr.isInSystemHeader(Loc));
1017 bool InPrivateHeader =
false;
1018 for (
auto Header : HeaderInfo.findAllModulesForHeader(*FE)) {
1019 if (!Header.isAccessibleFrom(IncM)) {
1024 InPrivateHeader =
true;
1041 return std::nullopt;
1051 if (InPrivateHeader)
1052 return std::nullopt;
1060 Loc =
SM.getIncludeLoc(ID);
1063 return std::nullopt;
1072 bool *IsFrameworkFound,
bool SkipCache,
bool OpenFile,
bool CacheFailures) {
1077 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
1082 bool BuildSystemModule =
false;
1083 if (!FromDir && !FromFile) {
1100 if (FID == SourceMgr.getMainFileID() && MainFileDir) {
1102 HeaderInfo.getModuleMap().shouldImportRelativeToBuiltinIncludeDir(
1104 ? HeaderInfo.getModuleMap().getBuiltinDir()
1106 Includers.push_back(std::make_pair(std::nullopt, *IncludeDir));
1108 }
else if ((FileEnt = SourceMgr.getFileEntryRefForID(
1109 SourceMgr.getMainFileID()))) {
1110 auto CWD = FileMgr.getOptionalDirectoryRef(
".");
1111 Includers.push_back(std::make_pair(*FileEnt, *CWD));
1114 Includers.push_back(std::make_pair(*FileEnt, FileEnt->
getDir()));
1120 if (LangOpts.MSVCCompat && !isAngled) {
1121 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1122 if (IsFileLexer(ISEntry))
1124 Includers.push_back(std::make_pair(*FileEnt, FileEnt->
getDir()));
1129 CurDir = CurDirLookup;
1137 Filename, FilenameLoc, isAngled, TmpFromDir, &TmpCurDir,
1138 Includers, SearchPath, RelativePath, RequestingModule,
1139 SuggestedModule,
nullptr,
1140 nullptr, SkipCache)) {
1142 TmpFromDir = TmpCurDir;
1144 if (&FE->getFileEntry() == FromFile) {
1146 FromDir = TmpFromDir;
1155 Filename, FilenameLoc, isAngled, FromDir, &CurDir, Includers, SearchPath,
1156 RelativePath, RequestingModule, SuggestedModule, IsMapped,
1157 IsFrameworkFound, SkipCache, BuildSystemModule, OpenFile, CacheFailures);
1165 if (IsFileLexer()) {
1168 Filename, *CurFileEnt, SearchPath, RelativePath, RequestingModule,
1175 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1176 if (IsFileLexer(ISEntry)) {
1177 if ((CurFileEnt = ISEntry.ThePPLexer->
getFileEntry())) {
1179 Filename, *CurFileEnt, SearchPath, RelativePath,
1180 RequestingModule, SuggestedModule)) {
1188 return std::nullopt;
1195 if (llvm::sys::path::is_absolute(Filename)) {
1202 StringRef StartingFrom, StringRef
FileName,
1203 bool RemoveInitialFileComponentFromLookupPath) {
1204 llvm::sys::path::native(StartingFrom, LookupPath);
1205 if (RemoveInitialFileComponentFromLookupPath)
1206 llvm::sys::path::remove_filename(LookupPath);
1207 if (!LookupPath.empty() &&
1208 !llvm::sys::path::is_separator(LookupPath.back())) {
1209 LookupPath.push_back(llvm::sys::path::get_separator().front());
1219 if (LookupFromFile) {
1223 llvm::sys::path::append(TmpDir, Filename);
1224 if (!TmpDir.empty()) {
1226 TmpDir, OpenFile,
true,
false);
1228 return ShouldBeEntry;
1235 if (MaybeWorkingDirEntry) {
1237 StringRef WorkingDir = WorkingDirEntry.
getName();
1238 if (!WorkingDir.empty()) {
1239 SeparateComponents(LookupPath, WorkingDir, Filename,
false);
1241 LookupPath, OpenFile,
true,
false);
1243 return ShouldBeEntry;
1248 for (
const auto &Entry : PPOpts.EmbedEntries) {
1250 SeparateComponents(LookupPath, Entry, Filename,
false);
1252 LookupPath, OpenFile,
true,
false);
1254 return ShouldBeEntry;
1256 return std::nullopt;
1266 : PP(pp), save(pp->DisableMacroExpansion) {
1267 if (pp->MacroExpansionInDirectivesOverride)
1268 pp->DisableMacroExpansion =
false;
1272 PP->DisableMacroExpansion = save;
1290 return HandleDefineDirective(
Result,
1293 if (SkippingUntilPCHThroughHeader &&
1295 return HandleIncludeDirective(HashLoc,
Result);
1297 if (SkippingUntilPragmaHdrStop && II->
getPPKeywordID() == tok::pp_pragma) {
1299 auto *II =
Result.getIdentifierInfo();
1300 if (II && II->
getName() ==
"hdrstop")
1317 CurPPLexer->ParsingPreprocessorDirective =
true;
1318 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
1320 bool ImmediatelyAfterTopLevelIfndef =
1321 CurPPLexer->MIOpt.getImmediatelyAfterTopLevelIfndef();
1322 CurPPLexer->MIOpt.resetImmediatelyAfterTopLevelIfndef();
1329 bool ReadAnyTokensBeforeDirective =CurPPLexer->MIOpt.getHasReadAnyTokensVal();
1337 if (Introducer.
isOneOf(tok::hash, tok::at))
1351 case tok::pp_include:
1352 case tok::pp_import:
1353 case tok::pp_include_next:
1354 case tok::pp___include_macros:
1355 case tok::pp_pragma:
1357 case tok::pp_module:
1358 case tok::pp___preprocessed_module:
1359 case tok::pp___preprocessed_import:
1361 << Introducer.
is(tok::hash) << II->
getName();
1362 Diag(*ArgMacro, diag::note_macro_expansion_here)
1363 << ArgMacro->getIdentifierInfo();
1377 if (SkippingUntilPCHThroughHeader || SkippingUntilPragmaHdrStop)
1381 switch (
Result.getKind()) {
1386 CurPPLexer->MIOpt.SetReadToken(ReadAnyTokensBeforeDirective);
1388 case tok::code_completion:
1391 CodeComplete->CodeCompleteDirective(
1392 CurPPLexer->getConditionalStackDepth() > 0);
1394 case tok::numeric_constant:
1401 return HandleDigitDirective(
Result);
1411 return HandleIfDirective(
Result, Introducer,
1412 ReadAnyTokensBeforeDirective);
1414 return HandleIfdefDirective(
Result, Introducer,
false,
1416 case tok::pp_ifndef:
1417 return HandleIfdefDirective(
Result, Introducer,
true,
1418 ReadAnyTokensBeforeDirective);
1420 case tok::pp_elifdef:
1421 case tok::pp_elifndef:
1422 return HandleElifFamilyDirective(
Result, Introducer,
1426 return HandleElseDirective(
Result, Introducer);
1428 return HandleEndifDirective(
Result);
1431 case tok::pp_include:
1434 case tok::pp___include_macros:
1439 case tok::pp_define:
1440 return HandleDefineDirective(
Result, ImmediatelyAfterTopLevelIfndef);
1442 return HandleUndefDirective();
1446 return HandleLineDirective();
1450 return HandleUserDiagnosticDirective(
Result,
false);
1453 case tok::pp_pragma:
1455 case tok::pp_module:
1456 case tok::pp___preprocessed_module:
1460 case tok::pp___preprocessed_import:
1462 case tok::pp_import:
1463 switch (Introducer.
getKind()) {
1467 return HandleObjCImportDirective(Introducer,
Result);
1468 case tok::kw_import:
1471 llvm_unreachable(
"not a valid import directive");
1475 case tok::pp_include_next:
1478 case tok::pp_warning:
1479 if (LangOpts.CPlusPlus)
1481 ? diag::warn_cxx23_compat_warning_directive
1482 : diag::ext_pp_warning_directive)
1485 Diag(
Result, LangOpts.C23 ? diag::warn_c23_compat_warning_directive
1486 : diag::ext_pp_warning_directive)
1489 return HandleUserDiagnosticDirective(
Result,
true);
1491 return HandleIdentSCCSDirective(
Result);
1493 return HandleIdentSCCSDirective(
Result);
1496 case tok::pp_assert:
1499 case tok::pp_unassert:
1503 case tok::pp___public_macro:
1505 return HandleMacroPublicDirective(
Result);
1508 case tok::pp___private_macro:
1510 return HandleMacroPrivateDirective();
1521 auto Toks = std::make_unique<Token[]>(2);
1523 Toks[0] = Introducer;
1528 if (
Result.is(tok::hashhash))
1529 Toks[1].setKind(tok::unknown);
1534 EnterTokenStream(std::move(Toks), 2,
false,
false);
1540 Diag(
Result, diag::err_pp_invalid_directive) << 0;
1552 bool IsGNULineDirective=
false) {
1553 if (DigitTok.
isNot(tok::numeric_constant)) {
1554 PP.
Diag(DigitTok, DiagID);
1556 if (DigitTok.
isNot(tok::eod))
1562 IntegerBuffer.resize(DigitTok.
getLength());
1563 const char *DigitTokBegin = &IntegerBuffer[0];
1573 for (
unsigned i = 0; i != ActualLength; ++i) {
1576 if (DigitTokBegin[i] ==
'\'')
1579 if (!
isDigit(DigitTokBegin[i])) {
1581 diag::err_pp_line_digit_sequence) << IsGNULineDirective;
1586 unsigned NextVal = Val*10+(DigitTokBegin[i]-
'0');
1587 if (NextVal < Val) {
1588 PP.
Diag(DigitTok, DiagID);
1595 if (DigitTokBegin[0] ==
'0' && Val)
1597 << IsGNULineDirective;
1609void Preprocessor::HandleLineDirective() {
1617 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*
this))
1621 Diag(DigitTok, diag::ext_pp_line_zero);
1625 unsigned LineLimit = 32768U;
1626 if (LangOpts.C99 || LangOpts.CPlusPlus11)
1627 LineLimit = 2147483648U;
1628 if (LineNo >= LineLimit)
1629 Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
1630 else if (LangOpts.CPlusPlus11 && LineNo >= 32768U)
1631 Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
1633 int FilenameID = -1;
1639 if (StrTok.
is(tok::eod))
1641 else if (StrTok.
isNot(tok::header_name)) {
1642 Diag(StrTok, diag::err_pp_line_invalid_filename);
1646 SmallString<128> FilenameBuffer;
1647 StringRef Filename =
getSpelling(StrTok, FilenameBuffer);
1649 FilenameID = SourceMgr.getLineTableFilenameID(Filename);
1662 SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1664 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID,
false,
1668 Callbacks->FileChanged(CurPPLexer->getSourceLocation(),
1680 if (FlagTok.
is(tok::eod))
return false;
1681 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1688 if (FlagTok.
is(tok::eod))
return false;
1689 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1691 }
else if (FlagVal == 2) {
1707 SM.getDecomposedExpansionLoc(IncLoc).first != CurFileID) {
1708 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);
1714 if (FlagTok.
is(tok::eod))
return false;
1715 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1721 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1729 if (FlagTok.
is(tok::eod))
return false;
1730 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1735 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1743 if (FlagTok.
is(tok::eod))
return false;
1746 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1758void Preprocessor::HandleDigitDirective(
Token &DigitTok) {
1762 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
1769 bool IsFileEntry =
false, IsFileExit =
false;
1770 int FilenameID = -1;
1775 if (StrTok.
is(tok::eod)) {
1776 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1778 FileKind = SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1779 }
else if (StrTok.
isNot(tok::header_name)) {
1780 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1784 SmallString<128> FilenameBuffer;
1785 StringRef Filename =
getSpelling(StrTok, FilenameBuffer);
1790 if (!SourceMgr.isInPredefinedFile(DigitTok.
getLocation()))
1791 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1795 if (!(IsFileExit && Filename.empty()))
1796 FilenameID = SourceMgr.getLineTableFilenameID(Filename);
1800 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID, IsFileEntry,
1801 IsFileExit, FileKind);
1810 else if (IsFileExit)
1813 Callbacks->FileChanged(CurPPLexer->getSourceLocation(), Reason, FileKind);
1819void Preprocessor::HandleUserDiagnosticDirective(
Token &
Tok,
1827 CurLexer->ReadToEndOfLine(&Message);
1831 StringRef Msg =
Message.str().ltrim(
' ');
1834 Diag(
Tok, diag::pp_hash_warning) << Msg;
1836 Diag(
Tok, diag::err_pp_hash_error) << Msg;
1841void Preprocessor::HandleIdentSCCSDirective(
Token &
Tok) {
1843 Diag(
Tok, diag::ext_pp_ident_directive);
1850 if (StrTok.
isNot(tok::string_literal) &&
1851 StrTok.
isNot(tok::wide_string_literal)) {
1852 Diag(StrTok, diag::err_pp_malformed_ident);
1853 if (StrTok.
isNot(tok::eod))
1859 Diag(StrTok, diag::err_invalid_string_udl);
1876void Preprocessor::HandleMacroPublicDirective(
Token &
Tok) {
1878 ReadMacroName(MacroNameTok,
MU_Undef);
1881 if (MacroNameTok.
is(tok::eod))
1893 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1903void Preprocessor::HandleMacroPrivateDirective() {
1905 ReadMacroName(MacroNameTok,
MU_Undef);
1908 if (MacroNameTok.
is(tok::eod))
1920 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1940 StringRef &Buffer) {
1942 assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1954 if (Buffer[0] ==
'<') {
1955 if (Buffer.back() !=
'>') {
1956 Diag(Loc, diag::err_pp_expects_filename);
1957 Buffer = StringRef();
1961 }
else if (Buffer[0] ==
'"') {
1962 if (Buffer.back() !=
'"') {
1963 Diag(Loc, diag::err_pp_expects_filename);
1964 Buffer = StringRef();
1969 Diag(Loc, diag::err_pp_expects_filename);
1970 Buffer = StringRef();
1975 if (Buffer.size() <= 2) {
1976 Diag(Loc, diag::err_pp_empty_filename);
1977 Buffer = StringRef();
1982 Buffer = Buffer.substr(1, Buffer.size()-2);
1987 StringRef &Buffer) {
1989 assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1990 if (Buffer.size() < 2 || Buffer.front() !=
'"' || Buffer.back() !=
'"') {
1991 Diag(Loc, diag::err_pp_line_invalid_filename);
1992 Buffer = StringRef();
1995 Buffer = Buffer.substr(1, Buffer.size() - 2);
2001 void *AnnotationVal) {
2004 auto Tok = std::make_unique<Token[]>(1);
2005 Tok[0].startToken();
2006 Tok[0].setKind(Kind);
2007 Tok[0].setLocation(Range.getBegin());
2008 Tok[0].setAnnotationEndLoc(Range.getEnd());
2009 Tok[0].setAnnotationValue(AnnotationVal);
2010 EnterTokenStream(std::move(
Tok), 1,
true,
false);
2020 for (
size_t I = 0, N = Path.size(); I != N; ++I) {
2023 PathString += Path[I].getIdentifierInfo()->getName();
2026 int IncludeKind = 0;
2028 case tok::pp_include:
2032 case tok::pp_import:
2036 case tok::pp_include_next:
2040 case tok::pp___include_macros:
2045 llvm_unreachable(
"unknown include directive kind");
2048 PP.
Diag(HashLoc, diag::remark_pp_include_directive_modular_translation)
2049 << IncludeKind << PathString;
2056 StringRef RealPathName,
2057 llvm::sys::path::Style Separator) {
2058 auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName);
2059 auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName);
2061 bool SuggestReplacement =
false;
2063 auto IsSep = [Separator](StringRef Component) {
2064 return Component.size() == 1 &&
2065 llvm::sys::path::is_separator(Component[0], Separator);
2070 for (
auto &Component : llvm::reverse(Components)) {
2071 if (
"." == Component) {
2072 }
else if (
".." == Component) {
2076 }
else if (RealPathComponentIter != RealPathComponentEnd) {
2077 if (!IsSep(Component) && !IsSep(*RealPathComponentIter) &&
2078 Component != *RealPathComponentIter) {
2082 SuggestReplacement =
2083 RealPathComponentIter->equals_insensitive(Component);
2084 if (!SuggestReplacement)
2086 Component = *RealPathComponentIter;
2088 ++RealPathComponentIter;
2091 return SuggestReplacement;
2100 Module *ShadowingModule =
nullptr;
2106 Diags.Report(MissingHeader.
FileNameLoc, diag::err_module_header_missing)
2108 }
else if (ShadowingModule) {
2111 diag::note_previous_definition);
2122std::pair<ConstSearchDirIterator, const FileEntry *>
2123Preprocessor::getIncludeNextStart(
const Token &IncludeNextTok)
const {
2128 const FileEntry *LookupFromFile =
nullptr;
2136 Diag(IncludeNextTok, diag::pp_include_next_in_primary);
2137 }
else if (CurLexerSubmodule) {
2140 assert(CurPPLexer &&
"#include_next directive in macro?");
2141 if (
auto FE = CurPPLexer->getFileEntry())
2142 LookupFromFile = *FE;
2144 }
else if (!Lookup) {
2149 Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
2155 return {Lookup, LookupFromFile};
2171 if (FilenameTok.
isNot(tok::header_name)) {
2172 if (FilenameTok.
is(tok::identifier) &&
2173 (PPOpts.SingleFileParseMode || PPOpts.SingleModuleParseMode)) {
2183 if (FilenameTok.
isNot(tok::eod))
2192 SourceLocation EndLoc =
2195 auto Action = HandleHeaderIncludeOrImport(HashLoc, IncludeTok, FilenameTok,
2196 EndLoc, LookupFrom, LookupFromFile);
2197 switch (Action.Kind) {
2198 case ImportAction::None:
2199 case ImportAction::SkippedModuleImport:
2201 case ImportAction::ModuleBegin:
2203 tok::annot_module_begin, Action.ModuleForHeader);
2205 case ImportAction::HeaderUnitImport:
2207 Action.ModuleForHeader);
2209 case ImportAction::ModuleImport:
2211 tok::annot_module_include, Action.ModuleForHeader);
2213 case ImportAction::Failure:
2214 assert(TheModuleLoader.HadFatalFailure &&
2215 "This should be an early exit only to a fatal error");
2216 TheModuleLoader.HadFatalFailure =
true;
2218 CurLexer->cutOffLexing();
2226 const Token &FilenameTok,
bool &IsFrameworkFound,
bool IsImportDecl,
2228 const FileEntry *LookupFromFile, StringRef &LookupFilename,
2231 auto DiagnoseHeaderInclusion = [&](FileEntryRef FE) {
2232 if (LangOpts.AsmPreprocessor)
2236 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
2237 bool RequestingModuleIsModuleInterface =
2238 !SourceMgr.isInMainFile(FilenameLoc);
2240 HeaderInfo.getModuleMap().diagnoseHeaderInclusion(
2241 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
2246 FilenameLoc, LookupFilename, isAngled, LookupFrom, LookupFromFile, CurDir,
2247 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2248 &SuggestedModule, &IsMapped, &IsFrameworkFound);
2250 DiagnoseHeaderInclusion(*
File);
2255 if (Callbacks && Callbacks->FileNotFound(Filename))
2256 return std::nullopt;
2258 if (SuppressIncludeNotFoundError)
2259 return std::nullopt;
2266 FilenameLoc, LookupFilename,
false, LookupFrom, LookupFromFile, CurDir,
2267 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2268 &SuggestedModule, &IsMapped,
2271 DiagnoseHeaderInclusion(*
File);
2272 Diag(FilenameTok, diag::err_pp_file_not_found_angled_include_not_fatal)
2273 << Filename << IsImportDecl
2275 "\"" + Filename.str() +
"\"");
2282 StringRef OriginalFilename = Filename;
2283 if (LangOpts.SpellChecking) {
2286 auto CorrectTypoFilename = [](llvm::StringRef Filename) {
2289 Filename = Filename.drop_back();
2293 StringRef TypoCorrectionName = CorrectTypoFilename(Filename);
2294 StringRef TypoCorrectionLookupName = CorrectTypoFilename(LookupFilename);
2297 FilenameLoc, TypoCorrectionLookupName, isAngled, LookupFrom,
2298 LookupFromFile, CurDir, Callbacks ? &SearchPath :
nullptr,
2299 Callbacks ? &RelativePath :
nullptr, &SuggestedModule, &IsMapped,
2302 DiagnoseHeaderInclusion(*
File);
2305 FilenameRange,
"<" + TypoCorrectionName.str() +
">")
2306 : FixItHint::CreateReplacement(
2307 FilenameRange,
"\"" + TypoCorrectionName.str() +
"\"");
2308 Diag(FilenameTok, diag::err_pp_file_not_found_typo_not_fatal)
2309 << OriginalFilename << TypoCorrectionName << Hint;
2312 Filename = TypoCorrectionName;
2313 LookupFilename = TypoCorrectionLookupName;
2319 assert(!
File &&
"expected missing file");
2320 Diag(FilenameTok, diag::err_pp_file_not_found)
2321 << OriginalFilename << FilenameRange;
2322 if (IsFrameworkFound) {
2323 size_t SlashPos = OriginalFilename.find(
'/');
2324 assert(SlashPos != StringRef::npos &&
2325 "Include with framework name should have '/' in the filename");
2326 StringRef FrameworkName = OriginalFilename.substr(0, SlashPos);
2327 FrameworkCacheEntry &CacheEntry =
2328 HeaderInfo.LookupFrameworkCache(FrameworkName);
2329 assert(CacheEntry.
Directory &&
"Found framework should be in cache");
2330 Diag(FilenameTok, diag::note_pp_framework_without_header)
2331 << OriginalFilename.substr(SlashPos + 1) << FrameworkName
2335 return std::nullopt;
2350Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
2354 SmallString<128> FilenameBuffer;
2355 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
2356 SourceLocation CharEnd = FilenameTok.
getEndLoc();
2358 CharSourceRange FilenameRange
2360 StringRef OriginalFilename = Filename;
2366 if (Filename.empty())
2367 return {ImportAction::None};
2368 if (Filename.ends_with(
' ') || Filename.ends_with(
'.')) {
2369 unsigned Selection = Filename.ends_with(
'.') ? 1 : 0;
2370 Diag(FilenameTok, diag::pp_nonportable_path_trailing)
2371 << Filename << Selection;
2374 bool IsImportDecl = HashLoc.
isInvalid();
2375 SourceLocation StartLoc = IsImportDecl ? IncludeTok.
getLocation() : HashLoc;
2378 if (PragmaARCCFCodeAuditedInfo.getLoc().isValid()) {
2379 Diag(StartLoc, diag::err_pp_include_in_arc_cf_code_audited) << IsImportDecl;
2380 Diag(PragmaARCCFCodeAuditedInfo.getLoc(), diag::note_pragma_entered_here);
2383 PragmaARCCFCodeAuditedInfo = IdentifierLoc();
2387 if (PragmaAssumeNonNullLoc.isValid()) {
2388 Diag(StartLoc, diag::err_pp_include_in_assume_nonnull) << IsImportDecl;
2389 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
2392 PragmaAssumeNonNullLoc = SourceLocation();
2395 if (HeaderInfo.HasIncludeAliasMap()) {
2399 StringRef NewName = HeaderInfo.MapHeaderToIncludeAlias(OriginalFilename);
2400 if (!NewName.empty())
2405 bool IsMapped =
false;
2406 bool IsFrameworkFound =
false;
2408 SmallString<1024> SearchPath;
2409 SmallString<1024> RelativePath;
2412 ModuleMap::KnownHeader SuggestedModule;
2413 SourceLocation FilenameLoc = FilenameTok.
getLocation();
2414 StringRef LookupFilename = Filename;
2418 SmallString<128> NormalizedPath;
2419 llvm::sys::path::Style BackslashStyle = llvm::sys::path::Style::native;
2420 if (is_style_posix(BackslashStyle) && LangOpts.MicrosoftExt) {
2421 NormalizedPath = Filename.str();
2422 llvm::sys::path::native(NormalizedPath);
2423 LookupFilename = NormalizedPath;
2424 BackslashStyle = llvm::sys::path::Style::windows;
2428 &CurDir, Filename, FilenameLoc, FilenameRange, FilenameTok,
2429 IsFrameworkFound, IsImportDecl, IsMapped, LookupFrom, LookupFromFile,
2430 LookupFilename, RelativePath, SearchPath, SuggestedModule, isAngled);
2434 SkippingUntilPCHThroughHeader =
false;
2435 return {ImportAction::None};
2453 enum { Enter,
Import,
Skip, IncludeLimitReached } Action = Enter;
2455 if (PPOpts.SingleFileParseMode)
2456 Action = IncludeLimitReached;
2461 if (Action == Enter && HasReachedMaxIncludeDepth &&
File &&
2463 Action = IncludeLimitReached;
2470 bool MaybeTranslateInclude = Action == Enter &&
File && ModuleToImport &&
2474 bool UsableHeaderUnit =
false;
2475 if (
getLangOpts().CPlusPlusModules && ModuleToImport &&
2477 if (TrackGMFState.inGMF() || IsImportDecl)
2478 UsableHeaderUnit =
true;
2479 else if (!IsImportDecl) {
2481 ModuleToImport =
nullptr;
2485 bool UsableClangHeaderModule =
2492 if (MaybeTranslateInclude && (UsableHeaderUnit || UsableClangHeaderModule)) {
2500 diag::note_implicit_top_level_module_import_here)
2502 return {ImportAction::None};
2508 SmallVector<IdentifierLoc, 2> Path;
2509 for (
Module *Mod = ModuleToImport; Mod; Mod = Mod->Parent)
2512 std::reverse(Path.begin(), Path.end());
2522 ModuleLoadResult Imported = TheModuleLoader.loadModule(
2525 assert((Imported ==
nullptr || Imported == ModuleToImport) &&
2526 "the imported module is different than the suggested one");
2532 static_cast<Module *
>(Imported)->getTopLevelModule());
2537 ModuleToImport =
nullptr;
2545 Token &
Result = IncludeTok;
2546 assert(CurLexer &&
"#include but no current lexer set!");
2548 CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
2549 CurLexer->cutOffLexing();
2551 return {ImportAction::None};
2559 SourceMgr.getFileCharacteristic(FilenameTok.
getLocation());
2561 FileCharacter = std::max(HeaderInfo.getFileDirFlavor(*
File), FileCharacter);
2572 bool IsFirstIncludeOfFile =
false;
2576 if (Action == Enter &&
File &&
2577 !HeaderInfo.ShouldEnterIncludeFile(*
this, *
File, EnterOnce,
2579 IsFirstIncludeOfFile)) {
2590 if (UsableHeaderUnit && !
getLangOpts().CompilingPCH)
2591 Action = TrackGMFState.inGMF() ?
Import :
Skip;
2593 Action = (ModuleToImport && !
getLangOpts().CompilingPCH) ? Import :
Skip;
2601 if (Action == Enter &&
File && PreambleConditionalStack.isRecording() &&
2602 SourceMgr.isMainFile(
File->getFileEntry())) {
2604 diag::err_pp_including_mainfile_in_preamble);
2605 return {ImportAction::None};
2608 if (Callbacks && !IsImportDecl) {
2611 Callbacks->InclusionDirective(HashLoc, IncludeTok, LookupFilename, isAngled,
2612 FilenameRange,
File, SearchPath, RelativePath,
2613 SuggestedModule.
getModule(), Action == Import,
2616 Callbacks->FileSkipped(*
File, FilenameTok, FileCharacter);
2620 return {ImportAction::None};
2624 if (IsImportDecl && !ModuleToImport) {
2625 Diag(FilenameTok, diag::err_header_import_not_header_unit)
2626 << OriginalFilename <<
File->getName();
2627 return {ImportAction::None};
2632 const bool CheckIncludePathPortability =
2633 !IsMapped && !
File->getFileEntry().tryGetRealPathName().empty();
2635 if (CheckIncludePathPortability) {
2636 StringRef Name = LookupFilename;
2637 StringRef NameWithoriginalSlashes = Filename;
2641 bool NameWasUNC = Name.consume_front(
"\\\\?\\");
2642 NameWithoriginalSlashes.consume_front(
"\\\\?\\");
2644 StringRef RealPathName =
File->getFileEntry().tryGetRealPathName();
2645 SmallVector<StringRef, 16> Components(llvm::sys::path::begin(Name),
2646 llvm::sys::path::end(Name));
2658 SmallString<128> FixedDriveRealPath;
2659 if (llvm::sys::path::is_absolute(Name) &&
2660 llvm::sys::path::is_absolute(RealPathName) &&
2663 assert(Components.size() >= 3 &&
"should have drive, backslash, name");
2664 assert(Components[0].size() == 2 &&
"should start with drive");
2665 assert(Components[0][1] ==
':' &&
"should have colon");
2666 FixedDriveRealPath = (Name.substr(0, 1) + RealPathName.substr(1)).str();
2667 RealPathName = FixedDriveRealPath;
2672 SmallString<128> Path;
2673 Path.reserve(Name.size()+2);
2674 Path.push_back(isAngled ?
'<' :
'"');
2676 const auto IsSep = [BackslashStyle](
char c) {
2677 return llvm::sys::path::is_separator(c, BackslashStyle);
2680 for (
auto Component : Components) {
2692 if (!(Component.size() == 1 && IsSep(Component[0])))
2693 Path.append(Component);
2694 else if (Path.size() != 1)
2698 if (Path.size() > NameWithoriginalSlashes.size()) {
2699 Path.push_back(isAngled ?
'>' :
'"');
2702 assert(IsSep(NameWithoriginalSlashes[Path.size()-1]));
2704 Path.push_back(NameWithoriginalSlashes[Path.size()-1]);
2705 while (Path.size() <= NameWithoriginalSlashes.size() &&
2706 IsSep(NameWithoriginalSlashes[Path.size()-1]));
2712 Path = (Path.substr(0, 1) +
"\\\\?\\" + Path.substr(1)).str();
2719 ? diag::pp_nonportable_path
2720 : diag::pp_nonportable_system_path;
2721 Diag(FilenameTok, DiagId) << Path <<
2725 bool SuppressBackslashDiag =
2727 Diags->isIgnored(diag::pp_nonportable_path_separator, FilenameLoc) ||
2730 SourceMgr.isWrittenInBuiltinFile(FilenameLoc) ||
2731 SourceMgr.isWrittenInModuleIncludes(FilenameLoc);
2732 if (!SuppressBackslashDiag && OriginalFilename.contains(
'\\')) {
2733 std::string SuggestedPath = OriginalFilename.str();
2734 llvm::replace(SuggestedPath,
'\\',
'/');
2735 Diag(FilenameTok, diag::pp_nonportable_path_separator)
2744 return {ImportAction::SkippedModuleImport, ModuleToImport};
2745 return {ImportAction::None};
2747 case IncludeLimitReached:
2750 return {ImportAction::None};
2754 assert(ModuleToImport &&
"no module to import");
2759 tok::pp___include_macros)
2760 return {ImportAction::None};
2762 return {ImportAction::ModuleImport, ModuleToImport};
2770 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
2771 Diag(FilenameTok, diag::err_pp_include_too_deep);
2772 HasReachedMaxIncludeDepth =
true;
2773 return {ImportAction::None};
2777 Diag(FilenameTok, diag::warn_pp_include_angled_in_module_purview)
2781 SourceLocation IncludePos = FilenameTok.
getLocation();
2785 IncludePos = SourceMgr.getExpansionRange(IncludePos).getEnd();
2786 FileID FID = SourceMgr.createFileID(*
File, IncludePos, FileCharacter);
2788 TheModuleLoader.HadFatalFailure =
true;
2789 return ImportAction::Failure;
2794 IsFirstIncludeOfFile))
2795 return {ImportAction::None};
2799 if (ModuleToImport && !ModuleToImport->
isHeaderUnit()) {
2804 diag::err_module_build_shadowed_submodule)
2807 diag::note_previous_definition);
2808 return {ImportAction::None};
2820 return {ImportAction::None};
2822 assert(!CurLexerSubmodule &&
"should not have marked this as a module yet");
2823 CurLexerSubmodule = ModuleToImport;
2833 return {ImportAction::ModuleBegin, ModuleToImport};
2836 assert(!IsImportDecl &&
"failed to diagnose missing module for import decl");
2837 return {ImportAction::None};
2842void Preprocessor::HandleIncludeNextDirective(
SourceLocation HashLoc,
2843 Token &IncludeNextTok) {
2844 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
2847 const FileEntry *LookupFromFile;
2848 std::tie(Lookup, LookupFromFile) = getIncludeNextStart(IncludeNextTok);
2850 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
2855void Preprocessor::HandleMicrosoftImportDirective(
Token &
Tok) {
2861 Diag(
Tok, diag::err_pp_import_directive_ms );
2872 if (!LangOpts.ObjC) {
2873 if (LangOpts.MSVCCompat)
2874 return HandleMicrosoftImportDirective(ImportTok);
2875 Diag(ImportTok, diag::ext_pp_import_directive);
2877 return HandleIncludeDirective(HashLoc, ImportTok);
2884void Preprocessor::HandleIncludeMacrosDirective(
SourceLocation HashLoc,
2885 Token &IncludeMacrosTok) {
2888 SourceLocation Loc = IncludeMacrosTok.
getLocation();
2889 if (SourceMgr.getBufferName(Loc) !=
"<built-in>") {
2891 diag::pp_include_macros_out_of_predefines);
2898 HandleIncludeDirective(HashLoc, IncludeMacrosTok);
2903 assert(TmpTok.
isNot(tok::eof) &&
"Didn't find end of -imacros!");
2904 }
while (TmpTok.
isNot(tok::hashhash));
2926 Diag(
Tok, diag::err_pp_expected_ident_in_arg_list);
2930 Diag(
Tok, LangOpts.CPlusPlus11 ?
2931 diag::warn_cxx98_compat_variadic_macro :
2932 diag::ext_variadic_macro);
2935 if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus) {
2936 Diag(
Tok, diag::ext_pp_opencl_variadic_macros);
2942 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2951 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2959 Diag(
Tok, diag::err_pp_invalid_tok_in_arg_list);
2965 if (llvm::is_contained(Parameters, II)) {
2966 Diag(
Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
2978 Diag(
Tok, diag::err_pp_expected_comma_in_arg_list);
2987 Diag(
Tok, diag::ext_named_variadic_macro);
2992 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
3022 StringRef ValueText = II->
getName();
3023 StringRef TrimmedValue = ValueText;
3024 if (!ValueText.starts_with(
"__")) {
3025 if (ValueText.starts_with(
"_"))
3026 TrimmedValue = TrimmedValue.drop_front(1);
3030 TrimmedValue = TrimmedValue.drop_front(2);
3031 if (TrimmedValue.ends_with(
"__"))
3032 TrimmedValue = TrimmedValue.drop_back(2);
3034 return TrimmedValue == MacroText;
3041 return MacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
3054MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
3055 const Token &MacroNameTok,
const bool ImmediatelyAfterHeaderGuard) {
3057 Token LastTok = MacroNameTok;
3065 llvm::scope_exit _([&]() {
3067 if (CurLexer->ParsingPreprocessorDirective)
3078 if (
Tok.
is(tok::eod)) {
3079 if (ImmediatelyAfterHeaderGuard) {
3089 }
else if (
Tok.
is(tok::l_paren)) {
3092 if (ReadMacroParameterList(MI, LastTok))
3106 }
else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
3109 Diag(
Tok, diag::ext_c99_whitespace_required_after_macro_name);
3118 if (
Tok.
is(tok::at))
3120 else if (
Tok.
is(tok::unknown)) {
3127 Diag(
Tok, diag::ext_missing_whitespace_after_macro_name);
3129 Diag(
Tok, diag::warn_missing_whitespace_after_macro_name);
3132 if (!
Tok.
is(tok::eod))
3135 SmallVector<Token, 16> Tokens;
3142 Tokens.push_back(
Tok);
3156 if (!
Tok.
isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
3157 Tokens.push_back(
Tok);
3159 if (VAOCtx.isVAOptToken(
Tok)) {
3161 if (VAOCtx.isInVAOpt()) {
3162 Diag(
Tok, diag::err_pp_vaopt_nested_use);
3168 Diag(
Tok, diag::err_pp_missing_lparen_in_vaopt_use);
3171 Tokens.push_back(
Tok);
3174 if (
Tok.
is(tok::hashhash)) {
3175 Diag(
Tok, diag::err_vaopt_paste_at_start);
3179 }
else if (VAOCtx.isInVAOpt()) {
3180 if (
Tok.
is(tok::r_paren)) {
3181 if (VAOCtx.sawClosingParen()) {
3182 assert(Tokens.size() >= 3 &&
3183 "Must have seen at least __VA_OPT__( "
3184 "and a subsequent tok::r_paren");
3185 if (Tokens[Tokens.size() - 2].is(tok::hashhash)) {
3186 Diag(
Tok, diag::err_vaopt_paste_at_end);
3190 }
else if (
Tok.
is(tok::l_paren)) {
3204 Tokens.push_back(
Tok);
3211 if (
Tok.
is(tok::hashhash)) {
3219 if (
Tok.
is(tok::eod)) {
3220 Tokens.push_back(LastTok);
3225 Tokens[Tokens.size() - 1].is(tok::comma))
3229 Tokens.push_back(LastTok);
3238 if (!VAOCtx.isVAOptToken(
Tok) &&
3247 LastTok.
setKind(tok::unknown);
3248 Tokens.push_back(LastTok);
3251 Diag(
Tok, diag::err_pp_stringize_not_parameter)
3252 << LastTok.
is(tok::hashat);
3258 Tokens.push_back(LastTok);
3263 if (!VAOCtx.isVAOptToken(
Tok)) {
3264 Tokens.push_back(
Tok);
3271 if (VAOCtx.isInVAOpt()) {
3272 assert(
Tok.
is(tok::eod) &&
"Must be at End Of preprocessing Directive");
3273 Diag(
Tok, diag::err_pp_expected_after)
3274 << LastTok.
getKind() << tok::r_paren;
3275 Diag(VAOCtx.getUnmatchedOpeningParenLoc(), diag::note_matching) << tok::l_paren;
3286 return II->
isStr(
"__strong") || II->
isStr(
"__weak") ||
3287 II->
isStr(
"__unsafe_unretained") || II->
isStr(
"__autoreleasing");
3292void Preprocessor::HandleDefineDirective(
3293 Token &DefineTok,
const bool ImmediatelyAfterHeaderGuard) {
3297 bool MacroShadowsKeyword;
3298 ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
3301 if (MacroNameTok.
is(tok::eod))
3308 emitFinalMacroWarning(MacroNameTok,
false);
3312 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
3314 MacroInfo *
const MI = ReadOptionalMacroParameterListAndBody(
3315 MacroNameTok, ImmediatelyAfterHeaderGuard);
3319 if (MacroShadowsKeyword &&
3321 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
3326 if (NumTokens != 0) {
3338 if (SkippingUntilPCHThroughHeader) {
3341 LangOpts.MicrosoftExt))
3345 if (!LangOpts.MicrosoftExt)
3356 emitFinalMacroWarning(MacroNameTok,
false);
3367 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) &&
3369 LangOpts.MicrosoftExt)) {
3380 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) {
3388 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
3392 !MI->
isIdenticalTo(*OtherMI, *
this, LangOpts.MicrosoftExt)) {
3402 DefMacroDirective *MD =
3410 !MacroExpansionInDirectivesOverride &&
3419 Callbacks->MacroDefined(MacroNameTok, MD);
3424void Preprocessor::HandleUndefDirective() {
3428 ReadMacroName(MacroNameTok,
MU_Undef);
3431 if (MacroNameTok.
is(tok::eod))
3440 UndefMacroDirective *Undef =
nullptr;
3443 emitFinalMacroWarning(MacroNameTok,
true);
3453 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
3458 Undef = AllocateUndefMacroDirective(MacroNameTok.
getLocation());
3464 Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
3479void Preprocessor::HandleIfdefDirective(
Token &
Result,
3480 const Token &HashToken,
3482 bool ReadAnyTokensBeforeDirective) {
3484 Token DirectiveTok =
Result;
3487 ReadMacroName(MacroNameTok);
3490 if (MacroNameTok.
is(tok::eod)) {
3493 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3508 if (CurPPLexer->getConditionalStackDepth() == 0) {
3513 if (!ReadAnyTokensBeforeDirective && !MI) {
3514 assert(isIfndef &&
"#ifdef shouldn't reach here");
3515 CurPPLexer->MIOpt.EnterTopLevelIfndef(MII, MacroNameTok.
getLocation());
3517 CurPPLexer->MIOpt.EnterTopLevelConditional();
3526 Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3528 Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3531 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3535 if (PPOpts.SingleFileParseMode && !MI) {
3538 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3541 }
else if (PPOpts.SingleModuleParseMode && !MI) {
3545 SkipExcludedConditionalBlock(
3548 }
else if (!MI == isIfndef || RetainExcludedCB) {
3550 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3555 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3564void Preprocessor::HandleIfDirective(
Token &IfToken,
3565 const Token &HashToken,
3566 bool ReadAnyTokensBeforeDirective) {
3570 IdentifierInfo *IfNDefMacro =
nullptr;
3571 const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
3572 const bool ConditionalTrue = DER.Conditional;
3580 if (CurPPLexer->getConditionalStackDepth() == 0) {
3581 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
3583 CurPPLexer->MIOpt.EnterTopLevelIfndef(IfNDefMacro, IfToken.
getLocation());
3585 CurPPLexer->MIOpt.EnterTopLevelConditional();
3593 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3597 if (PPOpts.SingleFileParseMode && DER.IncludedUndefinedIds) {
3600 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3602 }
else if (PPOpts.SingleModuleParseMode && DER.IncludedUndefinedIds) {
3609 }
else if (ConditionalTrue || RetainExcludedCB) {
3611 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3623void Preprocessor::HandleEndifDirective(
Token &EndifToken) {
3629 PPConditionalInfo CondInfo;
3630 if (CurPPLexer->popConditionalLevel(CondInfo)) {
3632 Diag(EndifToken, diag::err_pp_endif_without_if);
3637 if (CurPPLexer->getConditionalStackDepth() == 0)
3638 CurPPLexer->MIOpt.ExitTopLevelConditional();
3640 assert(!CondInfo.
WasSkipping && !CurPPLexer->LexingRawMode &&
3641 "This code should only be reachable in the non-skipping case!");
3649void Preprocessor::HandleElseDirective(
Token &
Result,
const Token &HashToken) {
3655 PPConditionalInfo CI;
3656 if (CurPPLexer->popConditionalLevel(CI)) {
3662 if (CurPPLexer->getConditionalStackDepth() == 0)
3663 CurPPLexer->MIOpt.EnterTopLevelConditional();
3671 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3674 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3677 CurPPLexer->pushConditionalLevel(CI.
IfLoc,
false,
3685 true,
Result.getLocation());
3689void Preprocessor::HandleElifFamilyDirective(
Token &ElifToken,
3690 const Token &HashToken,
3702 if (LangOpts.CPlusPlus)
3703 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
3704 : diag::ext_cxx23_pp_directive;
3706 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
3707 : diag::ext_c23_pp_directive;
3708 Diag(ElifToken, DiagID) << DirKind;
3719 PPConditionalInfo CI;
3720 if (CurPPLexer->popConditionalLevel(CI)) {
3721 Diag(ElifToken, diag::pp_err_elif_without_if) << DirKind;
3726 if (CurPPLexer->getConditionalStackDepth() == 0)
3727 CurPPLexer->MIOpt.EnterTopLevelConditional();
3731 Diag(ElifToken, diag::pp_err_elif_after_else) << DirKind;
3736 Callbacks->Elif(ElifToken.
getLocation(), ConditionRange,
3739 case tok::pp_elifdef:
3742 case tok::pp_elifndef:
3746 assert(
false &&
"unexpected directive kind");
3751 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3754 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3757 CurPPLexer->pushConditionalLevel(ElifToken.
getLocation(),
false,
3763 SkipExcludedConditionalBlock(
3768std::optional<LexEmbedParametersResult>
3771 tok::TokenKind EndTokenKind = ForHasEmbed ? tok::r_paren : tok::eod;
3773 auto DiagMismatchedBracesAndSkipToEOD =
3775 std::pair<tok::TokenKind, SourceLocation> Matches) {
3777 Diag(Matches.second, diag::note_matching) << Matches.first;
3778 if (CurTok.
isNot(tok::eod))
3783 if (CurTok.
isNot(Kind)) {
3784 Diag(CurTok, diag::err_expected) << Kind;
3785 if (CurTok.
isNot(tok::eod))
3802 auto LexPPParameterName = [&]() -> std::optional<std::string> {
3805 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3806 return std::nullopt;
3813 if (CurTok.
is(tok::coloncolon)) {
3816 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3817 return std::nullopt;
3823 return (llvm::Twine(Prefix->
getName()) +
"::" + Suffix->
getName()).str();
3825 return Prefix->
getName().str();
3832 auto NormalizeParameterName = [](StringRef Name) {
3833 if (Name.size() > 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
3834 return Name.substr(2, Name.size() - 4);
3838 auto LexParenthesizedIntegerExpr = [&]() -> std::optional<size_t> {
3841 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3842 return std::nullopt;
3847 bool EvaluatedDefined;
3848 DirectiveEvalResult LimitEvalResult = EvaluateDirectiveExpression(
3849 ParameterIfNDef, CurTok, EvaluatedDefined,
false);
3851 if (!LimitEvalResult.Value) {
3854 assert(CurTok.
is(tok::eod) &&
"expect to be at the end of directive");
3855 return std::nullopt;
3858 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3859 return std::nullopt;
3866 if (EvaluatedDefined) {
3867 Diag(CurTok, diag::err_defined_in_pp_embed);
3868 return std::nullopt;
3871 if (LimitEvalResult.Value) {
3872 const llvm::APSInt &
Result = *LimitEvalResult.Value;
3873 if (
Result.isNegative()) {
3874 Diag(CurTok, diag::err_requires_positive_value)
3876 if (CurTok.
isNot(EndTokenKind))
3878 return std::nullopt;
3880 return Result.getLimitedValue();
3882 return std::nullopt;
3888 return tok::r_paren;
3890 return tok::r_brace;
3892 return tok::r_square;
3894 llvm_unreachable(
"should not get here");
3898 auto LexParenthesizedBalancedTokenSoup =
3900 std::vector<std::pair<tok::TokenKind, SourceLocation>> BracketStack;
3903 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3907 bool WaitingForInnerCloseParen =
false;
3908 while (CurTok.
isNot(tok::eod) &&
3909 (WaitingForInnerCloseParen || CurTok.
isNot(tok::r_paren))) {
3914 WaitingForInnerCloseParen =
true;
3921 WaitingForInnerCloseParen =
false;
3924 case tok::r_square: {
3925 if (BracketStack.empty()) {
3926 ExpectOrDiagAndSkipToEOD(tok::r_paren);
3930 GetMatchingCloseBracket(BracketStack.back().first);
3931 if (CurTok.
getKind() != Matching) {
3932 DiagMismatchedBracesAndSkipToEOD(Matching, BracketStack.back());
3935 BracketStack.pop_back();
3938 Tokens.push_back(CurTok);
3943 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3951 while (!CurTok.
isOneOf(EndTokenKind, tok::eod)) {
3953 std::optional<std::string> ParamName = LexPPParameterName();
3955 return std::nullopt;
3956 StringRef
Parameter = NormalizeParameterName(*ParamName);
3963 if (
Result.MaybeLimitParam)
3966 std::optional<size_t> Limit = LexParenthesizedIntegerExpr();
3968 return std::nullopt;
3971 }
else if (
Parameter ==
"clang::offset") {
3972 if (
Result.MaybeOffsetParam)
3975 std::optional<size_t> Offset = LexParenthesizedIntegerExpr();
3977 return std::nullopt;
3981 if (
Result.MaybePrefixParam)
3985 if (!LexParenthesizedBalancedTokenSoup(Soup))
3986 return std::nullopt;
3988 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
3990 if (
Result.MaybeSuffixParam)
3994 if (!LexParenthesizedBalancedTokenSoup(Soup))
3995 return std::nullopt;
3997 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
3999 if (
Result.MaybeIfEmptyParam)
4003 if (!LexParenthesizedBalancedTokenSoup(Soup))
4004 return std::nullopt;
4006 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
4008 ++
Result.UnrecognizedParams;
4012 if (CurTok.
is(tok::l_paren)) {
4014 if (!LexParenthesizedBalancedTokenSoup(Soup))
4015 return std::nullopt;
4018 Diag(ParamStartLoc, diag::err_pp_unknown_parameter) << 1 <<
Parameter;
4019 if (CurTok.
isNot(EndTokenKind))
4021 return std::nullopt;
4028void Preprocessor::HandleEmbedDirectiveImpl(
4030 StringRef BinaryContents, StringRef
FileName) {
4031 if (BinaryContents.empty()) {
4039 size_t TokCount = Toks.size();
4040 auto NewToks = std::make_unique<Token[]>(TokCount);
4041 llvm::copy(Toks, NewToks.get());
4042 EnterTokenStream(std::move(NewToks), TokCount,
true,
true);
4049 size_t TotalNumToks = 1 + NumPrefixToks + NumSuffixToks;
4051 auto Toks = std::make_unique<Token[]>(TotalNumToks);
4056 CurIdx += NumPrefixToks;
4059 EmbedAnnotationData *
Data =
new (BP) EmbedAnnotationData;
4060 Data->BinaryData = BinaryContents;
4063 Toks[CurIdx].startToken();
4064 Toks[CurIdx].setKind(tok::annot_embed);
4065 Toks[CurIdx].setAnnotationRange(HashLoc);
4066 Toks[CurIdx++].setAnnotationValue(
Data);
4071 CurIdx += NumSuffixToks;
4074 assert(CurIdx == TotalNumToks &&
"Calculated the incorrect number of tokens");
4075 EnterTokenStream(std::move(Toks), TotalNumToks,
true,
true);
4082 Diag(EmbedTok, diag::warn_compat_pp_embed_directive);
4084 Diag(EmbedTok, diag::ext_pp_embed_directive)
4085 << (LangOpts.CPlusPlus ? 1 : 0);
4092 if (FilenameTok.
isNot(tok::header_name)) {
4094 if (FilenameTok.
isNot(tok::eod))
4107 std::optional<LexEmbedParametersResult> Params =
4110 assert((Params || CurTok.
is(tok::eod)) &&
4111 "expected success or to be at the end of the directive");
4116 SmallString<128> FilenameBuffer;
4117 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
4118 StringRef OriginalFilename = Filename;
4124 if (Filename.empty())
4129 if (!MaybeFileRef) {
4131 if (Callbacks && Callbacks->EmbedFileNotFound(Filename)) {
4134 Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
4139 Diag(FilenameTok, diag::err_pp_embed_device_file) << Filename;
4143 std::optional<llvm::MemoryBufferRef> MaybeFile =
4147 Diag(FilenameTok, diag::err_cannot_open_file)
4148 << Filename <<
"a buffer to the contents could not be created";
4151 StringRef BinaryContents = MaybeFile->getBuffer();
4156 if (Params->MaybeOffsetParam) {
4161 BinaryContents = BinaryContents.substr(Params->MaybeOffsetParam->Offset);
4164 if (Params->MaybeLimitParam) {
4168 BinaryContents = BinaryContents.substr(0, Params->MaybeLimitParam->Limit);
4172 Callbacks->EmbedDirective(HashLoc, Filename, isAngled, MaybeFileRef,
4181 void *Mem = BP.Allocate(OriginalFilename.size(),
alignof(
char *));
4182 memcpy(Mem, OriginalFilename.data(), OriginalFilename.size());
4183 StringRef FilenameToGo =
4184 StringRef(
static_cast<char *
>(Mem), OriginalFilename.size());
4185 HandleEmbedDirectiveImpl(HashLoc, *Params, BinaryContents, FilenameToGo);
4198 assert(
getLangOpts().CPlusPlusModules && ImportTok.
is(tok::kw_import));
4200 this->ImportingCXXNamedModules,
true);
4204 if (
Tok.isNot(tok::eod))
4212 bool ImportingHeader =
false;
4213 bool IsPartition =
false;
4215 switch (
Tok.getKind()) {
4216 case tok::header_name:
4217 ImportingHeader =
true;
4218 DirToks.push_back(
Tok);
4219 Lex(DirToks.emplace_back());
4223 DirToks.push_back(
Tok);
4224 UseLoc =
Tok.getLocation();
4227 case tok::identifier: {
4229 Path, DirToks,
true,
4233 std::string FlatName;
4235 (IsPartition && ModuleDeclState.isNamedModule()) || !IsPartition;
4236 if (Callbacks && IsValid) {
4237 if (IsPartition && ModuleDeclState.isNamedModule()) {
4238 FlatName += ModuleDeclState.getPrimaryName();
4243 SourceLocation StartLoc = IsPartition ? UseLoc : Path[0].getLoc();
4255 DirToks.push_back(
Tok);
4261 if (!DirToks.back().isOneOf(tok::semi, tok::eod))
4264 if (DirToks.back().isNot(tok::eod))
4270 if (DirToks.back().isNot(tok::semi)) {
4275 if (ImportingHeader) {
4281 Diag(SemiLoc, diag::err_header_import_semi_in_macro);
4283 auto Action = HandleHeaderIncludeOrImport(
4285 switch (Action.Kind) {
4286 case ImportAction::None:
4289 case ImportAction::ModuleBegin:
4291 DirToks.emplace_back();
4292 DirToks.back().startToken();
4293 DirToks.back().setKind(tok::annot_module_begin);
4294 DirToks.back().setLocation(SemiLoc);
4295 DirToks.back().setAnnotationEndLoc(SemiLoc);
4296 DirToks.back().setAnnotationValue(Action.ModuleForHeader);
4299 case ImportAction::ModuleImport:
4300 case ImportAction::HeaderUnitImport:
4301 case ImportAction::SkippedModuleImport:
4304 DirToks[1].setKind(tok::annot_header_unit);
4305 DirToks[1].setAnnotationEndLoc(DirToks[0].getLocation());
4306 DirToks[1].setAnnotationValue(Action.ModuleForHeader);
4309 case ImportAction::Failure:
4310 assert(TheModuleLoader.HadFatalFailure &&
4311 "This should be an early exit only to a fatal error");
4312 CurLexer->cutOffLexing();
4341 assert(
getLangOpts().CPlusPlusModules && ModuleTok.
is(tok::kw_module));
4350 switch (
Tok.getKind()) {
4353 DirToks.push_back(
Tok);
4356 DirToks.push_back(
Tok);
4358 if (
Tok.isNot(tok::kw_private)) {
4359 if (
Tok.isNot(tok::eod))
4365 DirToks.push_back(
Tok);
4367 case tok::identifier: {
4369 Path, DirToks,
false,
4376 if (
Tok.is(tok::colon)) {
4379 Tok, Partition, DirToks,
4390 if (
Tok.is(tok::identifier) &&
4392 std::unique_ptr<Token[]> TokCopy = std::make_unique<Token[]>(1);
4394 EnterTokenStream(std::move(TokCopy), 1,
4397 DirToks.back() =
Tok;
4402 DirToks.push_back(
Tok);
4408 std::optional<Token> NextPPTok =
4409 DirToks.back().is(tok::eod) ? peekNextPPToken() : DirToks.back();
4414 if (NextPPTok->is(tok::raw_identifier))
4416 if (!NextPPTok->isOneOf(tok::semi, tok::eod, tok::l_square,
4418 Diag(*NextPPTok, diag::err_pp_unexpected_tok_after_module_name)
4422 if (!DirToks.back().isOneOf(tok::semi, tok::eod)) {
4429 DirToks.back().isNot(tok::eod)
4433 : DirToks.pop_back_val().getLocation();
4435 if (!IncludeMacroStack.empty()) {
4436 Diag(StartLoc, diag::err_pp_module_decl_in_header)
4440 if (CurPPLexer->getConditionalStackDepth() != 0) {
4441 Diag(StartLoc, diag::err_pp_cond_span_module_decl)
4459void Preprocessor::HandleObjCImportDirective(
Token &AtTok,
Token &ImportTok) {
4462 ImportTok.
setKind(tok::kw_import);
4477 if (!DirToks.back().isOneOf(tok::semi, tok::eod))
4481 DirToks.back().isNot(tok::eod)
4485 : DirToks.pop_back_val().getLocation();
4487 Module *Imported =
nullptr;
4496 Callbacks->moduleImport(ModuleImportLoc, Path, Imported);
static bool isInMainFile(const clang::Diagnostic &D)
Defines interfaces for clang::DirectoryEntry and clang::DirectoryEntryRef.
Defines the clang::FileManager interface and associated types.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Defines the clang::LangOptions interface.
Defines the clang::MacroInfo and clang::MacroDirective classes.
Defines the clang::Module class, which describes a module in the source code.
Defines the PPCallbacks interface.
static bool ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit, SrcMgr::CharacteristicKind &FileKind, Preprocessor &PP)
ReadLineMarkerFlags - Parse and validate any flags at the end of a GNU line marker directive.
static bool isConfigurationPattern(Token &MacroName, MacroInfo *MI, const LangOptions &LOptions)
static void diagnoseAutoModuleImport(Preprocessor &PP, SourceLocation HashLoc, Token &IncludeTok, ArrayRef< IdentifierLoc > Path, SourceLocation PathEnd)
Produce a diagnostic informing the user that a include or similar was implicitly treated as a module ...
static std::optional< StringRef > findSimilarStr(StringRef LHS, const std::vector< StringRef > &Candidates)
Find a similar string in Candidates.
static bool isLanguageDefinedBuiltin(const SourceManager &SourceMgr, const MacroInfo *MI, const StringRef MacroName)
static bool trySimplifyPath(SmallVectorImpl< StringRef > &Components, StringRef RealPathName, llvm::sys::path::Style Separator)
static bool warnByDefaultOnWrongCase(StringRef Include)
MacroDiag
Enumerates possible cases of define/undef a reserved identifier.
@ MD_ReservedAttributeIdentifier
static bool isFeatureTestMacro(StringRef MacroName)
static bool GetLineValue(Token &DigitTok, unsigned &Val, unsigned DiagID, Preprocessor &PP, bool IsGNULineDirective=false)
GetLineValue - Convert a numeric token into an unsigned value, emitting Diagnostic DiagID if it is in...
PPElifDiag
Enumerates possible select values for the pp_err_elif_after_else and pp_err_elif_without_if diagnosti...
static bool isReservedCXXAttributeName(Preprocessor &PP, IdentifierInfo *II)
static MacroDiag shouldWarnOnMacroUndef(Preprocessor &PP, IdentifierInfo *II)
static bool isObjCProtectedMacro(const IdentifierInfo *II)
static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II)
Defines the clang::Preprocessor interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines the clang::SourceLocation class and associated facilities.
static bool isInvalid(LocType Loc, bool *Invalid)
Defines the SourceManager interface.
Defines the clang::TokenKind enum and support functions.
VerifyDiagnosticConsumer::Directive Directive
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
ResetMacroExpansionHelper(Preprocessor *pp)
~ResetMacroExpansionHelper()
static AttrArgsInfo getCXX11AttrArgsInfo(const IdentifierInfo *Name)
Represents a byte-granular source range.
static CharSourceRange getCharRange(SourceRange R)
virtual void CodeCompleteMacroName(bool IsDefinition)
Callback invoked when performing code completion in a context where the name of a macro is expected.
A directive for a defined macro or a macro imported from a module.
Concrete class used by the front-end to report problems and issues.
A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...
StringRef getName() const
bool isDeviceFile() const
const FileEntry & getFileEntry() const
DirectoryEntryRef getDir() const
Cached information about one file (either on disk or in the virtual file system).
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements support for file system lookup, file system caching, and directory search management.
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true, bool IsText=true)
Get a FileEntryRef if it exists, without doing anything on error.
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
One of these records is kept for each identifier that is lexed.
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.
bool isCPlusPlusOperatorKeyword() const
bool hadMacroDefinition() const
Returns true if this identifier was #defined to some value at any moment.
bool hasMacroDefinition() const
Return true if this identifier is #defined to some other value.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
bool isKeyword(const LangOptions &LangOpts) const
Return true if this token is a keyword in the specified language.
ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const
Determine whether this is a name reserved for the implementation (C99 7.1.3, C++ [lib....
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
A simple pair of identifier info and location.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool IsHeaderFile
Indicates whether the front-end is explicitly told that the input is a header file (i....
std::string CurrentModule
The name of the current module, of which the main source file is a part.
const MacroInfo * getMacroInfo() const
Encapsulates the data about a macro definition (e.g.
bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP, bool Syntactically) const
Return true if the specified macro definition is equal to this macro in spelling, arguments,...
bool isUsed() const
Return false if this macro is defined in the main file and has not yet been used.
bool isC99Varargs() const
bool isAllowRedefinitionsWithoutWarning() const
Return true if this macro can be redefined without warning.
void setHasCommaPasting()
unsigned getNumTokens() const
Return the number of tokens that this macro expands to.
const Token & getReplacementToken(unsigned Tok) const
void setDefinitionEndLoc(SourceLocation EndLoc)
Set the location of the last token in the macro.
bool isBuiltinMacro() const
Return true if this macro requires processing before expansion.
void setTokens(ArrayRef< Token > Tokens, llvm::BumpPtrAllocator &PPAllocator)
void setParameterList(ArrayRef< IdentifierInfo * > List, llvm::BumpPtrAllocator &PPAllocator)
Set the specified list of identifiers as the parameter list for this macro.
SourceLocation getDefinitionLoc() const
Return the location that the macro was defined at.
void setIsFunctionLike()
Function/Object-likeness.
bool isObjectLike() const
void setIsWarnIfUnused(bool val)
Set the value of the IsWarnIfUnused flag.
int getParameterNum(const IdentifierInfo *Arg) const
Return the parameter number of the specified identifier, or -1 if the identifier is not a formal para...
bool isWarnIfUnused() const
Return true if we should emit a warning if the macro is unused.
void setIsC99Varargs()
Varargs querying methods. This can only be set for function-like macros.
bool isMissingExpected() const
Determines whether the module, which failed to load, was actually a submodule that we expected to see...
bool isConfigMismatch() const
Determines whether the module failed to load due to a configuration mismatch with an explicitly-named...
virtual ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective)=0
Attempt to load the given module.
static std::string getFlatNameFromPath(ModuleIdPath Path)
@ ExcludedHeader
This header is explicitly excluded from the module.
@ TextualHeader
This header is part of the module (for layering purposes) but should be textually included.
Describes a module or submodule.
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
bool isForBuilding(const LangOptions &LangOpts) const
Determine whether this module can be built in this compilation.
@ Hidden
All of the names in this module are hidden.
SourceLocation DefinitionLoc
The location of the module definition.
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers).
std::string Name
The name of this module.
bool isAvailable() const
Determine whether this module is available for use within the current translation unit.
bool isHeaderUnit() const
Is this module a header unit.
Module * ShadowingModule
A module with the same name that shadows this module.
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
Preprocessor standard embed parameter "if_empty" if_empty( balanced-token-seq )
Preprocessor standard embed parameter "limit" limit( constant-expression )
Preprocessor extension embed parameter "clang::offset" clang::offset( constant-expression )
Preprocessor standard embed parameter "prefix" prefix( balanced-token-seq )
Preprocessor standard embed parameter "suffix" suffix( balanced-token-seq )
OptionalFileEntryRef getFileEntry() const
getFileEntry - Return the FileEntry corresponding to this FileID.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
MacroDirective * getLocalMacroDirective(const IdentifierInfo *II) const
Given an identifier, return its latest non-imported MacroDirective if it is #define'd and not #undef'...
void EnterModuleSuffixTokenStream(ArrayRef< Token > Toks)
void markClangModuleAsAffecting(Module *M)
Mark the given clang module as affecting the current clang module or translation unit.
void HandleCXXImportDirective(Token Import)
HandleCXXImportDirective - Handle the C++ modules import directives.
SourceRange DiscardUntilEndOfDirective(SmallVectorImpl< Token > *DiscardedToks=nullptr)
Read and discard all tokens remaining on the current line until the tok::eod token is found.
const MacroInfo * getMacroInfo(const IdentifierInfo *II) const
bool isRecordingPreamble() const
void HandleSkippedDirectiveWhileUsingPCH(Token &Result, SourceLocation HashLoc)
Process directives while skipping until the through header or pragma hdrstop is found.
bool isInPrimaryFile() const
Return true if we're in the top-level file, not in a #include.
void markMacroAsUsed(MacroInfo *MI)
A macro is used, update information about macros that need unused warnings.
void EnterSubmodule(Module *M, SourceLocation ImportLoc, bool ForPragma)
IdentifierInfo * LookUpIdentifierInfo(Token &Identifier) const
Given a tok::raw_identifier token, look up the identifier information for the token and install it in...
void setCodeCompletionReached()
Note that we hit the code-completion point.
StringRef getNamedModuleName() const
Get the named module name we're preprocessing.
void Lex(Token &Result)
Lex the next token for this preprocessor.
bool EnterSourceFile(FileID FID, ConstSearchDirIterator Dir, SourceLocation Loc, bool IsFirstIncludeOfFile=true)
Add a source file to the top of the include stack and start lexing tokens from it instead of the curr...
void LexNonComment(Token &Result)
Lex a token.
friend class VAOptDefinitionContext
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
SourceManager & getSourceManager() const
MacroDefinition getMacroDefinition(const IdentifierInfo *II)
bool CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef, bool *ShadowFlag=nullptr)
SourceLocation CheckEndOfDirective(StringRef DirType, bool EnableMacros=false, SmallVectorImpl< Token > *ExtraToks=nullptr)
Ensure that the next token is a tok::eod token.
static bool checkModuleIsAvailable(const LangOptions &LangOpts, const TargetInfo &TargetInfo, const Module &M, DiagnosticsEngine &Diags)
Check that the given module is available, producing a diagnostic if not.
SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart, unsigned Char) const
Given a location that specifies the start of a token, return a new location that specifies a characte...
Module * getCurrentModule()
Retrieves the module that we're currently building, if any.
OptionalFileEntryRef LookupEmbedFile(StringRef Filename, bool isAngled, bool OpenFile)
Given a "Filename" or <Filename> reference, look up the indicated embed resource.
void makeModuleVisible(Module *M, SourceLocation Loc, bool IncludeExports=true)
bool hadModuleLoaderFatalFailure() const
bool HandleModuleContextualKeyword(Token &Result)
Callback invoked when the lexer sees one of export, import or module token at the start of a line.
const TargetInfo & getTargetInfo() const
FileManager & getFileManager() const
bool LexHeaderName(Token &Result, bool AllowMacroExpansion=true)
Lex a token, forming a header-name token if possible.
bool isPCHThroughHeader(const FileEntry *FE)
Returns true if the FileEntry is the PCH through header.
friend class VariadicMacroScopeGuard
MacroInfo * AllocateMacroInfo(SourceLocation L)
Allocate a new MacroInfo object with the provided SourceLocation.
void LexUnexpandedToken(Token &Result)
Just like Lex, but disables macro expansion of identifier tokens.
bool alreadyIncluded(FileEntryRef File) const
Return true if this header has already been included.
FileID getPredefinesFileID() const
Returns the FileID for the preprocessor predefines.
void LexUnexpandedNonComment(Token &Result)
Like LexNonComment, but this disables macro expansion of identifier tokens.
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
bool GetIncludeFilenameSpelling(SourceLocation Loc, StringRef &Buffer)
Turn the specified lexer token into a fully checked and spelled filename, e.g.
PreprocessorLexer * getCurrentFileLexer() const
Return the current file lexer being lexed from.
HeaderSearch & getHeaderSearchInfo() const
void emitMacroExpansionWarnings(const Token &Identifier, bool IsIfnDef=false) const
void GetLineDirectiveFilenameSpelling(SourceLocation Loc, StringRef &Buffer)
Turn the specified lexer token into a fully checked and spelled filename, e.g.
void HandleDirective(Token &Result)
Callback invoked when the lexer sees a # token at the start of a line.
void EnterAnnotationToken(SourceRange Range, tok::TokenKind Kind, void *AnnotationVal)
Enter an annotation token into the token stream.
OptionalFileEntryRef LookupFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled, ConstSearchDirIterator FromDir, const FileEntry *FromFile, ConstSearchDirIterator *CurDir, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool *IsFrameworkFound, bool SkipCache=false, bool OpenFile=true, bool CacheFailures=true)
Given a "foo" or <foo> reference, look up the indicated file.
const LangOptions & getLangOpts() const
bool isInNamedModule() const
If we are preprocessing a named module.
OptionalFileEntryRef getHeaderToIncludeForDiagnostics(SourceLocation IncLoc, SourceLocation MLoc)
We want to produce a diagnostic at location IncLoc concerning an unreachable effect at location MLoc ...
bool isNextPPTokenOneOf(Ts... Ks) const
isNextPPTokenOneOf - Check whether the next pp-token is one of the specificed token kind.
DefMacroDirective * appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI, SourceLocation Loc)
void CollectPPImportSuffix(SmallVectorImpl< Token > &Toks, bool StopUntilEOD=false)
Collect the tokens of a C++20 pp-import-suffix.
void HandlePragmaHdrstop(Token &Tok)
DiagnosticsEngine & getDiagnostics() const
void HandleCXXModuleDirective(Token Module)
HandleCXXModuleDirective - Handle C++ module declaration directives.
std::optional< LexEmbedParametersResult > LexEmbedParameters(Token &Current, bool ForHasEmbed)
Lex the parameters for an embed directive, returns nullopt on error.
Module * getModuleForLocation(SourceLocation Loc, bool AllowTextual)
Find the module that owns the source or header file that Loc points to.
bool HandleModuleName(StringRef DirType, SourceLocation UseLoc, Token &Tok, SmallVectorImpl< IdentifierLoc > &Path, SmallVectorImpl< Token > &DirToks, bool AllowMacroExpansion, bool IsPartition)
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
bool usingPCHWithThroughHeader()
True if using a PCH with a through header.
Preprocessor(const PreprocessorOptions &PPOpts, DiagnosticsEngine &diags, const LangOptions &LangOpts, SourceManager &SM, HeaderSearch &Headers, ModuleLoader &TheModuleLoader, IdentifierInfoLookup *IILookup=nullptr, bool OwnsHeaderSearch=false, TranslationUnitKind TUKind=TU_Complete)
void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD)
Add a directive to the macro directive history for this identifier.
Represents an unpacked "presumed" location which can be presented to the user.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
SourceLocation getIncludeLoc() const
Return the presumed include location of this location.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
bool isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
std::optional< llvm::MemoryBufferRef > getMemoryBufferForFileOrNone(FileEntryRef File)
Retrieve the memory buffer associated with the given file.
A trivial tuple used to represent a source range.
void setBegin(SourceLocation b)
SourceLocation getEnd() const
void setEnd(SourceLocation e)
Exposes information about the current target.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getEndLoc() const
void clearFlag(TokenFlags Flag)
Unset the specified flag.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
unsigned getLength() const
void setKind(tok::TokenKind K)
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
tok::TokenKind getKind() const
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
bool isOneOf(Ts... Ks) const
bool isModuleContextualKeyword(bool AllowExport=true) const
Return true if we have a C++20 modules contextual keyword(export, importor module).
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
bool isNot(tok::TokenKind K) const
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix.
bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const
Return true if we have an ObjC keyword identifier.
void startToken()
Reset all flags to cleared.
bool needsCleaning() const
Return true if this token has trigraphs or escaped newlines in it.
StringRef getRawIdentifier() const
getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode),...
A directive for an undefined macro.
A directive for setting the module visibility of a macro.
Defines the clang::TargetInfo interface.
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
bool Sub(InterpState &S, CodePtr OpPC)
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
PPKeywordKind
Provides a namespace for preprocessor keywords which start with a '#' at the beginning of the line.
The JSON file list parser is used to communicate input to InstallAPI.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
bool isReservedInAllContexts(ReservedIdentifierStatus Status)
Determine whether an identifier is reserved in all contexts.
int hasAttribute(AttributeCommonInfo::Syntax Syntax, llvm::StringRef ScopeName, llvm::StringRef AttrName, const TargetInfo &Target, const LangOptions &LangOpts, bool CheckPlugins)
Return the version number associated with the attribute if we recognize and implement the attribute s...
ArrayRef< IdentifierLoc > ModuleIdPath
A sequence of identifier/location pairs used to describe a particular module or submodule,...
LLVM_READONLY char toLowercase(char c)
Converts the given ASCII character to its lowercase equivalent.
detail::SearchDirIteratorImpl< true > ConstSearchDirIterator
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
MacroUse
Context in which macro name is used.
LLVM_READONLY bool isAlphanumeric(unsigned char c)
Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Default
Set to the current date and time.
@ Parameter
The parameter type of a method or function.
@ Result
The result type of a method or function.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
LLVM_READONLY bool isLowercase(unsigned char c)
Return true if this character is a lowercase ASCII letter: [a-z].
@ PIK_HashPragma
The pragma was introduced via #pragma.
OptionalDirectoryEntryRef Directory
The directory entry which should be used for the cached framework.
std::optional< PPEmbedParameterIfEmpty > MaybeIfEmptyParam
size_t SuffixTokenCount() const
std::optional< PPEmbedParameterSuffix > MaybeSuffixParam
std::optional< PPEmbedParameterPrefix > MaybePrefixParam
size_t PrefixTokenCount() const
bool FoundNonSkip
True if we have emitted tokens already, and now we're in an #else block or something.
SourceLocation IfLoc
Location where the conditional started.
bool WasSkipping
True if this was contained in a skipping directive, e.g., in a "\#if 0" block.
bool FoundElse
True if we've seen a #else in this block.