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:
1459 case tok::pp___preprocessed_import:
1462 case tok::pp_import:
1463 switch (Introducer.
getKind()) {
1467 return HandleObjCImportDirective(Introducer,
Result);
1468 case tok::kw_import:
1471 llvm_unreachable(
"not a valid import directive");
1473 case tok::pp_include_next:
1476 case tok::pp_warning:
1477 if (LangOpts.CPlusPlus)
1479 ? diag::warn_cxx23_compat_warning_directive
1480 : diag::ext_pp_warning_directive)
1483 Diag(
Result, LangOpts.C23 ? diag::warn_c23_compat_warning_directive
1484 : diag::ext_pp_warning_directive)
1487 return HandleUserDiagnosticDirective(
Result,
true);
1489 return HandleIdentSCCSDirective(
Result);
1491 return HandleIdentSCCSDirective(
Result);
1494 case tok::pp_assert:
1497 case tok::pp_unassert:
1501 case tok::pp___public_macro:
1503 return HandleMacroPublicDirective(
Result);
1506 case tok::pp___private_macro:
1508 return HandleMacroPrivateDirective();
1519 auto Toks = std::make_unique<Token[]>(2);
1521 Toks[0] = Introducer;
1526 if (
Result.is(tok::hashhash))
1527 Toks[1].setKind(tok::unknown);
1532 EnterTokenStream(std::move(Toks), 2,
false,
false);
1538 Diag(
Result, diag::err_pp_invalid_directive) << 0;
1550 bool IsGNULineDirective=
false) {
1551 if (DigitTok.
isNot(tok::numeric_constant)) {
1552 PP.
Diag(DigitTok, DiagID);
1554 if (DigitTok.
isNot(tok::eod))
1560 IntegerBuffer.resize(DigitTok.
getLength());
1561 const char *DigitTokBegin = &IntegerBuffer[0];
1571 for (
unsigned i = 0; i != ActualLength; ++i) {
1574 if (DigitTokBegin[i] ==
'\'')
1577 if (!
isDigit(DigitTokBegin[i])) {
1579 diag::err_pp_line_digit_sequence) << IsGNULineDirective;
1584 unsigned NextVal = Val*10+(DigitTokBegin[i]-
'0');
1585 if (NextVal < Val) {
1586 PP.
Diag(DigitTok, DiagID);
1593 if (DigitTokBegin[0] ==
'0' && Val)
1595 << IsGNULineDirective;
1607void Preprocessor::HandleLineDirective() {
1615 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*
this))
1619 Diag(DigitTok, diag::ext_pp_line_zero);
1623 unsigned LineLimit = 32768U;
1624 if (LangOpts.C99 || LangOpts.CPlusPlus11)
1625 LineLimit = 2147483648U;
1626 if (LineNo >= LineLimit)
1627 Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
1628 else if (LangOpts.CPlusPlus11 && LineNo >= 32768U)
1629 Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
1631 int FilenameID = -1;
1637 if (StrTok.
is(tok::eod))
1639 else if (StrTok.
isNot(tok::string_literal)) {
1640 Diag(StrTok, diag::err_pp_line_invalid_filename);
1644 Diag(StrTok, diag::err_invalid_string_udl);
1649 StringLiteralParser
Literal(StrTok, *
this);
1650 assert(
Literal.isOrdinary() &&
"Didn't allow wide strings in");
1656 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1660 FilenameID = SourceMgr.getLineTableFilenameID(
Literal.GetString());
1673 SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1675 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID,
false,
1679 Callbacks->FileChanged(CurPPLexer->getSourceLocation(),
1691 if (FlagTok.
is(tok::eod))
return false;
1692 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1699 if (FlagTok.
is(tok::eod))
return false;
1700 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1702 }
else if (FlagVal == 2) {
1718 SM.getDecomposedExpansionLoc(IncLoc).first != CurFileID) {
1719 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);
1725 if (FlagTok.
is(tok::eod))
return false;
1726 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1732 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1740 if (FlagTok.
is(tok::eod))
return false;
1741 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1746 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1754 if (FlagTok.
is(tok::eod))
return false;
1757 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1769void Preprocessor::HandleDigitDirective(
Token &DigitTok) {
1773 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
1780 bool IsFileEntry =
false, IsFileExit =
false;
1781 int FilenameID = -1;
1786 if (StrTok.
is(tok::eod)) {
1787 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1789 FileKind = SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1790 }
else if (StrTok.
isNot(tok::string_literal)) {
1791 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1795 Diag(StrTok, diag::err_invalid_string_udl);
1800 StringLiteralParser
Literal(StrTok, *
this);
1801 assert(
Literal.isOrdinary() &&
"Didn't allow wide strings in");
1807 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1815 if (!SourceMgr.isInPredefinedFile(DigitTok.
getLocation()))
1816 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1820 if (!(IsFileExit &&
Literal.GetString().empty()))
1821 FilenameID = SourceMgr.getLineTableFilenameID(
Literal.GetString());
1825 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID, IsFileEntry,
1826 IsFileExit, FileKind);
1835 else if (IsFileExit)
1838 Callbacks->FileChanged(CurPPLexer->getSourceLocation(), Reason, FileKind);
1844void Preprocessor::HandleUserDiagnosticDirective(
Token &
Tok,
1852 CurLexer->ReadToEndOfLine(&Message);
1856 StringRef Msg =
Message.str().ltrim(
' ');
1859 Diag(
Tok, diag::pp_hash_warning) << Msg;
1861 Diag(
Tok, diag::err_pp_hash_error) << Msg;
1866void Preprocessor::HandleIdentSCCSDirective(
Token &
Tok) {
1868 Diag(
Tok, diag::ext_pp_ident_directive);
1875 if (StrTok.
isNot(tok::string_literal) &&
1876 StrTok.
isNot(tok::wide_string_literal)) {
1877 Diag(StrTok, diag::err_pp_malformed_ident);
1878 if (StrTok.
isNot(tok::eod))
1884 Diag(StrTok, diag::err_invalid_string_udl);
1901void Preprocessor::HandleMacroPublicDirective(
Token &
Tok) {
1903 ReadMacroName(MacroNameTok,
MU_Undef);
1906 if (MacroNameTok.
is(tok::eod))
1918 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1928void Preprocessor::HandleMacroPrivateDirective() {
1930 ReadMacroName(MacroNameTok,
MU_Undef);
1933 if (MacroNameTok.
is(tok::eod))
1945 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1965 StringRef &Buffer) {
1967 assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1979 if (Buffer[0] ==
'<') {
1980 if (Buffer.back() !=
'>') {
1981 Diag(Loc, diag::err_pp_expects_filename);
1982 Buffer = StringRef();
1986 }
else if (Buffer[0] ==
'"') {
1987 if (Buffer.back() !=
'"') {
1988 Diag(Loc, diag::err_pp_expects_filename);
1989 Buffer = StringRef();
1994 Diag(Loc, diag::err_pp_expects_filename);
1995 Buffer = StringRef();
2000 if (Buffer.size() <= 2) {
2001 Diag(Loc, diag::err_pp_empty_filename);
2002 Buffer = StringRef();
2007 Buffer = Buffer.substr(1, Buffer.size()-2);
2014 void *AnnotationVal) {
2017 auto Tok = std::make_unique<Token[]>(1);
2018 Tok[0].startToken();
2019 Tok[0].setKind(Kind);
2020 Tok[0].setLocation(Range.getBegin());
2021 Tok[0].setAnnotationEndLoc(Range.getEnd());
2022 Tok[0].setAnnotationValue(AnnotationVal);
2023 EnterTokenStream(std::move(
Tok), 1,
true,
false);
2033 for (
size_t I = 0, N = Path.size(); I != N; ++I) {
2036 PathString += Path[I].getIdentifierInfo()->getName();
2039 int IncludeKind = 0;
2041 case tok::pp_include:
2045 case tok::pp_import:
2049 case tok::pp_include_next:
2053 case tok::pp___include_macros:
2058 llvm_unreachable(
"unknown include directive kind");
2061 PP.
Diag(HashLoc, diag::remark_pp_include_directive_modular_translation)
2062 << IncludeKind << PathString;
2069 StringRef RealPathName,
2070 llvm::sys::path::Style Separator) {
2071 auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName);
2072 auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName);
2074 bool SuggestReplacement =
false;
2076 auto IsSep = [Separator](StringRef Component) {
2077 return Component.size() == 1 &&
2078 llvm::sys::path::is_separator(Component[0], Separator);
2083 for (
auto &Component : llvm::reverse(Components)) {
2084 if (
"." == Component) {
2085 }
else if (
".." == Component) {
2089 }
else if (RealPathComponentIter != RealPathComponentEnd) {
2090 if (!IsSep(Component) && !IsSep(*RealPathComponentIter) &&
2091 Component != *RealPathComponentIter) {
2095 SuggestReplacement =
2096 RealPathComponentIter->equals_insensitive(Component);
2097 if (!SuggestReplacement)
2099 Component = *RealPathComponentIter;
2101 ++RealPathComponentIter;
2104 return SuggestReplacement;
2113 Module *ShadowingModule =
nullptr;
2119 Diags.Report(MissingHeader.
FileNameLoc, diag::err_module_header_missing)
2121 }
else if (ShadowingModule) {
2124 diag::note_previous_definition);
2135std::pair<ConstSearchDirIterator, const FileEntry *>
2136Preprocessor::getIncludeNextStart(
const Token &IncludeNextTok)
const {
2141 const FileEntry *LookupFromFile =
nullptr;
2149 Diag(IncludeNextTok, diag::pp_include_next_in_primary);
2150 }
else if (CurLexerSubmodule) {
2153 assert(CurPPLexer &&
"#include_next directive in macro?");
2154 if (
auto FE = CurPPLexer->getFileEntry())
2155 LookupFromFile = *FE;
2157 }
else if (!Lookup) {
2162 Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
2168 return {Lookup, LookupFromFile};
2184 if (FilenameTok.
isNot(tok::header_name)) {
2185 if (FilenameTok.
is(tok::identifier) &&
2186 (PPOpts.SingleFileParseMode || PPOpts.SingleModuleParseMode)) {
2196 if (FilenameTok.
isNot(tok::eod))
2205 SourceLocation EndLoc =
2208 auto Action = HandleHeaderIncludeOrImport(HashLoc, IncludeTok, FilenameTok,
2209 EndLoc, LookupFrom, LookupFromFile);
2210 switch (Action.Kind) {
2211 case ImportAction::None:
2212 case ImportAction::SkippedModuleImport:
2214 case ImportAction::ModuleBegin:
2216 tok::annot_module_begin, Action.ModuleForHeader);
2218 case ImportAction::HeaderUnitImport:
2220 Action.ModuleForHeader);
2222 case ImportAction::ModuleImport:
2224 tok::annot_module_include, Action.ModuleForHeader);
2226 case ImportAction::Failure:
2227 assert(TheModuleLoader.HadFatalFailure &&
2228 "This should be an early exit only to a fatal error");
2229 TheModuleLoader.HadFatalFailure =
true;
2231 CurLexer->cutOffLexing();
2239 const Token &FilenameTok,
bool &IsFrameworkFound,
bool IsImportDecl,
2241 const FileEntry *LookupFromFile, StringRef &LookupFilename,
2244 auto DiagnoseHeaderInclusion = [&](FileEntryRef FE) {
2245 if (LangOpts.AsmPreprocessor)
2249 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
2250 bool RequestingModuleIsModuleInterface =
2251 !SourceMgr.isInMainFile(FilenameLoc);
2253 HeaderInfo.getModuleMap().diagnoseHeaderInclusion(
2254 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
2259 FilenameLoc, LookupFilename, isAngled, LookupFrom, LookupFromFile, CurDir,
2260 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2261 &SuggestedModule, &IsMapped, &IsFrameworkFound);
2263 DiagnoseHeaderInclusion(*
File);
2268 if (Callbacks && Callbacks->FileNotFound(Filename))
2269 return std::nullopt;
2271 if (SuppressIncludeNotFoundError)
2272 return std::nullopt;
2279 FilenameLoc, LookupFilename,
false, LookupFrom, LookupFromFile, CurDir,
2280 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2281 &SuggestedModule, &IsMapped,
2284 DiagnoseHeaderInclusion(*
File);
2285 Diag(FilenameTok, diag::err_pp_file_not_found_angled_include_not_fatal)
2286 << Filename << IsImportDecl
2288 "\"" + Filename.str() +
"\"");
2295 StringRef OriginalFilename = Filename;
2296 if (LangOpts.SpellChecking) {
2299 auto CorrectTypoFilename = [](llvm::StringRef Filename) {
2302 Filename = Filename.drop_back();
2306 StringRef TypoCorrectionName = CorrectTypoFilename(Filename);
2307 StringRef TypoCorrectionLookupName = CorrectTypoFilename(LookupFilename);
2310 FilenameLoc, TypoCorrectionLookupName, isAngled, LookupFrom,
2311 LookupFromFile, CurDir, Callbacks ? &SearchPath :
nullptr,
2312 Callbacks ? &RelativePath :
nullptr, &SuggestedModule, &IsMapped,
2315 DiagnoseHeaderInclusion(*
File);
2318 FilenameRange,
"<" + TypoCorrectionName.str() +
">")
2319 : FixItHint::CreateReplacement(
2320 FilenameRange,
"\"" + TypoCorrectionName.str() +
"\"");
2321 Diag(FilenameTok, diag::err_pp_file_not_found_typo_not_fatal)
2322 << OriginalFilename << TypoCorrectionName << Hint;
2325 Filename = TypoCorrectionName;
2326 LookupFilename = TypoCorrectionLookupName;
2332 assert(!
File &&
"expected missing file");
2333 Diag(FilenameTok, diag::err_pp_file_not_found)
2334 << OriginalFilename << FilenameRange;
2335 if (IsFrameworkFound) {
2336 size_t SlashPos = OriginalFilename.find(
'/');
2337 assert(SlashPos != StringRef::npos &&
2338 "Include with framework name should have '/' in the filename");
2339 StringRef FrameworkName = OriginalFilename.substr(0, SlashPos);
2340 FrameworkCacheEntry &CacheEntry =
2341 HeaderInfo.LookupFrameworkCache(FrameworkName);
2342 assert(CacheEntry.
Directory &&
"Found framework should be in cache");
2343 Diag(FilenameTok, diag::note_pp_framework_without_header)
2344 << OriginalFilename.substr(SlashPos + 1) << FrameworkName
2348 return std::nullopt;
2363Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
2367 SmallString<128> FilenameBuffer;
2368 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
2369 SourceLocation CharEnd = FilenameTok.
getEndLoc();
2371 CharSourceRange FilenameRange
2373 StringRef OriginalFilename = Filename;
2379 if (Filename.empty())
2380 return {ImportAction::None};
2381 if (Filename.ends_with(
' ') || Filename.ends_with(
'.')) {
2382 unsigned Selection = Filename.ends_with(
'.') ? 1 : 0;
2383 Diag(FilenameTok, diag::pp_nonportable_path_trailing)
2384 << Filename << Selection;
2387 bool IsImportDecl = HashLoc.
isInvalid();
2388 SourceLocation StartLoc = IsImportDecl ? IncludeTok.
getLocation() : HashLoc;
2391 if (PragmaARCCFCodeAuditedInfo.getLoc().isValid()) {
2392 Diag(StartLoc, diag::err_pp_include_in_arc_cf_code_audited) << IsImportDecl;
2393 Diag(PragmaARCCFCodeAuditedInfo.getLoc(), diag::note_pragma_entered_here);
2396 PragmaARCCFCodeAuditedInfo = IdentifierLoc();
2400 if (PragmaAssumeNonNullLoc.isValid()) {
2401 Diag(StartLoc, diag::err_pp_include_in_assume_nonnull) << IsImportDecl;
2402 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
2405 PragmaAssumeNonNullLoc = SourceLocation();
2408 if (HeaderInfo.HasIncludeAliasMap()) {
2412 StringRef NewName = HeaderInfo.MapHeaderToIncludeAlias(OriginalFilename);
2413 if (!NewName.empty())
2418 bool IsMapped =
false;
2419 bool IsFrameworkFound =
false;
2421 SmallString<1024> SearchPath;
2422 SmallString<1024> RelativePath;
2425 ModuleMap::KnownHeader SuggestedModule;
2426 SourceLocation FilenameLoc = FilenameTok.
getLocation();
2427 StringRef LookupFilename = Filename;
2431 SmallString<128> NormalizedPath;
2432 llvm::sys::path::Style BackslashStyle = llvm::sys::path::Style::native;
2433 if (is_style_posix(BackslashStyle) && LangOpts.MicrosoftExt) {
2434 NormalizedPath = Filename.str();
2435 llvm::sys::path::native(NormalizedPath);
2436 LookupFilename = NormalizedPath;
2437 BackslashStyle = llvm::sys::path::Style::windows;
2441 &CurDir, Filename, FilenameLoc, FilenameRange, FilenameTok,
2442 IsFrameworkFound, IsImportDecl, IsMapped, LookupFrom, LookupFromFile,
2443 LookupFilename, RelativePath, SearchPath, SuggestedModule, isAngled);
2447 SkippingUntilPCHThroughHeader =
false;
2448 return {ImportAction::None};
2466 enum { Enter,
Import,
Skip, IncludeLimitReached } Action = Enter;
2468 if (PPOpts.SingleFileParseMode)
2469 Action = IncludeLimitReached;
2474 if (Action == Enter && HasReachedMaxIncludeDepth &&
File &&
2476 Action = IncludeLimitReached;
2483 bool MaybeTranslateInclude = Action == Enter &&
File && ModuleToImport &&
2487 bool UsableHeaderUnit =
false;
2488 if (
getLangOpts().CPlusPlusModules && ModuleToImport &&
2490 if (TrackGMFState.inGMF() || IsImportDecl)
2491 UsableHeaderUnit =
true;
2492 else if (!IsImportDecl) {
2494 ModuleToImport =
nullptr;
2498 bool UsableClangHeaderModule =
2505 if (MaybeTranslateInclude && (UsableHeaderUnit || UsableClangHeaderModule)) {
2513 diag::note_implicit_top_level_module_import_here)
2515 return {ImportAction::None};
2521 SmallVector<IdentifierLoc, 2> Path;
2522 for (
Module *Mod = ModuleToImport; Mod; Mod = Mod->Parent)
2525 std::reverse(Path.begin(), Path.end());
2535 ModuleLoadResult Imported = TheModuleLoader.loadModule(
2538 assert((Imported ==
nullptr || Imported == ModuleToImport) &&
2539 "the imported module is different than the suggested one");
2545 static_cast<Module *
>(Imported)->getTopLevelModule());
2550 ModuleToImport =
nullptr;
2558 Token &
Result = IncludeTok;
2559 assert(CurLexer &&
"#include but no current lexer set!");
2561 CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
2562 CurLexer->cutOffLexing();
2564 return {ImportAction::None};
2572 SourceMgr.getFileCharacteristic(FilenameTok.
getLocation());
2574 FileCharacter = std::max(HeaderInfo.getFileDirFlavor(*
File), FileCharacter);
2585 bool IsFirstIncludeOfFile =
false;
2589 if (Action == Enter &&
File &&
2590 !HeaderInfo.ShouldEnterIncludeFile(*
this, *
File, EnterOnce,
2592 IsFirstIncludeOfFile)) {
2603 if (UsableHeaderUnit && !
getLangOpts().CompilingPCH)
2604 Action = TrackGMFState.inGMF() ?
Import :
Skip;
2606 Action = (ModuleToImport && !
getLangOpts().CompilingPCH) ? Import :
Skip;
2614 if (Action == Enter &&
File && PreambleConditionalStack.isRecording() &&
2615 SourceMgr.isMainFile(
File->getFileEntry())) {
2617 diag::err_pp_including_mainfile_in_preamble);
2618 return {ImportAction::None};
2621 if (Callbacks && !IsImportDecl) {
2624 Callbacks->InclusionDirective(HashLoc, IncludeTok, LookupFilename, isAngled,
2625 FilenameRange,
File, SearchPath, RelativePath,
2626 SuggestedModule.
getModule(), Action == Import,
2629 Callbacks->FileSkipped(*
File, FilenameTok, FileCharacter);
2633 return {ImportAction::None};
2637 if (IsImportDecl && !ModuleToImport) {
2638 Diag(FilenameTok, diag::err_header_import_not_header_unit)
2639 << OriginalFilename <<
File->getName();
2640 return {ImportAction::None};
2645 const bool CheckIncludePathPortability =
2646 !IsMapped && !
File->getFileEntry().tryGetRealPathName().empty();
2648 if (CheckIncludePathPortability) {
2649 StringRef Name = LookupFilename;
2650 StringRef NameWithoriginalSlashes = Filename;
2654 bool NameWasUNC = Name.consume_front(
"\\\\?\\");
2655 NameWithoriginalSlashes.consume_front(
"\\\\?\\");
2657 StringRef RealPathName =
File->getFileEntry().tryGetRealPathName();
2658 SmallVector<StringRef, 16> Components(llvm::sys::path::begin(Name),
2659 llvm::sys::path::end(Name));
2671 SmallString<128> FixedDriveRealPath;
2672 if (llvm::sys::path::is_absolute(Name) &&
2673 llvm::sys::path::is_absolute(RealPathName) &&
2676 assert(Components.size() >= 3 &&
"should have drive, backslash, name");
2677 assert(Components[0].size() == 2 &&
"should start with drive");
2678 assert(Components[0][1] ==
':' &&
"should have colon");
2679 FixedDriveRealPath = (Name.substr(0, 1) + RealPathName.substr(1)).str();
2680 RealPathName = FixedDriveRealPath;
2685 SmallString<128> Path;
2686 Path.reserve(Name.size()+2);
2687 Path.push_back(isAngled ?
'<' :
'"');
2689 const auto IsSep = [BackslashStyle](
char c) {
2690 return llvm::sys::path::is_separator(
c, BackslashStyle);
2693 for (
auto Component : Components) {
2705 if (!(Component.size() == 1 && IsSep(Component[0])))
2706 Path.append(Component);
2707 else if (Path.size() != 1)
2711 if (Path.size() > NameWithoriginalSlashes.size()) {
2712 Path.push_back(isAngled ?
'>' :
'"');
2715 assert(IsSep(NameWithoriginalSlashes[Path.size()-1]));
2717 Path.push_back(NameWithoriginalSlashes[Path.size()-1]);
2718 while (Path.size() <= NameWithoriginalSlashes.size() &&
2719 IsSep(NameWithoriginalSlashes[Path.size()-1]));
2725 Path = (Path.substr(0, 1) +
"\\\\?\\" + Path.substr(1)).str();
2732 ? diag::pp_nonportable_path
2733 : diag::pp_nonportable_system_path;
2734 Diag(FilenameTok, DiagId) << Path <<
2738 bool SuppressBackslashDiag =
2740 Diags->isIgnored(diag::pp_nonportable_path_separator, FilenameLoc) ||
2743 SourceMgr.isWrittenInBuiltinFile(FilenameLoc) ||
2744 SourceMgr.isWrittenInModuleIncludes(FilenameLoc);
2745 if (!SuppressBackslashDiag && OriginalFilename.contains(
'\\')) {
2746 std::string SuggestedPath = OriginalFilename.str();
2747 llvm::replace(SuggestedPath,
'\\',
'/');
2748 Diag(FilenameTok, diag::pp_nonportable_path_separator)
2757 return {ImportAction::SkippedModuleImport, ModuleToImport};
2758 return {ImportAction::None};
2760 case IncludeLimitReached:
2763 return {ImportAction::None};
2767 assert(ModuleToImport &&
"no module to import");
2772 tok::pp___include_macros)
2773 return {ImportAction::None};
2775 return {ImportAction::ModuleImport, ModuleToImport};
2783 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
2784 Diag(FilenameTok, diag::err_pp_include_too_deep);
2785 HasReachedMaxIncludeDepth =
true;
2786 return {ImportAction::None};
2790 Diag(FilenameTok, diag::warn_pp_include_angled_in_module_purview)
2794 SourceLocation IncludePos = FilenameTok.
getLocation();
2798 IncludePos = SourceMgr.getExpansionRange(IncludePos).getEnd();
2799 FileID FID = SourceMgr.createFileID(*
File, IncludePos, FileCharacter);
2801 TheModuleLoader.HadFatalFailure =
true;
2802 return ImportAction::Failure;
2807 IsFirstIncludeOfFile))
2808 return {ImportAction::None};
2812 if (ModuleToImport && !ModuleToImport->
isHeaderUnit()) {
2817 diag::err_module_build_shadowed_submodule)
2820 diag::note_previous_definition);
2821 return {ImportAction::None};
2833 return {ImportAction::None};
2835 assert(!CurLexerSubmodule &&
"should not have marked this as a module yet");
2836 CurLexerSubmodule = ModuleToImport;
2846 return {ImportAction::ModuleBegin, ModuleToImport};
2849 assert(!IsImportDecl &&
"failed to diagnose missing module for import decl");
2850 return {ImportAction::None};
2855void Preprocessor::HandleIncludeNextDirective(
SourceLocation HashLoc,
2856 Token &IncludeNextTok) {
2857 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
2860 const FileEntry *LookupFromFile;
2861 std::tie(Lookup, LookupFromFile) = getIncludeNextStart(IncludeNextTok);
2863 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
2868void Preprocessor::HandleMicrosoftImportDirective(
Token &
Tok) {
2874 Diag(
Tok, diag::err_pp_import_directive_ms );
2885 if (!LangOpts.ObjC) {
2886 if (LangOpts.MSVCCompat)
2887 return HandleMicrosoftImportDirective(ImportTok);
2888 Diag(ImportTok, diag::ext_pp_import_directive);
2890 return HandleIncludeDirective(HashLoc, ImportTok);
2897void Preprocessor::HandleIncludeMacrosDirective(
SourceLocation HashLoc,
2898 Token &IncludeMacrosTok) {
2901 SourceLocation Loc = IncludeMacrosTok.
getLocation();
2902 if (SourceMgr.getBufferName(Loc) !=
"<built-in>") {
2904 diag::pp_include_macros_out_of_predefines);
2911 HandleIncludeDirective(HashLoc, IncludeMacrosTok);
2916 assert(TmpTok.
isNot(tok::eof) &&
"Didn't find end of -imacros!");
2917 }
while (TmpTok.
isNot(tok::hashhash));
2939 Diag(
Tok, diag::err_pp_expected_ident_in_arg_list);
2943 Diag(
Tok, LangOpts.CPlusPlus11 ?
2944 diag::warn_cxx98_compat_variadic_macro :
2945 diag::ext_variadic_macro);
2948 if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus) {
2949 Diag(
Tok, diag::ext_pp_opencl_variadic_macros);
2955 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2964 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2972 Diag(
Tok, diag::err_pp_invalid_tok_in_arg_list);
2978 if (llvm::is_contained(Parameters, II)) {
2979 Diag(
Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
2991 Diag(
Tok, diag::err_pp_expected_comma_in_arg_list);
3000 Diag(
Tok, diag::ext_named_variadic_macro);
3005 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
3035 StringRef ValueText = II->
getName();
3036 StringRef TrimmedValue = ValueText;
3037 if (!ValueText.starts_with(
"__")) {
3038 if (ValueText.starts_with(
"_"))
3039 TrimmedValue = TrimmedValue.drop_front(1);
3043 TrimmedValue = TrimmedValue.drop_front(2);
3044 if (TrimmedValue.ends_with(
"__"))
3045 TrimmedValue = TrimmedValue.drop_back(2);
3047 return TrimmedValue == MacroText;
3054 return MacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
3067MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
3068 const Token &MacroNameTok,
const bool ImmediatelyAfterHeaderGuard) {
3070 Token LastTok = MacroNameTok;
3078 llvm::scope_exit _([&]() {
3080 if (CurLexer->ParsingPreprocessorDirective)
3091 if (
Tok.
is(tok::eod)) {
3092 if (ImmediatelyAfterHeaderGuard) {
3102 }
else if (
Tok.
is(tok::l_paren)) {
3105 if (ReadMacroParameterList(MI, LastTok))
3119 }
else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
3122 Diag(
Tok, diag::ext_c99_whitespace_required_after_macro_name);
3131 if (
Tok.
is(tok::at))
3133 else if (
Tok.
is(tok::unknown)) {
3140 Diag(
Tok, diag::ext_missing_whitespace_after_macro_name);
3142 Diag(
Tok, diag::warn_missing_whitespace_after_macro_name);
3145 if (!
Tok.
is(tok::eod))
3148 SmallVector<Token, 16> Tokens;
3155 Tokens.push_back(
Tok);
3169 if (!
Tok.
isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
3170 Tokens.push_back(
Tok);
3172 if (VAOCtx.isVAOptToken(
Tok)) {
3174 if (VAOCtx.isInVAOpt()) {
3175 Diag(
Tok, diag::err_pp_vaopt_nested_use);
3181 Diag(
Tok, diag::err_pp_missing_lparen_in_vaopt_use);
3184 Tokens.push_back(
Tok);
3187 if (
Tok.
is(tok::hashhash)) {
3188 Diag(
Tok, diag::err_vaopt_paste_at_start);
3192 }
else if (VAOCtx.isInVAOpt()) {
3193 if (
Tok.
is(tok::r_paren)) {
3194 if (VAOCtx.sawClosingParen()) {
3195 assert(Tokens.size() >= 3 &&
3196 "Must have seen at least __VA_OPT__( "
3197 "and a subsequent tok::r_paren");
3198 if (Tokens[Tokens.size() - 2].is(tok::hashhash)) {
3199 Diag(
Tok, diag::err_vaopt_paste_at_end);
3203 }
else if (
Tok.
is(tok::l_paren)) {
3217 Tokens.push_back(
Tok);
3224 if (
Tok.
is(tok::hashhash)) {
3232 if (
Tok.
is(tok::eod)) {
3233 Tokens.push_back(LastTok);
3238 Tokens[Tokens.size() - 1].is(tok::comma))
3242 Tokens.push_back(LastTok);
3251 if (!VAOCtx.isVAOptToken(
Tok) &&
3260 LastTok.
setKind(tok::unknown);
3261 Tokens.push_back(LastTok);
3264 Diag(
Tok, diag::err_pp_stringize_not_parameter)
3265 << LastTok.
is(tok::hashat);
3271 Tokens.push_back(LastTok);
3276 if (!VAOCtx.isVAOptToken(
Tok)) {
3277 Tokens.push_back(
Tok);
3284 if (VAOCtx.isInVAOpt()) {
3285 assert(
Tok.
is(tok::eod) &&
"Must be at End Of preprocessing Directive");
3286 Diag(
Tok, diag::err_pp_expected_after)
3287 << LastTok.
getKind() << tok::r_paren;
3288 Diag(VAOCtx.getUnmatchedOpeningParenLoc(), diag::note_matching) << tok::l_paren;
3299 return II->
isStr(
"__strong") || II->
isStr(
"__weak") ||
3300 II->
isStr(
"__unsafe_unretained") || II->
isStr(
"__autoreleasing");
3305void Preprocessor::HandleDefineDirective(
3306 Token &DefineTok,
const bool ImmediatelyAfterHeaderGuard) {
3310 bool MacroShadowsKeyword;
3311 ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
3314 if (MacroNameTok.
is(tok::eod))
3321 emitFinalMacroWarning(MacroNameTok,
false);
3325 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
3327 MacroInfo *
const MI = ReadOptionalMacroParameterListAndBody(
3328 MacroNameTok, ImmediatelyAfterHeaderGuard);
3332 if (MacroShadowsKeyword &&
3334 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
3339 if (NumTokens != 0) {
3351 if (SkippingUntilPCHThroughHeader) {
3354 LangOpts.MicrosoftExt))
3358 if (!LangOpts.MicrosoftExt)
3369 emitFinalMacroWarning(MacroNameTok,
false);
3380 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) &&
3382 LangOpts.MicrosoftExt)) {
3393 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) {
3401 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
3405 !MI->
isIdenticalTo(*OtherMI, *
this, LangOpts.MicrosoftExt)) {
3415 DefMacroDirective *MD =
3423 !MacroExpansionInDirectivesOverride &&
3432 Callbacks->MacroDefined(MacroNameTok, MD);
3437void Preprocessor::HandleUndefDirective() {
3441 ReadMacroName(MacroNameTok,
MU_Undef);
3444 if (MacroNameTok.
is(tok::eod))
3453 UndefMacroDirective *Undef =
nullptr;
3456 emitFinalMacroWarning(MacroNameTok,
true);
3466 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
3471 Undef = AllocateUndefMacroDirective(MacroNameTok.
getLocation());
3477 Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
3492void Preprocessor::HandleIfdefDirective(
Token &
Result,
3493 const Token &HashToken,
3495 bool ReadAnyTokensBeforeDirective) {
3497 Token DirectiveTok =
Result;
3500 ReadMacroName(MacroNameTok);
3503 if (MacroNameTok.
is(tok::eod)) {
3506 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3521 if (CurPPLexer->getConditionalStackDepth() == 0) {
3526 if (!ReadAnyTokensBeforeDirective && !MI) {
3527 assert(isIfndef &&
"#ifdef shouldn't reach here");
3528 CurPPLexer->MIOpt.EnterTopLevelIfndef(MII, MacroNameTok.
getLocation());
3530 CurPPLexer->MIOpt.EnterTopLevelConditional();
3539 Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3541 Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3544 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3548 if (PPOpts.SingleFileParseMode && !MI) {
3551 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3554 }
else if (PPOpts.SingleModuleParseMode && !MI) {
3558 SkipExcludedConditionalBlock(
3561 }
else if (!MI == isIfndef || RetainExcludedCB) {
3563 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3568 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3577void Preprocessor::HandleIfDirective(
Token &IfToken,
3578 const Token &HashToken,
3579 bool ReadAnyTokensBeforeDirective) {
3583 IdentifierInfo *IfNDefMacro =
nullptr;
3584 const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
3585 const bool ConditionalTrue = DER.Conditional;
3593 if (CurPPLexer->getConditionalStackDepth() == 0) {
3594 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
3596 CurPPLexer->MIOpt.EnterTopLevelIfndef(IfNDefMacro, IfToken.
getLocation());
3598 CurPPLexer->MIOpt.EnterTopLevelConditional();
3606 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3610 if (PPOpts.SingleFileParseMode && DER.IncludedUndefinedIds) {
3613 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3615 }
else if (PPOpts.SingleModuleParseMode && DER.IncludedUndefinedIds) {
3622 }
else if (ConditionalTrue || RetainExcludedCB) {
3624 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3636void Preprocessor::HandleEndifDirective(
Token &EndifToken) {
3642 PPConditionalInfo CondInfo;
3643 if (CurPPLexer->popConditionalLevel(CondInfo)) {
3645 Diag(EndifToken, diag::err_pp_endif_without_if);
3650 if (CurPPLexer->getConditionalStackDepth() == 0)
3651 CurPPLexer->MIOpt.ExitTopLevelConditional();
3653 assert(!CondInfo.
WasSkipping && !CurPPLexer->LexingRawMode &&
3654 "This code should only be reachable in the non-skipping case!");
3662void Preprocessor::HandleElseDirective(
Token &
Result,
const Token &HashToken) {
3668 PPConditionalInfo CI;
3669 if (CurPPLexer->popConditionalLevel(CI)) {
3675 if (CurPPLexer->getConditionalStackDepth() == 0)
3676 CurPPLexer->MIOpt.EnterTopLevelConditional();
3684 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3687 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3690 CurPPLexer->pushConditionalLevel(CI.
IfLoc,
false,
3698 true,
Result.getLocation());
3702void Preprocessor::HandleElifFamilyDirective(
Token &ElifToken,
3703 const Token &HashToken,
3715 if (LangOpts.CPlusPlus)
3716 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
3717 : diag::ext_cxx23_pp_directive;
3719 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
3720 : diag::ext_c23_pp_directive;
3721 Diag(ElifToken, DiagID) << DirKind;
3732 PPConditionalInfo CI;
3733 if (CurPPLexer->popConditionalLevel(CI)) {
3734 Diag(ElifToken, diag::pp_err_elif_without_if) << DirKind;
3739 if (CurPPLexer->getConditionalStackDepth() == 0)
3740 CurPPLexer->MIOpt.EnterTopLevelConditional();
3744 Diag(ElifToken, diag::pp_err_elif_after_else) << DirKind;
3749 Callbacks->Elif(ElifToken.
getLocation(), ConditionRange,
3752 case tok::pp_elifdef:
3755 case tok::pp_elifndef:
3759 assert(
false &&
"unexpected directive kind");
3764 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3767 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3770 CurPPLexer->pushConditionalLevel(ElifToken.
getLocation(),
false,
3776 SkipExcludedConditionalBlock(
3781std::optional<LexEmbedParametersResult>
3784 tok::TokenKind EndTokenKind = ForHasEmbed ? tok::r_paren : tok::eod;
3786 auto DiagMismatchedBracesAndSkipToEOD =
3788 std::pair<tok::TokenKind, SourceLocation> Matches) {
3790 Diag(Matches.second, diag::note_matching) << Matches.first;
3791 if (CurTok.
isNot(tok::eod))
3796 if (CurTok.
isNot(Kind)) {
3797 Diag(CurTok, diag::err_expected) << Kind;
3798 if (CurTok.
isNot(tok::eod))
3815 auto LexPPParameterName = [&]() -> std::optional<std::string> {
3818 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3819 return std::nullopt;
3826 if (CurTok.
is(tok::coloncolon)) {
3829 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3830 return std::nullopt;
3836 return (llvm::Twine(Prefix->
getName()) +
"::" + Suffix->
getName()).str();
3838 return Prefix->
getName().str();
3845 auto NormalizeParameterName = [](StringRef Name) {
3846 if (Name.size() > 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
3847 return Name.substr(2, Name.size() - 4);
3851 auto LexParenthesizedIntegerExpr = [&]() -> std::optional<size_t> {
3854 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3855 return std::nullopt;
3860 bool EvaluatedDefined;
3861 DirectiveEvalResult LimitEvalResult = EvaluateDirectiveExpression(
3862 ParameterIfNDef, CurTok, EvaluatedDefined,
false);
3864 if (!LimitEvalResult.Value) {
3867 assert(CurTok.
is(tok::eod) &&
"expect to be at the end of directive");
3868 return std::nullopt;
3871 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3872 return std::nullopt;
3879 if (EvaluatedDefined) {
3880 Diag(CurTok, diag::err_defined_in_pp_embed);
3881 return std::nullopt;
3884 if (LimitEvalResult.Value) {
3885 const llvm::APSInt &
Result = *LimitEvalResult.Value;
3886 if (
Result.isNegative()) {
3887 Diag(CurTok, diag::err_requires_positive_value)
3889 if (CurTok.
isNot(EndTokenKind))
3891 return std::nullopt;
3893 return Result.getLimitedValue();
3895 return std::nullopt;
3901 return tok::r_paren;
3903 return tok::r_brace;
3905 return tok::r_square;
3907 llvm_unreachable(
"should not get here");
3911 auto LexParenthesizedBalancedTokenSoup =
3913 std::vector<std::pair<tok::TokenKind, SourceLocation>> BracketStack;
3916 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3920 bool WaitingForInnerCloseParen =
false;
3921 while (CurTok.
isNot(tok::eod) &&
3922 (WaitingForInnerCloseParen || CurTok.
isNot(tok::r_paren))) {
3927 WaitingForInnerCloseParen =
true;
3934 WaitingForInnerCloseParen =
false;
3937 case tok::r_square: {
3938 if (BracketStack.empty()) {
3939 ExpectOrDiagAndSkipToEOD(tok::r_paren);
3943 GetMatchingCloseBracket(BracketStack.back().first);
3944 if (CurTok.
getKind() != Matching) {
3945 DiagMismatchedBracesAndSkipToEOD(Matching, BracketStack.back());
3948 BracketStack.pop_back();
3951 Tokens.push_back(CurTok);
3956 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3964 while (!CurTok.
isOneOf(EndTokenKind, tok::eod)) {
3966 std::optional<std::string> ParamName = LexPPParameterName();
3968 return std::nullopt;
3969 StringRef
Parameter = NormalizeParameterName(*ParamName);
3976 if (
Result.MaybeLimitParam)
3979 std::optional<size_t> Limit = LexParenthesizedIntegerExpr();
3981 return std::nullopt;
3984 }
else if (
Parameter ==
"clang::offset") {
3985 if (
Result.MaybeOffsetParam)
3988 std::optional<size_t> Offset = LexParenthesizedIntegerExpr();
3990 return std::nullopt;
3994 if (
Result.MaybePrefixParam)
3998 if (!LexParenthesizedBalancedTokenSoup(Soup))
3999 return std::nullopt;
4001 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
4003 if (
Result.MaybeSuffixParam)
4007 if (!LexParenthesizedBalancedTokenSoup(Soup))
4008 return std::nullopt;
4010 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
4012 if (
Result.MaybeIfEmptyParam)
4016 if (!LexParenthesizedBalancedTokenSoup(Soup))
4017 return std::nullopt;
4019 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
4021 ++
Result.UnrecognizedParams;
4025 if (CurTok.
is(tok::l_paren)) {
4027 if (!LexParenthesizedBalancedTokenSoup(Soup))
4028 return std::nullopt;
4031 Diag(ParamStartLoc, diag::err_pp_unknown_parameter) << 1 <<
Parameter;
4032 if (CurTok.
isNot(EndTokenKind))
4034 return std::nullopt;
4041void Preprocessor::HandleEmbedDirectiveImpl(
4043 StringRef BinaryContents, StringRef
FileName) {
4044 if (BinaryContents.empty()) {
4052 size_t TokCount = Toks.size();
4053 auto NewToks = std::make_unique<Token[]>(TokCount);
4054 llvm::copy(Toks, NewToks.get());
4055 EnterTokenStream(std::move(NewToks), TokCount,
true,
true);
4062 size_t TotalNumToks = 1 + NumPrefixToks + NumSuffixToks;
4064 auto Toks = std::make_unique<Token[]>(TotalNumToks);
4069 CurIdx += NumPrefixToks;
4072 EmbedAnnotationData *
Data =
new (BP) EmbedAnnotationData;
4073 Data->BinaryData = BinaryContents;
4076 Toks[CurIdx].startToken();
4077 Toks[CurIdx].setKind(tok::annot_embed);
4078 Toks[CurIdx].setAnnotationRange(HashLoc);
4079 Toks[CurIdx++].setAnnotationValue(
Data);
4084 CurIdx += NumSuffixToks;
4087 assert(CurIdx == TotalNumToks &&
"Calculated the incorrect number of tokens");
4088 EnterTokenStream(std::move(Toks), TotalNumToks,
true,
true);
4095 Diag(EmbedTok, diag::warn_compat_pp_embed_directive);
4097 Diag(EmbedTok, diag::ext_pp_embed_directive)
4098 << (LangOpts.CPlusPlus ? 1 : 0);
4105 if (FilenameTok.
isNot(tok::header_name)) {
4107 if (FilenameTok.
isNot(tok::eod))
4120 std::optional<LexEmbedParametersResult> Params =
4123 assert((Params || CurTok.
is(tok::eod)) &&
4124 "expected success or to be at the end of the directive");
4129 SmallString<128> FilenameBuffer;
4130 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
4131 StringRef OriginalFilename = Filename;
4137 if (Filename.empty())
4142 if (!MaybeFileRef) {
4144 if (Callbacks && Callbacks->EmbedFileNotFound(Filename)) {
4147 Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
4152 Diag(FilenameTok, diag::err_pp_embed_device_file) << Filename;
4156 std::optional<llvm::MemoryBufferRef> MaybeFile =
4160 Diag(FilenameTok, diag::err_cannot_open_file)
4161 << Filename <<
"a buffer to the contents could not be created";
4164 StringRef BinaryContents = MaybeFile->getBuffer();
4169 if (Params->MaybeOffsetParam) {
4174 BinaryContents = BinaryContents.substr(Params->MaybeOffsetParam->Offset);
4177 if (Params->MaybeLimitParam) {
4181 BinaryContents = BinaryContents.substr(0, Params->MaybeLimitParam->Limit);
4185 Callbacks->EmbedDirective(HashLoc, Filename, isAngled, MaybeFileRef,
4194 void *Mem = BP.Allocate(OriginalFilename.size(),
alignof(
char *));
4195 memcpy(Mem, OriginalFilename.data(), OriginalFilename.size());
4196 StringRef FilenameToGo =
4197 StringRef(
static_cast<char *
>(Mem), OriginalFilename.size());
4198 HandleEmbedDirectiveImpl(HashLoc, *Params, BinaryContents, FilenameToGo);
4211 assert(
getLangOpts().CPlusPlusModules && ImportTok.
is(tok::kw_import));
4213 this->ImportingCXXNamedModules,
true);
4217 if (
Tok.isNot(tok::eod))
4225 bool ImportingHeader =
false;
4226 bool IsPartition =
false;
4228 switch (
Tok.getKind()) {
4229 case tok::header_name:
4230 ImportingHeader =
true;
4231 DirToks.push_back(
Tok);
4232 Lex(DirToks.emplace_back());
4236 DirToks.push_back(
Tok);
4237 UseLoc =
Tok.getLocation();
4240 case tok::identifier: {
4242 Path, DirToks,
true,
4246 std::string FlatName;
4248 (IsPartition && ModuleDeclState.isNamedModule()) || !IsPartition;
4249 if (Callbacks && IsValid) {
4250 if (IsPartition && ModuleDeclState.isNamedModule()) {
4251 FlatName += ModuleDeclState.getPrimaryName();
4256 SourceLocation StartLoc = IsPartition ? UseLoc : Path[0].getLoc();
4268 DirToks.push_back(
Tok);
4274 if (!DirToks.back().isOneOf(tok::semi, tok::eod))
4277 if (DirToks.back().isNot(tok::eod))
4283 if (DirToks.back().isNot(tok::semi)) {
4288 if (ImportingHeader) {
4294 Diag(SemiLoc, diag::err_header_import_semi_in_macro);
4296 auto Action = HandleHeaderIncludeOrImport(
4298 switch (Action.Kind) {
4299 case ImportAction::None:
4302 case ImportAction::ModuleBegin:
4304 DirToks.emplace_back();
4305 DirToks.back().startToken();
4306 DirToks.back().setKind(tok::annot_module_begin);
4307 DirToks.back().setLocation(SemiLoc);
4308 DirToks.back().setAnnotationEndLoc(SemiLoc);
4309 DirToks.back().setAnnotationValue(Action.ModuleForHeader);
4312 case ImportAction::ModuleImport:
4313 case ImportAction::HeaderUnitImport:
4314 case ImportAction::SkippedModuleImport:
4317 DirToks[1].setKind(tok::annot_header_unit);
4318 DirToks[1].setAnnotationEndLoc(DirToks[0].getLocation());
4319 DirToks[1].setAnnotationValue(Action.ModuleForHeader);
4322 case ImportAction::Failure:
4323 assert(TheModuleLoader.HadFatalFailure &&
4324 "This should be an early exit only to a fatal error");
4325 CurLexer->cutOffLexing();
4354 assert(
getLangOpts().CPlusPlusModules && ModuleTok.
is(tok::kw_module));
4363 switch (
Tok.getKind()) {
4366 DirToks.push_back(
Tok);
4369 DirToks.push_back(
Tok);
4371 if (
Tok.isNot(tok::kw_private)) {
4372 if (
Tok.isNot(tok::eod))
4378 DirToks.push_back(
Tok);
4380 case tok::identifier: {
4382 Path, DirToks,
false,
4389 if (
Tok.is(tok::colon)) {
4392 Tok, Partition, DirToks,
4403 if (
Tok.is(tok::identifier) &&
4405 std::unique_ptr<Token[]> TokCopy = std::make_unique<Token[]>(1);
4407 EnterTokenStream(std::move(TokCopy), 1,
4410 DirToks.back() =
Tok;
4415 DirToks.push_back(
Tok);
4421 std::optional<Token> NextPPTok =
4422 DirToks.back().is(tok::eod) ? peekNextPPToken() : DirToks.back();
4427 if (NextPPTok->is(tok::raw_identifier))
4429 if (!NextPPTok->isOneOf(tok::semi, tok::eod, tok::l_square,
4431 Diag(*NextPPTok, diag::err_pp_unexpected_tok_after_module_name)
4435 if (!DirToks.back().isOneOf(tok::semi, tok::eod)) {
4442 DirToks.back().isNot(tok::eod)
4446 : DirToks.pop_back_val().getLocation();
4448 if (!IncludeMacroStack.empty()) {
4449 Diag(StartLoc, diag::err_pp_module_decl_in_header)
4453 if (CurPPLexer->getConditionalStackDepth() != 0) {
4454 Diag(StartLoc, diag::err_pp_cond_span_module_decl)
4472void Preprocessor::HandleObjCImportDirective(
Token &AtTok,
Token &ImportTok) {
4475 ImportTok.
setKind(tok::kw_import);
4490 if (!DirToks.back().isOneOf(tok::semi, tok::eod))
4494 DirToks.back().isNot(tok::eod)
4498 : DirToks.pop_back_val().getLocation();
4500 Module *Imported =
nullptr;
4509 Callbacks->moduleImport(ModuleImportLoc, Path, Imported);
static bool isInMainFile(const clang::Diagnostic &D)
Defines interfaces for clang::DirectoryEntry and clang::DirectoryEntryRef.
Defines the clang::FileManager interface and associated types.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Defines the clang::LangOptions interface.
Defines the clang::MacroInfo and clang::MacroDirective classes.
Defines the clang::Module class, which describes a module in the source code.
Defines the PPCallbacks interface.
static bool ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit, SrcMgr::CharacteristicKind &FileKind, Preprocessor &PP)
ReadLineMarkerFlags - Parse and validate any flags at the end of a GNU line marker directive.
static bool isConfigurationPattern(Token &MacroName, MacroInfo *MI, const LangOptions &LOptions)
static void diagnoseAutoModuleImport(Preprocessor &PP, SourceLocation HashLoc, Token &IncludeTok, ArrayRef< IdentifierLoc > Path, SourceLocation PathEnd)
Produce a diagnostic informing the user that a include or similar was implicitly treated as a module ...
static std::optional< StringRef > findSimilarStr(StringRef LHS, const std::vector< StringRef > &Candidates)
Find a similar string in Candidates.
static bool isLanguageDefinedBuiltin(const SourceManager &SourceMgr, const MacroInfo *MI, const StringRef MacroName)
static bool trySimplifyPath(SmallVectorImpl< StringRef > &Components, StringRef RealPathName, llvm::sys::path::Style Separator)
static bool warnByDefaultOnWrongCase(StringRef Include)
MacroDiag
Enumerates possible cases of define/undef a reserved identifier.
@ MD_ReservedAttributeIdentifier
static bool isFeatureTestMacro(StringRef MacroName)
static bool GetLineValue(Token &DigitTok, unsigned &Val, unsigned DiagID, Preprocessor &PP, bool IsGNULineDirective=false)
GetLineValue - Convert a numeric token into an unsigned value, emitting Diagnostic DiagID if it is in...
PPElifDiag
Enumerates possible select values for the pp_err_elif_after_else and pp_err_elif_without_if diagnosti...
static bool isReservedCXXAttributeName(Preprocessor &PP, IdentifierInfo *II)
static MacroDiag shouldWarnOnMacroUndef(Preprocessor &PP, IdentifierInfo *II)
static bool isObjCProtectedMacro(const IdentifierInfo *II)
static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II)
Defines the clang::Preprocessor interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines the clang::SourceLocation class and associated facilities.
static bool isInvalid(LocType Loc, bool *Invalid)
Defines the SourceManager interface.
Defines the clang::TokenKind enum and support functions.
VerifyDiagnosticConsumer::Directive Directive
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
__device__ __2f16 float c
ResetMacroExpansionHelper(Preprocessor *pp)
~ResetMacroExpansionHelper()
static AttrArgsInfo getCXX11AttrArgsInfo(const IdentifierInfo *Name)
Represents a byte-granular source range.
static CharSourceRange getCharRange(SourceRange R)
virtual void CodeCompleteMacroName(bool IsDefinition)
Callback invoked when performing code completion in a context where the name of a macro is expected.
A directive for a defined macro or a macro imported from a module.
Concrete class used by the front-end to report problems and issues.
A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...
StringRef getName() const
bool isDeviceFile() const
const FileEntry & getFileEntry() const
DirectoryEntryRef getDir() const
Cached information about one file (either on disk or in the virtual file system).
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements support for file system lookup, file system caching, and directory search management.
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 hasLeadingSpace() const
Return true if this token has whitespace before it.
bool isNot(tok::TokenKind K) const
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix.
bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const
Return true if we have an ObjC keyword identifier.
void startToken()
Reset all flags to cleared.
bool needsCleaning() const
Return true if this token has trigraphs or escaped newlines in it.
StringRef getRawIdentifier() const
getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode),...
A directive for an undefined macro.
A directive for setting the module visibility of a macro.
Defines the clang::TargetInfo interface.
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
uint32_t Literal
Literals are represented as positive integers.
bool Sub(InterpState &S, CodePtr OpPC)
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
PPKeywordKind
Provides a namespace for preprocessor keywords which start with a '#' at the beginning of the line.
The JSON file list parser is used to communicate input to InstallAPI.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
bool isReservedInAllContexts(ReservedIdentifierStatus Status)
Determine whether an identifier is reserved in all contexts.
int hasAttribute(AttributeCommonInfo::Syntax Syntax, llvm::StringRef ScopeName, llvm::StringRef AttrName, const TargetInfo &Target, const LangOptions &LangOpts, bool CheckPlugins)
Return the version number associated with the attribute if we recognize and implement the attribute s...
ArrayRef< IdentifierLoc > ModuleIdPath
A sequence of identifier/location pairs used to describe a particular module or submodule,...
LLVM_READONLY char toLowercase(char c)
Converts the given ASCII character to its lowercase equivalent.
detail::SearchDirIteratorImpl< true > ConstSearchDirIterator
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
MacroUse
Context in which macro name is used.
LLVM_READONLY bool isAlphanumeric(unsigned char c)
Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Parameter
The parameter type of a method or function.
@ Result
The result type of a method or function.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
LLVM_READONLY bool isLowercase(unsigned char c)
Return true if this character is a lowercase ASCII letter: [a-z].
@ PIK_HashPragma
The pragma was introduced via #pragma.
OptionalDirectoryEntryRef Directory
The directory entry which should be used for the cached framework.
std::optional< PPEmbedParameterIfEmpty > MaybeIfEmptyParam
size_t SuffixTokenCount() const
std::optional< PPEmbedParameterSuffix > MaybeSuffixParam
std::optional< PPEmbedParameterPrefix > MaybePrefixParam
size_t PrefixTokenCount() const
bool FoundNonSkip
True if we have emitted tokens already, and now we're in an #else block or something.
SourceLocation IfLoc
Location where the conditional started.
bool WasSkipping
True if this was contained in a skipping directive, e.g., in a "\#if 0" block.
bool FoundElse
True if we've seen a #else in this block.