Ping
On Tue, May 21, 2013 at 2:41 PM, Reid Kleckner <[email protected]> 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(); >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
