aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGClass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGClass.cpp')
-rw-r--r--lib/CodeGen/CGClass.cpp93
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);