diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-12-18 20:30:12 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2024-04-06 20:11:55 +0000 |
commit | 5f757f3ff9144b609b3c433dfd370cc6bdc191ad (patch) | |
tree | 1b4e980b866cd26a00af34c0a653eb640bd09caf /contrib/llvm-project/clang/lib/Lex/ModuleMap.cpp | |
parent | 3e1c8a35f741a5d114d0ba670b15191355711fe9 (diff) | |
parent | 312c0ed19cc5276a17bacf2120097bec4515b0f1 (diff) |
Diffstat (limited to 'contrib/llvm-project/clang/lib/Lex/ModuleMap.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Lex/ModuleMap.cpp | 162 |
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 ⤅ /// 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; } |