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);
1405 case tok::pp_assert:
1408 case tok::pp_unassert:
1412 case tok::pp___public_macro:
1414 return HandleMacroPublicDirective(
Result);
1417 case tok::pp___private_macro:
1419 return HandleMacroPrivateDirective();
1430 auto Toks = std::make_unique<Token[]>(2);
1432 Toks[0] = SavedHash;
1437 if (
Result.is(tok::hashhash))
1438 Toks[1].setKind(tok::unknown);
1443 EnterTokenStream(std::move(Toks), 2,
false,
false);
1449 Diag(
Result, diag::err_pp_invalid_directive) << 0;
1461 bool IsGNULineDirective=
false) {
1462 if (DigitTok.
isNot(tok::numeric_constant)) {
1463 PP.
Diag(DigitTok, DiagID);
1465 if (DigitTok.
isNot(tok::eod))
1471 IntegerBuffer.resize(DigitTok.
getLength());
1472 const char *DigitTokBegin = &IntegerBuffer[0];
1482 for (
unsigned i = 0; i != ActualLength; ++i) {
1485 if (DigitTokBegin[i] ==
'\'')
1488 if (!
isDigit(DigitTokBegin[i])) {
1490 diag::err_pp_line_digit_sequence) << IsGNULineDirective;
1495 unsigned NextVal = Val*10+(DigitTokBegin[i]-
'0');
1496 if (NextVal < Val) {
1497 PP.
Diag(DigitTok, DiagID);
1504 if (DigitTokBegin[0] ==
'0' && Val)
1506 << IsGNULineDirective;
1518void Preprocessor::HandleLineDirective() {
1526 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*
this))
1530 Diag(DigitTok, diag::ext_pp_line_zero);
1534 unsigned LineLimit = 32768U;
1535 if (LangOpts.C99 || LangOpts.CPlusPlus11)
1536 LineLimit = 2147483648U;
1537 if (LineNo >= LineLimit)
1538 Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
1539 else if (LangOpts.CPlusPlus11 && LineNo >= 32768U)
1540 Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
1542 int FilenameID = -1;
1548 if (StrTok.
is(tok::eod))
1550 else if (StrTok.
isNot(tok::string_literal)) {
1551 Diag(StrTok, diag::err_pp_line_invalid_filename);
1555 Diag(StrTok, diag::err_invalid_string_udl);
1560 StringLiteralParser
Literal(StrTok, *
this);
1561 assert(
Literal.isOrdinary() &&
"Didn't allow wide strings in");
1567 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1571 FilenameID = SourceMgr.getLineTableFilenameID(
Literal.GetString());
1584 SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1586 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID,
false,
1590 Callbacks->FileChanged(CurPPLexer->getSourceLocation(),
1602 if (FlagTok.
is(tok::eod))
return false;
1603 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1610 if (FlagTok.
is(tok::eod))
return false;
1611 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1613 }
else if (FlagVal == 2) {
1629 SM.getDecomposedExpansionLoc(IncLoc).first != CurFileID) {
1630 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);
1636 if (FlagTok.
is(tok::eod))
return false;
1637 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1643 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1651 if (FlagTok.
is(tok::eod))
return false;
1652 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1657 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1665 if (FlagTok.
is(tok::eod))
return false;
1668 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1680void Preprocessor::HandleDigitDirective(
Token &DigitTok) {
1684 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
1691 bool IsFileEntry =
false, IsFileExit =
false;
1692 int FilenameID = -1;
1697 if (StrTok.
is(tok::eod)) {
1698 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1700 FileKind = SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1701 }
else if (StrTok.
isNot(tok::string_literal)) {
1702 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1706 Diag(StrTok, diag::err_invalid_string_udl);
1711 StringLiteralParser
Literal(StrTok, *
this);
1712 assert(
Literal.isOrdinary() &&
"Didn't allow wide strings in");
1718 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1726 if (!SourceMgr.isInPredefinedFile(DigitTok.
getLocation()))
1727 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1731 if (!(IsFileExit &&
Literal.GetString().empty()))
1732 FilenameID = SourceMgr.getLineTableFilenameID(
Literal.GetString());
1736 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID, IsFileEntry,
1737 IsFileExit, FileKind);
1746 else if (IsFileExit)
1749 Callbacks->FileChanged(CurPPLexer->getSourceLocation(), Reason, FileKind);
1755void Preprocessor::HandleUserDiagnosticDirective(
Token &
Tok,
1763 CurLexer->ReadToEndOfLine(&Message);
1767 StringRef Msg =
Message.str().ltrim(
' ');
1770 Diag(
Tok, diag::pp_hash_warning) << Msg;
1772 Diag(
Tok, diag::err_pp_hash_error) << Msg;
1777void Preprocessor::HandleIdentSCCSDirective(
Token &
Tok) {
1779 Diag(
Tok, diag::ext_pp_ident_directive);
1786 if (StrTok.
isNot(tok::string_literal) &&
1787 StrTok.
isNot(tok::wide_string_literal)) {
1788 Diag(StrTok, diag::err_pp_malformed_ident);
1789 if (StrTok.
isNot(tok::eod))
1795 Diag(StrTok, diag::err_invalid_string_udl);
1812void Preprocessor::HandleMacroPublicDirective(
Token &
Tok) {
1814 ReadMacroName(MacroNameTok,
MU_Undef);
1817 if (MacroNameTok.
is(tok::eod))
1829 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1839void Preprocessor::HandleMacroPrivateDirective() {
1841 ReadMacroName(MacroNameTok,
MU_Undef);
1844 if (MacroNameTok.
is(tok::eod))
1856 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1876 StringRef &Buffer) {
1878 assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1890 if (Buffer[0] ==
'<') {
1891 if (Buffer.back() !=
'>') {
1892 Diag(Loc, diag::err_pp_expects_filename);
1893 Buffer = StringRef();
1897 }
else if (Buffer[0] ==
'"') {
1898 if (Buffer.back() !=
'"') {
1899 Diag(Loc, diag::err_pp_expects_filename);
1900 Buffer = StringRef();
1905 Diag(Loc, diag::err_pp_expects_filename);
1906 Buffer = StringRef();
1911 if (Buffer.size() <= 2) {
1912 Diag(Loc, diag::err_pp_empty_filename);
1913 Buffer = StringRef();
1918 Buffer = Buffer.substr(1, Buffer.size()-2);
1925 void *AnnotationVal) {
1928 auto Tok = std::make_unique<Token[]>(1);
1929 Tok[0].startToken();
1930 Tok[0].setKind(Kind);
1931 Tok[0].setLocation(Range.getBegin());
1932 Tok[0].setAnnotationEndLoc(Range.getEnd());
1933 Tok[0].setAnnotationValue(AnnotationVal);
1934 EnterTokenStream(std::move(
Tok), 1,
true,
false);
1944 for (
size_t I = 0, N = Path.size(); I != N; ++I) {
1947 PathString += Path[I].getIdentifierInfo()->getName();
1950 int IncludeKind = 0;
1952 case tok::pp_include:
1956 case tok::pp_import:
1960 case tok::pp_include_next:
1964 case tok::pp___include_macros:
1969 llvm_unreachable(
"unknown include directive kind");
1972 PP.
Diag(HashLoc, diag::remark_pp_include_directive_modular_translation)
1973 << IncludeKind << PathString;
1980 StringRef RealPathName,
1981 llvm::sys::path::Style Separator) {
1982 auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName);
1983 auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName);
1985 bool SuggestReplacement =
false;
1987 auto IsSep = [Separator](StringRef Component) {
1988 return Component.size() == 1 &&
1989 llvm::sys::path::is_separator(Component[0], Separator);
1994 for (
auto &Component : llvm::reverse(Components)) {
1995 if (
"." == Component) {
1996 }
else if (
".." == Component) {
2000 }
else if (RealPathComponentIter != RealPathComponentEnd) {
2001 if (!IsSep(Component) && !IsSep(*RealPathComponentIter) &&
2002 Component != *RealPathComponentIter) {
2006 SuggestReplacement =
2007 RealPathComponentIter->equals_insensitive(Component);
2008 if (!SuggestReplacement)
2010 Component = *RealPathComponentIter;
2012 ++RealPathComponentIter;
2015 return SuggestReplacement;
2024 Module *ShadowingModule =
nullptr;
2030 Diags.Report(MissingHeader.
FileNameLoc, diag::err_module_header_missing)
2032 }
else if (ShadowingModule) {
2035 diag::note_previous_definition);
2046std::pair<ConstSearchDirIterator, const FileEntry *>
2047Preprocessor::getIncludeNextStart(
const Token &IncludeNextTok)
const {
2052 const FileEntry *LookupFromFile =
nullptr;
2060 Diag(IncludeNextTok, diag::pp_include_next_in_primary);
2061 }
else if (CurLexerSubmodule) {
2064 assert(CurPPLexer &&
"#include_next directive in macro?");
2065 if (
auto FE = CurPPLexer->getFileEntry())
2066 LookupFromFile = *FE;
2068 }
else if (!Lookup) {
2073 Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
2079 return {Lookup, LookupFromFile};
2095 if (FilenameTok.
isNot(tok::header_name)) {
2096 if (FilenameTok.
is(tok::identifier) && PPOpts.SingleFileParseMode) {
2106 if (FilenameTok.
isNot(tok::eod))
2115 SourceLocation EndLoc =
2118 auto Action = HandleHeaderIncludeOrImport(HashLoc, IncludeTok, FilenameTok,
2119 EndLoc, LookupFrom, LookupFromFile);
2120 switch (Action.Kind) {
2121 case ImportAction::None:
2122 case ImportAction::SkippedModuleImport:
2124 case ImportAction::ModuleBegin:
2126 tok::annot_module_begin, Action.ModuleForHeader);
2128 case ImportAction::HeaderUnitImport:
2130 Action.ModuleForHeader);
2132 case ImportAction::ModuleImport:
2134 tok::annot_module_include, Action.ModuleForHeader);
2136 case ImportAction::Failure:
2137 assert(TheModuleLoader.HadFatalFailure &&
2138 "This should be an early exit only to a fatal error");
2139 TheModuleLoader.HadFatalFailure =
true;
2141 CurLexer->cutOffLexing();
2149 const Token &FilenameTok,
bool &IsFrameworkFound,
bool IsImportDecl,
2151 const FileEntry *LookupFromFile, StringRef &LookupFilename,
2154 auto DiagnoseHeaderInclusion = [&](FileEntryRef FE) {
2155 if (LangOpts.AsmPreprocessor)
2159 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
2160 bool RequestingModuleIsModuleInterface =
2161 !SourceMgr.isInMainFile(FilenameLoc);
2163 HeaderInfo.getModuleMap().diagnoseHeaderInclusion(
2164 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
2169 FilenameLoc, LookupFilename, isAngled, LookupFrom, LookupFromFile, CurDir,
2170 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2171 &SuggestedModule, &IsMapped, &IsFrameworkFound);
2173 DiagnoseHeaderInclusion(*
File);
2178 if (Callbacks && Callbacks->FileNotFound(Filename))
2179 return std::nullopt;
2181 if (SuppressIncludeNotFoundError)
2182 return std::nullopt;
2189 FilenameLoc, LookupFilename,
false, LookupFrom, LookupFromFile, CurDir,
2190 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
2191 &SuggestedModule, &IsMapped,
2194 DiagnoseHeaderInclusion(*
File);
2195 Diag(FilenameTok, diag::err_pp_file_not_found_angled_include_not_fatal)
2196 << Filename << IsImportDecl
2198 "\"" + Filename.str() +
"\"");
2205 StringRef OriginalFilename = Filename;
2206 if (LangOpts.SpellChecking) {
2209 auto CorrectTypoFilename = [](llvm::StringRef Filename) {
2212 Filename = Filename.drop_back();
2216 StringRef TypoCorrectionName = CorrectTypoFilename(Filename);
2217 StringRef TypoCorrectionLookupName = CorrectTypoFilename(LookupFilename);
2220 FilenameLoc, TypoCorrectionLookupName, isAngled, LookupFrom,
2221 LookupFromFile, CurDir, Callbacks ? &SearchPath :
nullptr,
2222 Callbacks ? &RelativePath :
nullptr, &SuggestedModule, &IsMapped,
2225 DiagnoseHeaderInclusion(*
File);
2228 FilenameRange,
"<" + TypoCorrectionName.str() +
">")
2229 : FixItHint::CreateReplacement(
2230 FilenameRange,
"\"" + TypoCorrectionName.str() +
"\"");
2231 Diag(FilenameTok, diag::err_pp_file_not_found_typo_not_fatal)
2232 << OriginalFilename << TypoCorrectionName << Hint;
2235 Filename = TypoCorrectionName;
2236 LookupFilename = TypoCorrectionLookupName;
2242 assert(!
File &&
"expected missing file");
2243 Diag(FilenameTok, diag::err_pp_file_not_found)
2244 << OriginalFilename << FilenameRange;
2245 if (IsFrameworkFound) {
2246 size_t SlashPos = OriginalFilename.find(
'/');
2247 assert(SlashPos != StringRef::npos &&
2248 "Include with framework name should have '/' in the filename");
2249 StringRef FrameworkName = OriginalFilename.substr(0, SlashPos);
2250 FrameworkCacheEntry &CacheEntry =
2251 HeaderInfo.LookupFrameworkCache(FrameworkName);
2252 assert(CacheEntry.
Directory &&
"Found framework should be in cache");
2253 Diag(FilenameTok, diag::note_pp_framework_without_header)
2254 << OriginalFilename.substr(SlashPos + 1) << FrameworkName
2258 return std::nullopt;
2273Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
2277 SmallString<128> FilenameBuffer;
2278 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
2279 SourceLocation CharEnd = FilenameTok.
getEndLoc();
2281 CharSourceRange FilenameRange
2283 StringRef OriginalFilename = Filename;
2289 if (Filename.empty())
2290 return {ImportAction::None};
2292 bool IsImportDecl = HashLoc.
isInvalid();
2293 SourceLocation StartLoc = IsImportDecl ? IncludeTok.
getLocation() : HashLoc;
2296 if (PragmaARCCFCodeAuditedInfo.getLoc().isValid()) {
2297 Diag(StartLoc, diag::err_pp_include_in_arc_cf_code_audited) << IsImportDecl;
2298 Diag(PragmaARCCFCodeAuditedInfo.getLoc(), diag::note_pragma_entered_here);
2301 PragmaARCCFCodeAuditedInfo = IdentifierLoc();
2305 if (PragmaAssumeNonNullLoc.isValid()) {
2306 Diag(StartLoc, diag::err_pp_include_in_assume_nonnull) << IsImportDecl;
2307 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
2310 PragmaAssumeNonNullLoc = SourceLocation();
2313 if (HeaderInfo.HasIncludeAliasMap()) {
2317 StringRef NewName = HeaderInfo.MapHeaderToIncludeAlias(OriginalFilename);
2318 if (!NewName.empty())
2323 bool IsMapped =
false;
2324 bool IsFrameworkFound =
false;
2326 SmallString<1024> SearchPath;
2327 SmallString<1024> RelativePath;
2330 ModuleMap::KnownHeader SuggestedModule;
2331 SourceLocation FilenameLoc = FilenameTok.
getLocation();
2332 StringRef LookupFilename = Filename;
2336 SmallString<128> NormalizedPath;
2337 llvm::sys::path::Style BackslashStyle = llvm::sys::path::Style::native;
2338 if (is_style_posix(BackslashStyle) && LangOpts.MicrosoftExt) {
2339 NormalizedPath = Filename.str();
2340 llvm::sys::path::native(NormalizedPath);
2341 LookupFilename = NormalizedPath;
2342 BackslashStyle = llvm::sys::path::Style::windows;
2346 &CurDir, Filename, FilenameLoc, FilenameRange, FilenameTok,
2347 IsFrameworkFound, IsImportDecl, IsMapped, LookupFrom, LookupFromFile,
2348 LookupFilename, RelativePath, SearchPath, SuggestedModule, isAngled);
2352 SkippingUntilPCHThroughHeader =
false;
2353 return {ImportAction::None};
2371 enum { Enter,
Import,
Skip, IncludeLimitReached } Action = Enter;
2373 if (PPOpts.SingleFileParseMode)
2374 Action = IncludeLimitReached;
2379 if (Action == Enter && HasReachedMaxIncludeDepth &&
File &&
2381 Action = IncludeLimitReached;
2388 bool MaybeTranslateInclude = Action == Enter &&
File && ModuleToImport &&
2392 bool UsableHeaderUnit =
false;
2393 if (
getLangOpts().CPlusPlusModules && ModuleToImport &&
2395 if (TrackGMFState.inGMF() || IsImportDecl)
2396 UsableHeaderUnit =
true;
2397 else if (!IsImportDecl) {
2399 ModuleToImport =
nullptr;
2403 bool UsableClangHeaderModule =
2410 if (MaybeTranslateInclude && (UsableHeaderUnit || UsableClangHeaderModule)) {
2418 diag::note_implicit_top_level_module_import_here)
2420 return {ImportAction::None};
2426 SmallVector<IdentifierLoc, 2> Path;
2427 for (
Module *Mod = ModuleToImport; Mod; Mod = Mod->Parent)
2430 std::reverse(Path.begin(), Path.end());
2440 ModuleLoadResult Imported = TheModuleLoader.loadModule(
2443 assert((Imported ==
nullptr || Imported == ModuleToImport) &&
2444 "the imported module is different than the suggested one");
2450 static_cast<Module *
>(Imported)->getTopLevelModule());
2455 ModuleToImport =
nullptr;
2463 Token &
Result = IncludeTok;
2464 assert(CurLexer &&
"#include but no current lexer set!");
2466 CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
2467 CurLexer->cutOffLexing();
2469 return {ImportAction::None};
2477 SourceMgr.getFileCharacteristic(FilenameTok.
getLocation());
2479 FileCharacter = std::max(HeaderInfo.getFileDirFlavor(*
File), FileCharacter);
2490 bool IsFirstIncludeOfFile =
false;
2494 if (Action == Enter &&
File &&
2495 !HeaderInfo.ShouldEnterIncludeFile(*
this, *
File, EnterOnce,
2497 IsFirstIncludeOfFile)) {
2508 if (UsableHeaderUnit && !
getLangOpts().CompilingPCH)
2509 Action = TrackGMFState.inGMF() ?
Import :
Skip;
2511 Action = (ModuleToImport && !
getLangOpts().CompilingPCH) ? Import :
Skip;
2519 if (Action == Enter &&
File && PreambleConditionalStack.isRecording() &&
2520 SourceMgr.isMainFile(
File->getFileEntry())) {
2522 diag::err_pp_including_mainfile_in_preamble);
2523 return {ImportAction::None};
2526 if (Callbacks && !IsImportDecl) {
2529 Callbacks->InclusionDirective(HashLoc, IncludeTok, LookupFilename, isAngled,
2530 FilenameRange,
File, SearchPath, RelativePath,
2531 SuggestedModule.
getModule(), Action == Import,
2534 Callbacks->FileSkipped(*
File, FilenameTok, FileCharacter);
2538 return {ImportAction::None};
2542 if (IsImportDecl && !ModuleToImport) {
2543 Diag(FilenameTok, diag::err_header_import_not_header_unit)
2544 << OriginalFilename <<
File->getName();
2545 return {ImportAction::None};
2550 const bool CheckIncludePathPortability =
2551 !IsMapped && !
File->getFileEntry().tryGetRealPathName().empty();
2553 if (CheckIncludePathPortability) {
2554 StringRef Name = LookupFilename;
2555 StringRef NameWithoriginalSlashes = Filename;
2559 bool NameWasUNC = Name.consume_front(
"\\\\?\\");
2560 NameWithoriginalSlashes.consume_front(
"\\\\?\\");
2562 StringRef RealPathName =
File->getFileEntry().tryGetRealPathName();
2563 SmallVector<StringRef, 16> Components(llvm::sys::path::begin(Name),
2564 llvm::sys::path::end(Name));
2576 SmallString<128> FixedDriveRealPath;
2577 if (llvm::sys::path::is_absolute(Name) &&
2578 llvm::sys::path::is_absolute(RealPathName) &&
2581 assert(Components.size() >= 3 &&
"should have drive, backslash, name");
2582 assert(Components[0].size() == 2 &&
"should start with drive");
2583 assert(Components[0][1] ==
':' &&
"should have colon");
2584 FixedDriveRealPath = (Name.substr(0, 1) + RealPathName.substr(1)).str();
2585 RealPathName = FixedDriveRealPath;
2590 SmallString<128> Path;
2591 Path.reserve(Name.size()+2);
2592 Path.push_back(isAngled ?
'<' :
'"');
2594 const auto IsSep = [BackslashStyle](
char c) {
2595 return llvm::sys::path::is_separator(
c, BackslashStyle);
2598 for (
auto Component : Components) {
2610 if (!(Component.size() == 1 && IsSep(Component[0])))
2611 Path.append(Component);
2612 else if (Path.size() != 1)
2616 if (Path.size() > NameWithoriginalSlashes.size()) {
2617 Path.push_back(isAngled ?
'>' :
'"');
2620 assert(IsSep(NameWithoriginalSlashes[Path.size()-1]));
2622 Path.push_back(NameWithoriginalSlashes[Path.size()-1]);
2623 while (Path.size() <= NameWithoriginalSlashes.size() &&
2624 IsSep(NameWithoriginalSlashes[Path.size()-1]));
2630 Path = (Path.substr(0, 1) +
"\\\\?\\" + Path.substr(1)).str();
2637 ? diag::pp_nonportable_path
2638 : diag::pp_nonportable_system_path;
2639 Diag(FilenameTok, DiagId) << Path <<
2648 return {ImportAction::SkippedModuleImport, ModuleToImport};
2649 return {ImportAction::None};
2651 case IncludeLimitReached:
2654 return {ImportAction::None};
2658 assert(ModuleToImport &&
"no module to import");
2663 tok::pp___include_macros)
2664 return {ImportAction::None};
2666 return {ImportAction::ModuleImport, ModuleToImport};
2674 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
2675 Diag(FilenameTok, diag::err_pp_include_too_deep);
2676 HasReachedMaxIncludeDepth =
true;
2677 return {ImportAction::None};
2681 Diag(FilenameTok, diag::warn_pp_include_angled_in_module_purview)
2685 SourceLocation IncludePos = FilenameTok.
getLocation();
2689 IncludePos = SourceMgr.getExpansionRange(IncludePos).getEnd();
2690 FileID FID = SourceMgr.createFileID(*
File, IncludePos, FileCharacter);
2692 TheModuleLoader.HadFatalFailure =
true;
2693 return ImportAction::Failure;
2698 IsFirstIncludeOfFile))
2699 return {ImportAction::None};
2703 if (ModuleToImport && !ModuleToImport->
isHeaderUnit()) {
2708 diag::err_module_build_shadowed_submodule)
2711 diag::note_previous_definition);
2712 return {ImportAction::None};
2724 return {ImportAction::None};
2726 assert(!CurLexerSubmodule &&
"should not have marked this as a module yet");
2727 CurLexerSubmodule = ModuleToImport;
2737 return {ImportAction::ModuleBegin, ModuleToImport};
2740 assert(!IsImportDecl &&
"failed to diagnose missing module for import decl");
2741 return {ImportAction::None};
2746void Preprocessor::HandleIncludeNextDirective(
SourceLocation HashLoc,
2747 Token &IncludeNextTok) {
2748 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
2751 const FileEntry *LookupFromFile;
2752 std::tie(Lookup, LookupFromFile) = getIncludeNextStart(IncludeNextTok);
2754 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
2759void Preprocessor::HandleMicrosoftImportDirective(
Token &
Tok) {
2765 Diag(
Tok, diag::err_pp_import_directive_ms );
2776 if (!LangOpts.ObjC) {
2777 if (LangOpts.MSVCCompat)
2778 return HandleMicrosoftImportDirective(ImportTok);
2779 Diag(ImportTok, diag::ext_pp_import_directive);
2781 return HandleIncludeDirective(HashLoc, ImportTok);
2788void Preprocessor::HandleIncludeMacrosDirective(
SourceLocation HashLoc,
2789 Token &IncludeMacrosTok) {
2792 SourceLocation Loc = IncludeMacrosTok.
getLocation();
2793 if (SourceMgr.getBufferName(Loc) !=
"<built-in>") {
2795 diag::pp_include_macros_out_of_predefines);
2802 HandleIncludeDirective(HashLoc, IncludeMacrosTok);
2807 assert(TmpTok.
isNot(tok::eof) &&
"Didn't find end of -imacros!");
2808 }
while (TmpTok.
isNot(tok::hashhash));
2830 Diag(
Tok, diag::err_pp_expected_ident_in_arg_list);
2834 Diag(
Tok, LangOpts.CPlusPlus11 ?
2835 diag::warn_cxx98_compat_variadic_macro :
2836 diag::ext_variadic_macro);
2839 if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus) {
2840 Diag(
Tok, diag::ext_pp_opencl_variadic_macros);
2846 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2855 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2863 Diag(
Tok, diag::err_pp_invalid_tok_in_arg_list);
2869 if (llvm::is_contained(Parameters, II)) {
2870 Diag(
Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
2882 Diag(
Tok, diag::err_pp_expected_comma_in_arg_list);
2891 Diag(
Tok, diag::ext_named_variadic_macro);
2896 Diag(
Tok, diag::err_pp_missing_rparen_in_macro_def);
2926 StringRef ValueText = II->
getName();
2927 StringRef TrimmedValue = ValueText;
2928 if (!ValueText.starts_with(
"__")) {
2929 if (ValueText.starts_with(
"_"))
2930 TrimmedValue = TrimmedValue.drop_front(1);
2934 TrimmedValue = TrimmedValue.drop_front(2);
2935 if (TrimmedValue.ends_with(
"__"))
2936 TrimmedValue = TrimmedValue.drop_back(2);
2938 return TrimmedValue == MacroText;
2945 return MacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
2958MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
2959 const Token &MacroNameTok,
const bool ImmediatelyAfterHeaderGuard) {
2961 Token LastTok = MacroNameTok;
2969 auto _ = llvm::make_scope_exit([&]() {
2971 if (CurLexer->ParsingPreprocessorDirective)
2982 if (
Tok.
is(tok::eod)) {
2983 if (ImmediatelyAfterHeaderGuard) {
2993 }
else if (
Tok.
is(tok::l_paren)) {
2996 if (ReadMacroParameterList(MI, LastTok))
3010 }
else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
3013 Diag(
Tok, diag::ext_c99_whitespace_required_after_macro_name);
3022 if (
Tok.
is(tok::at))
3024 else if (
Tok.
is(tok::unknown)) {
3031 Diag(
Tok, diag::ext_missing_whitespace_after_macro_name);
3033 Diag(
Tok, diag::warn_missing_whitespace_after_macro_name);
3036 if (!
Tok.
is(tok::eod))
3039 SmallVector<Token, 16> Tokens;
3046 Tokens.push_back(
Tok);
3060 if (!
Tok.
isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
3061 Tokens.push_back(
Tok);
3063 if (VAOCtx.isVAOptToken(
Tok)) {
3065 if (VAOCtx.isInVAOpt()) {
3066 Diag(
Tok, diag::err_pp_vaopt_nested_use);
3072 Diag(
Tok, diag::err_pp_missing_lparen_in_vaopt_use);
3075 Tokens.push_back(
Tok);
3078 if (
Tok.
is(tok::hashhash)) {
3079 Diag(
Tok, diag::err_vaopt_paste_at_start);
3083 }
else if (VAOCtx.isInVAOpt()) {
3084 if (
Tok.
is(tok::r_paren)) {
3085 if (VAOCtx.sawClosingParen()) {
3086 assert(Tokens.size() >= 3 &&
3087 "Must have seen at least __VA_OPT__( "
3088 "and a subsequent tok::r_paren");
3089 if (Tokens[Tokens.size() - 2].is(tok::hashhash)) {
3090 Diag(
Tok, diag::err_vaopt_paste_at_end);
3094 }
else if (
Tok.
is(tok::l_paren)) {
3108 Tokens.push_back(
Tok);
3115 if (
Tok.
is(tok::hashhash)) {
3123 if (
Tok.
is(tok::eod)) {
3124 Tokens.push_back(LastTok);
3129 Tokens[Tokens.size() - 1].is(tok::comma))
3133 Tokens.push_back(LastTok);
3142 if (!VAOCtx.isVAOptToken(
Tok) &&
3151 LastTok.
setKind(tok::unknown);
3152 Tokens.push_back(LastTok);
3155 Diag(
Tok, diag::err_pp_stringize_not_parameter)
3156 << LastTok.
is(tok::hashat);
3162 Tokens.push_back(LastTok);
3167 if (!VAOCtx.isVAOptToken(
Tok)) {
3168 Tokens.push_back(
Tok);
3175 if (VAOCtx.isInVAOpt()) {
3176 assert(
Tok.
is(tok::eod) &&
"Must be at End Of preprocessing Directive");
3177 Diag(
Tok, diag::err_pp_expected_after)
3178 << LastTok.
getKind() << tok::r_paren;
3179 Diag(VAOCtx.getUnmatchedOpeningParenLoc(), diag::note_matching) << tok::l_paren;
3190 return II->
isStr(
"__strong") || II->
isStr(
"__weak") ||
3191 II->
isStr(
"__unsafe_unretained") || II->
isStr(
"__autoreleasing");
3196void Preprocessor::HandleDefineDirective(
3197 Token &DefineTok,
const bool ImmediatelyAfterHeaderGuard) {
3201 bool MacroShadowsKeyword;
3202 ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
3205 if (MacroNameTok.
is(tok::eod))
3212 emitFinalMacroWarning(MacroNameTok,
false);
3216 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
3218 MacroInfo *
const MI = ReadOptionalMacroParameterListAndBody(
3219 MacroNameTok, ImmediatelyAfterHeaderGuard);
3223 if (MacroShadowsKeyword &&
3225 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
3230 if (NumTokens != 0) {
3242 if (SkippingUntilPCHThroughHeader) {
3245 LangOpts.MicrosoftExt))
3249 if (!LangOpts.MicrosoftExt)
3260 emitFinalMacroWarning(MacroNameTok,
false);
3271 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) &&
3273 LangOpts.MicrosoftExt)) {
3284 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) {
3292 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
3296 !MI->
isIdenticalTo(*OtherMI, *
this, LangOpts.MicrosoftExt)) {
3306 DefMacroDirective *MD =
3314 !MacroExpansionInDirectivesOverride &&
3323 Callbacks->MacroDefined(MacroNameTok, MD);
3328void Preprocessor::HandleUndefDirective() {
3332 ReadMacroName(MacroNameTok,
MU_Undef);
3335 if (MacroNameTok.
is(tok::eod))
3344 UndefMacroDirective *Undef =
nullptr;
3347 emitFinalMacroWarning(MacroNameTok,
true);
3357 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
3362 Undef = AllocateUndefMacroDirective(MacroNameTok.
getLocation());
3368 Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
3383void Preprocessor::HandleIfdefDirective(
Token &
Result,
3384 const Token &HashToken,
3386 bool ReadAnyTokensBeforeDirective) {
3388 Token DirectiveTok =
Result;
3391 ReadMacroName(MacroNameTok);
3394 if (MacroNameTok.
is(tok::eod)) {
3397 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3412 if (CurPPLexer->getConditionalStackDepth() == 0) {
3417 if (!ReadAnyTokensBeforeDirective && !MI) {
3418 assert(isIfndef &&
"#ifdef shouldn't reach here");
3419 CurPPLexer->MIOpt.EnterTopLevelIfndef(MII, MacroNameTok.
getLocation());
3421 CurPPLexer->MIOpt.EnterTopLevelConditional();
3430 Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3432 Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3435 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3439 if (PPOpts.SingleFileParseMode && !MI) {
3442 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3445 }
else if (!MI == isIfndef || RetainExcludedCB) {
3447 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
3452 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3461void Preprocessor::HandleIfDirective(
Token &IfToken,
3462 const Token &HashToken,
3463 bool ReadAnyTokensBeforeDirective) {
3467 IdentifierInfo *IfNDefMacro =
nullptr;
3468 const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
3469 const bool ConditionalTrue = DER.Conditional;
3477 if (CurPPLexer->getConditionalStackDepth() == 0) {
3478 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
3480 CurPPLexer->MIOpt.EnterTopLevelIfndef(IfNDefMacro, IfToken.
getLocation());
3482 CurPPLexer->MIOpt.EnterTopLevelConditional();
3490 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3494 if (PPOpts.SingleFileParseMode && DER.IncludedUndefinedIds) {
3497 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3499 }
else if (ConditionalTrue || RetainExcludedCB) {
3501 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
3513void Preprocessor::HandleEndifDirective(
Token &EndifToken) {
3519 PPConditionalInfo CondInfo;
3520 if (CurPPLexer->popConditionalLevel(CondInfo)) {
3522 Diag(EndifToken, diag::err_pp_endif_without_if);
3527 if (CurPPLexer->getConditionalStackDepth() == 0)
3528 CurPPLexer->MIOpt.ExitTopLevelConditional();
3530 assert(!CondInfo.
WasSkipping && !CurPPLexer->LexingRawMode &&
3531 "This code should only be reachable in the non-skipping case!");
3539void Preprocessor::HandleElseDirective(
Token &
Result,
const Token &HashToken) {
3545 PPConditionalInfo CI;
3546 if (CurPPLexer->popConditionalLevel(CI)) {
3552 if (CurPPLexer->getConditionalStackDepth() == 0)
3553 CurPPLexer->MIOpt.EnterTopLevelConditional();
3561 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3564 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3567 CurPPLexer->pushConditionalLevel(CI.
IfLoc,
false,
3575 true,
Result.getLocation());
3579void Preprocessor::HandleElifFamilyDirective(
Token &ElifToken,
3580 const Token &HashToken,
3592 if (LangOpts.CPlusPlus)
3593 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
3594 : diag::ext_cxx23_pp_directive;
3596 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
3597 : diag::ext_c23_pp_directive;
3598 Diag(ElifToken, DiagID) << DirKind;
3609 PPConditionalInfo CI;
3610 if (CurPPLexer->popConditionalLevel(CI)) {
3611 Diag(ElifToken, diag::pp_err_elif_without_if) << DirKind;
3616 if (CurPPLexer->getConditionalStackDepth() == 0)
3617 CurPPLexer->MIOpt.EnterTopLevelConditional();
3621 Diag(ElifToken, diag::pp_err_elif_after_else) << DirKind;
3626 Callbacks->Elif(ElifToken.
getLocation(), ConditionRange,
3629 case tok::pp_elifdef:
3632 case tok::pp_elifndef:
3636 assert(
false &&
"unexpected directive kind");
3641 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&
3644 if ((PPOpts.SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3647 CurPPLexer->pushConditionalLevel(ElifToken.
getLocation(),
false,
3653 SkipExcludedConditionalBlock(
3658std::optional<LexEmbedParametersResult>
3661 tok::TokenKind EndTokenKind = ForHasEmbed ? tok::r_paren : tok::eod;
3663 auto DiagMismatchedBracesAndSkipToEOD =
3665 std::pair<tok::TokenKind, SourceLocation> Matches) {
3667 Diag(Matches.second, diag::note_matching) << Matches.first;
3668 if (CurTok.
isNot(EndTokenKind))
3673 if (CurTok.
isNot(Kind)) {
3674 Diag(CurTok, diag::err_expected) << Kind;
3675 if (CurTok.
isNot(EndTokenKind))
3692 auto LexPPParameterName = [&]() -> std::optional<std::string> {
3695 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3696 return std::nullopt;
3703 if (CurTok.
is(tok::coloncolon)) {
3706 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3707 return std::nullopt;
3713 return (llvm::Twine(Prefix->
getName()) +
"::" + Suffix->
getName()).str();
3715 return Prefix->
getName().str();
3722 auto NormalizeParameterName = [](StringRef Name) {
3723 if (Name.size() > 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
3724 return Name.substr(2, Name.size() - 4);
3728 auto LexParenthesizedIntegerExpr = [&]() -> std::optional<size_t> {
3731 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3732 return std::nullopt;
3737 bool EvaluatedDefined;
3738 DirectiveEvalResult LimitEvalResult = EvaluateDirectiveExpression(
3739 ParameterIfNDef, CurTok, EvaluatedDefined,
false);
3741 if (!LimitEvalResult.Value) {
3744 assert(CurTok.
is(tok::eod) &&
"expect to be at the end of directive");
3745 return std::nullopt;
3748 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3749 return std::nullopt;
3756 if (EvaluatedDefined) {
3757 Diag(CurTok, diag::err_defined_in_pp_embed);
3758 return std::nullopt;
3761 if (LimitEvalResult.Value) {
3762 const llvm::APSInt &
Result = *LimitEvalResult.Value;
3763 if (
Result.isNegative()) {
3764 Diag(CurTok, diag::err_requires_positive_value)
3766 if (CurTok.
isNot(EndTokenKind))
3768 return std::nullopt;
3770 return Result.getLimitedValue();
3772 return std::nullopt;
3778 return tok::r_paren;
3780 return tok::r_brace;
3782 return tok::r_square;
3784 llvm_unreachable(
"should not get here");
3788 auto LexParenthesizedBalancedTokenSoup =
3790 std::vector<std::pair<tok::TokenKind, SourceLocation>> BracketStack;
3793 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3797 bool WaitingForInnerCloseParen =
false;
3798 while (CurTok.
isNot(tok::eod) &&
3799 (WaitingForInnerCloseParen || CurTok.
isNot(tok::r_paren))) {
3804 WaitingForInnerCloseParen =
true;
3811 WaitingForInnerCloseParen =
false;
3814 case tok::r_square: {
3815 if (BracketStack.empty()) {
3816 ExpectOrDiagAndSkipToEOD(tok::r_paren);
3820 GetMatchingCloseBracket(BracketStack.back().first);
3821 if (CurTok.
getKind() != Matching) {
3822 DiagMismatchedBracesAndSkipToEOD(Matching, BracketStack.back());
3825 BracketStack.pop_back();
3828 Tokens.push_back(CurTok);
3833 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3841 while (!CurTok.
isOneOf(EndTokenKind, tok::eod)) {
3843 std::optional<std::string> ParamName = LexPPParameterName();
3845 return std::nullopt;
3846 StringRef
Parameter = NormalizeParameterName(*ParamName);
3853 if (
Result.MaybeLimitParam)
3856 std::optional<size_t> Limit = LexParenthesizedIntegerExpr();
3858 return std::nullopt;
3861 }
else if (
Parameter ==
"clang::offset") {
3862 if (
Result.MaybeOffsetParam)
3865 std::optional<size_t> Offset = LexParenthesizedIntegerExpr();
3867 return std::nullopt;
3871 if (
Result.MaybePrefixParam)
3875 if (!LexParenthesizedBalancedTokenSoup(Soup))
3876 return std::nullopt;
3878 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
3880 if (
Result.MaybeSuffixParam)
3884 if (!LexParenthesizedBalancedTokenSoup(Soup))
3885 return std::nullopt;
3887 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
3889 if (
Result.MaybeIfEmptyParam)
3893 if (!LexParenthesizedBalancedTokenSoup(Soup))
3894 return std::nullopt;
3896 std::move(Soup), {ParamStartLoc, CurTok.
getLocation()}};
3898 ++
Result.UnrecognizedParams;
3902 if (CurTok.
is(tok::l_paren)) {
3904 if (!LexParenthesizedBalancedTokenSoup(Soup))
3905 return std::nullopt;
3908 Diag(ParamStartLoc, diag::err_pp_unknown_parameter) << 1 <<
Parameter;
3909 if (CurTok.
isNot(EndTokenKind))
3911 return std::nullopt;
3918void Preprocessor::HandleEmbedDirectiveImpl(
3920 StringRef BinaryContents, StringRef
FileName) {
3921 if (BinaryContents.empty()) {
3929 size_t TokCount = Toks.size();
3930 auto NewToks = std::make_unique<Token[]>(TokCount);
3931 llvm::copy(Toks, NewToks.get());
3932 EnterTokenStream(std::move(NewToks), TokCount,
true,
true);
3939 size_t TotalNumToks = 1 + NumPrefixToks + NumSuffixToks;
3941 auto Toks = std::make_unique<Token[]>(TotalNumToks);
3946 CurIdx += NumPrefixToks;
3949 EmbedAnnotationData *
Data =
new (BP) EmbedAnnotationData;
3950 Data->BinaryData = BinaryContents;
3953 Toks[CurIdx].startToken();
3954 Toks[CurIdx].setKind(tok::annot_embed);
3955 Toks[CurIdx].setAnnotationRange(HashLoc);
3956 Toks[CurIdx++].setAnnotationValue(
Data);
3961 CurIdx += NumSuffixToks;
3964 assert(CurIdx == TotalNumToks &&
"Calculated the incorrect number of tokens");
3965 EnterTokenStream(std::move(Toks), TotalNumToks,
true,
true);
3972 Diag(EmbedTok, diag::warn_compat_pp_embed_directive);
3974 Diag(EmbedTok, diag::ext_pp_embed_directive)
3975 << (LangOpts.CPlusPlus ? 1 : 0);
3982 if (FilenameTok.
isNot(tok::header_name)) {
3984 if (FilenameTok.
isNot(tok::eod))
3997 std::optional<LexEmbedParametersResult> Params =
4000 assert((Params || CurTok.
is(tok::eod)) &&
4001 "expected success or to be at the end of the directive");
4006 SmallString<128> FilenameBuffer;
4007 StringRef Filename =
getSpelling(FilenameTok, FilenameBuffer);
4008 StringRef OriginalFilename = Filename;
4014 if (Filename.empty())
4019 if (!MaybeFileRef) {
4021 if (Callbacks && Callbacks->EmbedFileNotFound(OriginalFilename)) {
4024 Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
4029 Diag(FilenameTok, diag::err_pp_embed_device_file) << Filename;
4033 std::optional<llvm::MemoryBufferRef> MaybeFile =
4037 Diag(FilenameTok, diag::err_cannot_open_file)
4038 << Filename <<
"a buffer to the contents could not be created";
4041 StringRef BinaryContents = MaybeFile->getBuffer();
4046 if (Params->MaybeOffsetParam) {
4051 BinaryContents = BinaryContents.substr(Params->MaybeOffsetParam->Offset);
4054 if (Params->MaybeLimitParam) {
4058 BinaryContents = BinaryContents.substr(0, Params->MaybeLimitParam->Limit);
4062 Callbacks->EmbedDirective(HashLoc, Filename, isAngled, MaybeFileRef,
4071 void *Mem = BP.Allocate(OriginalFilename.size(),
alignof(
char *));
4072 memcpy(Mem, OriginalFilename.data(), OriginalFilename.size());
4073 StringRef FilenameToGo =
4074 StringRef(
static_cast<char *
>(Mem), OriginalFilename.size());
4075 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.