diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 26 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGVtable.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenTypes.h | 6 |
3 files changed, 33 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index d0c7d03f20e..16f4e7b5334 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -418,6 +418,32 @@ 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)) + return GetFunctionType(getFunctionInfo(MD), FPT->isVariadic()); + + return llvm::OpaqueType::get(getLLVMContext()); +} + void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI, const Decl *TargetDecl, AttributeListType &PAL, diff --git a/clang/lib/CodeGen/CGVtable.cpp b/clang/lib/CodeGen/CGVtable.cpp index f68dbe910f5..0c36ef492b3 100644 --- a/clang/lib/CodeGen/CGVtable.cpp +++ b/clang/lib/CodeGen/CGVtable.cpp @@ -367,10 +367,7 @@ public: if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(MD)) return wrap(CGM.GetAddrOfCXXDestructor(Dtor, GD.getDtorType())); - const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); - const llvm::Type *Ty = - CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), - FPT->isVariadic()); + const llvm::Type *Ty = CGM.getTypes().GetFunctionTypeForVtable(MD); return wrap(CGM.GetAddrOfFunction(MD, Ty)); } diff --git a/clang/lib/CodeGen/CodeGenTypes.h b/clang/lib/CodeGen/CodeGenTypes.h index f447549f669..d4adebecde1 100644 --- a/clang/lib/CodeGen/CodeGenTypes.h +++ b/clang/lib/CodeGen/CodeGenTypes.h @@ -173,6 +173,12 @@ public: const llvm::FunctionType *GetFunctionType(const CGFunctionInfo &Info, bool IsVariadic); + + /// GetFunctionTypeForVtable - Get the LLVM function type for use in a vtable, + /// given a CXXMethodDecl. If the method to has an incomplete return type, + /// and/or incomplete argument types, this will return the opaque type. + const llvm::Type *GetFunctionTypeForVtable(const CXXMethodDecl *MD); + const CGRecordLayout &getCGRecordLayout(const TagDecl*) const; /// getLLVMFieldNo - Return llvm::StructType element number |