aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/Module.h4
-rw-r--r--clang/include/clang/Lex/ModuleMap.h13
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp6
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp6
-rw-r--r--clang/lib/Lex/ModuleMap.cpp20
-rw-r--r--clang/lib/Serialization/ASTReader.cpp2
-rw-r--r--clang/test/Modules/Inputs/exportas-link/OtherKit.framework/Headers/OtherKit.h6
-rw-r--r--clang/test/Modules/Inputs/exportas-link/OtherKit.framework/Modules/module.modulemap5
-rw-r--r--clang/test/Modules/Inputs/exportas-link/SomeKit.framework/Headers/SKWidget.h1
-rw-r--r--clang/test/Modules/Inputs/exportas-link/SomeKit.framework/Headers/SomeKit.h1
-rw-r--r--clang/test/Modules/Inputs/exportas-link/SomeKit.framework/Modules/module.modulemap6
-rw-r--r--clang/test/Modules/Inputs/exportas-link/SomeKit.framework/SomeKit.tbd1
-rw-r--r--clang/test/Modules/Inputs/exportas-link/SomeKitCore.framework/Headers/SKWidget.h4
-rw-r--r--clang/test/Modules/Inputs/exportas-link/SomeKitCore.framework/Headers/SomeKitCore.h1
-rw-r--r--clang/test/Modules/Inputs/exportas-link/SomeKitCore.framework/Modules/module.modulemap7
-rw-r--r--clang/test/Modules/Inputs/exportas-link/SomeKitCore.framework/SomeKitCore.tbd1
-rw-r--r--clang/test/Modules/use-exportas-for-link.m44
17 files changed, 128 insertions, 0 deletions
diff --git a/clang/include/clang/Basic/Module.h b/clang/include/clang/Basic/Module.h
index 3725fcb..d4e2dd4 100644
--- a/clang/include/clang/Basic/Module.h
+++ b/clang/include/clang/Basic/Module.h
@@ -331,6 +331,10 @@ public:
/// an entity from this module is used.
llvm::SmallVector<LinkLibrary, 2> LinkLibraries;
+ /// Autolinking uses the framework name for linking purposes
+ /// when this is false and the export_as name otherwise.
+ bool UseExportAsModuleLinkName = false;
+
/// \brief The set of "configuration macros", which are macros that
/// (intentionally) change how this module is built.
std::vector<std::string> ConfigMacros;
diff --git a/clang/include/clang/Lex/ModuleMap.h b/clang/include/clang/Lex/ModuleMap.h
index 8593fcd..a34f0d8 100644
--- a/clang/include/clang/Lex/ModuleMap.h
+++ b/clang/include/clang/Lex/ModuleMap.h
@@ -21,6 +21,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
@@ -104,7 +105,19 @@ class ModuleMap {
/// \brief The number of modules we have created in total.
unsigned NumCreatedModules = 0;
+ /// In case a module has a export_as entry, it might have a pending link
+ /// name to be determined if that module is imported.
+ llvm::StringMap<llvm::StringSet<>> PendingLinkAsModule;
+
public:
+ /// Use PendingLinkAsModule information to mark top level link names that
+ /// are going to be replaced by export_as aliases.
+ void resolveLinkAsDependencies(Module *Mod);
+
+ /// Make module to use export_as as the link dependency name if enough
+ /// information is available or add it to a pending list otherwise.
+ void addLinkAsDependency(Module *Mod);
+
/// \brief Flags describing the role of a module header.
enum ModuleHeaderRole {
/// \brief This header is normally included in the module.
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 687a6ca..42a8cd8 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1556,6 +1556,12 @@ static void addLinkOptionsPostorder(CodeGenModule &CGM, Module *Mod,
// Add linker options to link against the libraries/frameworks
// described by this module.
llvm::LLVMContext &Context = CGM.getLLVMContext();
+
+ // For modules that use export_as for linking, use that module
+ // name instead.
+ if (Mod->UseExportAsModuleLinkName)
+ return;
+
for (unsigned I = Mod->LinkLibraries.size(); I > 0; --I) {
// Link against a framework. Frameworks are currently Darwin only, so we
// don't to ask TargetCodeGenInfo for the spelling of the linker option.
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index b8f55b6..f57246b 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -1979,6 +1979,12 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
Module, ImportLoc);
}
+ // Resolve any remaining module using export_as for this one.
+ getPreprocessor()
+ .getHeaderSearchInfo()
+ .getModuleMap()
+ .resolveLinkAsDependencies(TopModule);
+
LastModuleImportLoc = ImportLoc;
LastModuleImportResult = ModuleLoadResult(Module);
return LastModuleImportResult;
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index a711e1d..e47abd5 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -54,6 +54,24 @@
using namespace clang;
+void ModuleMap::resolveLinkAsDependencies(Module *Mod) {
+ auto PendingLinkAs = PendingLinkAsModule.find(Mod->Name);
+ if (PendingLinkAs != PendingLinkAsModule.end()) {
+ for (auto &Name : PendingLinkAs->second) {
+ auto *M = findModule(Name.getKey());
+ if (M)
+ M->UseExportAsModuleLinkName = true;
+ }
+ }
+}
+
+void ModuleMap::addLinkAsDependency(Module *Mod) {
+ if (findModule(Mod->ExportAsModule))
+ Mod->UseExportAsModuleLinkName = true;
+ else
+ PendingLinkAsModule[Mod->ExportAsModule].insert(Mod->Name);
+}
+
Module::HeaderKind ModuleMap::headerRoleToKind(ModuleHeaderRole Role) {
switch ((int)Role) {
default: llvm_unreachable("unknown header role");
@@ -2412,6 +2430,8 @@ void ModuleMapParser::parseExportAsDecl() {
}
ActiveModule->ExportAsModule = Tok.getString();
+ Map.addLinkAsDependency(ActiveModule);
+
consumeToken();
}
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 9e83250..179f25e 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -5171,6 +5171,7 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
break;
case SUBMODULE_LINK_LIBRARY:
+ ModMap.resolveLinkAsDependencies(CurrentModule);
CurrentModule->LinkLibraries.push_back(
Module::LinkLibrary(Blob, Record[0]));
break;
@@ -5203,6 +5204,7 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
case SUBMODULE_EXPORT_AS:
CurrentModule->ExportAsModule = Blob.str();
+ ModMap.addLinkAsDependency(CurrentModule);
break;
}
}
diff --git a/clang/test/Modules/Inputs/exportas-link/OtherKit.framework/Headers/OtherKit.h b/clang/test/Modules/Inputs/exportas-link/OtherKit.framework/Headers/OtherKit.h
new file mode 100644
index 0000000..18f0bd5
--- /dev/null
+++ b/clang/test/Modules/Inputs/exportas-link/OtherKit.framework/Headers/OtherKit.h
@@ -0,0 +1,6 @@
+#import <SomeKitCore/SomeKitCore.h>
+
+#ifdef F
+#import <SomeKit/SomeKit.h>
+#endif
+
diff --git a/clang/test/Modules/Inputs/exportas-link/OtherKit.framework/Modules/module.modulemap b/clang/test/Modules/Inputs/exportas-link/OtherKit.framework/Modules/module.modulemap
new file mode 100644
index 0000000..1ce7351
--- /dev/null
+++ b/clang/test/Modules/Inputs/exportas-link/OtherKit.framework/Modules/module.modulemap
@@ -0,0 +1,5 @@
+
+framework module OtherKit {
+ header "OtherKit.h"
+ export *
+}
diff --git a/clang/test/Modules/Inputs/exportas-link/SomeKit.framework/Headers/SKWidget.h b/clang/test/Modules/Inputs/exportas-link/SomeKit.framework/Headers/SKWidget.h
new file mode 100644
index 0000000..dd99ff7
--- /dev/null
+++ b/clang/test/Modules/Inputs/exportas-link/SomeKit.framework/Headers/SKWidget.h
@@ -0,0 +1 @@
+#import <SomeKitCore/SKWidget.h>
diff --git a/clang/test/Modules/Inputs/exportas-link/SomeKit.framework/Headers/SomeKit.h b/clang/test/Modules/Inputs/exportas-link/SomeKit.framework/Headers/SomeKit.h
new file mode 100644
index 0000000..17a4cc8
--- /dev/null
+++ b/clang/test/Modules/Inputs/exportas-link/SomeKit.framework/Headers/SomeKit.h
@@ -0,0 +1 @@
+#import <SomeKit/SKWidget.h>
diff --git a/clang/test/Modules/Inputs/exportas-link/SomeKit.framework/Modules/module.modulemap b/clang/test/Modules/Inputs/exportas-link/SomeKit.framework/Modules/module.modulemap
new file mode 100644
index 0000000..ae4b276
--- /dev/null
+++ b/clang/test/Modules/Inputs/exportas-link/SomeKit.framework/Modules/module.modulemap
@@ -0,0 +1,6 @@
+framework module SomeKit {
+ umbrella header "SomeKit.h"
+ module * {
+ export *
+ }
+}
diff --git a/clang/test/Modules/Inputs/exportas-link/SomeKit.framework/SomeKit.tbd b/clang/test/Modules/Inputs/exportas-link/SomeKit.framework/SomeKit.tbd
new file mode 100644
index 0000000..ab95795
--- /dev/null
+++ b/clang/test/Modules/Inputs/exportas-link/SomeKit.framework/SomeKit.tbd
@@ -0,0 +1 @@
+dummy tbd file
diff --git a/clang/test/Modules/Inputs/exportas-link/SomeKitCore.framework/Headers/SKWidget.h b/clang/test/Modules/Inputs/exportas-link/SomeKitCore.framework/Headers/SKWidget.h
new file mode 100644
index 0000000..1fb010c
--- /dev/null
+++ b/clang/test/Modules/Inputs/exportas-link/SomeKitCore.framework/Headers/SKWidget.h
@@ -0,0 +1,4 @@
+@interface SKWidget
+- (void)someObjCMethod;
+@end
+
diff --git a/clang/test/Modules/Inputs/exportas-link/SomeKitCore.framework/Headers/SomeKitCore.h b/clang/test/Modules/Inputs/exportas-link/SomeKitCore.framework/Headers/SomeKitCore.h
new file mode 100644
index 0000000..dd99ff7
--- /dev/null
+++ b/clang/test/Modules/Inputs/exportas-link/SomeKitCore.framework/Headers/SomeKitCore.h
@@ -0,0 +1 @@
+#import <SomeKitCore/SKWidget.h>
diff --git a/clang/test/Modules/Inputs/exportas-link/SomeKitCore.framework/Modules/module.modulemap b/clang/test/Modules/Inputs/exportas-link/SomeKitCore.framework/Modules/module.modulemap
new file mode 100644
index 0000000..30f9770
--- /dev/null
+++ b/clang/test/Modules/Inputs/exportas-link/SomeKitCore.framework/Modules/module.modulemap
@@ -0,0 +1,7 @@
+framework module SomeKitCore {
+ umbrella header "SomeKitCore.h"
+ export_as SomeKit
+ module * {
+ export *
+ }
+}
diff --git a/clang/test/Modules/Inputs/exportas-link/SomeKitCore.framework/SomeKitCore.tbd b/clang/test/Modules/Inputs/exportas-link/SomeKitCore.framework/SomeKitCore.tbd
new file mode 100644
index 0000000..ab95795
--- /dev/null
+++ b/clang/test/Modules/Inputs/exportas-link/SomeKitCore.framework/SomeKitCore.tbd
@@ -0,0 +1 @@
+dummy tbd file
diff --git a/clang/test/Modules/use-exportas-for-link.m b/clang/test/Modules/use-exportas-for-link.m
new file mode 100644
index 0000000..69773e6
--- /dev/null
+++ b/clang/test/Modules/use-exportas-for-link.m
@@ -0,0 +1,44 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t -DA -fmodules -fimplicit-module-maps -F %S/Inputs/exportas-link %s | FileCheck --check-prefix=CHECK_A %s
+// CHECK_A: !llvm.linker.options = !{![[MODULE:[0-9]+]]}
+// CHECK_A: ![[MODULE]] = !{!"-framework", !"SomeKit"}
+#ifdef A
+@import SomeKitCore;
+@import SomeKit;
+#endif
+
+// RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t -DB -fmodules -fimplicit-module-maps -F %S/Inputs/exportas-link %s | FileCheck --check-prefix=CHECK_B %s
+// CHECK_B: !llvm.linker.options = !{![[MODULE:[0-9]+]]}
+// CHECK_B: ![[MODULE]] = !{!"-framework", !"SomeKit"}
+#ifdef B
+@import SomeKit;
+@import SomeKitCore;
+#endif
+
+// RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t -DC -fmodules -fimplicit-module-maps -F %S/Inputs/exportas-link %s | FileCheck --check-prefix=CHECK_C %s
+// CHECK_C: !llvm.linker.options = !{![[MODULE:[0-9]+]]}
+// CHECK_C: ![[MODULE]] = !{!"-framework", !"SomeKitCore"}
+#ifdef C
+@import SomeKitCore;
+#endif
+
+// RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t -DD -fmodules -fimplicit-module-maps -F %S/Inputs/exportas-link %s | FileCheck --check-prefix=CHECK_D %s
+// CHECK_D: !llvm.linker.options = !{![[MODULE:[0-9]+]]}
+// CHECK_D: ![[MODULE]] = !{!"-framework", !"SomeKit"}
+#ifdef D
+@import SomeKit;
+#endif
+
+// 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
+// CHECK_E: !llvm.linker.options = !{![[MODULE:[0-9]+]]}
+// CHECK_E: ![[MODULE]] = !{!"-framework", !"SomeKitCore"}
+#ifdef E
+@import OtherKit;
+#endif
+
+// 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
+// CHECK_F: !llvm.linker.options = !{![[MODULE:[0-9]+]]}
+// CHECK_F: ![[MODULE]] = !{!"-framework", !"SomeKit"}
+#ifdef F
+@import OtherKit;
+#endif