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"
63 static_assert(std::is_trivially_destructible_v<MacroInfo>,
"");
73Preprocessor::AllocateUndefMacroDirective(
SourceLocation UndefLoc) {
80 return new (BP) VisibilityMacroDirective(Loc, isPublic);
90 while (Tmp.
isNot(tok::eod)) {
91 assert(Tmp.
isNot(tok::eof) &&
"EOF seen while discarding directive tokens");
120 static constexpr StringRef ReservedMacro[] = {
123 "_CRT_NONSTDC_NO_WARNINGS",
124 "_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES",
125 "_CRT_SECURE_NO_WARNINGS",
128 "_GLIBCXX_ASSERTIONS",
129 "_GLIBCXX_CONCEPT_CHECKS",
131 "_GLIBCXX_DEBUG_PEDANTIC",
133 "_GLIBCXX_PARALLEL_ASSERTIONS",
134 "_GLIBCXX_SANITIZE_VECTOR",
135 "_GLIBCXX_USE_CXX11_ABI",
136 "_GLIBCXX_USE_DEPRECATED",
141 "_LARGEFILE64_SOURCE",
147 "_XOPEN_SOURCE_EXTENDED",
148 "__STDCPP_WANT_MATH_SPEC_FUNCS__",
149 "__STDC_FORMAT_MACROS",
151 return llvm::binary_search(ReservedMacro, MacroName);
156 const StringRef MacroName) {
166 if (MacroName.starts_with(
"__STDC"))
169 if (MacroName ==
"__cplusplus")
172 if (MacroName.starts_with(
"__cpp"))
180 if (Lang.CPlusPlus &&
201 if (Lang.CPlusPlus11 && (
Text ==
"override" ||
Text ==
"final"))
226 if (::llvm::sys::path::begin(Include)->equals_insensitive(
"boost"))
231 static const size_t MaxStdHeaderNameLen = 18u;
232 if (Include.size() > MaxStdHeaderNameLen)
237 for (
char &Ch : LowerInclude) {
239 if (
static_cast<unsigned char>(Ch) > 0x7f)
242 if (Ch >=
'A' && Ch <=
'Z')
245 else if (::llvm::sys::path::is_separator(Ch))
250 return llvm::StringSwitch<bool>(LowerInclude)
252 .Cases({
"assert.h",
"complex.h",
"ctype.h",
"errno.h",
"fenv.h"},
true)
253 .Cases({
"float.h",
"inttypes.h",
"iso646.h",
"limits.h",
"locale.h"},
255 .Cases({
"math.h",
"setjmp.h",
"signal.h",
"stdalign.h",
"stdarg.h"},
true)
256 .Cases({
"stdatomic.h",
"stdbool.h",
"stdckdint.h",
"stdcountof.h"},
true)
257 .Cases({
"stddef.h",
"stdint.h",
"stdio.h",
"stdlib.h",
"stdnoreturn.h"},
259 .Cases({
"string.h",
"tgmath.h",
"threads.h",
"time.h",
"uchar.h"},
true)
260 .Cases({
"wchar.h",
"wctype.h"},
true)
263 .Cases({
"cassert",
"ccomplex",
"cctype",
"cerrno",
"cfenv"},
true)
264 .Cases({
"cfloat",
"cinttypes",
"ciso646",
"climits",
"clocale"},
true)
265 .Cases({
"cmath",
"csetjmp",
"csignal",
"cstdalign",
"cstdarg"},
true)
266 .Cases({
"cstdbool",
"cstddef",
"cstdint",
"cstdio",
"cstdlib"},
true)
267 .Cases({
"cstring",
"ctgmath",
"ctime",
"cuchar",
"cwchar"},
true)
268 .Case(
"cwctype",
true)
271 .Cases({
"algorithm",
"fstream",
"list",
"regex",
"thread"},
true)
272 .Cases({
"array",
"functional",
"locale",
"scoped_allocator",
"tuple"},
274 .Cases({
"atomic",
"future",
"map",
"set",
"type_traits"},
true)
276 {
"bitset",
"initializer_list",
"memory",
"shared_mutex",
"typeindex"},
278 .Cases({
"chrono",
"iomanip",
"mutex",
"sstream",
"typeinfo"},
true)
279 .Cases({
"codecvt",
"ios",
"new",
"stack",
"unordered_map"},
true)
280 .Cases({
"complex",
"iosfwd",
"numeric",
"stdexcept",
"unordered_set"},
283 {
"condition_variable",
"iostream",
"ostream",
"streambuf",
"utility"},
285 .Cases({
"deque",
"istream",
"queue",
"string",
"valarray"},
true)
286 .Cases({
"exception",
"iterator",
"random",
"strstream",
"vector"},
true)
287 .Cases({
"forward_list",
"limits",
"ratio",
"system_error"},
true)
290 .Cases({
"aio.h",
"arpa/inet.h",
"cpio.h",
"dirent.h",
"dlfcn.h"},
true)
291 .Cases({
"fcntl.h",
"fmtmsg.h",
"fnmatch.h",
"ftw.h",
"glob.h"},
true)
292 .Cases({
"grp.h",
"iconv.h",
"langinfo.h",
"libgen.h",
"monetary.h"},
true)
293 .Cases({
"mqueue.h",
"ndbm.h",
"net/if.h",
"netdb.h",
"netinet/in.h"},
295 .Cases({
"netinet/tcp.h",
"nl_types.h",
"poll.h",
"pthread.h",
"pwd.h"},
297 .Cases({
"regex.h",
"sched.h",
"search.h",
"semaphore.h",
"spawn.h"},
true)
298 .Cases({
"strings.h",
"stropts.h",
"sys/ipc.h",
"sys/mman.h",
"sys/msg.h"},
300 .Cases({
"sys/resource.h",
"sys/select.h",
"sys/sem.h",
"sys/shm.h",
303 .Cases({
"sys/stat.h",
"sys/statvfs.h",
"sys/time.h",
"sys/times.h",
307 {
"sys/uio.h",
"sys/un.h",
"sys/utsname.h",
"sys/wait.h",
"syslog.h"},
309 .Cases({
"tar.h",
"termios.h",
"trace.h",
"ulimit.h"},
true)
310 .Cases({
"unistd.h",
"utime.h",
"utmpx.h",
"wordexp.h"},
true)
322static std::optional<StringRef>
326 for (StringRef
C : Candidates) {
327 if (LHS.equals_insensitive(
C)) {
335 size_t Length = LHS.size();
336 size_t MaxDist = Length < 3 ? Length - 1 : Length / 3;
338 std::optional<std::pair<StringRef, size_t>> SimilarStr;
339 for (StringRef
C : Candidates) {
340 size_t CurDist = LHS.edit_distance(
C,
true);
341 if (CurDist <= MaxDist) {
344 SimilarStr = {
C, CurDist};
345 }
else if (CurDist < SimilarStr->second) {
347 SimilarStr = {
C, CurDist};
353 return SimilarStr->first;
362 if (MacroNameTok.
is(tok::eod))
363 return Diag(MacroNameTok, diag::err_pp_missing_macro_name);
367 return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
373 ? diag::ext_pp_operator_used_as_macro_name
374 : diag::err_pp_operator_used_as_macro_name)
375 << II << MacroNameTok.
getKind();
382 return Diag(MacroNameTok, diag::err_defined_macro_name);
395 if (!SourceMgr.isInSystemHeader(MacroNameLoc) &&
396 !SourceMgr.isInPredefinedFile(MacroNameLoc)) {
411 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id);
413 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_attribute_id)
430void Preprocessor::ReadMacroName(
Token &MacroNameTok,
MacroUse isDefineUndef,
435 if (MacroNameTok.
is(tok::code_completion)) {
447 if (MacroNameTok.
isNot(tok::eod)) {
448 MacroNameTok.
setKind(tok::eod);
472 while (Tmp.
is(tok::comment))
475 if (Tmp.
is(tok::eod))
483 if ((LangOpts.GNUMode || LangOpts.C99 || LangOpts.CPlusPlus) &&
486 Diag(Tmp, diag::ext_pp_extra_tokens_at_eol) << DirType << Hint;
490void Preprocessor::SuggestTypoedDirective(
const Token &
Tok,
491 StringRef Directive)
const {
496 std::vector<StringRef> Candidates = {
497 "if",
"ifdef",
"ifndef",
"elif",
"else",
"endif"
499 if (LangOpts.C23 || LangOpts.CPlusPlus23)
500 Candidates.insert(Candidates.end(), {
"elifdef",
"elifndef"});
504 assert(
Tok.getLocation().isFileID());
508 StringRef SuggValue = *Sugg;
511 Diag(
Tok, diag::warn_pp_invalid_directive) << 1 << SuggValue << Hint;
523void Preprocessor::SkipExcludedConditionalBlock(
SourceLocation HashTokenLoc,
525 bool FoundNonSkipPortion,
536 assert(!SkippingExcludedConditionalBlock &&
537 "calling SkipExcludedConditionalBlock recursively");
538 llvm::SaveAndRestore SARSkipping(SkippingExcludedConditionalBlock,
true);
541 assert(!CurTokenLexer &&
"Conditional PP block cannot appear in a macro!");
542 assert(CurPPLexer &&
"Conditional PP block must be in a file!");
543 assert(CurLexer &&
"Conditional PP block but no current lexer set!");
545 if (PreambleConditionalStack.reachedEOFWhileSkipping())
546 PreambleConditionalStack.clearSkipInfo();
548 CurPPLexer->pushConditionalLevel(IfTokenLoc,
false,
549 FoundNonSkipPortion, FoundElse);
553 CurPPLexer->LexingRawMode =
true;
555 SourceLocation endLoc;
559 struct SkippingRangeStateTy {
562 const char *BeginPtr =
nullptr;
563 unsigned *SkipRangePtr =
nullptr;
565 SkippingRangeStateTy(Preprocessor &PP) : PP(PP) {}
567 void beginLexPass() {
573 BeginPtr = PP.CurLexer->getBufferLocation();
574 SkipRangePtr = &PP.RecordedSkippedRanges[BeginPtr];
576 PP.CurLexer->seek(PP.CurLexer->getCurrentBufferOffset() + *SkipRangePtr,
581 void endLexPass(
const char *Hashptr) {
584 assert(PP.CurLexer->isDependencyDirectivesLexer());
589 if (!*SkipRangePtr) {
590 *SkipRangePtr = Hashptr - BeginPtr;
592 assert(*SkipRangePtr ==
unsigned(Hashptr - BeginPtr));
594 SkipRangePtr =
nullptr;
596 } SkippingRangeState(*
this);
599 if (CurLexer->isDependencyDirectivesLexer()) {
600 CurLexer->LexDependencyDirectiveTokenWhileSkipping(
Tok);
602 SkippingRangeState.beginLexPass();
606 if (
Tok.
is(tok::code_completion)) {
609 CodeComplete->CodeCompleteInConditionalExclusion();
614 if (
Tok.
is(tok::eof)) {
618 if (PreambleConditionalStack.isRecording())
619 PreambleConditionalStack.SkipInfo.emplace(HashTokenLoc, IfTokenLoc,
632 if (
Tok.
is(tok::eof))
638 CurPPLexer->ParsingPreprocessorDirective =
true;
639 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
641 assert(
Tok.
is(tok::hash));
642 const char *Hashptr = CurLexer->getBufferLocation() -
Tok.
getLength();
643 assert(CurLexer->getSourceLocation(Hashptr) ==
Tok.
getLocation());
650 if (
Tok.
isNot(tok::raw_identifier)) {
651 CurPPLexer->ParsingPreprocessorDirective =
false;
653 if (CurLexer) CurLexer->resetExtendedTokenMode();
664 char FirstChar = RI[0];
665 if (FirstChar >=
'a' && FirstChar <=
'z' &&
666 FirstChar !=
'i' && FirstChar !=
'e') {
667 CurPPLexer->ParsingPreprocessorDirective =
false;
669 if (CurLexer) CurLexer->resetExtendedTokenMode();
676 char DirectiveBuf[20];
682 size_t IdLen = DirectiveStr.size();
684 CurPPLexer->ParsingPreprocessorDirective =
false;
686 if (CurLexer) CurLexer->resetExtendedTokenMode();
689 memcpy(DirectiveBuf, &DirectiveStr[0], IdLen);
690 Directive = StringRef(DirectiveBuf, IdLen);
710 PPConditionalInfo CondInfo;
712 bool InCond = CurPPLexer->popConditionalLevel(CondInfo);
714 assert(!InCond &&
"Can't be skipping if not in a conditional!");
718 SkippingRangeState.endLexPass(Hashptr);
721 CurPPLexer->LexingRawMode =
false;
723 CurPPLexer->LexingRawMode =
true;
730 }
else if (Sub ==
"lse") {
734 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
737 SkippingRangeState.endLexPass(Hashptr);
741 Diag(
Tok, diag::pp_err_else_after_else);
752 CurPPLexer->LexingRawMode =
false;
754 CurPPLexer->LexingRawMode =
true;
761 }
else if (Sub ==
"lif") {
762 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
765 SkippingRangeState.endLexPass(Hashptr);
782 assert(CurPPLexer->LexingRawMode &&
"We have to be skipping here!");
783 CurPPLexer->LexingRawMode =
false;
784 IdentifierInfo *IfNDefMacro =
nullptr;
785 DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
789 const bool CondValue = DER.Conditional;
790 CurPPLexer->LexingRawMode =
true;
803 }
else if (Sub ==
"lifdef" ||
805 bool IsElifDef =
Sub ==
"lifdef";
806 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
807 Token DirectiveToken =
Tok;
810 SkippingRangeState.endLexPass(Hashptr);
815 if (LangOpts.CPlusPlus)
816 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
817 : diag::ext_cxx23_pp_directive;
819 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
820 : diag::ext_c23_pp_directive;
825 Diag(
Tok, diag::pp_err_elif_after_else)
839 assert(CurPPLexer->LexingRawMode &&
"We have to be skipping here!");
840 CurPPLexer->LexingRawMode =
false;
842 ReadMacroName(MacroNameTok);
843 CurPPLexer->LexingRawMode =
true;
847 if (MacroNameTok.
is(tok::eod)) {
859 MacroInfo *MI = MD.getMacroInfo();
863 Callbacks->Elifdef(DirectiveToken.
getLocation(), MacroNameTok,
866 Callbacks->Elifndef(DirectiveToken.
getLocation(), MacroNameTok,
871 if (
static_cast<bool>(MI) == IsElifDef) {
883 CurPPLexer->ParsingPreprocessorDirective =
false;
885 if (CurLexer) CurLexer->resetExtendedTokenMode();
891 CurPPLexer->LexingRawMode =
false;
896 Callbacks->SourceRangeSkipped(
897 SourceRange(HashTokenLoc, endLoc.
isValid()
899 : CurPPLexer->getSourceLocation()),
905 if (!SourceMgr.isInMainFile(Loc)) {
908 FileID IDOfIncl = SourceMgr.getFileID(SourceMgr.getExpansionLoc(Loc));
909 if (
auto EntryOfIncl = SourceMgr.getFileEntryRefForID(IDOfIncl)) {
911 return HeaderInfo.getModuleMap()
912 .findModuleForHeader(*EntryOfIncl, AllowTextual)
921 : HeaderInfo.lookupModule(
getLangOpts().CurrentModule, Loc);
928 IncLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
935 while (!Loc.
isInvalid() && !
SM.isInMainFile(Loc)) {
936 auto ID =
SM.getFileID(
SM.getExpansionLoc(Loc));
937 auto FE =
SM.getFileEntryRefForID(ID);
943 HeaderInfo.hasModuleMap(FE->getName(),
nullptr,
944 SourceMgr.isInSystemHeader(Loc));
946 bool InPrivateHeader =
false;
947 for (
auto Header : HeaderInfo.findAllModulesForHeader(*FE)) {
948 if (!Header.isAccessibleFrom(IncM)) {
953 InPrivateHeader =
true;
989 Loc =
SM.getIncludeLoc(ID);
1001 bool *IsFrameworkFound,
bool SkipCache,
bool OpenFile,
bool CacheFailures) {
1006 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
1011 bool BuildSystemModule =
false;
1012 if (!FromDir && !FromFile) {
1029 if (FID == SourceMgr.getMainFileID() && MainFileDir) {
1031 HeaderInfo.getModuleMap().shouldImportRelativeToBuiltinIncludeDir(
1033 ? HeaderInfo.getModuleMap().getBuiltinDir()
1035 Includers.push_back(std::make_pair(std::nullopt, *IncludeDir));
1037 }
else if ((FileEnt = SourceMgr.getFileEntryRefForID(
1038 SourceMgr.getMainFileID()))) {
1039 auto CWD = FileMgr.getOptionalDirectoryRef(
".");
1040 Includers.push_back(std::make_pair(*FileEnt, *CWD));
1043 Includers.push_back(std::make_pair(*FileEnt, FileEnt->
getDir()));
1049 if (LangOpts.MSVCCompat && !isAngled) {
1050 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1051 if (IsFileLexer(ISEntry))
1053 Includers.push_back(std::make_pair(*FileEnt, FileEnt->
getDir()));
1058 CurDir = CurDirLookup;
1066 Filename, FilenameLoc, isAngled, TmpFromDir, &TmpCurDir,
1067 Includers, SearchPath, RelativePath, RequestingModule,
1068 SuggestedModule,
nullptr,
1069 nullptr, SkipCache)) {
1071 TmpFromDir = TmpCurDir;
1073 if (&FE->getFileEntry() == FromFile) {
1075 FromDir = TmpFromDir;
1084 Filename, FilenameLoc, isAngled, FromDir, &CurDir, Includers, SearchPath,
1085 RelativePath, RequestingModule, SuggestedModule, IsMapped,
1086 IsFrameworkFound, SkipCache, BuildSystemModule, OpenFile, CacheFailures);
1094 if (IsFileLexer()) {
1097 Filename, *CurFileEnt, SearchPath, RelativePath, RequestingModule,
1104 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1105 if (IsFileLexer(ISEntry)) {
1106 if ((CurFileEnt = ISEntry.ThePPLexer->
getFileEntry())) {
1108 Filename, *CurFileEnt, SearchPath, RelativePath,
1109 RequestingModule, SuggestedModule)) {
1117 return std::nullopt;
1124 if (llvm::sys::path::is_absolute(Filename)) {
1127 Filename, OpenFile,
true,
false);
1128 return llvm::expectedToOptional(std::move(ShouldBeEntry));
1132 StringRef StartingFrom, StringRef
FileName,
1133 bool RemoveInitialFileComponentFromLookupPath) {
1134 llvm::sys::path::native(StartingFrom, LookupPath);
1135 if (RemoveInitialFileComponentFromLookupPath)
1136 llvm::sys::path::remove_filename(LookupPath);
1137 if (!LookupPath.empty() &&
1138 !llvm::sys::path::is_separator(LookupPath.back())) {
1139 LookupPath.push_back(llvm::sys::path::get_separator().front());
1148 if (LookupFromFile) {
1151 if (!FullFileDir.empty()) {
1152 SeparateComponents(LookupPath, FullFileDir, Filename,
true);
1154 LookupPath, OpenFile,
true,
false);
1156 return llvm::expectedToOptional(std::move(ShouldBeEntry));
1157 llvm::consumeError(ShouldBeEntry.takeError());
1164 if (MaybeWorkingDirEntry) {
1166 StringRef WorkingDir = WorkingDirEntry.
getName();
1167 if (!WorkingDir.empty()) {
1168 SeparateComponents(LookupPath, WorkingDir, Filename,
false);
1170 LookupPath, OpenFile,
true,
false);
1172 return llvm::expectedToOptional(std::move(ShouldBeEntry));
1173 llvm::consumeError(ShouldBeEntry.takeError());
1178 for (
const auto &Entry : PPOpts.EmbedEntries) {
1180 SeparateComponents(LookupPath, Entry, Filename,
false);
1182 LookupPath, OpenFile,
true,
false);
1184 return llvm::expectedToOptional(std::move(ShouldBeEntry));
1185 llvm::consumeError(ShouldBeEntry.takeError());
1187 return std::nullopt;
1197 : PP(pp), save(pp->DisableMacroExpansion) {
1198 if (pp->MacroExpansionInDirectivesOverride)
1199 pp->DisableMacroExpansion =
false;
1203 PP->DisableMacroExpansion = save;
1220 if (II->getPPKeywordID() == tok::pp_define) {
1221 return HandleDefineDirective(
Result,
1224 if (SkippingUntilPCHThroughHeader &&
1225 II->getPPKeywordID() == tok::pp_include) {
1226 return HandleIncludeDirective(HashLoc,
Result);
1228 if (SkippingUntilPragmaHdrStop && II->getPPKeywordID() == tok::pp_pragma) {
1230 auto *II =
Result.getIdentifierInfo();
1231 if (II && II->getName() ==
"hdrstop")
1248 CurPPLexer->ParsingPreprocessorDirective =
true;
1249 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
1251 bool ImmediatelyAfterTopLevelIfndef =
1252 CurPPLexer->MIOpt.getImmediatelyAfterTopLevelIfndef();
1253 CurPPLexer->MIOpt.resetImmediatelyAfterTopLevelIfndef();
1260 bool ReadAnyTokensBeforeDirective =CurPPLexer->MIOpt.getHasReadAnyTokensVal();
1279 switch (II->getPPKeywordID()) {
1280 case tok::pp_include:
1281 case tok::pp_import:
1282 case tok::pp_include_next:
1283 case tok::pp___include_macros:
1284 case tok::pp_pragma:
1286 Diag(
Result, diag::err_embedded_directive) << II->getName();
1287 Diag(*ArgMacro, diag::note_macro_expansion_here)
1288 << ArgMacro->getIdentifierInfo();
1302 if (SkippingUntilPCHThroughHeader || SkippingUntilPragmaHdrStop)
1305 switch (
Result.getKind()) {
1310 CurPPLexer->MIOpt.SetReadToken(ReadAnyTokensBeforeDirective);
1312 case tok::code_completion:
1315 CodeComplete->CodeCompleteDirective(
1316 CurPPLexer->getConditionalStackDepth() > 0);
1318 case tok::numeric_constant:
1325 return HandleDigitDirective(
Result);
1335 return HandleIfDirective(
Result, SavedHash, ReadAnyTokensBeforeDirective);
1337 return HandleIfdefDirective(
Result, SavedHash,
false,
1339 case tok::pp_ifndef:
1340 return HandleIfdefDirective(
Result, SavedHash,
true,
1341 ReadAnyTokensBeforeDirective);
1343 case tok::pp_elifdef:
1344 case tok::pp_elifndef:
1348 return HandleElseDirective(
Result, SavedHash);
1350 return HandleEndifDirective(
Result);
1353 case tok::pp_include:
1356 case tok::pp___include_macros:
1361 case tok::pp_define:
1362 return HandleDefineDirective(
Result, ImmediatelyAfterTopLevelIfndef);
1364 return HandleUndefDirective();
1368 return HandleLineDirective();
1372 return HandleUserDiagnosticDirective(
Result,
false);
1375 case tok::pp_pragma:
1379 case tok::pp_import:
1381 case tok::pp_include_next:
1384 case tok::pp_warning:
1385 if (LangOpts.CPlusPlus)
1387 ? diag::warn_cxx23_compat_warning_directive
1388 : diag::ext_pp_warning_directive)
1391 Diag(
Result, LangOpts.C23 ? diag::warn_c23_compat_warning_directive
1392 : diag::ext_pp_warning_directive)
1395 return HandleUserDiagnosticDirective(
Result,
true);
1397 return HandleIdentSCCSDirective(
Result);
1399 return HandleIdentSCCSDirective(
Result);
1400 case tok::pp_embed: {
1406 case tok::pp_assert:
1409 case tok::pp_unassert:
1413 case tok::pp___public_macro:
1415 return HandleMacroPublicDirective(
Result);
1418 case tok::pp___private_macro:
1420 return HandleMacroPrivateDirective();
1431 auto Toks = std::make_unique<Token[]>(2);
1433 Toks[0] = SavedHash;
1438 if (
Result.is(tok::hashhash))
1439 Toks[1].setKind(tok::unknown);
1444 EnterTokenStream(std::move(Toks), 2,
false,
false);
1450 Diag(
Result, diag::err_pp_invalid_directive) << 0;
1462 bool IsGNULineDirective=
false) {
1463 if (DigitTok.
isNot(tok::numeric_constant)) {
1464 PP.
Diag(DigitTok, DiagID);
1466 if (DigitTok.
isNot(tok::eod))
1472 IntegerBuffer.resize(DigitTok.
getLength());
1473 const char *DigitTokBegin = &IntegerBuffer[0];
1483 for (
unsigned i = 0; i != ActualLength; ++i) {
1486 if (DigitTokBegin[i] ==
'\'')
1489 if (!
isDigit(DigitTokBegin[i])) {
1491 diag::err_pp_line_digit_sequence) << IsGNULineDirective;
1496 unsigned NextVal = Val*10+(DigitTokBegin[i]-
'0');
1497 if (NextVal < Val) {
1498 PP.
Diag(DigitTok, DiagID);
1505 if (DigitTokBegin[0] ==
'0' && Val)
1507 << IsGNULineDirective;
1519void Preprocessor::HandleLineDirective() {
1527 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*
this))
1531 Diag(DigitTok, diag::ext_pp_line_zero);
1535 unsigned LineLimit = 32768U;
1536 if (LangOpts.C99 || LangOpts.CPlusPlus11)
1537 LineLimit = 2147483648U;
1538 if (LineNo >= LineLimit)
1539 Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
1540 else if (LangOpts.CPlusPlus11 && LineNo >= 32768U)
1541 Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
1543 int FilenameID = -1;
1549 if (StrTok.
is(tok::eod))
1551 else if (StrTok.
isNot(tok::string_literal)) {
1552 Diag(StrTok, diag::err_pp_line_invalid_filename);
1556 Diag(StrTok, diag::err_invalid_string_udl);
1561 StringLiteralParser
Literal(StrTok, *
this);
1562 assert(
Literal.isOrdinary() &&
"Didn't allow wide strings in");
1568 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1572 FilenameID = SourceMgr.getLineTableFilenameID(
Literal.GetString());
1585 SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1587 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID,
false,
1591 Callbacks->FileChanged(CurPPLexer->getSourceLocation(),
1603 if (FlagTok.
is(tok::eod))
return false;
1604 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1611 if (FlagTok.
is(tok::eod))
return false;
1612 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1614 }
else if (FlagVal == 2) {
1630 SM.getDecomposedExpansionLoc(IncLoc).first != CurFileID) {
1631 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);
1637 if (FlagTok.
is(tok::eod))
return false;
1638 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1644 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1652 if (FlagTok.
is(tok::eod))
return false;
1653 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1658 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1666 if (FlagTok.
is(tok::eod))
return false;
1669 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1681void Preprocessor::HandleDigitDirective(
Token &DigitTok) {
1685 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
1692 bool IsFileEntry =
false, IsFileExit =
false;
1693 int FilenameID = -1;
1698 if (StrTok.
is(tok::eod)) {
1699 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1701 FileKind = SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1702 }
else if (StrTok.
isNot(tok::string_literal)) {
1703 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1707 Diag(StrTok, diag::err_invalid_string_udl);
1712 StringLiteralParser
Literal(StrTok, *
this);
1713 assert(
Literal.isOrdinary() &&
"Didn't allow wide strings in");
1719 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1727 if (!SourceMgr.isInPredefinedFile(DigitTok.
getLocation()))
1728 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1732 if (!(IsFileExit &&
Literal.GetString().empty()))
1733 FilenameID = SourceMgr.getLineTableFilenameID(
Literal.GetString());
1737 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID, IsFileEntry,
1738 IsFileExit, FileKind);
1747 else if (IsFileExit)
1750 Callbacks->FileChanged(CurPPLexer->getSourceLocation(), Reason, FileKind);
1756void Preprocessor::HandleUserDiagnosticDirective(
Token &
Tok,
1764 CurLexer->ReadToEndOfLine(&Message);
1768 StringRef Msg =
Message.str().ltrim(
' ');
1771 Diag(
Tok, diag::pp_hash_warning) << Msg;
1773 Diag(
Tok, diag::err_pp_hash_error) << Msg;
1778void Preprocessor::HandleIdentSCCSDirective(
Token &
Tok) {
1780 Diag(
Tok, diag::ext_pp_ident_directive);
1787 if (StrTok.
isNot(tok::string_literal) &&
1788 StrTok.
isNot(tok::wide_string_literal)) {
1789 Diag(StrTok, diag::err_pp_malformed_ident);
1790 if (StrTok.
isNot(tok::eod))
1796 Diag(StrTok, diag::err_invalid_string_udl);
1813void Preprocessor::HandleMacroPublicDirective(
Token &
Tok) {
1815 ReadMacroName(MacroNameTok,
MU_Undef);
1818 if (MacroNameTok.
is(tok::eod))
1830 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1840void Preprocessor::HandleMacroPrivateDirective() {
1842 ReadMacroName(MacroNameTok,
MU_Undef);
1845 if (MacroNameTok.
is(tok::eod))
1857 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1877 StringRef &Buffer) {
1879 assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1891 if (Buffer[0] ==
'<') {
1892 if (Buffer.back() !=
'>') {
1893 Diag(Loc, diag::err_pp_expects_filename);
1894 Buffer = StringRef();
1898 }
else if (Buffer[0] ==
'"') {
1899 if (Buffer.back() !=
'"') {
1900 Diag(Loc, diag::err_pp_expects_filename);
1901 Buffer = StringRef();
1906 Diag(Loc, diag::err_pp_expects_filename);
1907 Buffer = StringRef();
1912 if (Buffer.size() <= 2) {
1913 Diag(Loc, diag::err_pp_empty_filename);
1914 Buffer = StringRef();
1919 Buffer = Buffer.substr(1, Buffer.size()-2);
1926 void *AnnotationVal) {
1929 auto Tok = std::make_unique<Token[]>(1);
1930 Tok[0].startToken();
1931 Tok[0].setKind(Kind);
1932 Tok[0].setLocation(Range.getBegin());
1933 Tok[0].setAnnotationEndLoc(Range.getEnd());
1934 Tok[0].setAnnotationValue(AnnotationVal);
1935 EnterTokenStream(std::move(
Tok), 1,
true,
false);
1945 for (
size_t I = 0, N = Path.size(); I != N; ++I) {
1948 PathString += Path[I].getIdentifierInfo()->getName();
1951 int IncludeKind = 0;
1953 case tok::pp_include:
1957 case tok::pp_import:
1961 case tok::pp_include_next:
1965 case tok::pp___include_macros:
1970 llvm_unreachable(
"unknown include directive kind");
1973 PP.
Diag(HashLoc, diag::remark_pp_include_directive_modular_translation)
1974 << IncludeKind << PathString;
1981 StringRef RealPathName,
1982 llvm::sys::path::Style Separator) {
1983 auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName);
1984 auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName);
1986 bool SuggestReplacement =
false;
1988 auto IsSep = [Separator](StringRef Component) {
1989 return Component.size() == 1 &&
1990 llvm::sys::path::is_separator(Component[0], Separator);
1995 for (
auto &Component : llvm::reverse(Components)) {
1996 if (
"." == Component) {
1997 }
else if (
".." == Component) {
2001 }
else if (RealPathComponentIter != RealPathComponentEnd) {
2002 if (!IsSep(Component) && !IsSep(*RealPathComponentIter) &&
2003 Component != *RealPathComponentIter) {
2007 SuggestReplacement =
2008 RealPathComponentIter->equals_insensitive(Component);
2009 if (!SuggestReplacement)
2011 Component = *RealPathComponentIter;
2013 ++RealPathComponentIter;
2016 return SuggestReplacement;
2025 Module *ShadowingModule =
nullptr;
2031 Diags.Report(MissingHeader.
FileNameLoc, diag::err_module_header_missing)
2033 }
else if (ShadowingModule) {
2036 diag::note_previous_definition);
2047std::pair<ConstSearchDirIterator, const FileEntry *>
2048Preprocessor::getIncludeNextStart(
const Token &IncludeNextTok)
const {
2053 const FileEntry *LookupFromFile =
nullptr;
2061 Diag(IncludeNextTok, diag::pp_include_next_in_primary);
2062 }
else if (CurLexerSubmodule) {
2065 assert(CurPPLexer &&
"#include_next directive in macro?");
2066 if (
auto FE = CurPPLexer->getFileEntry())
2067 LookupFromFile = *FE;
2069 }
else if (!Lookup) {
2074 Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
2080 return {Lookup, LookupFromFile};
2096 if (FilenameTok.
isNot(tok::header_name)) {
2097 if (FilenameTok.
is(tok::identifier) && PPOpts.SingleFileParseMode) {
2107 if (FilenameTok.
isNot(tok::eod))
2116 SourceLocation EndLoc =
2119 auto Action = HandleHeaderIncludeOrImport(HashLoc, IncludeTok, FilenameTok,
2120 EndLoc, LookupFrom, LookupFromFile);
2121 switch (Action.Kind) {
2122 case ImportAction::None:
2123 case ImportAction::SkippedModuleImport:
2125 case ImportAction::ModuleBegin:
2127 tok::annot_module_begin, Action.ModuleForHeader);
2129 case ImportAction::HeaderUnitImport:
2131 Action.ModuleForHeader);
2133 case ImportAction::ModuleImport:
2135 tok::annot_module_include, Action.ModuleForHeader);
2137 case ImportAction::Failure:
2138 assert(TheModuleLoader.HadFatalFailure &&
2139 "This should be an early exit only to a fatal error");
2140 TheModuleLoader.HadFatalFailure =
true;
2142 CurLexer->cutOffLexing();
2150 const Token &FilenameTok,
bool &IsFrameworkFound,
bool IsImportDecl,
2152 const FileEntry *LookupFromFile, StringRef &LookupFilename,
2155 auto DiagnoseHeaderInclusion = [&](FileEntryRef FE) {
2156 if (LangOpts.AsmPreprocessor)
2160 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
2161 bool RequestingModuleIsModuleInterface =
2162 !SourceMgr.isInMainFile(FilenameLoc);
2164 HeaderInfo.getModuleMap().diagnoseHeaderInclusion(
2165 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
2170 FilenameLoc, LookupFilename, isAngled, LookupFrom, LookupFromFile, CurDir,
2171 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2172 &SuggestedModule, &IsMapped, &IsFrameworkFound);
2174 DiagnoseHeaderInclusion(*
File);
2179 if (Callbacks && Callbacks->FileNotFound(Filename))
2180 return std::nullopt;
2182 if (SuppressIncludeNotFoundError)
2183 return std::nullopt;
2190 FilenameLoc, LookupFilename,
false, LookupFrom, LookupFromFile, CurDir,
2191 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2192 &SuggestedModule, &IsMapped,
2195 DiagnoseHeaderInclusion(*
File);
2196 Diag(FilenameTok, diag::err_pp_file_not_found_angled_include_not_fatal)
2197 << Filename << IsImportDecl
2199 "\"" + Filename.str() +
"\"");
2206 StringRef OriginalFilename = Filename;
2207 if (LangOpts.SpellChecking) {
2210 auto CorrectTypoFilename = [](llvm::StringRef Filename) {
2213 Filename = Filename.drop_back();
2217 StringRef TypoCorrectionName = CorrectTypoFilename(Filename);
2218 StringRef TypoCorrectionLookupName = CorrectTypoFilename(LookupFilename);
2221 FilenameLoc, TypoCorrectionLookupName, isAngled, LookupFrom,
2222 LookupFromFile, CurDir, Callbacks ? &SearchPath :
nullptr,
2223 Callbacks ? &RelativePath :
nullptr, &SuggestedModule, &IsMapped,
2226 DiagnoseHeaderInclusion(*
File);
2229 FilenameRange,
"<" + TypoCorrectionName.str() +
">")
2230 : FixItHint::CreateReplacement(
2231 FilenameRange,
"\"" + TypoCorrectionName.str() +
"\"");
2232 Diag(FilenameTok, diag::err_pp_file_not_found_typo_not_fatal)
2233 << OriginalFilename << TypoCorrectionName << Hint;
2236 Filename = TypoCorrectionName;
2237 LookupFilename = TypoCorrectionLookupName;
2243 assert(!
File &&
"expected missing file");
2244 Diag(FilenameTok, diag::err_pp_file_not_found)
2245 << OriginalFilename << FilenameRange;
2246 if (IsFrameworkFound) {
2247 size_t SlashPos = OriginalFilename.find(
'/');
2248 assert(SlashPos != StringRef::npos &&
2249 "Include with framework name should have '/' in the filename");
2250 StringRef FrameworkName = OriginalFilename.substr(0, SlashPos);
2251 FrameworkCacheEntry &CacheEntry =
2252 HeaderInfo.LookupFrameworkCache(FrameworkName);
2253 assert(CacheEntry.
Directory &&
"Found framework should be in cache");
2254 Diag(FilenameTok, diag::note_pp_framework_without_header)
2255 << OriginalFilename.substr(SlashPos + 1) << FrameworkName
2259 return std::nullopt;
2274Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
2278 SmallString<128> FilenameBuffer;
2279 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
2280 SourceLocation CharEnd = FilenameTok.
getEndLoc();
2282 CharSourceRange FilenameRange
2284 StringRef OriginalFilename = Filename;
2290 if (Filename.empty())
2291 return {ImportAction::None};
2293 bool IsImportDecl = HashLoc.
isInvalid();
2294 SourceLocation StartLoc = IsImportDecl ? IncludeTok.
getLocation() : HashLoc;
2297 if (PragmaARCCFCodeAuditedInfo.getLoc().isValid()) {
2298 Diag(StartLoc, diag::err_pp_include_in_arc_cf_code_audited) << IsImportDecl;
2299 Diag(PragmaARCCFCodeAuditedInfo.getLoc(), diag::note_pragma_entered_here);
2302 PragmaARCCFCodeAuditedInfo = IdentifierLoc();
2306 if (PragmaAssumeNonNullLoc.isValid()) {
2307 Diag(StartLoc, diag::err_pp_include_in_assume_nonnull) << IsImportDecl;
2308 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
2311 PragmaAssumeNonNullLoc = SourceLocation();
2314 if (HeaderInfo.HasIncludeAliasMap()) {
2318 StringRef NewName = HeaderInfo.MapHeaderToIncludeAlias(OriginalFilename);
2319 if (!NewName.empty())
2324 bool IsMapped =
false;
2325 bool IsFrameworkFound =
false;
2327 SmallString<1024> SearchPath;
2328 SmallString<1024> RelativePath;
2331 ModuleMap::KnownHeader SuggestedModule;
2332 SourceLocation FilenameLoc = FilenameTok.
getLocation();
2333 StringRef LookupFilename = Filename;
2337 SmallString<128> NormalizedPath;
2338 llvm::sys::path::Style BackslashStyle = llvm::sys::path::Style::native;
2339 if (is_style_posix(BackslashStyle) && LangOpts.MicrosoftExt) {
2340 NormalizedPath = Filename.str();
2341 llvm::sys::path::native(NormalizedPath);
2342 LookupFilename = NormalizedPath;
2343 BackslashStyle = llvm::sys::path::Style::windows;
2347 &CurDir, Filename, FilenameLoc, FilenameRange, FilenameTok,
2348 IsFrameworkFound, IsImportDecl, IsMapped, LookupFrom, LookupFromFile,
2349 LookupFilename, RelativePath, SearchPath, SuggestedModule, isAngled);
2353 SkippingUntilPCHThroughHeader =
false;
2354 return {ImportAction::None};
2372 enum { Enter,
Import,
Skip, IncludeLimitReached } Action = Enter;
2374 if (PPOpts.SingleFileParseMode)
2375 Action = IncludeLimitReached;
2380 if (Action == Enter && HasReachedMaxIncludeDepth &&
File &&
2382 Action = IncludeLimitReached;
2389 bool MaybeTranslateInclude = Action == Enter &&
File && ModuleToImport &&
2393 bool UsableHeaderUnit =
false;
2394 if (
getLangOpts().CPlusPlusModules && ModuleToImport &&
2396 if (TrackGMFState.inGMF() || IsImportDecl)
2397 UsableHeaderUnit =
true;
2398 else if (!IsImportDecl) {
2400 ModuleToImport =
nullptr;
2404 bool UsableClangHeaderModule =
2411 if (MaybeTranslateInclude && (UsableHeaderUnit || UsableClangHeaderModule)) {
2419 diag::note_implicit_top_level_module_import_here)
2421 return {ImportAction::None};
2427 SmallVector<IdentifierLoc, 2> Path;
2428 for (
Module *Mod = ModuleToImport; Mod; Mod = Mod->Parent)
2431 std::reverse(Path.begin(), Path.end());
2441 ModuleLoadResult Imported = TheModuleLoader.loadModule(
2444 assert((Imported ==
nullptr || Imported == ModuleToImport) &&
2445 "the imported module is different than the suggested one");
2451 static_cast<Module *
>(Imported)->getTopLevelModule());
2456 ModuleToImport =
nullptr;
2464 Token &
Result = IncludeTok;
2465 assert(CurLexer &&
"#include but no current lexer set!");
2467 CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
2468 CurLexer->cutOffLexing();
2470 return {ImportAction::None};
2478 SourceMgr.getFileCharacteristic(FilenameTok.
getLocation());
2480 FileCharacter = std::max(HeaderInfo.getFileDirFlavor(*
File), FileCharacter);
2491 bool IsFirstIncludeOfFile =
false;
2495 if (Action == Enter &&
File &&
2496 !HeaderInfo.ShouldEnterIncludeFile(*
this, *
File, EnterOnce,
2498 IsFirstIncludeOfFile)) {
2509 if (UsableHeaderUnit && !
getLangOpts().CompilingPCH)
2510 Action = TrackGMFState.inGMF() ?
Import :
Skip;
2512 Action = (ModuleToImport && !
getLangOpts().CompilingPCH) ? Import :
Skip;
2520 if (Action == Enter &&
File && PreambleConditionalStack.isRecording() &&
2521 SourceMgr.isMainFile(
File->getFileEntry())) {
2523 diag::err_pp_including_mainfile_in_preamble);
2524 return {ImportAction::None};
2527 if (Callbacks && !IsImportDecl) {
2530 Callbacks->InclusionDirective(HashLoc, IncludeTok, LookupFilename, isAngled,
2531 FilenameRange,
File, SearchPath, RelativePath,
2532 SuggestedModule.
getModule(), Action == Import,
2535 Callbacks->FileSkipped(*
File, FilenameTok, FileCharacter);
2539 return {ImportAction::None};
2543 if (IsImportDecl && !ModuleToImport) {
2544 Diag(FilenameTok, diag::err_header_import_not_header_unit)
2545 << OriginalFilename <<
File->getName();
2546 return {ImportAction::None};
2551 const bool CheckIncludePathPortability =
2552 !IsMapped && !
File->getFileEntry().tryGetRealPathName().empty();
2554 if (CheckIncludePathPortability) {
2555 StringRef Name = LookupFilename;
2556 StringRef NameWithoriginalSlashes = Filename;
2560 bool NameWasUNC = Name.consume_front(
"\\\\?\\");
2561 NameWithoriginalSlashes.consume_front(
"\\\\?\\");
2563 StringRef RealPathName =
File->getFileEntry().tryGetRealPathName();
2564 SmallVector<StringRef, 16> Components(llvm::sys::path::begin(Name),
2565 llvm::sys::path::end(Name));
2577 SmallString<128> FixedDriveRealPath;
2578 if (llvm::sys::path::is_absolute(Name) &&
2579 llvm::sys::path::is_absolute(RealPathName) &&
2582 assert(Components.size() >= 3 &&
"should have drive, backslash, name");
2583 assert(Components[0].size() == 2 &&
"should start with drive");
2584 assert(Components[0][1] ==
':' &&
"should have colon");
2585 FixedDriveRealPath = (Name.substr(0, 1) + RealPathName.substr(1)).str();
2586 RealPathName = FixedDriveRealPath;
2591 SmallString<128> Path;
2592 Path.reserve(Name.size()+2);
2593 Path.push_back(isAngled ?
'<' :
'"');
2595 const auto IsSep = [BackslashStyle](
char c) {
2596 return llvm::sys::path::is_separator(
c, BackslashStyle);
2599 for (
auto Component : Components) {
2611 if (!(Component.size() == 1 && IsSep(Component[0])))
2612 Path.append(Component);
2613 else if (Path.size() != 1)
2617 if (Path.size() > NameWithoriginalSlashes.size()) {
2618 Path.push_back(isAngled ?
'>' :
'"');
2621 assert(IsSep(NameWithoriginalSlashes[Path.size()-1]));
2623 Path.push_back(NameWithoriginalSlashes[Path.size()-1]);
2624 while (Path.size() <= NameWithoriginalSlashes.size() &&
2625 IsSep(NameWithoriginalSlashes[Path.size()-1]));
2631 Path = (Path.substr(0, 1) +
"\\\\?\\" + Path.substr(1)).str();
2638 ? diag::pp_nonportable_path
2639 : diag::pp_nonportable_system_path;
2640 Diag(FilenameTok, DiagId) << Path <<
2649 return {ImportAction::SkippedModuleImport, ModuleToImport};
2650 return {ImportAction::None};
2652 case IncludeLimitReached:
2655 return {ImportAction::None};
2659 assert(ModuleToImport &&
"no module to import");
2664 tok::pp___include_macros)
2665 return {ImportAction::None};
2667 return {ImportAction::ModuleImport, ModuleToImport};
2675 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
2676 Diag(FilenameTok, diag::err_pp_include_too_deep);
2677 HasReachedMaxIncludeDepth =
true;
2678 return {ImportAction::None};
2682 Diag(FilenameTok, diag::warn_pp_include_angled_in_module_purview)
2686 SourceLocation IncludePos = FilenameTok.
getLocation();
2690 IncludePos = SourceMgr.getExpansionRange(IncludePos).getEnd();
2691 FileID FID = SourceMgr.createFileID(*
File, IncludePos, FileCharacter);
2693 TheModuleLoader.HadFatalFailure =
true;
2694 return ImportAction::Failure;
2699 IsFirstIncludeOfFile))
2700 return {ImportAction::None};
2704 if (ModuleToImport && !ModuleToImport->
isHeaderUnit()) {
2709 diag::err_module_build_shadowed_submodule)
2712 diag::note_previous_definition);
2713 return {ImportAction::None};
2725 return {ImportAction::None};
2727 assert(!CurLexerSubmodule &&
"should not have marked this as a module yet");
2728 CurLexerSubmodule = ModuleToImport;
2738 return {ImportAction::ModuleBegin, ModuleToImport};
2741 assert(!IsImportDecl &&
"failed to diagnose missing module for import decl");
2742 return {ImportAction::None};
2747void Preprocessor::HandleIncludeNextDirective(
SourceLocation HashLoc,
2748 Token &IncludeNextTok) {
2749 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
2752 const FileEntry *LookupFromFile;
2753 std::tie(Lookup, LookupFromFile) = getIncludeNextStart(IncludeNextTok);
2755 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
2760void Preprocessor::HandleMicrosoftImportDirective(
Token &
Tok) {
2766 Diag(
Tok, diag::err_pp_import_directive_ms );
2777 if (!LangOpts.ObjC) {
2778 if (LangOpts.MSVCCompat)
2779 return HandleMicrosoftImportDirective(ImportTok);
2780 Diag(ImportTok, diag::ext_pp_import_directive);
2782 return HandleIncludeDirective(HashLoc, ImportTok);
2789void Preprocessor::HandleIncludeMacrosDirective(
SourceLocation HashLoc,
2790 Token &IncludeMacrosTok) {
2793 SourceLocation Loc = IncludeMacrosTok.
getLocation();
2794 if (SourceMgr.getBufferName(Loc) !=
"<built-in>") {
2796 diag::pp_include_macros_out_of_predefines);
2803 HandleIncludeDirective(HashLoc, IncludeMacrosTok);
2808 assert(TmpTok.
isNot(tok::eof) &&
"Didn't find end of -imacros!");
2809 }
while (TmpTok.
isNot(tok::hashhash));
2831 Diag(
Tok, diag::err_pp_expected_ident_in_arg_list);
2835 Diag(
Tok, LangOpts.CPlusPlus11 ?
2836 diag::warn_cxx98_compat_variadic_macro :
2837 diag::ext_variadic_macro);
2840 if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus) {
2841 Diag(
Tok, diag::ext_pp_opencl_variadic_macros);
2847 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2856 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2864 Diag(
Tok, diag::err_pp_invalid_tok_in_arg_list);
2870 if (llvm::is_contained(Parameters, II)) {
2871 Diag(
Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
2883 Diag(
Tok, diag::err_pp_expected_comma_in_arg_list);
2892 Diag(
Tok, diag::ext_named_variadic_macro);
2897 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2927 StringRef ValueText = II->
getName();
2928 StringRef TrimmedValue = ValueText;
2929 if (!ValueText.starts_with(
"__")) {
2930 if (ValueText.starts_with(
"_"))
2931 TrimmedValue = TrimmedValue.drop_front(1);
2935 TrimmedValue = TrimmedValue.drop_front(2);
2936 if (TrimmedValue.ends_with(
"__"))
2937 TrimmedValue = TrimmedValue.drop_back(2);
2939 return TrimmedValue == MacroText;
2946 return MacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
2959MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
2960 const Token &MacroNameTok,
const bool ImmediatelyAfterHeaderGuard) {
2962 Token LastTok = MacroNameTok;
2970 auto _ = llvm::make_scope_exit([&]() {
2972 if (CurLexer->ParsingPreprocessorDirective)
2983 if (
Tok.
is(tok::eod)) {
2984 if (ImmediatelyAfterHeaderGuard) {
2994 }
else if (
Tok.
is(tok::l_paren)) {
2997 if (ReadMacroParameterList(MI, LastTok))
3011 }
else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
3014 Diag(
Tok, diag::ext_c99_whitespace_required_after_macro_name);
3023 if (
Tok.
is(tok::at))
3025 else if (
Tok.
is(tok::unknown)) {
3032 Diag(
Tok, diag::ext_missing_whitespace_after_macro_name);
3034 Diag(
Tok, diag::warn_missing_whitespace_after_macro_name);
3037 if (!
Tok.
is(tok::eod))
3040 SmallVector<Token, 16> Tokens;
3047 Tokens.push_back(
Tok);
3061 if (!
Tok.
isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
3062 Tokens.push_back(
Tok);
3064 if (VAOCtx.isVAOptToken(
Tok)) {
3066 if (VAOCtx.isInVAOpt()) {
3067 Diag(
Tok, diag::err_pp_vaopt_nested_use);
3073 Diag(
Tok, diag::err_pp_missing_lparen_in_vaopt_use);
3076 Tokens.push_back(
Tok);
3079 if (
Tok.
is(tok::hashhash)) {
3080 Diag(
Tok, diag::err_vaopt_paste_at_start);
3084 }
else if (VAOCtx.isInVAOpt()) {
3085 if (
Tok.
is(tok::r_paren)) {
3086 if (VAOCtx.sawClosingParen()) {
3087 assert(Tokens.size() >= 3 &&
3088 "Must have seen at least __VA_OPT__( "
3089 "and a subsequent tok::r_paren");
3090 if (Tokens[Tokens.size() - 2].is(tok::hashhash)) {
3091 Diag(
Tok, diag::err_vaopt_paste_at_end);
3095 }
else if (
Tok.
is(tok::l_paren)) {
3109 Tokens.push_back(
Tok);
3116 if (
Tok.
is(tok::hashhash)) {
3124 if (
Tok.
is(tok::eod)) {
3125 Tokens.push_back(LastTok);
3130 Tokens[Tokens.size() - 1].is(tok::comma))
3134 Tokens.push_back(LastTok);
3143 if (!VAOCtx.isVAOptToken(
Tok) &&
3152 LastTok.
setKind(tok::unknown);
3153 Tokens.push_back(LastTok);
3156 Diag(
Tok, diag::err_pp_stringize_not_parameter)
3157 << LastTok.
is(tok::hashat);
3163 Tokens.push_back(LastTok);
3168 if (!VAOCtx.isVAOptToken(
Tok)) {
3169 Tokens.push_back(
Tok);
3176 if (VAOCtx.isInVAOpt()) {
3177 assert(
Tok.
is(tok::eod) &&
"Must be at End Of preprocessing Directive");
3178 Diag(
Tok, diag::err_pp_expected_after)
3179 << LastTok.
getKind() << tok::r_paren;
3180 Diag(VAOCtx.getUnmatchedOpeningParenLoc(), diag::note_matching) << tok::l_paren;
3191 return II->
isStr(
"__strong") || II->
isStr(
"__weak") ||
3192 II->
isStr(
"__unsafe_unretained") || II->
isStr(
"__autoreleasing");
3197void Preprocessor::HandleDefineDirective(
3198 Token &DefineTok,
const bool ImmediatelyAfterHeaderGuard) {
3202 bool MacroShadowsKeyword;
3203 ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
3206 if (MacroNameTok.
is(tok::eod))
3213 emitFinalMacroWarning(MacroNameTok,
false);
3217 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
3219 MacroInfo *
const MI = ReadOptionalMacroParameterListAndBody(
3220 MacroNameTok, ImmediatelyAfterHeaderGuard);
3224 if (MacroShadowsKeyword &&
3226 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
3231 if (NumTokens != 0) {
3243 if (SkippingUntilPCHThroughHeader) {
3246 LangOpts.MicrosoftExt))
3250 if (!LangOpts.MicrosoftExt)
3261 emitFinalMacroWarning(MacroNameTok,
false);
3272 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) &&
3274 LangOpts.MicrosoftExt)) {
3285 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) {
3293 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
3297 !MI->
isIdenticalTo(*OtherMI, *
this, LangOpts.MicrosoftExt)) {
3307 DefMacroDirective *MD =
3315 !MacroExpansionInDirectivesOverride &&
3324 Callbacks->MacroDefined(MacroNameTok, MD);
3329void Preprocessor::HandleUndefDirective() {
3333 ReadMacroName(MacroNameTok,
MU_Undef);
3336 if (MacroNameTok.
is(tok::eod))
3345 UndefMacroDirective *Undef =
nullptr;
3348 emitFinalMacroWarning(MacroNameTok,
true);
3358 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
3363 Undef = AllocateUndefMacroDirective(MacroNameTok.
getLocation());
3369 Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
3384void Preprocessor::HandleIfdefDirective(
Token &
Result,
3385 const Token &HashToken,
3387 bool ReadAnyTokensBeforeDirective) {
3389 Token DirectiveTok =
Result;
3392 ReadMacroName(MacroNameTok);
3395 if (MacroNameTok.
is(tok::eod)) {
3398 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3413 if (CurPPLexer->getConditionalStackDepth() == 0) {
3418 if (!ReadAnyTokensBeforeDirective && !MI) {
3419 assert(isIfndef &&
"#ifdef shouldn't reach here");
3420 CurPPLexer->MIOpt.EnterTopLevelIfndef(MII, MacroNameTok.
getLocation());
3422 CurPPLexer->MIOpt.EnterTopLevelConditional();
3431 Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3433 Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3436 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3440 if (PPOpts.SingleFileParseMode && !MI) {
3443 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3446 }
else if (!MI == isIfndef || RetainExcludedCB) {
3448 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3453 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3462void Preprocessor::HandleIfDirective(
Token &IfToken,
3463 const Token &HashToken,
3464 bool ReadAnyTokensBeforeDirective) {
3468 IdentifierInfo *IfNDefMacro =
nullptr;
3469 const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
3470 const bool ConditionalTrue = DER.Conditional;
3478 if (CurPPLexer->getConditionalStackDepth() == 0) {
3479 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
3481 CurPPLexer->MIOpt.EnterTopLevelIfndef(IfNDefMacro, IfToken.
getLocation());
3483 CurPPLexer->MIOpt.EnterTopLevelConditional();
3491 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3495 if (PPOpts.SingleFileParseMode && DER.IncludedUndefinedIds) {
3498 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3500 }
else if (ConditionalTrue || RetainExcludedCB) {
3502 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3514void Preprocessor::HandleEndifDirective(
Token &EndifToken) {
3520 PPConditionalInfo CondInfo;
3521 if (CurPPLexer->popConditionalLevel(CondInfo)) {
3523 Diag(EndifToken, diag::err_pp_endif_without_if);
3528 if (CurPPLexer->getConditionalStackDepth() == 0)
3529 CurPPLexer->MIOpt.ExitTopLevelConditional();
3531 assert(!CondInfo.
WasSkipping && !CurPPLexer->LexingRawMode &&
3532 "This code should only be reachable in the non-skipping case!");
3540void Preprocessor::HandleElseDirective(
Token &
Result,
const Token &HashToken) {
3546 PPConditionalInfo CI;
3547 if (CurPPLexer->popConditionalLevel(CI)) {
3553 if (CurPPLexer->getConditionalStackDepth() == 0)
3554 CurPPLexer->MIOpt.EnterTopLevelConditional();
3562 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3565 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3568 CurPPLexer->pushConditionalLevel(CI.
IfLoc,
false,
3576 true,
Result.getLocation());
3580void Preprocessor::HandleElifFamilyDirective(
Token &ElifToken,
3581 const Token &HashToken,
3593 if (LangOpts.CPlusPlus)
3594 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
3595 : diag::ext_cxx23_pp_directive;
3597 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
3598 : diag::ext_c23_pp_directive;
3599 Diag(ElifToken, DiagID) << DirKind;
3610 PPConditionalInfo CI;
3611 if (CurPPLexer->popConditionalLevel(CI)) {
3612 Diag(ElifToken, diag::pp_err_elif_without_if) << DirKind;
3617 if (CurPPLexer->getConditionalStackDepth() == 0)
3618 CurPPLexer->MIOpt.EnterTopLevelConditional();
3622 Diag(ElifToken, diag::pp_err_elif_after_else) << DirKind;
3627 Callbacks->Elif(ElifToken.
getLocation(), ConditionRange,
3630 case tok::pp_elifdef:
3633 case tok::pp_elifndef:
3637 assert(
false &&
"unexpected directive kind");
3642 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3645 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3648 CurPPLexer->pushConditionalLevel(ElifToken.
getLocation(),
false,
3654 SkipExcludedConditionalBlock(
3659std::optional<LexEmbedParametersResult>
3662 tok::TokenKind EndTokenKind = ForHasEmbed ? tok::r_paren : tok::eod;
3664 auto DiagMismatchedBracesAndSkipToEOD =
3666 std::pair<tok::TokenKind, SourceLocation> Matches) {
3668 Diag(Matches.second, diag::note_matching) << Matches.first;
3669 if (CurTok.
isNot(EndTokenKind))
3674 if (CurTok.
isNot(Kind)) {
3675 Diag(CurTok, diag::err_expected) << Kind;
3676 if (CurTok.
isNot(EndTokenKind))
3693 auto LexPPParameterName = [&]() -> std::optional<std::string> {
3696 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3697 return std::nullopt;
3704 if (CurTok.
is(tok::coloncolon)) {
3707 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3708 return std::nullopt;
3714 return (llvm::Twine(Prefix->
getName()) +
"::" + Suffix->
getName()).str();
3716 return Prefix->
getName().str();
3723 auto NormalizeParameterName = [](StringRef Name) {
3724 if (Name.size() > 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
3725 return Name.substr(2, Name.size() - 4);
3729 auto LexParenthesizedIntegerExpr = [&]() -> std::optional<size_t> {
3732 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3733 return std::nullopt;
3738 bool EvaluatedDefined;
3739 DirectiveEvalResult LimitEvalResult = EvaluateDirectiveExpression(
3740 ParameterIfNDef, CurTok, EvaluatedDefined,
false);
3742 if (!LimitEvalResult.Value) {
3745 assert(CurTok.
is(tok::eod) &&
"expect to be at the end of directive");
3746 return std::nullopt;
3749 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3750 return std::nullopt;
3757 if (EvaluatedDefined) {
3758 Diag(CurTok, diag::err_defined_in_pp_embed);
3759 return std::nullopt;
3762 if (LimitEvalResult.Value) {
3763 const llvm::APSInt &
Result = *LimitEvalResult.Value;
3764 if (
Result.isNegative()) {
3765 Diag(CurTok, diag::err_requires_positive_value)
3767 if (CurTok.
isNot(EndTokenKind))
3769 return std::nullopt;
3771 return Result.getLimitedValue();
3773 return std::nullopt;
3779 return tok::r_paren;
3781 return tok::r_brace;
3783 return tok::r_square;
3785 llvm_unreachable(
"should not get here");
3789 auto LexParenthesizedBalancedTokenSoup =
3791 std::vector<std::pair<tok::TokenKind, SourceLocation>> BracketStack;
3794 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3798 bool WaitingForInnerCloseParen =
false;
3799 while (CurTok.
isNot(tok::eod) &&
3800 (WaitingForInnerCloseParen || CurTok.
isNot(tok::r_paren))) {
3805 WaitingForInnerCloseParen =
true;
3812 WaitingForInnerCloseParen =
false;
3815 case tok::r_square: {
3816 if (BracketStack.empty()) {
3817 ExpectOrDiagAndSkipToEOD(tok::r_paren);
3821 GetMatchingCloseBracket(BracketStack.back().first);
3822 if (CurTok.
getKind() != Matching) {
3823 DiagMismatchedBracesAndSkipToEOD(Matching, BracketStack.back());
3826 BracketStack.pop_back();
3829 Tokens.push_back(CurTok);
3834 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3842 while (!CurTok.
isOneOf(EndTokenKind, tok::eod)) {
3844 std::optional<std::string> ParamName = LexPPParameterName();
3846 return std::nullopt;
3847 StringRef
Parameter = NormalizeParameterName(*ParamName);
3854 if (
Result.MaybeLimitParam)
3857 std::optional<size_t> Limit = LexParenthesizedIntegerExpr();
3859 return std::nullopt;
3862 }
else if (
Parameter ==
"clang::offset") {
3863 if (
Result.MaybeOffsetParam)
3866 std::optional<size_t> Offset = LexParenthesizedIntegerExpr();
3868 return std::nullopt;
3872 if (
Result.MaybePrefixParam)
3876 if (!LexParenthesizedBalancedTokenSoup(Soup))
3877 return std::nullopt;
3879 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
3881 if (
Result.MaybeSuffixParam)
3885 if (!LexParenthesizedBalancedTokenSoup(Soup))
3886 return std::nullopt;
3888 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
3890 if (
Result.MaybeIfEmptyParam)
3894 if (!LexParenthesizedBalancedTokenSoup(Soup))
3895 return std::nullopt;
3897 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
3899 ++
Result.UnrecognizedParams;
3903 if (CurTok.
is(tok::l_paren)) {
3905 if (!LexParenthesizedBalancedTokenSoup(Soup))
3906 return std::nullopt;
3909 Diag(ParamStartLoc, diag::err_pp_unknown_parameter) << 1 <<
Parameter;
3910 if (CurTok.
isNot(EndTokenKind))
3912 return std::nullopt;
3919void Preprocessor::HandleEmbedDirectiveImpl(
3921 StringRef BinaryContents, StringRef
FileName) {
3922 if (BinaryContents.empty()) {
3930 size_t TokCount = Toks.size();
3931 auto NewToks = std::make_unique<Token[]>(TokCount);
3932 llvm::copy(Toks, NewToks.get());
3933 EnterTokenStream(std::move(NewToks), TokCount,
true,
true);
3940 size_t TotalNumToks = 1 + NumPrefixToks + NumSuffixToks;
3942 auto Toks = std::make_unique<Token[]>(TotalNumToks);
3947 CurIdx += NumPrefixToks;
3950 EmbedAnnotationData *
Data =
new (BP) EmbedAnnotationData;
3951 Data->BinaryData = BinaryContents;
3954 Toks[CurIdx].startToken();
3955 Toks[CurIdx].setKind(tok::annot_embed);
3956 Toks[CurIdx].setAnnotationRange(HashLoc);
3957 Toks[CurIdx++].setAnnotationValue(
Data);
3962 CurIdx += NumSuffixToks;
3965 assert(CurIdx == TotalNumToks &&
"Calculated the incorrect number of tokens");
3966 EnterTokenStream(std::move(Toks), TotalNumToks,
true,
true);
3973 Diag(EmbedTok, diag::warn_compat_pp_embed_directive);
3975 Diag(EmbedTok, diag::ext_pp_embed_directive)
3976 << (LangOpts.CPlusPlus ? 1 : 0);
3983 if (FilenameTok.
isNot(tok::header_name)) {
3985 if (FilenameTok.
isNot(tok::eod))
3998 std::optional<LexEmbedParametersResult> Params =
4001 assert((Params || CurTok.
is(tok::eod)) &&
4002 "expected success or to be at the end of the directive");
4007 SmallString<128> FilenameBuffer;
4008 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
4009 StringRef OriginalFilename = Filename;
4015 if (Filename.empty())
4020 if (!MaybeFileRef) {
4022 if (Callbacks && Callbacks->EmbedFileNotFound(Filename)) {
4025 Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
4030 Diag(FilenameTok, diag::err_pp_embed_device_file) << Filename;
4034 std::optional<llvm::MemoryBufferRef> MaybeFile =
4038 Diag(FilenameTok, diag::err_cannot_open_file)
4039 << Filename <<
"a buffer to the contents could not be created";
4042 StringRef BinaryContents = MaybeFile->getBuffer();
4047 if (Params->MaybeOffsetParam) {
4052 BinaryContents = BinaryContents.substr(Params->MaybeOffsetParam->Offset);
4055 if (Params->MaybeLimitParam) {
4059 BinaryContents = BinaryContents.substr(0, Params->MaybeLimitParam->Limit);
4063 Callbacks->EmbedDirective(HashLoc, Filename, isAngled, MaybeFileRef,
4072 void *Mem = BP.Allocate(OriginalFilename.size(),
alignof(
char *));
4073 memcpy(Mem, OriginalFilename.data(), OriginalFilename.size());
4074 StringRef FilenameToGo =
4075 StringRef(
static_cast<char *
>(Mem), OriginalFilename.size());
4076 HandleEmbedDirectiveImpl(HashLoc, *Params, BinaryContents, FilenameToGo);
static bool isInMainFile(const clang::Diagnostic &D)
Defines interfaces for clang::DirectoryEntry and clang::DirectoryEntryRef.
Defines the clang::FileManager interface and associated types.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Defines the clang::LangOptions interface.
Defines the clang::MacroInfo and clang::MacroDirective classes.
Defines the clang::Module class, which describes a module in the source code.
Defines the PPCallbacks interface.
static bool ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit, SrcMgr::CharacteristicKind &FileKind, Preprocessor &PP)
ReadLineMarkerFlags - Parse and validate any flags at the end of a GNU line marker directive.
static bool isConfigurationPattern(Token &MacroName, MacroInfo *MI, const LangOptions &LOptions)
static void diagnoseAutoModuleImport(Preprocessor &PP, SourceLocation HashLoc, Token &IncludeTok, ArrayRef< IdentifierLoc > Path, SourceLocation PathEnd)
Produce a diagnostic informing the user that a include or similar was implicitly treated as a module ...
static std::optional< StringRef > findSimilarStr(StringRef LHS, const std::vector< StringRef > &Candidates)
Find a similar string in Candidates.
static bool isLanguageDefinedBuiltin(const SourceManager &SourceMgr, const MacroInfo *MI, const StringRef MacroName)
static bool trySimplifyPath(SmallVectorImpl< StringRef > &Components, StringRef RealPathName, llvm::sys::path::Style Separator)
static bool warnByDefaultOnWrongCase(StringRef Include)
MacroDiag
Enumerates possible cases of define/undef a reserved identifier.
@ MD_ReservedAttributeIdentifier
static bool isFeatureTestMacro(StringRef MacroName)
static bool GetLineValue(Token &DigitTok, unsigned &Val, unsigned DiagID, Preprocessor &PP, bool IsGNULineDirective=false)
GetLineValue - Convert a numeric token into an unsigned value, emitting Diagnostic DiagID if it is in...
PPElifDiag
Enumerates possible select values for the pp_err_elif_after_else and pp_err_elif_without_if diagnosti...
static bool isReservedCXXAttributeName(Preprocessor &PP, IdentifierInfo *II)
static MacroDiag shouldWarnOnMacroUndef(Preprocessor &PP, IdentifierInfo *II)
static bool isObjCProtectedMacro(const IdentifierInfo *II)
static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II)
Defines the clang::Preprocessor interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines the clang::SourceLocation class and associated facilities.
static bool isInvalid(LocType Loc, bool *Invalid)
Defines the SourceManager interface.
Defines the clang::TokenKind enum and support functions.
VerifyDiagnosticConsumer::Directive Directive
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
__device__ __2f16 float c
ResetMacroExpansionHelper(Preprocessor *pp)
~ResetMacroExpansionHelper()
static AttrArgsInfo getCXX11AttrArgsInfo(const IdentifierInfo *Name)
Represents a character-granular source range.
static CharSourceRange getCharRange(SourceRange R)
virtual void CodeCompleteMacroName(bool IsDefinition)
Callback invoked when performing code completion in a context where the name of a macro is expected.
A directive for a defined macro or a macro imported from a module.
Concrete class used by the front-end to report problems and issues.
A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...
StringRef getName() const
bool isDeviceFile() const
const FileEntry & getFileEntry() const
DirectoryEntryRef getDir() const
Cached information about one file (either on disk or in the virtual file system).
StringRef tryGetRealPathName() const
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements support for file system lookup, file system caching, and directory search management.
llvm::Expected< DirectoryEntryRef > getDirectoryRef(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
llvm::Expected< FileEntryRef > getFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true, bool IsText=true)
Lookup, cache, and verify the specified file (real or virtual).
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
One of these records is kept for each identifier that is lexed.
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.
bool isCPlusPlusOperatorKeyword() const
bool hadMacroDefinition() const
Returns true if this identifier was #defined to some value at any moment.
bool hasMacroDefinition() const
Return true if this identifier is #defined to some other value.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
bool isKeyword(const LangOptions &LangOpts) const
Return true if this token is a keyword in the specified language.
ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const
Determine whether this is a name reserved for the implementation (C99 7.1.3, C++ [lib....
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
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...
@ 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 )
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 markClangModuleAsAffecting(Module *M)
Mark the given clang module as affecting the current clang module or translation unit.
OptionalFileEntryRef LookupEmbedFile(StringRef Filename, bool isAngled, bool OpenFile, const FileEntry *LookupFromFile=nullptr)
Given a "Filename" or <Filename> reference, look up the indicated embed resource.
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)
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.
SourceRange DiscardUntilEndOfDirective()
Read and discard all tokens remaining on the current line until the tok::eod token is found.
SourceLocation CheckEndOfDirective(const char *DirType, bool EnableMacros=false)
Ensure that the next token is a tok::eod 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)
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...
bool isNextPPTokenOneOf(Ts... Ks)
Check whether the next pp-token is one of the specificed token kind.
Module * getCurrentModule()
Retrieves the module that we're currently building, if any.
void makeModuleVisible(Module *M, SourceLocation Loc, bool IncludeExports=true)
bool hadModuleLoaderFatalFailure() const
const TargetInfo & getTargetInfo() const
FileManager & getFileManager() const
bool LexHeaderName(Token &Result, bool AllowMacroExpansion=true)
Lex a token, forming a header-name token if possible.
bool isPCHThroughHeader(const FileEntry *FE)
Returns true if the FileEntry is the PCH through header.
friend class VariadicMacroScopeGuard
MacroInfo * AllocateMacroInfo(SourceLocation L)
Allocate a new MacroInfo object with the provided SourceLocation.
void LexUnexpandedToken(Token &Result)
Just like Lex, but disables macro expansion of identifier tokens.
bool alreadyIncluded(FileEntryRef File) const
Return true if this header has already been included.
FileID getPredefinesFileID() const
Returns the FileID for the preprocessor predefines.
void LexUnexpandedNonComment(Token &Result)
Like LexNonComment, but this disables macro expansion of identifier tokens.
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
bool GetIncludeFilenameSpelling(SourceLocation Loc, StringRef &Buffer)
Turn the specified lexer token into a fully checked and spelled filename, e.g.
PreprocessorLexer * getCurrentFileLexer() const
Return the current file lexer being lexed from.
HeaderSearch & getHeaderSearchInfo() const
void emitMacroExpansionWarnings(const Token &Identifier, bool IsIfnDef=false) const
void HandleDirective(Token &Result)
Callback invoked when the lexer sees a # token at the start of a line.
void EnterAnnotationToken(SourceRange Range, tok::TokenKind Kind, void *AnnotationVal)
Enter an annotation token into the token stream.
OptionalFileEntryRef LookupFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled, ConstSearchDirIterator FromDir, const FileEntry *FromFile, ConstSearchDirIterator *CurDir, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool *IsFrameworkFound, bool SkipCache=false, bool OpenFile=true, bool CacheFailures=true)
Given a "foo" or <foo> reference, look up the indicated file.
const LangOptions & getLangOpts() const
bool isInNamedModule() const
If we are preprocessing a named module.
OptionalFileEntryRef getHeaderToIncludeForDiagnostics(SourceLocation IncLoc, SourceLocation MLoc)
We want to produce a diagnostic at location IncLoc concerning an unreachable effect at location MLoc ...
DefMacroDirective * appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI, SourceLocation Loc)
void HandlePragmaHdrstop(Token &Tok)
DiagnosticsEngine & getDiagnostics() const
std::optional< LexEmbedParametersResult > LexEmbedParameters(Token &Current, bool ForHasEmbed)
Lex the parameters for an embed directive, returns nullopt on error.
Module * getModuleForLocation(SourceLocation Loc, bool AllowTextual)
Find the module that owns the source or header file that Loc points to.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
bool usingPCHWithThroughHeader()
True if using a PCH with a through header.
Preprocessor(const PreprocessorOptions &PPOpts, DiagnosticsEngine &diags, const LangOptions &LangOpts, SourceManager &SM, HeaderSearch &Headers, ModuleLoader &TheModuleLoader, IdentifierInfoLookup *IILookup=nullptr, bool OwnsHeaderSearch=false, TranslationUnitKind TUKind=TU_Complete)
void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD)
Add a directive to the macro directive history for this identifier.
Represents an unpacked "presumed" location which can be presented to the user.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
SourceLocation getIncludeLoc() const
Return the presumed include location of this location.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
bool isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
std::optional< llvm::MemoryBufferRef > getMemoryBufferForFileOrNone(FileEntryRef File)
Retrieve the memory buffer associated with the given file.
A trivial tuple used to represent a source range.
void setBegin(SourceLocation b)
SourceLocation getEnd() const
void setEnd(SourceLocation e)
Exposes information about the current target.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getEndLoc() const
void clearFlag(TokenFlags Flag)
Unset the specified flag.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
unsigned getLength() const
void setKind(tok::TokenKind K)
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
tok::TokenKind getKind() const
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
bool isOneOf(Ts... Ks) const
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
bool isNot(tok::TokenKind K) const
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix.
bool needsCleaning() const
Return true if this token has trigraphs or escaped newlines in it.
StringRef getRawIdentifier() const
getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode),...
A directive for an undefined macro.
A directive for setting the module visibility of a macro.
Defines the clang::TargetInfo interface.
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
uint32_t Literal
Literals are represented as positive integers.
bool Sub(InterpState &S, CodePtr OpPC)
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
PPKeywordKind
Provides a namespace for preprocessor keywords which start with a '#' at the beginning of the line.
The JSON file list parser is used to communicate input to InstallAPI.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
bool isReservedInAllContexts(ReservedIdentifierStatus Status)
Determine whether an identifier is reserved in all contexts.
int hasAttribute(AttributeCommonInfo::Syntax Syntax, llvm::StringRef ScopeName, llvm::StringRef AttrName, const TargetInfo &Target, const LangOptions &LangOpts, bool CheckPlugins)
Return the version number associated with the attribute if we recognize and implement the attribute s...
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.