39#include "llvm/ADT/ArrayRef.h"
40#include "llvm/ADT/STLExtras.h"
41#include "llvm/ADT/ScopeExit.h"
42#include "llvm/ADT/SmallVector.h"
43#include "llvm/ADT/StringExtras.h"
44#include "llvm/ADT/StringRef.h"
45#include "llvm/ADT/StringSwitch.h"
46#include "llvm/Support/ErrorHandling.h"
47#include "llvm/Support/Path.h"
48#include "llvm/Support/SaveAndRestore.h"
64 static_assert(std::is_trivially_destructible_v<MacroInfo>,
"");
74Preprocessor::AllocateUndefMacroDirective(
SourceLocation UndefLoc) {
81 return new (BP) VisibilityMacroDirective(Loc, isPublic);
89 auto ReadNextTok = [&]() {
91 if (DiscardedToks && Tmp.
isNot(tok::eod))
92 DiscardedToks->push_back(Tmp);
96 while (Tmp.
isNot(tok::eod)) {
97 assert(Tmp.
isNot(tok::eof) &&
"EOF seen while discarding directive tokens");
126 static constexpr StringRef ReservedMacro[] = {
129 "_CRT_NONSTDC_NO_WARNINGS",
130 "_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES",
131 "_CRT_SECURE_NO_WARNINGS",
134 "_GLIBCXX_ASSERTIONS",
135 "_GLIBCXX_CONCEPT_CHECKS",
137 "_GLIBCXX_DEBUG_PEDANTIC",
139 "_GLIBCXX_PARALLEL_ASSERTIONS",
140 "_GLIBCXX_SANITIZE_VECTOR",
141 "_GLIBCXX_USE_CXX11_ABI",
142 "_GLIBCXX_USE_DEPRECATED",
147 "_LARGEFILE64_SOURCE",
153 "_XOPEN_SOURCE_EXTENDED",
154 "__STDCPP_WANT_MATH_SPEC_FUNCS__",
155 "__STDC_FORMAT_MACROS",
157 return llvm::binary_search(ReservedMacro, MacroName);
162 const StringRef MacroName) {
172 if (MacroName.starts_with(
"__STDC"))
175 if (MacroName ==
"__cplusplus")
178 if (MacroName.starts_with(
"__cpp"))
186 if (Lang.CPlusPlus &&
207 if (Lang.CPlusPlus11 && (
Text ==
"override" ||
Text ==
"final"))
232 if (::llvm::sys::path::begin(Include)->equals_insensitive(
"boost"))
237 static const size_t MaxStdHeaderNameLen = 18u;
238 if (Include.size() > MaxStdHeaderNameLen)
243 for (
char &Ch : LowerInclude) {
245 if (
static_cast<unsigned char>(Ch) > 0x7f)
248 if (Ch >=
'A' && Ch <=
'Z')
251 else if (::llvm::sys::path::is_separator(Ch))
256 return llvm::StringSwitch<bool>(LowerInclude)
258 .Cases({
"assert.h",
"complex.h",
"ctype.h",
"errno.h",
"fenv.h"},
true)
259 .Cases({
"float.h",
"inttypes.h",
"iso646.h",
"limits.h",
"locale.h"},
261 .Cases({
"math.h",
"setjmp.h",
"signal.h",
"stdalign.h",
"stdarg.h"},
true)
262 .Cases({
"stdatomic.h",
"stdbool.h",
"stdckdint.h",
"stdcountof.h"},
true)
263 .Cases({
"stddef.h",
"stdint.h",
"stdio.h",
"stdlib.h",
"stdnoreturn.h"},
265 .Cases({
"string.h",
"tgmath.h",
"threads.h",
"time.h",
"uchar.h"},
true)
266 .Cases({
"wchar.h",
"wctype.h"},
true)
269 .Cases({
"cassert",
"ccomplex",
"cctype",
"cerrno",
"cfenv"},
true)
270 .Cases({
"cfloat",
"cinttypes",
"ciso646",
"climits",
"clocale"},
true)
271 .Cases({
"cmath",
"csetjmp",
"csignal",
"cstdalign",
"cstdarg"},
true)
272 .Cases({
"cstdbool",
"cstddef",
"cstdint",
"cstdio",
"cstdlib"},
true)
273 .Cases({
"cstring",
"ctgmath",
"ctime",
"cuchar",
"cwchar"},
true)
274 .Case(
"cwctype",
true)
277 .Cases({
"algorithm",
"fstream",
"list",
"regex",
"thread"},
true)
278 .Cases({
"array",
"functional",
"locale",
"scoped_allocator",
"tuple"},
280 .Cases({
"atomic",
"future",
"map",
"set",
"type_traits"},
true)
282 {
"bitset",
"initializer_list",
"memory",
"shared_mutex",
"typeindex"},
284 .Cases({
"chrono",
"iomanip",
"mutex",
"sstream",
"typeinfo"},
true)
285 .Cases({
"codecvt",
"ios",
"new",
"stack",
"unordered_map"},
true)
286 .Cases({
"complex",
"iosfwd",
"numeric",
"stdexcept",
"unordered_set"},
289 {
"condition_variable",
"iostream",
"ostream",
"streambuf",
"utility"},
291 .Cases({
"deque",
"istream",
"queue",
"string",
"valarray"},
true)
292 .Cases({
"exception",
"iterator",
"random",
"strstream",
"vector"},
true)
293 .Cases({
"forward_list",
"limits",
"ratio",
"system_error"},
true)
296 .Cases({
"aio.h",
"arpa/inet.h",
"cpio.h",
"dirent.h",
"dlfcn.h"},
true)
297 .Cases({
"fcntl.h",
"fmtmsg.h",
"fnmatch.h",
"ftw.h",
"glob.h"},
true)
298 .Cases({
"grp.h",
"iconv.h",
"langinfo.h",
"libgen.h",
"monetary.h"},
true)
299 .Cases({
"mqueue.h",
"ndbm.h",
"net/if.h",
"netdb.h",
"netinet/in.h"},
301 .Cases({
"netinet/tcp.h",
"nl_types.h",
"poll.h",
"pthread.h",
"pwd.h"},
303 .Cases({
"regex.h",
"sched.h",
"search.h",
"semaphore.h",
"spawn.h"},
true)
304 .Cases({
"strings.h",
"stropts.h",
"sys/ipc.h",
"sys/mman.h",
"sys/msg.h"},
306 .Cases({
"sys/resource.h",
"sys/select.h",
"sys/sem.h",
"sys/shm.h",
309 .Cases({
"sys/stat.h",
"sys/statvfs.h",
"sys/time.h",
"sys/times.h",
313 {
"sys/uio.h",
"sys/un.h",
"sys/utsname.h",
"sys/wait.h",
"syslog.h"},
315 .Cases({
"tar.h",
"termios.h",
"trace.h",
"ulimit.h"},
true)
316 .Cases({
"unistd.h",
"utime.h",
"utmpx.h",
"wordexp.h"},
true)
328static std::optional<StringRef>
332 for (StringRef
C : Candidates) {
333 if (LHS.equals_insensitive(
C)) {
341 size_t Length = LHS.size();
342 size_t MaxDist = Length < 3 ? Length - 1 : Length / 3;
344 std::optional<std::pair<StringRef, size_t>> SimilarStr;
345 for (StringRef
C : Candidates) {
346 size_t CurDist = LHS.edit_distance(
C,
true);
347 if (CurDist <= MaxDist) {
350 SimilarStr = {
C, CurDist};
351 }
else if (CurDist < SimilarStr->second) {
353 SimilarStr = {
C, CurDist};
359 return SimilarStr->first;
368 if (MacroNameTok.
is(tok::eod))
369 return Diag(MacroNameTok, diag::err_pp_missing_macro_name);
373 return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
379 ? diag::ext_pp_operator_used_as_macro_name
380 : diag::err_pp_operator_used_as_macro_name)
381 << II << MacroNameTok.
getKind();
388 return Diag(MacroNameTok, diag::err_defined_macro_name);
401 if (!SourceMgr.isInSystemHeader(MacroNameLoc) &&
402 !SourceMgr.isInPredefinedFile(MacroNameLoc)) {
417 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id);
419 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_attribute_id)
436void Preprocessor::ReadMacroName(
Token &MacroNameTok,
MacroUse isDefineUndef,
441 if (MacroNameTok.
is(tok::code_completion)) {
453 if (MacroNameTok.
isNot(tok::eod)) {
454 MacroNameTok.
setKind(tok::eod);
469 auto ReadNextTok = [
this, ExtraToks, &Tmp](
auto &&LexFn) {
470 std::invoke(LexFn,
this, Tmp);
471 if (ExtraToks && Tmp.
isNot(tok::eod))
472 ExtraToks->push_back(Tmp);
484 while (Tmp.
is(tok::comment))
487 if (Tmp.
is(tok::eod))
495 if ((LangOpts.GNUMode || LangOpts.C99 || LangOpts.CPlusPlus) &&
499 unsigned DiagID = diag::ext_pp_extra_tokens_at_eol;
502 (DirType ==
"import" || DirType ==
"module"))
503 DiagID = diag::warn_pp_extra_tokens_at_module_directive_eol;
505 Diag(Tmp, DiagID) << DirType << Hint;
509void Preprocessor::SuggestTypoedDirective(
const Token &
Tok,
510 StringRef Directive)
const {
515 std::vector<StringRef> Candidates = {
516 "if",
"ifdef",
"ifndef",
"elif",
"else",
"endif"
518 if (LangOpts.C23 || LangOpts.CPlusPlus23)
519 Candidates.insert(Candidates.end(), {
"elifdef",
"elifndef"});
523 assert(
Tok.getLocation().isFileID());
527 StringRef SuggValue = *Sugg;
530 Diag(
Tok, diag::warn_pp_invalid_directive) << 1 << SuggValue << Hint;
542void Preprocessor::SkipExcludedConditionalBlock(
SourceLocation HashTokenLoc,
544 bool FoundNonSkipPortion,
555 assert(!SkippingExcludedConditionalBlock &&
556 "calling SkipExcludedConditionalBlock recursively");
557 llvm::SaveAndRestore SARSkipping(SkippingExcludedConditionalBlock,
true);
560 assert(!CurTokenLexer &&
"Conditional PP block cannot appear in a macro!");
561 assert(CurPPLexer &&
"Conditional PP block must be in a file!");
562 assert(CurLexer &&
"Conditional PP block but no current lexer set!");
564 if (PreambleConditionalStack.reachedEOFWhileSkipping())
565 PreambleConditionalStack.clearSkipInfo();
567 CurPPLexer->pushConditionalLevel(IfTokenLoc,
false,
568 FoundNonSkipPortion, FoundElse);
572 CurPPLexer->LexingRawMode =
true;
574 SourceLocation endLoc;
578 struct SkippingRangeStateTy {
581 const char *BeginPtr =
nullptr;
582 unsigned *SkipRangePtr =
nullptr;
584 SkippingRangeStateTy(Preprocessor &PP) : PP(PP) {}
586 void beginLexPass() {
592 BeginPtr = PP.CurLexer->getBufferLocation();
593 SkipRangePtr = &PP.RecordedSkippedRanges[BeginPtr];
595 PP.CurLexer->seek(PP.CurLexer->getCurrentBufferOffset() + *SkipRangePtr,
600 void endLexPass(
const char *Hashptr) {
603 assert(PP.CurLexer->isDependencyDirectivesLexer());
608 if (!*SkipRangePtr) {
609 *SkipRangePtr = Hashptr - BeginPtr;
611 assert(*SkipRangePtr ==
unsigned(Hashptr - BeginPtr));
613 SkipRangePtr =
nullptr;
615 } SkippingRangeState(*
this);
618 if (CurLexer->isDependencyDirectivesLexer()) {
619 CurLexer->LexDependencyDirectiveTokenWhileSkipping(
Tok);
621 SkippingRangeState.beginLexPass();
625 if (
Tok.
is(tok::code_completion)) {
628 CodeComplete->CodeCompleteInConditionalExclusion();
641 Tok.
is(tok::raw_identifier) &&
644 llvm::SaveAndRestore ModuleDirectiveSkipping(
645 LastTokenWasExportKeyword);
646 LastTokenWasExportKeyword.reset();
653 if (
Tok.
is(tok::raw_identifier)) {
662 llvm::SaveAndRestore RestoreLexingRawMode(CurPPLexer->LexingRawMode,
669 CurPPLexer->ParsingPreprocessorDirective =
true;
672 Diag(StartLoc, diag::err_pp_cond_span_module_decl)
673 << SourceRange(StartLoc, End);
674 CurPPLexer->ParsingPreprocessorDirective =
false;
677 CurLexer->resetExtendedTokenMode();
684 if (
Tok.
is(tok::eof)) {
688 if (PreambleConditionalStack.isRecording())
689 PreambleConditionalStack.SkipInfo.emplace(HashTokenLoc, IfTokenLoc,
702 if (
Tok.
is(tok::eof))
708 CurPPLexer->ParsingPreprocessorDirective =
true;
709 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
711 assert(
Tok.
is(tok::hash));
712 const char *Hashptr = CurLexer->getBufferLocation() -
Tok.
getLength();
713 assert(CurLexer->getSourceLocation(Hashptr) ==
Tok.
getLocation());
720 if (
Tok.
isNot(tok::raw_identifier)) {
721 CurPPLexer->ParsingPreprocessorDirective =
false;
723 if (CurLexer) CurLexer->resetExtendedTokenMode();
734 char FirstChar = RI[0];
735 if (FirstChar >=
'a' && FirstChar <=
'z' &&
736 FirstChar !=
'i' && FirstChar !=
'e') {
737 CurPPLexer->ParsingPreprocessorDirective =
false;
739 if (CurLexer) CurLexer->resetExtendedTokenMode();
746 char DirectiveBuf[20];
752 size_t IdLen = DirectiveStr.size();
754 CurPPLexer->ParsingPreprocessorDirective =
false;
756 if (CurLexer) CurLexer->resetExtendedTokenMode();
759 memcpy(DirectiveBuf, &DirectiveStr[0], IdLen);
760 Directive = StringRef(DirectiveBuf, IdLen);
780 PPConditionalInfo CondInfo;
782 bool InCond = CurPPLexer->popConditionalLevel(CondInfo);
784 assert(!InCond &&
"Can't be skipping if not in a conditional!");
788 SkippingRangeState.endLexPass(Hashptr);
791 CurPPLexer->LexingRawMode =
false;
793 CurPPLexer->LexingRawMode =
true;
800 }
else if (Sub ==
"lse") {
804 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
807 SkippingRangeState.endLexPass(Hashptr);
811 Diag(
Tok, diag::pp_err_else_after_else);
822 CurPPLexer->LexingRawMode =
false;
824 CurPPLexer->LexingRawMode =
true;
831 }
else if (Sub ==
"lif") {
832 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
835 SkippingRangeState.endLexPass(Hashptr);
852 assert(CurPPLexer->LexingRawMode &&
"We have to be skipping here!");
853 CurPPLexer->LexingRawMode =
false;
854 IdentifierInfo *IfNDefMacro =
nullptr;
855 DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
859 const bool CondValue = DER.Conditional;
860 CurPPLexer->LexingRawMode =
true;
873 }
else if (Sub ==
"lifdef" ||
875 bool IsElifDef =
Sub ==
"lifdef";
876 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
877 Token DirectiveToken =
Tok;
880 SkippingRangeState.endLexPass(Hashptr);
885 if (LangOpts.CPlusPlus)
886 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
887 : diag::ext_cxx23_pp_directive;
889 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
890 : diag::ext_c23_pp_directive;
895 Diag(
Tok, diag::pp_err_elif_after_else)
909 assert(CurPPLexer->LexingRawMode &&
"We have to be skipping here!");
910 CurPPLexer->LexingRawMode =
false;
912 ReadMacroName(MacroNameTok);
913 CurPPLexer->LexingRawMode =
true;
917 if (MacroNameTok.
is(tok::eod)) {
929 MacroInfo *MI = MD.getMacroInfo();
933 Callbacks->Elifdef(DirectiveToken.
getLocation(), MacroNameTok,
936 Callbacks->Elifndef(DirectiveToken.
getLocation(), MacroNameTok,
941 if (
static_cast<bool>(MI) == IsElifDef) {
953 CurPPLexer->ParsingPreprocessorDirective =
false;
955 if (CurLexer) CurLexer->resetExtendedTokenMode();
961 CurPPLexer->LexingRawMode =
false;
966 Callbacks->SourceRangeSkipped(
967 SourceRange(HashTokenLoc, endLoc.
isValid()
969 : CurPPLexer->getSourceLocation()),
975 if (!SourceMgr.isInMainFile(Loc)) {
978 FileID IDOfIncl = SourceMgr.getFileID(SourceMgr.getExpansionLoc(Loc));
979 if (
auto EntryOfIncl = SourceMgr.getFileEntryRefForID(IDOfIncl)) {
981 return HeaderInfo.getModuleMap()
982 .findModuleForHeader(*EntryOfIncl, AllowTextual)
991 : HeaderInfo.lookupModule(
getLangOpts().CurrentModule, Loc);
998 IncLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
1005 while (!Loc.
isInvalid() && !
SM.isInMainFile(Loc)) {
1006 auto ID =
SM.getFileID(
SM.getExpansionLoc(Loc));
1007 auto FE =
SM.getFileEntryRefForID(ID);
1013 HeaderInfo.hasModuleMap(FE->getName(),
nullptr,
1014 SourceMgr.isInSystemHeader(Loc));
1016 bool InPrivateHeader =
false;
1017 for (
auto Header : HeaderInfo.findAllModulesForHeader(*FE)) {
1018 if (!Header.isAccessibleFrom(IncM)) {
1023 InPrivateHeader =
true;
1040 return std::nullopt;
1050 if (InPrivateHeader)
1051 return std::nullopt;
1059 Loc =
SM.getIncludeLoc(ID);
1062 return std::nullopt;
1071 bool *IsFrameworkFound,
bool SkipCache,
bool OpenFile,
bool CacheFailures) {
1076 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
1081 bool BuildSystemModule =
false;
1082 if (!FromDir && !FromFile) {
1099 if (FID == SourceMgr.getMainFileID() && MainFileDir) {
1101 HeaderInfo.getModuleMap().shouldImportRelativeToBuiltinIncludeDir(
1103 ? HeaderInfo.getModuleMap().getBuiltinDir()
1105 Includers.push_back(std::make_pair(std::nullopt, *IncludeDir));
1107 }
else if ((FileEnt = SourceMgr.getFileEntryRefForID(
1108 SourceMgr.getMainFileID()))) {
1109 auto CWD = FileMgr.getOptionalDirectoryRef(
".");
1110 Includers.push_back(std::make_pair(*FileEnt, *CWD));
1113 Includers.push_back(std::make_pair(*FileEnt, FileEnt->
getDir()));
1119 if (LangOpts.MSVCCompat && !isAngled) {
1120 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1121 if (IsFileLexer(ISEntry))
1123 Includers.push_back(std::make_pair(*FileEnt, FileEnt->
getDir()));
1128 CurDir = CurDirLookup;
1136 Filename, FilenameLoc, isAngled, TmpFromDir, &TmpCurDir,
1137 Includers, SearchPath, RelativePath, RequestingModule,
1138 SuggestedModule,
nullptr,
1139 nullptr, SkipCache)) {
1141 TmpFromDir = TmpCurDir;
1143 if (&FE->getFileEntry() == FromFile) {
1145 FromDir = TmpFromDir;
1154 Filename, FilenameLoc, isAngled, FromDir, &CurDir, Includers, SearchPath,
1155 RelativePath, RequestingModule, SuggestedModule, IsMapped,
1156 IsFrameworkFound, SkipCache, BuildSystemModule, OpenFile, CacheFailures);
1164 if (IsFileLexer()) {
1167 Filename, *CurFileEnt, SearchPath, RelativePath, RequestingModule,
1174 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1175 if (IsFileLexer(ISEntry)) {
1176 if ((CurFileEnt = ISEntry.ThePPLexer->
getFileEntry())) {
1178 Filename, *CurFileEnt, SearchPath, RelativePath,
1179 RequestingModule, SuggestedModule)) {
1187 return std::nullopt;
1194 if (llvm::sys::path::is_absolute(Filename)) {
1197 Filename, OpenFile,
true,
false);
1198 return llvm::expectedToOptional(std::move(ShouldBeEntry));
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());
1218 if (LookupFromFile) {
1221 if (!FullFileDir.empty()) {
1222 SeparateComponents(LookupPath, FullFileDir, Filename,
true);
1224 LookupPath, OpenFile,
true,
false);
1226 return llvm::expectedToOptional(std::move(ShouldBeEntry));
1227 llvm::consumeError(ShouldBeEntry.takeError());
1234 if (MaybeWorkingDirEntry) {
1236 StringRef WorkingDir = WorkingDirEntry.
getName();
1237 if (!WorkingDir.empty()) {
1238 SeparateComponents(LookupPath, WorkingDir, Filename,
false);
1240 LookupPath, OpenFile,
true,
false);
1242 return llvm::expectedToOptional(std::move(ShouldBeEntry));
1243 llvm::consumeError(ShouldBeEntry.takeError());
1248 for (
const auto &Entry : PPOpts.EmbedEntries) {
1250 SeparateComponents(LookupPath, Entry, Filename,
false);
1252 LookupPath, OpenFile,
true,
false);
1254 return llvm::expectedToOptional(std::move(ShouldBeEntry));
1255 llvm::consumeError(ShouldBeEntry.takeError());
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.
is(tok::hash))
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:
1366 Diag(*ArgMacro, diag::note_macro_expansion_here)
1367 << ArgMacro->getIdentifierInfo();
1381 if (SkippingUntilPCHThroughHeader || SkippingUntilPragmaHdrStop)
1385 switch (
Result.getKind()) {
1390 CurPPLexer->MIOpt.SetReadToken(ReadAnyTokensBeforeDirective);
1392 case tok::code_completion:
1395 CodeComplete->CodeCompleteDirective(
1396 CurPPLexer->getConditionalStackDepth() > 0);
1398 case tok::numeric_constant:
1405 return HandleDigitDirective(
Result);
1415 return HandleIfDirective(
Result, Introducer,
1416 ReadAnyTokensBeforeDirective);
1418 return HandleIfdefDirective(
Result, Introducer,
false,
1420 case tok::pp_ifndef:
1421 return HandleIfdefDirective(
Result, Introducer,
true,
1422 ReadAnyTokensBeforeDirective);
1424 case tok::pp_elifdef:
1425 case tok::pp_elifndef:
1426 return HandleElifFamilyDirective(
Result, Introducer,
1430 return HandleElseDirective(
Result, Introducer);
1432 return HandleEndifDirective(
Result);
1435 case tok::pp_include:
1438 case tok::pp___include_macros:
1443 case tok::pp_define:
1444 return HandleDefineDirective(
Result, ImmediatelyAfterTopLevelIfndef);
1446 return HandleUndefDirective();
1450 return HandleLineDirective();
1454 return HandleUserDiagnosticDirective(
Result,
false);
1457 case tok::pp_pragma:
1459 case tok::pp_module:
1460 case tok::pp___preprocessed_module:
1462 case tok::pp___preprocessed_import:
1465 case tok::pp_import:
1471 case tok::pp_include_next:
1474 case tok::pp_warning:
1475 if (LangOpts.CPlusPlus)
1477 ? diag::warn_cxx23_compat_warning_directive
1478 : diag::ext_pp_warning_directive)
1481 Diag(
Result, LangOpts.C23 ? diag::warn_c23_compat_warning_directive
1482 : diag::ext_pp_warning_directive)
1485 return HandleUserDiagnosticDirective(
Result,
true);
1487 return HandleIdentSCCSDirective(
Result);
1489 return HandleIdentSCCSDirective(
Result);
1490 case tok::pp_embed: {
1496 case tok::pp_assert:
1499 case tok::pp_unassert:
1503 case tok::pp___public_macro:
1505 return HandleMacroPublicDirective(
Result);
1508 case tok::pp___private_macro:
1510 return HandleMacroPrivateDirective();
1521 auto Toks = std::make_unique<Token[]>(2);
1523 Toks[0] = Introducer;
1528 if (
Result.is(tok::hashhash))
1529 Toks[1].setKind(tok::unknown);
1534 EnterTokenStream(std::move(Toks), 2,
false,
false);
1540 Diag(
Result, diag::err_pp_invalid_directive) << 0;
1552 bool IsGNULineDirective=
false) {
1553 if (DigitTok.
isNot(tok::numeric_constant)) {
1554 PP.
Diag(DigitTok, DiagID);
1556 if (DigitTok.
isNot(tok::eod))
1562 IntegerBuffer.resize(DigitTok.
getLength());
1563 const char *DigitTokBegin = &IntegerBuffer[0];
1573 for (
unsigned i = 0; i != ActualLength; ++i) {
1576 if (DigitTokBegin[i] ==
'\'')
1579 if (!
isDigit(DigitTokBegin[i])) {
1581 diag::err_pp_line_digit_sequence) << IsGNULineDirective;
1586 unsigned NextVal = Val*10+(DigitTokBegin[i]-
'0');
1587 if (NextVal < Val) {
1588 PP.
Diag(DigitTok, DiagID);
1595 if (DigitTokBegin[0] ==
'0' && Val)
1597 << IsGNULineDirective;
1609void Preprocessor::HandleLineDirective() {
1617 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*
this))
1621 Diag(DigitTok, diag::ext_pp_line_zero);
1625 unsigned LineLimit = 32768U;
1626 if (LangOpts.C99 || LangOpts.CPlusPlus11)
1627 LineLimit = 2147483648U;
1628 if (LineNo >= LineLimit)
1629 Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
1630 else if (LangOpts.CPlusPlus11 && LineNo >= 32768U)
1631 Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
1633 int FilenameID = -1;
1639 if (StrTok.
is(tok::eod))
1641 else if (StrTok.
isNot(tok::string_literal)) {
1642 Diag(StrTok, diag::err_pp_line_invalid_filename);
1646 Diag(StrTok, diag::err_invalid_string_udl);
1651 StringLiteralParser
Literal(StrTok, *
this);
1652 assert(
Literal.isOrdinary() &&
"Didn't allow wide strings in");
1658 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1662 FilenameID = SourceMgr.getLineTableFilenameID(
Literal.GetString());
1675 SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1677 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID,
false,
1681 Callbacks->FileChanged(CurPPLexer->getSourceLocation(),
1693 if (FlagTok.
is(tok::eod))
return false;
1694 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1701 if (FlagTok.
is(tok::eod))
return false;
1702 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1704 }
else if (FlagVal == 2) {
1720 SM.getDecomposedExpansionLoc(IncLoc).first != CurFileID) {
1721 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);
1727 if (FlagTok.
is(tok::eod))
return false;
1728 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1734 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1742 if (FlagTok.
is(tok::eod))
return false;
1743 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1748 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1756 if (FlagTok.
is(tok::eod))
return false;
1759 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1771void Preprocessor::HandleDigitDirective(
Token &DigitTok) {
1775 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
1782 bool IsFileEntry =
false, IsFileExit =
false;
1783 int FilenameID = -1;
1788 if (StrTok.
is(tok::eod)) {
1789 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1791 FileKind = SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1792 }
else if (StrTok.
isNot(tok::string_literal)) {
1793 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1797 Diag(StrTok, diag::err_invalid_string_udl);
1802 StringLiteralParser
Literal(StrTok, *
this);
1803 assert(
Literal.isOrdinary() &&
"Didn't allow wide strings in");
1809 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1817 if (!SourceMgr.isInPredefinedFile(DigitTok.
getLocation()))
1818 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1822 if (!(IsFileExit &&
Literal.GetString().empty()))
1823 FilenameID = SourceMgr.getLineTableFilenameID(
Literal.GetString());
1827 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID, IsFileEntry,
1828 IsFileExit, FileKind);
1837 else if (IsFileExit)
1840 Callbacks->FileChanged(CurPPLexer->getSourceLocation(), Reason, FileKind);
1846void Preprocessor::HandleUserDiagnosticDirective(
Token &
Tok,
1854 CurLexer->ReadToEndOfLine(&Message);
1858 StringRef Msg =
Message.str().ltrim(
' ');
1861 Diag(
Tok, diag::pp_hash_warning) << Msg;
1863 Diag(
Tok, diag::err_pp_hash_error) << Msg;
1868void Preprocessor::HandleIdentSCCSDirective(
Token &
Tok) {
1870 Diag(
Tok, diag::ext_pp_ident_directive);
1877 if (StrTok.
isNot(tok::string_literal) &&
1878 StrTok.
isNot(tok::wide_string_literal)) {
1879 Diag(StrTok, diag::err_pp_malformed_ident);
1880 if (StrTok.
isNot(tok::eod))
1886 Diag(StrTok, diag::err_invalid_string_udl);
1903void Preprocessor::HandleMacroPublicDirective(
Token &
Tok) {
1905 ReadMacroName(MacroNameTok,
MU_Undef);
1908 if (MacroNameTok.
is(tok::eod))
1920 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1930void Preprocessor::HandleMacroPrivateDirective() {
1932 ReadMacroName(MacroNameTok,
MU_Undef);
1935 if (MacroNameTok.
is(tok::eod))
1947 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1967 StringRef &Buffer) {
1969 assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1981 if (Buffer[0] ==
'<') {
1982 if (Buffer.back() !=
'>') {
1983 Diag(Loc, diag::err_pp_expects_filename);
1984 Buffer = StringRef();
1988 }
else if (Buffer[0] ==
'"') {
1989 if (Buffer.back() !=
'"') {
1990 Diag(Loc, diag::err_pp_expects_filename);
1991 Buffer = StringRef();
1996 Diag(Loc, diag::err_pp_expects_filename);
1997 Buffer = StringRef();
2002 if (Buffer.size() <= 2) {
2003 Diag(Loc, diag::err_pp_empty_filename);
2004 Buffer = StringRef();
2009 Buffer = Buffer.substr(1, Buffer.size()-2);
2016 void *AnnotationVal) {
2019 auto Tok = std::make_unique<Token[]>(1);
2020 Tok[0].startToken();
2021 Tok[0].setKind(Kind);
2022 Tok[0].setLocation(Range.getBegin());
2023 Tok[0].setAnnotationEndLoc(Range.getEnd());
2024 Tok[0].setAnnotationValue(AnnotationVal);
2025 EnterTokenStream(std::move(
Tok), 1,
true,
false);
2035 for (
size_t I = 0, N = Path.size(); I != N; ++I) {
2038 PathString += Path[I].getIdentifierInfo()->getName();
2041 int IncludeKind = 0;
2043 case tok::pp_include:
2047 case tok::pp_import:
2051 case tok::pp_include_next:
2055 case tok::pp___include_macros:
2060 llvm_unreachable(
"unknown include directive kind");
2063 PP.
Diag(HashLoc, diag::remark_pp_include_directive_modular_translation)
2064 << IncludeKind << PathString;
2071 StringRef RealPathName,
2072 llvm::sys::path::Style Separator) {
2073 auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName);
2074 auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName);
2076 bool SuggestReplacement =
false;
2078 auto IsSep = [Separator](StringRef Component) {
2079 return Component.size() == 1 &&
2080 llvm::sys::path::is_separator(Component[0], Separator);
2085 for (
auto &Component : llvm::reverse(Components)) {
2086 if (
"." == Component) {
2087 }
else if (
".." == Component) {
2091 }
else if (RealPathComponentIter != RealPathComponentEnd) {
2092 if (!IsSep(Component) && !IsSep(*RealPathComponentIter) &&
2093 Component != *RealPathComponentIter) {
2097 SuggestReplacement =
2098 RealPathComponentIter->equals_insensitive(Component);
2099 if (!SuggestReplacement)
2101 Component = *RealPathComponentIter;
2103 ++RealPathComponentIter;
2106 return SuggestReplacement;
2115 Module *ShadowingModule =
nullptr;
2121 Diags.Report(MissingHeader.
FileNameLoc, diag::err_module_header_missing)
2123 }
else if (ShadowingModule) {
2126 diag::note_previous_definition);
2137std::pair<ConstSearchDirIterator, const FileEntry *>
2138Preprocessor::getIncludeNextStart(
const Token &IncludeNextTok)
const {
2143 const FileEntry *LookupFromFile =
nullptr;
2151 Diag(IncludeNextTok, diag::pp_include_next_in_primary);
2152 }
else if (CurLexerSubmodule) {
2155 assert(CurPPLexer &&
"#include_next directive in macro?");
2156 if (
auto FE = CurPPLexer->getFileEntry())
2157 LookupFromFile = *FE;
2159 }
else if (!Lookup) {
2164 Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
2170 return {Lookup, LookupFromFile};
2186 if (FilenameTok.
isNot(tok::header_name)) {
2187 if (FilenameTok.
is(tok::identifier) &&
2188 (PPOpts.SingleFileParseMode || PPOpts.SingleModuleParseMode)) {
2198 if (FilenameTok.
isNot(tok::eod))
2207 SourceLocation EndLoc =
2210 auto Action = HandleHeaderIncludeOrImport(HashLoc, IncludeTok, FilenameTok,
2211 EndLoc, LookupFrom, LookupFromFile);
2212 switch (Action.Kind) {
2213 case ImportAction::None:
2214 case ImportAction::SkippedModuleImport:
2216 case ImportAction::ModuleBegin:
2218 tok::annot_module_begin, Action.ModuleForHeader);
2220 case ImportAction::HeaderUnitImport:
2222 Action.ModuleForHeader);
2224 case ImportAction::ModuleImport:
2226 tok::annot_module_include, Action.ModuleForHeader);
2228 case ImportAction::Failure:
2229 assert(TheModuleLoader.HadFatalFailure &&
2230 "This should be an early exit only to a fatal error");
2231 TheModuleLoader.HadFatalFailure =
true;
2233 CurLexer->cutOffLexing();
2241 const Token &FilenameTok,
bool &IsFrameworkFound,
bool IsImportDecl,
2243 const FileEntry *LookupFromFile, StringRef &LookupFilename,
2246 auto DiagnoseHeaderInclusion = [&](FileEntryRef FE) {
2247 if (LangOpts.AsmPreprocessor)
2251 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
2252 bool RequestingModuleIsModuleInterface =
2253 !SourceMgr.isInMainFile(FilenameLoc);
2255 HeaderInfo.getModuleMap().diagnoseHeaderInclusion(
2256 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
2261 FilenameLoc, LookupFilename, isAngled, LookupFrom, LookupFromFile, CurDir,
2262 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2263 &SuggestedModule, &IsMapped, &IsFrameworkFound);
2265 DiagnoseHeaderInclusion(*
File);
2270 if (Callbacks && Callbacks->FileNotFound(Filename))
2271 return std::nullopt;
2273 if (SuppressIncludeNotFoundError)
2274 return std::nullopt;
2281 FilenameLoc, LookupFilename,
false, LookupFrom, LookupFromFile, CurDir,
2282 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2283 &SuggestedModule, &IsMapped,
2286 DiagnoseHeaderInclusion(*
File);
2287 Diag(FilenameTok, diag::err_pp_file_not_found_angled_include_not_fatal)
2288 << Filename << IsImportDecl
2290 "\"" + Filename.str() +
"\"");
2297 StringRef OriginalFilename = Filename;
2298 if (LangOpts.SpellChecking) {
2301 auto CorrectTypoFilename = [](llvm::StringRef Filename) {
2304 Filename = Filename.drop_back();
2308 StringRef TypoCorrectionName = CorrectTypoFilename(Filename);
2309 StringRef TypoCorrectionLookupName = CorrectTypoFilename(LookupFilename);
2312 FilenameLoc, TypoCorrectionLookupName, isAngled, LookupFrom,
2313 LookupFromFile, CurDir, Callbacks ? &SearchPath :
nullptr,
2314 Callbacks ? &RelativePath :
nullptr, &SuggestedModule, &IsMapped,
2317 DiagnoseHeaderInclusion(*
File);
2320 FilenameRange,
"<" + TypoCorrectionName.str() +
">")
2321 : FixItHint::CreateReplacement(
2322 FilenameRange,
"\"" + TypoCorrectionName.str() +
"\"");
2323 Diag(FilenameTok, diag::err_pp_file_not_found_typo_not_fatal)
2324 << OriginalFilename << TypoCorrectionName << Hint;
2327 Filename = TypoCorrectionName;
2328 LookupFilename = TypoCorrectionLookupName;
2334 assert(!
File &&
"expected missing file");
2335 Diag(FilenameTok, diag::err_pp_file_not_found)
2336 << OriginalFilename << FilenameRange;
2337 if (IsFrameworkFound) {
2338 size_t SlashPos = OriginalFilename.find(
'/');
2339 assert(SlashPos != StringRef::npos &&
2340 "Include with framework name should have '/' in the filename");
2341 StringRef FrameworkName = OriginalFilename.substr(0, SlashPos);
2342 FrameworkCacheEntry &CacheEntry =
2343 HeaderInfo.LookupFrameworkCache(FrameworkName);
2344 assert(CacheEntry.
Directory &&
"Found framework should be in cache");
2345 Diag(FilenameTok, diag::note_pp_framework_without_header)
2346 << OriginalFilename.substr(SlashPos + 1) << FrameworkName
2350 return std::nullopt;
2365Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
2369 SmallString<128> FilenameBuffer;
2370 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
2371 SourceLocation CharEnd = FilenameTok.
getEndLoc();
2373 CharSourceRange FilenameRange
2375 StringRef OriginalFilename = Filename;
2381 if (Filename.empty())
2382 return {ImportAction::None};
2384 bool IsImportDecl = HashLoc.
isInvalid();
2385 SourceLocation StartLoc = IsImportDecl ? IncludeTok.
getLocation() : HashLoc;
2388 if (PragmaARCCFCodeAuditedInfo.getLoc().isValid()) {
2389 Diag(StartLoc, diag::err_pp_include_in_arc_cf_code_audited) << IsImportDecl;
2390 Diag(PragmaARCCFCodeAuditedInfo.getLoc(), diag::note_pragma_entered_here);
2393 PragmaARCCFCodeAuditedInfo = IdentifierLoc();
2397 if (PragmaAssumeNonNullLoc.isValid()) {
2398 Diag(StartLoc, diag::err_pp_include_in_assume_nonnull) << IsImportDecl;
2399 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
2402 PragmaAssumeNonNullLoc = SourceLocation();
2405 if (HeaderInfo.HasIncludeAliasMap()) {
2409 StringRef NewName = HeaderInfo.MapHeaderToIncludeAlias(OriginalFilename);
2410 if (!NewName.empty())
2415 bool IsMapped =
false;
2416 bool IsFrameworkFound =
false;
2418 SmallString<1024> SearchPath;
2419 SmallString<1024> RelativePath;
2422 ModuleMap::KnownHeader SuggestedModule;
2423 SourceLocation FilenameLoc = FilenameTok.
getLocation();
2424 StringRef LookupFilename = Filename;
2428 SmallString<128> NormalizedPath;
2429 llvm::sys::path::Style BackslashStyle = llvm::sys::path::Style::native;
2430 if (is_style_posix(BackslashStyle) && LangOpts.MicrosoftExt) {
2431 NormalizedPath = Filename.str();
2432 llvm::sys::path::native(NormalizedPath);
2433 LookupFilename = NormalizedPath;
2434 BackslashStyle = llvm::sys::path::Style::windows;
2438 &CurDir, Filename, FilenameLoc, FilenameRange, FilenameTok,
2439 IsFrameworkFound, IsImportDecl, IsMapped, LookupFrom, LookupFromFile,
2440 LookupFilename, RelativePath, SearchPath, SuggestedModule, isAngled);
2444 SkippingUntilPCHThroughHeader =
false;
2445 return {ImportAction::None};
2463 enum { Enter,
Import,
Skip, IncludeLimitReached } Action = Enter;
2465 if (PPOpts.SingleFileParseMode)
2466 Action = IncludeLimitReached;
2471 if (Action == Enter && HasReachedMaxIncludeDepth &&
File &&
2473 Action = IncludeLimitReached;
2480 bool MaybeTranslateInclude = Action == Enter &&
File && ModuleToImport &&
2484 bool UsableHeaderUnit =
false;
2485 if (
getLangOpts().CPlusPlusModules && ModuleToImport &&
2487 if (TrackGMFState.inGMF() || IsImportDecl)
2488 UsableHeaderUnit =
true;
2489 else if (!IsImportDecl) {
2491 ModuleToImport =
nullptr;
2495 bool UsableClangHeaderModule =
2499 if (MaybeTranslateInclude && (UsableHeaderUnit || UsableClangHeaderModule) &&
2500 PPOpts.SingleModuleParseMode) {
2501 Action = IncludeLimitReached;
2506 else if (MaybeTranslateInclude &&
2507 (UsableHeaderUnit || UsableClangHeaderModule)) {
2515 diag::note_implicit_top_level_module_import_here)
2517 return {ImportAction::None};
2523 SmallVector<IdentifierLoc, 2> Path;
2524 for (
Module *Mod = ModuleToImport; Mod; Mod = Mod->Parent)
2527 std::reverse(Path.begin(), Path.end());
2537 ModuleLoadResult Imported = TheModuleLoader.loadModule(
2540 assert((Imported ==
nullptr || Imported == ModuleToImport) &&
2541 "the imported module is different than the suggested one");
2547 static_cast<Module *
>(Imported)->getTopLevelModule());
2552 ModuleToImport =
nullptr;
2560 Token &
Result = IncludeTok;
2561 assert(CurLexer &&
"#include but no current lexer set!");
2563 CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
2564 CurLexer->cutOffLexing();
2566 return {ImportAction::None};
2574 SourceMgr.getFileCharacteristic(FilenameTok.
getLocation());
2576 FileCharacter = std::max(HeaderInfo.getFileDirFlavor(*
File), FileCharacter);
2587 bool IsFirstIncludeOfFile =
false;
2591 if (Action == Enter &&
File &&
2592 !HeaderInfo.ShouldEnterIncludeFile(*
this, *
File, EnterOnce,
2594 IsFirstIncludeOfFile)) {
2605 if (UsableHeaderUnit && !
getLangOpts().CompilingPCH)
2606 Action = TrackGMFState.inGMF() ?
Import :
Skip;
2608 Action = (ModuleToImport && !
getLangOpts().CompilingPCH) ? Import :
Skip;
2616 if (Action == Enter &&
File && PreambleConditionalStack.isRecording() &&
2617 SourceMgr.isMainFile(
File->getFileEntry())) {
2619 diag::err_pp_including_mainfile_in_preamble);
2620 return {ImportAction::None};
2623 if (Callbacks && !IsImportDecl) {
2626 Callbacks->InclusionDirective(HashLoc, IncludeTok, LookupFilename, isAngled,
2627 FilenameRange,
File, SearchPath, RelativePath,
2628 SuggestedModule.
getModule(), Action == Import,
2631 Callbacks->FileSkipped(*
File, FilenameTok, FileCharacter);
2635 return {ImportAction::None};
2639 if (IsImportDecl && !ModuleToImport) {
2640 Diag(FilenameTok, diag::err_header_import_not_header_unit)
2641 << OriginalFilename <<
File->getName();
2642 return {ImportAction::None};
2647 const bool CheckIncludePathPortability =
2648 !IsMapped && !
File->getFileEntry().tryGetRealPathName().empty();
2650 if (CheckIncludePathPortability) {
2651 StringRef Name = LookupFilename;
2652 StringRef NameWithoriginalSlashes = Filename;
2656 bool NameWasUNC = Name.consume_front(
"\\\\?\\");
2657 NameWithoriginalSlashes.consume_front(
"\\\\?\\");
2659 StringRef RealPathName =
File->getFileEntry().tryGetRealPathName();
2660 SmallVector<StringRef, 16> Components(llvm::sys::path::begin(Name),
2661 llvm::sys::path::end(Name));
2673 SmallString<128> FixedDriveRealPath;
2674 if (llvm::sys::path::is_absolute(Name) &&
2675 llvm::sys::path::is_absolute(RealPathName) &&
2678 assert(Components.size() >= 3 &&
"should have drive, backslash, name");
2679 assert(Components[0].size() == 2 &&
"should start with drive");
2680 assert(Components[0][1] ==
':' &&
"should have colon");
2681 FixedDriveRealPath = (Name.substr(0, 1) + RealPathName.substr(1)).str();
2682 RealPathName = FixedDriveRealPath;
2687 SmallString<128> Path;
2688 Path.reserve(Name.size()+2);
2689 Path.push_back(isAngled ?
'<' :
'"');
2691 const auto IsSep = [BackslashStyle](
char c) {
2692 return llvm::sys::path::is_separator(
c, BackslashStyle);
2695 for (
auto Component : Components) {
2707 if (!(Component.size() == 1 && IsSep(Component[0])))
2708 Path.append(Component);
2709 else if (Path.size() != 1)
2713 if (Path.size() > NameWithoriginalSlashes.size()) {
2714 Path.push_back(isAngled ?
'>' :
'"');
2717 assert(IsSep(NameWithoriginalSlashes[Path.size()-1]));
2719 Path.push_back(NameWithoriginalSlashes[Path.size()-1]);
2720 while (Path.size() <= NameWithoriginalSlashes.size() &&
2721 IsSep(NameWithoriginalSlashes[Path.size()-1]));
2727 Path = (Path.substr(0, 1) +
"\\\\?\\" + Path.substr(1)).str();
2734 ? diag::pp_nonportable_path
2735 : diag::pp_nonportable_system_path;
2736 Diag(FilenameTok, DiagId) << Path <<
2745 return {ImportAction::SkippedModuleImport, ModuleToImport};
2746 return {ImportAction::None};
2748 case IncludeLimitReached:
2751 return {ImportAction::None};
2755 assert(ModuleToImport &&
"no module to import");
2760 tok::pp___include_macros)
2761 return {ImportAction::None};
2763 return {ImportAction::ModuleImport, ModuleToImport};
2771 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
2772 Diag(FilenameTok, diag::err_pp_include_too_deep);
2773 HasReachedMaxIncludeDepth =
true;
2774 return {ImportAction::None};
2778 Diag(FilenameTok, diag::warn_pp_include_angled_in_module_purview)
2782 SourceLocation IncludePos = FilenameTok.
getLocation();
2786 IncludePos = SourceMgr.getExpansionRange(IncludePos).getEnd();
2787 FileID FID = SourceMgr.createFileID(*
File, IncludePos, FileCharacter);
2789 TheModuleLoader.HadFatalFailure =
true;
2790 return ImportAction::Failure;
2795 IsFirstIncludeOfFile))
2796 return {ImportAction::None};
2800 if (ModuleToImport && !ModuleToImport->
isHeaderUnit()) {
2805 diag::err_module_build_shadowed_submodule)
2808 diag::note_previous_definition);
2809 return {ImportAction::None};
2821 return {ImportAction::None};
2823 assert(!CurLexerSubmodule &&
"should not have marked this as a module yet");
2824 CurLexerSubmodule = ModuleToImport;
2834 return {ImportAction::ModuleBegin, ModuleToImport};
2837 assert(!IsImportDecl &&
"failed to diagnose missing module for import decl");
2838 return {ImportAction::None};
2843void Preprocessor::HandleIncludeNextDirective(
SourceLocation HashLoc,
2844 Token &IncludeNextTok) {
2845 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
2848 const FileEntry *LookupFromFile;
2849 std::tie(Lookup, LookupFromFile) = getIncludeNextStart(IncludeNextTok);
2851 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
2856void Preprocessor::HandleMicrosoftImportDirective(
Token &
Tok) {
2862 Diag(
Tok, diag::err_pp_import_directive_ms );
2873 if (!LangOpts.ObjC) {
2874 if (LangOpts.MSVCCompat)
2875 return HandleMicrosoftImportDirective(ImportTok);
2876 Diag(ImportTok, diag::ext_pp_import_directive);
2878 return HandleIncludeDirective(HashLoc, ImportTok);
2885void Preprocessor::HandleIncludeMacrosDirective(
SourceLocation HashLoc,
2886 Token &IncludeMacrosTok) {
2889 SourceLocation Loc = IncludeMacrosTok.
getLocation();
2890 if (SourceMgr.getBufferName(Loc) !=
"<built-in>") {
2892 diag::pp_include_macros_out_of_predefines);
2899 HandleIncludeDirective(HashLoc, IncludeMacrosTok);
2904 assert(TmpTok.
isNot(tok::eof) &&
"Didn't find end of -imacros!");
2905 }
while (TmpTok.
isNot(tok::hashhash));
2927 Diag(
Tok, diag::err_pp_expected_ident_in_arg_list);
2931 Diag(
Tok, LangOpts.CPlusPlus11 ?
2932 diag::warn_cxx98_compat_variadic_macro :
2933 diag::ext_variadic_macro);
2936 if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus) {
2937 Diag(
Tok, diag::ext_pp_opencl_variadic_macros);
2943 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2952 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2960 Diag(
Tok, diag::err_pp_invalid_tok_in_arg_list);
2966 if (llvm::is_contained(Parameters, II)) {
2967 Diag(
Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
2979 Diag(
Tok, diag::err_pp_expected_comma_in_arg_list);
2988 Diag(
Tok, diag::ext_named_variadic_macro);
2993 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
3023 StringRef ValueText = II->
getName();
3024 StringRef TrimmedValue = ValueText;
3025 if (!ValueText.starts_with(
"__")) {
3026 if (ValueText.starts_with(
"_"))
3027 TrimmedValue = TrimmedValue.drop_front(1);
3031 TrimmedValue = TrimmedValue.drop_front(2);
3032 if (TrimmedValue.ends_with(
"__"))
3033 TrimmedValue = TrimmedValue.drop_back(2);
3035 return TrimmedValue == MacroText;
3042 return MacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
3055MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
3056 const Token &MacroNameTok,
const bool ImmediatelyAfterHeaderGuard) {
3058 Token LastTok = MacroNameTok;
3066 llvm::scope_exit _([&]() {
3068 if (CurLexer->ParsingPreprocessorDirective)
3079 if (
Tok.
is(tok::eod)) {
3080 if (ImmediatelyAfterHeaderGuard) {
3090 }
else if (
Tok.
is(tok::l_paren)) {
3093 if (ReadMacroParameterList(MI, LastTok))
3107 }
else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
3110 Diag(
Tok, diag::ext_c99_whitespace_required_after_macro_name);
3119 if (
Tok.
is(tok::at))
3121 else if (
Tok.
is(tok::unknown)) {
3128 Diag(
Tok, diag::ext_missing_whitespace_after_macro_name);
3130 Diag(
Tok, diag::warn_missing_whitespace_after_macro_name);
3133 if (!
Tok.
is(tok::eod))
3136 SmallVector<Token, 16> Tokens;
3143 Tokens.push_back(
Tok);
3157 if (!
Tok.
isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
3158 Tokens.push_back(
Tok);
3160 if (VAOCtx.isVAOptToken(
Tok)) {
3162 if (VAOCtx.isInVAOpt()) {
3163 Diag(
Tok, diag::err_pp_vaopt_nested_use);
3169 Diag(
Tok, diag::err_pp_missing_lparen_in_vaopt_use);
3172 Tokens.push_back(
Tok);
3175 if (
Tok.
is(tok::hashhash)) {
3176 Diag(
Tok, diag::err_vaopt_paste_at_start);
3180 }
else if (VAOCtx.isInVAOpt()) {
3181 if (
Tok.
is(tok::r_paren)) {
3182 if (VAOCtx.sawClosingParen()) {
3183 assert(Tokens.size() >= 3 &&
3184 "Must have seen at least __VA_OPT__( "
3185 "and a subsequent tok::r_paren");
3186 if (Tokens[Tokens.size() - 2].is(tok::hashhash)) {
3187 Diag(
Tok, diag::err_vaopt_paste_at_end);
3191 }
else if (
Tok.
is(tok::l_paren)) {
3205 Tokens.push_back(
Tok);
3212 if (
Tok.
is(tok::hashhash)) {
3220 if (
Tok.
is(tok::eod)) {
3221 Tokens.push_back(LastTok);
3226 Tokens[Tokens.size() - 1].is(tok::comma))
3230 Tokens.push_back(LastTok);
3239 if (!VAOCtx.isVAOptToken(
Tok) &&
3248 LastTok.
setKind(tok::unknown);
3249 Tokens.push_back(LastTok);
3252 Diag(
Tok, diag::err_pp_stringize_not_parameter)
3253 << LastTok.
is(tok::hashat);
3259 Tokens.push_back(LastTok);
3264 if (!VAOCtx.isVAOptToken(
Tok)) {
3265 Tokens.push_back(
Tok);
3272 if (VAOCtx.isInVAOpt()) {
3273 assert(
Tok.
is(tok::eod) &&
"Must be at End Of preprocessing Directive");
3274 Diag(
Tok, diag::err_pp_expected_after)
3275 << LastTok.
getKind() << tok::r_paren;
3276 Diag(VAOCtx.getUnmatchedOpeningParenLoc(), diag::note_matching) << tok::l_paren;
3287 return II->
isStr(
"__strong") || II->
isStr(
"__weak") ||
3288 II->
isStr(
"__unsafe_unretained") || II->
isStr(
"__autoreleasing");
3293void Preprocessor::HandleDefineDirective(
3294 Token &DefineTok,
const bool ImmediatelyAfterHeaderGuard) {
3298 bool MacroShadowsKeyword;
3299 ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
3302 if (MacroNameTok.
is(tok::eod))
3309 emitFinalMacroWarning(MacroNameTok,
false);
3313 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
3315 MacroInfo *
const MI = ReadOptionalMacroParameterListAndBody(
3316 MacroNameTok, ImmediatelyAfterHeaderGuard);
3320 if (MacroShadowsKeyword &&
3322 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
3327 if (NumTokens != 0) {
3339 if (SkippingUntilPCHThroughHeader) {
3342 LangOpts.MicrosoftExt))
3346 if (!LangOpts.MicrosoftExt)
3357 emitFinalMacroWarning(MacroNameTok,
false);
3368 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) &&
3370 LangOpts.MicrosoftExt)) {
3381 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) {
3389 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
3393 !MI->
isIdenticalTo(*OtherMI, *
this, LangOpts.MicrosoftExt)) {
3403 DefMacroDirective *MD =
3411 !MacroExpansionInDirectivesOverride &&
3420 Callbacks->MacroDefined(MacroNameTok, MD);
3425void Preprocessor::HandleUndefDirective() {
3429 ReadMacroName(MacroNameTok,
MU_Undef);
3432 if (MacroNameTok.
is(tok::eod))
3441 UndefMacroDirective *Undef =
nullptr;
3444 emitFinalMacroWarning(MacroNameTok,
true);
3454 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
3459 Undef = AllocateUndefMacroDirective(MacroNameTok.
getLocation());
3465 Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
3480void Preprocessor::HandleIfdefDirective(
Token &
Result,
3481 const Token &HashToken,
3483 bool ReadAnyTokensBeforeDirective) {
3485 Token DirectiveTok =
Result;
3488 ReadMacroName(MacroNameTok);
3491 if (MacroNameTok.
is(tok::eod)) {
3494 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3509 if (CurPPLexer->getConditionalStackDepth() == 0) {
3514 if (!ReadAnyTokensBeforeDirective && !MI) {
3515 assert(isIfndef &&
"#ifdef shouldn't reach here");
3516 CurPPLexer->MIOpt.EnterTopLevelIfndef(MII, MacroNameTok.
getLocation());
3518 CurPPLexer->MIOpt.EnterTopLevelConditional();
3527 Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3529 Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3532 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3536 if (PPOpts.SingleFileParseMode && !MI) {
3539 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3542 }
else if (PPOpts.SingleModuleParseMode && !MI) {
3546 SkipExcludedConditionalBlock(
3549 }
else if (!MI == isIfndef || RetainExcludedCB) {
3551 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3556 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3565void Preprocessor::HandleIfDirective(
Token &IfToken,
3566 const Token &HashToken,
3567 bool ReadAnyTokensBeforeDirective) {
3571 IdentifierInfo *IfNDefMacro =
nullptr;
3572 const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
3573 const bool ConditionalTrue = DER.Conditional;
3581 if (CurPPLexer->getConditionalStackDepth() == 0) {
3582 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
3584 CurPPLexer->MIOpt.EnterTopLevelIfndef(IfNDefMacro, IfToken.
getLocation());
3586 CurPPLexer->MIOpt.EnterTopLevelConditional();
3594 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3598 if (PPOpts.SingleFileParseMode && DER.IncludedUndefinedIds) {
3601 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3603 }
else if (PPOpts.SingleModuleParseMode && DER.IncludedUndefinedIds) {
3610 }
else if (ConditionalTrue || RetainExcludedCB) {
3612 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3624void Preprocessor::HandleEndifDirective(
Token &EndifToken) {
3630 PPConditionalInfo CondInfo;
3631 if (CurPPLexer->popConditionalLevel(CondInfo)) {
3633 Diag(EndifToken, diag::err_pp_endif_without_if);
3638 if (CurPPLexer->getConditionalStackDepth() == 0)
3639 CurPPLexer->MIOpt.ExitTopLevelConditional();
3641 assert(!CondInfo.
WasSkipping && !CurPPLexer->LexingRawMode &&
3642 "This code should only be reachable in the non-skipping case!");
3650void Preprocessor::HandleElseDirective(
Token &
Result,
const Token &HashToken) {
3656 PPConditionalInfo CI;
3657 if (CurPPLexer->popConditionalLevel(CI)) {
3663 if (CurPPLexer->getConditionalStackDepth() == 0)
3664 CurPPLexer->MIOpt.EnterTopLevelConditional();
3672 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3675 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3678 CurPPLexer->pushConditionalLevel(CI.
IfLoc,
false,
3686 true,
Result.getLocation());
3690void Preprocessor::HandleElifFamilyDirective(
Token &ElifToken,
3691 const Token &HashToken,
3703 if (LangOpts.CPlusPlus)
3704 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
3705 : diag::ext_cxx23_pp_directive;
3707 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
3708 : diag::ext_c23_pp_directive;
3709 Diag(ElifToken, DiagID) << DirKind;
3720 PPConditionalInfo CI;
3721 if (CurPPLexer->popConditionalLevel(CI)) {
3722 Diag(ElifToken, diag::pp_err_elif_without_if) << DirKind;
3727 if (CurPPLexer->getConditionalStackDepth() == 0)
3728 CurPPLexer->MIOpt.EnterTopLevelConditional();
3732 Diag(ElifToken, diag::pp_err_elif_after_else) << DirKind;
3737 Callbacks->Elif(ElifToken.
getLocation(), ConditionRange,
3740 case tok::pp_elifdef:
3743 case tok::pp_elifndef:
3747 assert(
false &&
"unexpected directive kind");
3752 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3755 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3758 CurPPLexer->pushConditionalLevel(ElifToken.
getLocation(),
false,
3764 SkipExcludedConditionalBlock(
3769std::optional<LexEmbedParametersResult>
3772 tok::TokenKind EndTokenKind = ForHasEmbed ? tok::r_paren : tok::eod;
3774 auto DiagMismatchedBracesAndSkipToEOD =
3776 std::pair<tok::TokenKind, SourceLocation> Matches) {
3778 Diag(Matches.second, diag::note_matching) << Matches.first;
3779 if (CurTok.
isNot(tok::eod))
3784 if (CurTok.
isNot(Kind)) {
3785 Diag(CurTok, diag::err_expected) << Kind;
3786 if (CurTok.
isNot(tok::eod))
3803 auto LexPPParameterName = [&]() -> std::optional<std::string> {
3806 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3807 return std::nullopt;
3814 if (CurTok.
is(tok::coloncolon)) {
3817 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3818 return std::nullopt;
3824 return (llvm::Twine(Prefix->
getName()) +
"::" + Suffix->
getName()).str();
3826 return Prefix->
getName().str();
3833 auto NormalizeParameterName = [](StringRef Name) {
3834 if (Name.size() > 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
3835 return Name.substr(2, Name.size() - 4);
3839 auto LexParenthesizedIntegerExpr = [&]() -> std::optional<size_t> {
3842 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3843 return std::nullopt;
3848 bool EvaluatedDefined;
3849 DirectiveEvalResult LimitEvalResult = EvaluateDirectiveExpression(
3850 ParameterIfNDef, CurTok, EvaluatedDefined,
false);
3852 if (!LimitEvalResult.Value) {
3855 assert(CurTok.
is(tok::eod) &&
"expect to be at the end of directive");
3856 return std::nullopt;
3859 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3860 return std::nullopt;
3867 if (EvaluatedDefined) {
3868 Diag(CurTok, diag::err_defined_in_pp_embed);
3869 return std::nullopt;
3872 if (LimitEvalResult.Value) {
3873 const llvm::APSInt &
Result = *LimitEvalResult.Value;
3874 if (
Result.isNegative()) {
3875 Diag(CurTok, diag::err_requires_positive_value)
3877 if (CurTok.
isNot(EndTokenKind))
3879 return std::nullopt;
3881 return Result.getLimitedValue();
3883 return std::nullopt;
3889 return tok::r_paren;
3891 return tok::r_brace;
3893 return tok::r_square;
3895 llvm_unreachable(
"should not get here");
3899 auto LexParenthesizedBalancedTokenSoup =
3901 std::vector<std::pair<tok::TokenKind, SourceLocation>> BracketStack;
3904 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3908 bool WaitingForInnerCloseParen =
false;
3909 while (CurTok.
isNot(tok::eod) &&
3910 (WaitingForInnerCloseParen || CurTok.
isNot(tok::r_paren))) {
3915 WaitingForInnerCloseParen =
true;
3922 WaitingForInnerCloseParen =
false;
3925 case tok::r_square: {
3926 if (BracketStack.empty()) {
3927 ExpectOrDiagAndSkipToEOD(tok::r_paren);
3931 GetMatchingCloseBracket(BracketStack.back().first);
3932 if (CurTok.
getKind() != Matching) {
3933 DiagMismatchedBracesAndSkipToEOD(Matching, BracketStack.back());
3936 BracketStack.pop_back();
3939 Tokens.push_back(CurTok);
3944 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3952 while (!CurTok.
isOneOf(EndTokenKind, tok::eod)) {
3954 std::optional<std::string> ParamName = LexPPParameterName();
3956 return std::nullopt;
3957 StringRef
Parameter = NormalizeParameterName(*ParamName);
3964 if (
Result.MaybeLimitParam)
3967 std::optional<size_t> Limit = LexParenthesizedIntegerExpr();
3969 return std::nullopt;
3972 }
else if (
Parameter ==
"clang::offset") {
3973 if (
Result.MaybeOffsetParam)
3976 std::optional<size_t> Offset = LexParenthesizedIntegerExpr();
3978 return std::nullopt;
3982 if (
Result.MaybePrefixParam)
3986 if (!LexParenthesizedBalancedTokenSoup(Soup))
3987 return std::nullopt;
3989 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
3991 if (
Result.MaybeSuffixParam)
3995 if (!LexParenthesizedBalancedTokenSoup(Soup))
3996 return std::nullopt;
3998 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
4000 if (
Result.MaybeIfEmptyParam)
4004 if (!LexParenthesizedBalancedTokenSoup(Soup))
4005 return std::nullopt;
4007 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
4009 ++
Result.UnrecognizedParams;
4013 if (CurTok.
is(tok::l_paren)) {
4015 if (!LexParenthesizedBalancedTokenSoup(Soup))
4016 return std::nullopt;
4019 Diag(ParamStartLoc, diag::err_pp_unknown_parameter) << 1 <<
Parameter;
4020 if (CurTok.
isNot(EndTokenKind))
4022 return std::nullopt;
4029void Preprocessor::HandleEmbedDirectiveImpl(
4031 StringRef BinaryContents, StringRef
FileName) {
4032 if (BinaryContents.empty()) {
4040 size_t TokCount = Toks.size();
4041 auto NewToks = std::make_unique<Token[]>(TokCount);
4042 llvm::copy(Toks, NewToks.get());
4043 EnterTokenStream(std::move(NewToks), TokCount,
true,
true);
4050 size_t TotalNumToks = 1 + NumPrefixToks + NumSuffixToks;
4052 auto Toks = std::make_unique<Token[]>(TotalNumToks);
4057 CurIdx += NumPrefixToks;
4060 EmbedAnnotationData *
Data =
new (BP) EmbedAnnotationData;
4061 Data->BinaryData = BinaryContents;
4064 Toks[CurIdx].startToken();
4065 Toks[CurIdx].setKind(tok::annot_embed);
4066 Toks[CurIdx].setAnnotationRange(HashLoc);
4067 Toks[CurIdx++].setAnnotationValue(
Data);
4072 CurIdx += NumSuffixToks;
4075 assert(CurIdx == TotalNumToks &&
"Calculated the incorrect number of tokens");
4076 EnterTokenStream(std::move(Toks), TotalNumToks,
true,
true);
4083 Diag(EmbedTok, diag::warn_compat_pp_embed_directive);
4085 Diag(EmbedTok, diag::ext_pp_embed_directive)
4086 << (LangOpts.CPlusPlus ? 1 : 0);
4093 if (FilenameTok.
isNot(tok::header_name)) {
4095 if (FilenameTok.
isNot(tok::eod))
4108 std::optional<LexEmbedParametersResult> Params =
4111 assert((Params || CurTok.
is(tok::eod)) &&
4112 "expected success or to be at the end of the directive");
4117 SmallString<128> FilenameBuffer;
4118 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
4119 StringRef OriginalFilename = Filename;
4125 if (Filename.empty())
4130 if (!MaybeFileRef) {
4132 if (Callbacks && Callbacks->EmbedFileNotFound(Filename)) {
4135 Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
4140 Diag(FilenameTok, diag::err_pp_embed_device_file) << Filename;
4144 std::optional<llvm::MemoryBufferRef> MaybeFile =
4148 Diag(FilenameTok, diag::err_cannot_open_file)
4149 << Filename <<
"a buffer to the contents could not be created";
4152 StringRef BinaryContents = MaybeFile->getBuffer();
4157 if (Params->MaybeOffsetParam) {
4162 BinaryContents = BinaryContents.substr(Params->MaybeOffsetParam->Offset);
4165 if (Params->MaybeLimitParam) {
4169 BinaryContents = BinaryContents.substr(0, Params->MaybeLimitParam->Limit);
4173 Callbacks->EmbedDirective(HashLoc, Filename, isAngled, MaybeFileRef,
4182 void *Mem = BP.Allocate(OriginalFilename.size(),
alignof(
char *));
4183 memcpy(Mem, OriginalFilename.data(), OriginalFilename.size());
4184 StringRef FilenameToGo =
4185 StringRef(
static_cast<char *
>(Mem), OriginalFilename.size());
4186 HandleEmbedDirectiveImpl(HashLoc, *Params, BinaryContents, FilenameToGo);
4199 assert(
getLangOpts().CPlusPlusModules && ImportTok.
is(tok::kw_import));
4201 this->ImportingCXXNamedModules,
true);
4203 if (LastTokenWasExportKeyword.isValid())
4204 LastTokenWasExportKeyword.reset();
4208 if (
Tok.isNot(tok::eod))
4216 bool ImportingHeader =
false;
4217 bool IsPartition =
false;
4218 std::string FlatName;
4219 switch (
Tok.getKind()) {
4220 case tok::header_name:
4221 ImportingHeader =
true;
4222 DirToks.push_back(
Tok);
4223 Lex(DirToks.emplace_back());
4227 DirToks.push_back(
Tok);
4228 UseLoc =
Tok.getLocation();
4231 case tok::identifier: {
4232 bool LeadingSpace =
Tok.hasLeadingSpace();
4233 unsigned NumToksInDirective = DirToks.size();
4235 if (
Tok.isNot(tok::eod))
4244 DirToks.resize(NumToksInDirective);
4246 DirToks.emplace_back();
4247 DirToks.back().setKind(tok::annot_module_name);
4248 DirToks.back().setAnnotationRange(NameLoc->
getRange());
4249 DirToks.back().setAnnotationValue(
static_cast<void *
>(NameLoc));
4251 DirToks.push_back(
Tok);
4254 (IsPartition && ModuleDeclState.isNamedModule()) || !IsPartition;
4255 if (Callbacks && IsValid) {
4256 if (IsPartition && ModuleDeclState.isNamedModule()) {
4257 FlatName += ModuleDeclState.getPrimaryName();
4262 SourceLocation StartLoc = IsPartition ? UseLoc : Path[0].getLoc();
4274 DirToks.push_back(
Tok);
4280 if (!DirToks.back().isOneOf(tok::semi, tok::eod))
4283 if (DirToks.back().isNot(tok::eod))
4289 if (DirToks.back().isNot(tok::semi)) {
4294 if (ImportingHeader) {
4300 Diag(SemiLoc, diag::err_header_import_semi_in_macro);
4302 auto Action = HandleHeaderIncludeOrImport(
4304 switch (Action.Kind) {
4305 case ImportAction::None:
4308 case ImportAction::ModuleBegin:
4310 DirToks.emplace_back();
4311 DirToks.back().startToken();
4312 DirToks.back().setKind(tok::annot_module_begin);
4313 DirToks.back().setLocation(SemiLoc);
4314 DirToks.back().setAnnotationEndLoc(SemiLoc);
4315 DirToks.back().setAnnotationValue(Action.ModuleForHeader);
4318 case ImportAction::ModuleImport:
4319 case ImportAction::HeaderUnitImport:
4320 case ImportAction::SkippedModuleImport:
4323 DirToks[1].setKind(tok::annot_header_unit);
4324 DirToks[1].setAnnotationEndLoc(DirToks[0].getLocation());
4325 DirToks[1].setAnnotationValue(Action.ModuleForHeader);
4328 case ImportAction::Failure:
4329 assert(TheModuleLoader.HadFatalFailure &&
4330 "This should be an early exit only to a fatal error");
4331 CurLexer->cutOffLexing();
4360 assert(
getLangOpts().CPlusPlusModules && ModuleTok.
is(tok::kw_module));
4361 Token Introducer = ModuleTok;
4362 if (LastTokenWasExportKeyword.isValid()) {
4363 Introducer = LastTokenWasExportKeyword.getExportTok();
4364 LastTokenWasExportKeyword.reset();
4375 switch (
Tok.getKind()) {
4378 DirToks.push_back(
Tok);
4381 DirToks.push_back(
Tok);
4383 if (
Tok.isNot(tok::kw_private)) {
4384 if (
Tok.isNot(tok::eod))
4390 DirToks.push_back(
Tok);
4392 case tok::identifier: {
4393 bool LeadingSpace =
Tok.hasLeadingSpace();
4394 unsigned NumToksInDirective = DirToks.size();
4403 if (
Tok.isNot(tok::eod))
4411 DirToks.resize(NumToksInDirective);
4412 DirToks.emplace_back();
4413 DirToks.back().setKind(tok::annot_module_name);
4414 DirToks.back().setAnnotationRange(NameLoc->
getRange());
4415 DirToks.back().setAnnotationValue(
static_cast<void *
>(NameLoc));
4417 DirToks.push_back(
Tok);
4422 if (
Tok.is(tok::colon)) {
4423 NumToksInDirective = DirToks.size();
4425 LeadingSpace =
Tok.hasLeadingSpace();
4429 if (
Tok.isNot(tok::eod))
4437 DirToks.resize(NumToksInDirective);
4438 DirToks.emplace_back();
4439 DirToks.back().setKind(tok::annot_module_name);
4440 DirToks.back().setAnnotationRange(NameLoc->
getRange());
4441 DirToks.back().setAnnotationValue(
static_cast<void *
>(PartitionLoc));
4443 DirToks.push_back(
Tok);
4452 if (
Tok.is(tok::identifier) &&
4454 std::unique_ptr<Token[]> TokCopy = std::make_unique<Token[]>(1);
4456 EnterTokenStream(std::move(TokCopy), 1,
4459 DirToks.back() =
Tok;
4464 DirToks.push_back(
Tok);
4471 std::optional<Token> NextPPTok = DirToks.back();
4472 if (DirToks.back().is(tok::eod)) {
4473 NextPPTok = peekNextPPToken();
4474 if (NextPPTok && NextPPTok->is(tok::raw_identifier))
4480 if (!NextPPTok->isOneOf(tok::semi, tok::eod, tok::l_square, tok::kw_private))
4481 Diag(*NextPPTok, diag::err_pp_unexpected_tok_after_module_name)
4484 if (!DirToks.back().isOneOf(tok::semi, tok::eod)) {
4488 End = DirToks.back().getLocation();
4491 if (DirToks.back().isNot(tok::eod))
4495 End = DirToks.pop_back_val().getLocation();
4497 if (!IncludeMacroStack.empty()) {
4498 Diag(StartLoc, diag::err_pp_module_decl_in_header)
4502 if (CurPPLexer->getConditionalStackDepth() != 0) {
4503 Diag(StartLoc, diag::err_pp_cond_span_module_decl)
static bool isInMainFile(const clang::Diagnostic &D)
Defines interfaces for clang::DirectoryEntry and clang::DirectoryEntryRef.
Defines the clang::FileManager interface and associated types.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Defines the clang::LangOptions interface.
Defines the clang::MacroInfo and clang::MacroDirective classes.
Defines the clang::Module class, which describes a module in the source code.
Defines the PPCallbacks interface.
static bool ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit, SrcMgr::CharacteristicKind &FileKind, Preprocessor &PP)
ReadLineMarkerFlags - Parse and validate any flags at the end of a GNU line marker directive.
static bool isConfigurationPattern(Token &MacroName, MacroInfo *MI, const LangOptions &LOptions)
static void diagnoseAutoModuleImport(Preprocessor &PP, SourceLocation HashLoc, Token &IncludeTok, ArrayRef< IdentifierLoc > Path, SourceLocation PathEnd)
Produce a diagnostic informing the user that a include or similar was implicitly treated as a module ...
static std::optional< StringRef > findSimilarStr(StringRef LHS, const std::vector< StringRef > &Candidates)
Find a similar string in Candidates.
static bool isLanguageDefinedBuiltin(const SourceManager &SourceMgr, const MacroInfo *MI, const StringRef MacroName)
static bool trySimplifyPath(SmallVectorImpl< StringRef > &Components, StringRef RealPathName, llvm::sys::path::Style Separator)
static bool warnByDefaultOnWrongCase(StringRef Include)
MacroDiag
Enumerates possible cases of define/undef a reserved identifier.
@ MD_ReservedAttributeIdentifier
static bool isFeatureTestMacro(StringRef MacroName)
static bool GetLineValue(Token &DigitTok, unsigned &Val, unsigned DiagID, Preprocessor &PP, bool IsGNULineDirective=false)
GetLineValue - Convert a numeric token into an unsigned value, emitting Diagnostic DiagID if it is in...
PPElifDiag
Enumerates possible select values for the pp_err_elif_after_else and pp_err_elif_without_if diagnosti...
static bool isReservedCXXAttributeName(Preprocessor &PP, IdentifierInfo *II)
static MacroDiag shouldWarnOnMacroUndef(Preprocessor &PP, IdentifierInfo *II)
static bool isObjCProtectedMacro(const IdentifierInfo *II)
static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II)
Defines the clang::Preprocessor interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines the clang::SourceLocation class and associated facilities.
static bool isInvalid(LocType Loc, bool *Invalid)
Defines the SourceManager interface.
Defines the clang::TokenKind enum and support functions.
VerifyDiagnosticConsumer::Directive Directive
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
__device__ __2f16 float c
ResetMacroExpansionHelper(Preprocessor *pp)
~ResetMacroExpansionHelper()
static AttrArgsInfo getCXX11AttrArgsInfo(const IdentifierInfo *Name)
Represents a character-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).
StringRef tryGetRealPathName() const
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements support for file system lookup, file system caching, and directory search management.
llvm::Expected< DirectoryEntryRef > getDirectoryRef(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
llvm::Expected< FileEntryRef > getFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true, bool IsText=true)
Lookup, cache, and verify the specified file (real or virtual).
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
One of these records is kept for each identifier that is lexed.
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.
bool isCPlusPlusOperatorKeyword() const
bool hadMacroDefinition() const
Returns true if this identifier was #defined to some value at any moment.
bool hasMacroDefinition() const
Return true if this identifier is #defined to some other value.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
bool isKeyword(const LangOptions &LangOpts) const
Return true if this token is a keyword in the specified language.
ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const
Determine whether this is a name reserved for the implementation (C99 7.1.3, C++ [lib....
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
A simple pair of identifier info and location.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool IsHeaderFile
Indicates whether the front-end is explicitly told that the input is a header file (i....
std::string CurrentModule
The name of the current module, of which the main source file is a part.
const MacroInfo * getMacroInfo() const
Encapsulates the data about a macro definition (e.g.
bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP, bool Syntactically) const
Return true if the specified macro definition is equal to this macro in spelling, arguments,...
bool isUsed() const
Return false if this macro is defined in the main file and has not yet been used.
bool isC99Varargs() const
bool isAllowRedefinitionsWithoutWarning() const
Return true if this macro can be redefined without warning.
void setHasCommaPasting()
unsigned getNumTokens() const
Return the number of tokens that this macro expands to.
const Token & getReplacementToken(unsigned Tok) const
void setDefinitionEndLoc(SourceLocation EndLoc)
Set the location of the last token in the macro.
bool isBuiltinMacro() const
Return true if this macro requires processing before expansion.
void setTokens(ArrayRef< Token > Tokens, llvm::BumpPtrAllocator &PPAllocator)
void setParameterList(ArrayRef< IdentifierInfo * > List, llvm::BumpPtrAllocator &PPAllocator)
Set the specified list of identifiers as the parameter list for this macro.
SourceLocation getDefinitionLoc() const
Return the location that the macro was defined at.
void setIsFunctionLike()
Function/Object-likeness.
bool isObjectLike() const
void setIsWarnIfUnused(bool val)
Set the value of the IsWarnIfUnused flag.
int getParameterNum(const IdentifierInfo *Arg) const
Return the parameter number of the specified identifier, or -1 if the identifier is not a formal para...
bool isWarnIfUnused() const
Return true if we should emit a warning if the macro is unused.
void setIsC99Varargs()
Varargs querying methods. This can only be set for function-like macros.
bool isMissingExpected() const
Determines whether the module, which failed to load, was actually a submodule that we expected to see...
bool isConfigMismatch() const
Determines whether the module failed to load due to a configuration mismatch with an explicitly-named...
static std::string getFlatNameFromPath(ModuleIdPath Path)
@ ExcludedHeader
This header is explicitly excluded from the module.
@ TextualHeader
This header is part of the module (for layering purposes) but should be textually included.
static ModuleNameLoc * Create(Preprocessor &PP, ModuleIdPath Path)
SourceRange getRange() const
Describes a module or submodule.
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
bool isForBuilding(const LangOptions &LangOpts) const
Determine whether this module can be built in this compilation.
@ Hidden
All of the names in this module are hidden.
SourceLocation DefinitionLoc
The location of the module definition.
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers).
std::string Name
The name of this module.
bool isAvailable() const
Determine whether this module is available for use within the current translation unit.
bool isHeaderUnit() const
Is this module a header unit.
Module * ShadowingModule
A module with the same name that shadows this module.
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
Preprocessor standard embed parameter "if_empty" if_empty( balanced-token-seq )
Preprocessor standard embed parameter "limit" limit( constant-expression )
Preprocessor extension embed parameter "clang::offset" clang::offset( constant-expression )
Preprocessor standard embed parameter "prefix" prefix( balanced-token-seq )
Preprocessor standard embed parameter "suffix" suffix( balanced-token-seq )
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.
OptionalFileEntryRef LookupEmbedFile(StringRef Filename, bool isAngled, bool OpenFile, const FileEntry *LookupFromFile=nullptr)
Given a "Filename" or <Filename> reference, look up the indicated embed resource.
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.
void makeModuleVisible(Module *M, SourceLocation Loc, bool IncludeExports=true)
bool hadModuleLoaderFatalFailure() const
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.
bool HandleModuleContextualKeyword(Token &Result, bool TokAtPhysicalStartOfLine)
Callback invoked when the lexer sees one of export, import or module token at the start of a line.
OptionalFileEntryRef getHeaderToIncludeForDiagnostics(SourceLocation IncLoc, SourceLocation MLoc)
We want to produce a diagnostic at location IncLoc concerning an unreachable effect at location MLoc ...
bool isNextPPTokenOneOf(Ts... Ks) const
isNextPPTokenOneOf - Check whether the next pp-token is one of the specificed token kind.
DefMacroDirective * appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI, SourceLocation Loc)
bool LexModuleNameContinue(Token &Tok, SourceLocation UseLoc, SmallVectorImpl< Token > &Suffix, SmallVectorImpl< IdentifierLoc > &Path, bool AllowMacroExpansion=true, bool IsPartition=false)
void CollectPPImportSuffix(SmallVectorImpl< Token > &Toks, bool StopUntilEOD=false)
Collect the tokens of a C++20 pp-import-suffix.
void HandlePragmaHdrstop(Token &Tok)
DiagnosticsEngine & getDiagnostics() const
void HandleCXXModuleDirective(Token Module)
HandleCXXModuleDirective - Handle C++ module declaration directives.
std::optional< LexEmbedParametersResult > LexEmbedParameters(Token &Current, bool ForHasEmbed)
Lex the parameters for an embed directive, returns nullopt on error.
Module * getModuleForLocation(SourceLocation Loc, bool AllowTextual)
Find the module that owns the source or header file that Loc points to.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
bool usingPCHWithThroughHeader()
True if using a PCH with a through header.
Preprocessor(const PreprocessorOptions &PPOpts, DiagnosticsEngine &diags, const LangOptions &LangOpts, SourceManager &SM, HeaderSearch &Headers, ModuleLoader &TheModuleLoader, IdentifierInfoLookup *IILookup=nullptr, bool OwnsHeaderSearch=false, TranslationUnitKind TUKind=TU_Complete)
void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD)
Add a directive to the macro directive history for this identifier.
Represents an unpacked "presumed" location which can be presented to the user.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
SourceLocation getIncludeLoc() const
Return the presumed include location of this location.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
bool isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
std::optional< llvm::MemoryBufferRef > getMemoryBufferForFileOrNone(FileEntryRef File)
Retrieve the memory buffer associated with the given file.
A trivial tuple used to represent a source range.
void setBegin(SourceLocation b)
SourceLocation getEnd() const
void setEnd(SourceLocation e)
Exposes information about the current target.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getEndLoc() const
void clearFlag(TokenFlags Flag)
Unset the specified flag.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
unsigned getLength() const
void setKind(tok::TokenKind K)
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
tok::TokenKind getKind() const
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
bool isOneOf(Ts... Ks) const
bool isModuleContextualKeyword(bool AllowExport=true) const
Return true if we have a C++20 modules contextual keyword(export, importor module).
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
bool isNot(tok::TokenKind K) const
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix.
bool needsCleaning() const
Return true if this token has trigraphs or escaped newlines in it.
StringRef getRawIdentifier() const
getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode),...
A directive for an undefined macro.
A directive for setting the module visibility of a macro.
Defines the clang::TargetInfo interface.
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
uint32_t Literal
Literals are represented as positive integers.
bool Sub(InterpState &S, CodePtr OpPC)
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
PPKeywordKind
Provides a namespace for preprocessor keywords which start with a '#' at the beginning of the line.
The JSON file list parser is used to communicate input to InstallAPI.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
bool isReservedInAllContexts(ReservedIdentifierStatus Status)
Determine whether an identifier is reserved in all contexts.
int hasAttribute(AttributeCommonInfo::Syntax Syntax, llvm::StringRef ScopeName, llvm::StringRef AttrName, const TargetInfo &Target, const LangOptions &LangOpts, bool CheckPlugins)
Return the version number associated with the attribute if we recognize and implement the attribute s...
ArrayRef< IdentifierLoc > ModuleIdPath
A sequence of identifier/location pairs used to describe a particular module or submodule,...
LLVM_READONLY char toLowercase(char c)
Converts the given ASCII character to its lowercase equivalent.
detail::SearchDirIteratorImpl< true > ConstSearchDirIterator
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
MacroUse
Context in which macro name is used.
LLVM_READONLY bool isAlphanumeric(unsigned char c)
Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Parameter
The parameter type of a method or function.
@ Result
The result type of a method or function.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
LLVM_READONLY bool isLowercase(unsigned char c)
Return true if this character is a lowercase ASCII letter: [a-z].
@ PIK_HashPragma
The pragma was introduced via #pragma.
OptionalDirectoryEntryRef Directory
The directory entry which should be used for the cached framework.
std::optional< PPEmbedParameterIfEmpty > MaybeIfEmptyParam
size_t SuffixTokenCount() const
std::optional< PPEmbedParameterSuffix > MaybeSuffixParam
std::optional< PPEmbedParameterPrefix > MaybePrefixParam
size_t PrefixTokenCount() const
bool FoundNonSkip
True if we have emitted tokens already, and now we're in an #else block or something.
SourceLocation IfLoc
Location where the conditional started.
bool WasSkipping
True if this was contained in a skipping directive, e.g., in a "\#if 0" block.
bool FoundElse
True if we've seen a #else in this block.