diff options
author | Akira Hatanaka <ahatanaka@apple.com> | 2018-03-10 06:36:08 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@apple.com> | 2018-03-10 06:36:08 +0000 |
commit | c181b127c0e33ac5bbdab559de0ad1e6383737b1 (patch) | |
tree | 9ce6ebc866c0ff47020bcb3b4b37d2af1180794a /clang/lib/CodeGen/CGNonTrivialStruct.cpp | |
parent | b76ed82b58cba454799456217bc341ce59e83192 (diff) | |
download | bcm5719-llvm-c181b127c0e33ac5bbdab559de0ad1e6383737b1.tar.gz bcm5719-llvm-c181b127c0e33ac5bbdab559de0ad1e6383737b1.zip |
[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.
rdar://problem/33599681
Differential Revision: https://reviews.llvm.org/D44095
llvm-svn: 327206
Diffstat (limited to 'clang/lib/CodeGen/CGNonTrivialStruct.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGNonTrivialStruct.cpp | 59 |
1 files changed, 54 insertions, 5 deletions
diff --git a/clang/lib/CodeGen/CGNonTrivialStruct.cpp b/clang/lib/CodeGen/CGNonTrivialStruct.cpp index 3b0b1731987..731938af867 100644 --- a/clang/lib/CodeGen/CGNonTrivialStruct.cpp +++ b/clang/lib/CodeGen/CGNonTrivialStruct.cpp @@ -77,6 +77,8 @@ struct DefaultInitializedTypeVisitor { switch (PDIK) { case QualType::PDIK_ARCStrong: return asDerived().visitARCStrong(FT, std::forward<Ts>(Args)...); + case QualType::PDIK_ARCWeak: + return asDerived().visitARCWeak(FT, std::forward<Ts>(Args)...); case QualType::PDIK_Struct: return asDerived().visitStruct(FT, std::forward<Ts>(Args)...); case QualType::PDIK_Trivial: @@ -108,6 +110,8 @@ struct CopiedTypeVisitor { switch (PCK) { case QualType::PCK_ARCStrong: return asDerived().visitARCStrong(FT, std::forward<Ts>(Args)...); + case QualType::PCK_ARCWeak: + return asDerived().visitARCWeak(FT, std::forward<Ts>(Args)...); case QualType::PCK_Struct: return asDerived().visitStruct(FT, std::forward<Ts>(Args)...); case QualType::PCK_Trivial: @@ -141,11 +145,6 @@ template <class Derived> struct StructVisitor { template <class... Ts> void visitTrivial(Ts... Args) {} - template <class... Ts> void visitARCWeak(Ts... Args) { - // FIXME: remove this when visitARCWeak is implemented in the subclasses. - llvm_unreachable("weak field is not expected"); - } - template <class... Ts> void visitCXXDestructor(Ts... Args) { llvm_unreachable("field of a C++ struct type is not expected"); } @@ -245,6 +244,13 @@ template <class Derived> struct GenFuncNameBase { appendStr(getVolatileOffsetStr(FT.isVolatileQualified(), FieldOffset)); } + void visitARCWeak(QualType FT, const FieldDecl *FD, + CharUnits CurStructOffset) { + appendStr("_w"); + CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD); + appendStr(getVolatileOffsetStr(FT.isVolatileQualified(), FieldOffset)); + } + void visitStruct(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset) { CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD); @@ -615,6 +621,12 @@ struct GenDestructor : StructVisitor<GenDestructor>, *CGF, getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD), QT); } + void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStackOffset, + std::array<Address, 1> Addrs) { + CGF->destroyARCWeak( + *CGF, getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD), QT); + } + void callSpecialFunction(QualType FT, CharUnits Offset, std::array<Address, 1> Addrs) { CGF->callCStructDestructor( @@ -636,6 +648,12 @@ struct GenDefaultInitialize getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD), QT); } + void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStackOffset, + std::array<Address, 1> Addrs) { + CGF->EmitNullInitialization( + getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD), QT); + } + template <class FieldKind, size_t... Is> void visitArray(FieldKind FK, QualType QT, const FieldDecl *FD, CharUnits CurStackOffset, std::array<Address, 1> Addrs) { @@ -678,6 +696,14 @@ struct GenCopyConstructor : GenBinaryFunc<GenCopyConstructor, false> { llvm::Value *Val = CGF->EmitARCRetain(QT, SrcVal); CGF->EmitStoreOfScalar(Val, CGF->MakeAddrLValue(Addrs[DstIdx], QT), true); } + + void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStackOffset, + std::array<Address, 2> Addrs) { + Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD); + Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD); + CGF->EmitARCCopyWeak(Addrs[DstIdx], Addrs[SrcIdx]); + } + void callSpecialFunction(QualType FT, CharUnits Offset, std::array<Address, 2> Addrs) { CGF->callCStructCopyConstructor(CGF->MakeAddrLValue(Addrs[DstIdx], FT), @@ -700,6 +726,14 @@ struct GenMoveConstructor : GenBinaryFunc<GenMoveConstructor, true> { CGF->EmitStoreOfScalar(SrcVal, CGF->MakeAddrLValue(Addrs[DstIdx], QT), /* isInitialization */ true); } + + void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStackOffset, + std::array<Address, 2> Addrs) { + Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD); + Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD); + CGF->EmitARCMoveWeak(Addrs[DstIdx], Addrs[SrcIdx]); + } + void callSpecialFunction(QualType FT, CharUnits Offset, std::array<Address, 2> Addrs) { CGF->callCStructMoveConstructor(CGF->MakeAddrLValue(Addrs[DstIdx], FT), @@ -720,6 +754,14 @@ struct GenCopyAssignment : GenBinaryFunc<GenCopyAssignment, false> { CGF->EmitARCStoreStrong(CGF->MakeAddrLValue(Addrs[DstIdx], QT), SrcVal, false); } + + void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStackOffset, + std::array<Address, 2> Addrs) { + Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD); + Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD); + CGF->emitARCCopyAssignWeak(QT, Addrs[DstIdx], Addrs[SrcIdx]); + } + void callSpecialFunction(QualType FT, CharUnits Offset, std::array<Address, 2> Addrs) { CGF->callCStructCopyAssignmentOperator( @@ -747,6 +789,13 @@ struct GenMoveAssignment : GenBinaryFunc<GenMoveAssignment, true> { CGF->EmitARCRelease(DstVal, ARCImpreciseLifetime); } + void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStackOffset, + std::array<Address, 2> Addrs) { + Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD); + Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD); + CGF->emitARCMoveAssignWeak(QT, Addrs[DstIdx], Addrs[SrcIdx]); + } + void callSpecialFunction(QualType FT, CharUnits Offset, std::array<Address, 2> Addrs) { CGF->callCStructMoveAssignmentOperator( |