aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-09-19 18:05:26 +0000
committerJohn McCall <rjmccall@apple.com>2011-09-19 18:05:26 +0000
commit5584d91c938384b57563edbca5c2d4f1c66ff02a (patch)
tree37aa7c112a9ed723dc10ccfdf9da353a65c58e6b
parent84e0ccff7a6e51d7b81fd58686b493a4880dd44d (diff)
In apple-kext mode, use external linkage for explicit template instantiations
instead of internal linkage. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@140030 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CodeGenModule.cpp9
-rw-r--r--test/CodeGenCXX/apple-kext-linkage.C12
2 files changed, 17 insertions, 4 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 19c3b064d6..917f4b7545 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -400,7 +400,12 @@ CodeGenModule::getFunctionLinkage(const FunctionDecl *D) {
// definition somewhere else, so we can use available_externally linkage.
if (Linkage == GVA_C99Inline)
return llvm::Function::AvailableExternallyLinkage;
-
+
+ // Note that Apple's kernel linker doesn't support symbol
+ // coalescing, so we need to avoid linkonce and weak linkages there.
+ // Normally, this means we just map to internal, but for explicit
+ // instantiations we'll map to external.
+
// In C++, the compiler has to emit a definition in every translation unit
// that references the function. We should use linkonce_odr because
// a) if all references in this translation unit are optimized away, we
@@ -419,7 +424,7 @@ CodeGenModule::getFunctionLinkage(const FunctionDecl *D) {
if (Linkage == GVA_ExplicitTemplateInstantiation)
return !Context.getLangOptions().AppleKext
? llvm::Function::WeakODRLinkage
- : llvm::Function::InternalLinkage;
+ : llvm::Function::ExternalLinkage;
// Otherwise, we have strong external linkage.
assert(Linkage == GVA_StrongExternal);
diff --git a/test/CodeGenCXX/apple-kext-linkage.C b/test/CodeGenCXX/apple-kext-linkage.C
index 9df1151176..59d228e230 100644
--- a/test/CodeGenCXX/apple-kext-linkage.C
+++ b/test/CodeGenCXX/apple-kext-linkage.C
@@ -13,13 +13,21 @@ void foo() {
Derived d1; // ok
}
+// CHECK: define internal i32 @_Z1fj(
inline unsigned f(unsigned n) { return n == 0 ? 0 : n + f(n-1); }
unsigned g(unsigned n) { return f(n); }
+// rdar://problem/10133200: give explicit instantiations external linkage in kernel mode
+// CHECK: define void @_Z3barIiEvv()
+template <typename T> void bar() {}
+template void bar<int>();
+// CHECK: define internal i32 @_Z5identIiET_S0_(
template <typename X> X ident(X x) { return x; }
+
int foo(int n) { return ident(n); }
-// CHECK-NOT: define linkonce_odr
-// CHECK 5 : define internal
+// CHECK: define internal void @_ZN7DerivedD1Ev(
+// CHECK: define internal void @_ZN7DerivedD0Ev(
+// CHECK: define internal void @_ZN7DeriveddlEPv(