[cfe-commits] r88828 - in /cfe/trunk: lib/CodeGen/CGRtti.cpp test/CodeGenCXX/rtti.cpp
Mike Stump
mrs at apple.com
Sat Nov 14 19:28:11 PST 2009
Author: mrs
Date: Sat Nov 14 21:28:10 2009
New Revision: 88828
URL: http://llvm.org/viewvc/llvm-project?rev=88828&view=rev
Log:
Finish off support for typeinfo generation for classes.
Added:
cfe/trunk/test/CodeGenCXX/rtti.cpp
Modified:
cfe/trunk/lib/CodeGen/CGRtti.cpp
Modified: cfe/trunk/lib/CodeGen/CGRtti.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGRtti.cpp?rev=88828&r1=88827&r2=88828&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGRtti.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGRtti.cpp Sat Nov 14 21:28:10 2009
@@ -20,6 +20,8 @@
CodeGenModule &CGM; // Per-module state.
llvm::LLVMContext &VMContext;
const llvm::Type *Int8PtrTy;
+ llvm::SmallSet<const CXXRecordDecl *, 16> SeenVBase;
+ llvm::SmallSet<const CXXRecordDecl *, 32> SeenBase;
public:
RttiBuilder(CodeGenModule &cgm)
: CGM(cgm), VMContext(cgm.getModule().getContext()),
@@ -98,6 +100,47 @@
return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
}
+ /// CalculateFlags - Calculate the flags for the __vmi_class_type_info
+ /// datastructure. 1 for non-diamond repeated inheritance, 2 for a dimond
+ /// shaped class.
+ int CalculateFlags(const CXXRecordDecl*RD) {
+ int flags = 0;
+ if (SeenBase.count(RD))
+ flags |= 1;
+ else
+ SeenBase.insert(RD);
+ for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
+ e = RD->bases_end(); i != e; ++i) {
+ const CXXRecordDecl *Base =
+ cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+ if (i->isVirtual()) {
+ if (SeenVBase.count(Base))
+ flags |= 2;
+ else
+ SeenVBase.insert(Base);
+ }
+ flags |= CalculateFlags(Base);
+ }
+ return flags;
+ }
+
+ bool SimpleInheritance(const CXXRecordDecl *RD) {
+ if (RD->getNumBases() != 1)
+ return false;
+ CXXRecordDecl::base_class_const_iterator i = RD->bases_begin();
+ if (i->isVirtual())
+ return false;
+ if (i->getAccessSpecifier() != AS_public)
+ return false;
+
+ const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
+ const CXXRecordDecl *Base =
+ cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+ if (Layout.getBaseClassOffset(Base) != 0)
+ return false;
+ return true;
+ }
+
llvm::Constant *Buildclass_type_info(const CXXRecordDecl *RD) {
const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
llvm::Constant *C;
@@ -119,31 +162,35 @@
linktype = llvm::GlobalValue::LinkOnceODRLinkage;
std::vector<llvm::Constant *> info;
+ bool simple = false;
if (RD->getNumBases() == 0)
C = BuildVtableRef("_ZTVN10__cxxabiv117__class_type_infoE");
- // FIXME: Add si_class_type_info optimization
- else
+ else if (SimpleInheritance(RD)) {
+ simple = true;
+ C = BuildVtableRef("_ZTVN10__cxxabiv120__si_class_type_infoE");
+ } else
C = BuildVtableRef("_ZTVN10__cxxabiv121__vmi_class_type_infoE");
info.push_back(C);
info.push_back(BuildName(RD));
// If we have no bases, there are no more fields.
if (RD->getNumBases()) {
-
- // FIXME: Calculate is_diamond and non-diamond repeated inheritance, 3 is
- // conservative.
- info.push_back(BuildFlags(3));
- info.push_back(BuildBaseCount(RD->getNumBases()));
+ if (!simple) {
+ info.push_back(BuildFlags(CalculateFlags(RD)));
+ info.push_back(BuildBaseCount(RD->getNumBases()));
+ }
const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
e = RD->bases_end(); i != e; ++i) {
const CXXRecordDecl *Base =
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
- info.push_back(CGM.GenerateRtti(Base));
+ info.push_back(CGM.GenerateRttiRef(Base));
+ if (simple)
+ break;
int64_t offset;
if (!i->isVirtual())
- offset = Layout.getBaseClassOffset(Base);
+ offset = Layout.getBaseClassOffset(Base)/8;
else
offset = CGM.getVtableInfo().getVirtualBaseOffsetIndex(RD, Base);
offset <<= 8;
Added: cfe/trunk/test/CodeGenCXX/rtti.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/rtti.cpp?rev=88828&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/rtti.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/rtti.cpp Sat Nov 14 21:28:10 2009
@@ -0,0 +1,89 @@
+// RUN: clang-cc -triple x86_64-apple-darwin -std=c++0x -O0 -S %s -o %t.s
+// RUN: FileCheck --input-file=%t.s %s
+
+class test1_B1 {
+ virtual void foo() { }
+};
+class test1_B2 : public test1_B1 {
+ virtual void foo() { }
+};
+class test1_B3 : public test1_B2, public test1_B1 {
+ virtual void foo() { }
+};
+class test1_B4 : virtual public test1_B3 {
+ virtual void foo() { }
+};
+class test1_B5 : virtual test1_B3, test1_B4 {
+ virtual void foo() { }
+};
+class test1_B6 {
+ virtual void foo() { }
+};
+class test1_B7 : public test1_B6, public test1_B5 {
+ virtual void foo() { }
+};
+class test1_D : public test1_B7 {
+ virtual void foo() { }
+} d1;
+
+// CHECK:__ZTI7test1_D:
+// CHECK-NEXT: .quad (__ZTVN10__cxxabiv120__si_class_type_infoE) + 16
+// CHECK-NEXT: .quad __ZTS7test1_D
+// CHECK-NEXT: .quad __ZTI8test1_B7
+
+// CHECK:__ZTI8test1_B7:
+// CHECK-NEXT: .quad (__ZTVN10__cxxabiv121__vmi_class_type_infoE) + 16
+// CHECK-NEXT: .quad __ZTS8test1_B7
+// CHECK-NEXT: .long 3
+// CHECK-NEXT: .long 2
+// CHECK-NEXT: .quad __ZTI8test1_B6
+// CHECK-NEXT: .quad 2
+// CHECK-NEXT: .quad __ZTI8test1_B5
+// CHECK-NEXT: .quad 2050
+
+// CHECK:__ZTI8test1_B5:
+// CHECK-NEXT: .quad (__ZTVN10__cxxabiv121__vmi_class_type_infoE) + 16
+// CHECK-NEXT: .quad __ZTS8test1_B5
+// CHECK-NEXT: .long 3
+// CHECK-NEXT: .long 2
+// CHECK-NEXT: .quad __ZTI8test1_B3
+// CHECK-NEXT: .quad 18446744073709545473
+// CHECK-NEXT: .quad __ZTI8test1_B4
+// CHECK-NEXT: .space 8
+
+// CHECK:__ZTI8test1_B4:
+// CHECK-NEXT: .quad (__ZTVN10__cxxabiv121__vmi_class_type_infoE) + 16
+// CHECK-NEXT: .quad __ZTS8test1_B4
+// CHECK-NEXT: .long 1
+// CHECK-NEXT: .long 1
+// CHECK-NEXT: .quad __ZTI8test1_B3
+// CHECK-NEXT: .quad 18446744073709545475
+
+// CHECK:__ZTI8test1_B6:
+// CHECK-NEXT: .quad (__ZTVN10__cxxabiv117__class_type_infoE) + 16
+// CHECK-NEXT: .quad __ZTS8test1_B6
+
+// CHECK:__ZTI8test1_B3:
+// CHECK-NEXT: .quad (__ZTVN10__cxxabiv121__vmi_class_type_infoE) + 16
+// CHECK-NEXT: .quad __ZTS8test1_B3
+// CHECK-NEXT: .long 1
+// CHECK-NEXT: .long 2
+// CHECK-NEXT: .quad __ZTI8test1_B2
+// CHECK-NEXT: .quad 2
+// CHECK-NEXT: .quad __ZTI8test1_B1
+// CHECK-NEXT: .quad 2050
+
+// CHECK:__ZTS8test1_B1:
+// CHECK-NEXT: .asciz "8test1_B1"
+
+// CHECK:__ZTI8test1_B1:
+// CHECK-NEXT: .quad (__ZTVN10__cxxabiv117__class_type_infoE) + 16
+// CHECK-NEXT:. quad __ZTS8test1_B1
+
+// CHECK:__ZTS8test1_B2:
+// CHECK-NEXT: .asciz "8test1_B2"
+
+// CHECK:__ZTI8test1_B2:
+// CHECK-NEXT: .quad (__ZTVN10__cxxabiv120__si_class_type_infoE) + 16
+// CHECK-NEXT: .quad __ZTS8test1_B2
+// CHECK-NEXT: .quad __ZTI8test1_B1
More information about the cfe-commits
mailing list