Author: ahatanak Date: Mon Mar 12 10:05:06 2018 New Revision: 327294 URL: http://llvm.org/viewvc/llvm-project?rev=327294&view=rev Log: Revert "[ObjC] Allow declaring __weak pointer fields in C structs in ARC."
This reverts commit r327206 as there were test failures caused by this patch. http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20180312/221427.html Removed: cfe/trunk/test/CodeGenObjC/weak-in-c-struct.m Modified: cfe/trunk/include/clang/AST/Decl.h cfe/trunk/include/clang/AST/DeclCXX.h cfe/trunk/include/clang/AST/Type.h cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/lib/AST/Decl.cpp cfe/trunk/lib/AST/DeclCXX.cpp cfe/trunk/lib/AST/Type.cpp cfe/trunk/lib/CodeGen/CGBlocks.cpp cfe/trunk/lib/CodeGen/CGNonTrivialStruct.cpp cfe/trunk/lib/CodeGen/CGObjC.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.h cfe/trunk/lib/CodeGen/TargetInfo.cpp cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Serialization/ASTReaderDecl.cpp cfe/trunk/lib/Serialization/ASTWriter.cpp cfe/trunk/lib/Serialization/ASTWriterDecl.cpp cfe/trunk/test/CodeGenObjC/nontrivial-c-struct-exception.m Modified: cfe/trunk/include/clang/AST/Decl.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=327294&r1=327293&r2=327294&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/Decl.h (original) +++ cfe/trunk/include/clang/AST/Decl.h Mon Mar 12 10:05:06 2018 @@ -3553,12 +3553,6 @@ class RecordDecl : public TagDecl { bool NonTrivialToPrimitiveCopy : 1; bool NonTrivialToPrimitiveDestroy : 1; - /// True if this class can be passed in a non-address-preserving fashion - /// (such as in registers). - /// This does not imply anything about how the ABI in use will actually - /// pass an object of this class. - bool CanPassInRegisters : 1; - protected: RecordDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, @@ -3642,18 +3636,6 @@ public: NonTrivialToPrimitiveDestroy = true; } - /// Determine whether this class can be passed in registers. In C++ mode, - /// it must have at least one trivial, non-deleted copy or move constructor. - /// FIXME: This should be set as part of completeDefinition. - bool canPassInRegisters() const { - return CanPassInRegisters; - } - - /// Set that we can pass this RecordDecl in registers. - void setCanPassInRegisters(bool CanPass) { - CanPassInRegisters = CanPass; - } - /// \brief Determines whether this declaration represents the /// injected class name. /// Modified: cfe/trunk/include/clang/AST/DeclCXX.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=327294&r1=327293&r2=327294&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/DeclCXX.h (original) +++ cfe/trunk/include/clang/AST/DeclCXX.h Mon Mar 12 10:05:06 2018 @@ -467,6 +467,12 @@ class CXXRecordDecl : public RecordDecl /// constructor. unsigned HasDefaultedDefaultConstructor : 1; + /// \brief True if this class can be passed in a non-address-preserving + /// fashion (such as in registers) according to the C++ language rules. + /// This does not imply anything about how the ABI in use will actually + /// pass an object of this class. + unsigned CanPassInRegisters : 1; + /// \brief True if a defaulted default constructor for this class would /// be constexpr. unsigned DefaultedDefaultConstructorIsConstexpr : 1; @@ -1468,6 +1474,18 @@ public: return data().HasIrrelevantDestructor; } + /// \brief Determine whether this class has at least one trivial, non-deleted + /// copy or move constructor. + bool canPassInRegisters() const { + return data().CanPassInRegisters; + } + + /// \brief Set that we can pass this RecordDecl in registers. + // FIXME: This should be set as part of completeDefinition. + void setCanPassInRegisters(bool CanPass) { + data().CanPassInRegisters = CanPass; + } + /// Determine whether the triviality for the purpose of calls for this class /// is overridden to be trivial because this class or the type of one of its /// subobjects has attribute "trivial_abi". Modified: cfe/trunk/include/clang/AST/Type.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=327294&r1=327293&r2=327294&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/Type.h (original) +++ cfe/trunk/include/clang/AST/Type.h Mon Mar 12 10:05:06 2018 @@ -1097,10 +1097,6 @@ public: /// with the ARC __strong qualifier. PDIK_ARCStrong, - /// The type is an Objective-C retainable pointer type that is qualified - /// with the ARC __weak qualifier. - PDIK_ARCWeak, - /// The type is a struct containing a field whose type is not PCK_Trivial. PDIK_Struct }; @@ -1128,10 +1124,6 @@ public: /// with the ARC __strong qualifier. PCK_ARCStrong, - /// The type is an Objective-C retainable pointer type that is qualified - /// with the ARC __weak qualifier. - PCK_ARCWeak, - /// The type is a struct containing a field whose type is neither /// PCK_Trivial nor PCK_VolatileTrivial. /// Note that a C++ struct type does not necessarily match this; C++ copying @@ -1154,8 +1146,6 @@ public: /// source object is placed in an uninitialized state. PrimitiveCopyKind isNonTrivialToPrimitiveDestructiveMove() const; - bool canPassInRegisters() const; - enum DestructionKind { DK_none, DK_cxx_destructor, Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=327294&r1=327293&r2=327294&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Mar 12 10:05:06 2018 @@ -1105,6 +1105,7 @@ bool ASTNodeImporter::ImportDefinition(R = FromData.HasConstexprNonCopyMoveConstructor; ToData.HasDefaultedDefaultConstructor = FromData.HasDefaultedDefaultConstructor; + ToData.CanPassInRegisters = FromData.CanPassInRegisters; ToData.DefaultedDefaultConstructorIsConstexpr = FromData.DefaultedDefaultConstructorIsConstexpr; ToData.HasConstexprDefaultConstructor Modified: cfe/trunk/lib/AST/Decl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=327294&r1=327293&r2=327294&view=diff ============================================================================== --- cfe/trunk/lib/AST/Decl.cpp (original) +++ cfe/trunk/lib/AST/Decl.cpp Mon Mar 12 10:05:06 2018 @@ -3931,8 +3931,7 @@ RecordDecl::RecordDecl(Kind DK, TagKind HasObjectMember(false), HasVolatileMember(false), LoadedFieldsFromExternalStorage(false), NonTrivialToPrimitiveDefaultInitialize(false), - NonTrivialToPrimitiveCopy(false), NonTrivialToPrimitiveDestroy(false), - CanPassInRegisters(true) { + NonTrivialToPrimitiveCopy(false), NonTrivialToPrimitiveDestroy(false) { assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!"); } Modified: cfe/trunk/lib/AST/DeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=327294&r1=327293&r2=327294&view=diff ============================================================================== --- cfe/trunk/lib/AST/DeclCXX.cpp (original) +++ cfe/trunk/lib/AST/DeclCXX.cpp Mon Mar 12 10:05:06 2018 @@ -93,6 +93,7 @@ CXXRecordDecl::DefinitionData::Definitio DeclaredNonTrivialSpecialMembersForCall(0), HasIrrelevantDestructor(true), HasConstexprNonCopyMoveConstructor(false), HasDefaultedDefaultConstructor(false), + CanPassInRegisters(true), DefaultedDefaultConstructorIsConstexpr(true), HasConstexprDefaultConstructor(false), HasNonLiteralTypeFieldsOrBases(false), ComputedVisibleConversions(false), Modified: cfe/trunk/lib/AST/Type.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=327294&r1=327293&r2=327294&view=diff ============================================================================== --- cfe/trunk/lib/AST/Type.cpp (original) +++ cfe/trunk/lib/AST/Type.cpp Mon Mar 12 10:05:06 2018 @@ -2214,14 +2214,11 @@ QualType::isNonTrivialToPrimitiveDefault if (RT->getDecl()->isNonTrivialToPrimitiveDefaultInitialize()) return PDIK_Struct; - switch (getQualifiers().getObjCLifetime()) { - case Qualifiers::OCL_Strong: + Qualifiers::ObjCLifetime Lifetime = getQualifiers().getObjCLifetime(); + if (Lifetime == Qualifiers::OCL_Strong) return PDIK_ARCStrong; - case Qualifiers::OCL_Weak: - return PDIK_ARCWeak; - default: - return PDIK_Trivial; - } + + return PDIK_Trivial; } QualType::PrimitiveCopyKind QualType::isNonTrivialToPrimitiveCopy() const { @@ -2231,14 +2228,10 @@ QualType::PrimitiveCopyKind QualType::is return PCK_Struct; Qualifiers Qs = getQualifiers(); - switch (Qs.getObjCLifetime()) { - case Qualifiers::OCL_Strong: + if (Qs.getObjCLifetime() == Qualifiers::OCL_Strong) return PCK_ARCStrong; - case Qualifiers::OCL_Weak: - return PCK_ARCWeak; - default: - return Qs.hasVolatile() ? PCK_VolatileTrivial : PCK_Trivial; - } + + return Qs.hasVolatile() ? PCK_VolatileTrivial : PCK_Trivial; } QualType::PrimitiveCopyKind @@ -2246,17 +2239,6 @@ QualType::isNonTrivialToPrimitiveDestruc 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; Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=327294&r1=327293&r2=327294&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original) +++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Mon Mar 12 10:05:06 2018 @@ -1525,9 +1525,6 @@ computeCopyInfoForBlockCapture(const Blo case QualType::PCK_Struct: return std::make_pair(BlockCaptureEntityKind::NonTrivialCStruct, BlockFieldFlags()); - case QualType::PCK_ARCWeak: - // We need to register __weak direct captures with the runtime. - return std::make_pair(BlockCaptureEntityKind::ARCWeak, Flags); case QualType::PCK_ARCStrong: // We need to retain the copied value for __strong direct captures. // If it's a block pointer, we have to copy the block and assign that to @@ -1545,6 +1542,10 @@ computeCopyInfoForBlockCapture(const Blo // Special rules for ARC captures: Qualifiers QS = T.getQualifiers(); + // We need to register __weak direct captures with the runtime. + if (QS.getObjCLifetime() == Qualifiers::OCL_Weak) + return std::make_pair(BlockCaptureEntityKind::ARCWeak, Flags); + // Non-ARC captures of retainable pointers are strong and // therefore require a call to _Block_object_assign. if (!QS.getObjCLifetime() && !LangOpts.ObjCAutoRefCount) Modified: cfe/trunk/lib/CodeGen/CGNonTrivialStruct.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGNonTrivialStruct.cpp?rev=327294&r1=327293&r2=327294&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGNonTrivialStruct.cpp (original) +++ cfe/trunk/lib/CodeGen/CGNonTrivialStruct.cpp Mon Mar 12 10:05:06 2018 @@ -77,8 +77,6 @@ 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: @@ -110,8 +108,6 @@ 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: @@ -145,6 +141,11 @@ template <class Derived> struct StructVi 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"); } @@ -244,13 +245,6 @@ template <class Derived> struct GenFuncN 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); @@ -621,12 +615,6 @@ struct GenDestructor : StructVisitor<Gen *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( @@ -648,12 +636,6 @@ 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) { @@ -696,14 +678,6 @@ struct GenCopyConstructor : GenBinaryFun 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), @@ -726,14 +700,6 @@ struct GenMoveConstructor : GenBinaryFun 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), @@ -754,14 +720,6 @@ struct GenCopyAssignment : GenBinaryFunc 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( @@ -789,13 +747,6 @@ struct GenMoveAssignment : GenBinaryFunc 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( Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=327294&r1=327293&r2=327294&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGObjC.cpp (original) +++ cfe/trunk/lib/CodeGen/CGObjC.cpp Mon Mar 12 10:05:06 2018 @@ -2307,21 +2307,6 @@ void CodeGenFunction::EmitARCCopyWeak(Ad "objc_copyWeak"); } -void CodeGenFunction::emitARCCopyAssignWeak(QualType Ty, Address DstAddr, - Address SrcAddr) { - llvm::Value *Object = EmitARCLoadWeakRetained(SrcAddr); - Object = EmitObjCConsumeObject(Ty, Object); - EmitARCStoreWeak(DstAddr, Object, false); -} - -void CodeGenFunction::emitARCMoveAssignWeak(QualType Ty, Address DstAddr, - Address SrcAddr) { - llvm::Value *Object = EmitARCLoadWeakRetained(SrcAddr); - Object = EmitObjCConsumeObject(Ty, Object); - EmitARCStoreWeak(DstAddr, Object, false); - EmitARCDestroyWeak(SrcAddr); -} - /// Produce the code to do a objc_autoreleasepool_push. /// call i8* \@objc_autoreleasePoolPush(void) llvm::Value *CodeGenFunction::EmitObjCAutoreleasePoolPush() { Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=327294&r1=327293&r2=327294&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original) +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Mon Mar 12 10:05:06 2018 @@ -3548,8 +3548,6 @@ public: llvm::Value *EmitARCLoadWeak(Address addr); llvm::Value *EmitARCLoadWeakRetained(Address addr); llvm::Value *EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored); - void emitARCCopyAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr); - void emitARCMoveAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr); void EmitARCCopyWeak(Address dst, Address src); void EmitARCMoveWeak(Address dst, Address src); llvm::Value *EmitARCRetainAutorelease(QualType type, llvm::Value *value); Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=327294&r1=327293&r2=327294&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original) +++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Mon Mar 12 10:05:06 2018 @@ -140,11 +140,8 @@ bool SwiftABIInfo::isLegalVectorTypeForS static CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI) { const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()); - if (!RD) { - if (!RT->getDecl()->canPassInRegisters()) - return CGCXXABI::RAA_Indirect; + if (!RD) return CGCXXABI::RAA_Default; - } return CXXABI.getRecordArgABI(RD); } @@ -156,20 +153,6 @@ static CGCXXABI::RecordArgABI getRecordA return getRecordArgABI(RT, CXXABI); } -static bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, - const ABIInfo &Info) { - QualType Ty = FI.getReturnType(); - - if (const auto *RT = Ty->getAs<RecordType>()) - if (!isa<CXXRecordDecl>(RT->getDecl()) && - !RT->getDecl()->canPassInRegisters()) { - FI.getReturnInfo() = Info.getNaturalAlignIndirect(Ty); - return true; - } - - return CXXABI.classifyReturnType(FI); -} - /// Pass transparent unions as if they were the type of the first element. Sema /// should ensure that all elements of the union have the same "machine type". static QualType useFirstFieldIfTransparentUnion(QualType Ty) { @@ -1766,7 +1749,7 @@ void X86_32ABIInfo::computeInfo(CGFuncti } else State.FreeRegs = DefaultNumRegisterParameters; - if (!::classifyReturnType(getCXXABI(), FI, *this)) { + if (!getCXXABI().classifyReturnType(FI)) { FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), State); } else if (FI.getReturnInfo().isIndirect()) { // The C++ ABI is not aware of register usage, so we have to check if the @@ -3562,7 +3545,7 @@ void X86_64ABIInfo::computeInfo(CGFuncti unsigned FreeSSERegs = IsRegCall ? 16 : 8; unsigned NeededInt, NeededSSE; - if (!::classifyReturnType(getCXXABI(), FI, *this)) { + if (!getCXXABI().classifyReturnType(FI)) { if (IsRegCall && FI.getReturnType()->getTypePtr()->isRecordType() && !FI.getReturnType()->getTypePtr()->isUnionType()) { FI.getReturnInfo() = @@ -4912,7 +4895,7 @@ private: bool isIllegalVectorType(QualType Ty) const; void computeInfo(CGFunctionInfo &FI) const override { - if (!::classifyReturnType(getCXXABI(), FI, *this)) + if (!getCXXABI().classifyReturnType(FI)) FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); for (auto &it : FI.arguments()) @@ -5643,7 +5626,7 @@ void WindowsARMTargetCodeGenInfo::setTar } void ARMABIInfo::computeInfo(CGFunctionInfo &FI) const { - if (!::classifyReturnType(getCXXABI(), FI, *this)) + if (!getCXXABI().classifyReturnType(FI)) FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), FI.isVariadic()); Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=327294&r1=327293&r2=327294&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Mar 12 10:05:06 2018 @@ -15260,6 +15260,7 @@ void Sema::ActOnFields(Scope *S, SourceL // Get the type for the field. const Type *FDTy = FD->getType().getTypePtr(); + Qualifiers QS = FD->getType().getQualifiers(); if (!FD->isAnonymousStructOrUnion()) { // Remember all fields written by the user. @@ -15400,7 +15401,10 @@ void Sema::ActOnFields(Scope *S, SourceL QualType T = Context.getObjCObjectPointerType(FD->getType()); FD->setType(T); } else if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() && - Record && !ObjCFieldLifetimeErrReported && Record->isUnion()) { + Record && !ObjCFieldLifetimeErrReported && + ((!getLangOpts().CPlusPlus && + QS.getObjCLifetime() == Qualifiers::OCL_Weak) || + Record->isUnion())) { // It's an error in ARC or Weak if a field has lifetime. // We don't want to report this in a system header, though, // so we just make the field unavailable. @@ -15446,8 +15450,6 @@ void Sema::ActOnFields(Scope *S, SourceL Record->setNonTrivialToPrimitiveCopy(); if (FT.isDestructedType()) Record->setNonTrivialToPrimitiveDestroy(); - if (!FT.canPassInRegisters()) - Record->setCanPassInRegisters(false); } if (Record && FD->getType().isVolatileQualified()) Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=327294&r1=327293&r2=327294&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Mon Mar 12 10:05:06 2018 @@ -739,7 +739,6 @@ ASTDeclReader::VisitRecordDeclImpl(Recor RD->setAnonymousStructOrUnion(Record.readInt()); RD->setHasObjectMember(Record.readInt()); RD->setHasVolatileMember(Record.readInt()); - RD->setCanPassInRegisters(Record.readInt()); return Redecl; } @@ -1585,6 +1584,7 @@ void ASTDeclReader::ReadCXXDefinitionDat Data.HasIrrelevantDestructor = Record.readInt(); Data.HasConstexprNonCopyMoveConstructor = Record.readInt(); Data.HasDefaultedDefaultConstructor = Record.readInt(); + Data.CanPassInRegisters = Record.readInt(); Data.DefaultedDefaultConstructorIsConstexpr = Record.readInt(); Data.HasConstexprDefaultConstructor = Record.readInt(); Data.HasNonLiteralTypeFieldsOrBases = Record.readInt(); @@ -1724,6 +1724,7 @@ void ASTDeclReader::MergeDefinitionData( MATCH_FIELD(HasIrrelevantDestructor) OR_FIELD(HasConstexprNonCopyMoveConstructor) OR_FIELD(HasDefaultedDefaultConstructor) + MATCH_FIELD(CanPassInRegisters) MATCH_FIELD(DefaultedDefaultConstructorIsConstexpr) OR_FIELD(HasConstexprDefaultConstructor) MATCH_FIELD(HasNonLiteralTypeFieldsOrBases) Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=327294&r1=327293&r2=327294&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original) +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Mon Mar 12 10:05:06 2018 @@ -6018,6 +6018,7 @@ void ASTRecordWriter::AddCXXDefinitionDa Record->push_back(Data.HasIrrelevantDestructor); Record->push_back(Data.HasConstexprNonCopyMoveConstructor); Record->push_back(Data.HasDefaultedDefaultConstructor); + Record->push_back(Data.CanPassInRegisters); Record->push_back(Data.DefaultedDefaultConstructorIsConstexpr); Record->push_back(Data.HasConstexprDefaultConstructor); Record->push_back(Data.HasNonLiteralTypeFieldsOrBases); Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=327294&r1=327293&r2=327294&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original) +++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Mon Mar 12 10:05:06 2018 @@ -465,7 +465,6 @@ void ASTDeclWriter::VisitRecordDecl(Reco Record.push_back(D->isAnonymousStructOrUnion()); Record.push_back(D->hasObjectMember()); Record.push_back(D->hasVolatileMember()); - Record.push_back(D->canPassInRegisters()); if (D->getDeclContext() == D->getLexicalDeclContext() && !D->hasAttrs() && @@ -1900,7 +1899,6 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // AnonymousStructUnion Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // hasObjectMember Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // hasVolatileMember - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // canPassInRegisters // DC Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalOffset Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // VisibleOffset Modified: cfe/trunk/test/CodeGenObjC/nontrivial-c-struct-exception.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/nontrivial-c-struct-exception.m?rev=327294&r1=327293&r2=327294&view=diff ============================================================================== --- cfe/trunk/test/CodeGenObjC/nontrivial-c-struct-exception.m (original) +++ cfe/trunk/test/CodeGenObjC/nontrivial-c-struct-exception.m Mon Mar 12 10:05:06 2018 @@ -1,18 +1,12 @@ -// RUN: %clang_cc1 -triple arm64-apple-ios11 -fobjc-arc -fblocks -fobjc-runtime=ios-11.0 -fobjc-exceptions -fexceptions -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple arm64-apple-ios11 -fobjc-arc -fblocks -fobjc-runtime=ios-11.0 -fobjc-exceptions -fexceptions -fobjc-arc-exceptions -emit-llvm -o - %s | FileCheck %s // CHECK: %[[STRUCT_STRONG:.*]] = type { i32, i8* } -// CHECK: %[[STRUCT_WEAK:.*]] = type { i32, i8* } typedef struct { int i; id f1; } Strong; -typedef struct { - int i; - __weak id f1; -} Weak; - // CHECK: define void @testStrongException() // CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_STRONG]], align 8 // CHECK: %[[AGG_TMP1:.*]] = alloca %[[STRUCT_STRONG]], align 8 @@ -37,26 +31,3 @@ void calleeStrong(Strong, Strong); void testStrongException(void) { calleeStrong(genStrong(), genStrong()); } - -// CHECK: define void @testWeakException() -// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_WEAK]], align 8 -// CHECK: %[[AGG_TMP1:.*]] = alloca %[[STRUCT_WEAK]], align 8 -// CHECK: call void @genWeak(%[[STRUCT_WEAK]]* sret %[[AGG_TMP]]) -// CHECK: invoke void @genWeak(%[[STRUCT_WEAK]]* sret %[[AGG_TMP1]]) - -// CHECK: call void @calleeWeak(%[[STRUCT_WEAK]]* %[[AGG_TMP]], %[[STRUCT_WEAK]]* %[[AGG_TMP1]]) -// CHECK: ret void - -// CHECK: landingpad { i8*, i32 } -// CHECK: %[[V3:.*]] = bitcast %[[STRUCT_WEAK]]* %[[AGG_TMP]] to i8** -// CHECK: call void @__destructor_8_w8(i8** %[[V3]]) -// CHECK: br label - -// CHECK: resume - -Weak genWeak(void); -void calleeWeak(Weak, Weak); - -void testWeakException(void) { - calleeWeak(genWeak(), genWeak()); -} Removed: cfe/trunk/test/CodeGenObjC/weak-in-c-struct.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/weak-in-c-struct.m?rev=327293&view=auto ============================================================================== --- cfe/trunk/test/CodeGenObjC/weak-in-c-struct.m (original) +++ cfe/trunk/test/CodeGenObjC/weak-in-c-struct.m (removed) @@ -1,193 +0,0 @@ -// RUN: %clang_cc1 -triple arm64-apple-ios11 -fobjc-arc -fblocks -fobjc-runtime=ios-11.0 -emit-llvm -o - %s | FileCheck -check-prefix=ARM64 -check-prefix=COMMON %s -// RUN: %clang_cc1 -triple thumbv7-apple-ios10 -fobjc-arc -fblocks -fobjc-runtime=ios-10.0 -emit-llvm -o - %s | FileCheck -check-prefix=COMMON %s -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.13 -fobjc-arc -fblocks -fobjc-runtime=macosx-10.13.0 -emit-llvm -o - %s | FileCheck -check-prefix=COMMON %s -// RUN: %clang_cc1 -triple i386-apple-macosx10.13.0 -fobjc-arc -fblocks -fobjc-runtime=macosx-fragile-10.13.0 -emit-llvm -o - %s | FileCheck -check-prefix=COMMON %s - -typedef void (^BlockTy)(void); - -// COMMON: %[[STRUCT_WEAK:.*]] = type { i32, i8* } - -typedef struct { - int f0; - __weak id f1; -} Weak; - -Weak getWeak(void); -void calleeWeak(Weak); - -// ARM64: define void @test_constructor_destructor_Weak() -// ARM64: %[[T:.*]] = alloca %[[STRUCT_WEAK]], align 8 -// ARM64: %[[V0:.*]] = bitcast %[[STRUCT_WEAK]]* %[[T]] to i8** -// ARM64: call void @__default_constructor_8_w8(i8** %[[V0]]) -// ARM64: %[[V1:.*]] = bitcast %[[STRUCT_WEAK]]* %[[T]] to i8** -// ARM64: call void @__destructor_8_w8(i8** %[[V1]]) -// ARM64: ret void - -// ARM64: define linkonce_odr hidden void @__default_constructor_8_w8(i8** %[[DST:.*]]) -// ARM64: %[[DST_ADDR:.*]] = alloca i8**, align 8 -// ARM64: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 -// ARM64: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 -// ARM64: %[[V1]] = bitcast i8** %[[V0]] to i8* -// ARM64: %[[V2:.*]] = getelementptr inbounds i8, i8* %[[V1]], i64 8 -// ARM64: %[[V3:.*]] = bitcast i8* %[[V2]] to i8** -// ARM64: %[[V4:.*]] = bitcast i8** %[[V3]] to i8* -// ARM64: call void @llvm.memset.p0i8.i64(i8* align 8 %[[V4]], i8 0, i64 8, i1 false) - -// ARM64: define linkonce_odr hidden void @__destructor_8_w8(i8** %[[DST:.*]]) -// ARM64: %[[DST_ADDR:.*]] = alloca i8**, align 8 -// ARM64: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 -// ARM64: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 -// ARM64: %[[V1:.*]] = bitcast i8** %[[V0]] to i8* -// ARM64: %[[V2:.*]] = getelementptr inbounds i8, i8* %[[V1]], i64 8 -// ARM64: %[[V3:.*]] = bitcast i8* %[[V2]] to i8** -// ARM64: call void @objc_destroyWeak(i8** %[[V3]]) - -void test_constructor_destructor_Weak(void) { - Weak t; -} - -// ARM64: define void @test_copy_constructor_Weak(%[[STRUCT_WEAK]]* %{{.*}}) -// ARM64: call void @__copy_constructor_8_8_t0w4_w8(i8** %{{.*}}, i8** %{{.*}}) -// ARM64: call void @__destructor_8_w8(i8** %{{.*}}) - -// ARM64: define linkonce_odr hidden void @__copy_constructor_8_8_t0w4_w8(i8** %[[DST:.*]], i8** %[[SRC:.*]]) -// ARM64: %[[DST_ADDR:.*]] = alloca i8**, align 8 -// ARM64: %[[SRC_ADDR:.*]] = alloca i8**, align 8 -// ARM64: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 -// ARM64: store i8** %[[SRC]], i8*** %[[SRC_ADDR]], align 8 -// ARM64: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 -// ARM64: %[[V1:.*]] = load i8**, i8*** %[[SRC_ADDR]], align 8 -// ARM64: %[[V2:.*]] = bitcast i8** %[[V0]] to i32* -// ARM64: %[[V3:.*]] = bitcast i8** %[[V1]] to i32* -// ARM64: %[[V4:.*]] = load i32, i32* %[[V3]], align 8 -// ARM64: store i32 %[[V4]], i32* %[[V2]], align 8 -// ARM64: %[[V5:.*]] = bitcast i8** %[[V0]] to i8* -// ARM64: %[[V6:.*]] = getelementptr inbounds i8, i8* %[[V5]], i64 8 -// ARM64: %[[V7:.*]] = bitcast i8* %[[V6]] to i8** -// ARM64: %[[V8:.*]] = bitcast i8** %[[V1]] to i8* -// ARM64: %[[V9:.*]] = getelementptr inbounds i8, i8* %[[V8]], i64 8 -// ARM64: %[[V10:.*]] = bitcast i8* %[[V9]] to i8** -// ARM64: call void @objc_copyWeak(i8** %[[V7]], i8** %[[V10]]) - -void test_copy_constructor_Weak(Weak *s) { - Weak t = *s; -} - -// ARM64: define void @test_copy_assignment_Weak(%[[STRUCT_WEAK]]* %{{.*}}, %[[STRUCT_WEAK]]* %{{.*}}) -// ARM64: call void @__copy_assignment_8_8_t0w4_w8(i8** %{{.*}}, i8** %{{.*}}) - -// ARM64: define linkonce_odr hidden void @__copy_assignment_8_8_t0w4_w8(i8** %[[DST:.*]], i8** %[[SRC:.*]]) -// ARM64: %[[DST_ADDR:.*]] = alloca i8**, align 8 -// ARM64: %[[SRC_ADDR:.*]] = alloca i8**, align 8 -// ARM64: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 -// ARM64: store i8** %[[SRC]], i8*** %[[SRC_ADDR]], align 8 -// ARM64: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 -// ARM64: %[[V1:.*]] = load i8**, i8*** %[[SRC_ADDR]], align 8 -// ARM64: %[[V2:.*]] = bitcast i8** %[[V0]] to i32* -// ARM64: %[[V3:.*]] = bitcast i8** %[[V1]] to i32* -// ARM64: %[[V4:.*]] = load i32, i32* %[[V3]], align 8 -// ARM64: store i32 %[[V4]], i32* %[[V2]], align 8 -// ARM64: %[[V5:.*]] = bitcast i8** %[[V0]] to i8* -// ARM64: %[[V6:.*]] = getelementptr inbounds i8, i8* %[[V5]], i64 8 -// ARM64: %[[V7:.*]] = bitcast i8* %[[V6]] to i8** -// ARM64: %[[V8:.*]] = bitcast i8** %[[V1]] to i8* -// ARM64: %[[V9:.*]] = getelementptr inbounds i8, i8* %[[V8]], i64 8 -// ARM64: %[[V10:.*]] = bitcast i8* %[[V9]] to i8** -// ARM64: %[[V11:.*]] = call i8* @objc_loadWeakRetained(i8** %[[V10]]) -// ARM64: %[[V12:.*]] = call i8* @objc_storeWeak(i8** %[[V7]], i8* %[[V11]]) -// ARM64: call void @objc_release(i8* %[[V11]]) - -void test_copy_assignment_Weak(Weak *d, Weak *s) { - *d = *s; -} - -// ARM64: define internal void @__Block_byref_object_copy_(i8*, i8*) -// ARM64: call void @__move_constructor_8_8_t0w4_w8(i8** %{{.*}}, i8** %{{.*}}) - -// ARM64: define linkonce_odr hidden void @__move_constructor_8_8_t0w4_w8(i8** %[[DST:.*]], i8** %[[SRC:.*]]) -// ARM64: %[[DST_ADDR:.*]] = alloca i8**, align 8 -// ARM64: %[[SRC_ADDR:.*]] = alloca i8**, align 8 -// ARM64: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 -// ARM64: store i8** %[[SRC]], i8*** %[[SRC_ADDR]], align 8 -// ARM64: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 -// ARM64: %[[V1:.*]] = load i8**, i8*** %[[SRC_ADDR]], align 8 -// ARM64: %[[V2:.*]] = bitcast i8** %[[V0]] to i32* -// ARM64: %[[V3:.*]] = bitcast i8** %[[V1]] to i32* -// ARM64: %[[V4:.*]] = load i32, i32* %[[V3]], align 8 -// ARM64: store i32 %[[V4]], i32* %[[V2]], align 8 -// ARM64: %[[V5:.*]] = bitcast i8** %[[V0]] to i8* -// ARM64: %[[V6:.*]] = getelementptr inbounds i8, i8* %[[V5]], i64 8 -// ARM64: %[[V7:.*]] = bitcast i8* %[[V6]] to i8** -// ARM64: %[[V8:.*]] = bitcast i8** %[[V1]] to i8* -// ARM64: %[[V9:.*]] = getelementptr inbounds i8, i8* %[[V8]], i64 8 -// ARM64: %[[V10:.*]] = bitcast i8* %[[V9]] to i8** -// ARM64: call void @objc_moveWeak(i8** %[[V7]], i8** %[[V10]]) - -void test_move_constructor_Weak(void) { - __block Weak t; - BlockTy b = ^{ (void)t; }; -} - -// ARM64: define void @test_move_assignment_Weak(%[[STRUCT_WEAK]]* %{{.*}}) -// ARM64: call void @__move_assignment_8_8_t0w4_w8(i8** %{{.*}}, i8** %{{.*}}) - -// ARM64: define linkonce_odr hidden void @__move_assignment_8_8_t0w4_w8(i8** %[[DST:.*]], i8** %[[SRC:.*]]) -// ARM64: %[[DST_ADDR:.*]] = alloca i8**, align 8 -// ARM64: %[[SRC_ADDR:.*]] = alloca i8**, align 8 -// ARM64: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 -// ARM64: store i8** %[[SRC]], i8*** %[[SRC_ADDR]], align 8 -// ARM64: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 -// ARM64: %[[V1:.*]] = load i8**, i8*** %[[SRC_ADDR]], align 8 -// ARM64: %[[V2:.*]] = bitcast i8** %[[V0]] to i32* -// ARM64: %[[V3:.*]] = bitcast i8** %[[V1]] to i32* -// ARM64: %[[V4:.*]] = load i32, i32* %[[V3]], align 8 -// ARM64: store i32 %[[V4]], i32* %[[V2]], align 8 -// ARM64: %[[V5:.*]] = bitcast i8** %[[V0]] to i8* -// ARM64: %[[V6:.*]] = getelementptr inbounds i8, i8* %[[V5]], i64 8 -// ARM64: %[[V7:.*]] = bitcast i8* %[[V6]] to i8** -// ARM64: %[[V8:.*]] = bitcast i8** %[[V1]] to i8* -// ARM64: %[[V9:.*]] = getelementptr inbounds i8, i8* %[[V8]], i64 8 -// ARM64: %[[V10:.*]] = bitcast i8* %[[V9]] to i8** -// ARM64: %[[V11:.*]] = call i8* @objc_loadWeakRetained(i8** %[[V10]]) -// ARM64: %[[V12:.*]] = call i8* @objc_storeWeak(i8** %[[V7]], i8* %[[V11]]) -// ARM64: call void @objc_destroyWeak(i8** %[[V10]]) -// ARM64: call void @objc_release(i8* %[[V11]]) - -void test_move_assignment_Weak(Weak *p) { - *p = getWeak(); -} - -// COMMON: define void @test_parameter_Weak(%[[STRUCT_WEAK]]* %[[A:.*]]) -// COMMON: %[[V0:.*]] = bitcast %[[STRUCT_WEAK]]* %[[A]] to i8** -// COMMON: call void @__destructor_{{.*}}(i8** %[[V0]]) - -void test_parameter_Weak(Weak a) { -} - -// COMMON: define void @test_argument_Weak(%[[STRUCT_WEAK]]* %[[A:.*]]) -// COMMON: %[[A_ADDR:.*]] = alloca %[[STRUCT_WEAK]]* -// COMMON: %[[AGG_TMP:.*]] = alloca %[[STRUCT_WEAK]] -// COMMON: store %[[STRUCT_WEAK]]* %[[A]], %[[STRUCT_WEAK]]** %[[A_ADDR]] -// COMMON: %[[V0:.*]] = load %[[STRUCT_WEAK]]*, %[[STRUCT_WEAK]]** %[[A_ADDR]] -// COMMON: %[[V1:.*]] = bitcast %[[STRUCT_WEAK]]* %[[AGG_TMP]] to i8** -// COMMON: %[[V2:.*]] = bitcast %[[STRUCT_WEAK]]* %[[V0]] to i8** -// COMMON: call void @__copy_constructor_{{.*}}(i8** %[[V1]], i8** %[[V2]]) -// COMMON: call void @calleeWeak(%[[STRUCT_WEAK]]* %[[AGG_TMP]]) -// COMMON-NEXT: ret - -void test_argument_Weak(Weak *a) { - calleeWeak(*a); -} - -// COMMON: define void @test_return_Weak(%[[STRUCT_WEAK]]* noalias sret %[[AGG_RESULT:.*]], %[[STRUCT_WEAK]]* %[[A:.*]]) -// COMMON: %[[A_ADDR:.*]] = alloca %[[STRUCT_WEAK]]* -// COMMON: store %[[STRUCT_WEAK]]* %[[A]], %[[STRUCT_WEAK]]** %[[A_ADDR]] -// COMMON: %[[V0:.*]] = load %[[STRUCT_WEAK]]*, %[[STRUCT_WEAK]]** %[[A_ADDR]] -// COMMON: %[[V1:.*]] = bitcast %[[STRUCT_WEAK]]* %[[AGG_RESULT]] to i8** -// COMMON: %[[V2:.*]] = bitcast %[[STRUCT_WEAK]]* %[[V0]] to i8** -// COMMON: call void @__copy_constructor_{{.*}}(i8** %[[V1]], i8** %[[V2]]) -// COMMON: ret void - -Weak test_return_Weak(Weak *a) { - return *a; -} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits