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 | 31168b077c3687bb79985102b08718cd77db353d (patch) | |
| tree | 489434d90661950c25716a5db40be446d933c95c /clang/lib/CodeGen/CGClass.cpp | |
| parent | ce45f88e451387c46bfd6b53c75c7fa72b730ba1 (diff) | |
| download | llvm-31168b077c3687bb79985102b08718cd77db353d.zip llvm-31168b077c3687bb79985102b08718cd77db353d.tar.gz llvm-31168b077c3687bb79985102b08718cd77db353d.tar.bz2  | |
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.
llvm-svn: 133103
Diffstat (limited to 'clang/lib/CodeGen/CGClass.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CGClass.cpp | 93 | 
1 files changed, 56 insertions, 37 deletions
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 5725d80..066f0d5 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/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);  | 
