diff options
Diffstat (limited to 'lib/AST/ASTContext.cpp')
-rw-r--r-- | lib/AST/ASTContext.cpp | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 80ce66a017..7b61c25b1d 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -4368,6 +4368,29 @@ bool ASTContext::BlockRequiresCopying(QualType Ty) const { return false; } +bool ASTContext::getByrefLifetime(QualType Ty, + Qualifiers::ObjCLifetime &LifeTime, + bool &HasByrefExtendedLayout) const { + + if (!getLangOpts().ObjC1 || + getLangOpts().getGC() != LangOptions::NonGC) + return false; + + HasByrefExtendedLayout = false; + if (Ty->isAggregateType()) { + HasByrefExtendedLayout = true; + LifeTime = Qualifiers::OCL_None; + } + else if (getLangOpts().ObjCAutoRefCount) + LifeTime = Ty.getObjCLifetime(); + // MRR. + else if (Ty->isObjCObjectPointerType() || Ty->isBlockPointerType()) + LifeTime = Qualifiers::OCL_ExplicitNone; + else + LifeTime = Qualifiers::OCL_None; + return true; +} + QualType ASTContext::BuildByRefType(StringRef DeclName, QualType Ty) const { // type = struct __Block_byref_1_X { @@ -4377,10 +4400,13 @@ ASTContext::BuildByRefType(StringRef DeclName, QualType Ty) const { // unsigned int __size; // void *__copy_helper; // as needed // void *__destroy_help // as needed + // void *__byref_variable_layout; // Extended layout info. for byref variable as needed // int X; // } * bool HasCopyAndDispose = BlockRequiresCopying(Ty); + bool HasByrefExtendedLayout; + Qualifiers::ObjCLifetime Lifetime; // FIXME: Move up SmallString<36> Name; @@ -4398,6 +4424,7 @@ ASTContext::BuildByRefType(StringRef DeclName, QualType Ty) const { Int32Ty, getPointerType(VoidPtrTy), getPointerType(VoidPtrTy), + getPointerType(VoidPtrTy), Ty }; @@ -4408,12 +4435,15 @@ ASTContext::BuildByRefType(StringRef DeclName, QualType Ty) const { "__size", "__copy_helper", "__destroy_helper", + "__byref_variable_layout", DeclName, }; - - for (size_t i = 0; i < 7; ++i) { + bool ByrefKnownLifetime = getByrefLifetime(Ty, Lifetime, HasByrefExtendedLayout); + for (size_t i = 0; i < 8; ++i) { if (!HasCopyAndDispose && i >=4 && i <= 5) continue; + if ((!ByrefKnownLifetime || !HasByrefExtendedLayout) && i == 6) + continue; FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(), SourceLocation(), &Idents.get(FieldNames[i]), |