<html><head><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Apr 1, 2018, at 6:00 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk" class="">richard@metafoo.co.uk</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><div class="gmail_extra"><div class="gmail_quote">On 28 March 2018 at 14:13, Akira Hatanaka via cfe-commits<span class="Apple-converted-space"> </span><span dir="ltr" class=""><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank" class="">cfe-commits@lists.llvm.org</a>></span><span class="Apple-converted-space"> </span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;">Author: ahatanak<br class="">Date: Wed Mar 28 14:13:14 2018<br class="">New Revision: 328731<br class=""><br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project?rev=328731&view=rev" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project?rev=328731&view=rev</a><br class="">Log:<br class="">[ObjC++] Make parameter passing and function return compatible with ObjC<br class=""><br class="">ObjC and ObjC++ pass non-trivial structs in a way that is incompatible<br class="">with each other. For example:<br class=""><br class="">typedef struct {<br class=""> <span class="Apple-converted-space"> </span>id f0;<br class=""> <span class="Apple-converted-space"> </span>__weak id f1;<br class="">} S;<br class=""><br class="">// this code is compiled in c++.<br class="">extern "C" {<br class=""> <span class="Apple-converted-space"> </span>void foo(S s);<br class="">}<br class=""><br class="">void caller() {<br class=""> <span class="Apple-converted-space"> </span>// the caller passes the parameter indirectly and destructs it.<br class=""> <span class="Apple-converted-space"> </span>foo(S());<br class="">}<br class=""><br class="">// this function is compiled in c.<br class="">// 'a' is passed directly and is destructed in the callee.<br class="">void foo(S a) {<br class="">}<br class=""><br class="">This patch fixes the incompatibility by passing and returning structs<br class="">with __strong or weak fields using the C ABI in C++ mode. __strong and<br class="">__weak fields in a struct do not cause the struct to be destructed in<br class="">the caller and __strong fields do not cause the struct to be passed<br class="">indirectly.<br class=""><br class="">Also, this patch fixes the microsoft ABI bug mentioned here:<br class=""><br class=""><a href="https://reviews.llvm.org/D41039?id=128767#inline-364710" rel="noreferrer" target="_blank" class="">https://reviews.llvm.org/<wbr class="">D41039?id=128767#inline-364710</a><br class=""><br class=""><a href="rdar://problem/38887866" class="">rdar://problem/38887866</a><br class=""><br class="">Differential Revision:<span class="Apple-converted-space"> </span><a href="https://reviews.llvm.org/D44908" rel="noreferrer" target="_blank" class="">https://reviews.llvm.org/<wbr class="">D44908</a><br class=""><br class="">Added:<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/test/CodeGenObjCXX/<a href="http://objc-struct-cxx-abi.mm/" rel="noreferrer" target="_blank" class="">o<wbr class="">bjc-struct-cxx-abi.mm</a><br class="">     <span class="Apple-converted-space"> </span>- copied, changed from r328730, cfe/trunk/test/CodeGenObjCXX/<a href="http://trivial_abi.mm/" rel="noreferrer" target="_blank" class="">t<wbr class="">rivial_abi.mm</a><br class="">Removed:<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/test/CodeGenObjCXX/<a href="http://trivial_abi.mm/" rel="noreferrer" target="_blank" class="">t<wbr class="">rivial_abi.mm</a><br class="">Modified:<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/include/clang/AST/<wbr class="">Decl.h<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/include/clang/AST/<wbr class="">DeclCXX.h<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/include/clang/AST/<wbr class="">Type.h<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/include/clang/Basic/<wbr class="">LangOptions.def<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/include/clang/Basic/<wbr class="">LangOptions.h<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/include/clang/Basic/<wbr class="">TargetInfo.h<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/include/clang/<wbr class="">Frontend/CodeGenOptions.def<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/lib/AST/ASTContext.<wbr class="">cpp<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/lib/AST/Decl.cpp<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/lib/AST/DeclCXX.cpp<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/lib/AST/Type.cpp<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/lib/Basic/<wbr class="">TargetInfo.cpp<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/lib/Basic/Targets/<wbr class="">X86.h<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/lib/CodeGen/CGCall.<wbr class="">cpp<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/lib/CodeGen/<wbr class="">ItaniumCXXABI.cpp<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/lib/CodeGen/<wbr class="">MicrosoftCXXABI.cpp<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/lib/CodeGen/<wbr class="">TargetInfo.cpp<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/lib/Frontend/<wbr class="">CompilerInvocation.cpp<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/lib/Sema/SemaDecl.<wbr class="">cpp<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/lib/Sema/<wbr class="">SemaDeclCXX.cpp<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/lib/Serialization/<wbr class="">ASTReaderDecl.cpp<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/lib/Serialization/<wbr class="">ASTWriter.cpp<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/lib/Serialization/<wbr class="">ASTWriterDecl.cpp<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/test/CodeGenCXX/<wbr class="">microsoft-abi-sret-and-byval.<wbr class="">cpp<br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/test/CodeGenObjCXX/<a href="http://arc-special-member-functions.mm/" rel="noreferrer" target="_blank" class="">a<wbr class="">rc-special-member-functions.mm</a><br class="">   <span class="Apple-converted-space"> </span>cfe/trunk/test/CodeGenObjCXX/<a href="http://property-dot-copy-elision.mm/" rel="noreferrer" target="_blank" class="">p<wbr class="">roperty-dot-copy-elision.mm</a><br class=""><br class="">Modified: cfe/trunk/include/clang/AST/<wbr class="">Decl.h<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/include/<wbr class="">clang/AST/Decl.h?rev=328731&<wbr class="">r1=328730&r2=328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/include/clang/AST/<wbr class="">Decl.h (original)<br class="">+++ cfe/trunk/include/clang/AST/<wbr class="">Decl.h Wed Mar 28 14:13:14 2018<br class="">@@ -3559,6 +3559,11 @@ class RecordDecl : public TagDecl {<br class="">   /// pass an object of this class.<br class="">   bool CanPassInRegisters : 1;<br class=""><br class="">+  /// Indicates whether this struct is destroyed in the callee. This flag is<br class="">+  /// meaningless when Microsoft ABI is used since parameters are always<br class="">+  /// destroyed in the callee.<br class="">+  bool ParamDestroyedInCallee : 1;<br class="">+<br class=""> protected:<br class="">   RecordDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,<br class="">             <span class="Apple-converted-space"> </span>SourceLocation StartLoc, SourceLocation IdLoc,<br class="">@@ -3654,6 +3659,14 @@ public:<br class="">     CanPassInRegisters = CanPass;<br class="">   }<br class=""><br class="">+  bool isParamDestroyedInCallee() const {<br class="">+    return ParamDestroyedInCallee;<br class="">+  }<br class="">+<br class="">+  void setParamDestroyedInCallee(bool V) {<br class="">+    ParamDestroyedInCallee = V;<br class="">+  }<br class="">+<br class="">   /// \brief Determines whether this declaration represents the<br class="">   /// injected class name.<br class="">   ///<br class=""><br class="">Modified: cfe/trunk/include/clang/AST/<wbr class="">DeclCXX.h<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/include/<wbr class="">clang/AST/DeclCXX.h?rev=<wbr class="">328731&r1=328730&r2=328731&<wbr class="">view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/include/clang/AST/<wbr class="">DeclCXX.h (original)<br class="">+++ cfe/trunk/include/clang/AST/<wbr class="">DeclCXX.h Wed Mar 28 14:13:14 2018<br class="">@@ -1468,13 +1468,6 @@ public:<br class="">     return data().<wbr class="">HasIrrelevantDestructor;<br class="">   }<br class=""><br class="">-  /// Determine whether the triviality for the purpose of calls for this class<br class="">-  /// is overridden to be trivial because this class or the type of one of its<br class="">-  /// subobjects has attribute "trivial_abi".<br class="">-  bool hasTrivialABIOverride() const {<br class="">-    return canPassInRegisters() && hasNonTrivialDestructor();<br class="">-  }<br class="">-<br class="">   /// \brief Determine whether this class has a non-literal or/ volatile type<br class="">   /// non-static data member or base class.<br class="">   bool hasNonLiteralTypeFieldsOrBases<wbr class="">() const {<br class=""><br class="">Modified: cfe/trunk/include/clang/AST/<wbr class="">Type.h<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/include/<wbr class="">clang/AST/Type.h?rev=328731&<wbr class="">r1=328730&r2=328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/include/clang/AST/<wbr class="">Type.h (original)<br class="">+++ cfe/trunk/include/clang/AST/<wbr class="">Type.h Wed Mar 28 14:13:14 2018<br class="">@@ -808,11 +808,6 @@ public:<br class="">   /// Return true if this is a trivially copyable type (C++0x [basic.types]p9)<br class="">   bool isTriviallyCopyableType(const ASTContext &Context) const;<br class=""><br class="">-  /// Determine whether this is a class whose triviality for the purpose of<br class="">-  /// calls is overridden to be trivial because the class or the type of one of<br class="">-  /// its subobjects has attribute "trivial_abi".<br class="">-  bool hasTrivialABIOverride() const;<br class="">-<br class="">   // Don't promise in the API that anything besides 'const' can be<br class="">   // easily added.<br class=""><br class=""><br class="">Modified: cfe/trunk/include/clang/Basic/<wbr class="">LangOptions.def<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/LangOptions.def?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/include/<wbr class="">clang/Basic/LangOptions.def?<wbr class="">rev=328731&r1=328730&r2=<wbr class="">328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/include/clang/Basic/<wbr class="">LangOptions.def (original)<br class="">+++ cfe/trunk/include/clang/Basic/<wbr class="">LangOptions.def Wed Mar 28 14:13:14 2018<br class="">@@ -284,6 +284,10 @@ LANGOPT(<wbr class="">XRayAlwaysEmitCustomEvents, 1, 0<br class=""> BENIGN_LANGOPT(<wbr class="">AllowEditorPlaceholders, 1, 0,<br class="">               <span class="Apple-converted-space"> </span>"allow editor placeholders in source")<br class=""><br class="">+ENUM_LANGOPT(ClangABICompat, ClangABI, 4, ClangABI::Latest,<br class="">+             "version of Clang that we should attempt to be ABI-compatible "<br class="">+             "with")<br class="">+<br class=""> #undef LANGOPT<br class=""> #undef COMPATIBLE_LANGOPT<br class=""> #undef BENIGN_LANGOPT<br class=""><br class="">Modified: cfe/trunk/include/clang/Basic/<wbr class="">LangOptions.h<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/LangOptions.h?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/include/<wbr class="">clang/Basic/LangOptions.h?rev=<wbr class="">328731&r1=328730&r2=328731&<wbr class="">view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/include/clang/Basic/<wbr class="">LangOptions.h (original)<br class="">+++ cfe/trunk/include/clang/Basic/<wbr class="">LangOptions.h Wed Mar 28 14:13:14 2018<br class="">@@ -102,6 +102,23 @@ public:<br class="">     MSVC2015 = 19<br class="">   };<br class=""><br class="">+  /// Clang versions with different platform ABI conformance.<br class="">+  enum class ClangABI {<br class="">+    /// Attempt to be ABI-compatible with code generated by Clang 3.8.x<br class="">+    /// (SVN r257626). This causes <1 x long long> to be passed in an<br class="">+    /// integer register instead of an SSE register on x64_64.<br class="">+    Ver3_8,<br class="">+<br class="">+    /// Attempt to be ABI-compatible with code generated by Clang 4.0.x<br class="">+    /// (SVN r291814). This causes move operations to be ignored when<br class="">+    /// determining whether a class type can be passed or returned directly.<br class="">+    Ver4,<br class="">+<br class="">+    /// Conform to the underlying platform's C and C++ ABIs as closely<br class="">+    /// as we can.<br class="">+    Latest<br class="">+  };<br class="">+<br class="">   enum FPContractModeKind {<br class="">     // Form fused FP ops only where result will not be affected.<br class="">     FPC_Off,<br class=""><br class="">Modified: cfe/trunk/include/clang/Basic/<wbr class="">TargetInfo.h<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TargetInfo.h?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/include/<wbr class="">clang/Basic/TargetInfo.h?rev=<wbr class="">328731&r1=328730&r2=328731&<wbr class="">view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/include/clang/Basic/<wbr class="">TargetInfo.h (original)<br class="">+++ cfe/trunk/include/clang/Basic/<wbr class="">TargetInfo.h Wed Mar 28 14:13:14 2018<br class="">@@ -1053,6 +1053,14 @@ public:<br class="">     }<br class="">   }<br class=""><br class="">+  enum CallingConvKind {<br class="">+    CCK_Default,<br class="">+    CCK_ClangABI4OrPS4,<br class="">+    CCK_MicrosoftX86_64<br class="">+  };<br class="">+<br class="">+  virtual CallingConvKind getCallingConvKind(bool ClangABICompat4) const;<br class="">+<br class="">   /// Controls if __builtin_longjmp / __builtin_setjmp can be lowered to<br class="">   /// llvm.eh.sjlj.longjmp / llvm.eh.sjlj.setjmp.<br class="">   virtual bool hasSjLjLowering() const {<br class=""><br class="">Modified: cfe/trunk/include/clang/<wbr class="">Frontend/CodeGenOptions.def<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CodeGenOptions.def?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/include/<wbr class="">clang/Frontend/CodeGenOptions.<wbr class="">def?rev=328731&r1=328730&r2=<wbr class="">328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/include/clang/<wbr class="">Frontend/CodeGenOptions.def (original)<br class="">+++ cfe/trunk/include/clang/<wbr class="">Frontend/CodeGenOptions.def Wed Mar 28 14:13:14 2018<br class="">@@ -138,9 +138,6 @@ ENUM_CODEGENOPT(<wbr class="">ObjCDispatchMethod, ObjC<br class=""> CODEGENOPT(<wbr class="">OmitLeafFramePointer , 1, 0) ///< Set when -momit-leaf-frame-pointer is<br class="">                                         ///< enabled.<br class=""><br class="">-/// A version of Clang that we should attempt to be ABI-compatible with.<br class="">-ENUM_CODEGENOPT(<wbr class="">ClangABICompat, ClangABI, 4, ClangABI::Latest)<br class="">-<br class=""> VALUE_CODEGENOPT(<wbr class="">OptimizationLevel, 2, 0) ///< The -O[0-3] option specified.<br class=""> VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified.<br class=""><br class=""><br class="">Modified: cfe/trunk/lib/AST/ASTContext.<wbr class="">cpp<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/AST/<wbr class="">ASTContext.cpp?rev=328731&r1=<wbr class="">328730&r2=328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/lib/AST/ASTContext.<wbr class="">cpp (original)<br class="">+++ cfe/trunk/lib/AST/ASTContext.<wbr class="">cpp Wed Mar 28 14:13:14 2018<br class="">@@ -2643,9 +2643,11 @@ void ASTContext::<wbr class="">adjustExceptionSpec(<br class=""> }<br class=""><br class=""> bool ASTContext::<wbr class="">isParamDestroyedInCallee(<wbr class="">QualType T) const {<br class="">-  return getTargetInfo().getCXXABI().<wbr class="">areArgsDestroyedLeftToRightInC<wbr class="">allee() ||<br class="">-         T.hasTrivialABIOverride() ||<br class="">-         T.isDestructedType() == QualType::DK_nontrivial_c_<wbr class="">struct;<br class="">+  if (getTargetInfo().getCXXABI().<wbr class="">areArgsDestroyedLeftToRightInC<wbr class="">allee())<br class="">+    return true;<br class="">+  if (const auto *RT = T->getBaseElementTypeUnsafe()-<wbr class="">>getAs<RecordType>())<br class="">+    return RT->getDecl()-><wbr class="">isParamDestroyedInCallee();<br class="">+  return false;<br class=""> }<br class=""><br class=""> /// getComplexType - Return the uniqued reference to the type for a complex<br class=""><br class="">Modified: cfe/trunk/lib/AST/Decl.cpp<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/AST/<wbr class="">Decl.cpp?rev=328731&r1=328730&<wbr class="">r2=328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/lib/AST/Decl.cpp (original)<br class="">+++ cfe/trunk/lib/AST/Decl.cpp Wed Mar 28 14:13:14 2018<br class="">@@ -3951,7 +3951,7 @@ RecordDecl::RecordDecl(Kind DK, TagKind<br class="">       LoadedFieldsFromExternalStorag<wbr class="">e(false),<br class="">       NonTrivialToPrimitiveDefaultIn<wbr class="">itialize(false),<br class="">       NonTrivialToPrimitiveCopy(<wbr class="">false), NonTrivialToPrimitiveDestroy(<wbr class="">false),<br class="">-      CanPassInRegisters(true) {<br class="">+      CanPassInRegisters(true), ParamDestroyedInCallee(false) {<br class="">   assert(classof(static_cast<<wbr class="">Decl*>(this)) && "Invalid Kind!");<br class=""> }<br class=""><br class=""><br class="">Modified: cfe/trunk/lib/AST/DeclCXX.cpp<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/AST/<wbr class="">DeclCXX.cpp?rev=328731&r1=<wbr class="">328730&r2=328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/lib/AST/DeclCXX.cpp (original)<br class="">+++ cfe/trunk/lib/AST/DeclCXX.cpp Wed Mar 28 14:13:14 2018<br class="">@@ -801,7 +801,17 @@ void CXXRecordDecl::addedMember(<wbr class="">Decl *D)<br class="">         struct DefinitionData &Data = data();<br class="">         Data.PlainOldData = false;<br class="">         Data.HasTrivialSpecialMembers = 0;<br class="">-        Data.<wbr class="">HasTrivialSpecialMembersForCal<wbr class="">l = 0;<br class="">+<br class="">+        // __strong or __weak fields do not make special functions non-trivial<br class="">+        // for the purpose of calls.<br class="">+        Qualifiers::ObjCLifetime LT = T.getQualifiers().<wbr class="">getObjCLifetime();<br class="">+        if (LT != Qualifiers::OCL_Strong && LT != Qualifiers::OCL_Weak)<br class="">+          data().<wbr class="">HasTrivialSpecialMembersForCal<wbr class="">l = 0;<br class="">+<br class="">+        // Structs with __weak fields should never be passed directly.<br class="">+        if (LT == Qualifiers::OCL_Weak)<br class="">+          setCanPassInRegisters(false);<br class="">+<br class="">         Data.HasIrrelevantDestructor = false;<br class="">       } else if (!Context.getLangOpts().<wbr class="">ObjCAutoRefCount) {<br class="">         setHasObjectMember(true);<br class=""><br class="">Modified: cfe/trunk/lib/AST/Type.cpp<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/AST/<wbr class="">Type.cpp?rev=328731&r1=328730&<wbr class="">r2=328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/lib/AST/Type.cpp (original)<br class="">+++ cfe/trunk/lib/AST/Type.cpp Wed Mar 28 14:13:14 2018<br class="">@@ -2195,12 +2195,6 @@ bool QualType::<wbr class="">isTriviallyCopyableType(c<br class="">   return false;<br class=""> }<br class=""><br class="">-bool QualType::<wbr class="">hasTrivialABIOverride() const {<br class="">-  if (const auto *RD = getTypePtr()-><wbr class="">getAsCXXRecordDecl())<br class="">-    return RD->hasTrivialABIOverride();<br class="">-  return false;<br class="">-}<br class="">-<br class=""> bool QualType::<wbr class="">isNonWeakInMRRWithObjCWeak(<wbr class="">const ASTContext &Context) const {<br class="">   return !Context.getLangOpts().<wbr class="">ObjCAutoRefCount &&<br class="">         <span class="Apple-converted-space"> </span>Context.getLangOpts().ObjCWeak &&<br class=""><br class="">Modified: cfe/trunk/lib/Basic/<wbr class="">TargetInfo.cpp<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/TargetInfo.cpp?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/Basic/<wbr class="">TargetInfo.cpp?rev=328731&r1=<wbr class="">328730&r2=328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/lib/Basic/<wbr class="">TargetInfo.cpp (original)<br class="">+++ cfe/trunk/lib/Basic/<wbr class="">TargetInfo.cpp Wed Mar 28 14:13:14 2018<br class="">@@ -357,6 +357,14 @@ bool TargetInfo::initFeatureMap(<br class="">   return true;<br class=""> }<br class=""><br class="">+TargetInfo::CallingConvKind<br class="">+TargetInfo::<wbr class="">getCallingConvKind(bool ClangABICompat4) const {<br class="">+  if (getCXXABI() != TargetCXXABI::Microsoft &&<br class="">+      (ClangABICompat4 || getTriple().getOS() == llvm::Triple::PS4))<br class="">+    return CCK_ClangABI4OrPS4;<br class="">+  return CCK_Default;<br class="">+}<br class="">+<br class=""> LangAS TargetInfo::<wbr class="">getOpenCLTypeAddrSpace(<wbr class="">OpenCLTypeKind TK) const {<br class="">   switch (TK) {<br class="">   case OCLTK_Image:<br class=""><br class="">Modified: cfe/trunk/lib/Basic/Targets/<wbr class="">X86.h<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets/X86.h?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/Basic/<wbr class="">Targets/X86.h?rev=328731&r1=<wbr class="">328730&r2=328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/lib/Basic/Targets/<wbr class="">X86.h (original)<br class="">+++ cfe/trunk/lib/Basic/Targets/<wbr class="">X86.h Wed Mar 28 14:13:14 2018<br class="">@@ -728,6 +728,11 @@ public:<br class="">     Builder.defineMacro("_M_X64", "100");<br class="">     Builder.defineMacro("_M_AMD64"<wbr class="">, "100");<br class="">   }<br class="">+<br class="">+  TargetInfo::CallingConvKind<br class="">+  getCallingConvKind(bool ClangABICompat4) const override {<br class="">+    return CCK_MicrosoftX86_64;<br class="">+  }<br class=""> };<br class=""><br class=""> // x86-64 MinGW target<br class=""><br class="">Modified: cfe/trunk/lib/CodeGen/CGCall.<wbr class="">cpp<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/CodeGen/<wbr class="">CGCall.cpp?rev=328731&r1=<wbr class="">328730&r2=328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/lib/CodeGen/CGCall.<wbr class="">cpp (original)<br class="">+++ cfe/trunk/lib/CodeGen/CGCall.<wbr class="">cpp Wed Mar 28 14:13:14 2018<br class="">@@ -3540,24 +3540,13 @@ void CodeGenFunction::EmitCallArg(<wbr class="">CallAr<br class="">     else<br class="">       Slot = CreateAggTemp(type, "agg.tmp");<br class=""><br class="">-    bool DestroyedInCallee = true, NeedsEHCleanup = true;<br class="">-    if (const auto *RD = type->getAsCXXRecordDecl()) {<br class="">-      DestroyedInCallee =<br class="">-          RD && RD->hasNonTrivialDestructor() &&<br class="">-          (CGM.getCXXABI().<wbr class="">getRecordArgABI(RD) != CGCXXABI::RAA_Default ||<br class="">-           RD->hasTrivialABIOverride());<br class="">-    } else {<br class="">-      NeedsEHCleanup = needsEHCleanup(type.<wbr class="">isDestructedType());<br class="">-    }<br class="">-<br class="">-    if (DestroyedInCallee)<br class="">-      Slot.setExternallyDestructed()<wbr class="">;<br class="">+    Slot.setExternallyDestructed()<wbr class="">;<br class=""><br class="">     EmitAggExpr(E, Slot);<br class="">     RValue RV = Slot.asRValue();<br class="">     args.add(RV, type);<br class=""><br class="">-    if (DestroyedInCallee && NeedsEHCleanup) {<br class="">+    if (type->getAsCXXRecordDecl() || needsEHCleanup(type.<wbr class="">isDestructedType())) {<br class="">       // Create a no-op GEP between the placeholder and the cleanup so we can<br class="">       // RAUW it successfully.  It also serves as a marker of the first<br class="">       // instruction where the cleanup is active.<br class=""><br class="">Modified: cfe/trunk/lib/CodeGen/<wbr class="">ItaniumCXXABI.cpp<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/CodeGen/<wbr class="">ItaniumCXXABI.cpp?rev=328731&<wbr class="">r1=328730&r2=328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/lib/CodeGen/<wbr class="">ItaniumCXXABI.cpp (original)<br class="">+++ cfe/trunk/lib/CodeGen/<wbr class="">ItaniumCXXABI.cpp Wed Mar 28 14:13:14 2018<br class="">@@ -63,13 +63,6 @@ public:<br class="">   bool classifyReturnType(<wbr class="">CGFunctionInfo &FI) const override;<br class=""><br class="">   bool passClassIndirect(const CXXRecordDecl *RD) const {<br class="">-    // Clang <= 4 used the pre-C++11 rule, which ignores move operations.<br class="">-    // The PS4 platform ABI follows the behavior of Clang 3.2.<br class="">-    if (CGM.getCodeGenOpts().<wbr class="">getClangABICompat() <=<br class="">-            CodeGenOptions::ClangABI::Ver4 ||<br class="">-        CGM.getTriple().getOS() == llvm::Triple::PS4)<br class="">-      return RD-><wbr class="">hasNonTrivialDestructorForCall<wbr class="">() ||<br class="">-             RD-><wbr class="">hasNonTrivialCopyConstructorFo<wbr class="">rCall();<br class="">     return !canCopyArgument(RD);<br class="">   }<br class=""><br class=""><br class="">Modified: cfe/trunk/lib/CodeGen/<wbr class="">MicrosoftCXXABI.cpp<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/CodeGen/<wbr class="">MicrosoftCXXABI.cpp?rev=<wbr class="">328731&r1=328730&r2=328731&<wbr class="">view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/lib/CodeGen/<wbr class="">MicrosoftCXXABI.cpp (original)<br class="">+++ cfe/trunk/lib/CodeGen/<wbr class="">MicrosoftCXXABI.cpp Wed Mar 28 14:13:14 2018<br class="">@@ -829,60 +829,7 @@ MicrosoftCXXABI::<wbr class="">getRecordArgABI(const C<br class="">     return RAA_Default;<br class=""><br class="">   case llvm::Triple::x86_64:<br class="">-    bool CopyCtorIsTrivial = false, CopyCtorIsTrivialForCall = false;<br class="">-    bool DtorIsTrivialForCall = false;<br class="">-<br class="">-    // If a class has at least one non-deleted, trivial copy constructor, it<br class="">-    // is passed according to the C ABI. Otherwise, it is passed indirectly.<br class="">-    //<br class="">-    // Note: This permits classes with non-trivial copy or move ctors to be<br class="">-    // passed in registers, so long as they *also* have a trivial copy ctor,<br class="">-    // which is non-conforming.<br class="">-    if (RD-><wbr class="">needsImplicitCopyConstructor()<wbr class="">) {<br class="">-      if (!RD-><wbr class="">defaultedCopyConstructorIsDele<wbr class="">ted()) {<br class="">-        if (RD-><wbr class="">hasTrivialCopyConstructor())<br class="">-          CopyCtorIsTrivial = true;<br class="">-        if (RD-><wbr class="">hasTrivialCopyConstructorForCa<wbr class="">ll())<br class="">-          CopyCtorIsTrivialForCall = true;<br class="">-      }<br class="">-    } else {<br class="">-      for (const CXXConstructorDecl *CD : RD->ctors()) {<br class="">-        if (CD->isCopyConstructor() && !CD->isDeleted()) {<br class="">-          if (CD->isTrivial())<br class="">-            CopyCtorIsTrivial = true;<br class="">-          if (CD->isTrivialForCall())<br class="">-            CopyCtorIsTrivialForCall = true;<br class="">-        }<br class="">-      }<br class="">-    }<br class="">-<br class="">-    if (RD->needsImplicitDestructor()<wbr class="">) {<br class="">-      if (!RD-><wbr class="">defaultedDestructorIsDeleted() &&<br class="">-          RD-><wbr class="">hasTrivialDestructorForCall())<br class="">-        DtorIsTrivialForCall = true;<br class="">-    } else if (const auto *D = RD->getDestructor()) {<br class="">-      if (!D->isDeleted() && D->isTrivialForCall())<br class="">-        DtorIsTrivialForCall = true;<br class="">-    }<br class="">-<br class="">-    // If the copy ctor and dtor are both trivial-for-calls, pass direct.<br class="">-    if (CopyCtorIsTrivialForCall && DtorIsTrivialForCall)<br class="">-      return RAA_Default;<br class="">-<br class="">-    // If a class has a destructor, we'd really like to pass it indirectly<br class="">-    // because it allows us to elide copies.  Unfortunately, MSVC makes that<br class="">-    // impossible for small types, which it will pass in a single register or<br class="">-    // stack slot. Most objects with dtors are large-ish, so handle that early.<br class="">-    // We can't call out all large objects as being indirect because there are<br class="">-    // multiple x64 calling conventions and the C++ ABI code shouldn't dictate<br class="">-    // how we pass large POD types.<br class="">-<br class="">-    // Note: This permits small classes with nontrivial destructors to be<br class="">-    // passed in registers, which is non-conforming.<br class="">-    if (CopyCtorIsTrivial &&<br class="">-        getContext().getTypeSize(RD-><wbr class="">getTypeForDecl()) <= 64)<br class="">-      return RAA_Default;<br class="">-    return RAA_Indirect;<br class="">+    return !canCopyArgument(RD) ? RAA_Indirect : RAA_Default;<br class="">   }<br class=""><br class="">   llvm_unreachable("invalid enum");<br class=""><br class="">Modified: cfe/trunk/lib/CodeGen/<wbr class="">TargetInfo.cpp<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/CodeGen/<wbr class="">TargetInfo.cpp?rev=328731&r1=<wbr class="">328730&r2=328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/lib/CodeGen/<wbr class="">TargetInfo.cpp (original)<br class="">+++ cfe/trunk/lib/CodeGen/<wbr class="">TargetInfo.cpp Wed Mar 28 14:13:14 2018<br class="">@@ -2131,8 +2131,8 @@ class X86_64ABIInfo : public SwiftABIInf<br class="">   /// classify it as INTEGER (for compatibility with older clang compilers).<br class="">   bool classifyIntegerMMXAsSSE() const {<br class="">     // Clang <= 3.8 did not do this.<br class="">-    if (getCodeGenOpts().<wbr class="">getClangABICompat() <=<br class="">-        CodeGenOptions::ClangABI::<wbr class="">Ver3_8)<br class="">+    if (getContext().getLangOpts().<wbr class="">getClangABICompat() <=<br class="">+        LangOptions::ClangABI::Ver3_8)<br class="">       return false;<br class=""><br class="">     const llvm::Triple &Triple = getTarget().getTriple();<br class=""><br class="">Modified: cfe/trunk/lib/Frontend/<wbr class="">CompilerInvocation.cpp<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/<wbr class="">Frontend/CompilerInvocation.<wbr class="">cpp?rev=328731&r1=328730&r2=<wbr class="">328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/lib/Frontend/<wbr class="">CompilerInvocation.cpp (original)<br class="">+++ cfe/trunk/lib/Frontend/<wbr class="">CompilerInvocation.cpp Wed Mar 28 14:13:14 2018<br class="">@@ -633,33 +633,6 @@ static bool ParseCodeGenArgs(CodeGenOpti<br class="">   if (!Opts.<wbr class="">ProfileInstrumentUsePath.<wbr class="">empty())<br class="">     setPGOUseInstrumentor(Opts, Opts.ProfileInstrumentUsePath)<wbr class="">;<br class=""><br class="">-  if (Arg *A = Args.getLastArg(OPT_fclang_<wbr class="">abi_compat_EQ)) {<br class="">-    Opts.setClangABICompat(<wbr class="">CodeGenOptions::ClangABI::<wbr class="">Latest);<br class="">-<br class="">-    StringRef Ver = A->getValue();<br class="">-    std::pair<StringRef, StringRef> VerParts = Ver.split('.');<br class="">-    unsigned Major, Minor = 0;<br class="">-<br class="">-    // Check the version number is valid: either 3.x (0 <= x <= 9) or<br class="">-    // y or y.0 (4 <= y <= current version).<br class="">-    if (!VerParts.first.startswith("<wbr class="">0") &&<br class="">-        !VerParts.first.getAsInteger(<wbr class="">10, Major) &&<br class="">-        3 <= Major && Major <= CLANG_VERSION_MAJOR &&<br class="">-        (Major == 3 ? VerParts.second.size() == 1 &&<br class="">-                      !VerParts.second.getAsInteger(<wbr class="">10, Minor)<br class="">-                    : VerParts.first.size() == Ver.size() ||<br class="">-                      VerParts.second == "0")) {<br class="">-      // Got a valid version number.<br class="">-      if (Major == 3 && Minor <= 8)<br class="">-        Opts.setClangABICompat(<wbr class="">CodeGenOptions::ClangABI::<wbr class="">Ver3_8);<br class="">-      else if (Major <= 4)<br class="">-        Opts.setClangABICompat(<wbr class="">CodeGenOptions::ClangABI::<wbr class="">Ver4);<br class="">-    } else if (Ver != "latest") {<br class="">-      Diags.Report(diag::err_drv_<wbr class="">invalid_value)<br class="">-          << A->getAsString(Args) << A->getValue();<br class="">-    }<br class="">-  }<br class="">-<br class="">   Opts.CoverageMapping =<br class="">       Args.hasFlag(OPT_fcoverage_<wbr class="">mapping, OPT_fno_coverage_mapping, false);<br class="">   Opts.DumpCoverageMapping = Args.hasArg(OPT_dump_coverage_<wbr class="">mapping);<br class="">@@ -2670,6 +2643,33 @@ static void ParseLangArgs(LangOptions &O<br class=""><br class="">   // -fallow-editor-placeholders<br class="">   Opts.AllowEditorPlaceholders = Args.hasArg(OPT_fallow_editor_<wbr class="">placeholders);<br class="">+<br class="">+  if (Arg *A = Args.getLastArg(OPT_fclang_<wbr class="">abi_compat_EQ)) {<br class="">+    Opts.setClangABICompat(<wbr class="">LangOptions::ClangABI::Latest)<wbr class="">;<br class="">+<br class="">+    StringRef Ver = A->getValue();<br class="">+    std::pair<StringRef, StringRef> VerParts = Ver.split('.');<br class="">+    unsigned Major, Minor = 0;<br class="">+<br class="">+    // Check the version number is valid: either 3.x (0 <= x <= 9) or<br class="">+    // y or y.0 (4 <= y <= current version).<br class="">+    if (!VerParts.first.startswith("<wbr class="">0") &&<br class="">+        !VerParts.first.getAsInteger(<wbr class="">10, Major) &&<br class="">+        3 <= Major && Major <= CLANG_VERSION_MAJOR &&<br class="">+        (Major == 3 ? VerParts.second.size() == 1 &&<br class="">+                      !VerParts.second.getAsInteger(<wbr class="">10, Minor)<br class="">+                    : VerParts.first.size() == Ver.size() ||<br class="">+                      VerParts.second == "0")) {<br class="">+      // Got a valid version number.<br class="">+      if (Major == 3 && Minor <= 8)<br class="">+        Opts.setClangABICompat(<wbr class="">LangOptions::ClangABI::Ver3_8)<wbr class="">;<br class="">+      else if (Major <= 4)<br class="">+        Opts.setClangABICompat(<wbr class="">LangOptions::ClangABI::Ver4);<br class="">+    } else if (Ver != "latest") {<br class="">+      Diags.Report(diag::err_drv_<wbr class="">invalid_value)<br class="">+          << A->getAsString(Args) << A->getValue();<br class="">+    }<br class="">+  }<br class=""> }<br class=""><br class=""> static bool isStrictlyPreprocessorAction(<wbr class="">frontend::ActionKind Action) {<br class=""><br class="">Modified: cfe/trunk/lib/Sema/SemaDecl.<wbr class="">cpp<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/Sema/<wbr class="">SemaDecl.cpp?rev=328731&r1=<wbr class="">328730&r2=328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/lib/Sema/SemaDecl.<wbr class="">cpp (original)<br class="">+++ cfe/trunk/lib/Sema/SemaDecl.<wbr class="">cpp Wed Mar 28 14:13:14 2018<br class="">@@ -15461,8 +15461,10 @@ void Sema::ActOnFields(Scope *S, SourceL<br class="">       QualType::PrimitiveCopyKind PCK = FT.<wbr class="">isNonTrivialToPrimitiveCopy();<br class="">       if (PCK != QualType::PCK_Trivial && PCK != QualType::PCK_VolatileTrivial)<br class="">         Record-><wbr class="">setNonTrivialToPrimitiveCopy(<wbr class="">true);<br class="">-      if (FT.isDestructedType())<br class="">+      if (FT.isDestructedType()) {<br class="">         Record-><wbr class="">setNonTrivialToPrimitiveDestro<wbr class="">y(true);<br class="">+        Record-><wbr class="">setParamDestroyedInCallee(<wbr class="">true);<br class="">+      }<br class="">       if (!FT.canPassInRegisters())<br class="">         Record->setCanPassInRegisters(<wbr class="">false);<br class="">     }<br class=""><br class="">Modified: cfe/trunk/lib/Sema/<wbr class="">SemaDeclCXX.cpp<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/Sema/<wbr class="">SemaDeclCXX.cpp?rev=328731&r1=<wbr class="">328730&r2=328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/lib/Sema/<wbr class="">SemaDeclCXX.cpp (original)<br class="">+++ cfe/trunk/lib/Sema/<wbr class="">SemaDeclCXX.cpp Wed Mar 28 14:13:14 2018<br class="">@@ -5791,12 +5791,21 @@ static void DefineImplicitSpecialMember(<br class="">   }<br class=""> }<br class=""><br class="">-/// Determine whether a type is permitted to be passed or returned in<br class="">-/// registers, per C++ [class.temporary]p3.<br class="">-static bool computeCanPassInRegisters(Sema &S, CXXRecordDecl *D) {<br class="">+/// Determine whether a type would be destructed in the callee if it had a<br class="">+/// non-trivial destructor. The rules here are based on C++ [class.temporary]p3,<br class="">+/// which determines whether a struct can be passed to or returned from<br class="">+/// functions in registers.<br class="">+static bool paramCanBeDestroyedInCallee(<wbr class="">Sema &S, CXXRecordDecl *D,<br class="">+                                        TargetInfo::CallingConvKind CCK) {<br class="">   if (D->isDependentType() || D->isInvalidDecl())<br class="">     return false;<br class=""><br class="">+  // Clang <= 4 used the pre-C++11 rule, which ignores move operations.<br class="">+  // The PS4 platform ABI follows the behavior of Clang 3.2.<br class="">+  if (CCK == TargetInfo::CCK_<wbr class="">ClangABI4OrPS4)<br class="">+    return !D-><wbr class="">hasNonTrivialDestructorForCall<wbr class="">() &&<br class="">+           !D-><wbr class="">hasNonTrivialCopyConstructorFo<wbr class="">rCall();<br class="">+<br class="">   // Per C++ [class.temporary]p3, the relevant condition is:<br class="">   //   each copy constructor, move constructor, and destructor of X is<br class="">   //   either trivial or deleted, and X has at least one non-deleted copy<br class="">@@ -5838,6 +5847,77 @@ static bool computeCanPassInRegisters(Se<br class="">   return HasNonDeletedCopyOrMove;<br class=""> }<br class=""><br class="">+static bool computeCanPassInRegister(bool DestroyedInCallee,<br class="">+                                     const CXXRecordDecl *RD,<br class="">+                                     TargetInfo::CallingConvKind CCK,<br class="">+                                     Sema &S) {<br class="">+  if (RD->isDependentType() || RD->isInvalidDecl())<br class="">+    return true;<br class="">+<br class="">+  // The param cannot be passed in registers if CanPassInRegisters is already<br class="">+  // set to false.<br class="">+  if (!RD->canPassInRegisters())<br class="">+    return false;<br class="">+<br class="">+  if (CCK != TargetInfo::CCK_MicrosoftX86_<wbr class="">64)<br class="">+    return DestroyedInCallee;<br class="">+<br class="">+  bool CopyCtorIsTrivial = false, CopyCtorIsTrivialForCall = false;<br class="">+  bool DtorIsTrivialForCall = false;<br class="">+<br class="">+  // If a class has at least one non-deleted, trivial copy constructor, it<br class="">+  // is passed according to the C ABI. Otherwise, it is passed indirectly.<br class="">+  //<br class="">+  // Note: This permits classes with non-trivial copy or move ctors to be<br class="">+  // passed in registers, so long as they *also* have a trivial copy ctor,<br class="">+  // which is non-conforming.<br class="">+  if (RD-><wbr class="">needsImplicitCopyConstructor()<wbr class="">) {<br class="">+    if (!RD-><wbr class="">defaultedCopyConstructorIsDele<wbr class="">ted()) {<br class="">+      if (RD-><wbr class="">hasTrivialCopyConstructor())<br class="">+        CopyCtorIsTrivial = true;<br class="">+      if (RD-><wbr class="">hasTrivialCopyConstructorForCa<wbr class="">ll())<br class="">+        CopyCtorIsTrivialForCall = true;<br class="">+    }<br class="">+  } else {<br class="">+    for (const CXXConstructorDecl *CD : RD->ctors()) {<br class="">+      if (CD->isCopyConstructor() && !CD->isDeleted()) {<br class="">+        if (CD->isTrivial())<br class="">+          CopyCtorIsTrivial = true;<br class="">+        if (CD->isTrivialForCall())<br class="">+          CopyCtorIsTrivialForCall = true;<br class="">+      }<br class="">+    }<br class="">+  }<br class="">+<br class="">+  if (RD->needsImplicitDestructor()<wbr class="">) {<br class="">+    if (!RD-><wbr class="">defaultedDestructorIsDeleted() &&<br class="">+        RD-><wbr class="">hasTrivialDestructorForCall())<br class="">+      DtorIsTrivialForCall = true;<br class="">+  } else if (const auto *D = RD->getDestructor()) {<br class="">+    if (!D->isDeleted() && D->isTrivialForCall())<br class="">+      DtorIsTrivialForCall = true;<br class="">+  }<br class="">+<br class="">+  // If the copy ctor and dtor are both trivial-for-calls, pass direct.<br class="">+  if (CopyCtorIsTrivialForCall && DtorIsTrivialForCall)<br class="">+    return true;<br class="">+<br class="">+  // If a class has a destructor, we'd really like to pass it indirectly<br class="">+  // because it allows us to elide copies.  Unfortunately, MSVC makes that<br class="">+  // impossible for small types, which it will pass in a single register or<br class="">+  // stack slot. Most objects with dtors are large-ish, so handle that early.<br class="">+  // We can't call out all large objects as being indirect because there are<br class="">+  // multiple x64 calling conventions and the C++ ABI code shouldn't dictate<br class="">+  // how we pass large POD types.<br class="">+<br class="">+  // Note: This permits small classes with nontrivial destructors to be<br class="">+  // passed in registers, which is non-conforming.<br class="">+  if (CopyCtorIsTrivial &&<br class="">+      S.getASTContext().getTypeSize(<wbr class="">RD->getTypeForDecl()) <= 64)<br class="">+    return true;<br class="">+  return false;<br class="">+}<br class="">+<br class=""> /// \brief Perform semantic checks on a class definition that has been<br class=""> /// completing, introducing implicitly-declared members, checking for<br class=""> /// abstract types, etc.<br class="">@@ -6001,7 +6081,17 @@ void Sema::CheckCompletedCXXClass(<wbr class="">CXXRec<br class=""><br class="">   checkClassLevelDLLAttribute(<wbr class="">Record);<br class=""><br class="">-  Record->setCanPassInRegisters(<wbr class="">computeCanPassInRegisters(*<wbr class="">this, Record));<br class="">+  bool ClangABICompat4 =<br class="">+      Context.getLangOpts().<wbr class="">getClangABICompat() <= LangOptions::ClangABI::Ver4;<br class="">+  TargetInfo::CallingConvKind CCK =<br class="">+      Context.getTargetInfo().<wbr class="">getCallingConvKind(<wbr class="">ClangABICompat4);<br class="">+  bool DestroyedInCallee = paramCanBeDestroyedInCallee(*<wbr class="">this, Record, CCK);<br class="">+<br class="">+  if (Record-><wbr class="">hasNonTrivialDestructor())<br class="">+    Record-><wbr class="">setParamDestroyedInCallee(<wbr class="">DestroyedInCallee);<br class="">+<br class="">+  Record->setCanPassInRegisters(<br class="">+      computeCanPassInRegister(<wbr class="">DestroyedInCallee, Record, CCK, *this));<br class=""> }<br class=""></blockquote><div class=""><br class=""></div><div class="">The naming you're using here doesn't make any sense to me.</div><div class=""><br class=""></div><div class="">"paramCanBeDestroyedInCallee" is computing whether the class is allowed to be passed in registers (per the language rules), not whether it's destroyed in callee (which is based on whether we're using the MS ABI, which sometimes destroys parameters in the callee).</div><div class="">"computeCanPassInRegister" appears to be computing whether the parameter *should* be passed in registers (per the quirks of the ABI), not whether it can be passed in registers. (Also I'm not sure why you converted the name from plural to singular -- we really do mean zero or more registers here, not exactly one.)</div><div class=""><br class=""></div></div></div></div></div></blockquote><div><br class=""></div><div>Does this patch make more sense to you?</div><div><div><br class=""></div><div></div></div></div></div></div></div></body></html>