diff options
author | dim <dim@FreeBSD.org> | 2011-05-02 19:39:53 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-05-02 19:39:53 +0000 |
commit | 110eaaceddcec790f7e6a5e3bf1261c9aa1e73ab (patch) | |
tree | 64a10f4c4154739d4a8191d7e1b52ce497f4ebd6 /lib/CodeGen/CGClass.cpp | |
parent | a0fb00f9837bd0d2e5948f16f6a6b82a7a628f51 (diff) | |
download | FreeBSD-src-110eaaceddcec790f7e6a5e3bf1261c9aa1e73ab.zip FreeBSD-src-110eaaceddcec790f7e6a5e3bf1261c9aa1e73ab.tar.gz |
Vendor import of clang trunk r130700:
http://llvm.org/svn/llvm-project/cfe/trunk@130700
Diffstat (limited to 'lib/CodeGen/CGClass.cpp')
-rw-r--r-- | lib/CodeGen/CGClass.cpp | 156 |
1 files changed, 83 insertions, 73 deletions
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index cd28bbe..ca8b657 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -22,12 +22,12 @@ using namespace clang; using namespace CodeGen; -static uint64_t +static CharUnits ComputeNonVirtualBaseClassOffset(ASTContext &Context, const CXXRecordDecl *DerivedClass, CastExpr::path_const_iterator Start, CastExpr::path_const_iterator End) { - uint64_t Offset = 0; + CharUnits Offset = CharUnits::Zero(); const CXXRecordDecl *RD = DerivedClass; @@ -42,13 +42,12 @@ ComputeNonVirtualBaseClassOffset(ASTContext &Context, cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); // Add the offset. - Offset += Layout.getBaseClassOffsetInBits(BaseDecl); + Offset += Layout.getBaseClassOffset(BaseDecl); RD = BaseDecl; } - // FIXME: We should not use / 8 here. - return Offset / 8; + return Offset; } llvm::Constant * @@ -57,16 +56,16 @@ CodeGenModule::GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl, CastExpr::path_const_iterator PathEnd) { assert(PathBegin != PathEnd && "Base path should not be empty!"); - uint64_t Offset = + CharUnits Offset = ComputeNonVirtualBaseClassOffset(getContext(), ClassDecl, PathBegin, PathEnd); - if (!Offset) + if (Offset.isZero()) return 0; const llvm::Type *PtrDiffTy = Types.ConvertType(getContext().getPointerDiffType()); - return llvm::ConstantInt::get(PtrDiffTy, Offset); + return llvm::ConstantInt::get(PtrDiffTy, Offset.getQuantity()); } /// Gets the address of a direct base class within a complete object. @@ -85,20 +84,20 @@ CodeGenFunction::GetAddressOfDirectBaseInCompleteClass(llvm::Value *This, == ConvertType(Derived)); // Compute the offset of the virtual base. - uint64_t Offset; + CharUnits Offset; const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Derived); if (BaseIsVirtual) - Offset = Layout.getVBaseClassOffsetInBits(Base); + Offset = Layout.getVBaseClassOffset(Base); else - Offset = Layout.getBaseClassOffsetInBits(Base); + Offset = Layout.getBaseClassOffset(Base); // Shift and cast down to the base type. // TODO: for complete types, this should be possible with a GEP. llvm::Value *V = This; - if (Offset) { + if (Offset.isPositive()) { const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext()); V = Builder.CreateBitCast(V, Int8PtrTy); - V = Builder.CreateConstInBoundsGEP1_64(V, Offset / 8); + V = Builder.CreateConstInBoundsGEP1_64(V, Offset.getQuantity()); } V = Builder.CreateBitCast(V, ConvertType(Base)->getPointerTo()); @@ -107,13 +106,14 @@ CodeGenFunction::GetAddressOfDirectBaseInCompleteClass(llvm::Value *This, static llvm::Value * ApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, llvm::Value *ThisPtr, - uint64_t NonVirtual, llvm::Value *Virtual) { + CharUnits NonVirtual, llvm::Value *Virtual) { const llvm::Type *PtrDiffTy = CGF.ConvertType(CGF.getContext().getPointerDiffType()); llvm::Value *NonVirtualOffset = 0; - if (NonVirtual) - NonVirtualOffset = llvm::ConstantInt::get(PtrDiffTy, NonVirtual); + if (!NonVirtual.isZero()) + NonVirtualOffset = llvm::ConstantInt::get(PtrDiffTy, + NonVirtual.getQuantity()); llvm::Value *BaseOffset; if (Virtual) { @@ -150,7 +150,7 @@ CodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value, ++Start; } - uint64_t NonVirtualOffset = + CharUnits NonVirtualOffset = ComputeNonVirtualBaseClassOffset(getContext(), VBase ? VBase : Derived, Start, PathEnd); @@ -158,7 +158,7 @@ CodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value, const llvm::Type *BasePtrTy = ConvertType((PathEnd[-1])->getType())->getPointerTo(); - if (!NonVirtualOffset && !VBase) { + if (NonVirtualOffset.isZero() && !VBase) { // Just cast back. return Builder.CreateBitCast(Value, BasePtrTy); } @@ -172,9 +172,7 @@ CodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value, CastNotNull = createBasicBlock("cast.notnull"); CastEnd = createBasicBlock("cast.end"); - llvm::Value *IsNull = - Builder.CreateICmpEQ(Value, - llvm::Constant::getNullValue(Value->getType())); + llvm::Value *IsNull = Builder.CreateIsNull(Value); Builder.CreateCondBr(IsNull, CastNull, CastNotNull); EmitBlock(CastNotNull); } @@ -187,14 +185,15 @@ CodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value, const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Derived); - uint64_t VBaseOffset = Layout.getVBaseClassOffsetInBits(VBase); - NonVirtualOffset += VBaseOffset / 8; + CharUnits VBaseOffset = Layout.getVBaseClassOffset(VBase); + NonVirtualOffset += VBaseOffset; } else VirtualOffset = GetVirtualBaseClassOffset(Value, Derived, VBase); } // Apply the offsets. - Value = ApplyNonVirtualAndVirtualOffset(*this, Value, NonVirtualOffset, + Value = ApplyNonVirtualAndVirtualOffset(*this, Value, + NonVirtualOffset, VirtualOffset); // Cast back. @@ -206,8 +205,7 @@ CodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value, Builder.CreateBr(CastEnd); EmitBlock(CastEnd); - llvm::PHINode *PHI = Builder.CreatePHI(Value->getType()); - PHI->reserveOperandSpace(2); + llvm::PHINode *PHI = Builder.CreatePHI(Value->getType(), 2); PHI->addIncoming(Value, CastNotNull); PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), CastNull); @@ -246,9 +244,7 @@ CodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value, CastNotNull = createBasicBlock("cast.notnull"); CastEnd = createBasicBlock("cast.end"); - llvm::Value *IsNull = - Builder.CreateICmpEQ(Value, - llvm::Constant::getNullValue(Value->getType())); + llvm::Value *IsNull = Builder.CreateIsNull(Value); Builder.CreateCondBr(IsNull, CastNull, CastNotNull); EmitBlock(CastNotNull); } @@ -267,8 +263,7 @@ CodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value, Builder.CreateBr(CastEnd); EmitBlock(CastEnd); - llvm::PHINode *PHI = Builder.CreatePHI(Value->getType()); - PHI->reserveOperandSpace(2); + llvm::PHINode *PHI = Builder.CreatePHI(Value->getType(), 2); PHI->addIncoming(Value, CastNotNull); PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), CastNull); @@ -304,9 +299,9 @@ static llvm::Value *GetVTTParameter(CodeGenFunction &CGF, GlobalDecl GD, } else { const ASTRecordLayout &Layout = CGF.getContext().getASTRecordLayout(RD); - uint64_t BaseOffset = ForVirtualBase ? - Layout.getVBaseClassOffsetInBits(Base) : - Layout.getBaseClassOffsetInBits(Base); + CharUnits BaseOffset = ForVirtualBase ? + Layout.getVBaseClassOffset(Base) : + Layout.getBaseClassOffset(Base); SubVTTIndex = CGF.CGM.getVTables().getSubVTTIndex(RD, BaseSubobject(Base, BaseOffset)); @@ -407,7 +402,7 @@ static void EmitBaseInitializer(CodeGenFunction &CGF, CGF.EmitAggExpr(BaseInit->getInit(), AggSlot); - if (CGF.CGM.getLangOptions().areExceptionsEnabled() && + if (CGF.CGM.getLangOptions().Exceptions && !BaseClassDecl->hasTrivialDestructor()) CGF.EHStack.pushCleanup<CallBaseDtor>(EHCleanup, BaseClassDecl, isBaseVirtual); @@ -589,8 +584,7 @@ static void EmitMemberInitializer(CodeGenFunction &CGF, // we know we're in a copy constructor. unsigned SrcArgIndex = Args.size() - 1; llvm::Value *SrcPtr - = CGF.Builder.CreateLoad( - CGF.GetAddrOfLocalVar(Args[SrcArgIndex].first)); + = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(Args[SrcArgIndex])); LValue Src = CGF.EmitLValueForFieldInitialization(SrcPtr, Field, 0); // Copy the aggregate. @@ -606,7 +600,7 @@ static void EmitMemberInitializer(CodeGenFunction &CGF, EmitAggMemberInitializer(CGF, LHS, ArrayIndexVar, MemberInit, FieldType, 0); - if (!CGF.CGM.getLangOptions().areExceptionsEnabled()) + if (!CGF.CGM.getLangOptions().Exceptions) return; // FIXME: If we have an array of classes w/ non-trivial destructors, @@ -664,6 +658,10 @@ static bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor) { if (Ctor->getType()->getAs<FunctionProtoType>()->isVariadic()) return false; + // FIXME: Decide if we can do a delegation of a delegating constructor. + if (Ctor->isDelegatingConstructor()) + return false; + return true; } @@ -716,6 +714,9 @@ void CodeGenFunction::EmitConstructorBody(FunctionArgList &Args) { void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType CtorType, FunctionArgList &Args) { + if (CD->isDelegatingConstructor()) + return EmitDelegatingCXXConstructorCall(CD, Args); + const CXXRecordDecl *ClassDecl = CD->getParent(); llvm::SmallVector<CXXCtorInitializer *, 8> MemberInitializers; @@ -727,8 +728,10 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, if (Member->isBaseInitializer()) EmitBaseInitializer(*this, ClassDecl, Member, CtorType); - else + else if (Member->isAnyMemberInitializer()) MemberInitializers.push_back(Member); + else + llvm_unreachable("Delegating initializer on non-delegating constructor"); } InitializeVTablePointers(ClassDecl); @@ -1196,15 +1199,14 @@ CodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, CallArgList Args; // Push the this ptr. - Args.push_back(std::make_pair(RValue::get(This), - D->getThisType(getContext()))); + Args.add(RValue::get(This), D->getThisType(getContext())); // Push the src ptr. QualType QT = *(FPT->arg_type_begin()); const llvm::Type *t = CGM.getTypes().ConvertType(QT); Src = Builder.CreateBitCast(Src, t); - Args.push_back(std::make_pair(RValue::get(Src), QT)); + Args.add(RValue::get(Src), QT); // Skip over first argument (Src). ++ArgBeg; @@ -1212,9 +1214,7 @@ CodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, for (FunctionProtoType::arg_type_iterator I = FPT->arg_type_begin()+1, E = FPT->arg_type_end(); I != E; ++I, ++Arg) { assert(Arg != ArgEnd && "Running over edge of argument list!"); - QualType ArgType = *I; - Args.push_back(std::make_pair(EmitCallArg(*Arg, ArgType), - ArgType)); + EmitCallArg(Args, *Arg, *I); } // Either we've emitted all the call args, or we have a call to a // variadic function. @@ -1223,8 +1223,7 @@ CodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, // If we still have any arguments, emit them using the type of the argument. for (; Arg != ArgEnd; ++Arg) { QualType ArgType = Arg->getType(); - Args.push_back(std::make_pair(EmitCallArg(*Arg, ArgType), - ArgType)); + EmitCallArg(Args, *Arg, ArgType); } QualType ResultType = FPT->getResultType(); @@ -1243,30 +1242,26 @@ CodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, assert(I != E && "no parameters to constructor"); // this - DelegateArgs.push_back(std::make_pair(RValue::get(LoadCXXThis()), - I->second)); + DelegateArgs.add(RValue::get(LoadCXXThis()), (*I)->getType()); ++I; // vtt if (llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(Ctor, CtorType), /*ForVirtualBase=*/false)) { QualType VoidPP = getContext().getPointerType(getContext().VoidPtrTy); - DelegateArgs.push_back(std::make_pair(RValue::get(VTT), VoidPP)); + DelegateArgs.add(RValue::get(VTT), VoidPP); if (CodeGenVTables::needsVTTParameter(CurGD)) { assert(I != E && "cannot skip vtt parameter, already done with args"); - assert(I->second == VoidPP && "skipping parameter not of vtt type"); + assert((*I)->getType() == VoidPP && "skipping parameter not of vtt type"); ++I; } } // Explicit arguments. for (; I != E; ++I) { - const VarDecl *Param = I->first; - QualType ArgType = Param->getType(); // because we're passing it to itself - RValue Arg = EmitDelegateCallArg(Param); - - DelegateArgs.push_back(std::make_pair(Arg, ArgType)); + const VarDecl *param = *I; + EmitDelegateCallArg(DelegateArgs, param); } EmitCall(CGM.getTypes().getFunctionInfo(Ctor, CtorType), @@ -1274,6 +1269,19 @@ CodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, ReturnValueSlot(), DelegateArgs, Ctor); } +void +CodeGenFunction::EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor, + const FunctionArgList &Args) { + assert(Ctor->isDelegatingConstructor()); + + llvm::Value *ThisPtr = LoadCXXThis(); + + AggValueSlot AggSlot = AggValueSlot::forAddr(ThisPtr, false, /*Lifetime*/ true); + + EmitAggExpr(Ctor->init_begin()[0]->getInit(), AggSlot); +} + + void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, @@ -1317,6 +1325,7 @@ void CodeGenFunction::PushDestructorCleanup(QualType T, llvm::Value *Addr) { if (ClassDecl->hasTrivialDestructor()) return; const CXXDestructorDecl *D = ClassDecl->getDestructor(); + assert(D && D->isUsed() && "destructor not marked as used!"); PushDestructorCleanup(D, Addr); } @@ -1325,11 +1334,12 @@ CodeGenFunction::GetVirtualBaseClassOffset(llvm::Value *This, const CXXRecordDecl *ClassDecl, const CXXRecordDecl *BaseClassDecl) { llvm::Value *VTablePtr = GetVTablePtr(This, Int8PtrTy); - int64_t VBaseOffsetOffset = + CharUnits VBaseOffsetOffset = CGM.getVTables().getVirtualBaseOffsetOffset(ClassDecl, BaseClassDecl); llvm::Value *VBaseOffsetPtr = - Builder.CreateConstGEP1_64(VTablePtr, VBaseOffsetOffset, "vbase.offset.ptr"); + Builder.CreateConstGEP1_64(VTablePtr, VBaseOffsetOffset.getQuantity(), + "vbase.offset.ptr"); const llvm::Type *PtrDiffTy = ConvertType(getContext().getPointerDiffType()); @@ -1344,7 +1354,7 @@ CodeGenFunction::GetVirtualBaseClassOffset(llvm::Value *This, void CodeGenFunction::InitializeVTablePointer(BaseSubobject Base, const CXXRecordDecl *NearestVBase, - uint64_t OffsetFromNearestVBase, + CharUnits OffsetFromNearestVBase, llvm::Constant *VTable, const CXXRecordDecl *VTableClass) { const CXXRecordDecl *RD = Base.getBase(); @@ -1374,23 +1384,23 @@ CodeGenFunction::InitializeVTablePointer(BaseSubobject Base, // Compute where to store the address point. llvm::Value *VirtualOffset = 0; - uint64_t NonVirtualOffset = 0; + CharUnits NonVirtualOffset = CharUnits::Zero(); if (CodeGenVTables::needsVTTParameter(CurGD) && NearestVBase) { // We need to use the virtual base offset offset because the virtual base // might have a different offset in the most derived class. VirtualOffset = GetVirtualBaseClassOffset(LoadCXXThis(), VTableClass, NearestVBase); - NonVirtualOffset = OffsetFromNearestVBase / 8; + NonVirtualOffset = OffsetFromNearestVBase; } else { // We can just use the base offset in the complete class. - NonVirtualOffset = Base.getBaseOffset() / 8; + NonVirtualOffset = Base.getBaseOffset(); } // Apply the offsets. llvm::Value *VTableField = LoadCXXThis(); - if (NonVirtualOffset || VirtualOffset) + if (!NonVirtualOffset.isZero() || VirtualOffset) VTableField = ApplyNonVirtualAndVirtualOffset(*this, VTableField, NonVirtualOffset, VirtualOffset); @@ -1405,7 +1415,7 @@ CodeGenFunction::InitializeVTablePointer(BaseSubobject Base, void CodeGenFunction::InitializeVTablePointers(BaseSubobject Base, const CXXRecordDecl *NearestVBase, - uint64_t OffsetFromNearestVBase, + CharUnits OffsetFromNearestVBase, bool BaseIsNonVirtualPrimaryBase, llvm::Constant *VTable, const CXXRecordDecl *VTableClass, @@ -1430,8 +1440,8 @@ CodeGenFunction::InitializeVTablePointers(BaseSubobject Base, if (!BaseDecl->isDynamicClass()) continue; - uint64_t BaseOffset; - uint64_t BaseOffsetFromNearestVBase; + CharUnits BaseOffset; + CharUnits BaseOffsetFromNearestVBase; bool BaseDeclIsNonVirtualPrimaryBase; if (I->isVirtual()) { @@ -1442,16 +1452,15 @@ CodeGenFunction::InitializeVTablePointers(BaseSubobject Base, const ASTRecordLayout &Layout = getContext().getASTRecordLayout(VTableClass); - BaseOffset = Layout.getVBaseClassOffsetInBits(BaseDecl); - BaseOffsetFromNearestVBase = 0; + BaseOffset = Layout.getVBaseClassOffset(BaseDecl); + BaseOffsetFromNearestVBase = CharUnits::Zero(); BaseDeclIsNonVirtualPrimaryBase = false; } else { const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); - BaseOffset = - Base.getBaseOffset() + Layout.getBaseClassOffsetInBits(BaseDecl); + BaseOffset = Base.getBaseOffset() + Layout.getBaseClassOffset(BaseDecl); BaseOffsetFromNearestVBase = - OffsetFromNearestVBase + Layout.getBaseClassOffsetInBits(BaseDecl); + OffsetFromNearestVBase + Layout.getBaseClassOffset(BaseDecl); BaseDeclIsNonVirtualPrimaryBase = Layout.getPrimaryBase() == BaseDecl; } @@ -1473,8 +1482,9 @@ void CodeGenFunction::InitializeVTablePointers(const CXXRecordDecl *RD) { // Initialize the vtable pointers for this class and all of its bases. VisitedVirtualBasesSetTy VBases; - InitializeVTablePointers(BaseSubobject(RD, 0), /*NearestVBase=*/0, - /*OffsetFromNearestVBase=*/0, + InitializeVTablePointers(BaseSubobject(RD, CharUnits::Zero()), + /*NearestVBase=*/0, + /*OffsetFromNearestVBase=*/CharUnits::Zero(), /*BaseIsNonVirtualPrimaryBase=*/false, VTable, RD, VBases); } |