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)) {
1199 Filename, OpenFile,
true,
false);
1200 return llvm::expectedToOptional(std::move(ShouldBeEntry));
1204 StringRef StartingFrom, StringRef
FileName,
1205 bool RemoveInitialFileComponentFromLookupPath) {
1206 llvm::sys::path::native(StartingFrom, LookupPath);
1207 if (RemoveInitialFileComponentFromLookupPath)
1208 llvm::sys::path::remove_filename(LookupPath);
1209 if (!LookupPath.empty() &&
1210 !llvm::sys::path::is_separator(LookupPath.back())) {
1211 LookupPath.push_back(llvm::sys::path::get_separator().front());
1221 if (LookupFromFile) {
1225 llvm::sys::path::append(TmpDir, Filename);
1226 if (!TmpDir.empty()) {
1228 TmpDir, OpenFile,
true,
false);
1230 return llvm::expectedToOptional(std::move(ShouldBeEntry));
1231 llvm::consumeError(ShouldBeEntry.takeError());
1238 if (MaybeWorkingDirEntry) {
1240 StringRef WorkingDir = WorkingDirEntry.
getName();
1241 if (!WorkingDir.empty()) {
1242 SeparateComponents(LookupPath, WorkingDir, Filename,
false);
1244 LookupPath, OpenFile,
true,
false);
1246 return llvm::expectedToOptional(std::move(ShouldBeEntry));
1247 llvm::consumeError(ShouldBeEntry.takeError());
1252 for (
const auto &Entry : PPOpts.EmbedEntries) {
1254 SeparateComponents(LookupPath, Entry, Filename,
false);
1256 LookupPath, OpenFile,
true,
false);
1258 return llvm::expectedToOptional(std::move(ShouldBeEntry));
1259 llvm::consumeError(ShouldBeEntry.takeError());
1261 return std::nullopt;
1271 : PP(pp), save(pp->DisableMacroExpansion) {
1272 if (pp->MacroExpansionInDirectivesOverride)
1273 pp->DisableMacroExpansion =
false;
1277 PP->DisableMacroExpansion = save;
1295 return HandleDefineDirective(
Result,
1298 if (SkippingUntilPCHThroughHeader &&
1300 return HandleIncludeDirective(HashLoc,
Result);
1302 if (SkippingUntilPragmaHdrStop && II->
getPPKeywordID() == tok::pp_pragma) {
1304 auto *II =
Result.getIdentifierInfo();
1305 if (II && II->
getName() ==
"hdrstop")
1322 CurPPLexer->ParsingPreprocessorDirective =
true;
1323 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
1325 bool ImmediatelyAfterTopLevelIfndef =
1326 CurPPLexer->MIOpt.getImmediatelyAfterTopLevelIfndef();
1327 CurPPLexer->MIOpt.resetImmediatelyAfterTopLevelIfndef();
1334 bool ReadAnyTokensBeforeDirective =CurPPLexer->MIOpt.getHasReadAnyTokensVal();
1342 if (Introducer.
is(tok::hash))
1356 case tok::pp_include:
1357 case tok::pp_import:
1358 case tok::pp_include_next:
1359 case tok::pp___include_macros:
1360 case tok::pp_pragma:
1362 case tok::pp_module:
1363 case tok::pp___preprocessed_module:
1364 case tok::pp___preprocessed_import:
1370 Diag(*ArgMacro, diag::note_macro_expansion_here)
1371 << ArgMacro->getIdentifierInfo();
1385 if (SkippingUntilPCHThroughHeader || SkippingUntilPragmaHdrStop)
1389 switch (
Result.getKind()) {
1394 CurPPLexer->MIOpt.SetReadToken(ReadAnyTokensBeforeDirective);
1396 case tok::code_completion:
1399 CodeComplete->CodeCompleteDirective(
1400 CurPPLexer->getConditionalStackDepth() > 0);
1402 case tok::numeric_constant:
1409 return HandleDigitDirective(
Result);
1419 return HandleIfDirective(
Result, Introducer,
1420 ReadAnyTokensBeforeDirective);
1422 return HandleIfdefDirective(
Result, Introducer,
false,
1424 case tok::pp_ifndef:
1425 return HandleIfdefDirective(
Result, Introducer,
true,
1426 ReadAnyTokensBeforeDirective);
1428 case tok::pp_elifdef:
1429 case tok::pp_elifndef:
1430 return HandleElifFamilyDirective(
Result, Introducer,
1434 return HandleElseDirective(
Result, Introducer);
1436 return HandleEndifDirective(
Result);
1439 case tok::pp_include:
1442 case tok::pp___include_macros:
1447 case tok::pp_define:
1448 return HandleDefineDirective(
Result, ImmediatelyAfterTopLevelIfndef);
1450 return HandleUndefDirective();
1454 return HandleLineDirective();
1458 return HandleUserDiagnosticDirective(
Result,
false);
1461 case tok::pp_pragma:
1463 case tok::pp_module:
1464 case tok::pp___preprocessed_module:
1466 case tok::pp___preprocessed_import:
1469 case tok::pp_import:
1475 case tok::pp_include_next:
1478 case tok::pp_warning:
1479 if (LangOpts.CPlusPlus)
1481 ? diag::warn_cxx23_compat_warning_directive
1482 : diag::ext_pp_warning_directive)
1485 Diag(
Result, LangOpts.C23 ? diag::warn_c23_compat_warning_directive
1486 : diag::ext_pp_warning_directive)
1489 return HandleUserDiagnosticDirective(
Result,
true);
1491 return HandleIdentSCCSDirective(
Result);
1493 return HandleIdentSCCSDirective(
Result);
1496 case tok::pp_assert:
1499 case tok::pp_unassert:
1503 case tok::pp___public_macro:
1505 return HandleMacroPublicDirective(
Result);
1508 case tok::pp___private_macro:
1510 return HandleMacroPrivateDirective();
1521 auto Toks = std::make_unique<Token[]>(2);
1523 Toks[0] = Introducer;
1528 if (
Result.is(tok::hashhash))
1529 Toks[1].setKind(tok::unknown);
1534 EnterTokenStream(std::move(Toks), 2,
false,
false);
1540 Diag(
Result, diag::err_pp_invalid_directive) << 0;
1552 bool IsGNULineDirective=
false) {
1553 if (DigitTok.
isNot(tok::numeric_constant)) {
1554 PP.
Diag(DigitTok, DiagID);
1556 if (DigitTok.
isNot(tok::eod))
1562 IntegerBuffer.resize(DigitTok.
getLength());
1563 const char *DigitTokBegin = &IntegerBuffer[0];
1573 for (
unsigned i = 0; i != ActualLength; ++i) {
1576 if (DigitTokBegin[i] ==
'\'')
1579 if (!
isDigit(DigitTokBegin[i])) {
1581 diag::err_pp_line_digit_sequence) << IsGNULineDirective;
1586 unsigned NextVal = Val*10+(DigitTokBegin[i]-
'0');
1587 if (NextVal < Val) {
1588 PP.
Diag(DigitTok, DiagID);
1595 if (DigitTokBegin[0] ==
'0' && Val)
1597 << IsGNULineDirective;
1609void Preprocessor::HandleLineDirective() {
1617 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*
this))
1621 Diag(DigitTok, diag::ext_pp_line_zero);
1625 unsigned LineLimit = 32768U;
1626 if (LangOpts.C99 || LangOpts.CPlusPlus11)
1627 LineLimit = 2147483648U;
1628 if (LineNo >= LineLimit)
1629 Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
1630 else if (LangOpts.CPlusPlus11 && LineNo >= 32768U)
1631 Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
1633 int FilenameID = -1;
1639 if (StrTok.
is(tok::eod))
1641 else if (StrTok.
isNot(tok::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 =
2502 if (MaybeTranslateInclude && (UsableHeaderUnit || UsableClangHeaderModule)) {
2510 diag::note_implicit_top_level_module_import_here)
2512 return {ImportAction::None};
2518 SmallVector<IdentifierLoc, 2> Path;
2519 for (
Module *Mod = ModuleToImport; Mod; Mod = Mod->Parent)
2522 std::reverse(Path.begin(), Path.end());
2532 ModuleLoadResult Imported = TheModuleLoader.loadModule(
2535 assert((Imported ==
nullptr || Imported == ModuleToImport) &&
2536 "the imported module is different than the suggested one");
2542 static_cast<Module *
>(Imported)->getTopLevelModule());
2547 ModuleToImport =
nullptr;
2555 Token &
Result = IncludeTok;
2556 assert(CurLexer &&
"#include but no current lexer set!");
2558 CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
2559 CurLexer->cutOffLexing();
2561 return {ImportAction::None};
2569 SourceMgr.getFileCharacteristic(FilenameTok.
getLocation());
2571 FileCharacter = std::max(HeaderInfo.getFileDirFlavor(*
File), FileCharacter);
2582 bool IsFirstIncludeOfFile =
false;
2586 if (Action == Enter &&
File &&
2587 !HeaderInfo.ShouldEnterIncludeFile(*
this, *
File, EnterOnce,
2589 IsFirstIncludeOfFile)) {
2600 if (UsableHeaderUnit && !
getLangOpts().CompilingPCH)
2601 Action = TrackGMFState.inGMF() ?
Import :
Skip;
2603 Action = (ModuleToImport && !
getLangOpts().CompilingPCH) ? Import :
Skip;
2611 if (Action == Enter &&
File && PreambleConditionalStack.isRecording() &&
2612 SourceMgr.isMainFile(
File->getFileEntry())) {
2614 diag::err_pp_including_mainfile_in_preamble);
2615 return {ImportAction::None};
2618 if (Callbacks && !IsImportDecl) {
2621 Callbacks->InclusionDirective(HashLoc, IncludeTok, LookupFilename, isAngled,
2622 FilenameRange,
File, SearchPath, RelativePath,
2623 SuggestedModule.
getModule(), Action == Import,
2626 Callbacks->FileSkipped(*
File, FilenameTok, FileCharacter);
2630 return {ImportAction::None};
2634 if (IsImportDecl && !ModuleToImport) {
2635 Diag(FilenameTok, diag::err_header_import_not_header_unit)
2636 << OriginalFilename <<
File->getName();
2637 return {ImportAction::None};
2642 const bool CheckIncludePathPortability =
2643 !IsMapped && !
File->getFileEntry().tryGetRealPathName().empty();
2645 if (CheckIncludePathPortability) {
2646 StringRef Name = LookupFilename;
2647 StringRef NameWithoriginalSlashes = Filename;
2651 bool NameWasUNC = Name.consume_front(
"\\\\?\\");
2652 NameWithoriginalSlashes.consume_front(
"\\\\?\\");
2654 StringRef RealPathName =
File->getFileEntry().tryGetRealPathName();
2655 SmallVector<StringRef, 16> Components(llvm::sys::path::begin(Name),
2656 llvm::sys::path::end(Name));
2668 SmallString<128> FixedDriveRealPath;
2669 if (llvm::sys::path::is_absolute(Name) &&
2670 llvm::sys::path::is_absolute(RealPathName) &&
2673 assert(Components.size() >= 3 &&
"should have drive, backslash, name");
2674 assert(Components[0].size() == 2 &&
"should start with drive");
2675 assert(Components[0][1] ==
':' &&
"should have colon");
2676 FixedDriveRealPath = (Name.substr(0, 1) + RealPathName.substr(1)).str();
2677 RealPathName = FixedDriveRealPath;
2682 SmallString<128> Path;
2683 Path.reserve(Name.size()+2);
2684 Path.push_back(isAngled ?
'<' :
'"');
2686 const auto IsSep = [BackslashStyle](
char c) {
2687 return llvm::sys::path::is_separator(
c, BackslashStyle);
2690 for (
auto Component : Components) {
2702 if (!(Component.size() == 1 && IsSep(Component[0])))
2703 Path.append(Component);
2704 else if (Path.size() != 1)
2708 if (Path.size() > NameWithoriginalSlashes.size()) {
2709 Path.push_back(isAngled ?
'>' :
'"');
2712 assert(IsSep(NameWithoriginalSlashes[Path.size()-1]));
2714 Path.push_back(NameWithoriginalSlashes[Path.size()-1]);
2715 while (Path.size() <= NameWithoriginalSlashes.size() &&
2716 IsSep(NameWithoriginalSlashes[Path.size()-1]));
2722 Path = (Path.substr(0, 1) +
"\\\\?\\" + Path.substr(1)).str();
2729 ? diag::pp_nonportable_path
2730 : diag::pp_nonportable_system_path;
2731 Diag(FilenameTok, DiagId) << Path <<
2740 return {ImportAction::SkippedModuleImport, ModuleToImport};
2741 return {ImportAction::None};
2743 case IncludeLimitReached:
2746 return {ImportAction::None};
2750 assert(ModuleToImport &&
"no module to import");
2755 tok::pp___include_macros)
2756 return {ImportAction::None};
2758 return {ImportAction::ModuleImport, ModuleToImport};
2766 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
2767 Diag(FilenameTok, diag::err_pp_include_too_deep);
2768 HasReachedMaxIncludeDepth =
true;
2769 return {ImportAction::None};
2773 Diag(FilenameTok, diag::warn_pp_include_angled_in_module_purview)
2777 SourceLocation IncludePos = FilenameTok.
getLocation();
2781 IncludePos = SourceMgr.getExpansionRange(IncludePos).getEnd();
2782 FileID FID = SourceMgr.createFileID(*
File, IncludePos, FileCharacter);
2784 TheModuleLoader.HadFatalFailure =
true;
2785 return ImportAction::Failure;
2790 IsFirstIncludeOfFile))
2791 return {ImportAction::None};
2795 if (ModuleToImport && !ModuleToImport->
isHeaderUnit()) {
2800 diag::err_module_build_shadowed_submodule)
2803 diag::note_previous_definition);
2804 return {ImportAction::None};
2816 return {ImportAction::None};
2818 assert(!CurLexerSubmodule &&
"should not have marked this as a module yet");
2819 CurLexerSubmodule = ModuleToImport;
2829 return {ImportAction::ModuleBegin, ModuleToImport};
2832 assert(!IsImportDecl &&
"failed to diagnose missing module for import decl");
2833 return {ImportAction::None};
2838void Preprocessor::HandleIncludeNextDirective(
SourceLocation HashLoc,
2839 Token &IncludeNextTok) {
2840 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
2843 const FileEntry *LookupFromFile;
2844 std::tie(Lookup, LookupFromFile) = getIncludeNextStart(IncludeNextTok);
2846 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
2851void Preprocessor::HandleMicrosoftImportDirective(
Token &
Tok) {
2857 Diag(
Tok, diag::err_pp_import_directive_ms );
2868 if (!LangOpts.ObjC) {
2869 if (LangOpts.MSVCCompat)
2870 return HandleMicrosoftImportDirective(ImportTok);
2871 Diag(ImportTok, diag::ext_pp_import_directive);
2873 return HandleIncludeDirective(HashLoc, ImportTok);
2880void Preprocessor::HandleIncludeMacrosDirective(
SourceLocation HashLoc,
2881 Token &IncludeMacrosTok) {
2884 SourceLocation Loc = IncludeMacrosTok.
getLocation();
2885 if (SourceMgr.getBufferName(Loc) !=
"<built-in>") {
2887 diag::pp_include_macros_out_of_predefines);
2894 HandleIncludeDirective(HashLoc, IncludeMacrosTok);
2899 assert(TmpTok.
isNot(tok::eof) &&
"Didn't find end of -imacros!");
2900 }
while (TmpTok.
isNot(tok::hashhash));
2922 Diag(
Tok, diag::err_pp_expected_ident_in_arg_list);
2926 Diag(
Tok, LangOpts.CPlusPlus11 ?
2927 diag::warn_cxx98_compat_variadic_macro :
2928 diag::ext_variadic_macro);
2931 if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus) {
2932 Diag(
Tok, diag::ext_pp_opencl_variadic_macros);
2938 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2947 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2955 Diag(
Tok, diag::err_pp_invalid_tok_in_arg_list);
2961 if (llvm::is_contained(Parameters, II)) {
2962 Diag(
Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
2974 Diag(
Tok, diag::err_pp_expected_comma_in_arg_list);
2983 Diag(
Tok, diag::ext_named_variadic_macro);
2988 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
3018 StringRef ValueText = II->
getName();
3019 StringRef TrimmedValue = ValueText;
3020 if (!ValueText.starts_with(
"__")) {
3021 if (ValueText.starts_with(
"_"))
3022 TrimmedValue = TrimmedValue.drop_front(1);
3026 TrimmedValue = TrimmedValue.drop_front(2);
3027 if (TrimmedValue.ends_with(
"__"))
3028 TrimmedValue = TrimmedValue.drop_back(2);
3030 return TrimmedValue == MacroText;
3037 return MacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
3050MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
3051 const Token &MacroNameTok,
const bool ImmediatelyAfterHeaderGuard) {
3053 Token LastTok = MacroNameTok;
3061 llvm::scope_exit _([&]() {
3063 if (CurLexer->ParsingPreprocessorDirective)
3074 if (
Tok.
is(tok::eod)) {
3075 if (ImmediatelyAfterHeaderGuard) {
3085 }
else if (
Tok.
is(tok::l_paren)) {
3088 if (ReadMacroParameterList(MI, LastTok))
3102 }
else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
3105 Diag(
Tok, diag::ext_c99_whitespace_required_after_macro_name);
3114 if (
Tok.
is(tok::at))
3116 else if (
Tok.
is(tok::unknown)) {
3123 Diag(
Tok, diag::ext_missing_whitespace_after_macro_name);
3125 Diag(
Tok, diag::warn_missing_whitespace_after_macro_name);
3128 if (!
Tok.
is(tok::eod))
3131 SmallVector<Token, 16> Tokens;
3138 Tokens.push_back(
Tok);
3152 if (!
Tok.
isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
3153 Tokens.push_back(
Tok);
3155 if (VAOCtx.isVAOptToken(
Tok)) {
3157 if (VAOCtx.isInVAOpt()) {
3158 Diag(
Tok, diag::err_pp_vaopt_nested_use);
3164 Diag(
Tok, diag::err_pp_missing_lparen_in_vaopt_use);
3167 Tokens.push_back(
Tok);
3170 if (
Tok.
is(tok::hashhash)) {
3171 Diag(
Tok, diag::err_vaopt_paste_at_start);
3175 }
else if (VAOCtx.isInVAOpt()) {
3176 if (
Tok.
is(tok::r_paren)) {
3177 if (VAOCtx.sawClosingParen()) {
3178 assert(Tokens.size() >= 3 &&
3179 "Must have seen at least __VA_OPT__( "
3180 "and a subsequent tok::r_paren");
3181 if (Tokens[Tokens.size() - 2].is(tok::hashhash)) {
3182 Diag(
Tok, diag::err_vaopt_paste_at_end);
3186 }
else if (
Tok.
is(tok::l_paren)) {
3200 Tokens.push_back(
Tok);
3207 if (
Tok.
is(tok::hashhash)) {
3215 if (
Tok.
is(tok::eod)) {
3216 Tokens.push_back(LastTok);
3221 Tokens[Tokens.size() - 1].is(tok::comma))
3225 Tokens.push_back(LastTok);
3234 if (!VAOCtx.isVAOptToken(
Tok) &&
3243 LastTok.
setKind(tok::unknown);
3244 Tokens.push_back(LastTok);
3247 Diag(
Tok, diag::err_pp_stringize_not_parameter)
3248 << LastTok.
is(tok::hashat);
3254 Tokens.push_back(LastTok);
3259 if (!VAOCtx.isVAOptToken(
Tok)) {
3260 Tokens.push_back(
Tok);
3267 if (VAOCtx.isInVAOpt()) {
3268 assert(
Tok.
is(tok::eod) &&
"Must be at End Of preprocessing Directive");
3269 Diag(
Tok, diag::err_pp_expected_after)
3270 << LastTok.
getKind() << tok::r_paren;
3271 Diag(VAOCtx.getUnmatchedOpeningParenLoc(), diag::note_matching) << tok::l_paren;
3282 return II->
isStr(
"__strong") || II->
isStr(
"__weak") ||
3283 II->
isStr(
"__unsafe_unretained") || II->
isStr(
"__autoreleasing");
3288void Preprocessor::HandleDefineDirective(
3289 Token &DefineTok,
const bool ImmediatelyAfterHeaderGuard) {
3293 bool MacroShadowsKeyword;
3294 ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
3297 if (MacroNameTok.
is(tok::eod))
3304 emitFinalMacroWarning(MacroNameTok,
false);
3308 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
3310 MacroInfo *
const MI = ReadOptionalMacroParameterListAndBody(
3311 MacroNameTok, ImmediatelyAfterHeaderGuard);
3315 if (MacroShadowsKeyword &&
3317 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
3322 if (NumTokens != 0) {
3334 if (SkippingUntilPCHThroughHeader) {
3337 LangOpts.MicrosoftExt))
3341 if (!LangOpts.MicrosoftExt)
3352 emitFinalMacroWarning(MacroNameTok,
false);
3363 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) &&
3365 LangOpts.MicrosoftExt)) {
3376 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) {
3384 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
3388 !MI->
isIdenticalTo(*OtherMI, *
this, LangOpts.MicrosoftExt)) {
3398 DefMacroDirective *MD =
3406 !MacroExpansionInDirectivesOverride &&
3415 Callbacks->MacroDefined(MacroNameTok, MD);
3420void Preprocessor::HandleUndefDirective() {
3424 ReadMacroName(MacroNameTok,
MU_Undef);
3427 if (MacroNameTok.
is(tok::eod))
3436 UndefMacroDirective *Undef =
nullptr;
3439 emitFinalMacroWarning(MacroNameTok,
true);
3449 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
3454 Undef = AllocateUndefMacroDirective(MacroNameTok.
getLocation());
3460 Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
3475void Preprocessor::HandleIfdefDirective(
Token &
Result,
3476 const Token &HashToken,
3478 bool ReadAnyTokensBeforeDirective) {
3480 Token DirectiveTok =
Result;
3483 ReadMacroName(MacroNameTok);
3486 if (MacroNameTok.
is(tok::eod)) {
3489 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3504 if (CurPPLexer->getConditionalStackDepth() == 0) {
3509 if (!ReadAnyTokensBeforeDirective && !MI) {
3510 assert(isIfndef &&
"#ifdef shouldn't reach here");
3511 CurPPLexer->MIOpt.EnterTopLevelIfndef(MII, MacroNameTok.
getLocation());
3513 CurPPLexer->MIOpt.EnterTopLevelConditional();
3522 Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3524 Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3527 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3531 if (PPOpts.SingleFileParseMode && !MI) {
3534 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3537 }
else if (PPOpts.SingleModuleParseMode && !MI) {
3541 SkipExcludedConditionalBlock(
3544 }
else if (!MI == isIfndef || RetainExcludedCB) {
3546 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3551 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3560void Preprocessor::HandleIfDirective(
Token &IfToken,
3561 const Token &HashToken,
3562 bool ReadAnyTokensBeforeDirective) {
3566 IdentifierInfo *IfNDefMacro =
nullptr;
3567 const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
3568 const bool ConditionalTrue = DER.Conditional;
3576 if (CurPPLexer->getConditionalStackDepth() == 0) {
3577 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
3579 CurPPLexer->MIOpt.EnterTopLevelIfndef(IfNDefMacro, IfToken.
getLocation());
3581 CurPPLexer->MIOpt.EnterTopLevelConditional();
3589 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3593 if (PPOpts.SingleFileParseMode && DER.IncludedUndefinedIds) {
3596 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3598 }
else if (PPOpts.SingleModuleParseMode && DER.IncludedUndefinedIds) {
3605 }
else if (ConditionalTrue || RetainExcludedCB) {
3607 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3619void Preprocessor::HandleEndifDirective(
Token &EndifToken) {
3625 PPConditionalInfo CondInfo;
3626 if (CurPPLexer->popConditionalLevel(CondInfo)) {
3628 Diag(EndifToken, diag::err_pp_endif_without_if);
3633 if (CurPPLexer->getConditionalStackDepth() == 0)
3634 CurPPLexer->MIOpt.ExitTopLevelConditional();
3636 assert(!CondInfo.
WasSkipping && !CurPPLexer->LexingRawMode &&
3637 "This code should only be reachable in the non-skipping case!");
3645void Preprocessor::HandleElseDirective(
Token &
Result,
const Token &HashToken) {
3651 PPConditionalInfo CI;
3652 if (CurPPLexer->popConditionalLevel(CI)) {
3658 if (CurPPLexer->getConditionalStackDepth() == 0)
3659 CurPPLexer->MIOpt.EnterTopLevelConditional();
3667 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3670 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3673 CurPPLexer->pushConditionalLevel(CI.
IfLoc,
false,
3681 true,
Result.getLocation());
3685void Preprocessor::HandleElifFamilyDirective(
Token &ElifToken,
3686 const Token &HashToken,
3698 if (LangOpts.CPlusPlus)
3699 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
3700 : diag::ext_cxx23_pp_directive;
3702 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
3703 : diag::ext_c23_pp_directive;
3704 Diag(ElifToken, DiagID) << DirKind;
3715 PPConditionalInfo CI;
3716 if (CurPPLexer->popConditionalLevel(CI)) {
3717 Diag(ElifToken, diag::pp_err_elif_without_if) << DirKind;
3722 if (CurPPLexer->getConditionalStackDepth() == 0)
3723 CurPPLexer->MIOpt.EnterTopLevelConditional();
3727 Diag(ElifToken, diag::pp_err_elif_after_else) << DirKind;
3732 Callbacks->Elif(ElifToken.
getLocation(), ConditionRange,
3735 case tok::pp_elifdef:
3738 case tok::pp_elifndef:
3742 assert(
false &&
"unexpected directive kind");
3747 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3750 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3753 CurPPLexer->pushConditionalLevel(ElifToken.
getLocation(),
false,
3759 SkipExcludedConditionalBlock(
3764std::optional<LexEmbedParametersResult>
3767 tok::TokenKind EndTokenKind = ForHasEmbed ? tok::r_paren : tok::eod;
3769 auto DiagMismatchedBracesAndSkipToEOD =
3771 std::pair<tok::TokenKind, SourceLocation> Matches) {
3773 Diag(Matches.second, diag::note_matching) << Matches.first;
3774 if (CurTok.
isNot(tok::eod))
3779 if (CurTok.
isNot(Kind)) {
3780 Diag(CurTok, diag::err_expected) << Kind;
3781 if (CurTok.
isNot(tok::eod))
3798 auto LexPPParameterName = [&]() -> std::optional<std::string> {
3801 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3802 return std::nullopt;
3809 if (CurTok.
is(tok::coloncolon)) {
3812 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3813 return std::nullopt;
3819 return (llvm::Twine(Prefix->
getName()) +
"::" + Suffix->
getName()).str();
3821 return Prefix->
getName().str();
3828 auto NormalizeParameterName = [](StringRef Name) {
3829 if (Name.size() > 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
3830 return Name.substr(2, Name.size() - 4);
3834 auto LexParenthesizedIntegerExpr = [&]() -> std::optional<size_t> {
3837 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3838 return std::nullopt;
3843 bool EvaluatedDefined;
3844 DirectiveEvalResult LimitEvalResult = EvaluateDirectiveExpression(
3845 ParameterIfNDef, CurTok, EvaluatedDefined,
false);
3847 if (!LimitEvalResult.Value) {
3850 assert(CurTok.
is(tok::eod) &&
"expect to be at the end of directive");
3851 return std::nullopt;
3854 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3855 return std::nullopt;
3862 if (EvaluatedDefined) {
3863 Diag(CurTok, diag::err_defined_in_pp_embed);
3864 return std::nullopt;
3867 if (LimitEvalResult.Value) {
3868 const llvm::APSInt &
Result = *LimitEvalResult.Value;
3869 if (
Result.isNegative()) {
3870 Diag(CurTok, diag::err_requires_positive_value)
3872 if (CurTok.
isNot(EndTokenKind))
3874 return std::nullopt;
3876 return Result.getLimitedValue();
3878 return std::nullopt;
3884 return tok::r_paren;
3886 return tok::r_brace;
3888 return tok::r_square;
3890 llvm_unreachable(
"should not get here");
3894 auto LexParenthesizedBalancedTokenSoup =
3896 std::vector<std::pair<tok::TokenKind, SourceLocation>> BracketStack;
3899 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3903 bool WaitingForInnerCloseParen =
false;
3904 while (CurTok.
isNot(tok::eod) &&
3905 (WaitingForInnerCloseParen || CurTok.
isNot(tok::r_paren))) {
3910 WaitingForInnerCloseParen =
true;
3917 WaitingForInnerCloseParen =
false;
3920 case tok::r_square: {
3921 if (BracketStack.empty()) {
3922 ExpectOrDiagAndSkipToEOD(tok::r_paren);
3926 GetMatchingCloseBracket(BracketStack.back().first);
3927 if (CurTok.
getKind() != Matching) {
3928 DiagMismatchedBracesAndSkipToEOD(Matching, BracketStack.back());
3931 BracketStack.pop_back();
3934 Tokens.push_back(CurTok);
3939 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3947 while (!CurTok.
isOneOf(EndTokenKind, tok::eod)) {
3949 std::optional<std::string> ParamName = LexPPParameterName();
3951 return std::nullopt;
3952 StringRef
Parameter = NormalizeParameterName(*ParamName);
3959 if (
Result.MaybeLimitParam)
3962 std::optional<size_t> Limit = LexParenthesizedIntegerExpr();
3964 return std::nullopt;
3967 }
else if (
Parameter ==
"clang::offset") {
3968 if (
Result.MaybeOffsetParam)
3971 std::optional<size_t> Offset = LexParenthesizedIntegerExpr();
3973 return std::nullopt;
3977 if (
Result.MaybePrefixParam)
3981 if (!LexParenthesizedBalancedTokenSoup(Soup))
3982 return std::nullopt;
3984 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
3986 if (
Result.MaybeSuffixParam)
3990 if (!LexParenthesizedBalancedTokenSoup(Soup))
3991 return std::nullopt;
3993 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
3995 if (
Result.MaybeIfEmptyParam)
3999 if (!LexParenthesizedBalancedTokenSoup(Soup))
4000 return std::nullopt;
4002 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
4004 ++
Result.UnrecognizedParams;
4008 if (CurTok.
is(tok::l_paren)) {
4010 if (!LexParenthesizedBalancedTokenSoup(Soup))
4011 return std::nullopt;
4014 Diag(ParamStartLoc, diag::err_pp_unknown_parameter) << 1 <<
Parameter;
4015 if (CurTok.
isNot(EndTokenKind))
4017 return std::nullopt;
4024void Preprocessor::HandleEmbedDirectiveImpl(
4026 StringRef BinaryContents, StringRef
FileName) {
4027 if (BinaryContents.empty()) {
4035 size_t TokCount = Toks.size();
4036 auto NewToks = std::make_unique<Token[]>(TokCount);
4037 llvm::copy(Toks, NewToks.get());
4038 EnterTokenStream(std::move(NewToks), TokCount,
true,
true);
4045 size_t TotalNumToks = 1 + NumPrefixToks + NumSuffixToks;
4047 auto Toks = std::make_unique<Token[]>(TotalNumToks);
4052 CurIdx += NumPrefixToks;
4055 EmbedAnnotationData *
Data =
new (BP) EmbedAnnotationData;
4056 Data->BinaryData = BinaryContents;
4059 Toks[CurIdx].startToken();
4060 Toks[CurIdx].setKind(tok::annot_embed);
4061 Toks[CurIdx].setAnnotationRange(HashLoc);
4062 Toks[CurIdx++].setAnnotationValue(
Data);
4067 CurIdx += NumSuffixToks;
4070 assert(CurIdx == TotalNumToks &&
"Calculated the incorrect number of tokens");
4071 EnterTokenStream(std::move(Toks), TotalNumToks,
true,
true);
4078 Diag(EmbedTok, diag::warn_compat_pp_embed_directive);
4080 Diag(EmbedTok, diag::ext_pp_embed_directive)
4081 << (LangOpts.CPlusPlus ? 1 : 0);
4088 if (FilenameTok.
isNot(tok::header_name)) {
4090 if (FilenameTok.
isNot(tok::eod))
4103 std::optional<LexEmbedParametersResult> Params =
4106 assert((Params || CurTok.
is(tok::eod)) &&
4107 "expected success or to be at the end of the directive");
4112 SmallString<128> FilenameBuffer;
4113 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
4114 StringRef OriginalFilename = Filename;
4120 if (Filename.empty())
4125 if (!MaybeFileRef) {
4127 if (Callbacks && Callbacks->EmbedFileNotFound(Filename)) {
4130 Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
4135 Diag(FilenameTok, diag::err_pp_embed_device_file) << Filename;
4139 std::optional<llvm::MemoryBufferRef> MaybeFile =
4143 Diag(FilenameTok, diag::err_cannot_open_file)
4144 << Filename <<
"a buffer to the contents could not be created";
4147 StringRef BinaryContents = MaybeFile->getBuffer();
4152 if (Params->MaybeOffsetParam) {
4157 BinaryContents = BinaryContents.substr(Params->MaybeOffsetParam->Offset);
4160 if (Params->MaybeLimitParam) {
4164 BinaryContents = BinaryContents.substr(0, Params->MaybeLimitParam->Limit);
4168 Callbacks->EmbedDirective(HashLoc, Filename, isAngled, MaybeFileRef,
4177 void *Mem = BP.Allocate(OriginalFilename.size(),
alignof(
char *));
4178 memcpy(Mem, OriginalFilename.data(), OriginalFilename.size());
4179 StringRef FilenameToGo =
4180 StringRef(
static_cast<char *
>(Mem), OriginalFilename.size());
4181 HandleEmbedDirectiveImpl(HashLoc, *Params, BinaryContents, FilenameToGo);
4194 assert(
getLangOpts().CPlusPlusModules && ImportTok.
is(tok::kw_import));
4196 this->ImportingCXXNamedModules,
true);
4198 if (LastExportKeyword.is(tok::kw_export))
4199 LastExportKeyword.startToken();
4203 if (
Tok.isNot(tok::eod))
4211 bool ImportingHeader =
false;
4212 bool IsPartition =
false;
4214 switch (
Tok.getKind()) {
4215 case tok::header_name:
4216 ImportingHeader =
true;
4217 DirToks.push_back(
Tok);
4218 Lex(DirToks.emplace_back());
4222 DirToks.push_back(
Tok);
4223 UseLoc =
Tok.getLocation();
4226 case tok::identifier: {
4228 Path, DirToks,
true,
4232 std::string FlatName;
4234 (IsPartition && ModuleDeclState.isNamedModule()) || !IsPartition;
4235 if (Callbacks && IsValid) {
4236 if (IsPartition && ModuleDeclState.isNamedModule()) {
4237 FlatName += ModuleDeclState.getPrimaryName();
4242 SourceLocation StartLoc = IsPartition ? UseLoc : Path[0].getLoc();
4254 DirToks.push_back(
Tok);
4260 if (!DirToks.back().isOneOf(tok::semi, tok::eod))
4263 if (DirToks.back().isNot(tok::eod))
4269 if (DirToks.back().isNot(tok::semi)) {
4274 if (ImportingHeader) {
4280 Diag(SemiLoc, diag::err_header_import_semi_in_macro);
4282 auto Action = HandleHeaderIncludeOrImport(
4284 switch (Action.Kind) {
4285 case ImportAction::None:
4288 case ImportAction::ModuleBegin:
4290 DirToks.emplace_back();
4291 DirToks.back().startToken();
4292 DirToks.back().setKind(tok::annot_module_begin);
4293 DirToks.back().setLocation(SemiLoc);
4294 DirToks.back().setAnnotationEndLoc(SemiLoc);
4295 DirToks.back().setAnnotationValue(Action.ModuleForHeader);
4298 case ImportAction::ModuleImport:
4299 case ImportAction::HeaderUnitImport:
4300 case ImportAction::SkippedModuleImport:
4303 DirToks[1].setKind(tok::annot_header_unit);
4304 DirToks[1].setAnnotationEndLoc(DirToks[0].getLocation());
4305 DirToks[1].setAnnotationValue(Action.ModuleForHeader);
4308 case ImportAction::Failure:
4309 assert(TheModuleLoader.HadFatalFailure &&
4310 "This should be an early exit only to a fatal error");
4311 CurLexer->cutOffLexing();
4340 assert(
getLangOpts().CPlusPlusModules && ModuleTok.
is(tok::kw_module));
4341 Token Introducer = ModuleTok;
4342 if (LastExportKeyword.is(tok::kw_export)) {
4343 Introducer = LastExportKeyword;
4355 switch (
Tok.getKind()) {
4358 DirToks.push_back(
Tok);
4361 DirToks.push_back(
Tok);
4363 if (
Tok.isNot(tok::kw_private)) {
4364 if (
Tok.isNot(tok::eod))
4370 DirToks.push_back(
Tok);
4372 case tok::identifier: {
4374 Path, DirToks,
false,
4381 if (
Tok.is(tok::colon)) {
4384 Tok, Partition, DirToks,
4395 if (
Tok.is(tok::identifier) &&
4397 std::unique_ptr<Token[]> TokCopy = std::make_unique<Token[]>(1);
4399 EnterTokenStream(std::move(TokCopy), 1,
4402 DirToks.back() =
Tok;
4407 DirToks.push_back(
Tok);
4413 std::optional<Token> NextPPTok =
4414 DirToks.back().is(tok::eod) ? peekNextPPToken() : DirToks.back();
4419 if (NextPPTok->is(tok::raw_identifier))
4421 if (!NextPPTok->isOneOf(tok::semi, tok::eod, tok::l_square,
4423 Diag(*NextPPTok, diag::err_pp_unexpected_tok_after_module_name)
4427 if (!DirToks.back().isOneOf(tok::semi, tok::eod)) {
4434 DirToks.back().isNot(tok::eod)
4438 : DirToks.pop_back_val().getLocation();
4440 if (!IncludeMacroStack.empty()) {
4441 Diag(StartLoc, diag::err_pp_module_decl_in_header)
4445 if (CurPPLexer->getConditionalStackDepth() != 0) {
4446 Diag(StartLoc, diag::err_pp_cond_span_module_decl)
static bool isInMainFile(const clang::Diagnostic &D)
Defines interfaces for clang::DirectoryEntry and clang::DirectoryEntryRef.
Defines the clang::FileManager interface and associated types.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Defines the clang::LangOptions interface.
Defines the clang::MacroInfo and clang::MacroDirective classes.
Defines the clang::Module class, which describes a module in the source code.
Defines the PPCallbacks interface.
static bool ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit, SrcMgr::CharacteristicKind &FileKind, Preprocessor &PP)
ReadLineMarkerFlags - Parse and validate any flags at the end of a GNU line marker directive.
static bool isConfigurationPattern(Token &MacroName, MacroInfo *MI, const LangOptions &LOptions)
static void diagnoseAutoModuleImport(Preprocessor &PP, SourceLocation HashLoc, Token &IncludeTok, ArrayRef< IdentifierLoc > Path, SourceLocation PathEnd)
Produce a diagnostic informing the user that a include or similar was implicitly treated as a module ...
static std::optional< StringRef > findSimilarStr(StringRef LHS, const std::vector< StringRef > &Candidates)
Find a similar string in Candidates.
static bool isLanguageDefinedBuiltin(const SourceManager &SourceMgr, const MacroInfo *MI, const StringRef MacroName)
static bool trySimplifyPath(SmallVectorImpl< StringRef > &Components, StringRef RealPathName, llvm::sys::path::Style Separator)
static bool warnByDefaultOnWrongCase(StringRef Include)
MacroDiag
Enumerates possible cases of define/undef a reserved identifier.
@ MD_ReservedAttributeIdentifier
static bool isFeatureTestMacro(StringRef MacroName)
static bool GetLineValue(Token &DigitTok, unsigned &Val, unsigned DiagID, Preprocessor &PP, bool IsGNULineDirective=false)
GetLineValue - Convert a numeric token into an unsigned value, emitting Diagnostic DiagID if it is in...
PPElifDiag
Enumerates possible select values for the pp_err_elif_after_else and pp_err_elif_without_if diagnosti...
static bool isReservedCXXAttributeName(Preprocessor &PP, IdentifierInfo *II)
static MacroDiag shouldWarnOnMacroUndef(Preprocessor &PP, IdentifierInfo *II)
static bool isObjCProtectedMacro(const IdentifierInfo *II)
static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II)
Defines the clang::Preprocessor interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines the clang::SourceLocation class and associated facilities.
static bool isInvalid(LocType Loc, bool *Invalid)
Defines the SourceManager interface.
Defines the clang::TokenKind enum and support functions.
VerifyDiagnosticConsumer::Directive Directive
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
__device__ __2f16 float c
ResetMacroExpansionHelper(Preprocessor *pp)
~ResetMacroExpansionHelper()
static AttrArgsInfo getCXX11AttrArgsInfo(const IdentifierInfo *Name)
Represents a byte-granular source range.
static CharSourceRange getCharRange(SourceRange R)
virtual void CodeCompleteMacroName(bool IsDefinition)
Callback invoked when performing code completion in a context where the name of a macro is expected.
A directive for a defined macro or a macro imported from a module.
Concrete class used by the front-end to report problems and issues.
A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...
StringRef getName() const
bool isDeviceFile() const
const FileEntry & getFileEntry() const
DirectoryEntryRef getDir() const
Cached information about one file (either on disk or in the virtual file system).
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements support for file system lookup, file system caching, and directory search management.
llvm::Expected< DirectoryEntryRef > getDirectoryRef(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
llvm::Expected< FileEntryRef > getFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true, bool IsText=true)
Lookup, cache, and verify the specified file (real or virtual).
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
One of these records is kept for each identifier that is lexed.
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.
bool isCPlusPlusOperatorKeyword() const
bool hadMacroDefinition() const
Returns true if this identifier was #defined to some value at any moment.
bool hasMacroDefinition() const
Return true if this identifier is #defined to some other value.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
bool isKeyword(const LangOptions &LangOpts) const
Return true if this token is a keyword in the specified language.
ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const
Determine whether this is a name reserved for the implementation (C99 7.1.3, C++ [lib....
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
A simple pair of identifier info and location.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool IsHeaderFile
Indicates whether the front-end is explicitly told that the input is a header file (i....
std::string CurrentModule
The name of the current module, of which the main source file is a part.
const MacroInfo * getMacroInfo() const
Encapsulates the data about a macro definition (e.g.
bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP, bool Syntactically) const
Return true if the specified macro definition is equal to this macro in spelling, arguments,...
bool isUsed() const
Return false if this macro is defined in the main file and has not yet been used.
bool isC99Varargs() const
bool isAllowRedefinitionsWithoutWarning() const
Return true if this macro can be redefined without warning.
void setHasCommaPasting()
unsigned getNumTokens() const
Return the number of tokens that this macro expands to.
const Token & getReplacementToken(unsigned Tok) const
void setDefinitionEndLoc(SourceLocation EndLoc)
Set the location of the last token in the macro.
bool isBuiltinMacro() const
Return true if this macro requires processing before expansion.
void setTokens(ArrayRef< Token > Tokens, llvm::BumpPtrAllocator &PPAllocator)
void setParameterList(ArrayRef< IdentifierInfo * > List, llvm::BumpPtrAllocator &PPAllocator)
Set the specified list of identifiers as the parameter list for this macro.
SourceLocation getDefinitionLoc() const
Return the location that the macro was defined at.
void setIsFunctionLike()
Function/Object-likeness.
bool isObjectLike() const
void setIsWarnIfUnused(bool val)
Set the value of the IsWarnIfUnused flag.
int getParameterNum(const IdentifierInfo *Arg) const
Return the parameter number of the specified identifier, or -1 if the identifier is not a formal para...
bool isWarnIfUnused() const
Return true if we should emit a warning if the macro is unused.
void setIsC99Varargs()
Varargs querying methods. This can only be set for function-like macros.
bool isMissingExpected() const
Determines whether the module, which failed to load, was actually a submodule that we expected to see...
bool isConfigMismatch() const
Determines whether the module failed to load due to a configuration mismatch with an explicitly-named...
static std::string getFlatNameFromPath(ModuleIdPath Path)
@ ExcludedHeader
This header is explicitly excluded from the module.
@ TextualHeader
This header is part of the module (for layering purposes) but should be textually included.
Describes a module or submodule.
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
bool isForBuilding(const LangOptions &LangOpts) const
Determine whether this module can be built in this compilation.
@ Hidden
All of the names in this module are hidden.
SourceLocation DefinitionLoc
The location of the module definition.
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers).
std::string Name
The name of this module.
bool isAvailable() const
Determine whether this module is available for use within the current translation unit.
bool isHeaderUnit() const
Is this module a header unit.
Module * ShadowingModule
A module with the same name that shadows this module.
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
Preprocessor standard embed parameter "if_empty" if_empty( balanced-token-seq )
Preprocessor standard embed parameter "limit" limit( constant-expression )
Preprocessor extension embed parameter "clang::offset" clang::offset( constant-expression )
Preprocessor standard embed parameter "prefix" prefix( balanced-token-seq )
Preprocessor standard embed parameter "suffix" suffix( balanced-token-seq )
OptionalFileEntryRef getFileEntry() const
getFileEntry - Return the FileEntry corresponding to this FileID.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
MacroDirective * getLocalMacroDirective(const IdentifierInfo *II) const
Given an identifier, return its latest non-imported MacroDirective if it is #define'd and not #undef'...
void EnterModuleSuffixTokenStream(ArrayRef< Token > Toks)
void markClangModuleAsAffecting(Module *M)
Mark the given clang module as affecting the current clang module or translation unit.
void HandleCXXImportDirective(Token Import)
HandleCXXImportDirective - Handle the C++ modules import directives.
SourceRange DiscardUntilEndOfDirective(SmallVectorImpl< Token > *DiscardedToks=nullptr)
Read and discard all tokens remaining on the current line until the tok::eod token is found.
const MacroInfo * getMacroInfo(const IdentifierInfo *II) const
bool isRecordingPreamble() const
void HandleSkippedDirectiveWhileUsingPCH(Token &Result, SourceLocation HashLoc)
Process directives while skipping until the through header or pragma hdrstop is found.
bool isInPrimaryFile() const
Return true if we're in the top-level file, not in a #include.
void markMacroAsUsed(MacroInfo *MI)
A macro is used, update information about macros that need unused warnings.
void EnterSubmodule(Module *M, SourceLocation ImportLoc, bool ForPragma)
IdentifierInfo * LookUpIdentifierInfo(Token &Identifier) const
Given a tok::raw_identifier token, look up the identifier information for the token and install it in...
void setCodeCompletionReached()
Note that we hit the code-completion point.
StringRef getNamedModuleName() const
Get the named module name we're preprocessing.
void Lex(Token &Result)
Lex the next token for this preprocessor.
bool EnterSourceFile(FileID FID, ConstSearchDirIterator Dir, SourceLocation Loc, bool IsFirstIncludeOfFile=true)
Add a source file to the top of the include stack and start lexing tokens from it instead of the curr...
void LexNonComment(Token &Result)
Lex a token.
friend class VAOptDefinitionContext
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
SourceManager & getSourceManager() const
MacroDefinition getMacroDefinition(const IdentifierInfo *II)
bool CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef, bool *ShadowFlag=nullptr)
SourceLocation CheckEndOfDirective(StringRef DirType, bool EnableMacros=false, SmallVectorImpl< Token > *ExtraToks=nullptr)
Ensure that the next token is a tok::eod token.
static bool checkModuleIsAvailable(const LangOptions &LangOpts, const TargetInfo &TargetInfo, const Module &M, DiagnosticsEngine &Diags)
Check that the given module is available, producing a diagnostic if not.
SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart, unsigned Char) const
Given a location that specifies the start of a token, return a new location that specifies a characte...
Module * getCurrentModule()
Retrieves the module that we're currently building, if any.
OptionalFileEntryRef LookupEmbedFile(StringRef Filename, bool isAngled, bool OpenFile)
Given a "Filename" or <Filename> reference, look up the indicated embed resource.
void makeModuleVisible(Module *M, SourceLocation Loc, bool IncludeExports=true)
bool hadModuleLoaderFatalFailure() const
bool HandleModuleContextualKeyword(Token &Result)
Callback invoked when the lexer sees one of export, import or module token at the start of a line.
const TargetInfo & getTargetInfo() const
FileManager & getFileManager() const
bool LexHeaderName(Token &Result, bool AllowMacroExpansion=true)
Lex a token, forming a header-name token if possible.
bool isPCHThroughHeader(const FileEntry *FE)
Returns true if the FileEntry is the PCH through header.
friend class VariadicMacroScopeGuard
MacroInfo * AllocateMacroInfo(SourceLocation L)
Allocate a new MacroInfo object with the provided SourceLocation.
void LexUnexpandedToken(Token &Result)
Just like Lex, but disables macro expansion of identifier tokens.
bool alreadyIncluded(FileEntryRef File) const
Return true if this header has already been included.
FileID getPredefinesFileID() const
Returns the FileID for the preprocessor predefines.
void LexUnexpandedNonComment(Token &Result)
Like LexNonComment, but this disables macro expansion of identifier tokens.
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
bool GetIncludeFilenameSpelling(SourceLocation Loc, StringRef &Buffer)
Turn the specified lexer token into a fully checked and spelled filename, e.g.
PreprocessorLexer * getCurrentFileLexer() const
Return the current file lexer being lexed from.
HeaderSearch & getHeaderSearchInfo() const
void emitMacroExpansionWarnings(const Token &Identifier, bool IsIfnDef=false) const
void HandleDirective(Token &Result)
Callback invoked when the lexer sees a # token at the start of a line.
void EnterAnnotationToken(SourceRange Range, tok::TokenKind Kind, void *AnnotationVal)
Enter an annotation token into the token stream.
OptionalFileEntryRef LookupFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled, ConstSearchDirIterator FromDir, const FileEntry *FromFile, ConstSearchDirIterator *CurDir, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool *IsFrameworkFound, bool SkipCache=false, bool OpenFile=true, bool CacheFailures=true)
Given a "foo" or <foo> reference, look up the indicated file.
const LangOptions & getLangOpts() const
bool isInNamedModule() const
If we are preprocessing a named module.
OptionalFileEntryRef getHeaderToIncludeForDiagnostics(SourceLocation IncLoc, SourceLocation MLoc)
We want to produce a diagnostic at location IncLoc concerning an unreachable effect at location MLoc ...
bool isNextPPTokenOneOf(Ts... Ks) const
isNextPPTokenOneOf - Check whether the next pp-token is one of the specificed token kind.
DefMacroDirective * appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI, SourceLocation Loc)
void CollectPPImportSuffix(SmallVectorImpl< Token > &Toks, bool StopUntilEOD=false)
Collect the tokens of a C++20 pp-import-suffix.
void HandlePragmaHdrstop(Token &Tok)
DiagnosticsEngine & getDiagnostics() const
void HandleCXXModuleDirective(Token Module)
HandleCXXModuleDirective - Handle C++ module declaration directives.
std::optional< LexEmbedParametersResult > LexEmbedParameters(Token &Current, bool ForHasEmbed)
Lex the parameters for an embed directive, returns nullopt on error.
Module * getModuleForLocation(SourceLocation Loc, bool AllowTextual)
Find the module that owns the source or header file that Loc points to.
bool HandleModuleName(StringRef DirType, SourceLocation UseLoc, Token &Tok, SmallVectorImpl< IdentifierLoc > &Path, SmallVectorImpl< Token > &DirToks, bool AllowMacroExpansion, bool IsPartition)
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
bool usingPCHWithThroughHeader()
True if using a PCH with a through header.
Preprocessor(const PreprocessorOptions &PPOpts, DiagnosticsEngine &diags, const LangOptions &LangOpts, SourceManager &SM, HeaderSearch &Headers, ModuleLoader &TheModuleLoader, IdentifierInfoLookup *IILookup=nullptr, bool OwnsHeaderSearch=false, TranslationUnitKind TUKind=TU_Complete)
void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD)
Add a directive to the macro directive history for this identifier.
Represents an unpacked "presumed" location which can be presented to the user.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
SourceLocation getIncludeLoc() const
Return the presumed include location of this location.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
bool isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
std::optional< llvm::MemoryBufferRef > getMemoryBufferForFileOrNone(FileEntryRef File)
Retrieve the memory buffer associated with the given file.
A trivial tuple used to represent a source range.
void setBegin(SourceLocation b)
SourceLocation getEnd() const
void setEnd(SourceLocation e)
Exposes information about the current target.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getEndLoc() const
void clearFlag(TokenFlags Flag)
Unset the specified flag.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
unsigned getLength() const
void setKind(tok::TokenKind K)
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
tok::TokenKind getKind() const
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
bool isOneOf(Ts... Ks) const
bool isModuleContextualKeyword(bool AllowExport=true) const
Return true if we have a C++20 modules contextual keyword(export, importor module).
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
bool isNot(tok::TokenKind K) const
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix.
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.