diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGCXX.cpp | 38 | ||||
-rw-r--r-- | lib/CodeGen/CGCall.cpp | 18 | ||||
-rw-r--r-- | lib/CodeGen/CGExprAgg.cpp | 26 | ||||
-rw-r--r-- | lib/CodeGen/CGExprConstant.cpp | 24 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 4 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenTypes.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenTypes.h | 4 |
7 files changed, 50 insertions, 66 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 525877903e..60f1f6f7eb 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -304,6 +304,44 @@ void CodeGenModule::getMangledCXXDtorName(MangleBuffer &Name, getMangleContext().mangleCXXDtor(D, Type, Name.getBuffer()); } +llvm::Constant * +CodeGenModule::GetCXXMemberFunctionPointerValue(const CXXMethodDecl *MD) { + assert(MD->isInstance() && "Member function must not be static!"); + + MD = MD->getCanonicalDecl(); + + const llvm::Type *PtrDiffTy = Types.ConvertType(Context.getPointerDiffType()); + + // Get the function pointer (or index if this is a virtual function). + if (MD->isVirtual()) { + uint64_t Index = VTables.getMethodVTableIndex(MD); + + // FIXME: We shouldn't use / 8 here. + uint64_t PointerWidthInBytes = Context.Target.getPointerWidth(0) / 8; + + // Itanium C++ ABI 2.3: + // For a non-virtual function, this field is a simple function pointer. + // For a virtual function, it is 1 plus the virtual table offset + // (in bytes) of the function, represented as a ptrdiff_t. + return llvm::ConstantInt::get(PtrDiffTy, (Index * PointerWidthInBytes) + 1); + } + + const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); + const llvm::Type *Ty; + // Check whether the function has a computable LLVM signature. + if (!CodeGenTypes::VerifyFuncTypeComplete(FPT)) { + // The function has a computable LLVM signature; use the correct type. + Ty = Types.GetFunctionType(Types.getFunctionInfo(MD), FPT->isVariadic()); + } else { + // Use an arbitrary non-function type to tell GetAddrOfFunction that the + // function type is incomplete. + Ty = PtrDiffTy; + } + + llvm::Constant *FuncPtr = GetAddrOfFunction(MD, Ty); + return llvm::ConstantExpr::getPtrToInt(FuncPtr, PtrDiffTy); +} + static llvm::Value *BuildVirtualCall(CodeGenFunction &CGF, uint64_t VTableIndex, llvm::Value *This, const llvm::Type *Ty) { Ty = Ty->getPointerTo()->getPointerTo()->getPointerTo(); diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 73cee3c10d..f8fa620c4b 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -515,27 +515,11 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool IsVariadic) { return llvm::FunctionType::get(ResultType, ArgTys, IsVariadic); } -static bool HasIncompleteReturnTypeOrArgumentTypes(const FunctionProtoType *T) { - if (const TagType *TT = T->getResultType()->getAs<TagType>()) { - if (!TT->getDecl()->isDefinition()) - return true; - } - - for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) { - if (const TagType *TT = T->getArgType(i)->getAs<TagType>()) { - if (!TT->getDecl()->isDefinition()) - return true; - } - } - - return false; -} - const llvm::Type * CodeGenTypes::GetFunctionTypeForVTable(const CXXMethodDecl *MD) { const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); - if (!HasIncompleteReturnTypeOrArgumentTypes(FPT)) + if (!VerifyFuncTypeComplete(FPT)) return GetFunctionType(getFunctionInfo(MD), FPT->isVariadic()); return llvm::OpaqueType::get(getLLVMContext()); diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index a4e64fb3d6..6c8a60e981 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -396,35 +396,11 @@ void AggExprEmitter::VisitUnaryAddrOf(const UnaryOperator *E) { const llvm::Type *PtrDiffTy = CGF.ConvertType(CGF.getContext().getPointerDiffType()); - llvm::Value *DstPtr = Builder.CreateStructGEP(DestPtr, 0, "dst.ptr"); - llvm::Value *FuncPtr; - - if (MD->isVirtual()) { - int64_t Index = CGF.CGM.getVTables().getMethodVTableIndex(MD); - - // FIXME: We shouldn't use / 8 here. - uint64_t PointerWidthInBytes = - CGF.CGM.getContext().Target.getPointerWidth(0) / 8; - - // Itanium C++ ABI 2.3: - // For a non-virtual function, this field is a simple function pointer. - // For a virtual function, it is 1 plus the virtual table offset - // (in bytes) of the function, represented as a ptrdiff_t. - FuncPtr = llvm::ConstantInt::get(PtrDiffTy, - (Index * PointerWidthInBytes) + 1); - } else { - const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); - const llvm::Type *Ty = - CGF.CGM.getTypes().GetFunctionType(CGF.CGM.getTypes().getFunctionInfo(MD), - FPT->isVariadic()); - llvm::Constant *Fn = CGF.CGM.GetAddrOfFunction(MD, Ty); - FuncPtr = llvm::ConstantExpr::getPtrToInt(Fn, PtrDiffTy); - } + llvm::Value *FuncPtr = CGF.CGM.GetCXXMemberFunctionPointerValue(MD); 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); diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index 978964d843..21a2a605a4 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -443,30 +443,8 @@ public: CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType()); llvm::Constant *Values[2]; - - // Get the function pointer (or index if this is a virtual function). - if (MD->isVirtual()) { - uint64_t Index = CGM.getVTables().getMethodVTableIndex(MD); - // FIXME: We shouldn't use / 8 here. - uint64_t PointerWidthInBytes = - CGM.getContext().Target.getPointerWidth(0) / 8; - - // Itanium C++ ABI 2.3: - // For a non-virtual function, this field is a simple function pointer. - // For a virtual function, it is 1 plus the virtual table offset - // (in bytes) of the function, represented as a ptrdiff_t. - Values[0] = llvm::ConstantInt::get(PtrDiffTy, - (Index * PointerWidthInBytes) + 1); - } else { - const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); - const llvm::Type *Ty = - CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), - FPT->isVariadic()); - - llvm::Constant *FuncPtr = CGM.GetAddrOfFunction(MD, Ty); - Values[0] = llvm::ConstantExpr::getPtrToInt(FuncPtr, PtrDiffTy); - } + Values[0] = CGM.GetCXXMemberFunctionPointerValue(MD); // The adjustment will always be 0. Values[1] = llvm::ConstantInt::get(PtrDiffTy, 0); diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 319744c4be..00974c70ec 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -315,6 +315,10 @@ public: llvm::GlobalValue *GetAddrOfCXXDestructor(const CXXDestructorDecl *D, CXXDtorType Type); + // GetCXXMemberFunctionPointerValue - Given a method declaration, return the + // integer used in a member function pointer to refer to that value. + llvm::Constant *GetCXXMemberFunctionPointerValue(const CXXMethodDecl *MD); + /// getBuiltinLibFunction - Given a builtin id for a function like /// "__builtin_fabsf", return a Function* for "fabsf". llvm::Value *getBuiltinLibFunction(const FunctionDecl *FD, diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp index a46dc726a4..c94dd89d5c 100644 --- a/lib/CodeGen/CodeGenTypes.cpp +++ b/lib/CodeGen/CodeGenTypes.cpp @@ -108,7 +108,7 @@ const llvm::Type *CodeGenTypes::ConvertTypeForMem(QualType T) { // Code to verify a given function type is complete, i.e. the return type // and all of the argument types are complete. -static const TagType *VerifyFuncTypeComplete(const Type* T) { +const TagType *CodeGenTypes::VerifyFuncTypeComplete(const Type* T) { const FunctionType *FT = cast<FunctionType>(T); if (const TagType* TT = FT->getResultType()->getAs<TagType>()) if (!TT->getDecl()->isDefinition()) diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h index fc28c3ae33..674fe8f8b4 100644 --- a/lib/CodeGen/CodeGenTypes.h +++ b/lib/CodeGen/CodeGenTypes.h @@ -122,6 +122,10 @@ public: const llvm::FunctionType *GetFunctionType(GlobalDecl GD); + /// VerifyFuncTypeComplete - Utility to check whether a function type can + /// be converted to an LLVM type (i.e. doesn't depend on an incomplete tag + /// type). + static const TagType *VerifyFuncTypeComplete(const Type* T); /// GetFunctionTypeForVTable - Get the LLVM function type for use in a vtable, /// given a CXXMethodDecl. If the method to has an incomplete return type, |