39#include "llvm/ADT/ArrayRef.h"
40#include "llvm/ADT/STLExtras.h"
41#include "llvm/ADT/ScopeExit.h"
42#include "llvm/ADT/SmallVector.h"
43#include "llvm/ADT/StringExtras.h"
44#include "llvm/ADT/StringRef.h"
45#include "llvm/ADT/StringSwitch.h"
46#include "llvm/Support/ErrorHandling.h"
47#include "llvm/Support/Path.h"
48#include "llvm/Support/SaveAndRestore.h"
64 static_assert(std::is_trivially_destructible_v<MacroInfo>,
"");
74Preprocessor::AllocateUndefMacroDirective(
SourceLocation UndefLoc) {
81 return new (BP) VisibilityMacroDirective(Loc, isPublic);
89 auto ReadNextTok = [&]() {
91 if (DiscardedToks && Tmp.
isNot(tok::eod))
92 DiscardedToks->push_back(Tmp);
96 while (Tmp.
isNot(tok::eod)) {
97 assert(Tmp.
isNot(tok::eof) &&
"EOF seen while discarding directive tokens");
126 static constexpr StringRef ReservedMacro[] = {
129 "_CRT_NONSTDC_NO_WARNINGS",
130 "_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES",
131 "_CRT_SECURE_NO_WARNINGS",
134 "_GLIBCXX_ASSERTIONS",
135 "_GLIBCXX_CONCEPT_CHECKS",
137 "_GLIBCXX_DEBUG_PEDANTIC",
139 "_GLIBCXX_PARALLEL_ASSERTIONS",
140 "_GLIBCXX_SANITIZE_VECTOR",
141 "_GLIBCXX_USE_CXX11_ABI",
142 "_GLIBCXX_USE_DEPRECATED",
147 "_LARGEFILE64_SOURCE",
153 "_XOPEN_SOURCE_EXTENDED",
154 "__STDCPP_WANT_MATH_SPEC_FUNCS__",
155 "__STDC_FORMAT_MACROS",
157 return llvm::binary_search(ReservedMacro, MacroName);
162 const StringRef MacroName) {
172 if (MacroName.starts_with(
"__STDC"))
175 if (MacroName ==
"__cplusplus")
178 if (MacroName.starts_with(
"__cpp"))
186 if (Lang.CPlusPlus &&
207 if (Lang.CPlusPlus11 && (
Text ==
"override" ||
Text ==
"final"))
232 if (::llvm::sys::path::begin(Include)->equals_insensitive(
"boost"))
237 static const size_t MaxStdHeaderNameLen = 18u;
238 if (Include.size() > MaxStdHeaderNameLen)
243 for (
char &Ch : LowerInclude) {
245 if (
static_cast<unsigned char>(Ch) > 0x7f)
248 if (Ch >=
'A' && Ch <=
'Z')
251 else if (::llvm::sys::path::is_separator(Ch))
256 return llvm::StringSwitch<bool>(LowerInclude)
258 .Cases({
"assert.h",
"complex.h",
"ctype.h",
"errno.h",
"fenv.h"},
true)
259 .Cases({
"float.h",
"inttypes.h",
"iso646.h",
"limits.h",
"locale.h"},
261 .Cases({
"math.h",
"setjmp.h",
"signal.h",
"stdalign.h",
"stdarg.h"},
true)
262 .Cases({
"stdatomic.h",
"stdbool.h",
"stdckdint.h",
"stdcountof.h"},
true)
263 .Cases({
"stddef.h",
"stdint.h",
"stdio.h",
"stdlib.h",
"stdnoreturn.h"},
265 .Cases({
"string.h",
"tgmath.h",
"threads.h",
"time.h",
"uchar.h"},
true)
266 .Cases({
"wchar.h",
"wctype.h"},
true)
269 .Cases({
"cassert",
"ccomplex",
"cctype",
"cerrno",
"cfenv"},
true)
270 .Cases({
"cfloat",
"cinttypes",
"ciso646",
"climits",
"clocale"},
true)
271 .Cases({
"cmath",
"csetjmp",
"csignal",
"cstdalign",
"cstdarg"},
true)
272 .Cases({
"cstdbool",
"cstddef",
"cstdint",
"cstdio",
"cstdlib"},
true)
273 .Cases({
"cstring",
"ctgmath",
"ctime",
"cuchar",
"cwchar"},
true)
274 .Case(
"cwctype",
true)
277 .Cases({
"algorithm",
"fstream",
"list",
"regex",
"thread"},
true)
278 .Cases({
"array",
"functional",
"locale",
"scoped_allocator",
"tuple"},
280 .Cases({
"atomic",
"future",
"map",
"set",
"type_traits"},
true)
282 {
"bitset",
"initializer_list",
"memory",
"shared_mutex",
"typeindex"},
284 .Cases({
"chrono",
"iomanip",
"mutex",
"sstream",
"typeinfo"},
true)
285 .Cases({
"codecvt",
"ios",
"new",
"stack",
"unordered_map"},
true)
286 .Cases({
"complex",
"iosfwd",
"numeric",
"stdexcept",
"unordered_set"},
289 {
"condition_variable",
"iostream",
"ostream",
"streambuf",
"utility"},
291 .Cases({
"deque",
"istream",
"queue",
"string",
"valarray"},
true)
292 .Cases({
"exception",
"iterator",
"random",
"strstream",
"vector"},
true)
293 .Cases({
"forward_list",
"limits",
"ratio",
"system_error"},
true)
296 .Cases({
"aio.h",
"arpa/inet.h",
"cpio.h",
"dirent.h",
"dlfcn.h"},
true)
297 .Cases({
"fcntl.h",
"fmtmsg.h",
"fnmatch.h",
"ftw.h",
"glob.h"},
true)
298 .Cases({
"grp.h",
"iconv.h",
"langinfo.h",
"libgen.h",
"monetary.h"},
true)
299 .Cases({
"mqueue.h",
"ndbm.h",
"net/if.h",
"netdb.h",
"netinet/in.h"},
301 .Cases({
"netinet/tcp.h",
"nl_types.h",
"poll.h",
"pthread.h",
"pwd.h"},
303 .Cases({
"regex.h",
"sched.h",
"search.h",
"semaphore.h",
"spawn.h"},
true)
304 .Cases({
"strings.h",
"stropts.h",
"sys/ipc.h",
"sys/mman.h",
"sys/msg.h"},
306 .Cases({
"sys/resource.h",
"sys/select.h",
"sys/sem.h",
"sys/shm.h",
309 .Cases({
"sys/stat.h",
"sys/statvfs.h",
"sys/time.h",
"sys/times.h",
313 {
"sys/uio.h",
"sys/un.h",
"sys/utsname.h",
"sys/wait.h",
"syslog.h"},
315 .Cases({
"tar.h",
"termios.h",
"trace.h",
"ulimit.h"},
true)
316 .Cases({
"unistd.h",
"utime.h",
"utmpx.h",
"wordexp.h"},
true)
328static std::optional<StringRef>
332 for (StringRef
C : Candidates) {
333 if (LHS.equals_insensitive(
C)) {
341 size_t Length = LHS.size();
342 size_t MaxDist = Length < 3 ? Length - 1 : Length / 3;
344 std::optional<std::pair<StringRef, size_t>> SimilarStr;
345 for (StringRef
C : Candidates) {
346 size_t CurDist = LHS.edit_distance(
C,
true);
347 if (CurDist <= MaxDist) {
350 SimilarStr = {
C, CurDist};
351 }
else if (CurDist < SimilarStr->second) {
353 SimilarStr = {
C, CurDist};
359 return SimilarStr->first;
368 if (MacroNameTok.
is(tok::eod))
369 return Diag(MacroNameTok, diag::err_pp_missing_macro_name);
373 return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
379 ? diag::ext_pp_operator_used_as_macro_name
380 : diag::err_pp_operator_used_as_macro_name)
381 << II << MacroNameTok.
getKind();
388 return Diag(MacroNameTok, diag::err_defined_macro_name);
401 if (!SourceMgr.isInSystemHeader(MacroNameLoc) &&
402 !SourceMgr.isInPredefinedFile(MacroNameLoc)) {
417 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id);
419 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_attribute_id)
436void Preprocessor::ReadMacroName(
Token &MacroNameTok,
MacroUse isDefineUndef,
441 if (MacroNameTok.
is(tok::code_completion)) {
453 if (MacroNameTok.
isNot(tok::eod)) {
454 MacroNameTok.
setKind(tok::eod);
472 auto ReadNextTok = [
this, ExtraToks, &Tmp](
auto &&LexFn) {
473 std::invoke(LexFn,
this, Tmp);
474 if (ExtraToks && Tmp.
isNot(tok::eod))
475 ExtraToks->push_back(Tmp);
487 while (Tmp.
is(tok::comment))
490 if (Tmp.
is(tok::eod))
498 if ((LangOpts.GNUMode || LangOpts.C99 || LangOpts.CPlusPlus) &&
502 unsigned DiagID = diag::ext_pp_extra_tokens_at_eol;
505 (DirType ==
"import" || DirType ==
"module"))
506 DiagID = diag::warn_pp_extra_tokens_at_module_directive_eol;
508 Diag(Tmp, DiagID) << DirType << Hint;
512void Preprocessor::SuggestTypoedDirective(
const Token &
Tok,
513 StringRef Directive)
const {
518 std::vector<StringRef> Candidates = {
519 "if",
"ifdef",
"ifndef",
"elif",
"else",
"endif"
521 if (LangOpts.C23 || LangOpts.CPlusPlus23)
522 Candidates.insert(Candidates.end(), {
"elifdef",
"elifndef"});
526 assert(
Tok.getLocation().isFileID());
530 StringRef SuggValue = *Sugg;
533 Diag(
Tok, diag::warn_pp_invalid_directive) << 1 << SuggValue << Hint;
545void Preprocessor::SkipExcludedConditionalBlock(
SourceLocation HashTokenLoc,
547 bool FoundNonSkipPortion,
558 assert(!SkippingExcludedConditionalBlock &&
559 "calling SkipExcludedConditionalBlock recursively");
560 llvm::SaveAndRestore SARSkipping(SkippingExcludedConditionalBlock,
true);
563 assert(!CurTokenLexer &&
"Conditional PP block cannot appear in a macro!");
564 assert(CurPPLexer &&
"Conditional PP block must be in a file!");
565 assert(CurLexer &&
"Conditional PP block but no current lexer set!");
567 if (PreambleConditionalStack.reachedEOFWhileSkipping())
568 PreambleConditionalStack.clearSkipInfo();
570 CurPPLexer->pushConditionalLevel(IfTokenLoc,
false,
571 FoundNonSkipPortion, FoundElse);
575 CurPPLexer->LexingRawMode =
true;
577 SourceLocation endLoc;
581 struct SkippingRangeStateTy {
584 const char *BeginPtr =
nullptr;
585 unsigned *SkipRangePtr =
nullptr;
587 SkippingRangeStateTy(Preprocessor &PP) : PP(PP) {}
589 void beginLexPass() {
595 BeginPtr = PP.CurLexer->getBufferLocation();
596 SkipRangePtr = &PP.RecordedSkippedRanges[BeginPtr];
598 PP.CurLexer->seek(PP.CurLexer->getCurrentBufferOffset() + *SkipRangePtr,
603 void endLexPass(
const char *Hashptr) {
606 assert(PP.CurLexer->isDependencyDirectivesLexer());
611 if (!*SkipRangePtr) {
612 *SkipRangePtr = Hashptr - BeginPtr;
614 assert(*SkipRangePtr ==
unsigned(Hashptr - BeginPtr));
616 SkipRangePtr =
nullptr;
618 } SkippingRangeState(*
this);
621 if (CurLexer->isDependencyDirectivesLexer()) {
622 CurLexer->LexDependencyDirectiveTokenWhileSkipping(
Tok);
624 SkippingRangeState.beginLexPass();
628 if (
Tok.
is(tok::code_completion)) {
631 CodeComplete->CodeCompleteInConditionalExclusion();
644 Tok.
is(tok::raw_identifier) &&
647 llvm::SaveAndRestore ModuleDirectiveSkipping(LastExportKeyword);
648 LastExportKeyword.startToken();
655 if (
Tok.
is(tok::raw_identifier)) {
664 llvm::SaveAndRestore RestoreLexingRawMode(CurPPLexer->LexingRawMode,
671 CurPPLexer->ParsingPreprocessorDirective =
true;
674 Diag(StartLoc, diag::err_pp_cond_span_module_decl)
675 << SourceRange(StartLoc, End);
676 CurPPLexer->ParsingPreprocessorDirective =
false;
679 CurLexer->resetExtendedTokenMode();
686 if (
Tok.
is(tok::eof)) {
690 if (PreambleConditionalStack.isRecording())
691 PreambleConditionalStack.SkipInfo.emplace(HashTokenLoc, IfTokenLoc,
704 if (
Tok.
is(tok::eof))
710 CurPPLexer->ParsingPreprocessorDirective =
true;
711 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
713 assert(
Tok.
is(tok::hash));
714 const char *Hashptr = CurLexer->getBufferLocation() -
Tok.
getLength();
715 assert(CurLexer->getSourceLocation(Hashptr) ==
Tok.
getLocation());
722 if (
Tok.
isNot(tok::raw_identifier)) {
723 CurPPLexer->ParsingPreprocessorDirective =
false;
725 if (CurLexer) CurLexer->resetExtendedTokenMode();
736 char FirstChar = RI[0];
737 if (FirstChar >=
'a' && FirstChar <=
'z' &&
738 FirstChar !=
'i' && FirstChar !=
'e') {
739 CurPPLexer->ParsingPreprocessorDirective =
false;
741 if (CurLexer) CurLexer->resetExtendedTokenMode();
748 char DirectiveBuf[20];
754 size_t IdLen = DirectiveStr.size();
756 CurPPLexer->ParsingPreprocessorDirective =
false;
758 if (CurLexer) CurLexer->resetExtendedTokenMode();
761 memcpy(DirectiveBuf, &DirectiveStr[0], IdLen);
762 Directive = StringRef(DirectiveBuf, IdLen);
782 PPConditionalInfo CondInfo;
784 bool InCond = CurPPLexer->popConditionalLevel(CondInfo);
786 assert(!InCond &&
"Can't be skipping if not in a conditional!");
790 SkippingRangeState.endLexPass(Hashptr);
793 CurPPLexer->LexingRawMode =
false;
795 CurPPLexer->LexingRawMode =
true;
802 }
else if (Sub ==
"lse") {
806 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
809 SkippingRangeState.endLexPass(Hashptr);
813 Diag(
Tok, diag::pp_err_else_after_else);
824 CurPPLexer->LexingRawMode =
false;
826 CurPPLexer->LexingRawMode =
true;
833 }
else if (Sub ==
"lif") {
834 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
837 SkippingRangeState.endLexPass(Hashptr);
854 assert(CurPPLexer->LexingRawMode &&
"We have to be skipping here!");
855 CurPPLexer->LexingRawMode =
false;
856 IdentifierInfo *IfNDefMacro =
nullptr;
857 DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
861 const bool CondValue = DER.Conditional;
862 CurPPLexer->LexingRawMode =
true;
875 }
else if (Sub ==
"lifdef" ||
877 bool IsElifDef =
Sub ==
"lifdef";
878 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
879 Token DirectiveToken =
Tok;
882 SkippingRangeState.endLexPass(Hashptr);
887 if (LangOpts.CPlusPlus)
888 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
889 : diag::ext_cxx23_pp_directive;
891 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
892 : diag::ext_c23_pp_directive;
897 Diag(
Tok, diag::pp_err_elif_after_else)
911 assert(CurPPLexer->LexingRawMode &&
"We have to be skipping here!");
912 CurPPLexer->LexingRawMode =
false;
914 ReadMacroName(MacroNameTok);
915 CurPPLexer->LexingRawMode =
true;
919 if (MacroNameTok.
is(tok::eod)) {
931 MacroInfo *MI = MD.getMacroInfo();
935 Callbacks->Elifdef(DirectiveToken.
getLocation(), MacroNameTok,
938 Callbacks->Elifndef(DirectiveToken.
getLocation(), MacroNameTok,
943 if (
static_cast<bool>(MI) == IsElifDef) {
955 CurPPLexer->ParsingPreprocessorDirective =
false;
957 if (CurLexer) CurLexer->resetExtendedTokenMode();
963 CurPPLexer->LexingRawMode =
false;
968 Callbacks->SourceRangeSkipped(
969 SourceRange(HashTokenLoc, endLoc.
isValid()
971 : CurPPLexer->getSourceLocation()),
977 if (!SourceMgr.isInMainFile(Loc)) {
980 FileID IDOfIncl = SourceMgr.getFileID(SourceMgr.getExpansionLoc(Loc));
981 if (
auto EntryOfIncl = SourceMgr.getFileEntryRefForID(IDOfIncl)) {
983 return HeaderInfo.getModuleMap()
984 .findModuleForHeader(*EntryOfIncl, AllowTextual)
993 : HeaderInfo.lookupModule(
getLangOpts().CurrentModule, Loc);
1000 IncLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
1007 while (!Loc.
isInvalid() && !
SM.isInMainFile(Loc)) {
1008 auto ID =
SM.getFileID(
SM.getExpansionLoc(Loc));
1009 auto FE =
SM.getFileEntryRefForID(ID);
1015 HeaderInfo.hasModuleMap(FE->getName(),
nullptr,
1016 SourceMgr.isInSystemHeader(Loc));
1018 bool InPrivateHeader =
false;
1019 for (
auto Header : HeaderInfo.findAllModulesForHeader(*FE)) {
1020 if (!Header.isAccessibleFrom(IncM)) {
1025 InPrivateHeader =
true;
1042 return std::nullopt;
1052 if (InPrivateHeader)
1053 return std::nullopt;
1061 Loc =
SM.getIncludeLoc(ID);
1064 return std::nullopt;
1073 bool *IsFrameworkFound,
bool SkipCache,
bool OpenFile,
bool CacheFailures) {
1078 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
1083 bool BuildSystemModule =
false;
1084 if (!FromDir && !FromFile) {
1101 if (FID == SourceMgr.getMainFileID() && MainFileDir) {
1103 HeaderInfo.getModuleMap().shouldImportRelativeToBuiltinIncludeDir(
1105 ? HeaderInfo.getModuleMap().getBuiltinDir()
1107 Includers.push_back(std::make_pair(std::nullopt, *IncludeDir));
1109 }
else if ((FileEnt = SourceMgr.getFileEntryRefForID(
1110 SourceMgr.getMainFileID()))) {
1111 auto CWD = FileMgr.getOptionalDirectoryRef(
".");
1112 Includers.push_back(std::make_pair(*FileEnt, *CWD));
1115 Includers.push_back(std::make_pair(*FileEnt, FileEnt->
getDir()));
1121 if (LangOpts.MSVCCompat && !isAngled) {
1122 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1123 if (IsFileLexer(ISEntry))
1125 Includers.push_back(std::make_pair(*FileEnt, FileEnt->
getDir()));
1130 CurDir = CurDirLookup;
1138 Filename, FilenameLoc, isAngled, TmpFromDir, &TmpCurDir,
1139 Includers, SearchPath, RelativePath, RequestingModule,
1140 SuggestedModule,
nullptr,
1141 nullptr, SkipCache)) {
1143 TmpFromDir = TmpCurDir;
1145 if (&FE->getFileEntry() == FromFile) {
1147 FromDir = TmpFromDir;
1156 Filename, FilenameLoc, isAngled, FromDir, &CurDir, Includers, SearchPath,
1157 RelativePath, RequestingModule, SuggestedModule, IsMapped,
1158 IsFrameworkFound, SkipCache, BuildSystemModule, OpenFile, CacheFailures);
1166 if (IsFileLexer()) {
1169 Filename, *CurFileEnt, SearchPath, RelativePath, RequestingModule,
1176 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1177 if (IsFileLexer(ISEntry)) {
1178 if ((CurFileEnt = ISEntry.ThePPLexer->
getFileEntry())) {
1180 Filename, *CurFileEnt, SearchPath, RelativePath,
1181 RequestingModule, SuggestedModule)) {
1189 return std::nullopt;
1196 if (llvm::sys::path::is_absolute(Filename)) {
1203 StringRef StartingFrom, StringRef
FileName,
1204 bool RemoveInitialFileComponentFromLookupPath) {
1205 llvm::sys::path::native(StartingFrom, LookupPath);
1206 if (RemoveInitialFileComponentFromLookupPath)
1207 llvm::sys::path::remove_filename(LookupPath);
1208 if (!LookupPath.empty() &&
1209 !llvm::sys::path::is_separator(LookupPath.back())) {
1210 LookupPath.push_back(llvm::sys::path::get_separator().front());
1220 if (LookupFromFile) {
1224 llvm::sys::path::append(TmpDir, Filename);
1225 if (!TmpDir.empty()) {
1227 TmpDir, OpenFile,
true,
false);
1229 return ShouldBeEntry;
1236 if (MaybeWorkingDirEntry) {
1238 StringRef WorkingDir = WorkingDirEntry.
getName();
1239 if (!WorkingDir.empty()) {
1240 SeparateComponents(LookupPath, WorkingDir, Filename,
false);
1242 LookupPath, OpenFile,
true,
false);
1244 return ShouldBeEntry;
1249 for (
const auto &Entry : PPOpts.EmbedEntries) {
1251 SeparateComponents(LookupPath, Entry, Filename,
false);
1253 LookupPath, OpenFile,
true,
false);
1255 return ShouldBeEntry;
1257 return std::nullopt;
1267 : PP(pp), save(pp->DisableMacroExpansion) {
1268 if (pp->MacroExpansionInDirectivesOverride)
1269 pp->DisableMacroExpansion =
false;
1273 PP->DisableMacroExpansion = save;
1291 return HandleDefineDirective(
Result,
1294 if (SkippingUntilPCHThroughHeader &&
1296 return HandleIncludeDirective(HashLoc,
Result);
1298 if (SkippingUntilPragmaHdrStop && II->
getPPKeywordID() == tok::pp_pragma) {
1300 auto *II =
Result.getIdentifierInfo();
1301 if (II && II->
getName() ==
"hdrstop")
1318 CurPPLexer->ParsingPreprocessorDirective =
true;
1319 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
1321 bool ImmediatelyAfterTopLevelIfndef =
1322 CurPPLexer->MIOpt.getImmediatelyAfterTopLevelIfndef();
1323 CurPPLexer->MIOpt.resetImmediatelyAfterTopLevelIfndef();
1330 bool ReadAnyTokensBeforeDirective =CurPPLexer->MIOpt.getHasReadAnyTokensVal();
1338 if (Introducer.
isOneOf(tok::hash, tok::at))
1352 case tok::pp_include:
1353 case tok::pp_import:
1354 case tok::pp_include_next:
1355 case tok::pp___include_macros:
1356 case tok::pp_pragma:
1358 case tok::pp_module:
1359 case tok::pp___preprocessed_module:
1360 case tok::pp___preprocessed_import:
1362 << Introducer.
is(tok::hash) << II->
getName();
1363 Diag(*ArgMacro, diag::note_macro_expansion_here)
1364 << ArgMacro->getIdentifierInfo();
1378 if (SkippingUntilPCHThroughHeader || SkippingUntilPragmaHdrStop)
1382 switch (
Result.getKind()) {
1387 CurPPLexer->MIOpt.SetReadToken(ReadAnyTokensBeforeDirective);
1389 case tok::code_completion:
1392 CodeComplete->CodeCompleteDirective(
1393 CurPPLexer->getConditionalStackDepth() > 0);
1395 case tok::numeric_constant:
1402 return HandleDigitDirective(
Result);
1412 return HandleIfDirective(
Result, Introducer,
1413 ReadAnyTokensBeforeDirective);
1415 return HandleIfdefDirective(
Result, Introducer,
false,
1417 case tok::pp_ifndef:
1418 return HandleIfdefDirective(
Result, Introducer,
true,
1419 ReadAnyTokensBeforeDirective);
1421 case tok::pp_elifdef:
1422 case tok::pp_elifndef:
1423 return HandleElifFamilyDirective(
Result, Introducer,
1427 return HandleElseDirective(
Result, Introducer);
1429 return HandleEndifDirective(
Result);
1432 case tok::pp_include:
1435 case tok::pp___include_macros:
1440 case tok::pp_define:
1441 return HandleDefineDirective(
Result, ImmediatelyAfterTopLevelIfndef);
1443 return HandleUndefDirective();
1447 return HandleLineDirective();
1451 return HandleUserDiagnosticDirective(
Result,
false);
1454 case tok::pp_pragma:
1456 case tok::pp_module:
1457 case tok::pp___preprocessed_module:
1461 case tok::pp___preprocessed_import:
1463 case tok::pp_import:
1464 switch (Introducer.
getKind()) {
1468 return HandleObjCImportDirective(Introducer,
Result);
1469 case tok::kw_import:
1472 llvm_unreachable(
"not a valid import directive");
1476 case tok::pp_include_next:
1479 case tok::pp_warning:
1480 if (LangOpts.CPlusPlus)
1482 ? diag::warn_cxx23_compat_warning_directive
1483 : diag::ext_pp_warning_directive)
1486 Diag(
Result, LangOpts.C23 ? diag::warn_c23_compat_warning_directive
1487 : diag::ext_pp_warning_directive)
1490 return HandleUserDiagnosticDirective(
Result,
true);
1492 return HandleIdentSCCSDirective(
Result);
1494 return HandleIdentSCCSDirective(
Result);
1497 case tok::pp_assert:
1500 case tok::pp_unassert:
1504 case tok::pp___public_macro:
1506 return HandleMacroPublicDirective(
Result);
1509 case tok::pp___private_macro:
1511 return HandleMacroPrivateDirective();
1522 auto Toks = std::make_unique<Token[]>(2);
1524 Toks[0] = Introducer;
1529 if (
Result.is(tok::hashhash))
1530 Toks[1].setKind(tok::unknown);
1535 EnterTokenStream(std::move(Toks), 2,
false,
false);
1541 Diag(
Result, diag::err_pp_invalid_directive) << 0;
1553 bool IsGNULineDirective=
false) {
1554 if (DigitTok.
isNot(tok::numeric_constant)) {
1555 PP.
Diag(DigitTok, DiagID);
1557 if (DigitTok.
isNot(tok::eod))
1563 IntegerBuffer.resize(DigitTok.
getLength());
1564 const char *DigitTokBegin = &IntegerBuffer[0];
1574 for (
unsigned i = 0; i != ActualLength; ++i) {
1577 if (DigitTokBegin[i] ==
'\'')
1580 if (!
isDigit(DigitTokBegin[i])) {
1582 diag::err_pp_line_digit_sequence) << IsGNULineDirective;
1587 unsigned NextVal = Val*10+(DigitTokBegin[i]-
'0');
1588 if (NextVal < Val) {
1589 PP.
Diag(DigitTok, DiagID);
1596 if (DigitTokBegin[0] ==
'0' && Val)
1598 << IsGNULineDirective;
1610void Preprocessor::HandleLineDirective() {
1618 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*
this))
1622 Diag(DigitTok, diag::ext_pp_line_zero);
1626 unsigned LineLimit = 32768U;
1627 if (LangOpts.C99 || LangOpts.CPlusPlus11)
1628 LineLimit = 2147483648U;
1629 if (LineNo >= LineLimit)
1630 Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
1631 else if (LangOpts.CPlusPlus11 && LineNo >= 32768U)
1632 Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
1634 int FilenameID = -1;
1640 if (StrTok.
is(tok::eod))
1642 else if (StrTok.
isNot(tok::string_literal)) {
1643 Diag(StrTok, diag::err_pp_line_invalid_filename);
1647 Diag(StrTok, diag::err_invalid_string_udl);
1652 StringLiteralParser
Literal(StrTok, *
this,
1654 assert(
Literal.isOrdinary() &&
"Didn't allow wide strings in");
1660 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1664 FilenameID = SourceMgr.getLineTableFilenameID(
Literal.GetString());
1677 SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1679 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID,
false,
1683 Callbacks->FileChanged(CurPPLexer->getSourceLocation(),
1695 if (FlagTok.
is(tok::eod))
return false;
1696 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1703 if (FlagTok.
is(tok::eod))
return false;
1704 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1706 }
else if (FlagVal == 2) {
1722 SM.getDecomposedExpansionLoc(IncLoc).first != CurFileID) {
1723 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);
1729 if (FlagTok.
is(tok::eod))
return false;
1730 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1736 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1744 if (FlagTok.
is(tok::eod))
return false;
1745 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1750 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1758 if (FlagTok.
is(tok::eod))
return false;
1761 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1773void Preprocessor::HandleDigitDirective(
Token &DigitTok) {
1777 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
1784 bool IsFileEntry =
false, IsFileExit =
false;
1785 int FilenameID = -1;
1790 if (StrTok.
is(tok::eod)) {
1791 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1793 FileKind = SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1794 }
else if (StrTok.
isNot(tok::string_literal)) {
1795 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1799 Diag(StrTok, diag::err_invalid_string_udl);
1804 StringLiteralParser
Literal(StrTok, *
this,
1806 assert(
Literal.isOrdinary() &&
"Didn't allow wide strings in");
1812 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1820 if (!SourceMgr.isInPredefinedFile(DigitTok.
getLocation()))
1821 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1825 if (!(IsFileExit &&
Literal.GetString().empty()))
1826 FilenameID = SourceMgr.getLineTableFilenameID(
Literal.GetString());
1830 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID, IsFileEntry,
1831 IsFileExit, FileKind);
1840 else if (IsFileExit)
1843 Callbacks->FileChanged(CurPPLexer->getSourceLocation(), Reason, FileKind);
1849void Preprocessor::HandleUserDiagnosticDirective(
Token &
Tok,
1857 CurLexer->ReadToEndOfLine(&Message);
1861 StringRef Msg =
Message.str().ltrim(
' ');
1864 Diag(
Tok, diag::pp_hash_warning) << Msg;
1866 Diag(
Tok, diag::err_pp_hash_error) << Msg;
1871void Preprocessor::HandleIdentSCCSDirective(
Token &
Tok) {
1873 Diag(
Tok, diag::ext_pp_ident_directive);
1880 if (StrTok.
isNot(tok::string_literal) &&
1881 StrTok.
isNot(tok::wide_string_literal)) {
1882 Diag(StrTok, diag::err_pp_malformed_ident);
1883 if (StrTok.
isNot(tok::eod))
1889 Diag(StrTok, diag::err_invalid_string_udl);
1906void Preprocessor::HandleMacroPublicDirective(
Token &
Tok) {
1908 ReadMacroName(MacroNameTok,
MU_Undef);
1911 if (MacroNameTok.
is(tok::eod))
1923 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1933void Preprocessor::HandleMacroPrivateDirective() {
1935 ReadMacroName(MacroNameTok,
MU_Undef);
1938 if (MacroNameTok.
is(tok::eod))
1950 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1970 StringRef &Buffer) {
1972 assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1984 if (Buffer[0] ==
'<') {
1985 if (Buffer.back() !=
'>') {
1986 Diag(Loc, diag::err_pp_expects_filename);
1987 Buffer = StringRef();
1991 }
else if (Buffer[0] ==
'"') {
1992 if (Buffer.back() !=
'"') {
1993 Diag(Loc, diag::err_pp_expects_filename);
1994 Buffer = StringRef();
1999 Diag(Loc, diag::err_pp_expects_filename);
2000 Buffer = StringRef();
2005 if (Buffer.size() <= 2) {
2006 Diag(Loc, diag::err_pp_empty_filename);
2007 Buffer = StringRef();
2012 Buffer = Buffer.substr(1, Buffer.size()-2);
2019 void *AnnotationVal) {
2022 auto Tok = std::make_unique<Token[]>(1);
2023 Tok[0].startToken();
2024 Tok[0].setKind(Kind);
2025 Tok[0].setLocation(Range.getBegin());
2026 Tok[0].setAnnotationEndLoc(Range.getEnd());
2027 Tok[0].setAnnotationValue(AnnotationVal);
2028 EnterTokenStream(std::move(
Tok), 1,
true,
false);
2038 for (
size_t I = 0, N = Path.size(); I != N; ++I) {
2041 PathString += Path[I].getIdentifierInfo()->getName();
2044 int IncludeKind = 0;
2046 case tok::pp_include:
2050 case tok::pp_import:
2054 case tok::pp_include_next:
2058 case tok::pp___include_macros:
2063 llvm_unreachable(
"unknown include directive kind");
2066 PP.
Diag(HashLoc, diag::remark_pp_include_directive_modular_translation)
2067 << IncludeKind << PathString;
2074 StringRef RealPathName,
2075 llvm::sys::path::Style Separator) {
2076 auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName);
2077 auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName);
2079 bool SuggestReplacement =
false;
2081 auto IsSep = [Separator](StringRef Component) {
2082 return Component.size() == 1 &&
2083 llvm::sys::path::is_separator(Component[0], Separator);
2088 for (
auto &Component : llvm::reverse(Components)) {
2089 if (
"." == Component) {
2090 }
else if (
".." == Component) {
2094 }
else if (RealPathComponentIter != RealPathComponentEnd) {
2095 if (!IsSep(Component) && !IsSep(*RealPathComponentIter) &&
2096 Component != *RealPathComponentIter) {
2100 SuggestReplacement =
2101 RealPathComponentIter->equals_insensitive(Component);
2102 if (!SuggestReplacement)
2104 Component = *RealPathComponentIter;
2106 ++RealPathComponentIter;
2109 return SuggestReplacement;
2118 Module *ShadowingModule =
nullptr;
2124 Diags.Report(MissingHeader.
FileNameLoc, diag::err_module_header_missing)
2126 }
else if (ShadowingModule) {
2129 diag::note_previous_definition);
2140std::pair<ConstSearchDirIterator, const FileEntry *>
2141Preprocessor::getIncludeNextStart(
const Token &IncludeNextTok)
const {
2146 const FileEntry *LookupFromFile =
nullptr;
2154 Diag(IncludeNextTok, diag::pp_include_next_in_primary);
2155 }
else if (CurLexerSubmodule) {
2158 assert(CurPPLexer &&
"#include_next directive in macro?");
2159 if (
auto FE = CurPPLexer->getFileEntry())
2160 LookupFromFile = *FE;
2162 }
else if (!Lookup) {
2167 Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
2173 return {Lookup, LookupFromFile};
2189 if (FilenameTok.
isNot(tok::header_name)) {
2190 if (FilenameTok.
is(tok::identifier) &&
2191 (PPOpts.SingleFileParseMode || PPOpts.SingleModuleParseMode)) {
2201 if (FilenameTok.
isNot(tok::eod))
2210 SourceLocation EndLoc =
2213 auto Action = HandleHeaderIncludeOrImport(HashLoc, IncludeTok, FilenameTok,
2214 EndLoc, LookupFrom, LookupFromFile);
2215 switch (Action.Kind) {
2216 case ImportAction::None:
2217 case ImportAction::SkippedModuleImport:
2219 case ImportAction::ModuleBegin:
2221 tok::annot_module_begin, Action.ModuleForHeader);
2223 case ImportAction::HeaderUnitImport:
2225 Action.ModuleForHeader);
2227 case ImportAction::ModuleImport:
2229 tok::annot_module_include, Action.ModuleForHeader);
2231 case ImportAction::Failure:
2232 assert(TheModuleLoader.HadFatalFailure &&
2233 "This should be an early exit only to a fatal error");
2234 TheModuleLoader.HadFatalFailure =
true;
2236 CurLexer->cutOffLexing();
2244 const Token &FilenameTok,
bool &IsFrameworkFound,
bool IsImportDecl,
2246 const FileEntry *LookupFromFile, StringRef &LookupFilename,
2249 auto DiagnoseHeaderInclusion = [&](FileEntryRef FE) {
2250 if (LangOpts.AsmPreprocessor)
2254 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
2255 bool RequestingModuleIsModuleInterface =
2256 !SourceMgr.isInMainFile(FilenameLoc);
2258 HeaderInfo.getModuleMap().diagnoseHeaderInclusion(
2259 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
2264 FilenameLoc, LookupFilename, isAngled, LookupFrom, LookupFromFile, CurDir,
2265 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2266 &SuggestedModule, &IsMapped, &IsFrameworkFound);
2268 DiagnoseHeaderInclusion(*
File);
2273 if (Callbacks && Callbacks->FileNotFound(Filename))
2274 return std::nullopt;
2276 if (SuppressIncludeNotFoundError)
2277 return std::nullopt;
2284 FilenameLoc, LookupFilename,
false, LookupFrom, LookupFromFile, CurDir,
2285 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2286 &SuggestedModule, &IsMapped,
2289 DiagnoseHeaderInclusion(*
File);
2290 Diag(FilenameTok, diag::err_pp_file_not_found_angled_include_not_fatal)
2291 << Filename << IsImportDecl
2293 "\"" + Filename.str() +
"\"");
2300 StringRef OriginalFilename = Filename;
2301 if (LangOpts.SpellChecking) {
2304 auto CorrectTypoFilename = [](llvm::StringRef Filename) {
2307 Filename = Filename.drop_back();
2311 StringRef TypoCorrectionName = CorrectTypoFilename(Filename);
2312 StringRef TypoCorrectionLookupName = CorrectTypoFilename(LookupFilename);
2315 FilenameLoc, TypoCorrectionLookupName, isAngled, LookupFrom,
2316 LookupFromFile, CurDir, Callbacks ? &SearchPath :
nullptr,
2317 Callbacks ? &RelativePath :
nullptr, &SuggestedModule, &IsMapped,
2320 DiagnoseHeaderInclusion(*
File);
2323 FilenameRange,
"<" + TypoCorrectionName.str() +
">")
2324 : FixItHint::CreateReplacement(
2325 FilenameRange,
"\"" + TypoCorrectionName.str() +
"\"");
2326 Diag(FilenameTok, diag::err_pp_file_not_found_typo_not_fatal)
2327 << OriginalFilename << TypoCorrectionName << Hint;
2330 Filename = TypoCorrectionName;
2331 LookupFilename = TypoCorrectionLookupName;
2337 assert(!
File &&
"expected missing file");
2338 Diag(FilenameTok, diag::err_pp_file_not_found)
2339 << OriginalFilename << FilenameRange;
2340 if (IsFrameworkFound) {
2341 size_t SlashPos = OriginalFilename.find(
'/');
2342 assert(SlashPos != StringRef::npos &&
2343 "Include with framework name should have '/' in the filename");
2344 StringRef FrameworkName = OriginalFilename.substr(0, SlashPos);
2345 FrameworkCacheEntry &CacheEntry =
2346 HeaderInfo.LookupFrameworkCache(FrameworkName);
2347 assert(CacheEntry.
Directory &&
"Found framework should be in cache");
2348 Diag(FilenameTok, diag::note_pp_framework_without_header)
2349 << OriginalFilename.substr(SlashPos + 1) << FrameworkName
2353 return std::nullopt;
2368Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
2372 SmallString<128> FilenameBuffer;
2373 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
2374 SourceLocation CharEnd = FilenameTok.
getEndLoc();
2376 CharSourceRange FilenameRange
2378 StringRef OriginalFilename = Filename;
2384 if (Filename.empty())
2385 return {ImportAction::None};
2386 if (Filename.ends_with(
' ') || Filename.ends_with(
'.')) {
2387 unsigned Selection = Filename.ends_with(
'.') ? 1 : 0;
2388 Diag(FilenameTok, diag::pp_nonportable_path_trailing)
2389 << Filename << Selection;
2392 bool IsImportDecl = HashLoc.
isInvalid();
2393 SourceLocation StartLoc = IsImportDecl ? IncludeTok.
getLocation() : HashLoc;
2396 if (PragmaARCCFCodeAuditedInfo.getLoc().isValid()) {
2397 Diag(StartLoc, diag::err_pp_include_in_arc_cf_code_audited) << IsImportDecl;
2398 Diag(PragmaARCCFCodeAuditedInfo.getLoc(), diag::note_pragma_entered_here);
2401 PragmaARCCFCodeAuditedInfo = IdentifierLoc();
2405 if (PragmaAssumeNonNullLoc.isValid()) {
2406 Diag(StartLoc, diag::err_pp_include_in_assume_nonnull) << IsImportDecl;
2407 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
2410 PragmaAssumeNonNullLoc = SourceLocation();
2413 if (HeaderInfo.HasIncludeAliasMap()) {
2417 StringRef NewName = HeaderInfo.MapHeaderToIncludeAlias(OriginalFilename);
2418 if (!NewName.empty())
2423 bool IsMapped =
false;
2424 bool IsFrameworkFound =
false;
2426 SmallString<1024> SearchPath;
2427 SmallString<1024> RelativePath;
2430 ModuleMap::KnownHeader SuggestedModule;
2431 SourceLocation FilenameLoc = FilenameTok.
getLocation();
2432 StringRef LookupFilename = Filename;
2436 SmallString<128> NormalizedPath;
2437 llvm::sys::path::Style BackslashStyle = llvm::sys::path::Style::native;
2438 if (is_style_posix(BackslashStyle) && LangOpts.MicrosoftExt) {
2439 NormalizedPath = Filename.str();
2440 llvm::sys::path::native(NormalizedPath);
2441 LookupFilename = NormalizedPath;
2442 BackslashStyle = llvm::sys::path::Style::windows;
2446 &CurDir, Filename, FilenameLoc, FilenameRange, FilenameTok,
2447 IsFrameworkFound, IsImportDecl, IsMapped, LookupFrom, LookupFromFile,
2448 LookupFilename, RelativePath, SearchPath, SuggestedModule, isAngled);
2452 SkippingUntilPCHThroughHeader =
false;
2453 return {ImportAction::None};
2471 enum { Enter,
Import,
Skip, IncludeLimitReached } Action = Enter;
2473 if (PPOpts.SingleFileParseMode)
2474 Action = IncludeLimitReached;
2479 if (Action == Enter && HasReachedMaxIncludeDepth &&
File &&
2481 Action = IncludeLimitReached;
2488 bool MaybeTranslateInclude = Action == Enter &&
File && ModuleToImport &&
2492 bool UsableHeaderUnit =
false;
2493 if (
getLangOpts().CPlusPlusModules && ModuleToImport &&
2495 if (TrackGMFState.inGMF() || IsImportDecl)
2496 UsableHeaderUnit =
true;
2497 else if (!IsImportDecl) {
2499 ModuleToImport =
nullptr;
2503 bool UsableClangHeaderModule =
2510 if (MaybeTranslateInclude && (UsableHeaderUnit || UsableClangHeaderModule)) {
2518 diag::note_implicit_top_level_module_import_here)
2520 return {ImportAction::None};
2526 SmallVector<IdentifierLoc, 2> Path;
2527 for (
Module *Mod = ModuleToImport; Mod; Mod = Mod->Parent)
2530 std::reverse(Path.begin(), Path.end());
2540 ModuleLoadResult Imported = TheModuleLoader.loadModule(
2543 assert((Imported ==
nullptr || Imported == ModuleToImport) &&
2544 "the imported module is different than the suggested one");
2550 static_cast<Module *
>(Imported)->getTopLevelModule());
2555 ModuleToImport =
nullptr;
2563 Token &
Result = IncludeTok;
2564 assert(CurLexer &&
"#include but no current lexer set!");
2566 CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
2567 CurLexer->cutOffLexing();
2569 return {ImportAction::None};
2577 SourceMgr.getFileCharacteristic(FilenameTok.
getLocation());
2579 FileCharacter = std::max(HeaderInfo.getFileDirFlavor(*
File), FileCharacter);
2590 bool IsFirstIncludeOfFile =
false;
2594 if (Action == Enter &&
File &&
2595 !HeaderInfo.ShouldEnterIncludeFile(*
this, *
File, EnterOnce,
2597 IsFirstIncludeOfFile)) {
2608 if (UsableHeaderUnit && !
getLangOpts().CompilingPCH)
2609 Action = TrackGMFState.inGMF() ?
Import :
Skip;
2611 Action = (ModuleToImport && !
getLangOpts().CompilingPCH) ? Import :
Skip;
2619 if (Action == Enter &&
File && PreambleConditionalStack.isRecording() &&
2620 SourceMgr.isMainFile(
File->getFileEntry())) {
2622 diag::err_pp_including_mainfile_in_preamble);
2623 return {ImportAction::None};
2626 if (Callbacks && !IsImportDecl) {
2629 Callbacks->InclusionDirective(HashLoc, IncludeTok, LookupFilename, isAngled,
2630 FilenameRange,
File, SearchPath, RelativePath,
2631 SuggestedModule.
getModule(), Action == Import,
2634 Callbacks->FileSkipped(*
File, FilenameTok, FileCharacter);
2638 return {ImportAction::None};
2642 if (IsImportDecl && !ModuleToImport) {
2643 Diag(FilenameTok, diag::err_header_import_not_header_unit)
2644 << OriginalFilename <<
File->getName();
2645 return {ImportAction::None};
2650 const bool CheckIncludePathPortability =
2651 !IsMapped && !
File->getFileEntry().tryGetRealPathName().empty();
2653 if (CheckIncludePathPortability) {
2654 StringRef Name = LookupFilename;
2655 StringRef NameWithoriginalSlashes = Filename;
2659 bool NameWasUNC = Name.consume_front(
"\\\\?\\");
2660 NameWithoriginalSlashes.consume_front(
"\\\\?\\");
2662 StringRef RealPathName =
File->getFileEntry().tryGetRealPathName();
2663 SmallVector<StringRef, 16> Components(llvm::sys::path::begin(Name),
2664 llvm::sys::path::end(Name));
2676 SmallString<128> FixedDriveRealPath;
2677 if (llvm::sys::path::is_absolute(Name) &&
2678 llvm::sys::path::is_absolute(RealPathName) &&
2681 assert(Components.size() >= 3 &&
"should have drive, backslash, name");
2682 assert(Components[0].size() == 2 &&
"should start with drive");
2683 assert(Components[0][1] ==
':' &&
"should have colon");
2684 FixedDriveRealPath = (Name.substr(0, 1) + RealPathName.substr(1)).str();
2685 RealPathName = FixedDriveRealPath;
2690 SmallString<128> Path;
2691 Path.reserve(Name.size()+2);
2692 Path.push_back(isAngled ?
'<' :
'"');
2694 const auto IsSep = [BackslashStyle](
char c) {
2695 return llvm::sys::path::is_separator(c, BackslashStyle);
2698 for (
auto Component : Components) {
2710 if (!(Component.size() == 1 && IsSep(Component[0])))
2711 Path.append(Component);
2712 else if (Path.size() != 1)
2716 if (Path.size() > NameWithoriginalSlashes.size()) {
2717 Path.push_back(isAngled ?
'>' :
'"');
2720 assert(IsSep(NameWithoriginalSlashes[Path.size()-1]));
2722 Path.push_back(NameWithoriginalSlashes[Path.size()-1]);
2723 while (Path.size() <= NameWithoriginalSlashes.size() &&
2724 IsSep(NameWithoriginalSlashes[Path.size()-1]));
2730 Path = (Path.substr(0, 1) +
"\\\\?\\" + Path.substr(1)).str();
2737 ? diag::pp_nonportable_path
2738 : diag::pp_nonportable_system_path;
2739 Diag(FilenameTok, DiagId) << Path <<
2743 bool SuppressBackslashDiag =
2745 Diags->isIgnored(diag::pp_nonportable_path_separator, FilenameLoc) ||
2748 SourceMgr.isWrittenInBuiltinFile(FilenameLoc) ||
2749 SourceMgr.isWrittenInModuleIncludes(FilenameLoc);
2750 if (!SuppressBackslashDiag && OriginalFilename.contains(
'\\')) {
2751 std::string SuggestedPath = OriginalFilename.str();
2752 llvm::replace(SuggestedPath,
'\\',
'/');
2753 Diag(FilenameTok, diag::pp_nonportable_path_separator)
2762 return {ImportAction::SkippedModuleImport, ModuleToImport};
2763 return {ImportAction::None};
2765 case IncludeLimitReached:
2768 return {ImportAction::None};
2772 assert(ModuleToImport &&
"no module to import");
2777 tok::pp___include_macros)
2778 return {ImportAction::None};
2780 return {ImportAction::ModuleImport, ModuleToImport};
2788 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
2789 Diag(FilenameTok, diag::err_pp_include_too_deep);
2790 HasReachedMaxIncludeDepth =
true;
2791 return {ImportAction::None};
2795 Diag(FilenameTok, diag::warn_pp_include_angled_in_module_purview)
2799 SourceLocation IncludePos = FilenameTok.
getLocation();
2803 IncludePos = SourceMgr.getExpansionRange(IncludePos).getEnd();
2804 FileID FID = SourceMgr.createFileID(*
File, IncludePos, FileCharacter);
2806 TheModuleLoader.HadFatalFailure =
true;
2807 return ImportAction::Failure;
2812 IsFirstIncludeOfFile))
2813 return {ImportAction::None};
2817 if (ModuleToImport && !ModuleToImport->
isHeaderUnit()) {
2822 diag::err_module_build_shadowed_submodule)
2825 diag::note_previous_definition);
2826 return {ImportAction::None};
2838 return {ImportAction::None};
2840 assert(!CurLexerSubmodule &&
"should not have marked this as a module yet");
2841 CurLexerSubmodule = ModuleToImport;
2851 return {ImportAction::ModuleBegin, ModuleToImport};
2854 assert(!IsImportDecl &&
"failed to diagnose missing module for import decl");
2855 return {ImportAction::None};
2860void Preprocessor::HandleIncludeNextDirective(
SourceLocation HashLoc,
2861 Token &IncludeNextTok) {
2862 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
2865 const FileEntry *LookupFromFile;
2866 std::tie(Lookup, LookupFromFile) = getIncludeNextStart(IncludeNextTok);
2868 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
2873void Preprocessor::HandleMicrosoftImportDirective(
Token &
Tok) {
2879 Diag(
Tok, diag::err_pp_import_directive_ms );
2890 if (!LangOpts.ObjC) {
2891 if (LangOpts.MSVCCompat)
2892 return HandleMicrosoftImportDirective(ImportTok);
2893 Diag(ImportTok, diag::ext_pp_import_directive);
2895 return HandleIncludeDirective(HashLoc, ImportTok);
2902void Preprocessor::HandleIncludeMacrosDirective(
SourceLocation HashLoc,
2903 Token &IncludeMacrosTok) {
2906 SourceLocation Loc = IncludeMacrosTok.
getLocation();
2907 if (SourceMgr.getBufferName(Loc) !=
"<built-in>") {
2909 diag::pp_include_macros_out_of_predefines);
2916 HandleIncludeDirective(HashLoc, IncludeMacrosTok);
2921 assert(TmpTok.
isNot(tok::eof) &&
"Didn't find end of -imacros!");
2922 }
while (TmpTok.
isNot(tok::hashhash));
2944 Diag(
Tok, diag::err_pp_expected_ident_in_arg_list);
2948 Diag(
Tok, LangOpts.CPlusPlus11 ?
2949 diag::warn_cxx98_compat_variadic_macro :
2950 diag::ext_variadic_macro);
2953 if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus) {
2954 Diag(
Tok, diag::ext_pp_opencl_variadic_macros);
2960 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2969 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2977 Diag(
Tok, diag::err_pp_invalid_tok_in_arg_list);
2983 if (llvm::is_contained(Parameters, II)) {
2984 Diag(
Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
2996 Diag(
Tok, diag::err_pp_expected_comma_in_arg_list);
3005 Diag(
Tok, diag::ext_named_variadic_macro);
3010 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
3040 StringRef ValueText = II->
getName();
3041 StringRef TrimmedValue = ValueText;
3042 if (!ValueText.starts_with(
"__")) {
3043 if (ValueText.starts_with(
"_"))
3044 TrimmedValue = TrimmedValue.drop_front(1);
3048 TrimmedValue = TrimmedValue.drop_front(2);
3049 if (TrimmedValue.ends_with(
"__"))
3050 TrimmedValue = TrimmedValue.drop_back(2);
3052 return TrimmedValue == MacroText;
3059 return MacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
3072MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
3073 const Token &MacroNameTok,
const bool ImmediatelyAfterHeaderGuard) {
3075 Token LastTok = MacroNameTok;
3083 llvm::scope_exit _([&]() {
3085 if (CurLexer->ParsingPreprocessorDirective)
3096 if (
Tok.
is(tok::eod)) {
3097 if (ImmediatelyAfterHeaderGuard) {
3107 }
else if (
Tok.
is(tok::l_paren)) {
3110 if (ReadMacroParameterList(MI, LastTok))
3124 }
else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
3127 Diag(
Tok, diag::ext_c99_whitespace_required_after_macro_name);
3136 if (
Tok.
is(tok::at))
3138 else if (
Tok.
is(tok::unknown)) {
3145 Diag(
Tok, diag::ext_missing_whitespace_after_macro_name);
3147 Diag(
Tok, diag::warn_missing_whitespace_after_macro_name);
3150 if (!
Tok.
is(tok::eod))
3153 SmallVector<Token, 16> Tokens;
3160 Tokens.push_back(
Tok);
3174 if (!
Tok.
isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
3175 Tokens.push_back(
Tok);
3177 if (VAOCtx.isVAOptToken(
Tok)) {
3179 if (VAOCtx.isInVAOpt()) {
3180 Diag(
Tok, diag::err_pp_vaopt_nested_use);
3186 Diag(
Tok, diag::err_pp_missing_lparen_in_vaopt_use);
3189 Tokens.push_back(
Tok);
3192 if (
Tok.
is(tok::hashhash)) {
3193 Diag(
Tok, diag::err_vaopt_paste_at_start);
3197 }
else if (VAOCtx.isInVAOpt()) {
3198 if (
Tok.
is(tok::r_paren)) {
3199 if (VAOCtx.sawClosingParen()) {
3200 assert(Tokens.size() >= 3 &&
3201 "Must have seen at least __VA_OPT__( "
3202 "and a subsequent tok::r_paren");
3203 if (Tokens[Tokens.size() - 2].is(tok::hashhash)) {
3204 Diag(
Tok, diag::err_vaopt_paste_at_end);
3208 }
else if (
Tok.
is(tok::l_paren)) {
3222 Tokens.push_back(
Tok);
3229 if (
Tok.
is(tok::hashhash)) {
3237 if (
Tok.
is(tok::eod)) {
3238 Tokens.push_back(LastTok);
3243 Tokens[Tokens.size() - 1].is(tok::comma))
3247 Tokens.push_back(LastTok);
3256 if (!VAOCtx.isVAOptToken(
Tok) &&
3265 LastTok.
setKind(tok::unknown);
3266 Tokens.push_back(LastTok);
3269 Diag(
Tok, diag::err_pp_stringize_not_parameter)
3270 << LastTok.
is(tok::hashat);
3276 Tokens.push_back(LastTok);
3281 if (!VAOCtx.isVAOptToken(
Tok)) {
3282 Tokens.push_back(
Tok);
3289 if (VAOCtx.isInVAOpt()) {
3290 assert(
Tok.
is(tok::eod) &&
"Must be at End Of preprocessing Directive");
3291 Diag(
Tok, diag::err_pp_expected_after)
3292 << LastTok.
getKind() << tok::r_paren;
3293 Diag(VAOCtx.getUnmatchedOpeningParenLoc(), diag::note_matching) << tok::l_paren;
3304 return II->
isStr(
"__strong") || II->
isStr(
"__weak") ||
3305 II->
isStr(
"__unsafe_unretained") || II->
isStr(
"__autoreleasing");
3310void Preprocessor::HandleDefineDirective(
3311 Token &DefineTok,
const bool ImmediatelyAfterHeaderGuard) {
3315 bool MacroShadowsKeyword;
3316 ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
3319 if (MacroNameTok.
is(tok::eod))
3326 emitFinalMacroWarning(MacroNameTok,
false);
3330 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
3332 MacroInfo *
const MI = ReadOptionalMacroParameterListAndBody(
3333 MacroNameTok, ImmediatelyAfterHeaderGuard);
3337 if (MacroShadowsKeyword &&
3339 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
3344 if (NumTokens != 0) {
3356 if (SkippingUntilPCHThroughHeader) {
3359 LangOpts.MicrosoftExt))
3363 if (!LangOpts.MicrosoftExt)
3374 emitFinalMacroWarning(MacroNameTok,
false);
3385 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) &&
3387 LangOpts.MicrosoftExt)) {
3398 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) {
3406 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
3410 !MI->
isIdenticalTo(*OtherMI, *
this, LangOpts.MicrosoftExt)) {
3420 DefMacroDirective *MD =
3428 !MacroExpansionInDirectivesOverride &&
3437 Callbacks->MacroDefined(MacroNameTok, MD);
3442void Preprocessor::HandleUndefDirective() {
3446 ReadMacroName(MacroNameTok,
MU_Undef);
3449 if (MacroNameTok.
is(tok::eod))
3458 UndefMacroDirective *Undef =
nullptr;
3461 emitFinalMacroWarning(MacroNameTok,
true);
3471 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
3476 Undef = AllocateUndefMacroDirective(MacroNameTok.
getLocation());
3482 Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
3497void Preprocessor::HandleIfdefDirective(
Token &
Result,
3498 const Token &HashToken,
3500 bool ReadAnyTokensBeforeDirective) {
3502 Token DirectiveTok =
Result;
3505 ReadMacroName(MacroNameTok);
3508 if (MacroNameTok.
is(tok::eod)) {
3511 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3526 if (CurPPLexer->getConditionalStackDepth() == 0) {
3531 if (!ReadAnyTokensBeforeDirective && !MI) {
3532 assert(isIfndef &&
"#ifdef shouldn't reach here");
3533 CurPPLexer->MIOpt.EnterTopLevelIfndef(MII, MacroNameTok.
getLocation());
3535 CurPPLexer->MIOpt.EnterTopLevelConditional();
3544 Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3546 Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3549 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3553 if (PPOpts.SingleFileParseMode && !MI) {
3556 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3559 }
else if (PPOpts.SingleModuleParseMode && !MI) {
3563 SkipExcludedConditionalBlock(
3566 }
else if (!MI == isIfndef || RetainExcludedCB) {
3568 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3573 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3582void Preprocessor::HandleIfDirective(
Token &IfToken,
3583 const Token &HashToken,
3584 bool ReadAnyTokensBeforeDirective) {
3588 IdentifierInfo *IfNDefMacro =
nullptr;
3589 const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
3590 const bool ConditionalTrue = DER.Conditional;
3598 if (CurPPLexer->getConditionalStackDepth() == 0) {
3599 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
3601 CurPPLexer->MIOpt.EnterTopLevelIfndef(IfNDefMacro, IfToken.
getLocation());
3603 CurPPLexer->MIOpt.EnterTopLevelConditional();
3611 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3615 if (PPOpts.SingleFileParseMode && DER.IncludedUndefinedIds) {
3618 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3620 }
else if (PPOpts.SingleModuleParseMode && DER.IncludedUndefinedIds) {
3627 }
else if (ConditionalTrue || RetainExcludedCB) {
3629 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3641void Preprocessor::HandleEndifDirective(
Token &EndifToken) {
3647 PPConditionalInfo CondInfo;
3648 if (CurPPLexer->popConditionalLevel(CondInfo)) {
3650 Diag(EndifToken, diag::err_pp_endif_without_if);
3655 if (CurPPLexer->getConditionalStackDepth() == 0)
3656 CurPPLexer->MIOpt.ExitTopLevelConditional();
3658 assert(!CondInfo.
WasSkipping && !CurPPLexer->LexingRawMode &&
3659 "This code should only be reachable in the non-skipping case!");
3667void Preprocessor::HandleElseDirective(
Token &
Result,
const Token &HashToken) {
3673 PPConditionalInfo CI;
3674 if (CurPPLexer->popConditionalLevel(CI)) {
3680 if (CurPPLexer->getConditionalStackDepth() == 0)
3681 CurPPLexer->MIOpt.EnterTopLevelConditional();
3689 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3692 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3695 CurPPLexer->pushConditionalLevel(CI.
IfLoc,
false,
3703 true,
Result.getLocation());
3707void Preprocessor::HandleElifFamilyDirective(
Token &ElifToken,
3708 const Token &HashToken,
3720 if (LangOpts.CPlusPlus)
3721 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
3722 : diag::ext_cxx23_pp_directive;
3724 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
3725 : diag::ext_c23_pp_directive;
3726 Diag(ElifToken, DiagID) << DirKind;
3737 PPConditionalInfo CI;
3738 if (CurPPLexer->popConditionalLevel(CI)) {
3739 Diag(ElifToken, diag::pp_err_elif_without_if) << DirKind;
3744 if (CurPPLexer->getConditionalStackDepth() == 0)
3745 CurPPLexer->MIOpt.EnterTopLevelConditional();
3749 Diag(ElifToken, diag::pp_err_elif_after_else) << DirKind;
3754 Callbacks->Elif(ElifToken.
getLocation(), ConditionRange,
3757 case tok::pp_elifdef:
3760 case tok::pp_elifndef:
3764 assert(
false &&
"unexpected directive kind");
3769 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3772 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3775 CurPPLexer->pushConditionalLevel(ElifToken.
getLocation(),
false,
3781 SkipExcludedConditionalBlock(
3786std::optional<LexEmbedParametersResult>
3789 tok::TokenKind EndTokenKind = ForHasEmbed ? tok::r_paren : tok::eod;
3791 auto DiagMismatchedBracesAndSkipToEOD =
3793 std::pair<tok::TokenKind, SourceLocation> Matches) {
3795 Diag(Matches.second, diag::note_matching) << Matches.first;
3796 if (CurTok.
isNot(tok::eod))
3801 if (CurTok.
isNot(Kind)) {
3802 Diag(CurTok, diag::err_expected) << Kind;
3803 if (CurTok.
isNot(tok::eod))
3820 auto LexPPParameterName = [&]() -> std::optional<std::string> {
3823 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3824 return std::nullopt;
3831 if (CurTok.
is(tok::coloncolon)) {
3834 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3835 return std::nullopt;
3841 return (llvm::Twine(Prefix->
getName()) +
"::" + Suffix->
getName()).str();
3843 return Prefix->
getName().str();
3850 auto NormalizeParameterName = [](StringRef Name) {
3851 if (Name.size() > 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
3852 return Name.substr(2, Name.size() - 4);
3856 auto LexParenthesizedIntegerExpr = [&]() -> std::optional<size_t> {
3859 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3860 return std::nullopt;
3865 bool EvaluatedDefined;
3866 DirectiveEvalResult LimitEvalResult = EvaluateDirectiveExpression(
3867 ParameterIfNDef, CurTok, EvaluatedDefined,
false);
3869 if (!LimitEvalResult.Value) {
3872 assert(CurTok.
is(tok::eod) &&
"expect to be at the end of directive");
3873 return std::nullopt;
3876 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3877 return std::nullopt;
3884 if (EvaluatedDefined) {
3885 Diag(CurTok, diag::err_defined_in_pp_embed);
3886 return std::nullopt;
3889 if (LimitEvalResult.Value) {
3890 const llvm::APSInt &
Result = *LimitEvalResult.Value;
3891 if (
Result.isNegative()) {
3892 Diag(CurTok, diag::err_requires_positive_value)
3894 if (CurTok.
isNot(EndTokenKind))
3896 return std::nullopt;
3898 return Result.getLimitedValue();
3900 return std::nullopt;
3906 return tok::r_paren;
3908 return tok::r_brace;
3910 return tok::r_square;
3912 llvm_unreachable(
"should not get here");
3916 auto LexParenthesizedBalancedTokenSoup =
3918 std::vector<std::pair<tok::TokenKind, SourceLocation>> BracketStack;
3921 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3925 bool WaitingForInnerCloseParen =
false;
3926 while (CurTok.
isNot(tok::eod) &&
3927 (WaitingForInnerCloseParen || CurTok.
isNot(tok::r_paren))) {
3932 WaitingForInnerCloseParen =
true;
3939 WaitingForInnerCloseParen =
false;
3942 case tok::r_square: {
3943 if (BracketStack.empty()) {
3944 ExpectOrDiagAndSkipToEOD(tok::r_paren);
3948 GetMatchingCloseBracket(BracketStack.back().first);
3949 if (CurTok.
getKind() != Matching) {
3950 DiagMismatchedBracesAndSkipToEOD(Matching, BracketStack.back());
3953 BracketStack.pop_back();
3956 Tokens.push_back(CurTok);
3961 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3969 while (!CurTok.
isOneOf(EndTokenKind, tok::eod)) {
3971 std::optional<std::string> ParamName = LexPPParameterName();
3973 return std::nullopt;
3974 StringRef
Parameter = NormalizeParameterName(*ParamName);
3981 if (
Result.MaybeLimitParam)
3984 std::optional<size_t> Limit = LexParenthesizedIntegerExpr();
3986 return std::nullopt;
3989 }
else if (
Parameter ==
"clang::offset") {
3990 if (
Result.MaybeOffsetParam)
3993 std::optional<size_t> Offset = LexParenthesizedIntegerExpr();
3995 return std::nullopt;
3999 if (
Result.MaybePrefixParam)
4003 if (!LexParenthesizedBalancedTokenSoup(Soup))
4004 return std::nullopt;
4006 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
4008 if (
Result.MaybeSuffixParam)
4012 if (!LexParenthesizedBalancedTokenSoup(Soup))
4013 return std::nullopt;
4015 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
4017 if (
Result.MaybeIfEmptyParam)
4021 if (!LexParenthesizedBalancedTokenSoup(Soup))
4022 return std::nullopt;
4024 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
4026 ++
Result.UnrecognizedParams;
4030 if (CurTok.
is(tok::l_paren)) {
4032 if (!LexParenthesizedBalancedTokenSoup(Soup))
4033 return std::nullopt;
4036 Diag(ParamStartLoc, diag::err_pp_unknown_parameter) << 1 <<
Parameter;
4037 if (CurTok.
isNot(EndTokenKind))
4039 return std::nullopt;
4046void Preprocessor::HandleEmbedDirectiveImpl(
4048 StringRef BinaryContents, StringRef
FileName) {
4049 if (BinaryContents.empty()) {
4057 size_t TokCount = Toks.size();
4058 auto NewToks = std::make_unique<Token[]>(TokCount);
4059 llvm::copy(Toks, NewToks.get());
4060 EnterTokenStream(std::move(NewToks), TokCount,
true,
true);
4067 size_t TotalNumToks = 1 + NumPrefixToks + NumSuffixToks;
4069 auto Toks = std::make_unique<Token[]>(TotalNumToks);
4074 CurIdx += NumPrefixToks;
4077 EmbedAnnotationData *
Data =
new (BP) EmbedAnnotationData;
4078 Data->BinaryData = BinaryContents;
4081 Toks[CurIdx].startToken();
4082 Toks[CurIdx].setKind(tok::annot_embed);
4083 Toks[CurIdx].setAnnotationRange(HashLoc);
4084 Toks[CurIdx++].setAnnotationValue(
Data);
4089 CurIdx += NumSuffixToks;
4092 assert(CurIdx == TotalNumToks &&
"Calculated the incorrect number of tokens");
4093 EnterTokenStream(std::move(Toks), TotalNumToks,
true,
true);
4100 Diag(EmbedTok, diag::warn_compat_pp_embed_directive);
4102 Diag(EmbedTok, diag::ext_pp_embed_directive)
4103 << (LangOpts.CPlusPlus ? 1 : 0);
4110 if (FilenameTok.
isNot(tok::header_name)) {
4112 if (FilenameTok.
isNot(tok::eod))
4125 std::optional<LexEmbedParametersResult> Params =
4128 assert((Params || CurTok.
is(tok::eod)) &&
4129 "expected success or to be at the end of the directive");
4134 SmallString<128> FilenameBuffer;
4135 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
4136 StringRef OriginalFilename = Filename;
4142 if (Filename.empty())
4147 if (!MaybeFileRef) {
4149 if (Callbacks && Callbacks->EmbedFileNotFound(Filename)) {
4152 Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
4157 Diag(FilenameTok, diag::err_pp_embed_device_file) << Filename;
4161 std::optional<llvm::MemoryBufferRef> MaybeFile =
4165 Diag(FilenameTok, diag::err_cannot_open_file)
4166 << Filename <<
"a buffer to the contents could not be created";
4169 StringRef BinaryContents = MaybeFile->getBuffer();
4174 if (Params->MaybeOffsetParam) {
4179 BinaryContents = BinaryContents.substr(Params->MaybeOffsetParam->Offset);
4182 if (Params->MaybeLimitParam) {
4186 BinaryContents = BinaryContents.substr(0, Params->MaybeLimitParam->Limit);
4190 Callbacks->EmbedDirective(HashLoc, Filename, isAngled, MaybeFileRef,
4199 void *Mem = BP.Allocate(OriginalFilename.size(),
alignof(
char *));
4200 memcpy(Mem, OriginalFilename.data(), OriginalFilename.size());
4201 StringRef FilenameToGo =
4202 StringRef(
static_cast<char *
>(Mem), OriginalFilename.size());
4203 HandleEmbedDirectiveImpl(HashLoc, *Params, BinaryContents, FilenameToGo);
4216 assert(
getLangOpts().CPlusPlusModules && ImportTok.
is(tok::kw_import));
4218 this->ImportingCXXNamedModules,
true);
4222 if (
Tok.isNot(tok::eod))
4230 bool ImportingHeader =
false;
4231 bool IsPartition =
false;
4233 switch (
Tok.getKind()) {
4234 case tok::header_name:
4235 ImportingHeader =
true;
4236 DirToks.push_back(
Tok);
4237 Lex(DirToks.emplace_back());
4241 DirToks.push_back(
Tok);
4242 UseLoc =
Tok.getLocation();
4245 case tok::identifier: {
4247 Path, DirToks,
true,
4251 std::string FlatName;
4253 (IsPartition && ModuleDeclState.isNamedModule()) || !IsPartition;
4254 if (Callbacks && IsValid) {
4255 if (IsPartition && ModuleDeclState.isNamedModule()) {
4256 FlatName += ModuleDeclState.getPrimaryName();
4261 SourceLocation StartLoc = IsPartition ? UseLoc : Path[0].getLoc();
4273 DirToks.push_back(
Tok);
4279 if (!DirToks.back().isOneOf(tok::semi, tok::eod))
4282 if (DirToks.back().isNot(tok::eod))
4288 if (DirToks.back().isNot(tok::semi)) {
4293 if (ImportingHeader) {
4299 Diag(SemiLoc, diag::err_header_import_semi_in_macro);
4301 auto Action = HandleHeaderIncludeOrImport(
4303 switch (Action.Kind) {
4304 case ImportAction::None:
4307 case ImportAction::ModuleBegin:
4309 DirToks.emplace_back();
4310 DirToks.back().startToken();
4311 DirToks.back().setKind(tok::annot_module_begin);
4312 DirToks.back().setLocation(SemiLoc);
4313 DirToks.back().setAnnotationEndLoc(SemiLoc);
4314 DirToks.back().setAnnotationValue(Action.ModuleForHeader);
4317 case ImportAction::ModuleImport:
4318 case ImportAction::HeaderUnitImport:
4319 case ImportAction::SkippedModuleImport:
4322 DirToks[1].setKind(tok::annot_header_unit);
4323 DirToks[1].setAnnotationEndLoc(DirToks[0].getLocation());
4324 DirToks[1].setAnnotationValue(Action.ModuleForHeader);
4327 case ImportAction::Failure:
4328 assert(TheModuleLoader.HadFatalFailure &&
4329 "This should be an early exit only to a fatal error");
4330 CurLexer->cutOffLexing();
4359 assert(
getLangOpts().CPlusPlusModules && ModuleTok.
is(tok::kw_module));
4368 switch (
Tok.getKind()) {
4371 DirToks.push_back(
Tok);
4374 DirToks.push_back(
Tok);
4376 if (
Tok.isNot(tok::kw_private)) {
4377 if (
Tok.isNot(tok::eod))
4383 DirToks.push_back(
Tok);
4385 case tok::identifier: {
4387 Path, DirToks,
false,
4394 if (
Tok.is(tok::colon)) {
4397 Tok, Partition, DirToks,
4408 if (
Tok.is(tok::identifier) &&
4410 std::unique_ptr<Token[]> TokCopy = std::make_unique<Token[]>(1);
4412 EnterTokenStream(std::move(TokCopy), 1,
4415 DirToks.back() =
Tok;
4420 DirToks.push_back(
Tok);
4426 std::optional<Token> NextPPTok =
4427 DirToks.back().is(tok::eod) ? peekNextPPToken() : DirToks.back();
4432 if (NextPPTok->is(tok::raw_identifier))
4434 if (!NextPPTok->isOneOf(tok::semi, tok::eod, tok::l_square,
4436 Diag(*NextPPTok, diag::err_pp_unexpected_tok_after_module_name)
4440 if (!DirToks.back().isOneOf(tok::semi, tok::eod)) {
4447 DirToks.back().isNot(tok::eod)
4451 : DirToks.pop_back_val().getLocation();
4453 if (!IncludeMacroStack.empty()) {
4454 Diag(StartLoc, diag::err_pp_module_decl_in_header)
4458 if (CurPPLexer->getConditionalStackDepth() != 0) {
4459 Diag(StartLoc, diag::err_pp_cond_span_module_decl)
4477void Preprocessor::HandleObjCImportDirective(
Token &AtTok,
Token &ImportTok) {
4480 ImportTok.
setKind(tok::kw_import);
4495 if (!DirToks.back().isOneOf(tok::semi, tok::eod))
4499 DirToks.back().isNot(tok::eod)
4503 : DirToks.pop_back_val().getLocation();
4505 Module *Imported =
nullptr;
4514 Callbacks->moduleImport(ModuleImportLoc, Path, Imported);
static bool isInMainFile(const clang::Diagnostic &D)
Defines interfaces for clang::DirectoryEntry and clang::DirectoryEntryRef.
Defines the clang::FileManager interface and associated types.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Defines the clang::LangOptions interface.
Defines the clang::MacroInfo and clang::MacroDirective classes.
Defines the clang::Module class, which describes a module in the source code.
Defines the PPCallbacks interface.
static bool ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit, SrcMgr::CharacteristicKind &FileKind, Preprocessor &PP)
ReadLineMarkerFlags - Parse and validate any flags at the end of a GNU line marker directive.
static bool isConfigurationPattern(Token &MacroName, MacroInfo *MI, const LangOptions &LOptions)
static void diagnoseAutoModuleImport(Preprocessor &PP, SourceLocation HashLoc, Token &IncludeTok, ArrayRef< IdentifierLoc > Path, SourceLocation PathEnd)
Produce a diagnostic informing the user that a include or similar was implicitly treated as a module ...
static std::optional< StringRef > findSimilarStr(StringRef LHS, const std::vector< StringRef > &Candidates)
Find a similar string in Candidates.
static bool isLanguageDefinedBuiltin(const SourceManager &SourceMgr, const MacroInfo *MI, const StringRef MacroName)
static bool trySimplifyPath(SmallVectorImpl< StringRef > &Components, StringRef RealPathName, llvm::sys::path::Style Separator)
static bool warnByDefaultOnWrongCase(StringRef Include)
MacroDiag
Enumerates possible cases of define/undef a reserved identifier.
@ MD_ReservedAttributeIdentifier
static bool isFeatureTestMacro(StringRef MacroName)
static bool GetLineValue(Token &DigitTok, unsigned &Val, unsigned DiagID, Preprocessor &PP, bool IsGNULineDirective=false)
GetLineValue - Convert a numeric token into an unsigned value, emitting Diagnostic DiagID if it is in...
PPElifDiag
Enumerates possible select values for the pp_err_elif_after_else and pp_err_elif_without_if diagnosti...
static bool isReservedCXXAttributeName(Preprocessor &PP, IdentifierInfo *II)
static MacroDiag shouldWarnOnMacroUndef(Preprocessor &PP, IdentifierInfo *II)
static bool isObjCProtectedMacro(const IdentifierInfo *II)
static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II)
Defines the clang::Preprocessor interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines the clang::SourceLocation class and associated facilities.
static bool isInvalid(LocType Loc, bool *Invalid)
Defines the SourceManager interface.
Defines the clang::TokenKind enum and support functions.
VerifyDiagnosticConsumer::Directive Directive
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
ResetMacroExpansionHelper(Preprocessor *pp)
~ResetMacroExpansionHelper()
static AttrArgsInfo getCXX11AttrArgsInfo(const IdentifierInfo *Name)
Represents a byte-granular source range.
static CharSourceRange getCharRange(SourceRange R)
virtual void CodeCompleteMacroName(bool IsDefinition)
Callback invoked when performing code completion in a context where the name of a macro is expected.
A directive for a defined macro or a macro imported from a module.
Concrete class used by the front-end to report problems and issues.
A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...
StringRef getName() const
bool isDeviceFile() const
const FileEntry & getFileEntry() const
DirectoryEntryRef getDir() const
Cached information about one file (either on disk or in the virtual file system).
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements support for file system lookup, file system caching, and directory search management.
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true, bool IsText=true)
Get a FileEntryRef if it exists, without doing anything on error.
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
One of these records is kept for each identifier that is lexed.
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.
bool isCPlusPlusOperatorKeyword() const
bool hadMacroDefinition() const
Returns true if this identifier was #defined to some value at any moment.
bool hasMacroDefinition() const
Return true if this identifier is #defined to some other value.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
bool isKeyword(const LangOptions &LangOpts) const
Return true if this token is a keyword in the specified language.
ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const
Determine whether this is a name reserved for the implementation (C99 7.1.3, C++ [lib....
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
A simple pair of identifier info and location.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool IsHeaderFile
Indicates whether the front-end is explicitly told that the input is a header file (i....
std::string CurrentModule
The name of the current module, of which the main source file is a part.
const MacroInfo * getMacroInfo() const
Encapsulates the data about a macro definition (e.g.
bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP, bool Syntactically) const
Return true if the specified macro definition is equal to this macro in spelling, arguments,...
bool isUsed() const
Return false if this macro is defined in the main file and has not yet been used.
bool isC99Varargs() const
bool isAllowRedefinitionsWithoutWarning() const
Return true if this macro can be redefined without warning.
void setHasCommaPasting()
unsigned getNumTokens() const
Return the number of tokens that this macro expands to.
const Token & getReplacementToken(unsigned Tok) const
void setDefinitionEndLoc(SourceLocation EndLoc)
Set the location of the last token in the macro.
bool isBuiltinMacro() const
Return true if this macro requires processing before expansion.
void setTokens(ArrayRef< Token > Tokens, llvm::BumpPtrAllocator &PPAllocator)
void setParameterList(ArrayRef< IdentifierInfo * > List, llvm::BumpPtrAllocator &PPAllocator)
Set the specified list of identifiers as the parameter list for this macro.
SourceLocation getDefinitionLoc() const
Return the location that the macro was defined at.
void setIsFunctionLike()
Function/Object-likeness.
bool isObjectLike() const
void setIsWarnIfUnused(bool val)
Set the value of the IsWarnIfUnused flag.
int getParameterNum(const IdentifierInfo *Arg) const
Return the parameter number of the specified identifier, or -1 if the identifier is not a formal para...
bool isWarnIfUnused() const
Return true if we should emit a warning if the macro is unused.
void setIsC99Varargs()
Varargs querying methods. This can only be set for function-like macros.
bool isMissingExpected() const
Determines whether the module, which failed to load, was actually a submodule that we expected to see...
bool isConfigMismatch() const
Determines whether the module failed to load due to a configuration mismatch with an explicitly-named...
virtual ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective)=0
Attempt to load the given module.
static std::string getFlatNameFromPath(ModuleIdPath Path)
@ ExcludedHeader
This header is explicitly excluded from the module.
@ TextualHeader
This header is part of the module (for layering purposes) but should be textually included.
Describes a module or submodule.
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
bool isForBuilding(const LangOptions &LangOpts) const
Determine whether this module can be built in this compilation.
@ Hidden
All of the names in this module are hidden.
SourceLocation DefinitionLoc
The location of the module definition.
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers).
std::string Name
The name of this module.
bool isAvailable() const
Determine whether this module is available for use within the current translation unit.
bool isHeaderUnit() const
Is this module a header unit.
Module * ShadowingModule
A module with the same name that shadows this module.
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
Preprocessor standard embed parameter "if_empty" if_empty( balanced-token-seq )
Preprocessor standard embed parameter "limit" limit( constant-expression )
Preprocessor extension embed parameter "clang::offset" clang::offset( constant-expression )
Preprocessor standard embed parameter "prefix" prefix( balanced-token-seq )
Preprocessor standard embed parameter "suffix" suffix( balanced-token-seq )
OptionalFileEntryRef getFileEntry() const
getFileEntry - Return the FileEntry corresponding to this FileID.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
MacroDirective * getLocalMacroDirective(const IdentifierInfo *II) const
Given an identifier, return its latest non-imported MacroDirective if it is #define'd and not #undef'...
void EnterModuleSuffixTokenStream(ArrayRef< Token > Toks)
void markClangModuleAsAffecting(Module *M)
Mark the given clang module as affecting the current clang module or translation unit.
void HandleCXXImportDirective(Token Import)
HandleCXXImportDirective - Handle the C++ modules import directives.
SourceRange DiscardUntilEndOfDirective(SmallVectorImpl< Token > *DiscardedToks=nullptr)
Read and discard all tokens remaining on the current line until the tok::eod token is found.
const MacroInfo * getMacroInfo(const IdentifierInfo *II) const
bool isRecordingPreamble() const
void HandleSkippedDirectiveWhileUsingPCH(Token &Result, SourceLocation HashLoc)
Process directives while skipping until the through header or pragma hdrstop is found.
bool isInPrimaryFile() const
Return true if we're in the top-level file, not in a #include.
void markMacroAsUsed(MacroInfo *MI)
A macro is used, update information about macros that need unused warnings.
void EnterSubmodule(Module *M, SourceLocation ImportLoc, bool ForPragma)
IdentifierInfo * LookUpIdentifierInfo(Token &Identifier) const
Given a tok::raw_identifier token, look up the identifier information for the token and install it in...
void setCodeCompletionReached()
Note that we hit the code-completion point.
StringRef getNamedModuleName() const
Get the named module name we're preprocessing.
void Lex(Token &Result)
Lex the next token for this preprocessor.
bool EnterSourceFile(FileID FID, ConstSearchDirIterator Dir, SourceLocation Loc, bool IsFirstIncludeOfFile=true)
Add a source file to the top of the include stack and start lexing tokens from it instead of the curr...
void LexNonComment(Token &Result)
Lex a token.
friend class VAOptDefinitionContext
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
SourceManager & getSourceManager() const
MacroDefinition getMacroDefinition(const IdentifierInfo *II)
bool CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef, bool *ShadowFlag=nullptr)
SourceLocation CheckEndOfDirective(StringRef DirType, bool EnableMacros=false, SmallVectorImpl< Token > *ExtraToks=nullptr)
Ensure that the next token is a tok::eod token.
static bool checkModuleIsAvailable(const LangOptions &LangOpts, const TargetInfo &TargetInfo, const Module &M, DiagnosticsEngine &Diags)
Check that the given module is available, producing a diagnostic if not.
SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart, unsigned Char) const
Given a location that specifies the start of a token, return a new location that specifies a characte...
Module * getCurrentModule()
Retrieves the module that we're currently building, if any.
OptionalFileEntryRef LookupEmbedFile(StringRef Filename, bool isAngled, bool OpenFile)
Given a "Filename" or <Filename> reference, look up the indicated embed resource.
void makeModuleVisible(Module *M, SourceLocation Loc, bool IncludeExports=true)
bool hadModuleLoaderFatalFailure() const
bool HandleModuleContextualKeyword(Token &Result)
Callback invoked when the lexer sees one of export, import or module token at the start of a line.
const TargetInfo & getTargetInfo() const
FileManager & getFileManager() const
bool LexHeaderName(Token &Result, bool AllowMacroExpansion=true)
Lex a token, forming a header-name token if possible.
bool isPCHThroughHeader(const FileEntry *FE)
Returns true if the FileEntry is the PCH through header.
friend class VariadicMacroScopeGuard
MacroInfo * AllocateMacroInfo(SourceLocation L)
Allocate a new MacroInfo object with the provided SourceLocation.
void LexUnexpandedToken(Token &Result)
Just like Lex, but disables macro expansion of identifier tokens.
bool alreadyIncluded(FileEntryRef File) const
Return true if this header has already been included.
FileID getPredefinesFileID() const
Returns the FileID for the preprocessor predefines.
void LexUnexpandedNonComment(Token &Result)
Like LexNonComment, but this disables macro expansion of identifier tokens.
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
bool GetIncludeFilenameSpelling(SourceLocation Loc, StringRef &Buffer)
Turn the specified lexer token into a fully checked and spelled filename, e.g.
PreprocessorLexer * getCurrentFileLexer() const
Return the current file lexer being lexed from.
HeaderSearch & getHeaderSearchInfo() const
void emitMacroExpansionWarnings(const Token &Identifier, bool IsIfnDef=false) const
void HandleDirective(Token &Result)
Callback invoked when the lexer sees a # token at the start of a line.
void EnterAnnotationToken(SourceRange Range, tok::TokenKind Kind, void *AnnotationVal)
Enter an annotation token into the token stream.
OptionalFileEntryRef LookupFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled, ConstSearchDirIterator FromDir, const FileEntry *FromFile, ConstSearchDirIterator *CurDir, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool *IsFrameworkFound, bool SkipCache=false, bool OpenFile=true, bool CacheFailures=true)
Given a "foo" or <foo> reference, look up the indicated file.
const LangOptions & getLangOpts() const
bool isInNamedModule() const
If we are preprocessing a named module.
OptionalFileEntryRef getHeaderToIncludeForDiagnostics(SourceLocation IncLoc, SourceLocation MLoc)
We want to produce a diagnostic at location IncLoc concerning an unreachable effect at location MLoc ...
bool isNextPPTokenOneOf(Ts... Ks) const
isNextPPTokenOneOf - Check whether the next pp-token is one of the specificed token kind.
DefMacroDirective * appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI, SourceLocation Loc)
void CollectPPImportSuffix(SmallVectorImpl< Token > &Toks, bool StopUntilEOD=false)
Collect the tokens of a C++20 pp-import-suffix.
void HandlePragmaHdrstop(Token &Tok)
DiagnosticsEngine & getDiagnostics() const
void HandleCXXModuleDirective(Token Module)
HandleCXXModuleDirective - Handle C++ module declaration directives.
std::optional< LexEmbedParametersResult > LexEmbedParameters(Token &Current, bool ForHasEmbed)
Lex the parameters for an embed directive, returns nullopt on error.
Module * getModuleForLocation(SourceLocation Loc, bool AllowTextual)
Find the module that owns the source or header file that Loc points to.
bool HandleModuleName(StringRef DirType, SourceLocation UseLoc, Token &Tok, SmallVectorImpl< IdentifierLoc > &Path, SmallVectorImpl< Token > &DirToks, bool AllowMacroExpansion, bool IsPartition)
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
bool usingPCHWithThroughHeader()
True if using a PCH with a through header.
Preprocessor(const PreprocessorOptions &PPOpts, DiagnosticsEngine &diags, const LangOptions &LangOpts, SourceManager &SM, HeaderSearch &Headers, ModuleLoader &TheModuleLoader, IdentifierInfoLookup *IILookup=nullptr, bool OwnsHeaderSearch=false, TranslationUnitKind TUKind=TU_Complete)
void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD)
Add a directive to the macro directive history for this identifier.
Represents an unpacked "presumed" location which can be presented to the user.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
SourceLocation getIncludeLoc() const
Return the presumed include location of this location.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
bool isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
std::optional< llvm::MemoryBufferRef > getMemoryBufferForFileOrNone(FileEntryRef File)
Retrieve the memory buffer associated with the given file.
A trivial tuple used to represent a source range.
void setBegin(SourceLocation b)
SourceLocation getEnd() const
void setEnd(SourceLocation e)
Exposes information about the current target.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getEndLoc() const
void clearFlag(TokenFlags Flag)
Unset the specified flag.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
unsigned getLength() const
void setKind(tok::TokenKind K)
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
tok::TokenKind getKind() const
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
bool isOneOf(Ts... Ks) const
bool isModuleContextualKeyword(bool AllowExport=true) const
Return true if we have a C++20 modules contextual keyword(export, importor module).
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
bool isNot(tok::TokenKind K) const
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix.
bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const
Return true if we have an ObjC keyword identifier.
void startToken()
Reset all flags to cleared.
bool needsCleaning() const
Return true if this token has trigraphs or escaped newlines in it.
StringRef getRawIdentifier() const
getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode),...
A directive for an undefined macro.
A directive for setting the module visibility of a macro.
Defines the clang::TargetInfo interface.
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
uint32_t Literal
Literals are represented as positive integers.
bool Sub(InterpState &S, CodePtr OpPC)
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
PPKeywordKind
Provides a namespace for preprocessor keywords which start with a '#' at the beginning of the line.
The JSON file list parser is used to communicate input to InstallAPI.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
bool isReservedInAllContexts(ReservedIdentifierStatus Status)
Determine whether an identifier is reserved in all contexts.
int hasAttribute(AttributeCommonInfo::Syntax Syntax, llvm::StringRef ScopeName, llvm::StringRef AttrName, const TargetInfo &Target, const LangOptions &LangOpts, bool CheckPlugins)
Return the version number associated with the attribute if we recognize and implement the attribute s...
ArrayRef< IdentifierLoc > ModuleIdPath
A sequence of identifier/location pairs used to describe a particular module or submodule,...
LLVM_READONLY char toLowercase(char c)
Converts the given ASCII character to its lowercase equivalent.
detail::SearchDirIteratorImpl< true > ConstSearchDirIterator
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
MacroUse
Context in which macro name is used.
LLVM_READONLY bool isAlphanumeric(unsigned char c)
Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Default
Set to the current date and time.
@ Parameter
The parameter type of a method or function.
@ Result
The result type of a method or function.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
LLVM_READONLY bool isLowercase(unsigned char c)
Return true if this character is a lowercase ASCII letter: [a-z].
@ PIK_HashPragma
The pragma was introduced via #pragma.
OptionalDirectoryEntryRef Directory
The directory entry which should be used for the cached framework.
std::optional< PPEmbedParameterIfEmpty > MaybeIfEmptyParam
size_t SuffixTokenCount() const
std::optional< PPEmbedParameterSuffix > MaybeSuffixParam
std::optional< PPEmbedParameterPrefix > MaybePrefixParam
size_t PrefixTokenCount() const
bool FoundNonSkip
True if we have emitted tokens already, and now we're in an #else block or something.
SourceLocation IfLoc
Location where the conditional started.
bool WasSkipping
True if this was contained in a skipping directive, e.g., in a "\#if 0" block.
bool FoundElse
True if we've seen a #else in this block.