Skip to content

Commit 29e2a4e

Browse files
committed
[clang] Unconditionally add autolink hints for frameworks.
Clang infers framework autolink hints when parsing a modulemap. In order to do so, it checks if the module is a framework and if there is a framework binary or TBD file in the SDK. Only when Clang finds the filei, then the autolink hint is added to the module metadata. During a project build many clang processes perform this check, which causes many stat calls - even for modules/frameworks that are not even used. The linker is already resilient to non-existing framework links that come from the autolink metadata, so there is no need for Clang to do this check. Instead the autolink hints are now added unconditionally and the linker only needs to do the check once. This reduces the overall number of stat calls. This fixes rdar://106578342. Differential Revision: https://reviews.llvm.org/D146255
1 parent f341d7a commit 29e2a4e

File tree

2 files changed

+13
-27
lines changed

2 files changed

+13
-27
lines changed

clang/lib/Lex/ModuleMap.cpp

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -930,27 +930,13 @@ Module *ModuleMap::createHeaderUnit(SourceLocation Loc, StringRef Name,
930930

931931
/// For a framework module, infer the framework against which we
932932
/// should link.
933-
static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
934-
FileManager &FileMgr) {
933+
static void inferFrameworkLink(Module *Mod) {
935934
assert(Mod->IsFramework && "Can only infer linking for framework modules");
936935
assert(!Mod->isSubFramework() &&
937936
"Can only infer linking for top-level frameworks");
938937

939-
SmallString<128> LibName;
940-
LibName += FrameworkDir->getName();
941-
llvm::sys::path::append(LibName, Mod->Name);
942-
943-
// The library name of a framework has more than one possible extension since
944-
// the introduction of the text-based dynamic library format. We need to check
945-
// for both before we give up.
946-
for (const char *extension : {"", ".tbd"}) {
947-
llvm::sys::path::replace_extension(LibName, extension);
948-
if (FileMgr.getFile(LibName)) {
949-
Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
950-
/*IsFramework=*/true));
951-
return;
952-
}
953-
}
938+
Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
939+
/*IsFramework=*/true));
954940
}
955941

956942
Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
@@ -1129,9 +1115,8 @@ Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
11291115

11301116
// If the module is a top-level framework, automatically link against the
11311117
// framework.
1132-
if (!Result->isSubFramework()) {
1133-
inferFrameworkLink(Result, FrameworkDir, FileMgr);
1134-
}
1118+
if (!Result->isSubFramework())
1119+
inferFrameworkLink(Result);
11351120

11361121
return Result;
11371122
}
@@ -2185,9 +2170,8 @@ void ModuleMapParser::parseModuleDecl() {
21852170
// If the active module is a top-level framework, and there are no link
21862171
// libraries, automatically link against the framework.
21872172
if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
2188-
ActiveModule->LinkLibraries.empty()) {
2189-
inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
2190-
}
2173+
ActiveModule->LinkLibraries.empty())
2174+
inferFrameworkLink(ActiveModule);
21912175

21922176
// If the module meets all requirements but is still unavailable, mark the
21932177
// whole tree as unavailable to prevent it from building.

clang/test/Modules/use-exportas-for-link.m

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,17 @@
3131
#endif
3232

3333
// RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t -DE -fmodules -fimplicit-module-maps -F %S/Inputs/exportas-link %s | FileCheck --check-prefix=CHECK_E %s
34-
// CHECK_E: !llvm.linker.options = !{![[MODULE:[0-9]+]]}
35-
// CHECK_E: ![[MODULE]] = !{!"-framework", !"SomeKitCore"}
34+
// CHECK_E: !llvm.linker.options = !{![[MODULE1:[0-9]+]], ![[MODULE2:[0-9]+]]}
35+
// CHECK_E: ![[MODULE1]] = !{!"-framework", !"OtherKit"}
36+
// CHECK_E: ![[MODULE2]] = !{!"-framework", !"SomeKitCore"}
3637
#ifdef E
3738
@import OtherKit;
3839
#endif
3940

4041
// RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t -DF -fmodules -fimplicit-module-maps -F %S/Inputs/exportas-link %s | FileCheck --check-prefix=CHECK_F %s
41-
// CHECK_F: !llvm.linker.options = !{![[MODULE:[0-9]+]]}
42-
// CHECK_F: ![[MODULE]] = !{!"-framework", !"SomeKit"}
42+
// CHECK_F: !llvm.linker.options = !{![[MODULE1:[0-9]+]], ![[MODULE2:[0-9]+]]}
43+
// CHECK_F: ![[MODULE1]] = !{!"-framework", !"OtherKit"}
44+
// CHECK_F: ![[MODULE2]] = !{!"-framework", !"SomeKit"}
4345
#ifdef F
4446
@import OtherKit;
4547
#endif

0 commit comments

Comments
 (0)