mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-11 02:16:50 +00:00
Use export_as for autolinking frameworks
framework module SomeKitCore { ... export_as SomeKit } Given the module above, while generting autolink information during codegen, clang should to emit '-framework SomeKitCore' only if SomeKit was not imported in the relevant TU, otherwise it should use '-framework SomeKit' instead. rdar://problem/38269782 llvm-svn: 330152
This commit is contained in:
parent
1c3bd2ff0c
commit
a3b5f71eaa
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,6 @@
|
||||
#import <SomeKitCore/SomeKitCore.h>
|
||||
|
||||
#ifdef F
|
||||
#import <SomeKit/SomeKit.h>
|
||||
#endif
|
||||
|
@ -0,0 +1,5 @@
|
||||
|
||||
framework module OtherKit {
|
||||
header "OtherKit.h"
|
||||
export *
|
||||
}
|
@ -0,0 +1 @@
|
||||
#import <SomeKitCore/SKWidget.h>
|
@ -0,0 +1 @@
|
||||
#import <SomeKit/SKWidget.h>
|
@ -0,0 +1,6 @@
|
||||
framework module SomeKit {
|
||||
umbrella header "SomeKit.h"
|
||||
module * {
|
||||
export *
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
dummy tbd file
|
@ -0,0 +1,4 @@
|
||||
@interface SKWidget
|
||||
- (void)someObjCMethod;
|
||||
@end
|
||||
|
@ -0,0 +1 @@
|
||||
#import <SomeKitCore/SKWidget.h>
|
@ -0,0 +1,7 @@
|
||||
framework module SomeKitCore {
|
||||
umbrella header "SomeKitCore.h"
|
||||
export_as SomeKit
|
||||
module * {
|
||||
export *
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
dummy tbd file
|
44
clang/test/Modules/use-exportas-for-link.m
Normal file
44
clang/test/Modules/use-exportas-for-link.m
Normal file
@ -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
|
Loading…
x
Reference in New Issue
Block a user