diff options
| author | Fariborz Jahanian <fjahanian@apple.com> | 2009-07-30 00:10:25 +0000 |
|---|---|---|
| committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-07-30 00:10:25 +0000 |
| commit | d375454dcf33c1285e40d27b97137aadf1f49f01 (patch) | |
| tree | b79c12e0574e2e16f08fee892d5de92bf36584ef /clang/lib/CodeGen/CGCXX.cpp | |
| parent | da9ba9ec2c40ed964de5fe7a3d83474d978ae8cb (diff) | |
| download | bcm5719-llvm-d375454dcf33c1285e40d27b97137aadf1f49f01.tar.gz bcm5719-llvm-d375454dcf33c1285e40d27b97137aadf1f49f01.zip | |
ir-gen for nested non-virtual base member access
in current class.
llvm-svn: 77554
Diffstat (limited to 'clang/lib/CodeGen/CGCXX.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CGCXX.cpp | 52 |
1 files changed, 47 insertions, 5 deletions
diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp index f80956b93f2..bce22e5ec36 100644 --- a/clang/lib/CodeGen/CGCXX.cpp +++ b/clang/lib/CodeGen/CGCXX.cpp @@ -155,19 +155,61 @@ llvm::Value *CodeGenFunction::LoadCXXThis() { return Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this"); } +static bool +GetNestedPaths(llvm::SmallVectorImpl<const CXXRecordDecl *> &NestedBasePaths, + const CXXRecordDecl *ClassDecl, + const CXXRecordDecl *BaseClassDecl) { + assert(!ClassDecl->isPolymorphic() && + "FIXME: We don't support polymorphic classes yet!"); + for (CXXRecordDecl::base_class_const_iterator i = ClassDecl->bases_begin(), + e = ClassDecl->bases_end(); i != e; ++i) { + if (i->isVirtual()) + continue; + const CXXRecordDecl *Base = + cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); + if (Base == BaseClassDecl) { + NestedBasePaths.push_back(BaseClassDecl); + return true; + } + } + // BaseClassDecl not an immediate base of ClassDecl. + for (CXXRecordDecl::base_class_const_iterator i = ClassDecl->bases_begin(), + e = ClassDecl->bases_end(); i != e; ++i) { + if (i->isVirtual()) + continue; + const CXXRecordDecl *Base = + cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); + if (GetNestedPaths(NestedBasePaths, Base, BaseClassDecl)) { + NestedBasePaths.push_back(Base); + return true; + } + } + return false; +} + llvm::Value *CodeGenFunction::AddressCXXOfBaseClass(llvm::Value *BaseValue, const CXXRecordDecl *ClassDecl, const CXXRecordDecl *BaseClassDecl) { if (ClassDecl == BaseClassDecl) return BaseValue; + llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); + llvm::SmallVector<const CXXRecordDecl *, 16> NestedBasePaths; + GetNestedPaths(NestedBasePaths, ClassDecl, BaseClassDecl); + assert(NestedBasePaths.size() > 0 && + "AddressCXXOfBaseClass - inheritence path failed"); + NestedBasePaths.push_back(ClassDecl); + uint64_t Offset = 0; + // Accessing a member of the base class. Must add delata to // the load of 'this'. - // FIXME. Once type layout is complete, this will probably change. - const ASTRecordLayout &Layout = - getContext().getASTRecordLayout(ClassDecl); - llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); - uint64_t Offset = Layout.getBaseClassOffset(BaseClassDecl) / 8; + for (unsigned i = NestedBasePaths.size()-1; i > 0; i--) { + const CXXRecordDecl *DerivedClass = NestedBasePaths[i]; + const CXXRecordDecl *BaseClass = NestedBasePaths[i-1]; + const ASTRecordLayout &Layout = + getContext().getASTRecordLayout(DerivedClass); + Offset += Layout.getBaseClassOffset(BaseClass) / 8; + } llvm::Value *OffsetVal = llvm::ConstantInt::get( CGM.getTypes().ConvertType(CGM.getContext().LongTy), Offset); |

