diff options
author | John McCall <rjmccall@apple.com> | 2011-06-15 23:02:42 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-06-15 23:02:42 +0000 |
commit | f85e193739c953358c865005855253af4f68a497 (patch) | |
tree | e242284beb7fd2b88a2f3ce08644585497d5910d /lib/CodeGen/CGClass.cpp | |
parent | 204e13395d83524e9a557c3f3fd6df2e2f353b9d (diff) |
Automatic Reference Counting.
Language-design credit goes to a lot of people, but I particularly want
to single out Blaine Garst and Patrick Beard for their contributions.
Compiler implementation credit goes to Argyrios, Doug, Fariborz, and myself,
in no particular order.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133103 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGClass.cpp')
-rw-r--r-- | lib/CodeGen/CGClass.cpp | 93 |
1 files changed, 56 insertions, 37 deletions
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index 5725d80b7d..066f0d5c7d 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -398,7 +398,8 @@ static void EmitBaseInitializer(CodeGenFunction &CGF, BaseClassDecl, isBaseVirtual); - AggValueSlot AggSlot = AggValueSlot::forAddr(V, false, /*Lifetime*/ true); + AggValueSlot AggSlot = AggValueSlot::forAddr(V, Qualifiers(), + /*Lifetime*/ true); CGF.EmitAggExpr(BaseInit->getInit(), AggSlot); @@ -428,10 +429,20 @@ static void EmitAggMemberInitializer(CodeGenFunction &CGF, CGF.Builder.CreateStore(Next, ArrayIndexVar); } - AggValueSlot Slot = AggValueSlot::forAddr(Dest, LHS.isVolatileQualified(), - /*Lifetime*/ true); - - CGF.EmitAggExpr(MemberInit->getInit(), Slot); + if (!CGF.hasAggregateLLVMType(T)) { + CGF.EmitScalarInit(MemberInit->getInit(), 0, Dest, false, + LHS.isVolatileQualified(), + CGF.getContext().getTypeAlign(T), + T); + } else if (T->isAnyComplexType()) { + CGF.EmitComplexExprIntoAddr(MemberInit->getInit(), Dest, + LHS.isVolatileQualified()); + } else { + AggValueSlot Slot = AggValueSlot::forAddr(Dest, LHS.getQuals(), + /*Lifetime*/ true); + + CGF.EmitAggExpr(MemberInit->getInit(), Slot); + } return; } @@ -540,15 +551,16 @@ static void EmitMemberInitializer(CodeGenFunction &CGF, // FIXME: If there's no initializer and the CXXCtorInitializer // was implicitly generated, we shouldn't be zeroing memory. - RValue RHS; - if (FieldType->isReferenceType()) { - RHS = CGF.EmitReferenceBindingToExpr(MemberInit->getInit(), Field); - CGF.EmitStoreThroughLValue(RHS, LHS, FieldType); - } else if (FieldType->isArrayType() && !MemberInit->getInit()) { + if (FieldType->isArrayType() && !MemberInit->getInit()) { CGF.EmitNullInitialization(LHS.getAddress(), Field->getType()); } else if (!CGF.hasAggregateLLVMType(Field->getType())) { - RHS = RValue::get(CGF.EmitScalarExpr(MemberInit->getInit())); - CGF.EmitStoreThroughLValue(RHS, LHS, FieldType); + if (LHS.isSimple()) { + CGF.EmitExprAsInit(MemberInit->getInit(), Field, LHS.getAddress(), + CGF.getContext().getDeclAlign(Field), false); + } else { + RValue RHS = RValue::get(CGF.EmitScalarExpr(MemberInit->getInit())); + CGF.EmitStoreThroughLValue(RHS, LHS, FieldType); + } } else if (MemberInit->getInit()->getType()->isAnyComplexType()) { CGF.EmitComplexExprIntoAddr(MemberInit->getInit(), LHS.getAddress(), LHS.isVolatileQualified()); @@ -576,11 +588,11 @@ static void EmitMemberInitializer(CodeGenFunction &CGF, llvm::Value *Zero = llvm::Constant::getNullValue(SizeTy); CGF.Builder.CreateStore(Zero, ArrayIndexVar); - // If we are copying an array of scalars or classes with trivial copy + // If we are copying an array of PODs or classes with trivial copy // constructors, perform a single aggregate copy. - const RecordType *Record = BaseElementTy->getAs<RecordType>(); - if (!Record || - cast<CXXRecordDecl>(Record->getDecl())->hasTrivialCopyConstructor()) { + const CXXRecordDecl *Record = BaseElementTy->getAsCXXRecordDecl(); + if (BaseElementTy.isPODType(CGF.getContext()) || + (Record && Record->hasTrivialCopyConstructor())) { // Find the source pointer. We knows it's the last argument because // we know we're in a copy constructor. unsigned SrcArgIndex = Args.size() - 1; @@ -925,12 +937,8 @@ namespace { CallArrayFieldDtor(const FieldDecl *Field) : Field(Field) {} void Emit(CodeGenFunction &CGF, bool IsForEH) { - QualType FieldType = Field->getType(); - const ConstantArrayType *Array = - CGF.getContext().getAsConstantArrayType(FieldType); - - QualType BaseType = - CGF.getContext().getBaseElementType(Array->getElementType()); + QualType FieldType = Field->getType(); + QualType BaseType = CGF.getContext().getBaseElementType(FieldType); const CXXRecordDecl *FieldClassDecl = BaseType->getAsCXXRecordDecl(); llvm::Value *ThisPtr = CGF.LoadCXXThis(); @@ -938,9 +946,12 @@ namespace { // FIXME: Qualifiers? /*CVRQualifiers=*/0); - const llvm::Type *BasePtr = CGF.ConvertType(BaseType)->getPointerTo(); - llvm::Value *BaseAddrPtr = - CGF.Builder.CreateBitCast(LHS.getAddress(), BasePtr); + const llvm::Type *BasePtr + = CGF.ConvertType(BaseType)->getPointerTo(); + llvm::Value *BaseAddrPtr + = CGF.Builder.CreateBitCast(LHS.getAddress(), BasePtr); + const ConstantArrayType *Array + = CGF.getContext().getAsConstantArrayType(FieldType); CGF.EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(), Array, BaseAddrPtr); } @@ -1042,19 +1053,26 @@ void CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD, getContext().getAsConstantArrayType(FieldType); if (Array) FieldType = getContext().getBaseElementType(Array->getElementType()); - - const RecordType *RT = FieldType->getAs<RecordType>(); - if (!RT) + + switch (FieldType.isDestructedType()) { + case QualType::DK_none: continue; - - CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); - if (FieldClassDecl->hasTrivialDestructor()) - continue; + + case QualType::DK_cxx_destructor: + if (Array) + EHStack.pushCleanup<CallArrayFieldDtor>(NormalAndEHCleanup, Field); + else + EHStack.pushCleanup<CallFieldDtor>(NormalAndEHCleanup, Field); + break; + + case QualType::DK_objc_strong_lifetime: + PushARCFieldReleaseCleanup(getARCCleanupKind(), Field); + break; - if (Array) - EHStack.pushCleanup<CallArrayFieldDtor>(NormalAndEHCleanup, Field); - else - EHStack.pushCleanup<CallFieldDtor>(NormalAndEHCleanup, Field); + case QualType::DK_objc_weak_lifetime: + PushARCFieldWeakReleaseCleanup(getARCCleanupKind(), Field); + break; + } } } @@ -1384,7 +1402,8 @@ CodeGenFunction::EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor llvm::Value *ThisPtr = LoadCXXThis(); - AggValueSlot AggSlot = AggValueSlot::forAddr(ThisPtr, false, /*Lifetime*/ true); + AggValueSlot AggSlot = + AggValueSlot::forAddr(ThisPtr, Qualifiers(), /*Lifetime*/ true); EmitAggExpr(Ctor->init_begin()[0]->getInit(), AggSlot); |