[PATCH] [ms-cxxabi] There are no key functions in the Microsoft C++ ABI
Reid Kleckner
rnk at google.com
Tue May 28 06:20:50 PDT 2013
Ping
On Tue, May 21, 2013 at 2:41 PM, Reid Kleckner <rnk at google.com> wrote:
> 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 --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130528/960765e6/attachment.html>
More information about the cfe-commits
mailing list