[ObjC] Allow declaring __weak pointer fields in C structs in ARC.
This patch uses the infrastructure added in r326307 for enabling
non-trivial fields to be declared in C structs to allow __weak fields in
C structs in ARC.
This recommits r327206, which was reverted because it caused
module-enabled builders to fail. I discovered that the
CXXRecordDecl::CanPassInRegisters flag wasn't being set correctly in
some cases after I moved it to RecordDecl.
Thanks to Eric Liu for helping me investigate the bug.
rdar://problem/33599681
https://reviews.llvm.org/D44095
llvm-svn: 327870
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index ac262e7..6b9260d 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -1105,7 +1105,6 @@
= FromData.HasConstexprNonCopyMoveConstructor;
ToData.HasDefaultedDefaultConstructor
= FromData.HasDefaultedDefaultConstructor;
- ToData.CanPassInRegisters = FromData.CanPassInRegisters;
ToData.DefaultedDefaultConstructorIsConstexpr
= FromData.DefaultedDefaultConstructorIsConstexpr;
ToData.HasConstexprDefaultConstructor
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index b640dcc..35364d6 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -3931,7 +3931,8 @@
HasObjectMember(false), HasVolatileMember(false),
LoadedFieldsFromExternalStorage(false),
NonTrivialToPrimitiveDefaultInitialize(false),
- NonTrivialToPrimitiveCopy(false), NonTrivialToPrimitiveDestroy(false) {
+ NonTrivialToPrimitiveCopy(false), NonTrivialToPrimitiveDestroy(false),
+ CanPassInRegisters(true) {
assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
}
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 487386f..2718723 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -93,7 +93,6 @@
DeclaredNonTrivialSpecialMembersForCall(0), HasIrrelevantDestructor(true),
HasConstexprNonCopyMoveConstructor(false),
HasDefaultedDefaultConstructor(false),
- CanPassInRegisters(true),
DefaultedDefaultConstructorIsConstexpr(true),
HasConstexprDefaultConstructor(false),
HasNonLiteralTypeFieldsOrBases(false), ComputedVisibleConversions(false),
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 99f5b13..2985aac 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2214,11 +2214,14 @@
if (RT->getDecl()->isNonTrivialToPrimitiveDefaultInitialize())
return PDIK_Struct;
- Qualifiers::ObjCLifetime Lifetime = getQualifiers().getObjCLifetime();
- if (Lifetime == Qualifiers::OCL_Strong)
+ switch (getQualifiers().getObjCLifetime()) {
+ case Qualifiers::OCL_Strong:
return PDIK_ARCStrong;
-
- return PDIK_Trivial;
+ case Qualifiers::OCL_Weak:
+ return PDIK_ARCWeak;
+ default:
+ return PDIK_Trivial;
+ }
}
QualType::PrimitiveCopyKind QualType::isNonTrivialToPrimitiveCopy() const {
@@ -2228,10 +2231,14 @@
return PCK_Struct;
Qualifiers Qs = getQualifiers();
- if (Qs.getObjCLifetime() == Qualifiers::OCL_Strong)
+ switch (Qs.getObjCLifetime()) {
+ case Qualifiers::OCL_Strong:
return PCK_ARCStrong;
-
- return Qs.hasVolatile() ? PCK_VolatileTrivial : PCK_Trivial;
+ case Qualifiers::OCL_Weak:
+ return PCK_ARCWeak;
+ default:
+ return Qs.hasVolatile() ? PCK_VolatileTrivial : PCK_Trivial;
+ }
}
QualType::PrimitiveCopyKind
@@ -2239,6 +2246,17 @@
return isNonTrivialToPrimitiveCopy();
}
+bool QualType::canPassInRegisters() const {
+ if (const auto *RT =
+ getTypePtr()->getBaseElementTypeUnsafe()->getAs<RecordType>())
+ return RT->getDecl()->canPassInRegisters();
+
+ if (getQualifiers().getObjCLifetime() == Qualifiers::OCL_Weak)
+ return false;
+
+ return true;
+}
+
bool Type::isLiteralType(const ASTContext &Ctx) const {
if (isDependentType())
return false;