Re: r328731 - [ObjC++] Make parameter passing and function return compatible with ObjC
On 3 April 2018 at 13:07, Akira Hatanaka via cfe-commits < cfe-commits@lists.llvm.org> wrote: > > > On Apr 1, 2018, at 6:00 PM, Richard Smithwrote: > > On 28 March 2018 at 14:13, Akira Hatanaka via cfe-commits lists.llvm.org> wrote: > >> Author: ahatanak >> Date: Wed Mar 28 14:13:14 2018 >> New Revision: 328731 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=328731=rev >> Log: >> [ObjC++] Make parameter passing and function return compatible with ObjC >> >> ObjC and ObjC++ pass non-trivial structs in a way that is incompatible >> with each other. For example: >> >> typedef struct { >> id f0; >> __weak id f1; >> } S; >> >> // this code is compiled in c++. >> extern "C" { >> void foo(S s); >> } >> >> void caller() { >> // the caller passes the parameter indirectly and destructs it. >> foo(S()); >> } >> >> // this function is compiled in c. >> // 'a' is passed directly and is destructed in the callee. >> void foo(S a) { >> } >> >> This patch fixes the incompatibility by passing and returning structs >> with __strong or weak fields using the C ABI in C++ mode. __strong and >> __weak fields in a struct do not cause the struct to be destructed in >> the caller and __strong fields do not cause the struct to be passed >> indirectly. >> >> Also, this patch fixes the microsoft ABI bug mentioned here: >> >> https://reviews.llvm.org/D41039?id=128767#inline-364710 >> >> rdar://problem/38887866 >> >> Differential Revision: https://reviews.llvm.org/D44908 >> >> Added: >> cfe/trunk/test/CodeGenObjCXX/objc-struct-cxx-abi.mm >> - copied, changed from r328730, cfe/trunk/test/CodeGenObjCXX/t >> rivial_abi.mm >> Removed: >> cfe/trunk/test/CodeGenObjCXX/trivial_abi.mm >> Modified: >> cfe/trunk/include/clang/AST/Decl.h >> cfe/trunk/include/clang/AST/DeclCXX.h >> cfe/trunk/include/clang/AST/Type.h >> cfe/trunk/include/clang/Basic/LangOptions.def >> cfe/trunk/include/clang/Basic/LangOptions.h >> cfe/trunk/include/clang/Basic/TargetInfo.h >> cfe/trunk/include/clang/Frontend/CodeGenOptions.def >> cfe/trunk/lib/AST/ASTContext.cpp >> cfe/trunk/lib/AST/Decl.cpp >> cfe/trunk/lib/AST/DeclCXX.cpp >> cfe/trunk/lib/AST/Type.cpp >> cfe/trunk/lib/Basic/TargetInfo.cpp >> cfe/trunk/lib/Basic/Targets/X86.h >> cfe/trunk/lib/CodeGen/CGCall.cpp >> cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp >> cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp >> cfe/trunk/lib/CodeGen/TargetInfo.cpp >> cfe/trunk/lib/Frontend/CompilerInvocation.cpp >> cfe/trunk/lib/Sema/SemaDecl.cpp >> cfe/trunk/lib/Sema/SemaDeclCXX.cpp >> cfe/trunk/lib/Serialization/ASTReaderDecl.cpp >> cfe/trunk/lib/Serialization/ASTWriter.cpp >> cfe/trunk/lib/Serialization/ASTWriterDecl.cpp >> cfe/trunk/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp >> cfe/trunk/test/CodeGenObjCXX/arc-special-member-functions.mm >> cfe/trunk/test/CodeGenObjCXX/property-dot-copy-elision.mm >> >> Modified: cfe/trunk/include/clang/AST/Decl.h >> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/ >> include/clang/AST/Decl.h?rev=328731=328730=328731=diff >> >> == >> --- cfe/trunk/include/clang/AST/Decl.h (original) >> +++ cfe/trunk/include/clang/AST/Decl.h Wed Mar 28 14:13:14 2018 >> @@ -3559,6 +3559,11 @@ class RecordDecl : public TagDecl { >>/// pass an object of this class. >>bool CanPassInRegisters : 1; >> >> + /// Indicates whether this struct is destroyed in the callee. This >> flag is >> + /// meaningless when Microsoft ABI is used since parameters are always >> + /// destroyed in the callee. >> + bool ParamDestroyedInCallee : 1; >> + >> protected: >>RecordDecl(Kind DK, TagKind TK, const ASTContext , DeclContext *DC, >> SourceLocation StartLoc, SourceLocation IdLoc, >> @@ -3654,6 +3659,14 @@ public: >> CanPassInRegisters = CanPass; >>} >> >> + bool isParamDestroyedInCallee() const { >> +return ParamDestroyedInCallee; >> + } >> + >> + void setParamDestroyedInCallee(bool V) { >> +ParamDestroyedInCallee = V; >> + } >> + >>/// \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=328731=328730=328731=diff >> >> == >> --- cfe/trunk/include/clang/AST/DeclCXX.h (original) >> +++ cfe/trunk/include/clang/AST/DeclCXX.h Wed Mar 28 14:13:14 2018 >> @@ -1468,13 +1468,6 @@ public: >> return data().HasIrrelevantDestructor; >>} >> >> - /// 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". >> - bool
Re: r328731 - [ObjC++] Make parameter passing and function return compatible with ObjC
On 28 March 2018 at 14:13, Akira Hatanaka via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Author: ahatanak > Date: Wed Mar 28 14:13:14 2018 > New Revision: 328731 > > URL: http://llvm.org/viewvc/llvm-project?rev=328731=rev > Log: > [ObjC++] Make parameter passing and function return compatible with ObjC > > ObjC and ObjC++ pass non-trivial structs in a way that is incompatible > with each other. For example: > > typedef struct { > id f0; > __weak id f1; > } S; > > // this code is compiled in c++. > extern "C" { > void foo(S s); > } > > void caller() { > // the caller passes the parameter indirectly and destructs it. > foo(S()); > } > > // this function is compiled in c. > // 'a' is passed directly and is destructed in the callee. > void foo(S a) { > } > > This patch fixes the incompatibility by passing and returning structs > with __strong or weak fields using the C ABI in C++ mode. __strong and > __weak fields in a struct do not cause the struct to be destructed in > the caller and __strong fields do not cause the struct to be passed > indirectly. > > Also, this patch fixes the microsoft ABI bug mentioned here: > > https://reviews.llvm.org/D41039?id=128767#inline-364710 > > rdar://problem/38887866 > > Differential Revision: https://reviews.llvm.org/D44908 > > Added: > cfe/trunk/test/CodeGenObjCXX/objc-struct-cxx-abi.mm > - copied, changed from r328730, cfe/trunk/test/CodeGenObjCXX/t > rivial_abi.mm > Removed: > cfe/trunk/test/CodeGenObjCXX/trivial_abi.mm > Modified: > cfe/trunk/include/clang/AST/Decl.h > cfe/trunk/include/clang/AST/DeclCXX.h > cfe/trunk/include/clang/AST/Type.h > cfe/trunk/include/clang/Basic/LangOptions.def > cfe/trunk/include/clang/Basic/LangOptions.h > cfe/trunk/include/clang/Basic/TargetInfo.h > cfe/trunk/include/clang/Frontend/CodeGenOptions.def > cfe/trunk/lib/AST/ASTContext.cpp > cfe/trunk/lib/AST/Decl.cpp > cfe/trunk/lib/AST/DeclCXX.cpp > cfe/trunk/lib/AST/Type.cpp > cfe/trunk/lib/Basic/TargetInfo.cpp > cfe/trunk/lib/Basic/Targets/X86.h > cfe/trunk/lib/CodeGen/CGCall.cpp > cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp > cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp > cfe/trunk/lib/CodeGen/TargetInfo.cpp > cfe/trunk/lib/Frontend/CompilerInvocation.cpp > cfe/trunk/lib/Sema/SemaDecl.cpp > cfe/trunk/lib/Sema/SemaDeclCXX.cpp > cfe/trunk/lib/Serialization/ASTReaderDecl.cpp > cfe/trunk/lib/Serialization/ASTWriter.cpp > cfe/trunk/lib/Serialization/ASTWriterDecl.cpp > cfe/trunk/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp > cfe/trunk/test/CodeGenObjCXX/arc-special-member-functions.mm > cfe/trunk/test/CodeGenObjCXX/property-dot-copy-elision.mm > > Modified: cfe/trunk/include/clang/AST/Decl.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/ > clang/AST/Decl.h?rev=328731=328730=328731=diff > > == > --- cfe/trunk/include/clang/AST/Decl.h (original) > +++ cfe/trunk/include/clang/AST/Decl.h Wed Mar 28 14:13:14 2018 > @@ -3559,6 +3559,11 @@ class RecordDecl : public TagDecl { >/// pass an object of this class. >bool CanPassInRegisters : 1; > > + /// Indicates whether this struct is destroyed in the callee. This flag > is > + /// meaningless when Microsoft ABI is used since parameters are always > + /// destroyed in the callee. > + bool ParamDestroyedInCallee : 1; > + > protected: >RecordDecl(Kind DK, TagKind TK, const ASTContext , DeclContext *DC, > SourceLocation StartLoc, SourceLocation IdLoc, > @@ -3654,6 +3659,14 @@ public: > CanPassInRegisters = CanPass; >} > > + bool isParamDestroyedInCallee() const { > +return ParamDestroyedInCallee; > + } > + > + void setParamDestroyedInCallee(bool V) { > +ParamDestroyedInCallee = V; > + } > + >/// \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=328731=328730=328731=diff > > == > --- cfe/trunk/include/clang/AST/DeclCXX.h (original) > +++ cfe/trunk/include/clang/AST/DeclCXX.h Wed Mar 28 14:13:14 2018 > @@ -1468,13 +1468,6 @@ public: > return data().HasIrrelevantDestructor; >} > > - /// 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". > - bool hasTrivialABIOverride() const { > -return canPassInRegisters() && hasNonTrivialDestructor(); > - } > - >/// \brief Determine whether this class has a non-literal or/ volatile > type >/// non-static data member or base class. >bool hasNonLiteralTypeFieldsOrBases() const { > > Modified:
r328731 - [ObjC++] Make parameter passing and function return compatible with ObjC
Author: ahatanak Date: Wed Mar 28 14:13:14 2018 New Revision: 328731 URL: http://llvm.org/viewvc/llvm-project?rev=328731=rev Log: [ObjC++] Make parameter passing and function return compatible with ObjC ObjC and ObjC++ pass non-trivial structs in a way that is incompatible with each other. For example: typedef struct { id f0; __weak id f1; } S; // this code is compiled in c++. extern "C" { void foo(S s); } void caller() { // the caller passes the parameter indirectly and destructs it. foo(S()); } // this function is compiled in c. // 'a' is passed directly and is destructed in the callee. void foo(S a) { } This patch fixes the incompatibility by passing and returning structs with __strong or weak fields using the C ABI in C++ mode. __strong and __weak fields in a struct do not cause the struct to be destructed in the caller and __strong fields do not cause the struct to be passed indirectly. Also, this patch fixes the microsoft ABI bug mentioned here: https://reviews.llvm.org/D41039?id=128767#inline-364710 rdar://problem/38887866 Differential Revision: https://reviews.llvm.org/D44908 Added: cfe/trunk/test/CodeGenObjCXX/objc-struct-cxx-abi.mm - copied, changed from r328730, cfe/trunk/test/CodeGenObjCXX/trivial_abi.mm Removed: cfe/trunk/test/CodeGenObjCXX/trivial_abi.mm Modified: cfe/trunk/include/clang/AST/Decl.h cfe/trunk/include/clang/AST/DeclCXX.h cfe/trunk/include/clang/AST/Type.h cfe/trunk/include/clang/Basic/LangOptions.def cfe/trunk/include/clang/Basic/LangOptions.h cfe/trunk/include/clang/Basic/TargetInfo.h cfe/trunk/include/clang/Frontend/CodeGenOptions.def cfe/trunk/lib/AST/ASTContext.cpp cfe/trunk/lib/AST/Decl.cpp cfe/trunk/lib/AST/DeclCXX.cpp cfe/trunk/lib/AST/Type.cpp cfe/trunk/lib/Basic/TargetInfo.cpp cfe/trunk/lib/Basic/Targets/X86.h cfe/trunk/lib/CodeGen/CGCall.cpp cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp cfe/trunk/lib/CodeGen/TargetInfo.cpp cfe/trunk/lib/Frontend/CompilerInvocation.cpp cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Sema/SemaDeclCXX.cpp cfe/trunk/lib/Serialization/ASTReaderDecl.cpp cfe/trunk/lib/Serialization/ASTWriter.cpp cfe/trunk/lib/Serialization/ASTWriterDecl.cpp cfe/trunk/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp cfe/trunk/test/CodeGenObjCXX/arc-special-member-functions.mm cfe/trunk/test/CodeGenObjCXX/property-dot-copy-elision.mm Modified: cfe/trunk/include/clang/AST/Decl.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=328731=328730=328731=diff == --- cfe/trunk/include/clang/AST/Decl.h (original) +++ cfe/trunk/include/clang/AST/Decl.h Wed Mar 28 14:13:14 2018 @@ -3559,6 +3559,11 @@ class RecordDecl : public TagDecl { /// pass an object of this class. bool CanPassInRegisters : 1; + /// Indicates whether this struct is destroyed in the callee. This flag is + /// meaningless when Microsoft ABI is used since parameters are always + /// destroyed in the callee. + bool ParamDestroyedInCallee : 1; + protected: RecordDecl(Kind DK, TagKind TK, const ASTContext , DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, @@ -3654,6 +3659,14 @@ public: CanPassInRegisters = CanPass; } + bool isParamDestroyedInCallee() const { +return ParamDestroyedInCallee; + } + + void setParamDestroyedInCallee(bool V) { +ParamDestroyedInCallee = V; + } + /// \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=328731=328730=328731=diff == --- cfe/trunk/include/clang/AST/DeclCXX.h (original) +++ cfe/trunk/include/clang/AST/DeclCXX.h Wed Mar 28 14:13:14 2018 @@ -1468,13 +1468,6 @@ public: return data().HasIrrelevantDestructor; } - /// 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". - bool hasTrivialABIOverride() const { -return canPassInRegisters() && hasNonTrivialDestructor(); - } - /// \brief Determine whether this class has a non-literal or/ volatile type /// non-static data member or base class. bool hasNonLiteralTypeFieldsOrBases() const { Modified: cfe/trunk/include/clang/AST/Type.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=328731=328730=328731=diff == --- cfe/trunk/include/clang/AST/Type.h (original) +++ cfe/trunk/include/clang/AST/Type.h Wed Mar 28 14:13:14 2018