summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGVtable.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-02-14 00:37:35 +0000
committerAnders Carlsson <andersca@mac.com>2010-02-14 00:37:35 +0000
commit6a7e6a4c3ca3ce9ebc3fca00626da4eccd8a8cc3 (patch)
tree3aad4ac0a9b238b3a7959db5d804769ed71ce922 /clang/lib/CodeGen/CGVtable.cpp
parent1888b44988e25cfc89ce4bf457d51fe1a86645bb (diff)
downloadbcm5719-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.cpp45
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));
}
OpenPOWER on IntegriCloud