forked from OSchip/llvm-project
Teach AggExprEmitter about pointers to member functions.
llvm-svn: 83266
This commit is contained in:
parent
3162e4945a
commit
c46bf276e1
|
@ -94,6 +94,7 @@ public:
|
|||
void VisitBinaryOperator(const BinaryOperator *BO);
|
||||
void VisitBinAssign(const BinaryOperator *E);
|
||||
void VisitBinComma(const BinaryOperator *E);
|
||||
void VisitUnaryAddrOf(const UnaryOperator *E);
|
||||
|
||||
void VisitObjCMessageExpr(ObjCMessageExpr *E);
|
||||
void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
|
||||
|
@ -281,6 +282,38 @@ void AggExprEmitter::VisitBinComma(const BinaryOperator *E) {
|
|||
/*IgnoreResult=*/false, IsInitializer);
|
||||
}
|
||||
|
||||
void AggExprEmitter::VisitUnaryAddrOf(const UnaryOperator *E) {
|
||||
// We have a member function pointer.
|
||||
const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>();
|
||||
assert(MPT->getPointeeType()->isFunctionProtoType() &&
|
||||
"Unexpected member pointer type!");
|
||||
|
||||
const QualifiedDeclRefExpr *DRE = cast<QualifiedDeclRefExpr>(E->getSubExpr());
|
||||
const CXXMethodDecl *MD = cast<CXXMethodDecl>(DRE->getDecl());
|
||||
|
||||
const llvm::Type *PtrDiffTy =
|
||||
CGF.ConvertType(CGF.getContext().getPointerDiffType());
|
||||
|
||||
llvm::Value *DstPtr = Builder.CreateStructGEP(DestPtr, 0, "dst.ptr");
|
||||
llvm::Value *FuncPtr;
|
||||
|
||||
if (MD->isVirtual()) {
|
||||
uint64_t Index = CGF.CGM.GetVtableIndex(MD);
|
||||
|
||||
FuncPtr = llvm::ConstantInt::get(PtrDiffTy, Index + 1);
|
||||
} else {
|
||||
FuncPtr = llvm::ConstantExpr::getPtrToInt(CGF.CGM.GetAddrOfFunction(MD),
|
||||
PtrDiffTy);
|
||||
}
|
||||
Builder.CreateStore(FuncPtr, DstPtr, VolatileDest);
|
||||
|
||||
llvm::Value *AdjPtr = Builder.CreateStructGEP(DestPtr, 1, "dst.adj");
|
||||
|
||||
// The adjustment will always be 0.
|
||||
Builder.CreateStore(llvm::ConstantInt::get(PtrDiffTy, 0), AdjPtr,
|
||||
VolatileDest);
|
||||
}
|
||||
|
||||
void AggExprEmitter::VisitStmtExpr(const StmtExpr *E) {
|
||||
CGF.EmitCompoundStmt(*E->getSubStmt(), true, DestPtr, VolatileDest);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,21 @@ void f() {
|
|||
vpa = 0;
|
||||
|
||||
// CHECK: store i64 %0, i64* getelementptr inbounds (%0* @pc, i32 0, i32 0)
|
||||
// CHECK: [[ADJ:%[a-zA-Z0-9]+]] = add i64 %1, 16
|
||||
// CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = add i64 %1, 16
|
||||
// CHECK: store i64 [[ADJ]], i64* getelementptr inbounds (%0* @pc, i32 0, i32 1)
|
||||
pc = pa;
|
||||
}
|
||||
|
||||
void f2() {
|
||||
// CHECK: [[pa2ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa2, i32 0, i32 0
|
||||
// CHECK: store i64 ptrtoint (void ()* @_ZN1A1fEv to i64), i64* [[pa2ptr]]
|
||||
// CHECK: [[pa2adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa2, i32 0, i32 1
|
||||
// CHECK: store i64 0, i64* [[pa2adj]]
|
||||
void (A::*pa2)() = &A::f;
|
||||
|
||||
// CHECK: [[pa3ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 0
|
||||
// CHECK: store i64 1, i64* [[pa3ptr]]
|
||||
// CHECK: [[pa3adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 1
|
||||
// CHECK: store i64 0, i64* [[pa2adj]]
|
||||
void (A::*pa3)() = &A::vf;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue