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) &&
2098 (PPOpts.SingleFileParseMode || PPOpts.SingleModuleParseMode)) {
2108 if (FilenameTok.
isNot(tok::eod))
2117 SourceLocation EndLoc =
2120 auto Action = HandleHeaderIncludeOrImport(HashLoc, IncludeTok, FilenameTok,
2121 EndLoc, LookupFrom, LookupFromFile);
2122 switch (Action.Kind) {
2123 case ImportAction::None:
2124 case ImportAction::SkippedModuleImport:
2126 case ImportAction::ModuleBegin:
2128 tok::annot_module_begin, Action.ModuleForHeader);
2130 case ImportAction::HeaderUnitImport:
2132 Action.ModuleForHeader);
2134 case ImportAction::ModuleImport:
2136 tok::annot_module_include, Action.ModuleForHeader);
2138 case ImportAction::Failure:
2139 assert(TheModuleLoader.HadFatalFailure &&
2140 "This should be an early exit only to a fatal error");
2141 TheModuleLoader.HadFatalFailure =
true;
2143 CurLexer->cutOffLexing();
2151 const Token &FilenameTok,
bool &IsFrameworkFound,
bool IsImportDecl,
2153 const FileEntry *LookupFromFile, StringRef &LookupFilename,
2156 auto DiagnoseHeaderInclusion = [&](FileEntryRef FE) {
2157 if (LangOpts.AsmPreprocessor)
2161 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
2162 bool RequestingModuleIsModuleInterface =
2163 !SourceMgr.isInMainFile(FilenameLoc);
2165 HeaderInfo.getModuleMap().diagnoseHeaderInclusion(
2166 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
2171 FilenameLoc, LookupFilename, isAngled, LookupFrom, LookupFromFile, CurDir,
2172 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2173 &SuggestedModule, &IsMapped, &IsFrameworkFound);
2175 DiagnoseHeaderInclusion(*
File);
2180 if (Callbacks && Callbacks->FileNotFound(Filename))
2181 return std::nullopt;
2183 if (SuppressIncludeNotFoundError)
2184 return std::nullopt;
2191 FilenameLoc, LookupFilename,
false, LookupFrom, LookupFromFile, CurDir,
2192 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2193 &SuggestedModule, &IsMapped,
2196 DiagnoseHeaderInclusion(*
File);
2197 Diag(FilenameTok, diag::err_pp_file_not_found_angled_include_not_fatal)
2198 << Filename << IsImportDecl
2200 "\"" + Filename.str() +
"\"");
2207 StringRef OriginalFilename = Filename;
2208 if (LangOpts.SpellChecking) {
2211 auto CorrectTypoFilename = [](llvm::StringRef Filename) {
2214 Filename = Filename.drop_back();
2218 StringRef TypoCorrectionName = CorrectTypoFilename(Filename);
2219 StringRef TypoCorrectionLookupName = CorrectTypoFilename(LookupFilename);
2222 FilenameLoc, TypoCorrectionLookupName, isAngled, LookupFrom,
2223 LookupFromFile, CurDir, Callbacks ? &SearchPath :
nullptr,
2224 Callbacks ? &RelativePath :
nullptr, &SuggestedModule, &IsMapped,
2227 DiagnoseHeaderInclusion(*
File);
2230 FilenameRange,
"<" + TypoCorrectionName.str() +
">")
2231 : FixItHint::CreateReplacement(
2232 FilenameRange,
"\"" + TypoCorrectionName.str() +
"\"");
2233 Diag(FilenameTok, diag::err_pp_file_not_found_typo_not_fatal)
2234 << OriginalFilename << TypoCorrectionName << Hint;
2237 Filename = TypoCorrectionName;
2238 LookupFilename = TypoCorrectionLookupName;
2244 assert(!
File &&
"expected missing file");
2245 Diag(FilenameTok, diag::err_pp_file_not_found)
2246 << OriginalFilename << FilenameRange;
2247 if (IsFrameworkFound) {
2248 size_t SlashPos = OriginalFilename.find(
'/');
2249 assert(SlashPos != StringRef::npos &&
2250 "Include with framework name should have '/' in the filename");
2251 StringRef FrameworkName = OriginalFilename.substr(0, SlashPos);
2252 FrameworkCacheEntry &CacheEntry =
2253 HeaderInfo.LookupFrameworkCache(FrameworkName);
2254 assert(CacheEntry.
Directory &&
"Found framework should be in cache");
2255 Diag(FilenameTok, diag::note_pp_framework_without_header)
2256 << OriginalFilename.substr(SlashPos + 1) << FrameworkName
2260 return std::nullopt;
2275Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
2279 SmallString<128> FilenameBuffer;
2280 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
2281 SourceLocation CharEnd = FilenameTok.
getEndLoc();
2283 CharSourceRange FilenameRange
2285 StringRef OriginalFilename = Filename;
2291 if (Filename.empty())
2292 return {ImportAction::None};
2294 bool IsImportDecl = HashLoc.
isInvalid();
2295 SourceLocation StartLoc = IsImportDecl ? IncludeTok.
getLocation() : HashLoc;
2298 if (PragmaARCCFCodeAuditedInfo.getLoc().isValid()) {
2299 Diag(StartLoc, diag::err_pp_include_in_arc_cf_code_audited) << IsImportDecl;
2300 Diag(PragmaARCCFCodeAuditedInfo.getLoc(), diag::note_pragma_entered_here);
2303 PragmaARCCFCodeAuditedInfo = IdentifierLoc();
2307 if (PragmaAssumeNonNullLoc.isValid()) {
2308 Diag(StartLoc, diag::err_pp_include_in_assume_nonnull) << IsImportDecl;
2309 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
2312 PragmaAssumeNonNullLoc = SourceLocation();
2315 if (HeaderInfo.HasIncludeAliasMap()) {
2319 StringRef NewName = HeaderInfo.MapHeaderToIncludeAlias(OriginalFilename);
2320 if (!NewName.empty())
2325 bool IsMapped =
false;
2326 bool IsFrameworkFound =
false;
2328 SmallString<1024> SearchPath;
2329 SmallString<1024> RelativePath;
2332 ModuleMap::KnownHeader SuggestedModule;
2333 SourceLocation FilenameLoc = FilenameTok.
getLocation();
2334 StringRef LookupFilename = Filename;
2338 SmallString<128> NormalizedPath;
2339 llvm::sys::path::Style BackslashStyle = llvm::sys::path::Style::native;
2340 if (is_style_posix(BackslashStyle) && LangOpts.MicrosoftExt) {
2341 NormalizedPath = Filename.str();
2342 llvm::sys::path::native(NormalizedPath);
2343 LookupFilename = NormalizedPath;
2344 BackslashStyle = llvm::sys::path::Style::windows;
2348 &CurDir, Filename, FilenameLoc, FilenameRange, FilenameTok,
2349 IsFrameworkFound, IsImportDecl, IsMapped, LookupFrom, LookupFromFile,
2350 LookupFilename, RelativePath, SearchPath, SuggestedModule, isAngled);
2354 SkippingUntilPCHThroughHeader =
false;
2355 return {ImportAction::None};
2373 enum { Enter,
Import,
Skip, IncludeLimitReached } Action = Enter;
2375 if (PPOpts.SingleFileParseMode)
2376 Action = IncludeLimitReached;
2381 if (Action == Enter && HasReachedMaxIncludeDepth &&
File &&
2383 Action = IncludeLimitReached;
2390 bool MaybeTranslateInclude = Action == Enter &&
File && ModuleToImport &&
2394 bool UsableHeaderUnit =
false;
2395 if (
getLangOpts().CPlusPlusModules && ModuleToImport &&
2397 if (TrackGMFState.inGMF() || IsImportDecl)
2398 UsableHeaderUnit =
true;
2399 else if (!IsImportDecl) {
2401 ModuleToImport =
nullptr;
2405 bool UsableClangHeaderModule =
2409 if (MaybeTranslateInclude && (UsableHeaderUnit || UsableClangHeaderModule) &&
2410 PPOpts.SingleModuleParseMode) {
2411 Action = IncludeLimitReached;
2416 else if (MaybeTranslateInclude &&
2417 (UsableHeaderUnit || UsableClangHeaderModule)) {
2425 diag::note_implicit_top_level_module_import_here)
2427 return {ImportAction::None};
2433 SmallVector<IdentifierLoc, 2> Path;
2434 for (
Module *Mod = ModuleToImport; Mod; Mod = Mod->Parent)
2437 std::reverse(Path.begin(), Path.end());
2447 ModuleLoadResult Imported = TheModuleLoader.loadModule(
2450 assert((Imported ==
nullptr || Imported == ModuleToImport) &&
2451 "the imported module is different than the suggested one");
2457 static_cast<Module *
>(Imported)->getTopLevelModule());
2462 ModuleToImport =
nullptr;
2470 Token &
Result = IncludeTok;
2471 assert(CurLexer &&
"#include but no current lexer set!");
2473 CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
2474 CurLexer->cutOffLexing();
2476 return {ImportAction::None};
2484 SourceMgr.getFileCharacteristic(FilenameTok.
getLocation());
2486 FileCharacter = std::max(HeaderInfo.getFileDirFlavor(*
File), FileCharacter);
2497 bool IsFirstIncludeOfFile =
false;
2501 if (Action == Enter &&
File &&
2502 !HeaderInfo.ShouldEnterIncludeFile(*
this, *
File, EnterOnce,
2504 IsFirstIncludeOfFile)) {
2515 if (UsableHeaderUnit && !
getLangOpts().CompilingPCH)
2516 Action = TrackGMFState.inGMF() ?
Import :
Skip;
2518 Action = (ModuleToImport && !
getLangOpts().CompilingPCH) ? Import :
Skip;
2526 if (Action == Enter &&
File && PreambleConditionalStack.isRecording() &&
2527 SourceMgr.isMainFile(
File->getFileEntry())) {
2529 diag::err_pp_including_mainfile_in_preamble);
2530 return {ImportAction::None};
2533 if (Callbacks && !IsImportDecl) {
2536 Callbacks->InclusionDirective(HashLoc, IncludeTok, LookupFilename, isAngled,
2537 FilenameRange,
File, SearchPath, RelativePath,
2538 SuggestedModule.
getModule(), Action == Import,
2541 Callbacks->FileSkipped(*
File, FilenameTok, FileCharacter);
2545 return {ImportAction::None};
2549 if (IsImportDecl && !ModuleToImport) {
2550 Diag(FilenameTok, diag::err_header_import_not_header_unit)
2551 << OriginalFilename <<
File->getName();
2552 return {ImportAction::None};
2557 const bool CheckIncludePathPortability =
2558 !IsMapped && !
File->getFileEntry().tryGetRealPathName().empty();
2560 if (CheckIncludePathPortability) {
2561 StringRef Name = LookupFilename;
2562 StringRef NameWithoriginalSlashes = Filename;
2566 bool NameWasUNC = Name.consume_front(
"\\\\?\\");
2567 NameWithoriginalSlashes.consume_front(
"\\\\?\\");
2569 StringRef RealPathName =
File->getFileEntry().tryGetRealPathName();
2570 SmallVector<StringRef, 16> Components(llvm::sys::path::begin(Name),
2571 llvm::sys::path::end(Name));
2583 SmallString<128> FixedDriveRealPath;
2584 if (llvm::sys::path::is_absolute(Name) &&
2585 llvm::sys::path::is_absolute(RealPathName) &&
2588 assert(Components.size() >= 3 &&
"should have drive, backslash, name");
2589 assert(Components[0].size() == 2 &&
"should start with drive");
2590 assert(Components[0][1] ==
':' &&
"should have colon");
2591 FixedDriveRealPath = (Name.substr(0, 1) + RealPathName.substr(1)).str();
2592 RealPathName = FixedDriveRealPath;
2597 SmallString<128> Path;
2598 Path.reserve(Name.size()+2);
2599 Path.push_back(isAngled ?
'<' :
'"');
2601 const auto IsSep = [BackslashStyle](
char c) {
2602 return llvm::sys::path::is_separator(
c, BackslashStyle);
2605 for (
auto Component : Components) {
2617 if (!(Component.size() == 1 && IsSep(Component[0])))
2618 Path.append(Component);
2619 else if (Path.size() != 1)
2623 if (Path.size() > NameWithoriginalSlashes.size()) {
2624 Path.push_back(isAngled ?
'>' :
'"');
2627 assert(IsSep(NameWithoriginalSlashes[Path.size()-1]));
2629 Path.push_back(NameWithoriginalSlashes[Path.size()-1]);
2630 while (Path.size() <= NameWithoriginalSlashes.size() &&
2631 IsSep(NameWithoriginalSlashes[Path.size()-1]));
2637 Path = (Path.substr(0, 1) +
"\\\\?\\" + Path.substr(1)).str();
2644 ? diag::pp_nonportable_path
2645 : diag::pp_nonportable_system_path;
2646 Diag(FilenameTok, DiagId) << Path <<
2655 return {ImportAction::SkippedModuleImport, ModuleToImport};
2656 return {ImportAction::None};
2658 case IncludeLimitReached:
2661 return {ImportAction::None};
2665 assert(ModuleToImport &&
"no module to import");
2670 tok::pp___include_macros)
2671 return {ImportAction::None};
2673 return {ImportAction::ModuleImport, ModuleToImport};
2681 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
2682 Diag(FilenameTok, diag::err_pp_include_too_deep);
2683 HasReachedMaxIncludeDepth =
true;
2684 return {ImportAction::None};
2688 Diag(FilenameTok, diag::warn_pp_include_angled_in_module_purview)
2692 SourceLocation IncludePos = FilenameTok.
getLocation();
2696 IncludePos = SourceMgr.getExpansionRange(IncludePos).getEnd();
2697 FileID FID = SourceMgr.createFileID(*
File, IncludePos, FileCharacter);
2699 TheModuleLoader.HadFatalFailure =
true;
2700 return ImportAction::Failure;
2705 IsFirstIncludeOfFile))
2706 return {ImportAction::None};
2710 if (ModuleToImport && !ModuleToImport->
isHeaderUnit()) {
2715 diag::err_module_build_shadowed_submodule)
2718 diag::note_previous_definition);
2719 return {ImportAction::None};
2731 return {ImportAction::None};
2733 assert(!CurLexerSubmodule &&
"should not have marked this as a module yet");
2734 CurLexerSubmodule = ModuleToImport;
2744 return {ImportAction::ModuleBegin, ModuleToImport};
2747 assert(!IsImportDecl &&
"failed to diagnose missing module for import decl");
2748 return {ImportAction::None};
2753void Preprocessor::HandleIncludeNextDirective(
SourceLocation HashLoc,
2754 Token &IncludeNextTok) {
2755 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
2758 const FileEntry *LookupFromFile;
2759 std::tie(Lookup, LookupFromFile) = getIncludeNextStart(IncludeNextTok);
2761 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
2766void Preprocessor::HandleMicrosoftImportDirective(
Token &
Tok) {
2772 Diag(
Tok, diag::err_pp_import_directive_ms );
2783 if (!LangOpts.ObjC) {
2784 if (LangOpts.MSVCCompat)
2785 return HandleMicrosoftImportDirective(ImportTok);
2786 Diag(ImportTok, diag::ext_pp_import_directive);
2788 return HandleIncludeDirective(HashLoc, ImportTok);
2795void Preprocessor::HandleIncludeMacrosDirective(
SourceLocation HashLoc,
2796 Token &IncludeMacrosTok) {
2799 SourceLocation Loc = IncludeMacrosTok.
getLocation();
2800 if (SourceMgr.getBufferName(Loc) !=
"<built-in>") {
2802 diag::pp_include_macros_out_of_predefines);
2809 HandleIncludeDirective(HashLoc, IncludeMacrosTok);
2814 assert(TmpTok.
isNot(tok::eof) &&
"Didn't find end of -imacros!");
2815 }
while (TmpTok.
isNot(tok::hashhash));
2837 Diag(
Tok, diag::err_pp_expected_ident_in_arg_list);
2841 Diag(
Tok, LangOpts.CPlusPlus11 ?
2842 diag::warn_cxx98_compat_variadic_macro :
2843 diag::ext_variadic_macro);
2846 if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus) {
2847 Diag(
Tok, diag::ext_pp_opencl_variadic_macros);
2853 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2862 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2870 Diag(
Tok, diag::err_pp_invalid_tok_in_arg_list);
2876 if (llvm::is_contained(Parameters, II)) {
2877 Diag(
Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
2889 Diag(
Tok, diag::err_pp_expected_comma_in_arg_list);
2898 Diag(
Tok, diag::ext_named_variadic_macro);
2903 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2933 StringRef ValueText = II->
getName();
2934 StringRef TrimmedValue = ValueText;
2935 if (!ValueText.starts_with(
"__")) {
2936 if (ValueText.starts_with(
"_"))
2937 TrimmedValue = TrimmedValue.drop_front(1);
2941 TrimmedValue = TrimmedValue.drop_front(2);
2942 if (TrimmedValue.ends_with(
"__"))
2943 TrimmedValue = TrimmedValue.drop_back(2);
2945 return TrimmedValue == MacroText;
2952 return MacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
2965MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
2966 const Token &MacroNameTok,
const bool ImmediatelyAfterHeaderGuard) {
2968 Token LastTok = MacroNameTok;
2976 auto _ = llvm::make_scope_exit([&]() {
2978 if (CurLexer->ParsingPreprocessorDirective)
2989 if (
Tok.
is(tok::eod)) {
2990 if (ImmediatelyAfterHeaderGuard) {
3000 }
else if (
Tok.
is(tok::l_paren)) {
3003 if (ReadMacroParameterList(MI, LastTok))
3017 }
else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
3020 Diag(
Tok, diag::ext_c99_whitespace_required_after_macro_name);
3029 if (
Tok.
is(tok::at))
3031 else if (
Tok.
is(tok::unknown)) {
3038 Diag(
Tok, diag::ext_missing_whitespace_after_macro_name);
3040 Diag(
Tok, diag::warn_missing_whitespace_after_macro_name);
3043 if (!
Tok.
is(tok::eod))
3046 SmallVector<Token, 16> Tokens;
3053 Tokens.push_back(
Tok);
3067 if (!
Tok.
isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
3068 Tokens.push_back(
Tok);
3070 if (VAOCtx.isVAOptToken(
Tok)) {
3072 if (VAOCtx.isInVAOpt()) {
3073 Diag(
Tok, diag::err_pp_vaopt_nested_use);
3079 Diag(
Tok, diag::err_pp_missing_lparen_in_vaopt_use);
3082 Tokens.push_back(
Tok);
3085 if (
Tok.
is(tok::hashhash)) {
3086 Diag(
Tok, diag::err_vaopt_paste_at_start);
3090 }
else if (VAOCtx.isInVAOpt()) {
3091 if (
Tok.
is(tok::r_paren)) {
3092 if (VAOCtx.sawClosingParen()) {
3093 assert(Tokens.size() >= 3 &&
3094 "Must have seen at least __VA_OPT__( "
3095 "and a subsequent tok::r_paren");
3096 if (Tokens[Tokens.size() - 2].is(tok::hashhash)) {
3097 Diag(
Tok, diag::err_vaopt_paste_at_end);
3101 }
else if (
Tok.
is(tok::l_paren)) {
3115 Tokens.push_back(
Tok);
3122 if (
Tok.
is(tok::hashhash)) {
3130 if (
Tok.
is(tok::eod)) {
3131 Tokens.push_back(LastTok);
3136 Tokens[Tokens.size() - 1].is(tok::comma))
3140 Tokens.push_back(LastTok);
3149 if (!VAOCtx.isVAOptToken(
Tok) &&
3158 LastTok.
setKind(tok::unknown);
3159 Tokens.push_back(LastTok);
3162 Diag(
Tok, diag::err_pp_stringize_not_parameter)
3163 << LastTok.
is(tok::hashat);
3169 Tokens.push_back(LastTok);
3174 if (!VAOCtx.isVAOptToken(
Tok)) {
3175 Tokens.push_back(
Tok);
3182 if (VAOCtx.isInVAOpt()) {
3183 assert(
Tok.
is(tok::eod) &&
"Must be at End Of preprocessing Directive");
3184 Diag(
Tok, diag::err_pp_expected_after)
3185 << LastTok.
getKind() << tok::r_paren;
3186 Diag(VAOCtx.getUnmatchedOpeningParenLoc(), diag::note_matching) << tok::l_paren;
3197 return II->
isStr(
"__strong") || II->
isStr(
"__weak") ||
3198 II->
isStr(
"__unsafe_unretained") || II->
isStr(
"__autoreleasing");
3203void Preprocessor::HandleDefineDirective(
3204 Token &DefineTok,
const bool ImmediatelyAfterHeaderGuard) {
3208 bool MacroShadowsKeyword;
3209 ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
3212 if (MacroNameTok.
is(tok::eod))
3219 emitFinalMacroWarning(MacroNameTok,
false);
3223 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
3225 MacroInfo *
const MI = ReadOptionalMacroParameterListAndBody(
3226 MacroNameTok, ImmediatelyAfterHeaderGuard);
3230 if (MacroShadowsKeyword &&
3232 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
3237 if (NumTokens != 0) {
3249 if (SkippingUntilPCHThroughHeader) {
3252 LangOpts.MicrosoftExt))
3256 if (!LangOpts.MicrosoftExt)
3267 emitFinalMacroWarning(MacroNameTok,
false);
3278 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) &&
3280 LangOpts.MicrosoftExt)) {
3291 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) {
3299 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
3303 !MI->
isIdenticalTo(*OtherMI, *
this, LangOpts.MicrosoftExt)) {
3313 DefMacroDirective *MD =
3321 !MacroExpansionInDirectivesOverride &&
3330 Callbacks->MacroDefined(MacroNameTok, MD);
3335void Preprocessor::HandleUndefDirective() {
3339 ReadMacroName(MacroNameTok,
MU_Undef);
3342 if (MacroNameTok.
is(tok::eod))
3351 UndefMacroDirective *Undef =
nullptr;
3354 emitFinalMacroWarning(MacroNameTok,
true);
3364 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
3369 Undef = AllocateUndefMacroDirective(MacroNameTok.
getLocation());
3375 Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
3390void Preprocessor::HandleIfdefDirective(
Token &
Result,
3391 const Token &HashToken,
3393 bool ReadAnyTokensBeforeDirective) {
3395 Token DirectiveTok =
Result;
3398 ReadMacroName(MacroNameTok);
3401 if (MacroNameTok.
is(tok::eod)) {
3404 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3419 if (CurPPLexer->getConditionalStackDepth() == 0) {
3424 if (!ReadAnyTokensBeforeDirective && !MI) {
3425 assert(isIfndef &&
"#ifdef shouldn't reach here");
3426 CurPPLexer->MIOpt.EnterTopLevelIfndef(MII, MacroNameTok.
getLocation());
3428 CurPPLexer->MIOpt.EnterTopLevelConditional();
3437 Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3439 Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3442 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3446 if (PPOpts.SingleFileParseMode && !MI) {
3449 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3452 }
else if (PPOpts.SingleModuleParseMode && !MI) {
3456 SkipExcludedConditionalBlock(
3459 }
else if (!MI == isIfndef || RetainExcludedCB) {
3461 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3466 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3475void Preprocessor::HandleIfDirective(
Token &IfToken,
3476 const Token &HashToken,
3477 bool ReadAnyTokensBeforeDirective) {
3481 IdentifierInfo *IfNDefMacro =
nullptr;
3482 const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
3483 const bool ConditionalTrue = DER.Conditional;
3491 if (CurPPLexer->getConditionalStackDepth() == 0) {
3492 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
3494 CurPPLexer->MIOpt.EnterTopLevelIfndef(IfNDefMacro, IfToken.
getLocation());
3496 CurPPLexer->MIOpt.EnterTopLevelConditional();
3504 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3508 if (PPOpts.SingleFileParseMode && DER.IncludedUndefinedIds) {
3511 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3513 }
else if (PPOpts.SingleModuleParseMode && DER.IncludedUndefinedIds) {
3520 }
else if (ConditionalTrue || RetainExcludedCB) {
3522 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3534void Preprocessor::HandleEndifDirective(
Token &EndifToken) {
3540 PPConditionalInfo CondInfo;
3541 if (CurPPLexer->popConditionalLevel(CondInfo)) {
3543 Diag(EndifToken, diag::err_pp_endif_without_if);
3548 if (CurPPLexer->getConditionalStackDepth() == 0)
3549 CurPPLexer->MIOpt.ExitTopLevelConditional();
3551 assert(!CondInfo.
WasSkipping && !CurPPLexer->LexingRawMode &&
3552 "This code should only be reachable in the non-skipping case!");
3560void Preprocessor::HandleElseDirective(
Token &
Result,
const Token &HashToken) {
3566 PPConditionalInfo CI;
3567 if (CurPPLexer->popConditionalLevel(CI)) {
3573 if (CurPPLexer->getConditionalStackDepth() == 0)
3574 CurPPLexer->MIOpt.EnterTopLevelConditional();
3582 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3585 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3588 CurPPLexer->pushConditionalLevel(CI.
IfLoc,
false,
3596 true,
Result.getLocation());
3600void Preprocessor::HandleElifFamilyDirective(
Token &ElifToken,
3601 const Token &HashToken,
3613 if (LangOpts.CPlusPlus)
3614 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
3615 : diag::ext_cxx23_pp_directive;
3617 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
3618 : diag::ext_c23_pp_directive;
3619 Diag(ElifToken, DiagID) << DirKind;
3630 PPConditionalInfo CI;
3631 if (CurPPLexer->popConditionalLevel(CI)) {
3632 Diag(ElifToken, diag::pp_err_elif_without_if) << DirKind;
3637 if (CurPPLexer->getConditionalStackDepth() == 0)
3638 CurPPLexer->MIOpt.EnterTopLevelConditional();
3642 Diag(ElifToken, diag::pp_err_elif_after_else) << DirKind;
3647 Callbacks->Elif(ElifToken.
getLocation(), ConditionRange,
3650 case tok::pp_elifdef:
3653 case tok::pp_elifndef:
3657 assert(
false &&
"unexpected directive kind");
3662 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3665 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3668 CurPPLexer->pushConditionalLevel(ElifToken.
getLocation(),
false,
3674 SkipExcludedConditionalBlock(
3679std::optional<LexEmbedParametersResult>
3682 tok::TokenKind EndTokenKind = ForHasEmbed ? tok::r_paren : tok::eod;
3684 auto DiagMismatchedBracesAndSkipToEOD =
3686 std::pair<tok::TokenKind, SourceLocation> Matches) {
3688 Diag(Matches.second, diag::note_matching) << Matches.first;
3689 if (CurTok.
isNot(EndTokenKind))
3694 if (CurTok.
isNot(Kind)) {
3695 Diag(CurTok, diag::err_expected) << Kind;
3696 if (CurTok.
isNot(EndTokenKind))
3713 auto LexPPParameterName = [&]() -> std::optional<std::string> {
3716 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3717 return std::nullopt;
3724 if (CurTok.
is(tok::coloncolon)) {
3727 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3728 return std::nullopt;
3734 return (llvm::Twine(Prefix->
getName()) +
"::" + Suffix->
getName()).str();
3736 return Prefix->
getName().str();
3743 auto NormalizeParameterName = [](StringRef Name) {
3744 if (Name.size() > 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
3745 return Name.substr(2, Name.size() - 4);
3749 auto LexParenthesizedIntegerExpr = [&]() -> std::optional<size_t> {
3752 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3753 return std::nullopt;
3758 bool EvaluatedDefined;
3759 DirectiveEvalResult LimitEvalResult = EvaluateDirectiveExpression(
3760 ParameterIfNDef, CurTok, EvaluatedDefined,
false);
3762 if (!LimitEvalResult.Value) {
3765 assert(CurTok.
is(tok::eod) &&
"expect to be at the end of directive");
3766 return std::nullopt;
3769 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3770 return std::nullopt;
3777 if (EvaluatedDefined) {
3778 Diag(CurTok, diag::err_defined_in_pp_embed);
3779 return std::nullopt;
3782 if (LimitEvalResult.Value) {
3783 const llvm::APSInt &
Result = *LimitEvalResult.Value;
3784 if (
Result.isNegative()) {
3785 Diag(CurTok, diag::err_requires_positive_value)
3787 if (CurTok.
isNot(EndTokenKind))
3789 return std::nullopt;
3791 return Result.getLimitedValue();
3793 return std::nullopt;
3799 return tok::r_paren;
3801 return tok::r_brace;
3803 return tok::r_square;
3805 llvm_unreachable(
"should not get here");
3809 auto LexParenthesizedBalancedTokenSoup =
3811 std::vector<std::pair<tok::TokenKind, SourceLocation>> BracketStack;
3814 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3818 bool WaitingForInnerCloseParen =
false;
3819 while (CurTok.
isNot(tok::eod) &&
3820 (WaitingForInnerCloseParen || CurTok.
isNot(tok::r_paren))) {
3825 WaitingForInnerCloseParen =
true;
3832 WaitingForInnerCloseParen =
false;
3835 case tok::r_square: {
3836 if (BracketStack.empty()) {
3837 ExpectOrDiagAndSkipToEOD(tok::r_paren);
3841 GetMatchingCloseBracket(BracketStack.back().first);
3842 if (CurTok.
getKind() != Matching) {
3843 DiagMismatchedBracesAndSkipToEOD(Matching, BracketStack.back());
3846 BracketStack.pop_back();
3849 Tokens.push_back(CurTok);
3854 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3862 while (!CurTok.
isOneOf(EndTokenKind, tok::eod)) {
3864 std::optional<std::string> ParamName = LexPPParameterName();
3866 return std::nullopt;
3867 StringRef
Parameter = NormalizeParameterName(*ParamName);
3874 if (
Result.MaybeLimitParam)
3877 std::optional<size_t> Limit = LexParenthesizedIntegerExpr();
3879 return std::nullopt;
3882 }
else if (
Parameter ==
"clang::offset") {
3883 if (
Result.MaybeOffsetParam)
3886 std::optional<size_t> Offset = LexParenthesizedIntegerExpr();
3888 return std::nullopt;
3892 if (
Result.MaybePrefixParam)
3896 if (!LexParenthesizedBalancedTokenSoup(Soup))
3897 return std::nullopt;
3899 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
3901 if (
Result.MaybeSuffixParam)
3905 if (!LexParenthesizedBalancedTokenSoup(Soup))
3906 return std::nullopt;
3908 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
3910 if (
Result.MaybeIfEmptyParam)
3914 if (!LexParenthesizedBalancedTokenSoup(Soup))
3915 return std::nullopt;
3917 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
3919 ++
Result.UnrecognizedParams;
3923 if (CurTok.
is(tok::l_paren)) {
3925 if (!LexParenthesizedBalancedTokenSoup(Soup))
3926 return std::nullopt;
3929 Diag(ParamStartLoc, diag::err_pp_unknown_parameter) << 1 <<
Parameter;
3930 if (CurTok.
isNot(EndTokenKind))
3932 return std::nullopt;
3939void Preprocessor::HandleEmbedDirectiveImpl(
3941 StringRef BinaryContents, StringRef
FileName) {
3942 if (BinaryContents.empty()) {
3950 size_t TokCount = Toks.size();
3951 auto NewToks = std::make_unique<Token[]>(TokCount);
3952 llvm::copy(Toks, NewToks.get());
3953 EnterTokenStream(std::move(NewToks), TokCount,
true,
true);
3960 size_t TotalNumToks = 1 + NumPrefixToks + NumSuffixToks;
3962 auto Toks = std::make_unique<Token[]>(TotalNumToks);
3967 CurIdx += NumPrefixToks;
3970 EmbedAnnotationData *
Data =
new (BP) EmbedAnnotationData;
3971 Data->BinaryData = BinaryContents;
3974 Toks[CurIdx].startToken();
3975 Toks[CurIdx].setKind(tok::annot_embed);
3976 Toks[CurIdx].setAnnotationRange(HashLoc);
3977 Toks[CurIdx++].setAnnotationValue(
Data);
3982 CurIdx += NumSuffixToks;
3985 assert(CurIdx == TotalNumToks &&
"Calculated the incorrect number of tokens");
3986 EnterTokenStream(std::move(Toks), TotalNumToks,
true,
true);
3993 Diag(EmbedTok, diag::warn_compat_pp_embed_directive);
3995 Diag(EmbedTok, diag::ext_pp_embed_directive)
3996 << (LangOpts.CPlusPlus ? 1 : 0);
4003 if (FilenameTok.
isNot(tok::header_name)) {
4005 if (FilenameTok.
isNot(tok::eod))
4018 std::optional<LexEmbedParametersResult> Params =
4021 assert((Params || CurTok.
is(tok::eod)) &&
4022 "expected success or to be at the end of the directive");
4027 SmallString<128> FilenameBuffer;
4028 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
4029 StringRef OriginalFilename = Filename;
4035 if (Filename.empty())
4040 if (!MaybeFileRef) {
4042 if (Callbacks && Callbacks->EmbedFileNotFound(Filename)) {
4045 Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
4050 Diag(FilenameTok, diag::err_pp_embed_device_file) << Filename;
4054 std::optional<llvm::MemoryBufferRef> MaybeFile =
4058 Diag(FilenameTok, diag::err_cannot_open_file)
4059 << Filename <<
"a buffer to the contents could not be created";
4062 StringRef BinaryContents = MaybeFile->getBuffer();
4067 if (Params->MaybeOffsetParam) {
4072 BinaryContents = BinaryContents.substr(Params->MaybeOffsetParam->Offset);
4075 if (Params->MaybeLimitParam) {
4079 BinaryContents = BinaryContents.substr(0, Params->MaybeLimitParam->Limit);
4083 Callbacks->EmbedDirective(HashLoc, Filename, isAngled, MaybeFileRef,
4092 void *Mem = BP.Allocate(OriginalFilename.size(),
alignof(
char *));
4093 memcpy(Mem, OriginalFilename.data(), OriginalFilename.size());
4094 StringRef FilenameToGo =
4095 StringRef(
static_cast<char *
>(Mem), OriginalFilename.size());
4096 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.