diff options
author | Anders Carlsson <andersca@mac.com> | 2010-02-14 00:37:35 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-02-14 00:37:35 +0000 |
commit | 9d6f0d551bbd08036baef2b892e31b87fc7e4322 (patch) | |
tree | 700ab3661e21562050ca65b5abf3a4209de1495e /lib/CodeGen/CGVtable.cpp | |
parent | c5874296f733b96e41431d30de25376636ed4b75 (diff) |
Baby steps towards teaching FinalOverriders about virtual bases.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96139 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGVtable.cpp')
-rw-r--r-- | lib/CodeGen/CGVtable.cpp | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index 9c3f1df5a5..3fc7135b8b 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -83,6 +83,10 @@ private: /// all the base subobjects of the most derived class. OverridersMapTy OverridersMap; + /// VisitedVirtualBases - A set of all the visited virtual bases, used to + /// avoid visiting virtual bases more than once. + llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases; + typedef llvm::DenseMap<BaseSubobjectMethodPairTy, BaseOffset> AdjustmentOffsetsMapTy; @@ -173,13 +177,16 @@ public: } /// dump - dump the final overriders. - void dump() const { - dump(llvm::errs(), BaseSubobject(MostDerivedClass, 0)); + void dump() { + assert(VisitedVirtualBases.empty() && + "Visited virtual bases aren't empty!"); + dump(llvm::errs(), BaseSubobject(MostDerivedClass, 0)); + VisitedVirtualBases.clear(); } /// dump - dump the final overriders for a base subobject, and all its direct /// and indirect base subobjects. - void dump(llvm::raw_ostream &Out, BaseSubobject Base) const; + void dump(llvm::raw_ostream &Out, BaseSubobject Base); }; FinalOverriders::FinalOverriders(const CXXRecordDecl *MostDerivedClass) @@ -491,11 +498,13 @@ void FinalOverriders::ComputeFinalOverriders(BaseSubobject Base, const CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); - assert(!I->isVirtual() && "FIXME: Handle virtual bases!"); - - uint64_t BaseOffset = Layout.getBaseClassOffset(BaseDecl) + - Base.getBaseOffset(); - + uint64_t BaseOffset; + if (I->isVirtual()) { + BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); + } else { + BaseOffset = Layout.getBaseClassOffset(BaseDecl) + Base.getBaseOffset(); + } + // Compute the final overriders for this base. ComputeFinalOverriders(BaseSubobject(BaseDecl, BaseOffset), NewOffsets); } @@ -510,20 +519,28 @@ void FinalOverriders::ComputeFinalOverriders(BaseSubobject Base, Offsets[RD].push_back(Base.getBaseOffset()); } -void FinalOverriders::dump(llvm::raw_ostream &Out, BaseSubobject Base) const { +void FinalOverriders::dump(llvm::raw_ostream &Out, BaseSubobject Base) { const CXXRecordDecl *RD = Base.getBase(); const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), E = RD->bases_end(); I != E; ++I) { - assert(!I->isVirtual() && "FIXME: Handle virtual bases!"); - const CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); - uint64_t BaseOffset = Layout.getBaseClassOffset(BaseDecl) + - Base.getBaseOffset(); - + uint64_t BaseOffset; + if (I->isVirtual()) { + if (!VisitedVirtualBases.insert(BaseDecl)) { + // We've visited this base before. + continue; + } + + BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); + } else { + BaseOffset = Layout.getBaseClassOffset(BaseDecl) + + Base.getBaseOffset(); + } + dump(Out, BaseSubobject(BaseDecl, BaseOffset)); } |