aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ASTContext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/ASTContext.cpp')
-rw-r--r--lib/AST/ASTContext.cpp34
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]),