diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGCXX.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/CGCall.cpp | 36 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 34 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 9 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenTypes.h | 9 |
5 files changed, 86 insertions, 6 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index e1b6739339..71cdf95f48 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -765,7 +765,7 @@ CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D, CXXCtorType Type) { const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>(); const llvm::FunctionType *FTy = - getTypes().GetFunctionType(getTypes().getFunctionInfo(D), + getTypes().GetFunctionType(getTypes().getFunctionInfo(D, Type), FPT->isVariadic()); const char *Name = getMangledCXXCtorName(D, Type); @@ -803,7 +803,7 @@ llvm::Function * CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D, CXXDtorType Type) { const llvm::FunctionType *FTy = - getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false); + getTypes().GetFunctionType(getTypes().getFunctionInfo(D, Type), false); const char *Name = getMangledCXXDtorName(D, Type); return cast<llvm::Function>( diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 16f4e7b533..decc73c6d4 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -91,6 +91,42 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXMethodDecl *MD) { getCallingConventionForDecl(MD)); } +const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXConstructorDecl *D, + CXXCtorType Type) { + llvm::SmallVector<QualType, 16> ArgTys; + + // Add the 'this' pointer. + ArgTys.push_back(D->getThisType(Context)); + + // Check if we need to add a VTT parameter (which has type void **). + if (Type == Ctor_Base && D->getParent()->getNumVBases() != 0) + ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy)); + + const FunctionProtoType *FTP = D->getType()->getAs<FunctionProtoType>(); + for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) + ArgTys.push_back(FTP->getArgType(i)); + return getFunctionInfo(FTP->getResultType(), ArgTys, + getCallingConventionForDecl(D)); +} + +const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXDestructorDecl *D, + CXXDtorType Type) { + llvm::SmallVector<QualType, 16> ArgTys; + + // Add the 'this' pointer. + ArgTys.push_back(D->getThisType(Context)); + + // Check if we need to add a VTT parameter (which has type void **). + if (Type == Dtor_Base && D->getParent()->getNumVBases() != 0) + ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy)); + + const FunctionProtoType *FTP = D->getType()->getAs<FunctionProtoType>(); + for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) + ArgTys.push_back(FTP->getArgType(i)); + return getFunctionInfo(FTP->getResultType(), ArgTys, + getCallingConventionForDecl(D)); +} + const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionDecl *FD) { if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) if (MD->isInstance()) diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index a4cbf449ef..6e0a77ca1b 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -29,7 +29,7 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm) Builder(cgm.getModule().getContext()), DebugInfo(0), IndirectBranch(0), SwitchInsn(0), CaseRangeBlock(0), InvokeDest(0), - CXXThisDecl(0), + CXXThisDecl(0), CXXVTTDecl(0), ConditionalBranchLevel(0) { LLVMIntTy = ConvertType(getContext().IntTy); LLVMPointerWidth = Target.getPointerWidth(0); @@ -217,6 +217,24 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, } } +static bool NeedsVTTParameter(GlobalDecl GD) { + const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); + + // We don't have any virtual bases, just return early. + if (!MD->getParent()->getNumVBases()) + return false; + + // Check if we have a base constructor. + if (isa<CXXConstructorDecl>(MD) && GD.getCtorType() == Ctor_Base) + return true; + + // Check if we have a base destructor. + if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base) + return true; + + return false; +} + void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn) { const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl()); @@ -236,6 +254,16 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, &getContext().Idents.get("this"), MD->getThisType(getContext())); Args.push_back(std::make_pair(CXXThisDecl, CXXThisDecl->getType())); + + // Check if we need a VTT parameter as well. + if (NeedsVTTParameter(GD)) { + // FIXME: The comment about using a fake decl above applies here too. + QualType T = getContext().getPointerType(getContext().VoidPtrTy); + CXXVTTDecl = + ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), + &getContext().Idents.get("vtt"), T); + Args.push_back(std::make_pair(CXXVTTDecl, CXXVTTDecl->getType())); + } } } @@ -318,6 +346,10 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, // Destroy the 'this' declaration. if (CXXThisDecl) CXXThisDecl->Destroy(getContext()); + + // Destroy the VTT declaration. + if (CXXVTTDecl) + CXXVTTDecl->Destroy(getContext()); } /// ContainsLabel - Return true if the statement contains a label in it. If diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 4fde0dd864..28e000a492 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -317,10 +317,15 @@ private: /// BlockScopes - Map of which "cleanup scope" scope basic blocks have. BlockScopeMap BlockScopes; - /// CXXThisDecl - When parsing an C++ function, this will hold the implicit - /// 'this' declaration. + /// CXXThisDecl - When generating code for a C++ member function, + /// this will hold the implicit 'this' declaration. ImplicitParamDecl *CXXThisDecl; + /// CXXVTTDecl - When generating code for a base object constructor or + /// base object destructor with virtual bases, this will hold the implicit + /// VTT parameter. + ImplicitParamDecl *CXXVTTDecl; + /// CXXLiveTemporaryInfo - Holds information about a live C++ temporary. struct CXXLiveTemporaryInfo { /// Temporary - The live temporary. diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h index d4adebecde..55827aac49 100644 --- a/lib/CodeGen/CodeGenTypes.h +++ b/lib/CodeGen/CodeGenTypes.h @@ -20,6 +20,7 @@ #include <vector> #include "CGCall.h" +#include "CGCXX.h" namespace llvm { class FunctionType; @@ -34,6 +35,8 @@ namespace llvm { namespace clang { class ABIInfo; class ASTContext; + class CXXConstructorDecl; + class CXXDestructorDecl; class CXXMethodDecl; class FieldDecl; class FunctionProtoType; @@ -198,7 +201,11 @@ public: const CGFunctionInfo &getFunctionInfo(const FunctionDecl *FD); const CGFunctionInfo &getFunctionInfo(const CXXMethodDecl *MD); const CGFunctionInfo &getFunctionInfo(const ObjCMethodDecl *MD); - + const CGFunctionInfo &getFunctionInfo(const CXXConstructorDecl *D, + CXXCtorType Type); + const CGFunctionInfo &getFunctionInfo(const CXXDestructorDecl *D, + CXXDtorType Type); + // getFunctionInfo - Get the function info for a member function. const CGFunctionInfo &getFunctionInfo(const CXXRecordDecl *RD, const FunctionProtoType *FTP); |