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