diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.cpp | 31 | ||||
-rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.h | 6 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGCXX.cpp | 34 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 4 |
4 files changed, 49 insertions, 26 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index bd994143087..7988106de59 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -26,14 +26,15 @@ ASTRecordLayoutBuilder::ASTRecordLayoutBuilder(ASTContext &Ctx) NextOffset(0), IsUnion(false), NonVirtualSize(0), NonVirtualAlignment(8) {} /// LayoutVtable - Lay out the vtable and set PrimaryBase. -void ASTRecordLayoutBuilder::LayoutVtable(const CXXRecordDecl *RD) { +void ASTRecordLayoutBuilder::LayoutVtable(const CXXRecordDecl *RD, + llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary) { if (!RD->isDynamicClass()) { // There is no primary base in this case. setPrimaryBase(0, false); return; } - SelectPrimaryBase(RD); + SelectPrimaryBase(RD, IndirectPrimary); if (PrimaryBase == 0) { int AS = 0; UpdateAlignment(Ctx.Target.getPointerAlign(AS)); @@ -85,9 +86,8 @@ void ASTRecordLayoutBuilder::SelectPrimaryForBase(const CXXRecordDecl *RD, cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); // Only bases with virtual bases participate in computing the // indirect primary virtual base classes. - if (Base->getNumVBases() == 0) - continue; - SelectPrimaryForBase(Base, IndirectPrimary); + if (Base->getNumVBases()) + SelectPrimaryForBase(Base, IndirectPrimary); } } @@ -117,7 +117,8 @@ void ASTRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD, /// SelectPrimaryBase - Selects the primary base for the given class and /// record that with setPrimaryBase. -void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) { +void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD, + llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary) { // The primary base is the first non-virtual indirect or direct base class, // if one exists. for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), @@ -146,7 +147,6 @@ void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) { // First, we compute all the primary virtual bases for all of our direct and // indirect bases, and record all their primary virtual base classes. const CXXRecordDecl *FirstPrimary = 0; - llvm::SmallSet<const CXXRecordDecl*, 32> IndirectPrimary; for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), e = RD->bases_end(); i != e; ++i) { const CXXRecordDecl *Base = @@ -169,13 +169,19 @@ void ASTRecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *RD) { void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD, llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary) { - // FIXME: Though complete, this is the wrong order - for (CXXRecordDecl::base_class_const_iterator i = RD->vbases_begin(), - e = RD->vbases_end(); i != e; ++i) { + // FIXME: Calculate IndirectPrimary when !PrimaryBaseWasVirtual + // assert(PrimaryBaseWasVirtual && "FIXME: calculate IndirectPrimary"); + 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 (!IndirectPrimary.count(Base)) + if (i->isVirtual() && !IndirectPrimary.count(Base)) { + // Mark it so we don't output it twice. + IndirectPrimary.insert(Base); LayoutVirtualBase(Base); + } + if (Base->getNumVBases()) + LayoutVirtualBases(Base, IndirectPrimary); } } @@ -216,13 +222,12 @@ void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) { if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) UpdateAlignment(AA->getAlignment()); - // FIXME: Calculate this completely. llvm::SmallSet<const CXXRecordDecl*, 32> IndirectPrimary; // If this is a C++ class, lay out the nonvirtual bases. const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D); if (RD) { - LayoutVtable(RD); + LayoutVtable(RD, IndirectPrimary); // PrimaryBase goes first. if (PrimaryBase) { // FIXME: We need all the primaries. diff --git a/clang/lib/AST/RecordLayoutBuilder.h b/clang/lib/AST/RecordLayoutBuilder.h index 05944ece7da..24a185c8abf 100644 --- a/clang/lib/AST/RecordLayoutBuilder.h +++ b/clang/lib/AST/RecordLayoutBuilder.h @@ -53,7 +53,8 @@ class ASTRecordLayoutBuilder { void LayoutFields(const RecordDecl *D); void LayoutField(const FieldDecl *D); - void SelectPrimaryBase(const CXXRecordDecl *RD); + void SelectPrimaryBase(const CXXRecordDecl *RD, + llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary); void SelectPrimaryVBase(const CXXRecordDecl *RD, const CXXRecordDecl *&FirstPrimary, llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary); @@ -64,7 +65,8 @@ class ASTRecordLayoutBuilder { PrimaryBaseWasVirtual = Virtual; } bool IsNearlyEmpty(const CXXRecordDecl *RD); - void LayoutVtable(const CXXRecordDecl *RD); + void LayoutVtable(const CXXRecordDecl *RD, + llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary); void LayoutNonVirtualBases(const CXXRecordDecl *RD); void LayoutBaseNonVirtually(const CXXRecordDecl *RD); void LayoutVirtualBase(const CXXRecordDecl *RD); diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp index 2940f18b4df..24e87f521f3 100644 --- a/clang/lib/CodeGen/CGCXX.cpp +++ b/clang/lib/CodeGen/CGCXX.cpp @@ -617,10 +617,10 @@ llvm::Constant *CodeGenFunction::GenerateRtti(const CXXRecordDecl *RD) { llvm::GlobalVariable::LinkageTypes linktype; linktype = llvm::GlobalValue::WeakAnyLinkage; std::vector<llvm::Constant *> info; - // assert (0 && "FIXME: implement rtti descriptor"); + // assert(0 && "FIXME: implement rtti descriptor"); // FIXME: descriptor info.push_back(llvm::Constant::getNullValue(Ptr8Ty)); - // assert (0 && "FIXME: implement rtti ts"); + // assert(0 && "FIXME: implement rtti ts"); // FIXME: TS info.push_back(llvm::Constant::getNullValue(Ptr8Ty)); @@ -666,6 +666,25 @@ void CodeGenFunction::GenerateMethods(std::vector<llvm::Constant *> &methods, } } +void CodeGenFunction::GenerateVtableForVBases(const CXXRecordDecl *RD, + llvm::Constant *rtti, + std::vector<llvm::Constant *> &methods, + llvm::SmallSet<const CXXRecordDecl *, 32> &IndirectPrimary) { + 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() && !IndirectPrimary.count(Base)) { + // Mark it so we don't output it twice. + IndirectPrimary.insert(Base); + GenerateVtableForBase(Base, RD, rtti, methods, false, true, + IndirectPrimary); + } + if (Base->getNumVBases()) + GenerateVtableForVBases(Base, rtti, methods, IndirectPrimary); + } +} + void CodeGenFunction::GenerateVtableForBase(const CXXRecordDecl *RD, const CXXRecordDecl *Class, llvm::Constant *rtti, @@ -776,15 +795,8 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) { IndirectPrimary); } - // FIXME: Though complete, this is the wrong order - for (CXXRecordDecl::base_class_const_iterator i = RD->vbases_begin(), - e = RD->vbases_end(); i != e; ++i) { - const CXXRecordDecl *Base = - cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); - if (!IndirectPrimary.count(Base)) - GenerateVtableForBase(Base, RD, rtti, methods, false, true, - IndirectPrimary); - } + // Then come the vtables for all the virtual bases. + GenerateVtableForVBases(RD, rtti, methods, IndirectPrimary); llvm::Constant *C; llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, methods.size()); diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 1ea19c6e13b..aa4bcceae26 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -363,6 +363,10 @@ public: const CXXRecordDecl *RD, llvm::Type *Ptr8Ty); void GenerateMethods(std::vector<llvm::Constant *> &methods, const CXXRecordDecl *RD, llvm::Type *Ptr8Ty); +void GenerateVtableForVBases(const CXXRecordDecl *RD, + llvm::Constant *rtti, + std::vector<llvm::Constant *> &methods, + llvm::SmallSet<const CXXRecordDecl *, 32> &IndirectPrimary); void GenerateVtableForBase(const CXXRecordDecl *RD, const CXXRecordDecl *Class, llvm::Constant *rtti, |