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");
|
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,
|
llvm::Value *CodeGenFunction::AddressCXXOfBaseClass(llvm::Value *BaseValue,
|
||||||
const CXXRecordDecl *ClassDecl,
|
const CXXRecordDecl *ClassDecl,
|
||||||
const CXXRecordDecl *BaseClassDecl) {
|
const CXXRecordDecl *BaseClassDecl) {
|
||||||
if (ClassDecl == BaseClassDecl)
|
if (ClassDecl == BaseClassDecl)
|
||||||
return BaseValue;
|
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
|
// Accessing a member of the base class. Must add delata to
|
||||||
// the load of 'this'.
|
// the load of 'this'.
|
||||||
// FIXME. Once type layout is complete, this will probably change.
|
for (unsigned i = NestedBasePaths.size()-1; i > 0; i--) {
|
||||||
const ASTRecordLayout &Layout =
|
const CXXRecordDecl *DerivedClass = NestedBasePaths[i];
|
||||||
getContext().getASTRecordLayout(ClassDecl);
|
const CXXRecordDecl *BaseClass = NestedBasePaths[i-1];
|
||||||
llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
|
const ASTRecordLayout &Layout =
|
||||||
uint64_t Offset = Layout.getBaseClassOffset(BaseClassDecl) / 8;
|
getContext().getASTRecordLayout(DerivedClass);
|
||||||
|
Offset += Layout.getBaseClassOffset(BaseClass) / 8;
|
||||||
|
}
|
||||||
llvm::Value *OffsetVal =
|
llvm::Value *OffsetVal =
|
||||||
llvm::ConstantInt::get(
|
llvm::ConstantInt::get(
|
||||||
CGM.getTypes().ConvertType(CGM.getContext().LongTy), Offset);
|
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