forked from OSchip/llvm-project
ir-gen for nested non-virtual base member access
in current class. llvm-svn: 77554
This commit is contained in:
parent
da9ba9ec2c
commit
d375454dcf
|
@ -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);
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
// 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();
|
||||
}
|
Loading…
Reference in New Issue