Re: r328731 - [ObjC++] Make parameter passing and function return compatible with ObjC

2018-04-03 Thread Richard Smith via cfe-commits
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 Smith  wrote:
>
> 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

2018-04-01 Thread Richard Smith via cfe-commits
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

2018-03-28 Thread Akira Hatanaka via cfe-commits
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