aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Lex/ModuleMap.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-12-18 20:30:12 +0000
committerDimitry Andric <dim@FreeBSD.org>2024-04-06 20:11:55 +0000
commit5f757f3ff9144b609b3c433dfd370cc6bdc191ad (patch)
tree1b4e980b866cd26a00af34c0a653eb640bd09caf /contrib/llvm-project/clang/lib/Lex/ModuleMap.cpp
parent3e1c8a35f741a5d114d0ba670b15191355711fe9 (diff)
parent312c0ed19cc5276a17bacf2120097bec4515b0f1 (diff)
Diffstat (limited to 'contrib/llvm-project/clang/lib/Lex/ModuleMap.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Lex/ModuleMap.cpp162
1 files changed, 94 insertions, 68 deletions
diff --git a/contrib/llvm-project/clang/lib/Lex/ModuleMap.cpp b/contrib/llvm-project/clang/lib/Lex/ModuleMap.cpp
index 6a5699dd484e..ea5d13deb114 100644
--- a/contrib/llvm-project/clang/lib/Lex/ModuleMap.cpp
+++ b/contrib/llvm-project/clang/lib/Lex/ModuleMap.cpp
@@ -235,7 +235,7 @@ OptionalFileEntryRef ModuleMap::findHeader(
llvm::sys::path::append(FullPathName, RelativePathName);
auto NormalHdrFile = GetFile(FullPathName);
- if (!NormalHdrFile && Directory->getName().endswith(".framework")) {
+ if (!NormalHdrFile && Directory->getName().ends_with(".framework")) {
// The lack of 'framework' keyword in a module declaration it's a simple
// mistake we can diagnose when the header exists within the proper
// framework style path.
@@ -253,6 +253,45 @@ OptionalFileEntryRef ModuleMap::findHeader(
return NormalHdrFile;
}
+/// Determine whether the given file name is the name of a builtin
+/// header, supplied by Clang to replace, override, or augment existing system
+/// headers.
+static bool isBuiltinHeaderName(StringRef FileName) {
+ return llvm::StringSwitch<bool>(FileName)
+ .Case("float.h", true)
+ .Case("iso646.h", true)
+ .Case("limits.h", true)
+ .Case("stdalign.h", true)
+ .Case("stdarg.h", true)
+ .Case("stdatomic.h", true)
+ .Case("stdbool.h", true)
+ .Case("stddef.h", true)
+ .Case("stdint.h", true)
+ .Case("tgmath.h", true)
+ .Case("unwind.h", true)
+ .Default(false);
+}
+
+/// Determine whether the given module name is the name of a builtin
+/// module that is cyclic with a system module on some platforms.
+static bool isBuiltInModuleName(StringRef ModuleName) {
+ return llvm::StringSwitch<bool>(ModuleName)
+ .Case("_Builtin_float", true)
+ .Case("_Builtin_inttypes", true)
+ .Case("_Builtin_iso646", true)
+ .Case("_Builtin_limits", true)
+ .Case("_Builtin_stdalign", true)
+ .Case("_Builtin_stdarg", true)
+ .Case("_Builtin_stdatomic", true)
+ .Case("_Builtin_stdbool", true)
+ .Case("_Builtin_stddef", true)
+ .Case("_Builtin_stdint", true)
+ .Case("_Builtin_stdnoreturn", true)
+ .Case("_Builtin_tgmath", true)
+ .Case("_Builtin_unwind", true)
+ .Default(false);
+}
+
void ModuleMap::resolveHeader(Module *Mod,
const Module::UnresolvedHeaderDirective &Header,
bool &NeedsFramework) {
@@ -297,7 +336,7 @@ bool ModuleMap::resolveAsBuiltinHeader(
llvm::sys::path::is_absolute(Header.FileName) ||
Mod->isPartOfFramework() || !Mod->IsSystem || Header.IsUmbrella ||
!BuiltinIncludeDir || BuiltinIncludeDir == Mod->Directory ||
- !isBuiltinHeader(Header.FileName))
+ !LangOpts.BuiltinHeadersInSystemModules || !isBuiltinHeaderName(Header.FileName))
return false;
// This is a system module with a top-level header. This header
@@ -309,8 +348,8 @@ bool ModuleMap::resolveAsBuiltinHeader(
if (!File)
return false;
+ Module::Header H = {Header.FileName, Header.FileName, *File};
auto Role = headerKindToRole(Header.Kind);
- Module::Header H = {Header.FileName, std::string(Path.str()), *File};
addHeader(Mod, H, Role);
return true;
}
@@ -373,32 +412,19 @@ static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
return Name;
}
-/// Determine whether the given file name is the name of a builtin
-/// header, supplied by Clang to replace, override, or augment existing system
-/// headers.
-bool ModuleMap::isBuiltinHeader(StringRef FileName) {
- return llvm::StringSwitch<bool>(FileName)
- .Case("float.h", true)
- .Case("iso646.h", true)
- .Case("limits.h", true)
- .Case("stdalign.h", true)
- .Case("stdarg.h", true)
- .Case("stdatomic.h", true)
- .Case("stdbool.h", true)
- .Case("stddef.h", true)
- .Case("stdint.h", true)
- .Case("tgmath.h", true)
- .Case("unwind.h", true)
- .Default(false);
+bool ModuleMap::isBuiltinHeader(FileEntryRef File) {
+ return File.getDir() == BuiltinIncludeDir && LangOpts.BuiltinHeadersInSystemModules &&
+ isBuiltinHeaderName(llvm::sys::path::filename(File.getName()));
}
-bool ModuleMap::isBuiltinHeader(const FileEntry *File) {
- return File->getDir() == BuiltinIncludeDir &&
- ModuleMap::isBuiltinHeader(llvm::sys::path::filename(File->getName()));
+bool ModuleMap::shouldImportRelativeToBuiltinIncludeDir(StringRef FileName,
+ Module *Module) const {
+ return LangOpts.BuiltinHeadersInSystemModules && BuiltinIncludeDir &&
+ Module->IsSystem && !Module->isPartOfFramework() &&
+ isBuiltinHeaderName(FileName);
}
-ModuleMap::HeadersMap::iterator
-ModuleMap::findKnownHeader(const FileEntry *File) {
+ModuleMap::HeadersMap::iterator ModuleMap::findKnownHeader(FileEntryRef File) {
resolveHeaderDirectives(File);
HeadersMap::iterator Known = Headers.find(File);
if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
@@ -622,7 +648,7 @@ ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(FileEntryRef File) {
UmbrellaModule = UmbrellaModule->Parent;
if (UmbrellaModule->InferSubmodules) {
- OptionalFileEntryRefDegradesToFileEntryPtr UmbrellaModuleMap =
+ OptionalFileEntryRef UmbrellaModuleMap =
getModuleMapFileForUniquing(UmbrellaModule);
// Infer submodules for each of the directories we found between
@@ -691,7 +717,7 @@ ModuleMap::findAllModulesForHeader(FileEntryRef File) {
}
ArrayRef<ModuleMap::KnownHeader>
-ModuleMap::findResolvedModulesForHeader(const FileEntry *File) const {
+ModuleMap::findResolvedModulesForHeader(FileEntryRef File) const {
// FIXME: Is this necessary?
resolveHeaderDirectives(File);
auto It = Headers.find(File);
@@ -855,17 +881,17 @@ Module *ModuleMap::createGlobalModuleFragmentForModuleUnit(SourceLocation Loc,
return Result;
}
-Module *ModuleMap::createImplicitGlobalModuleFragmentForModuleUnit(
- SourceLocation Loc, bool IsExported, Module *Parent) {
+Module *
+ModuleMap::createImplicitGlobalModuleFragmentForModuleUnit(SourceLocation Loc,
+ Module *Parent) {
assert(Parent && "We should only create an implicit global module fragment "
"in a module purview");
// Note: Here the `IsExplicit` parameter refers to the semantics in clang
// modules. All the non-explicit submodules in clang modules will be exported
// too. Here we simplify the implementation by using the concept.
- auto *Result = new Module(IsExported ? "<exported implicit global>"
- : "<implicit global>",
- Loc, Parent, /*IsFramework*/ false,
- /*IsExplicit*/ !IsExported, NumCreatedModules++);
+ auto *Result =
+ new Module("<implicit global>", Loc, Parent, /*IsFramework=*/false,
+ /*IsExplicit=*/false, NumCreatedModules++);
Result->Kind = Module::ImplicitGlobalModuleFragment;
return Result;
}
@@ -907,9 +933,9 @@ Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc,
// Mark the main source file as being within the newly-created module so that
// declarations and macros are properly visibility-restricted to it.
- auto *MainFile = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID());
+ auto MainFile = SourceMgr.getFileEntryRefForID(SourceMgr.getMainFileID());
assert(MainFile && "no input file for module interface");
- Headers[MainFile].push_back(KnownHeader(Result, PrivateHeader));
+ Headers[*MainFile].push_back(KnownHeader(Result, PrivateHeader));
return Result;
}
@@ -993,7 +1019,7 @@ Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
// If the framework has a parent path from which we're allowed to infer
// a framework module, do so.
- const FileEntry *ModuleMapFile = nullptr;
+ OptionalFileEntryRef ModuleMapFile;
if (!Parent) {
// Determine whether we're allowed to infer a module map.
bool canInfer = false;
@@ -1008,7 +1034,7 @@ Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
if (inferred == InferredDirectories.end()) {
// We haven't looked here before. Load a module map, if there is
// one.
- bool IsFrameworkDir = Parent.endswith(".framework");
+ bool IsFrameworkDir = Parent.ends_with(".framework");
if (OptionalFileEntryRef ModMapFile =
HeaderInfo.lookupModuleMapFile(*ParentDir, IsFrameworkDir)) {
parseModuleMapFile(*ModMapFile, Attrs.IsSystem, *ParentDir);
@@ -1041,9 +1067,7 @@ Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
if (!canInfer)
return nullptr;
} else {
- OptionalFileEntryRefDegradesToFileEntryPtr ModuleMapRef =
- getModuleMapFileForUniquing(Parent);
- ModuleMapFile = ModuleMapRef;
+ ModuleMapFile = getModuleMapFileForUniquing(Parent);
}
// Look for an umbrella header.
@@ -1101,7 +1125,7 @@ Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
Dir = FS.dir_begin(SubframeworksDirName, EC),
DirEnd;
Dir != DirEnd && !EC; Dir.increment(EC)) {
- if (!StringRef(Dir->path()).endswith(".framework"))
+ if (!StringRef(Dir->path()).ends_with(".framework"))
continue;
if (auto SubframeworkDir = FileMgr.getOptionalDirectoryRef(Dir->path())) {
@@ -1268,8 +1292,7 @@ void ModuleMap::addHeader(Module *Mod, Module::Header Header,
HeaderList.push_back(KH);
Mod->Headers[headerRoleToKind(Role)].push_back(Header);
- bool isCompilingModuleHeader =
- LangOpts.isCompilingModule() && Mod->getTopLevelModule() == SourceModule;
+ bool isCompilingModuleHeader = Mod->isForBuilding(LangOpts);
if (!Imported || isCompilingModuleHeader) {
// When we import HeaderFileInfo, the external source is expected to
// set the isModuleHeader flag itself.
@@ -1295,13 +1318,13 @@ OptionalFileEntryRef
ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
if (M->IsInferred) {
assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
- // FIXME: Update InferredModuleAllowedBy to use FileEntryRef.
- return InferredModuleAllowedBy.find(M)->second->getLastRef();
+ return InferredModuleAllowedBy.find(M)->second;
}
return getContainingModuleMapFile(M);
}
-void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
+void ModuleMap::setInferredModuleAllowedBy(Module *M,
+ OptionalFileEntryRef ModMap) {
assert(M->IsInferred && "module not inferred");
InferredModuleAllowedBy[M] = ModMap;
}
@@ -1314,7 +1337,7 @@ ModuleMap::canonicalizeModuleMapPath(SmallVectorImpl<char> &Path) {
// Modules/ not Versions/A/Modules.
if (llvm::sys::path::filename(Dir) == "Modules") {
StringRef Parent = llvm::sys::path::parent_path(Dir);
- if (Parent.endswith(".framework"))
+ if (Parent.ends_with(".framework"))
Dir = Parent;
}
@@ -1340,7 +1363,7 @@ ModuleMap::canonicalizeModuleMapPath(SmallVectorImpl<char> &Path) {
}
void ModuleMap::addAdditionalModuleMapFile(const Module *M,
- const FileEntry *ModuleMap) {
+ FileEntryRef ModuleMap) {
AdditionalModMaps[M].insert(ModuleMap);
}
@@ -1354,7 +1377,7 @@ LLVM_DUMP_METHOD void ModuleMap::dump() {
llvm::errs() << "Headers:";
for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
H != HEnd; ++H) {
- llvm::errs() << " \"" << H->first->getName() << "\" -> ";
+ llvm::errs() << " \"" << H->first.getName() << "\" -> ";
for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
E = H->second.end();
I != E; ++I) {
@@ -1380,16 +1403,17 @@ bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
}
bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
- auto Unresolved = std::move(Mod->UnresolvedDirectUses);
- Mod->UnresolvedDirectUses.clear();
+ auto *Top = Mod->getTopLevelModule();
+ auto Unresolved = std::move(Top->UnresolvedDirectUses);
+ Top->UnresolvedDirectUses.clear();
for (auto &UDU : Unresolved) {
- Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
+ Module *DirectUse = resolveModuleId(UDU, Top, Complain);
if (DirectUse)
- Mod->DirectUses.push_back(DirectUse);
+ Top->DirectUses.push_back(DirectUse);
else
- Mod->UnresolvedDirectUses.push_back(UDU);
+ Top->UnresolvedDirectUses.push_back(UDU);
}
- return !Mod->UnresolvedDirectUses.empty();
+ return !Top->UnresolvedDirectUses.empty();
}
bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
@@ -1491,7 +1515,7 @@ namespace clang {
ModuleMap &Map;
/// The current module map file.
- const FileEntry *ModuleMapFile;
+ FileEntryRef ModuleMapFile;
/// Source location of most recent parsed module declaration
SourceLocation CurrModuleDeclLoc;
@@ -1533,8 +1557,6 @@ namespace clang {
/// (or the end of the file).
void skipUntil(MMToken::TokenKind K);
- using ModuleId = SmallVector<std::pair<std::string, SourceLocation>, 2>;
-
bool parseModuleId(ModuleId &Id);
void parseModuleDecl();
void parseExternModuleDecl();
@@ -1563,7 +1585,7 @@ namespace clang {
public:
explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
const TargetInfo *Target, DiagnosticsEngine &Diags,
- ModuleMap &Map, const FileEntry *ModuleMapFile,
+ ModuleMap &Map, FileEntryRef ModuleMapFile,
DirectoryEntryRef Directory, bool IsSystem)
: L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
ModuleMapFile(ModuleMapFile), Directory(Directory),
@@ -1842,7 +1864,7 @@ void ModuleMapParser::diagnosePrivateModules(SourceLocation ExplicitLoc,
continue;
SmallString<128> FullName(ActiveModule->getFullModuleName());
- if (!FullName.startswith(M->Name) && !FullName.endswith("Private"))
+ if (!FullName.starts_with(M->Name) && !FullName.ends_with("Private"))
continue;
SmallString<128> FixedPrivModDecl;
SmallString<128> Canonical(M->Name);
@@ -2096,9 +2118,9 @@ void ModuleMapParser::parseModuleDecl() {
ActiveModule->NoUndeclaredIncludes = true;
ActiveModule->Directory = Directory;
- StringRef MapFileName(ModuleMapFile->getName());
- if (MapFileName.endswith("module.private.modulemap") ||
- MapFileName.endswith("module_private.map")) {
+ StringRef MapFileName(ModuleMapFile.getName());
+ if (MapFileName.ends_with("module.private.modulemap") ||
+ MapFileName.ends_with("module_private.map")) {
ActiveModule->ModuleMapIsPrivate = true;
}
@@ -2410,7 +2432,8 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
Header.Kind = Map.headerRoleToKind(Role);
// Check whether we already have an umbrella.
- if (Header.IsUmbrella && ActiveModule->Umbrella) {
+ if (Header.IsUmbrella &&
+ !std::holds_alternative<std::monostate>(ActiveModule->Umbrella)) {
Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
<< ActiveModule->getFullModuleName();
HadError = true;
@@ -2473,7 +2496,10 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
}
bool NeedsFramework = false;
- Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
+ // Don't add the top level headers to the builtin modules if the builtin headers
+ // belong to the system modules.
+ if (!Map.LangOpts.BuiltinHeadersInSystemModules || ActiveModule->isSubModule() || !isBuiltInModuleName(ActiveModule->Name))
+ Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
if (NeedsFramework)
Diags.Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)
@@ -2504,7 +2530,7 @@ void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
SourceLocation DirNameLoc = consumeToken();
// Check whether we already have an umbrella.
- if (ActiveModule->Umbrella) {
+ if (!std::holds_alternative<std::monostate>(ActiveModule->Umbrella)) {
Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
<< ActiveModule->getFullModuleName();
HadError = true;
@@ -3078,7 +3104,7 @@ bool ModuleMapParser::parseModuleMapFile() {
} while (true);
}
-bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
+bool ModuleMap::parseModuleMapFile(FileEntryRef File, bool IsSystem,
DirectoryEntryRef Dir, FileID ID,
unsigned *Offset,
SourceLocation ExternModuleLoc) {
@@ -3121,7 +3147,7 @@ bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
// Notify callbacks that we parsed it.
for (const auto &Cb : Callbacks)
- Cb->moduleMapFileRead(Start, *File, IsSystem);
+ Cb->moduleMapFileRead(Start, File, IsSystem);
return Result;
}