<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="">Sorry for the breakage, I reverted the patch in r329627 and reapplied it with a fix in r329635. Let me know if the tests are still failing.<br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Apr 9, 2018, at 3:47 PM, Galina Kistanova <<a href="mailto:gkistanova@gmail.com" class="">gkistanova@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Hello Akira,<br class=""><br class="">This commit added broken tests to one of our builders:<br class=""><a href="http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/8964" class="">http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/8964</a><br class=""><br class="">Failing Tests (8):<br class="">    Clang :: CodeGenObjCXX/<a href="http://objc-struct-cxx-abi.mm/" class="">objc-struct-cxx-abi.mm</a><br class="">    Clang :: SemaObjCXX/<a href="http://attr-trivial-abi.mm/" class="">attr-trivial-abi.mm</a><br class="">. . .<br class="">Please have a look?<br class=""><br class="">The builder was red and did not send notifications.<br class=""><br class="">Thanks<br class=""><br class="">Galina<br class=""></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Mon, Apr 9, 2018 at 1:39 PM, Akira Hatanaka via cfe-commits <span dir="ltr" class=""><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank" class="">cfe-commits@lists.llvm.org</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: ahatanak<br class="">
Date: Mon Apr  9 13:39:47 2018<br class="">
New Revision: 329617<br class="">
<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=329617&view=rev" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project?rev=329617&view=rev</a><br class="">
Log:<br class="">
[ObjC++] Never pass structs that transitively contain __weak fields in<br class="">
registers.<br class="">
<br class="">
This patch fixes a bug in r328731 that caused structs transitively<br class="">
containing __weak fields to be passed in registers. The patch replaces<br class="">
the flag RecordDecl::CanPassInRegisters with a 2-bit enum that indicates<br class="">
whether the struct or structs containing the struct are forced to be<br class="">
passed indirectly.<br class="">
<br class="">
<a href="rdar://problem/39194693" class="">rdar://problem/39194693</a><br class="">
<br class="">
Modified:<br class="">
    cfe/trunk/include/clang/AST/<wbr class="">Decl.h<br class="">
    cfe/trunk/include/clang/AST/<wbr class="">Type.h<br class="">
    cfe/trunk/lib/AST/Decl.cpp<br class="">
    cfe/trunk/lib/AST/DeclCXX.cpp<br class="">
    cfe/trunk/lib/AST/Type.cpp<br class="">
    cfe/trunk/lib/Sema/SemaDecl.<wbr class="">cpp<br class="">
    cfe/trunk/lib/Sema/<wbr class="">SemaDeclCXX.cpp<br class="">
    cfe/trunk/lib/Serialization/<wbr class="">ASTReaderDecl.cpp<br class="">
    cfe/trunk/lib/Serialization/<wbr class="">ASTWriter.cpp<br class="">
    cfe/trunk/lib/Serialization/<wbr class="">ASTWriterDecl.cpp<br class="">
    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="">
