Add VTT parameter to base ctors/dtors with virtual bases. (They aren't used yet).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89835 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Anders Carlsson 2009-11-25 03:15:49 +00:00
Родитель bc6c676448
Коммит f6c56e2323
6 изменённых файлов: 103 добавлений и 6 удалений

Просмотреть файл

@ -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>(

Просмотреть файл

@ -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())

Просмотреть файл

@ -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

Просмотреть файл

@ -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.

Просмотреть файл

@ -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);

Просмотреть файл

@ -0,0 +1,17 @@
// RUN: clang-cc -emit-llvm %s -o - -triple=x86_64-apple-darwin10 | FileCheck %s
struct A {
A();
};
// CHECK: define void @_ZN1AC1Ev(%struct.A* %this)
// CHECK: define void @_ZN1AC2Ev(%struct.A* %this)
A::A() { }
struct B : virtual A {
B();
};
// CHECK: define void @_ZN1BC1Ev(%struct.B* %this)
// CHECK: define void @_ZN1BC2Ev(%struct.B* %this, i8** %vtt)
B::B() { }