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 | 6a7e6a4c3ca3ce9ebc3fca00626da4eccd8a8cc3 (patch) | |
| tree | 3aad4ac0a9b238b3a7959db5d804769ed71ce922 /clang/lib/CodeGen/CGVtable.cpp | |
| parent | 1888b44988e25cfc89ce4bf457d51fe1a86645bb (diff) | |
| download | bcm5719-llvm-6a7e6a4c3ca3ce9ebc3fca00626da4eccd8a8cc3.tar.gz bcm5719-llvm-6a7e6a4c3ca3ce9ebc3fca00626da4eccd8a8cc3.zip | |
Baby steps towards teaching FinalOverriders about virtual bases.
llvm-svn: 96139
Diffstat (limited to 'clang/lib/CodeGen/CGVtable.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CGVtable.cpp | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/clang/lib/CodeGen/CGVtable.cpp b/clang/lib/CodeGen/CGVtable.cpp index 9c3f1df5a5c..3fc7135b8b3 100644 --- a/clang/lib/CodeGen/CGVtable.cpp +++ b/clang/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)); } |

