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)
332 for (StringRef
C : Candidates) {
333 if (LHS.equals_insensitive(
C)) {
341 size_t Length = LHS.size();
342 size_t MaxDist = Length < 3 ? Length - 1 : Length / 3;
344 std::optional<std::pair<StringRef, size_t>> SimilarStr;
345 for (StringRef
C : Candidates) {
346 size_t CurDist = LHS.edit_distance(
C,
true);
347 if (CurDist <= MaxDist) {
350 SimilarStr = {
C, CurDist};
351 }
else if (CurDist < SimilarStr->second) {
353 SimilarStr = {
C, CurDist};
359 return SimilarStr->first;
368 if (MacroNameTok.
is(tok::eod))
369 return Diag(MacroNameTok, diag::err_pp_missing_macro_name);
373 return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
379 ? diag::ext_pp_operator_used_as_macro_name
380 : diag::err_pp_operator_used_as_macro_name)
381 << II << MacroNameTok.
getKind();
388 return Diag(MacroNameTok, diag::err_defined_macro_name);
404 }
else if (isDefineUndef ==
MU_Undef)
406 if (D !=
MD_NoWarn && !SourceMgr.isInSystemHeader(MacroNameLoc) &&
407 !SourceMgr.isInPredefinedFile(MacroNameLoc)) {
416 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id);
418 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_attribute_id)
435void Preprocessor::ReadMacroName(
Token &MacroNameTok,
MacroUse isDefineUndef,
440 if (MacroNameTok.
is(tok::code_completion)) {
452 if (MacroNameTok.
isNot(tok::eod)) {
453 MacroNameTok.
setKind(tok::eod);
471 auto ReadNextTok = [
this, ExtraToks, &Tmp](
auto &&LexFn) {
472 std::invoke(LexFn,
this, Tmp);
473 if (ExtraToks && Tmp.
isNot(tok::eod))
474 ExtraToks->push_back(Tmp);
486 while (Tmp.
is(tok::comment))
489 if (Tmp.
is(tok::eod))
497 if ((LangOpts.GNUMode || LangOpts.C99 || LangOpts.CPlusPlus) &&
501 unsigned DiagID = diag::ext_pp_extra_tokens_at_eol;
504 (DirType ==
"import" || DirType ==
"module"))
505 DiagID = diag::warn_pp_extra_tokens_at_module_directive_eol;
507 Diag(Tmp, DiagID) << DirType << Hint;
511void Preprocessor::SuggestTypoedDirective(
const Token &
Tok,
512 StringRef Directive)
const {
528 static constexpr StringRef AllCandidates[] = {
529 "if",
"ifdef",
"ifndef",
"elif",
"else",
"endif",
"elifdef",
"elifndef"};
532 if (!LangOpts.C23 && !LangOpts.CPlusPlus23)
533 Candidates = Candidates.drop_back(2);
537 assert(
Tok.getLocation().isFileID());
541 StringRef SuggValue = *Sugg;
544 Diag(
Tok, diag::warn_pp_invalid_directive) << 1 << SuggValue << Hint;
556void Preprocessor::SkipExcludedConditionalBlock(
SourceLocation HashTokenLoc,
558 bool FoundNonSkipPortion,
569 assert(!SkippingExcludedConditionalBlock &&
570 "calling SkipExcludedConditionalBlock recursively");
571 llvm::SaveAndRestore SARSkipping(SkippingExcludedConditionalBlock,
true);
574 assert(!CurTokenLexer &&
"Conditional PP block cannot appear in a macro!");
575 assert(CurPPLexer &&
"Conditional PP block must be in a file!");
576 assert(CurLexer &&
"Conditional PP block but no current lexer set!");
578 if (PreambleConditionalStack.reachedEOFWhileSkipping())
579 PreambleConditionalStack.clearSkipInfo();
581 CurPPLexer->pushConditionalLevel(IfTokenLoc,
false,
582 FoundNonSkipPortion, FoundElse);
586 CurPPLexer->LexingRawMode =
true;
588 SourceLocation endLoc;
592 struct SkippingRangeStateTy {
595 const char *BeginPtr =
nullptr;
596 unsigned *SkipRangePtr =
nullptr;
598 SkippingRangeStateTy(Preprocessor &PP) : PP(PP) {}
600 void beginLexPass() {
606 BeginPtr = PP.CurLexer->getBufferLocation();
607 SkipRangePtr = &PP.RecordedSkippedRanges[BeginPtr];
609 PP.CurLexer->seek(PP.CurLexer->getCurrentBufferOffset() + *SkipRangePtr,
614 void endLexPass(
const char *Hashptr) {
617 assert(PP.CurLexer->isDependencyDirectivesLexer());
622 if (!*SkipRangePtr) {
623 *SkipRangePtr = Hashptr - BeginPtr;
625 assert(*SkipRangePtr ==
unsigned(Hashptr - BeginPtr));
627 SkipRangePtr =
nullptr;
629 } SkippingRangeState(*
this);
632 if (CurLexer->isDependencyDirectivesLexer()) {
633 CurLexer->LexDependencyDirectiveTokenWhileSkipping(
Tok);
635 SkippingRangeState.beginLexPass();
639 if (
Tok.
is(tok::code_completion)) {
642 CodeComplete->CodeCompleteInConditionalExclusion();
655 Tok.
is(tok::raw_identifier) &&
658 llvm::SaveAndRestore ModuleDirectiveSkipping(LastExportKeyword);
659 LastExportKeyword.startToken();
666 if (
Tok.
is(tok::raw_identifier)) {
675 llvm::SaveAndRestore RestoreLexingRawMode(CurPPLexer->LexingRawMode,
682 CurPPLexer->ParsingPreprocessorDirective =
true;
685 Diag(StartLoc, diag::err_pp_cond_span_module_decl)
686 << SourceRange(StartLoc, End);
687 CurPPLexer->ParsingPreprocessorDirective =
false;
690 CurLexer->resetExtendedTokenMode();
697 if (
Tok.
is(tok::eof)) {
701 if (PreambleConditionalStack.isRecording())
702 PreambleConditionalStack.SkipInfo.emplace(HashTokenLoc, IfTokenLoc,
715 if (
Tok.
is(tok::eof))
721 CurPPLexer->ParsingPreprocessorDirective =
true;
722 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
724 assert(
Tok.
is(tok::hash));
725 const char *Hashptr = CurLexer->getBufferLocation() -
Tok.
getLength();
726 assert(CurLexer->getSourceLocation(Hashptr) ==
Tok.
getLocation());
733 if (
Tok.
isNot(tok::raw_identifier)) {
734 CurPPLexer->ParsingPreprocessorDirective =
false;
736 if (CurLexer) CurLexer->resetExtendedTokenMode();
747 char FirstChar = RI[0];
748 if (FirstChar >=
'a' && FirstChar <=
'z' &&
749 FirstChar !=
'i' && FirstChar !=
'e') {
750 CurPPLexer->ParsingPreprocessorDirective =
false;
752 if (CurLexer) CurLexer->resetExtendedTokenMode();
759 char DirectiveBuf[20];
765 size_t IdLen = DirectiveStr.size();
767 CurPPLexer->ParsingPreprocessorDirective =
false;
769 if (CurLexer) CurLexer->resetExtendedTokenMode();
772 memcpy(DirectiveBuf, &DirectiveStr[0], IdLen);
773 Directive = StringRef(DirectiveBuf, IdLen);
793 PPConditionalInfo CondInfo;
795 bool InCond = CurPPLexer->popConditionalLevel(CondInfo);
797 assert(!InCond &&
"Can't be skipping if not in a conditional!");
801 SkippingRangeState.endLexPass(Hashptr);
804 CurPPLexer->LexingRawMode =
false;
806 CurPPLexer->LexingRawMode =
true;
813 }
else if (Sub ==
"lse") {
817 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
820 SkippingRangeState.endLexPass(Hashptr);
824 Diag(
Tok, diag::pp_err_else_after_else);
835 CurPPLexer->LexingRawMode =
false;
837 CurPPLexer->LexingRawMode =
true;
844 }
else if (Sub ==
"lif") {
845 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
848 SkippingRangeState.endLexPass(Hashptr);
865 assert(CurPPLexer->LexingRawMode &&
"We have to be skipping here!");
866 CurPPLexer->LexingRawMode =
false;
867 IdentifierInfo *IfNDefMacro =
nullptr;
868 DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
872 const bool CondValue = DER.Conditional;
873 CurPPLexer->LexingRawMode =
true;
886 }
else if (Sub ==
"lifdef" ||
888 bool IsElifDef =
Sub ==
"lifdef";
889 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
890 Token DirectiveToken =
Tok;
893 SkippingRangeState.endLexPass(Hashptr);
897 unsigned DiagID = LangOpts.CPlusPlus ? diag_compat::cxx23_pp_directive
898 : diag_compat::c23_pp_directive;
903 Diag(
Tok, diag::pp_err_elif_after_else)
917 assert(CurPPLexer->LexingRawMode &&
"We have to be skipping here!");
918 CurPPLexer->LexingRawMode =
false;
920 ReadMacroName(MacroNameTok);
921 CurPPLexer->LexingRawMode =
true;
925 if (MacroNameTok.
is(tok::eod)) {
937 MacroInfo *MI = MD.getMacroInfo();
941 Callbacks->Elifdef(DirectiveToken.
getLocation(), MacroNameTok,
944 Callbacks->Elifndef(DirectiveToken.
getLocation(), MacroNameTok,
949 if (
static_cast<bool>(MI) == IsElifDef) {
961 CurPPLexer->ParsingPreprocessorDirective =
false;
963 if (CurLexer) CurLexer->resetExtendedTokenMode();
969 CurPPLexer->LexingRawMode =
false;
974 Callbacks->SourceRangeSkipped(
975 SourceRange(HashTokenLoc, endLoc.
isValid()
977 : CurPPLexer->getSourceLocation()),
983 if (!SourceMgr.isInMainFile(Loc)) {
986 FileID IDOfIncl = SourceMgr.getFileID(SourceMgr.getExpansionLoc(Loc));
987 if (
auto EntryOfIncl = SourceMgr.getFileEntryRefForID(IDOfIncl)) {
989 return HeaderInfo.getModuleMap()
990 .findModuleForHeader(*EntryOfIncl, AllowTextual)
999 : HeaderInfo.lookupModule(
getLangOpts().CurrentModule, Loc);
1006 IncLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
1013 while (!Loc.
isInvalid() && !SM.isInMainFile(Loc)) {
1014 auto ID = SM.getFileID(SM.getExpansionLoc(Loc));
1015 auto FE = SM.getFileEntryRefForID(ID);
1021 HeaderInfo.hasModuleMap(FE->getName(),
nullptr,
1022 SourceMgr.isInSystemHeader(Loc));
1024 bool InPrivateHeader =
false;
1025 for (
auto Header : HeaderInfo.findAllModulesForHeader(*FE)) {
1026 if (!Header.isAccessibleFrom(IncM)) {
1031 InPrivateHeader =
true;
1048 return std::nullopt;
1058 if (InPrivateHeader)
1059 return std::nullopt;
1067 Loc = SM.getIncludeLoc(ID);
1070 return std::nullopt;
1079 bool *IsFrameworkFound,
bool SkipCache,
bool OpenFile,
bool CacheFailures) {
1084 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
1089 bool BuildSystemModule =
false;
1090 if (!FromDir && !FromFile) {
1107 if (FID == SourceMgr.getMainFileID() && MainFileDir) {
1109 HeaderInfo.getModuleMap().shouldImportRelativeToBuiltinIncludeDir(
1111 ? HeaderInfo.getModuleMap().getBuiltinDir()
1113 Includers.push_back(std::make_pair(std::nullopt, *IncludeDir));
1115 }
else if ((FileEnt = SourceMgr.getFileEntryRefForID(
1116 SourceMgr.getMainFileID()))) {
1117 auto CWD = FileMgr.getOptionalDirectoryRef(
".");
1118 Includers.push_back(std::make_pair(*FileEnt, *CWD));
1121 Includers.push_back(std::make_pair(*FileEnt, FileEnt->
getDir()));
1127 if (LangOpts.MSVCCompat && !isAngled) {
1128 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1129 if (IsFileLexer(ISEntry))
1131 Includers.push_back(std::make_pair(*FileEnt, FileEnt->
getDir()));
1136 CurDir = CurDirLookup;
1144 Filename, FilenameLoc, isAngled, TmpFromDir, &TmpCurDir,
1145 Includers, SearchPath, RelativePath, RequestingModule,
1146 SuggestedModule,
nullptr,
1147 nullptr, SkipCache)) {
1149 TmpFromDir = TmpCurDir;
1151 if (&FE->getFileEntry() == FromFile) {
1153 FromDir = TmpFromDir;
1162 Filename, FilenameLoc, isAngled, FromDir, &CurDir, Includers, SearchPath,
1163 RelativePath, RequestingModule, SuggestedModule, IsMapped,
1164 IsFrameworkFound, SkipCache, BuildSystemModule, OpenFile, CacheFailures);
1172 if (IsFileLexer()) {
1175 Filename, *CurFileEnt, SearchPath, RelativePath, RequestingModule,
1182 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1183 if (IsFileLexer(ISEntry)) {
1184 if ((CurFileEnt = ISEntry.ThePPLexer->
getFileEntry())) {
1186 Filename, *CurFileEnt, SearchPath, RelativePath,
1187 RequestingModule, SuggestedModule)) {
1195 return std::nullopt;
1202 if (llvm::sys::path::is_absolute(Filename)) {
1209 StringRef StartingFrom, StringRef
FileName,
1210 bool RemoveInitialFileComponentFromLookupPath) {
1211 llvm::sys::path::native(StartingFrom, LookupPath);
1212 if (RemoveInitialFileComponentFromLookupPath)
1213 llvm::sys::path::remove_filename(LookupPath);
1214 if (!LookupPath.empty() &&
1215 !llvm::sys::path::is_separator(LookupPath.back())) {
1216 LookupPath.push_back(llvm::sys::path::get_separator().front());
1226 if (LookupFromFile) {
1230 llvm::sys::path::append(TmpDir, Filename);
1231 if (!TmpDir.empty()) {
1233 TmpDir, OpenFile,
true,
false);
1235 return ShouldBeEntry;
1242 if (MaybeWorkingDirEntry) {
1244 StringRef WorkingDir = WorkingDirEntry.
getName();
1245 if (!WorkingDir.empty()) {
1246 SeparateComponents(LookupPath, WorkingDir, Filename,
false);
1248 LookupPath, OpenFile,
true,
false);
1250 return ShouldBeEntry;
1255 for (
const auto &Entry : PPOpts.EmbedEntries) {
1257 SeparateComponents(LookupPath, Entry, Filename,
false);
1259 LookupPath, OpenFile,
true,
false);
1261 return ShouldBeEntry;
1263 return std::nullopt;
1273 : PP(pp), save(pp->DisableMacroExpansion) {
1274 if (pp->MacroExpansionInDirectivesOverride)
1275 pp->DisableMacroExpansion =
false;
1279 PP->DisableMacroExpansion = save;
1297 return HandleDefineDirective(
Result,
1300 if (SkippingUntilPCHThroughHeader &&
1302 return HandleIncludeDirective(HashLoc,
Result);
1304 if (SkippingUntilPragmaHdrStop && II->
getPPKeywordID() == tok::pp_pragma) {
1306 auto *II =
Result.getIdentifierInfo();
1307 if (II && II->
getName() ==
"hdrstop")
1324 CurPPLexer->ParsingPreprocessorDirective =
true;
1325 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
1327 bool ImmediatelyAfterTopLevelIfndef =
1328 CurPPLexer->MIOpt.getImmediatelyAfterTopLevelIfndef();
1329 CurPPLexer->MIOpt.resetImmediatelyAfterTopLevelIfndef();
1336 bool ReadAnyTokensBeforeDirective =CurPPLexer->MIOpt.getHasReadAnyTokensVal();
1344 if (Introducer.
isOneOf(tok::hash, tok::at))
1358 case tok::pp_include:
1359 case tok::pp_import:
1360 case tok::pp_include_next:
1361 case tok::pp___include_macros:
1362 case tok::pp_pragma:
1364 case tok::pp_module:
1365 case tok::pp___preprocessed_module:
1366 case tok::pp___preprocessed_import:
1368 << Introducer.
is(tok::hash) << II->
getName();
1369 Diag(*ArgMacro, diag::note_macro_expansion_here)
1370 << ArgMacro->getIdentifierInfo();
1384 if (SkippingUntilPCHThroughHeader || SkippingUntilPragmaHdrStop)
1388 switch (
Result.getKind()) {
1393 CurPPLexer->MIOpt.SetReadToken(ReadAnyTokensBeforeDirective);
1395 case tok::code_completion:
1398 CodeComplete->CodeCompleteDirective(
1399 CurPPLexer->getConditionalStackDepth() > 0);
1401 case tok::numeric_constant:
1408 return HandleDigitDirective(
Result);
1418 return HandleIfDirective(
Result, Introducer,
1419 ReadAnyTokensBeforeDirective);
1421 return HandleIfdefDirective(
Result, Introducer,
false,
1423 case tok::pp_ifndef:
1424 return HandleIfdefDirective(
Result, Introducer,
true,
1425 ReadAnyTokensBeforeDirective);
1427 case tok::pp_elifdef:
1428 case tok::pp_elifndef:
1429 return HandleElifFamilyDirective(
Result, Introducer,
1433 return HandleElseDirective(
Result, Introducer);
1435 return HandleEndifDirective(
Result);
1438 case tok::pp_include:
1441 case tok::pp___include_macros:
1446 case tok::pp_define:
1447 return HandleDefineDirective(
Result, ImmediatelyAfterTopLevelIfndef);
1449 return HandleUndefDirective();
1453 return HandleLineDirective();
1457 return HandleUserDiagnosticDirective(
Result,
false);
1460 case tok::pp_pragma:
1462 case tok::pp_module:
1463 case tok::pp___preprocessed_module:
1467 case tok::pp___preprocessed_import:
1469 case tok::pp_import:
1470 switch (Introducer.
getKind()) {
1474 return HandleObjCImportDirective(Introducer,
Result);
1475 case tok::kw_import:
1478 llvm_unreachable(
"not a valid import directive");
1482 case tok::pp_include_next:
1485 case tok::pp_warning:
1486 if (LangOpts.CPlusPlus)
1488 ? diag::warn_cxx23_compat_warning_directive
1489 : diag::ext_pp_warning_directive)
1492 Diag(
Result, LangOpts.C23 ? diag::warn_c23_compat_warning_directive
1493 : diag::ext_pp_warning_directive)
1496 return HandleUserDiagnosticDirective(
Result,
true);
1498 return HandleIdentSCCSDirective(
Result);
1500 return HandleIdentSCCSDirective(
Result);
1503 case tok::pp_assert:
1506 case tok::pp_unassert:
1510 case tok::pp___public_macro:
1512 return HandleMacroPublicDirective(
Result);
1515 case tok::pp___private_macro:
1517 return HandleMacroPrivateDirective();
1528 auto Toks = std::make_unique<Token[]>(2);
1530 Toks[0] = Introducer;
1535 if (
Result.is(tok::hashhash))
1536 Toks[1].setKind(tok::unknown);
1541 EnterTokenStream(std::move(Toks), 2,
false,
false);
1547 Diag(
Result, diag::err_pp_invalid_directive) << 0;
1559 bool IsGNULineDirective=
false) {
1560 if (DigitTok.
isNot(tok::numeric_constant)) {
1561 PP.
Diag(DigitTok, DiagID);
1563 if (DigitTok.
isNot(tok::eod))
1569 IntegerBuffer.resize(DigitTok.
getLength());
1570 const char *DigitTokBegin = &IntegerBuffer[0];
1580 for (
unsigned i = 0; i != ActualLength; ++i) {
1583 if (DigitTokBegin[i] ==
'\'')
1586 if (!
isDigit(DigitTokBegin[i])) {
1588 diag::err_pp_line_digit_sequence) << IsGNULineDirective;
1593 unsigned NextVal = Val*10+(DigitTokBegin[i]-
'0');
1594 if (NextVal < Val) {
1595 PP.
Diag(DigitTok, DiagID);
1602 if (DigitTokBegin[0] ==
'0' && Val)
1604 << IsGNULineDirective;
1616void Preprocessor::HandleLineDirective() {
1624 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*
this))
1628 Diag(DigitTok, diag::ext_pp_line_zero);
1632 unsigned LineLimit = 32768U;
1633 if (LangOpts.C99 || LangOpts.CPlusPlus11)
1634 LineLimit = 2147483648U;
1635 if (LineNo >= LineLimit)
1636 Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
1637 else if (LangOpts.CPlusPlus11 && LineNo >= 32768U)
1638 Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
1640 int FilenameID = -1;
1646 if (StrTok.
is(tok::eod))
1648 else if (StrTok.
isNot(tok::header_name)) {
1649 Diag(StrTok, diag::err_pp_line_invalid_filename);
1653 SmallString<128> FilenameBuffer;
1654 StringRef Filename =
getSpelling(StrTok, FilenameBuffer);
1656 FilenameID = SourceMgr.getLineTableFilenameID(Filename);
1669 SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1671 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID,
false,
1675 Callbacks->FileChanged(CurPPLexer->getSourceLocation(),
1687 if (FlagTok.
is(tok::eod))
return false;
1688 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1695 if (FlagTok.
is(tok::eod))
return false;
1696 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1698 }
else if (FlagVal == 2) {
1715 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);
1721 if (FlagTok.
is(tok::eod))
return false;
1722 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1728 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1736 if (FlagTok.
is(tok::eod))
return false;
1737 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1742 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1750 if (FlagTok.
is(tok::eod))
return false;
1753 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1765void Preprocessor::HandleDigitDirective(
Token &DigitTok) {
1769 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
1776 bool IsFileEntry =
false, IsFileExit =
false;
1777 int FilenameID = -1;
1782 if (StrTok.
is(tok::eod)) {
1783 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1785 FileKind = SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1786 }
else if (StrTok.
isNot(tok::header_name)) {
1787 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1791 SmallString<128> FilenameBuffer;
1792 StringRef Filename =
getSpelling(StrTok, FilenameBuffer);
1797 if (!SourceMgr.isInPredefinedFile(DigitTok.
getLocation()))
1798 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1802 if (!(IsFileExit && Filename.empty()))
1803 FilenameID = SourceMgr.getLineTableFilenameID(Filename);
1807 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID, IsFileEntry,
1808 IsFileExit, FileKind);
1817 else if (IsFileExit)
1820 Callbacks->FileChanged(CurPPLexer->getSourceLocation(), Reason, FileKind);
1826void Preprocessor::HandleUserDiagnosticDirective(
Token &
Tok,
1834 CurLexer->ReadToEndOfLine(&Message);
1838 StringRef Msg =
Message.str().ltrim(
' ');
1841 Diag(
Tok, diag::pp_hash_warning) << Msg;
1843 Diag(
Tok, diag::err_pp_hash_error) << Msg;
1848void Preprocessor::HandleIdentSCCSDirective(
Token &
Tok) {
1850 Diag(
Tok, diag::ext_pp_ident_directive);
1857 if (StrTok.
isNot(tok::string_literal) &&
1858 StrTok.
isNot(tok::wide_string_literal)) {
1859 Diag(StrTok, diag::err_pp_malformed_ident);
1860 if (StrTok.
isNot(tok::eod))
1866 Diag(StrTok, diag::err_invalid_string_udl);
1883void Preprocessor::HandleMacroPublicDirective(
Token &
Tok) {
1885 ReadMacroName(MacroNameTok,
MU_Undef);
1888 if (MacroNameTok.
is(tok::eod))
1900 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1910void Preprocessor::HandleMacroPrivateDirective() {
1912 ReadMacroName(MacroNameTok,
MU_Undef);
1915 if (MacroNameTok.
is(tok::eod))
1927 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1947 StringRef &Buffer) {
1949 assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1961 if (Buffer[0] ==
'<') {
1962 if (Buffer.back() !=
'>') {
1963 Diag(Loc, diag::err_pp_expects_filename);
1964 Buffer = StringRef();
1968 }
else if (Buffer[0] ==
'"') {
1969 if (Buffer.back() !=
'"') {
1970 Diag(Loc, diag::err_pp_expects_filename);
1971 Buffer = StringRef();
1976 Diag(Loc, diag::err_pp_expects_filename);
1977 Buffer = StringRef();
1982 if (Buffer.size() <= 2) {
1983 Diag(Loc, diag::err_pp_empty_filename);
1984 Buffer = StringRef();
1989 Buffer = Buffer.substr(1, Buffer.size()-2);
1994 StringRef &Buffer) {
1996 assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1997 if (Buffer.size() < 2 || Buffer.front() !=
'"' || Buffer.back() !=
'"') {
1998 Diag(Loc, diag::err_pp_line_invalid_filename);
1999 Buffer = StringRef();
2002 Buffer = Buffer.substr(1, Buffer.size() - 2);
2008 void *AnnotationVal) {
2011 auto Tok = std::make_unique<Token[]>(1);
2013 EnterTokenStream(std::move(
Tok), 1,
true,
false);
2023 for (
size_t I = 0, N = Path.size(); I != N; ++I) {
2026 PathString += Path[I].getIdentifierInfo()->getName();
2029 int IncludeKind = 0;
2031 case tok::pp_include:
2035 case tok::pp_import:
2039 case tok::pp_include_next:
2043 case tok::pp___include_macros:
2048 llvm_unreachable(
"unknown include directive kind");
2051 PP.
Diag(HashLoc, diag::remark_pp_include_directive_modular_translation)
2052 << IncludeKind << PathString;
2059 StringRef RealPathName,
2060 llvm::sys::path::Style Separator) {
2061 auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName);
2062 auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName);
2064 bool SuggestReplacement =
false;
2066 auto IsSep = [Separator](StringRef Component) {
2067 return Component.size() == 1 &&
2068 llvm::sys::path::is_separator(Component[0], Separator);
2073 for (
auto &Component : llvm::reverse(Components)) {
2074 if (
"." == Component) {
2075 }
else if (
".." == Component) {
2079 }
else if (RealPathComponentIter != RealPathComponentEnd) {
2080 if (!IsSep(Component) && !IsSep(*RealPathComponentIter) &&
2081 Component != *RealPathComponentIter) {
2085 SuggestReplacement =
2086 RealPathComponentIter->equals_insensitive(Component);
2087 if (!SuggestReplacement)
2089 Component = *RealPathComponentIter;
2091 ++RealPathComponentIter;
2094 return SuggestReplacement;
2103 Module *ShadowingModule =
nullptr;
2109 Diags.Report(MissingHeader.
FileNameLoc, diag::err_module_header_missing)
2111 }
else if (ShadowingModule) {
2114 diag::note_previous_definition);
2125std::pair<ConstSearchDirIterator, const FileEntry *>
2126Preprocessor::getIncludeNextStart(
const Token &IncludeNextTok)
const {
2131 const FileEntry *LookupFromFile =
nullptr;
2139 Diag(IncludeNextTok, diag::pp_include_next_in_primary);
2140 }
else if (CurLexerSubmodule) {
2143 assert(CurPPLexer &&
"#include_next directive in macro?");
2144 if (
auto FE = CurPPLexer->getFileEntry())
2145 LookupFromFile = *FE;
2147 }
else if (!Lookup) {
2152 Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
2158 return {Lookup, LookupFromFile};
2174 if (FilenameTok.
isNot(tok::header_name)) {
2175 if (FilenameTok.
is(tok::identifier) &&
2176 (PPOpts.SingleFileParseMode || PPOpts.SingleModuleParseMode)) {
2186 if (FilenameTok.
isNot(tok::eod))
2195 SourceLocation EndLoc =
2198 auto Action = HandleHeaderIncludeOrImport(HashLoc, IncludeTok, FilenameTok,
2199 EndLoc, LookupFrom, LookupFromFile);
2200 switch (Action.Kind) {
2201 case ImportAction::None:
2202 case ImportAction::SkippedModuleImport:
2204 case ImportAction::ModuleBegin:
2206 tok::annot_module_begin, Action.ModuleForHeader);
2208 case ImportAction::HeaderUnitImport:
2210 Action.ModuleForHeader);
2212 case ImportAction::ModuleImport:
2214 tok::annot_module_include, Action.ModuleForHeader);
2216 case ImportAction::Failure:
2217 assert(TheModuleLoader.HadFatalFailure &&
2218 "This should be an early exit only to a fatal error");
2219 TheModuleLoader.HadFatalFailure =
true;
2221 CurLexer->cutOffLexing();
2229 const Token &FilenameTok,
bool &IsFrameworkFound,
bool IsImportDecl,
2231 const FileEntry *LookupFromFile, StringRef &LookupFilename,
2234 auto DiagnoseHeaderInclusion = [&](FileEntryRef FE) {
2235 if (LangOpts.AsmPreprocessor)
2239 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
2240 bool RequestingModuleIsModuleInterface =
2241 !SourceMgr.isInMainFile(FilenameLoc);
2243 HeaderInfo.getModuleMap().diagnoseHeaderInclusion(
2244 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
2249 FilenameLoc, LookupFilename, isAngled, LookupFrom, LookupFromFile, CurDir,
2250 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2251 &SuggestedModule, &IsMapped, &IsFrameworkFound);
2253 DiagnoseHeaderInclusion(*
File);
2258 if (Callbacks && Callbacks->FileNotFound(Filename))
2259 return std::nullopt;
2261 if (SuppressIncludeNotFoundError)
2262 return std::nullopt;
2269 FilenameLoc, LookupFilename,
false, LookupFrom, LookupFromFile, CurDir,
2270 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2271 &SuggestedModule, &IsMapped,
2274 DiagnoseHeaderInclusion(*
File);
2275 Diag(FilenameTok, diag::err_pp_file_not_found_angled_include_not_fatal)
2276 << Filename << IsImportDecl
2278 "\"" + Filename.str() +
"\"");
2285 StringRef OriginalFilename = Filename;
2286 if (LangOpts.SpellChecking) {
2289 auto CorrectTypoFilename = [](llvm::StringRef Filename) {
2292 Filename = Filename.drop_back();
2296 StringRef TypoCorrectionName = CorrectTypoFilename(Filename);
2297 StringRef TypoCorrectionLookupName = CorrectTypoFilename(LookupFilename);
2300 FilenameLoc, TypoCorrectionLookupName, isAngled, LookupFrom,
2301 LookupFromFile, CurDir, Callbacks ? &SearchPath :
nullptr,
2302 Callbacks ? &RelativePath :
nullptr, &SuggestedModule, &IsMapped,
2305 DiagnoseHeaderInclusion(*
File);
2308 FilenameRange,
"<" + TypoCorrectionName.str() +
">")
2309 : FixItHint::CreateReplacement(
2310 FilenameRange,
"\"" + TypoCorrectionName.str() +
"\"");
2311 Diag(FilenameTok, diag::err_pp_file_not_found_typo_not_fatal)
2312 << OriginalFilename << TypoCorrectionName << Hint;
2315 Filename = TypoCorrectionName;
2316 LookupFilename = TypoCorrectionLookupName;
2322 assert(!
File &&
"expected missing file");
2323 Diag(FilenameTok, diag::err_pp_file_not_found)
2324 << OriginalFilename << FilenameRange;
2325 if (IsFrameworkFound) {
2326 size_t SlashPos = OriginalFilename.find(
'/');
2327 assert(SlashPos != StringRef::npos &&
2328 "Include with framework name should have '/' in the filename");
2329 StringRef FrameworkName = OriginalFilename.substr(0, SlashPos);
2330 FrameworkCacheEntry &CacheEntry =
2331 HeaderInfo.LookupFrameworkCache(FrameworkName);
2332 assert(CacheEntry.
Directory &&
"Found framework should be in cache");
2333 Diag(FilenameTok, diag::note_pp_framework_without_header)
2334 << OriginalFilename.substr(SlashPos + 1) << FrameworkName
2338 return std::nullopt;
2353Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
2357 SmallString<128> FilenameBuffer;
2358 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
2359 SourceLocation CharEnd = FilenameTok.
getEndLoc();
2361 CharSourceRange FilenameRange
2363 StringRef OriginalFilename = Filename;
2369 if (Filename.empty())
2370 return {ImportAction::None};
2371 if (Filename.ends_with(
' ') || Filename.ends_with(
'.')) {
2372 unsigned Selection = Filename.ends_with(
'.') ? 1 : 0;
2373 Diag(FilenameTok, diag::pp_nonportable_path_trailing)
2374 << Filename << Selection;
2377 bool IsImportDecl = HashLoc.
isInvalid();
2378 SourceLocation StartLoc = IsImportDecl ? IncludeTok.
getLocation() : HashLoc;
2381 if (PragmaARCCFCodeAuditedInfo.getLoc().isValid()) {
2382 Diag(StartLoc, diag::err_pp_include_in_arc_cf_code_audited) << IsImportDecl;
2383 Diag(PragmaARCCFCodeAuditedInfo.getLoc(), diag::note_pragma_entered_here);
2386 PragmaARCCFCodeAuditedInfo = IdentifierLoc();
2390 if (PragmaAssumeNonNullLoc.isValid()) {
2391 Diag(StartLoc, diag::err_pp_include_in_assume_nonnull) << IsImportDecl;
2392 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
2395 PragmaAssumeNonNullLoc = SourceLocation();
2398 if (HeaderInfo.HasIncludeAliasMap()) {
2402 StringRef NewName = HeaderInfo.MapHeaderToIncludeAlias(OriginalFilename);
2403 if (!NewName.empty())
2408 bool IsMapped =
false;
2409 bool IsFrameworkFound =
false;
2411 SmallString<1024> SearchPath;
2412 SmallString<1024> RelativePath;
2415 ModuleMap::KnownHeader SuggestedModule;
2416 SourceLocation FilenameLoc = FilenameTok.
getLocation();
2417 StringRef LookupFilename = Filename;
2421 SmallString<128> NormalizedPath;
2422 llvm::sys::path::Style BackslashStyle = llvm::sys::path::Style::native;
2423 if (is_style_posix(BackslashStyle) && LangOpts.MicrosoftExt) {
2424 NormalizedPath = Filename.str();
2425 llvm::sys::path::native(NormalizedPath);
2426 LookupFilename = NormalizedPath;
2427 BackslashStyle = llvm::sys::path::Style::windows;
2431 &CurDir, Filename, FilenameLoc, FilenameRange, FilenameTok,
2432 IsFrameworkFound, IsImportDecl, IsMapped, LookupFrom, LookupFromFile,
2433 LookupFilename, RelativePath, SearchPath, SuggestedModule, isAngled);
2437 SkippingUntilPCHThroughHeader =
false;
2438 return {ImportAction::None};
2456 enum { Enter,
Import,
Skip, IncludeLimitReached } Action = Enter;
2457 bool DependencyScanModuleImport =
false;
2459 if (PPOpts.SingleFileParseMode)
2460 Action = IncludeLimitReached;
2465 if (Action == Enter && HasReachedMaxIncludeDepth &&
File &&
2467 Action = IncludeLimitReached;
2474 bool MaybeTranslateInclude = Action == Enter &&
File && ModuleToImport &&
2478 bool UsableHeaderUnit =
false;
2479 if (
getLangOpts().CPlusPlusModules && ModuleToImport &&
2481 if (TrackGMFState.inGMF() || IsImportDecl)
2482 UsableHeaderUnit =
true;
2483 else if (!IsImportDecl) {
2485 ModuleToImport =
nullptr;
2489 bool UsableClangHeaderModule =
2496 if (MaybeTranslateInclude && (UsableHeaderUnit || UsableClangHeaderModule)) {
2504 diag::note_implicit_top_level_module_import_here)
2506 return {ImportAction::None};
2512 SmallVector<IdentifierLoc, 2> Path;
2513 for (
Module *Mod = ModuleToImport; Mod; Mod = Mod->Parent)
2516 std::reverse(Path.begin(), Path.end());
2522 if (PPOpts.DependencyScanningModuleMapImports &&
2527 DependencyScanModuleImport =
true;
2533 ModuleLoadResult Imported = TheModuleLoader.loadModule(
2536 assert((Imported ==
nullptr || Imported == ModuleToImport) &&
2537 "the imported module is different than the suggested one");
2543 static_cast<Module *
>(Imported)->getTopLevelModule());
2548 ModuleToImport =
nullptr;
2549 UsableClangHeaderModule =
false;
2557 Token &
Result = IncludeTok;
2558 assert(CurLexer &&
"#include but no current lexer set!");
2560 CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
2561 CurLexer->cutOffLexing();
2563 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 = (UsableClangHeaderModule && !
getLangOpts().CompilingPCH) ? Import
2615 if (Action == Enter &&
File && PreambleConditionalStack.isRecording() &&
2616 SourceMgr.isMainFile(
File->getFileEntry())) {
2618 diag::err_pp_including_mainfile_in_preamble);
2619 return {ImportAction::None};
2622 if (Callbacks && !IsImportDecl) {
2625 Callbacks->InclusionDirective(
2626 HashLoc, IncludeTok, LookupFilename, isAngled, FilenameRange,
File,
2627 SearchPath, RelativePath, SuggestedModule.
getModule(),
2628 Action == Import || DependencyScanModuleImport, FileCharacter);
2630 Callbacks->FileSkipped(*
File, FilenameTok, FileCharacter);
2634 return {ImportAction::None};
2638 if (IsImportDecl && !ModuleToImport) {
2639 Diag(FilenameTok, diag::err_header_import_not_header_unit)
2640 << OriginalFilename <<
File->getName();
2641 return {ImportAction::None};
2646 const bool CheckIncludePathPortability =
2647 !IsMapped && !
File->getFileEntry().tryGetRealPathName().empty();
2649 if (CheckIncludePathPortability) {
2650 StringRef Name = LookupFilename;
2651 StringRef NameWithoriginalSlashes = Filename;
2655 bool NameWasUNC = Name.consume_front(
"\\\\?\\");
2656 NameWithoriginalSlashes.consume_front(
"\\\\?\\");
2658 StringRef RealPathName =
File->getFileEntry().tryGetRealPathName();
2659 SmallVector<StringRef, 16> Components(llvm::sys::path::begin(Name),
2660 llvm::sys::path::end(Name));
2672 SmallString<128> FixedDriveRealPath;
2673 if (llvm::sys::path::is_absolute(Name) &&
2674 llvm::sys::path::is_absolute(RealPathName) &&
2677 assert(Components.size() >= 3 &&
"should have drive, backslash, name");
2678 assert(Components[0].size() == 2 &&
"should start with drive");
2679 assert(Components[0][1] ==
':' &&
"should have colon");
2680 FixedDriveRealPath = (Name.substr(0, 1) + RealPathName.substr(1)).str();
2681 RealPathName = FixedDriveRealPath;
2686 SmallString<128> Path;
2687 Path.reserve(Name.size()+2);
2688 Path.push_back(isAngled ?
'<' :
'"');
2690 const auto IsSep = [BackslashStyle](
char c) {
2691 return llvm::sys::path::is_separator(c, BackslashStyle);
2694 for (
auto Component : Components) {
2706 if (!(Component.size() == 1 && IsSep(Component[0])))
2707 Path.append(Component);
2708 else if (Path.size() != 1)
2712 if (Path.size() > NameWithoriginalSlashes.size()) {
2713 Path.push_back(isAngled ?
'>' :
'"');
2716 assert(IsSep(NameWithoriginalSlashes[Path.size()-1]));
2718 Path.push_back(NameWithoriginalSlashes[Path.size()-1]);
2719 while (Path.size() <= NameWithoriginalSlashes.size() &&
2720 IsSep(NameWithoriginalSlashes[Path.size()-1]));
2726 Path = (Path.substr(0, 1) +
"\\\\?\\" + Path.substr(1)).str();
2733 ? diag::pp_nonportable_path
2734 : diag::pp_nonportable_system_path;
2735 Diag(FilenameTok, DiagId) << Path <<
2739 bool SuppressBackslashDiag =
2741 Diags->isIgnored(diag::pp_nonportable_path_separator, FilenameLoc) ||
2744 SourceMgr.isWrittenInBuiltinFile(FilenameLoc) ||
2745 SourceMgr.isWrittenInModuleIncludes(FilenameLoc);
2746 if (!SuppressBackslashDiag && OriginalFilename.contains(
'\\')) {
2747 std::string SuggestedPath = OriginalFilename.str();
2748 llvm::replace(SuggestedPath,
'\\',
'/');
2749 Diag(FilenameTok, diag::pp_nonportable_path_separator)
2758 return {ImportAction::SkippedModuleImport, ModuleToImport};
2759 return {ImportAction::None};
2761 case IncludeLimitReached:
2764 return {ImportAction::None};
2768 assert(ModuleToImport &&
"no module to import");
2773 tok::pp___include_macros)
2774 return {ImportAction::None};
2776 return {ImportAction::ModuleImport, ModuleToImport};
2784 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
2785 Diag(FilenameTok, diag::err_pp_include_too_deep);
2786 HasReachedMaxIncludeDepth =
true;
2787 return {ImportAction::None};
2791 Diag(FilenameTok, diag::warn_pp_include_angled_in_module_purview)
2795 SourceLocation IncludePos = FilenameTok.
getLocation();
2799 IncludePos = SourceMgr.getExpansionRange(IncludePos).getEnd();
2800 FileID FID = SourceMgr.createFileID(*
File, IncludePos, FileCharacter);
2802 TheModuleLoader.HadFatalFailure =
true;
2803 return ImportAction::Failure;
2808 IsFirstIncludeOfFile))
2809 return {ImportAction::None};
2813 if (ModuleToImport && !ModuleToImport->
isHeaderUnit()) {
2818 diag::err_module_build_shadowed_submodule)
2821 diag::note_previous_definition);
2822 return {ImportAction::None};
2834 return {ImportAction::None};
2836 assert(!CurLexerSubmodule &&
"should not have marked this as a module yet");
2837 CurLexerSubmodule = ModuleToImport;
2847 return {ImportAction::ModuleBegin, ModuleToImport};
2850 assert(!IsImportDecl &&
"failed to diagnose missing module for import decl");
2851 return {ImportAction::None};
2856void Preprocessor::HandleIncludeNextDirective(
SourceLocation HashLoc,
2857 Token &IncludeNextTok) {
2858 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
2861 const FileEntry *LookupFromFile;
2862 std::tie(Lookup, LookupFromFile) = getIncludeNextStart(IncludeNextTok);
2864 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
2869void Preprocessor::HandleMicrosoftImportDirective(
Token &
Tok) {
2875 Diag(
Tok, diag::err_pp_import_directive_ms );
2886 if (!LangOpts.ObjC) {
2887 if (LangOpts.MSVCCompat)
2888 return HandleMicrosoftImportDirective(ImportTok);
2889 Diag(ImportTok, diag::ext_pp_import_directive);
2891 return HandleIncludeDirective(HashLoc, ImportTok);
2898void Preprocessor::HandleIncludeMacrosDirective(
SourceLocation HashLoc,
2899 Token &IncludeMacrosTok) {
2903 SourceLocation Loc = IncludeMacrosTok.
getLocation();
2904 FileID FID = SourceMgr.getFileID(Loc);
2907 diag::pp_include_macros_out_of_predefines);
2914 HandleIncludeDirective(HashLoc, IncludeMacrosTok);
2919 assert(TmpTok.
isNot(tok::eof) &&
"Didn't find end of -imacros!");
2920 }
while (TmpTok.
isNot(tok::hashhash));
2942 Diag(
Tok, diag::err_pp_expected_ident_in_arg_list);
2946 Diag(
Tok, LangOpts.CPlusPlus11 ?
2947 diag::warn_cxx98_compat_variadic_macro :
2948 diag::ext_variadic_macro);
2951 if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus) {
2952 Diag(
Tok, diag::ext_pp_opencl_variadic_macros);
2958 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2967 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2975 Diag(
Tok, diag::err_pp_invalid_tok_in_arg_list);
2981 if (llvm::is_contained(Parameters, II)) {
2982 Diag(
Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
2994 Diag(
Tok, diag::err_pp_expected_comma_in_arg_list);
3003 Diag(
Tok, diag::ext_named_variadic_macro);
3008 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
3038 StringRef ValueText = II->
getName();
3039 StringRef TrimmedValue = ValueText;
3040 if (!ValueText.starts_with(
"__")) {
3041 if (ValueText.starts_with(
"_"))
3042 TrimmedValue = TrimmedValue.drop_front(1);
3046 TrimmedValue = TrimmedValue.drop_front(2);
3047 if (TrimmedValue.ends_with(
"__"))
3048 TrimmedValue = TrimmedValue.drop_back(2);
3050 return TrimmedValue == MacroText;
3057 return MacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
3070MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
3071 const Token &MacroNameTok,
const bool ImmediatelyAfterHeaderGuard) {
3073 Token LastTok = MacroNameTok;
3081 llvm::scope_exit _([&]() {
3083 if (CurLexer->ParsingPreprocessorDirective)
3094 if (
Tok.
is(tok::eod)) {
3095 if (ImmediatelyAfterHeaderGuard) {
3105 }
else if (
Tok.
is(tok::l_paren)) {
3108 if (ReadMacroParameterList(MI, LastTok))
3122 }
else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
3125 Diag(
Tok, diag::ext_c99_whitespace_required_after_macro_name);
3134 if (
Tok.
is(tok::at))
3136 else if (
Tok.
is(tok::unknown)) {
3143 Diag(
Tok, diag::ext_missing_whitespace_after_macro_name);
3145 Diag(
Tok, diag::warn_missing_whitespace_after_macro_name);
3148 if (!
Tok.
is(tok::eod))
3151 SmallVector<Token, 16> Tokens;
3158 Tokens.push_back(
Tok);
3172 if (!
Tok.
isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
3173 Tokens.push_back(
Tok);
3175 if (VAOCtx.isVAOptToken(
Tok)) {
3177 if (VAOCtx.isInVAOpt()) {
3178 Diag(
Tok, diag::err_pp_vaopt_nested_use);
3184 Diag(
Tok, diag::err_pp_missing_lparen_in_vaopt_use);
3187 Tokens.push_back(
Tok);
3190 if (
Tok.
is(tok::hashhash)) {
3191 Diag(
Tok, diag::err_vaopt_paste_at_start);
3195 }
else if (VAOCtx.isInVAOpt()) {
3196 if (
Tok.
is(tok::r_paren)) {
3197 if (VAOCtx.sawClosingParen()) {
3198 assert(Tokens.size() >= 3 &&
3199 "Must have seen at least __VA_OPT__( "
3200 "and a subsequent tok::r_paren");
3201 if (Tokens[Tokens.size() - 2].is(tok::hashhash)) {
3202 Diag(
Tok, diag::err_vaopt_paste_at_end);
3206 }
else if (
Tok.
is(tok::l_paren)) {
3220 Tokens.push_back(
Tok);
3227 if (
Tok.
is(tok::hashhash)) {
3235 if (
Tok.
is(tok::eod)) {
3236 Tokens.push_back(LastTok);
3241 Tokens[Tokens.size() - 1].is(tok::comma))
3245 Tokens.push_back(LastTok);
3254 if (!VAOCtx.isVAOptToken(
Tok) &&
3263 LastTok.
setKind(tok::unknown);
3264 Tokens.push_back(LastTok);
3267 Diag(
Tok, diag::err_pp_stringize_not_parameter)
3268 << LastTok.
is(tok::hashat);
3274 Tokens.push_back(LastTok);
3279 if (!VAOCtx.isVAOptToken(
Tok)) {
3280 Tokens.push_back(
Tok);
3287 if (VAOCtx.isInVAOpt()) {
3288 assert(
Tok.
is(tok::eod) &&
"Must be at End Of preprocessing Directive");
3289 Diag(
Tok, diag::err_pp_expected_after)
3290 << LastTok.
getKind() << tok::r_paren;
3291 Diag(VAOCtx.getUnmatchedOpeningParenLoc(), diag::note_matching) << tok::l_paren;
3302 return II->
isStr(
"__strong") || II->
isStr(
"__weak") ||
3303 II->
isStr(
"__unsafe_unretained") || II->
isStr(
"__autoreleasing");
3308void Preprocessor::HandleDefineDirective(
3309 Token &DefineTok,
const bool ImmediatelyAfterHeaderGuard) {
3313 bool MacroShadowsKeyword;
3314 ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
3317 if (MacroNameTok.
is(tok::eod))
3324 emitFinalMacroWarning(MacroNameTok,
false);
3328 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
3330 MacroInfo *
const MI = ReadOptionalMacroParameterListAndBody(
3331 MacroNameTok, ImmediatelyAfterHeaderGuard);
3335 if (MacroShadowsKeyword &&
3337 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
3342 if (NumTokens != 0) {
3354 if (SkippingUntilPCHThroughHeader) {
3357 LangOpts.MicrosoftExt))
3361 if (!LangOpts.MicrosoftExt)
3372 emitFinalMacroWarning(MacroNameTok,
false);
3383 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) &&
3385 LangOpts.MicrosoftExt)) {
3396 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) {
3404 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
3408 !MI->
isIdenticalTo(*OtherMI, *
this, LangOpts.MicrosoftExt)) {
3418 DefMacroDirective *MD =
3426 !MacroExpansionInDirectivesOverride &&
3435 Callbacks->MacroDefined(MacroNameTok, MD);
3440void Preprocessor::HandleUndefDirective() {
3444 ReadMacroName(MacroNameTok,
MU_Undef);
3447 if (MacroNameTok.
is(tok::eod))
3456 UndefMacroDirective *Undef =
nullptr;
3459 emitFinalMacroWarning(MacroNameTok,
true);
3469 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
3474 Undef = AllocateUndefMacroDirective(MacroNameTok.
getLocation());
3480 Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
3495void Preprocessor::HandleIfdefDirective(
Token &
Result,
3496 const Token &HashToken,
3498 bool ReadAnyTokensBeforeDirective) {
3500 Token DirectiveTok =
Result;
3503 ReadMacroName(MacroNameTok);
3506 if (MacroNameTok.
is(tok::eod)) {
3509 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3524 if (CurPPLexer->getConditionalStackDepth() == 0) {
3529 if (!ReadAnyTokensBeforeDirective && !MI) {
3530 assert(isIfndef &&
"#ifdef shouldn't reach here");
3531 CurPPLexer->MIOpt.EnterTopLevelIfndef(MII, MacroNameTok.
getLocation());
3533 CurPPLexer->MIOpt.EnterTopLevelConditional();
3542 Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3544 Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3547 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3551 if (PPOpts.SingleFileParseMode && !MI) {
3554 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3557 }
else if (PPOpts.SingleModuleParseMode && !MI) {
3561 SkipExcludedConditionalBlock(
3564 }
else if (!MI == isIfndef || RetainExcludedCB) {
3566 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3571 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3580void Preprocessor::HandleIfDirective(
Token &IfToken,
3581 const Token &HashToken,
3582 bool ReadAnyTokensBeforeDirective) {
3586 IdentifierInfo *IfNDefMacro =
nullptr;
3587 const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
3588 const bool ConditionalTrue = DER.Conditional;
3596 if (CurPPLexer->getConditionalStackDepth() == 0) {
3597 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
3599 CurPPLexer->MIOpt.EnterTopLevelIfndef(IfNDefMacro, IfToken.
getLocation());
3601 CurPPLexer->MIOpt.EnterTopLevelConditional();
3609 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3613 if (PPOpts.SingleFileParseMode && DER.IncludedUndefinedIds) {
3616 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3618 }
else if (PPOpts.SingleModuleParseMode && DER.IncludedUndefinedIds) {
3625 }
else if (ConditionalTrue || RetainExcludedCB) {
3627 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3639void Preprocessor::HandleEndifDirective(
Token &EndifToken) {
3645 PPConditionalInfo CondInfo;
3646 if (CurPPLexer->popConditionalLevel(CondInfo)) {
3648 Diag(EndifToken, diag::err_pp_endif_without_if);
3653 if (CurPPLexer->getConditionalStackDepth() == 0)
3654 CurPPLexer->MIOpt.ExitTopLevelConditional();
3656 assert(!CondInfo.
WasSkipping && !CurPPLexer->LexingRawMode &&
3657 "This code should only be reachable in the non-skipping case!");
3665void Preprocessor::HandleElseDirective(
Token &
Result,
const Token &HashToken) {
3671 PPConditionalInfo CI;
3672 if (CurPPLexer->popConditionalLevel(CI)) {
3678 if (CurPPLexer->getConditionalStackDepth() == 0)
3679 CurPPLexer->MIOpt.EnterTopLevelConditional();
3687 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3690 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3693 CurPPLexer->pushConditionalLevel(CI.
IfLoc,
false,
3701 true,
Result.getLocation());
3705void Preprocessor::HandleElifFamilyDirective(
Token &ElifToken,
3706 const Token &HashToken,
3717 DiagCompat(ElifToken, LangOpts.CPlusPlus ? diag_compat::cxx23_pp_directive
3718 : diag_compat::c23_pp_directive)
3730 PPConditionalInfo CI;
3731 if (CurPPLexer->popConditionalLevel(CI)) {
3732 Diag(ElifToken, diag::pp_err_elif_without_if) << DirKind;
3737 if (CurPPLexer->getConditionalStackDepth() == 0)
3738 CurPPLexer->MIOpt.EnterTopLevelConditional();
3742 Diag(ElifToken, diag::pp_err_elif_after_else) << DirKind;
3747 Callbacks->Elif(ElifToken.
getLocation(), ConditionRange,
3750 case tok::pp_elifdef:
3753 case tok::pp_elifndef:
3757 assert(
false &&
"unexpected directive kind");
3762 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3765 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3768 CurPPLexer->pushConditionalLevel(ElifToken.
getLocation(),
false,
3774 SkipExcludedConditionalBlock(
3779std::optional<LexEmbedParametersResult>
3782 tok::TokenKind EndTokenKind = ForHasEmbed ? tok::r_paren : tok::eod;
3784 auto DiagMismatchedBracesAndSkipToEOD =
3786 std::pair<tok::TokenKind, SourceLocation> Matches) {
3788 Diag(Matches.second, diag::note_matching) << Matches.first;
3789 if (CurTok.
isNot(tok::eod))
3794 if (CurTok.
isNot(Kind)) {
3795 Diag(CurTok, diag::err_expected) << Kind;
3796 if (CurTok.
isNot(tok::eod))
3813 auto LexPPParameterName = [&]() -> std::optional<std::string> {
3816 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3817 return std::nullopt;
3824 if (CurTok.
is(tok::coloncolon)) {
3827 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3828 return std::nullopt;
3834 return (llvm::Twine(Prefix->
getName()) +
"::" + Suffix->
getName()).str();
3836 return Prefix->
getName().str();
3843 auto NormalizeParameterName = [](StringRef Name) {
3844 if (Name.size() > 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
3845 return Name.substr(2, Name.size() - 4);
3849 auto LexParenthesizedIntegerExpr = [&]() -> std::optional<size_t> {
3852 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3853 return std::nullopt;
3858 bool EvaluatedDefined;
3859 DirectiveEvalResult LimitEvalResult = EvaluateDirectiveExpression(
3860 ParameterIfNDef, CurTok, EvaluatedDefined,
false);
3862 if (!LimitEvalResult.Value) {
3865 assert(CurTok.
is(tok::eod) &&
"expect to be at the end of directive");
3866 return std::nullopt;
3869 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3870 return std::nullopt;
3877 if (EvaluatedDefined) {
3878 Diag(CurTok, diag::err_defined_in_pp_embed);
3879 return std::nullopt;
3882 if (LimitEvalResult.Value) {
3883 const llvm::APSInt &
Result = *LimitEvalResult.Value;
3884 if (
Result.isNegative()) {
3885 Diag(CurTok, diag::err_requires_positive_value)
3887 if (CurTok.
isNot(EndTokenKind))
3889 return std::nullopt;
3891 return Result.getLimitedValue();
3893 return std::nullopt;
3899 return tok::r_paren;
3901 return tok::r_brace;
3903 return tok::r_square;
3905 llvm_unreachable(
"should not get here");
3909 auto LexParenthesizedBalancedTokenSoup =
3911 std::vector<std::pair<tok::TokenKind, SourceLocation>> BracketStack;
3914 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3918 bool WaitingForInnerCloseParen =
false;
3919 while (CurTok.
isNot(tok::eod) &&
3920 (WaitingForInnerCloseParen || CurTok.
isNot(tok::r_paren))) {
3925 WaitingForInnerCloseParen =
true;
3932 WaitingForInnerCloseParen =
false;
3935 case tok::r_square: {
3936 if (BracketStack.empty()) {
3937 ExpectOrDiagAndSkipToEOD(tok::r_paren);
3941 GetMatchingCloseBracket(BracketStack.back().first);
3942 if (CurTok.
getKind() != Matching) {
3943 DiagMismatchedBracesAndSkipToEOD(Matching, BracketStack.back());
3946 BracketStack.pop_back();
3949 Tokens.push_back(CurTok);
3954 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3962 while (!CurTok.
isOneOf(EndTokenKind, tok::eod)) {
3964 std::optional<std::string> ParamName = LexPPParameterName();
3966 return std::nullopt;
3967 StringRef
Parameter = NormalizeParameterName(*ParamName);
3974 if (
Result.MaybeLimitParam)
3977 std::optional<size_t> Limit = LexParenthesizedIntegerExpr();
3979 return std::nullopt;
3982 }
else if (
Parameter ==
"clang::offset") {
3983 if (
Result.MaybeOffsetParam)
3986 std::optional<size_t> Offset = LexParenthesizedIntegerExpr();
3988 return std::nullopt;
3992 if (
Result.MaybePrefixParam)
3996 if (!LexParenthesizedBalancedTokenSoup(Soup))
3997 return std::nullopt;
3999 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
4001 if (
Result.MaybeSuffixParam)
4005 if (!LexParenthesizedBalancedTokenSoup(Soup))
4006 return std::nullopt;
4008 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
4010 if (
Result.MaybeIfEmptyParam)
4014 if (!LexParenthesizedBalancedTokenSoup(Soup))
4015 return std::nullopt;
4017 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
4019 ++
Result.UnrecognizedParams;
4023 if (CurTok.
is(tok::l_paren)) {
4025 if (!LexParenthesizedBalancedTokenSoup(Soup))
4026 return std::nullopt;
4029 Diag(ParamStartLoc, diag::err_pp_unknown_parameter) << 1 <<
Parameter;
4030 if (CurTok.
isNot(EndTokenKind))
4032 return std::nullopt;
4039void Preprocessor::HandleEmbedDirectiveImpl(
4041 StringRef BinaryContents, StringRef
FileName) {
4042 if (BinaryContents.empty()) {
4050 size_t TokCount = Toks.size();
4051 auto NewToks = std::make_unique<Token[]>(TokCount);
4052 llvm::copy(Toks, NewToks.get());
4053 EnterTokenStream(std::move(NewToks), TokCount,
true,
true);
4060 size_t TotalNumToks = 1 + NumPrefixToks + NumSuffixToks;
4062 auto Toks = std::make_unique<Token[]>(TotalNumToks);
4067 CurIdx += NumPrefixToks;
4070 EmbedAnnotationData *
Data =
new (BP) EmbedAnnotationData;
4071 Data->BinaryData = BinaryContents;
4079 CurIdx += NumSuffixToks;
4082 assert(CurIdx == TotalNumToks &&
"Calculated the incorrect number of tokens");
4083 EnterTokenStream(std::move(Toks), TotalNumToks,
true,
true);
4090 Diag(EmbedTok, diag::warn_compat_pp_embed_directive);
4092 Diag(EmbedTok, diag::ext_pp_embed_directive)
4093 << (LangOpts.CPlusPlus ? 1 : 0);
4100 if (FilenameTok.
isNot(tok::header_name)) {
4102 if (FilenameTok.
isNot(tok::eod))
4115 std::optional<LexEmbedParametersResult> Params =
4118 assert((Params || CurTok.
is(tok::eod)) &&
4119 "expected success or to be at the end of the directive");
4124 SmallString<128> FilenameBuffer;
4125 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
4126 StringRef OriginalFilename = Filename;
4132 if (Filename.empty())
4137 if (!MaybeFileRef) {
4139 if (Callbacks && Callbacks->EmbedFileNotFound(Filename)) {
4142 Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
4147 Diag(FilenameTok, diag::err_pp_embed_device_file) << Filename;
4151 std::optional<llvm::MemoryBufferRef> MaybeFile =
4155 Diag(FilenameTok, diag::err_cannot_open_file)
4156 << Filename <<
"a buffer to the contents could not be created";
4159 StringRef BinaryContents = MaybeFile->getBuffer();
4164 if (Params->MaybeOffsetParam) {
4169 BinaryContents = BinaryContents.substr(Params->MaybeOffsetParam->Offset);
4172 if (Params->MaybeLimitParam) {
4176 BinaryContents = BinaryContents.substr(0, Params->MaybeLimitParam->Limit);
4180 Callbacks->EmbedDirective(HashLoc, Filename, isAngled, MaybeFileRef,
4189 void *Mem = BP.Allocate(OriginalFilename.size(),
alignof(
char *));
4190 memcpy(Mem, OriginalFilename.data(), OriginalFilename.size());
4191 StringRef FilenameToGo =
4192 StringRef(
static_cast<char *
>(Mem), OriginalFilename.size());
4193 HandleEmbedDirectiveImpl(HashLoc, *Params, BinaryContents, FilenameToGo);
4206 assert(
getLangOpts().CPlusPlusModules && ImportTok.
is(tok::kw_import));
4208 this->ImportingCXXNamedModules,
true);
4212 if (
Tok.isNot(tok::eod))
4220 bool ImportingHeader =
false;
4221 bool IsPartition =
false;
4223 switch (
Tok.getKind()) {
4224 case tok::header_name:
4225 ImportingHeader =
true;
4226 DirToks.push_back(
Tok);
4227 Lex(DirToks.emplace_back());
4231 DirToks.push_back(
Tok);
4232 UseLoc =
Tok.getLocation();
4235 case tok::code_completion:
4236 case tok::identifier: {
4238 Path, DirToks,
true,
4242 std::string FlatName;
4244 (IsPartition && ModuleDeclState.isNamedModule()) || !IsPartition;
4245 if (Callbacks && IsValid) {
4246 if (IsPartition && ModuleDeclState.isNamedModule()) {
4247 FlatName += ModuleDeclState.getPrimaryName();
4252 SourceLocation StartLoc = IsPartition ? UseLoc : Path[0].getLoc();
4264 DirToks.push_back(
Tok);
4270 if (!DirToks.back().isOneOf(tok::semi, tok::eod))
4273 if (DirToks.back().isNot(tok::eod))
4279 if (DirToks.back().isNot(tok::semi)) {
4284 if (ImportingHeader) {
4290 Diag(SemiLoc, diag::err_header_import_semi_in_macro);
4292 auto Action = HandleHeaderIncludeOrImport(
4294 switch (Action.Kind) {
4295 case ImportAction::None:
4298 case ImportAction::ModuleBegin:
4301 tok::annot_module_begin, SemiLoc, Action.ModuleForHeader));
4304 case ImportAction::ModuleImport:
4305 case ImportAction::HeaderUnitImport:
4306 case ImportAction::SkippedModuleImport:
4309 DirToks[1].setKind(tok::annot_header_unit);
4310 DirToks[1].setAnnotationEndLoc(DirToks[0].getLocation());
4311 DirToks[1].setAnnotationValue(Action.ModuleForHeader);
4314 case ImportAction::Failure:
4315 assert(TheModuleLoader.HadFatalFailure &&
4316 "This should be an early exit only to a fatal error");
4317 CurLexer->cutOffLexing();
4346 assert(
getLangOpts().CPlusPlusModules && ModuleTok.
is(tok::kw_module));
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);
4411 if (!DirToks.back().isOneOf(tok::semi, tok::eod)) {
4418 DirToks.back().isNot(tok::eod)
4422 : DirToks.pop_back_val().getLocation();
4424 bool IsGMFIntroducer = DirToks.size() == 2 && DirToks[0].is(tok::kw_module) &&
4425 DirToks[1].is(tok::semi);
4426 bool IsSynthesizedGMF = IsGMFIntroducer && HasSynthesizedGMF &&
4429 if (!IncludeMacroStack.empty() && !IsSynthesizedGMF) {
4430 Diag(StartLoc, diag::err_pp_module_decl_in_header)
4434 if (CurPPLexer->getConditionalStackDepth() != 0) {
4435 Diag(StartLoc, diag::err_pp_cond_span_module_decl)
4444 if (IsGMFIntroducer)
4445 EnterDeferredGMFInputs(End);
4462void Preprocessor::HandleObjCImportDirective(
Token &AtTok,
Token &ImportTok) {
4465 ImportTok.
setKind(tok::kw_import);
4480 if (!DirToks.back().isOneOf(tok::semi, tok::eod))
4484 DirToks.back().isNot(tok::eod)
4488 : DirToks.pop_back_val().getLocation();
4490 Module *Imported =
nullptr;
4499 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 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 std::optional< StringRef > findSimilarStr(StringRef LHS, ArrayRef< StringRef > Candidates)
Find a similar string in Candidates.
static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II)
Defines the clang::Preprocessor interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines the clang::SourceLocation class and associated facilities.
static bool isInvalid(LocType Loc, bool *Invalid)
Defines the SourceManager interface.
Defines the clang::TokenKind enum and support functions.
VerifyDiagnosticConsumer::Directive Directive
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
ResetMacroExpansionHelper(Preprocessor *pp)
~ResetMacroExpansionHelper()
static AttrArgsInfo getCXX11AttrArgsInfo(const IdentifierInfo *Name)
Represents a byte-granular source range.
static CharSourceRange getCharRange(SourceRange R)
virtual void CodeCompleteMacroName(bool IsDefinition)
Callback invoked when performing code completion in a context where the name of a macro is expected.
A directive for a defined macro or a macro imported from a module.
Concrete class used by the front-end to report problems and issues.
A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...
StringRef getName() const
bool isDeviceFile() const
const FileEntry & getFileEntry() const
DirectoryEntryRef getDir() const
Cached information about one file (either on disk or in the virtual file system).
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements support for file system lookup, file system caching, and directory search management.
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true, bool IsText=true)
Get a FileEntryRef if it exists, without doing anything on error.
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
One of these records is kept for each identifier that is lexed.
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.
bool isCPlusPlusOperatorKeyword() const
bool hadMacroDefinition() const
Returns true if this identifier was #defined to some value at any moment.
bool hasMacroDefinition() const
Return true if this identifier is #defined to some other value.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
bool isKeyword(const LangOptions &LangOpts) const
Return true if this token is a keyword in the specified language.
ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const
Determine whether this is a name reserved for the implementation (C99 7.1.3, C++ [lib....
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
A simple pair of identifier info and location.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool IsHeaderFile
Indicates whether the front-end is explicitly told that the input is a header file (i....
std::string CurrentModule
The name of the current module, of which the main source file is a part.
const MacroInfo * getMacroInfo() const
Encapsulates the data about a macro definition (e.g.
bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP, bool Syntactically) const
Return true if the specified macro definition is equal to this macro in spelling, arguments,...
bool isUsed() const
Return false if this macro is defined in the main file and has not yet been used.
bool isC99Varargs() const
bool isAllowRedefinitionsWithoutWarning() const
Return true if this macro can be redefined without warning.
void setHasCommaPasting()
unsigned getNumTokens() const
Return the number of tokens that this macro expands to.
const Token & getReplacementToken(unsigned Tok) const
void setDefinitionEndLoc(SourceLocation EndLoc)
Set the location of the last token in the macro.
bool isBuiltinMacro() const
Return true if this macro requires processing before expansion.
void setTokens(ArrayRef< Token > Tokens, llvm::BumpPtrAllocator &PPAllocator)
void setParameterList(ArrayRef< IdentifierInfo * > List, llvm::BumpPtrAllocator &PPAllocator)
Set the specified list of identifiers as the parameter list for this macro.
SourceLocation getDefinitionLoc() const
Return the location that the macro was defined at.
void setIsFunctionLike()
Function/Object-likeness.
bool isObjectLike() const
void setIsWarnIfUnused(bool val)
Set the value of the IsWarnIfUnused flag.
int getParameterNum(const IdentifierInfo *Arg) const
Return the parameter number of the specified identifier, or -1 if the identifier is not a formal para...
bool isWarnIfUnused() const
Return true if we should emit a warning if the macro is unused.
void setIsC99Varargs()
Varargs querying methods. This can only be set for function-like macros.
bool isMissingExpected() const
Determines whether the module, which failed to load, was actually a submodule that we expected to see...
bool isConfigMismatch() const
Determines whether the module failed to load due to a configuration mismatch with an explicitly-named...
virtual ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective)=0
Attempt to load the given module.
static std::string getFlatNameFromPath(ModuleIdPath Path)
@ ExcludedHeader
This header is explicitly excluded from the module.
@ TextualHeader
This header is part of the module (for layering purposes) but should be textually included.
Describes a module or submodule.
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
bool isForBuilding(const LangOptions &LangOpts) const
Determine whether this module can be built in this compilation.
@ Hidden
All of the names in this module are hidden.
SourceLocation DefinitionLoc
The location of the module definition.
ModuleKind Kind
The kind of this module.
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.
@ ModuleMapModule
This is a module that was defined by a module map and built out of header files.
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
DiagnosticBuilder DiagCompat(SourceLocation Loc, unsigned CompatDiagID) const
void HandleSkippedDirectiveWhileUsingPCH(Token &Result, SourceLocation HashLoc)
Process directives while skipping until the through header or pragma hdrstop is found.
bool isInPrimaryFile() const
Return true if we're in the top-level file, not in a #include.
void markMacroAsUsed(MacroInfo *MI)
A macro is used, update information about macros that need unused warnings.
void EnterSubmodule(Module *M, SourceLocation ImportLoc, bool ForPragma)
IdentifierInfo * LookUpIdentifierInfo(Token &Identifier) const
Given a tok::raw_identifier token, look up the identifier information for the token and install it in...
void setCodeCompletionReached()
Note that we hit the code-completion point.
StringRef getNamedModuleName() const
Get the named module name we're preprocessing.
void Lex(Token &Result)
Lex the next token for this preprocessor.
bool EnterSourceFile(FileID FID, ConstSearchDirIterator Dir, SourceLocation Loc, bool IsFirstIncludeOfFile=true)
Add a source file to the top of the include stack and start lexing tokens from it instead of the curr...
void LexNonComment(Token &Result)
Lex a token.
friend class VAOptDefinitionContext
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
SourceManager & getSourceManager() const
MacroDefinition getMacroDefinition(const IdentifierInfo *II)
bool CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef, bool *ShadowFlag=nullptr)
SourceLocation CheckEndOfDirective(StringRef DirType, bool EnableMacros=false, SmallVectorImpl< Token > *ExtraToks=nullptr)
Ensure that the next token is a tok::eod token.
static bool checkModuleIsAvailable(const LangOptions &LangOpts, const TargetInfo &TargetInfo, const Module &M, DiagnosticsEngine &Diags)
Check that the given module is available, producing a diagnostic if not.
SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart, unsigned Char) const
Given a location that specifies the start of a token, return a new location that specifies a characte...
Module * getCurrentModule()
Retrieves the module that we're currently building, if any.
OptionalFileEntryRef LookupEmbedFile(StringRef Filename, bool isAngled, bool OpenFile)
Given a "Filename" or <Filename> reference, look up the indicated embed resource.
void makeModuleVisible(Module *M, SourceLocation Loc, bool IncludeExports=true)
bool hadModuleLoaderFatalFailure() const
bool HandleModuleContextualKeyword(Token &Result)
Callback invoked when the lexer sees one of export, import or module token at the start of a line.
const TargetInfo & getTargetInfo() const
FileManager & getFileManager() const
bool LexHeaderName(Token &Result, bool AllowMacroExpansion=true)
Lex a token, forming a header-name token if possible.
bool isPCHThroughHeader(const FileEntry *FE)
Returns true if the FileEntry is the PCH through header.
friend class VariadicMacroScopeGuard
MacroInfo * AllocateMacroInfo(SourceLocation L)
Allocate a new MacroInfo object with the provided SourceLocation.
void LexUnexpandedToken(Token &Result)
Just like Lex, but disables macro expansion of identifier tokens.
bool alreadyIncluded(FileEntryRef File) const
Return true if this header has already been included.
FileID getPredefinesFileID() const
Returns the FileID for the preprocessor predefines.
void LexUnexpandedNonComment(Token &Result)
Like LexNonComment, but this disables macro expansion of identifier tokens.
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
bool GetIncludeFilenameSpelling(SourceLocation Loc, StringRef &Buffer)
Turn the specified lexer token into a fully checked and spelled filename, e.g.
PreprocessorLexer * getCurrentFileLexer() const
Return the current file lexer being lexed from.
HeaderSearch & getHeaderSearchInfo() const
void emitMacroExpansionWarnings(const Token &Identifier, bool IsIfnDef=false) const
void GetLineDirectiveFilenameSpelling(SourceLocation Loc, StringRef &Buffer)
Turn the specified lexer token into a fully checked and spelled filename, e.g.
void HandleDirective(Token &Result)
Callback invoked when the lexer sees a # token at the start of a line.
void EnterAnnotationToken(SourceRange Range, tok::TokenKind Kind, void *AnnotationVal)
Enter an annotation token into the token stream.
OptionalFileEntryRef LookupFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled, ConstSearchDirIterator FromDir, const FileEntry *FromFile, ConstSearchDirIterator *CurDir, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool *IsFrameworkFound, bool SkipCache=false, bool OpenFile=true, bool CacheFailures=true)
Given a "foo" or <foo> reference, look up the indicated file.
const LangOptions & getLangOpts() const
bool isInNamedModule() const
If we are preprocessing a named module.
OptionalFileEntryRef getHeaderToIncludeForDiagnostics(SourceLocation IncLoc, SourceLocation MLoc)
We want to produce a diagnostic at location IncLoc concerning an unreachable effect at location MLoc ...
bool isNextPPTokenOneOf(Ts... Ks) const
isNextPPTokenOneOf - Check whether the next pp-token is one of the specificed token kind.
DefMacroDirective * appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI, SourceLocation Loc)
void CollectPPImportSuffix(SmallVectorImpl< Token > &Toks, bool StopUntilEOD=false)
Collect the tokens of a C++20 pp-import-suffix.
void HandlePragmaHdrstop(Token &Tok)
DiagnosticsEngine & getDiagnostics() const
void HandleCXXModuleDirective(Token Module)
HandleCXXModuleDirective - Handle C++ module declaration directives.
std::optional< LexEmbedParametersResult > LexEmbedParameters(Token &Current, bool ForHasEmbed)
Lex the parameters for an embed directive, returns nullopt on error.
Module * getModuleForLocation(SourceLocation Loc, bool AllowTextual)
Find the module that owns the source or header file that Loc points to.
bool HandleModuleName(StringRef DirType, SourceLocation UseLoc, Token &Tok, SmallVectorImpl< IdentifierLoc > &Path, SmallVectorImpl< Token > &DirToks, bool AllowMacroExpansion, bool IsPartition)
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
bool usingPCHWithThroughHeader()
True if using a PCH with a through header.
Preprocessor(const PreprocessorOptions &PPOpts, DiagnosticsEngine &diags, const LangOptions &LangOpts, SourceManager &SM, HeaderSearch &Headers, ModuleLoader &TheModuleLoader, IdentifierInfoLookup *IILookup=nullptr, bool OwnsHeaderSearch=false, TranslationUnitKind TUKind=TU_Complete)
void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD)
Add a directive to the macro directive history for this identifier.
Represents an unpacked "presumed" location which can be presented to the user.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
SourceLocation getIncludeLoc() const
Return the presumed include location of this location.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
FileIDAndOffset getDecomposedExpansionLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
bool isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
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
static Token createAnnotation(tok::TokenKind Kind, SourceRange Range, void *Value=nullptr)
bool isModuleContextualKeyword(bool AllowExport=true) const
Return true if we have a C++20 modules contextual keyword(export, importor module).
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
bool isNot(tok::TokenKind K) const
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix.
bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const
Return true if we have an ObjC keyword identifier.
void startToken()
Reset all flags to cleared.
bool needsCleaning() const
Return true if this token has trigraphs or escaped newlines in it.
StringRef getRawIdentifier() const
getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode),...
A directive for an undefined macro.
A directive for setting the module visibility of a macro.
Defines the clang::TargetInfo interface.
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
bool Sub(InterpState &S, CodePtr OpPC)
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
PPKeywordKind
Provides a namespace for preprocessor keywords which start with a '#' at the beginning of the line.
Top level wrappers for InstallAPI frontend operations.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
bool isReservedInAllContexts(ReservedIdentifierStatus Status)
Determine whether an identifier is reserved in all contexts.
int hasAttribute(AttributeCommonInfo::Syntax Syntax, llvm::StringRef ScopeName, llvm::StringRef AttrName, const TargetInfo &Target, const LangOptions &LangOpts, bool CheckPlugins)
Return the version number associated with the attribute if we recognize and implement the attribute s...
ArrayRef< IdentifierLoc > ModuleIdPath
A sequence of identifier/location pairs used to describe a particular module or submodule,...
LLVM_READONLY char toLowercase(char c)
Converts the given ASCII character to its lowercase equivalent.
detail::SearchDirIteratorImpl< true > ConstSearchDirIterator
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
MacroUse
Context in which macro name is used.
LLVM_READONLY bool isAlphanumeric(unsigned char c)
Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Default
Set to the current date and time.
@ Parameter
The parameter type of a method or function.
@ Result
The result type of a method or function.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
LLVM_READONLY bool isLowercase(unsigned char c)
Return true if this character is a lowercase ASCII letter: [a-z].
@ PIK_HashPragma
The pragma was introduced via #pragma.
OptionalDirectoryEntryRef Directory
The directory entry which should be used for the cached framework.
std::optional< PPEmbedParameterIfEmpty > MaybeIfEmptyParam
size_t SuffixTokenCount() const
std::optional< PPEmbedParameterSuffix > MaybeSuffixParam
std::optional< PPEmbedParameterPrefix > MaybePrefixParam
size_t PrefixTokenCount() const
bool FoundNonSkip
True if we have emitted tokens already, and now we're in an #else block or something.
SourceLocation IfLoc
Location where the conditional started.
bool WasSkipping
True if this was contained in a skipping directive, e.g., in a "\#if 0" block.
bool FoundElse
True if we've seen a #else in this block.