[PATCH] [ms-cxxabi] There are no key functions in the Microsoft C++ ABI
Reid Kleckner
rnk at google.com
Tue May 21 11:41:38 PDT 2013
Hi pcc,
MSVC's class data is always comdat, so clang's should always be
linkonce_odr in LLVM IR.
http://llvm-reviews.chandlerc.com/D838
Files:
include/clang/Basic/TargetCXXABI.h
lib/AST/RecordLayoutBuilder.cpp
test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp
Index: include/clang/Basic/TargetCXXABI.h
===================================================================
--- include/clang/Basic/TargetCXXABI.h
+++ include/clang/Basic/TargetCXXABI.h
@@ -152,6 +152,13 @@
return isItaniumFamily();
}
+ /// \brief Does this ABI use key functions? If so, class data such as the
+ /// vtable is emitted with strong linkage by the TU containing the key
+ /// function.
+ bool hasKeyFunctions() const {
+ return isItaniumFamily();
+ }
+
/// \brief Can an out-of-line inline function serve as a key function?
///
/// This flag is only useful in ABIs where type data (for example,
Index: lib/AST/RecordLayoutBuilder.cpp
===================================================================
--- lib/AST/RecordLayoutBuilder.cpp
+++ lib/AST/RecordLayoutBuilder.cpp
@@ -2546,6 +2546,9 @@
}
const CXXMethodDecl *ASTContext::getCurrentKeyFunction(const CXXRecordDecl *RD) {
+ if (!getTargetInfo().getCXXABI().hasKeyFunctions())
+ return 0;
+
assert(RD->getDefinition() && "Cannot get key function for forward decl!");
RD = cast<CXXRecordDecl>(RD->getDefinition());
Index: test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp
===================================================================
--- test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp
+++ test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp
@@ -8,41 +8,49 @@
// RUN: FileCheck --check-prefix=CHECK-F %s < %t
// RUN: FileCheck --check-prefix=CHECK-G %s < %t
+// We call the ctors from a static initializer, so all vtables are used. For
+// some reason when the vtables used by initializers, they come out in reverse
+// order, so we have to pull them out.
+// EMITS-VTABLE-NOT: @"\01??_7G@@6B@"
+// EMITS-VTABLE: @"\01??_7F@@6B@" = linkonce_odr unnamed_addr constant [5 x i8*]
+// EMITS-VTABLE-NOT: @"\01??_7E@@6B@"
+// EMITS-VTABLE: @"\01??_7D@@6B@" = linkonce_odr unnamed_addr constant [2 x i8*]
+// EMITS-VTABLE-NOT: @"\01??_7C@@6B@"
+// EMITS-VTABLE: @"\01??_7B@@6B@" = linkonce_odr unnamed_addr constant [5 x i8*]
+// EMITS-VTABLE: @"\01??_7A@@6B@" = linkonce_odr unnamed_addr constant [3 x i8*]
+
struct A {
// CHECK-A: Vtable for 'A' (3 entries)
// CHECK-A-NEXT: 0 | void A::f()
// CHECK-A-NEXT: 1 | void A::g()
// CHECK-A-NEXT: 2 | void A::h()
- // EMITS-VTABLE: @"\01??_7A@@6B@" = unnamed_addr constant [3 x i8*]
virtual void f();
virtual void g();
virtual void h();
int ia;
};
-void A::f() {}
+A a;
struct B : A {
// CHECK-B: Vtable for 'B' (5 entries)
// CHECK-B-NEXT: 0 | void B::f()
// CHECK-B-NEXT: 1 | void A::g()
// CHECK-B-NEXT: 2 | void A::h()
// CHECK-B-NEXT: 3 | void B::i()
// CHECK-B-NEXT: 4 | void B::j()
- // EMITS-VTABLE: @"\01??_7B@@6B@" = unnamed_addr constant [5 x i8*]
virtual void f(); // overrides A::f()
virtual void i();
virtual void j();
};
-void B::f() {}
+B b;
struct C {
// CHECK-C: Vtable for 'C' (2 entries)
// CHECK-C-NEXT: 0 | C::~C() [scalar deleting]
// CHECK-C-NEXT: 1 | void C::f()
// CHECK-C: VTable indices for 'C' (2 entries).
// CHECK-C-NEXT: 0 | C::~C() [scalar deleting]
// CHECK-C-NEXT: 1 | void C::f()
- // Never used, so doesn't emit a vtable.
virtual ~C();
virtual void f();
@@ -53,12 +61,11 @@
// CHECK-D: Vtable for 'D' (2 entries)
// CHECK-D-NEXT: 0 | void D::f()
// CHECK-D-NEXT: 1 | D::~D() [scalar deleting]
- // EMITS-VTABLE: @"\01??_7D@@6B@" = unnamed_addr constant [2 x i8*]
virtual void f();
virtual ~D();
};
-void D::f() {}
+D d;
struct E : A {
// CHECK-E: Vtable for 'E' (5 entries)
@@ -71,7 +78,8 @@
// CHECK-E-NEXT: 3 | E::~E() [scalar deleting]
// CHECK-E-NEXT: 4 | void E::i()
- // Never used, so doesn't emit a vtable.
+ // ~E would be the key method, but it isn't used, and MS ABI has no key
+ // methods.
virtual ~E();
virtual void i();
};
@@ -87,11 +95,10 @@
// CHECK-F: VTable indices for 'F' (2 entries).
// CHECK-F-NEXT: 3 | void F::i()
// CHECK-F-NEXT: 4 | F::~F() [scalar deleting]
- // EMITS-VTABLE: @"\01??_7F@@6B@" = unnamed_addr constant [5 x i8*]
virtual void i();
virtual ~F();
};
-void F::i() {}
+F f;
struct G : E {
// CHECK-G: Vtable for 'G' (6 entries)
@@ -105,7 +112,6 @@
// CHECK-G-NEXT: 0 | void G::f()
// CHECK-G-NEXT: 3 | G::~G() [scalar deleting]
// CHECK-G-NEXT: 5 | void G::j()
- // Never used, so doesn't emit a vtable.
virtual void f(); // overrides A::f()
virtual ~G();
virtual void j();
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D838.1.patch
Type: text/x-patch
Size: 4525 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130521/77012c3a/attachment.bin>
More information about the cfe-commits
mailing list