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);
--- /dev/null
+// RUN: clang-cc %s -emit-llvm -o %t
+
+extern "C" int printf(...);
+
+struct M {
+ M(int i){ iM = i; }
+ int iM;
+ void MPR() { printf("iM = %d\n", iM); }
+
+};
+
+struct Q {
+ Q(int i){ iQ = i; }
+ int iQ;
+ void QPR() { printf("iQ = %d\n", iQ); }
+};
+
+struct IQ {
+ IQ(int i) { iIQ = i; }
+ void IQPR() { printf("iIQ = %d\n", iIQ); }
+ int iIQ;
+};
+
+struct L : IQ {
+ L(int i) : IQ(i+100) { iL = i; }
+ int iL;
+};
+
+struct P : Q, L {
+ P(int i) : Q(i+100), L(i+200) { iP = i; }
+ int iP;
+ void PPR() { printf("iP = %d\n", iP); }
+};
+
+
+struct N : M,P {
+ N() : M(100), P(200) {}
+ void PR() { this->MPR(); this->PPR(); this->QPR();
+ IQPR();
+ printf("iM = %d\n", iM);
+ printf("iP = %d\n", iP);
+ printf("iQ = %d\n", iQ);
+ printf("iL = %d\n", iL);
+ printf("iIQ = %d\n", iIQ);
+ }
+};
+
+int main() {
+ N n1;
+ n1.PR();
+}