aboutsummaryrefslogtreecommitdiff
path: root/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
commit9d6f0d551bbd08036baef2b892e31b87fc7e4322 (patch)
tree700ab3661e21562050ca65b5abf3a4209de1495e /lib/CodeGen/CGVtable.cpp
parentc5874296f733b96e41431d30de25376636ed4b75 (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.cpp45
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));
}