summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2011-01-30 20:45:54 +0000
committerAnders Carlsson <andersca@mac.com>2011-01-30 20:45:54 +0000
commita03f3a85cb8d7ed86943c12030088fddc05ba1b3 (patch)
treef05b7b39bc94045d4e2dd8f8ac46b4cc732b7b9c /clang/test
parent9af7afcb7f834ff7a4b78a284051c53db984007c (diff)
downloadbcm5719-llvm-a03f3a85cb8d7ed86943c12030088fddc05ba1b3.tar.gz
bcm5719-llvm-a03f3a85cb8d7ed86943c12030088fddc05ba1b3.zip
When building with optimizations, emit vtables where the key is not in the
current translation unit as available_externally. This helps devirtualize the second example in PR3100, comment 18: struct S { S() {}; virtual void xyzzy(); }; inline void foo(S *s) { s->xyzzy(); } void bar() { S s; foo(&s); } This involved four major changes: 1. In DefineUsedVTables, always mark virtual member functions as referenced for non-template classes and class template specializations. 2. In CodeGenVTables::ShouldEmitVTableInThisTU return true if optimizations are enabled, even if the key function is not implemented in this translation unit. We don't ever do this for code compiled with -fapple-kext, because we don't ever want to devirtualize virtual member function calls in that case. 3. Give the correct linkage for vtables where the key function is not defined. 4. Update the linkage for RTTI structures when necessary. llvm-svn: 124565
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/CodeGenCXX/vtable-available-externally.cpp55
1 files changed, 55 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/vtable-available-externally.cpp b/clang/test/CodeGenCXX/vtable-available-externally.cpp
new file mode 100644
index 00000000000..b6e48c8f8c9
--- /dev/null
+++ b/clang/test/CodeGenCXX/vtable-available-externally.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -O3 -o %t
+// RUN: FileCheck --check-prefix=CHECK-TEST1 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-TEST2 %s < %t
+
+#include <typeinfo>
+
+// Test1::A's key function (f) is not defined in this translation unit, but in
+// order to devirtualize calls, we emit the class related data with
+// available_externally linkage.
+
+// CHECK-TEST1: @_ZTVN5Test11AE = available_externally
+// CHECK-TEST1: @_ZTSN5Test11AE = available_externally
+// CHECK-TEST1: @_ZTIN5Test11AE = available_externally
+namespace Test1 {
+
+struct A {
+ A();
+ virtual void f();
+ virtual ~A() { }
+};
+
+A::A() { }
+
+void f(A* a) {
+ a->f();
+};
+
+// CHECK: define void @_ZN5Test11gEv
+// CHECK: call void @_ZN5Test11A1fEv
+void g() {
+ A a;
+ f(&a);
+}
+
+}
+
+// Test2::A's key function (f) is defined in this translation unit, but when
+// we're doing codegen for the typeid(A) call, we don't know that yet.
+// This tests mainly that the typeinfo and typename constants have their linkage
+// updated correctly.
+
+// CHECK-TEST2: @_ZTSN5Test21AE = constant
+// CHECK-TEST2: @_ZTIN5Test21AE = unnamed_addr constant
+// CHECK-TEST2: @_ZTVN5Test21AE = unnamed_addr constant
+namespace Test2 {
+ struct A {
+ virtual void f();
+ };
+
+ const std::type_info &g() {
+ return typeid(A);
+ };
+
+ void A::f() { }
+}
OpenPOWER on IntegriCloud