<br class="">
Modified: cfe/trunk/include/clang/AST/<wbr class="">Decl.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=329617&r1=329616&r2=329617&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=329617&<wbr class="">r1=329616&r2=329617&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 Mon Apr  9 13:39:47 2018<br class="">
@@ -3541,6 +3541,31 @@ public:<br class="">
 ///   union Y { int A, B; };     // Has body with members A and B (FieldDecls).<br class="">
 /// This decl will be marked invalid if *any* members are invalid.<br class="">
 class RecordDecl : public TagDecl {<br class="">
+public:<br class="">
+  /// Enum that represents the different ways arguments are passed to and<br class="">
+  /// returned from function calls. This takes into account the target-specific<br class="">
+  /// and version-specific rules along with the rules determined by the<br class="">
+  /// language.<br class="">
+  enum ArgPassingKind {<br class="">
+    /// The argument of this type can be passed directly in registers.<br class="">
+    APK_CanPassInRegs,<br class="">
+<br class="">
+    /// The argument of this type cannot be passed directly in registers.<br class="">
+    /// Records containing this type as a subobject are not forced to be passed<br class="">
+    /// indirectly. This value is used only in C++. This value is required by<br class="">
+    /// C++ because, in uncommon situations, it is possible for a class to have<br class="">
+    /// only trivial copy/move constructors even when one of its subobjects has<br class="">
+    /// a non-trivial copy/move constructor (if e.g. the corresponding copy/move<br class="">
+    /// constructor in the derived class is deleted).<br class="">
+    APK_CannotPassInRegs,<br class="">
+<br class="">
+    /// The argument of this type cannot be passed directly in registers.<br class="">
+    /// Records containing this type as a subobject are forced to be passed<br class="">
+    /// indirectly.<br class="">
+    APK_CanNeverPassInRegs<br class="">
+  };<br class="">
+<br class="">
+private:<br class="">
   friend class DeclContext;<br class="">
<br class="">
   // FIXME: This can be packed into the bitfields in Decl.<br class="">
@@ -3571,17 +3596,14 @@ class RecordDecl : public TagDecl {<br class="">
   bool NonTrivialToPrimitiveCopy : 1;<br class="">
   bool NonTrivialToPrimitiveDestroy : 1;<br class="">
<br class="">
-  /// True if this class can be passed in a non-address-preserving fashion<br class="">
-  /// (such as in registers).<br class="">
-  /// This does not imply anything about how the ABI in use will actually<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="">
+  /// Represents the way this type is passed to a function.<br class="">
+  ArgPassingKind ArgPassingRestrictions : 2;<br class="">
+<br class="">
 protected:<br class="">
   RecordDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,<br class="">
              SourceLocation StartLoc, SourceLocation IdLoc,<br class="">
@@ -3669,12 +3691,15 @@ public:<br class="">
   /// it must have at least one trivial, non-deleted copy or move constructor.<br class="">
   /// FIXME: This should be set as part of completeDefinition.<br class="">
   bool canPassInRegisters() const {<br class="">
-    return CanPassInRegisters;<br class="">
+    return ArgPassingRestrictions == APK_CanPassInRegs;<br class="">
+  }<br class="">
+<br class="">
+  ArgPassingKind getArgPassingRestrictions() const {<br class="">
+    return ArgPassingRestrictions;<br class="">
   }<br class="">
<br class="">
-  /// Set that we can pass this RecordDecl in registers.<br class="">
-  void setCanPassInRegisters(bool CanPass) {<br class="">
-    CanPassInRegisters = CanPass;<br class="">
+  void setArgPassingRestrictions(<wbr class="">ArgPassingKind Kind) {<br class="">
+    ArgPassingRestrictions = Kind;<br class="">
   }<br class="">
<br class="">
   bool isParamDestroyedInCallee() const {<br class="">
<br class="">
Modified: cfe/trunk/include/clang/AST/<wbr class="">Type.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=329617&r1=329616&r2=329617&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=329617&<wbr class="">r1=329616&r2=329617&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 Mon Apr  9 13:39:47 2018<br class="">
@@ -1149,8 +1149,6 @@ public:<br class="">
   /// source object is placed in an uninitialized state.<br class="">
   PrimitiveCopyKind isNonTrivialToPrimitiveDestruc<wbr class="">tiveMove() const;<br class="">
<br class="">
-  bool canPassInRegisters() const;<br class="">
-<br class="">
   enum DestructionKind {<br class="">
     DK_none,<br class="">
     DK_cxx_destructor,<br class="">
<br class="">
Modified: cfe/trunk/lib/AST/Decl.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=329617&r1=329616&r2=329617&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/AST/<wbr class="">Decl.cpp?rev=329617&r1=329616&<wbr class="">r2=329617&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 Mon Apr  9 13:39:47 2018<br class="">
@@ -3956,7 +3956,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), ParamDestroyedInCallee(false) {<br class="">
+      ParamDestroyedInCallee(false), ArgPassingRestrictions(APK_<wbr class="">CanPassInRegs) {<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: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=329617&r1=329616&r2=329617&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/AST/<wbr class="">DeclCXX.cpp?rev=329617&r1=<wbr class="">329616&r2=329617&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 Mon Apr  9 13:39:47 2018<br class="">
@@ -421,6 +421,10 @@ CXXRecordDecl::setBases(<wbr class="">CXXBaseSpecifier<br class="">
     if (BaseClassDecl-><wbr class="">hasVolatileMember())<br class="">
       setHasVolatileMember(true);<br class="">
<br class="">
+    if (BaseClassDecl-><wbr class="">getArgPassingRestrictions() ==<br class="">
+        RecordDecl::APK_<wbr class="">CanNeverPassInRegs)<br class="">
+      setArgPassingRestrictions(<wbr class="">RecordDecl::APK_<wbr class="">CanNeverPassInRegs);<br class="">
+<br class="">
     // Keep track of the presence of mutable fields.<br class="">
     if (BaseClassDecl-><wbr class="">hasMutableFields()) {<br class="">
       data().HasMutableFields = true;<br class="">
@@ -950,7 +954,7 @@ void CXXRecordDecl::addedMember(<wbr class="">Decl *D)<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="">
+          setArgPassingRestrictions(<wbr class="">RecordDecl::APK_<wbr class="">CanNeverPassInRegs);<br class="">
<br class="">
         Data.HasIrrelevantDestructor = false;<br class="">
       } else if (!Context.getLangOpts().<wbr class="">ObjCAutoRefCount) {<br class="">
@@ -1117,6 +1121,9 @@ void CXXRecordDecl::addedMember(<wbr class="">Decl *D)<br class="">
           setHasObjectMember(true);<br class="">
         if (FieldRec->hasVolatileMember()<wbr class="">)<br class="">
           setHasVolatileMember(true);<br class="">
+        if (FieldRec-><wbr class="">getArgPassingRestrictions() ==<br class="">
+            RecordDecl::APK_<wbr class="">CanNeverPassInRegs)<br class="">
+          setArgPassingRestrictions(<wbr class="">RecordDecl::APK_<wbr class="">CanNeverPassInRegs);<br class="">
<br class="">
         // C++0x [class]p7:<br class="">
         //   A standard-layout class is a class that:<br class="">
<br class="">
Modified: cfe/trunk/lib/AST/Type.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=329617&r1=329616&r2=329617&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/AST/<wbr class="">Type.cpp?rev=329617&r1=329616&<wbr class="">r2=329617&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 Mon Apr  9 13:39:47 2018<br class="">
@@ -2239,17 +2239,6 @@ QualType::<wbr class="">isNonTrivialToPrimitiveDestruc<br class="">
   return isNonTrivialToPrimitiveCopy();<br class="">
 }<br class="">
<br class="">
-bool QualType::canPassInRegisters() const {<br class="">
-  if (const auto *RT =<br class="">
-          getTypePtr()-><wbr class="">getBaseElementTypeUnsafe()-><wbr class="">getAs<RecordType>())<br class="">
-    return RT->getDecl()-><wbr class="">canPassInRegisters();<br class="">
-<br class="">
-  if (getQualifiers().<wbr class="">getObjCLifetime() == Qualifiers::OCL_Weak)<br class="">
-    return false;<br class="">
-<br class="">
-  return true;<br class="">
-}<br class="">
-<br class="">
 bool Type::isLiteralType(const ASTContext &Ctx) const {<br class="">
   if (isDependentType())<br class="">
     return false;<br class="">
<br class="">
Modified: cfe/trunk/lib/Sema/SemaDecl.<wbr class="">cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=329617&r1=329616&r2=329617&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/Sema/<wbr class="">SemaDecl.cpp?rev=329617&r1=<wbr class="">329616&r2=329617&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 Mon Apr  9 13:39:47 2018<br class="">
@@ -15465,8 +15465,13 @@ void Sema::ActOnFields(Scope *S, SourceL<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="">
+      if (const auto *RT = FT->getAs<RecordType>()) {<br class="">
+        if (RT->getDecl()-><wbr class="">getArgPassingRestrictions() ==<br class="">
+            RecordDecl::APK_<wbr class="">CanNeverPassInRegs)<br class="">
+          Record-><wbr class="">setArgPassingRestrictions(<wbr class="">RecordDecl::APK_<wbr class="">CanNeverPassInRegs);<br class="">
+      } else if (FT.getQualifiers().<wbr class="">getObjCLifetime() == Qualifiers::OCL_Weak)<br class="">
+        Record-><wbr class="">setArgPassingRestrictions(<wbr class="">RecordDecl::APK_<wbr class="">CanNeverPassInRegs);<br class="">
     }<br class="">
<br class="">
     if (Record && FD->getType().<wbr class="">isVolatileQualified())<br class="">
<br class="">
Modified: cfe/trunk/lib/Sema/<wbr class="">SemaDeclCXX.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=329617&r1=329616&r2=329617&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/Sema/<wbr class="">SemaDeclCXX.cpp?rev=329617&r1=<wbr class="">329616&r2=329617&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 Mon Apr  9 13:39:47 2018<br class="">
@@ -5847,20 +5847,20 @@ static bool paramCanBeDestroyedInCallee(<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="">
+static RecordDecl::ArgPassingKind<br class="">
+<wbr class="">computeArgPassingRestrictions(<wbr class="">bool DestroyedInCallee, const CXXRecordDecl *RD,<br class="">
+                              TargetInfo::CallingConvKind CCK, Sema &S) {<br class="">
   if (RD->isDependentType() || RD->isInvalidDecl())<br class="">
-    return true;<br class="">
+    return RecordDecl::APK_CanPassInRegs;<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="">
+  // The param cannot be passed in registers if ArgPassingRestrictions is set to<br class="">
+  // APK_CanNeverPassInRegs.<br class="">
+  if (RD-><wbr class="">getArgPassingRestrictions() == RecordDecl::APK_<wbr class="">CanNeverPassInRegs)<br class="">
+    return RecordDecl::APK_<wbr class="">CanNeverPassInRegs;<br class="">
<br class="">
   if (CCK != TargetInfo::CCK_MicrosoftX86_<wbr class="">64)<br class="">
-    return DestroyedInCallee;<br class="">
+    return DestroyedInCallee ? RecordDecl::APK_CanPassInRegs<br class="">
+                             : RecordDecl::APK_<wbr class="">CannotPassInRegs;<br class="">
<br class="">
   bool CopyCtorIsTrivial = false, CopyCtorIsTrivialForCall = false;<br class="">
   bool DtorIsTrivialForCall = false;<br class="">
@@ -5900,7 +5900,7 @@ static bool computeCanPassInRegister(boo<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="">
+    return RecordDecl::APK_CanPassInRegs;<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="">
@@ -5914,8 +5914,8 @@ static bool computeCanPassInRegister(boo<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="">
+    return RecordDecl::APK_CanPassInRegs;<br class="">
+  return RecordDecl::APK_<wbr class="">CannotPassInRegs;<br class="">
 }<br class="">
<br class="">
 /// \brief Perform semantic checks on a class definition that has been<br class="">
@@ -6090,8 +6090,8 @@ void Sema::CheckCompletedCXXClass(<wbr class="">CXXRec<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="">
+  Record-><wbr class="">setArgPassingRestrictions(<br class="">
+      computeArgPassingRestrictions(<wbr class="">DestroyedInCallee, Record, CCK, *this));<br class="">
 }<br class="">
<br class="">
 /// Look up the special member function that would be called by a special<br class="">
<br class="">
Modified: cfe/trunk/lib/Serialization/<wbr class="">ASTReaderDecl.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=329617&r1=329616&r2=329617&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/<wbr class="">Serialization/ASTReaderDecl.<wbr class="">cpp?rev=329617&r1=329616&r2=<wbr class="">329617&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/Serialization/<wbr class="">ASTReaderDecl.cpp (original)<br class="">
+++ cfe/trunk/lib/Serialization/<wbr class="">ASTReaderDecl.cpp Mon Apr  9 13:39:47 2018<br class="">
@@ -742,8 +742,8 @@ ASTDeclReader::<wbr class="">VisitRecordDeclImpl(Recor<br class="">
   RD-><wbr class="">setNonTrivialToPrimitiveDefaul<wbr class="">tInitialize(Record.readInt());<br class="">
   RD-><wbr class="">setNonTrivialToPrimitiveCopy(<wbr class="">Record.readInt());<br class="">
   RD-><wbr class="">setNonTrivialToPrimitiveDestro<wbr class="">y(Record.readInt());<br class="">
-  RD->setCanPassInRegisters(<wbr class="">Record.readInt());<br class="">
   RD->setParamDestroyedInCallee(<wbr class="">Record.readInt());<br class="">
+  RD->setArgPassingRestrictions(<wbr class="">(RecordDecl::ArgPassingKind)<wbr class="">Record.readInt());<br class="">
   return Redecl;<br class="">
 }<br class="">
<br class="">
@@ -4114,8 +4114,9 @@ void ASTDeclReader::UpdateDecl(Decl *D,<br class="">
       bool HadRealDefinition =<br class="">
           OldDD && (OldDD->Definition != RD ||<br class="">
                     !Reader.<wbr class="">PendingFakeDefinitionData.<wbr class="">count(OldDD));<br class="">
-      RD->setCanPassInRegisters(<wbr class="">Record.readInt());<br class="">
       RD->setParamDestroyedInCallee(<wbr class="">Record.readInt());<br class="">
+      RD->setArgPassingRestrictions(<br class="">
+          (RecordDecl::ArgPassingKind)<wbr class="">Record.readInt());<br class="">
       ReadCXXRecordDefinition(RD, /*Update*/true);<br class="">
<br class="">
       // Visible update is handled separately.<br class="">
<br class="">
Modified: cfe/trunk/lib/Serialization/<wbr class="">ASTWriter.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=329617&r1=329616&r2=329617&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/<wbr class="">Serialization/ASTWriter.cpp?<wbr class="">rev=329617&r1=329616&r2=<wbr class="">329617&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/Serialization/<wbr class="">ASTWriter.cpp (original)<br class="">
+++ cfe/trunk/lib/Serialization/<wbr class="">ASTWriter.cpp Mon Apr  9 13:39:47 2018<br class="">
@@ -5193,8 +5193,8 @@ void ASTWriter::<wbr class="">WriteDeclUpdatesBlocks(R<br class="">
       case UPD_CXX_INSTANTIATED_CLASS_<wbr class="">DEFINITION: {<br class="">
         auto *RD = cast<CXXRecordDecl>(D);<br class="">
         UpdatedDeclContexts.insert(RD-<wbr class="">>getPrimaryContext());<br class="">
-        Record.push_back(RD-><wbr class="">canPassInRegisters());<br class="">
         Record.push_back(RD-><wbr class="">isParamDestroyedInCallee());<br class="">
+        Record.push_back(RD-><wbr class="">getArgPassingRestrictions());<br class="">
         Record.AddCXXDefinitionData(<wbr class="">RD);<br class="">
         Record.AddOffset(<wbr class="">WriteDeclContextLexicalBlock(<br class="">
             *Context, const_cast<CXXRecordDecl *>(RD)));<br class="">
<br class="">
Modified: cfe/trunk/lib/Serialization/<wbr class="">ASTWriterDecl.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=329617&r1=329616&r2=329617&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/<wbr class="">Serialization/ASTWriterDecl.<wbr class="">cpp?rev=329617&r1=329616&r2=<wbr class="">329617&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/Serialization/<wbr class="">ASTWriterDecl.cpp (original)<br class="">
+++ cfe/trunk/lib/Serialization/<wbr class="">ASTWriterDecl.cpp Mon Apr  9 13:39:47 2018<br class="">
@@ -469,8 +469,8 @@ void ASTDeclWriter::<wbr class="">VisitRecordDecl(Reco<br class="">
   Record.push_back(D-><wbr class="">isNonTrivialToPrimitiveDefault<wbr class="">Initialize());<br class="">
   Record.push_back(D-><wbr class="">isNonTrivialToPrimitiveCopy())<wbr class="">;<br class="">
   Record.push_back(D-><wbr class="">isNonTrivialToPrimitiveDestroy<wbr class="">());<br class="">
-  Record.push_back(D-><wbr class="">canPassInRegisters());<br class="">
   Record.push_back(D-><wbr class="">isParamDestroyedInCallee());<br class="">
+  Record.push_back(D-><wbr class="">getArgPassingRestrictions());<br class="">
<br class="">
   if (D->getDeclContext() == D->getLexicalDeclContext() &&<br class="">
       !D->hasAttrs() &&<br class="">
@@ -1913,9 +1913,10 @@ void ASTWriter::WriteDeclAbbrevs() {<br class="">
   Abv->Add(BitCodeAbbrevOp(<wbr class="">BitCodeAbbrevOp::Fixed, 1));<br class="">
   // isNonTrivialToPrimitiveDestroy<br class="">
   Abv->Add(BitCodeAbbrevOp(<wbr class="">BitCodeAbbrevOp::Fixed, 1));<br class="">
-  Abv->Add(BitCodeAbbrevOp(<wbr class="">BitCodeAbbrevOp::Fixed, 1)); // canPassInRegisters<br class="">
   // isParamDestroyedInCallee<br class="">
   Abv->Add(BitCodeAbbrevOp(<wbr class="">BitCodeAbbrevOp::Fixed, 1));<br class="">
+  // getArgPassingRestrictions<br class="">
+  Abv->Add(BitCodeAbbrevOp(<wbr class="">BitCodeAbbrevOp::Fixed, 2));<br class="">
<br class="">
   // DC<br class="">
   Abv->Add(BitCodeAbbrevOp(<wbr class="">BitCodeAbbrevOp::VBR, 6));   // LexicalOffset<br class="">
<br class="">
Modified: 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="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/objc-struct-cxx-abi.mm?rev=329617&r1=329616&r2=329617&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/<wbr class="">CodeGenObjCXX/objc-struct-cxx-<wbr class="">abi.mm?rev=329617&r1=329616&<wbr class="">r2=329617&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- 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> (original)<br class="">
+++ 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> Mon Apr  9 13:39:47 2018<br class="">
@@ -8,6 +8,8 @@<br class="">
 // pointer fields are passed directly.<br class="">
<br class="">
 // CHECK: %[[STRUCT_STRONGWEAK:.*]] = type { i8*, i8* }<br class="">
+// CHECK: %[[STRUCT_CONTAINSSTRONGWEAK:.<wbr class="">*]] = type { %[[STRUCT_STRONGWEAK]] }<br class="">
+// CHECK: %[[STRUCT_DERIVEDSTRONGWEAK:.*<wbr class="">]] = type { %[[STRUCT_STRONGWEAK]] }<br class="">
 // CHECK: %[[STRUCT_STRONG:.*]] = type { i8* }<br class="">
 // CHECK: %[[STRUCT_S:.*]] = type { i8* }<br class="">
 // CHECK: %[[STRUCT_CONTAINSNONTRIVIAL:.<wbr class="">*]] = type { %{{.*}}, i8* }<br class="">
@@ -22,6 +24,21 @@ struct StrongWeak {<br class="">
 };<br class="">
<br class="">
 #ifdef TRIVIALABI<br class="">
+struct __attribute__((trivial_abi)) ContainsStrongWeak {<br class="">
+#else<br class="">
+struct ContainsStrongWeak {<br class="">
+#endif<br class="">
+  StrongWeak sw;<br class="">
+};<br class="">
+<br class="">
+#ifdef TRIVIALABI<br class="">
+struct __attribute__((trivial_abi)) DerivedStrongWeak : StrongWeak {<br class="">
+#else<br class="">
+struct DerivedStrongWeak : StrongWeak {<br class="">
+#endif<br class="">
+};<br class="">
+<br class="">
+#ifdef TRIVIALABI<br class="">
 struct __attribute__((trivial_abi)) Strong {<br class="">
 #else<br class="">
 struct Strong {<br class="">
@@ -84,6 +101,18 @@ StrongWeak testReturnStrongWeak(StrongWe<br class="">
   return *a;<br class="">
 }<br class="">
<br class="">
+// CHECK: define void @_<wbr class="">Z27testParamContainsStrongWeak<wbr class="">18ContainsStrongWeak(%[[<wbr class="">STRUCT_CONTAINSSTRONGWEAK]]* %[[A:.*]])<br class="">
+// CHECK: call %[[STRUCT_CONTAINSSTRONGWEAK]]<wbr class="">* @_ZN18ContainsStrongWeakD1Ev(%<wbr class="">[[STRUCT_CONTAINSSTRONGWEAK]]* %[[A]])<br class="">
+<br class="">
+void testParamContainsStrongWeak(<wbr class="">ContainsStrongWeak a) {<br class="">
+}<br class="">
+<br class="">
+// CHECK: define void @_<wbr class="">Z26testParamDerivedStrongWeak1<wbr class="">7DerivedStrongWeak(%[[STRUCT_<wbr class="">DERIVEDSTRONGWEAK]]* %[[A:.*]])<br class="">
+// CHECK: call %[[STRUCT_DERIVEDSTRONGWEAK]]* @_ZN17DerivedStrongWeakD1Ev(%[<wbr class="">[STRUCT_DERIVEDSTRONGWEAK]]* %[[A]])<br class="">
+<br class="">
+void testParamDerivedStrongWeak(<wbr class="">DerivedStrongWeak a) {<br class="">
+}<br class="">
+<br class="">
 // CHECK: define void @_Z15testParamStrong6Strong(<wbr class="">i64 %[[A_COERCE:.*]])<br class="">
 // CHECK: %[[A:.*]] = alloca %[[STRUCT_STRONG]], align 8<br class="">
 // CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], %[[STRUCT_STRONG]]* %[[A]], i32 0, i32 0<br class="">
<br class="">
<br class="">
______________________________<wbr class="">_________________<br class="">
cfe-commits mailing list<br class="">
<a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a><br class="">
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank" class="">http://lists.llvm.org/cgi-bin/<wbr class="">mailman/listinfo/cfe-commits</a><br class="">
</blockquote></div><br class=""></div>
</div></blockquote></div><br class=""></body></html>