<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div></div><div><br class=""><blockquote type="cite" class=""><div class=""><div 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=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class="" 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;"><div class="gmail_extra"><div class="gmail_quote"><div class="">Have you considered taking the target's "destroyed right to left in callee" flag into account when computing ParamDestroyedInCallee, rather than deferring that until ASTContext::isParamDestroyedInCallee? If this is going to be an ABI-dependent flag anyway (because it depends on CanPassInRegisters, which is ABI-dependent), it would make some sense for it to always reflect the ABI's rule.</div><div class=""><br class=""></div></div></div></div></div></blockquote><div class=""><br class=""></div><div class=""><div class="">I think I ran into problems when I tried to take into account what 'TargetCXXABI::areArgsDestroyedLeftToRightInCallee()’  returns to set ParamDestroyedInCallee and use the flag in IRGen instead of calling ASTContext::isParamDestroyedInCallee. There were a few ObjC test cases that started failing, if I remember correctly. But I think we should always set the correct value to RecordDecl::ParamDestroyedInCallee taking into account what TargetCXXABI::areArgsDestroyedLeftToRightInCallee() returns, even though we still have to call ASTContext::isParamDestroyedInCallee.</div><div class=""><br class=""></div></div></div></div></blockquote><div><br class=""></div><div>It turns out some of the microsoft CodeGen tests were failing because I wasn’t setting Record::ParamDestroyedInCallee when the RecordDecl didn’t have a non-trivial destructor. RecordDecl::ParamDestroyedInCallee has to be set to true when TargetCXXABI::areArgsDestroyedLeftToRightInCallee() returns true, regardless of whether the struct has a destructor.</div><br class=""><blockquote type="cite" class=""><div class=""><div 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=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class="" 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;"><div class="gmail_extra"><div class="gmail_quote"><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;"><div class="" style="word-wrap: break-word; line-break: after-white-space;"><div class=""><div class=""><div class="h5"><blockquote type="cite" class=""><div class=""><div dir="ltr" class="" style="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; text-decoration: none;"><div class="gmail_extra"><div class="gmail_quote"><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;"><div class="" style="word-wrap: break-word; line-break: after-white-space;"><div class=""><div class="m_-7519891156417877842h5"><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class="" style="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; text-decoration: none;"><div class="gmail_extra"><div class="gmail_quote"><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;"><div class="" style="word-wrap: break-word;"><div dir="auto" class="" style="word-wrap: break-word;"><div dir="auto" class="" style="word-wrap: break-word;"><div dir="auto" class="" style="word-wrap: break-word;"><div class=""><div class=""><div class=""><div class="">The static function canPassInRegisters computes whether the record can be passed in registers depending on which of the three ABIs (clang-abi-compat=4.0, 64-bit microsoft, and Itanium C++ ABI) we are using. The function returns the correct answer except when ARC is enabled and the record has a __weak field, which is why CXXRecordDecl::canPassInRegist<wbr class="">ers() has to be called too to check the presence of __weak fields when computing the value for flag RecordDecl::CanPassInRegisters<wbr class="">.  I discovered there is a bug which causes a struct containing another struct with __weak fields to be passed directly, but I think that can be fixed in a separate patch.</div><div class=""><br class=""></div><div class="">Sema::CheckCompletedCXXClass also computes the value for flag RecordDecl::ParamDestroyedInCa<wbr class="">llee (note that this flag is meaningless when Microsoft ABI is used). This is how it works when a struct has __weak or __strong fields:</div><div class=""><br class=""></div><div class="">1. In CXXRecordDecl::addedMember, pretend that __weak or __strong fields do not make special functions non-trivial for the purpose of calls.</div><div class="">2. If canPassInRegisters returns true, use the C ABI to pass the record, which destructs records in the callee and passes records with __weak fields indirectly (records having __strong fields but no __weak fields are not forced to be passed indirectly). If it returns false, use the C++ ABI, which destructs the record in the caller and passes it indirectly.</div><div class="">3. Since we cannot count on canPassInRegisters to tell whether a record can be passed directly in the presence of a __weak field, CXXRecordDecl::addedMember calls setCanPassInRegisters(false) so that we know the record cannot be passed directly.</div><div class=""><br class=""></div><div class="">hasTrivialABIOverride (which computes "canPassInRegisters() && hasNonTrivialDestructor()") used to determine whether a struct is destructed in the callee, but the function can no longer be used since structs with __weak fields are always passed indirectly.</div><div class=""><br class=""></div></div></div></div><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class="" style="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; text-decoration: none;"><div class="gmail_extra"><div class="gmail_quote"><div class="">Please can you fix these names?</div><div class=""> </div><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;"> /// Look up the special member function that would be called by a special<br class=""><br class="">Modified: cfe/trunk/lib/Serialization/AS<wbr class="">TReaderDecl.cpp<br class="">URL:<span class="m_-7519891156417877842m_-3422063603182055068gmail-m_-8093432400557341289Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/ll<wbr class="">vm-project/cfe/trunk/lib/Seria<wbr class="">lization/ASTReaderDecl.cpp?rev<wbr class="">=328731&r1=328730&r2=328731&vi<wbr class="">ew=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/lib/Serialization/AS<wbr class="">TReaderDecl.cpp (original)<br class="">+++ cfe/trunk/lib/Serialization/AS<wbr class="">TReaderDecl.cpp Wed Mar 28 14:13:14 2018<br class="">@@ -743,6 +743,7 @@ ASTDeclReader::VisitRecordDecl<wbr class="">Impl(Recor<br class="">   RD->setNonTrivialToPrimitiveC<wbr class="">opy(Record.readInt());<br class="">   RD->setNonTrivialToPrimitiveD<wbr class="">estroy(Record.readInt());<br class="">   RD->setCanPassInRegisters(Rec<wbr class="">ord.readInt());<br class="">+  RD->setParamDestroyedInCallee(<wbr class="">Record.readInt());<br class="">   return Redecl;<br class=""> }<br class=""><br class="">@@ -4109,6 +4110,7 @@ void ASTDeclReader::UpdateDecl(Decl *D,<br class="">           OldDD && (OldDD->Definition != RD ||<br class="">                     !Reader.PendingFakeDefinition<wbr class="">Data.count(OldDD));<br class="">       RD->setCanPassInRegisters(Rec<wbr class="">ord.readInt());<br class="">+      RD->setParamDestroyedInCallee(<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/AS<wbr class="">TWriter.cpp<br class="">URL:<span class="m_-7519891156417877842m_-3422063603182055068gmail-m_-8093432400557341289Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/ll<wbr class="">vm-project/cfe/trunk/lib/Seria<wbr class="">lization/ASTWriter.cpp?rev=328<wbr class="">731&r1=328730&r2=328731&view=d<wbr class="">iff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/lib/Serialization/AS<wbr class="">TWriter.cpp (original)<br class="">+++ cfe/trunk/lib/Serialization/AS<wbr class="">TWriter.cpp Wed Mar 28 14:13:14 2018<br class="">@@ -5194,6 +5194,7 @@ void ASTWriter::WriteDeclUpdatesBlo<wbr class="">cks(R<br class="">         auto *RD = cast<CXXRecordDecl>(D);<br class="">         UpdatedDeclContexts.insert(RD<wbr class="">->getPrimaryContext());<br class="">         Record.push_back(RD->canPassI<wbr class="">nRegisters());<br class="">+        Record.push_back(RD->isParamDe<wbr class="">stroyedInCallee());<br class="">         Record.AddCXXDefinitionData(R<wbr class="">D);<br class="">         Record.AddOffset(WriteDeclCon<wbr class="">textLexicalBlock(<br class="">             *Context, const_cast<CXXRecordDecl *>(RD)));<br class=""><br class="">Modified: cfe/trunk/lib/Serialization/AS<wbr class="">TWriterDecl.cpp<br class="">URL:<span class="m_-7519891156417877842m_-3422063603182055068gmail-m_-8093432400557341289Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/ll<wbr class="">vm-project/cfe/trunk/lib/Seria<wbr class="">lization/ASTWriterDecl.cpp?rev<wbr class="">=328731&r1=328730&r2=328731&vi<wbr class="">ew=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/lib/Serialization/AS<wbr class="">TWriterDecl.cpp (original)<br class="">+++ cfe/trunk/lib/Serialization/AS<wbr class="">TWriterDecl.cpp Wed Mar 28 14:13:14 2018<br class="">@@ -470,6 +470,7 @@ void ASTDeclWriter::VisitRecordDecl<wbr class="">(Reco<br class="">   Record.push_back(D->isNonTriv<wbr class="">ialToPrimitiveCopy());<br class="">   Record.push_back(D->isNonTriv<wbr class="">ialToPrimitiveDestroy());<br class="">   Record.push_back(D->canPassIn<wbr class="">Registers());<br class="">+  Record.push_back(D->isParamDes<wbr class="">troyedInCallee());<br class=""><br class="">   if (D->getDeclContext() == D->getLexicalDeclContext() &&<br class="">       !D->hasAttrs() &&<br class="">@@ -1912,6 +1913,8 @@ void ASTWriter::WriteDeclAbbrevs() {<br class="">   // isNonTrivialToPrimitiveDestroy<br class="">   Abv->Add(BitCodeAbbrevOp(BitC<wbr class="">odeAbbrevOp::Fixed, 1));<br class="">   Abv->Add(BitCodeAbbrevOp(BitC<wbr class="">odeAbbrevOp::Fixed, 1)); // canPassInRegisters<br class="">+  // isParamDestroyedInCallee<br class="">+  Abv->Add(BitCodeAbbrevOp(BitCo<wbr class="">deAbbrevOp::Fixed, 1));<br class=""><br class="">   // DC<br class="">   Abv->Add(BitCodeAbbrevOp(BitC<wbr class="">odeAbbrevOp::VBR, 6));   // LexicalOffset<br class=""><br class="">Modified: cfe/trunk/test/CodeGenCXX/micr<wbr class="">osoft-abi-sret-and-byval.cpp<br class="">URL:<span class="m_-7519891156417877842m_-3422063603182055068gmail-m_-8093432400557341289Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/ll<wbr class="">vm-project/cfe/trunk/test/Code<wbr class="">GenCXX/microsoft-abi-sret-and-<wbr class="">byval.cpp?rev=328731&r1=328730<wbr class="">&r2=328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/test/CodeGenCXX/micr<wbr class="">osoft-abi-sret-and-byval.cpp (original)<br class="">+++ cfe/trunk/test/CodeGenCXX/micr<wbr class="">osoft-abi-sret-and-byval.cpp Wed Mar 28 14:13:14 2018<br class="">@@ -172,12 +172,9 @@ void small_arg_with_dtor(SmallWithD<wbr class="">tor s<br class=""> void call_small_arg_with_dtor() {<br class="">   small_arg_with_dtor(SmallWith<wbr class="">Dtor());<br class=""> }<br class="">-// The temporary is copied, so it's destroyed in the caller as well as the<br class="">-// callee.<br class=""> // WIN64-LABEL: define dso_local void @"?call_small_arg_with_dtor@@Y<wbr class="">AXXZ"()<br class=""> // WIN64:   call %struct.SmallWithDtor* @"??0SmallWithDtor@@QEAA@XZ"<br class=""> // WIN64:   call void @"?small_arg_with_dtor@@YAXUSm<wbr class="">allWithDtor@@@Z"(i32 %{{.*}})<br class="">-// WIN64:   call void @"??1SmallWithDtor@@QEAA@XZ"<br class=""> // WIN64:   ret void<br class=""><br class=""> // Test that references aren't destroyed in the callee.<br class=""><br class="">Modified: 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="">URL:<span class="m_-7519891156417877842m_-3422063603182055068gmail-m_-8093432400557341289Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/arc-special-member-functions.mm?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/ll<wbr class="">vm-project/cfe/trunk/test/Code<wbr class="">GenObjCXX/arc-special-member-f<wbr class="">unctions.mm?rev=328731&r1=3287<wbr class="">30&r2=328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- 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><span class="m_-7519891156417877842m_-3422063603182055068gmail-m_-8093432400557341289Apple-converted-space"><wbr class=""> </span>(original)<br class="">+++ 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><span class="m_-7519891156417877842m_-3422063603182055068gmail-m_-8093432400557341289Apple-converted-space"><wbr class=""> </span>Wed Mar 28 14:13:14 2018<br class="">@@ -31,6 +31,8 @@ void test_ObjCMember_copy_construct<wbr class="">_dest<br class=""> void test_ObjCMember_copy_assign(Ob<wbr class="">jCMember m1, ObjCMember m2) {<br class="">   // CHECK: {{call.*_ZN10ObjCMemberaSERKS_<wbr class="">}}<br class="">   m1 = m2;<br class="">+  // CHECK-NEXT: call void @_ZN10ObjCMemberD1Ev(<br class="">+  // CHECK-NEXT: call void @_ZN10ObjCMemberD1Ev(<br class="">   // CHECK-NEXT: ret void<br class=""> }<br class=""><br class="">@@ -58,6 +60,8 @@ void test_ObjCArrayMember_copy_cons<wbr class="">truct<br class=""> void test_ObjCArrayMember_copy_assi<wbr class="">gn(ObjCArrayMember m1, ObjCArrayMember m2) {<br class="">   // CHECK: {{call.*@_ZN15ObjCArrayMembera<wbr class="">SERKS_}}<br class="">   m1 = m2;<br class="">+  // CHECK-NEXT: call void @_ZN15ObjCArrayMemberD1Ev(<br class="">+  // CHECK-NEXT: call void @_ZN15ObjCArrayMemberD1Ev(<br class="">   // CHECK-NEXT: ret void<br class=""> }<br class=""><br class="">@@ -79,7 +83,8 @@ void test_ObjCBlockMember_default_c<wbr class="">onstr<br class=""> void test_ObjCBlockMember_copy_cons<wbr class="">truct_destruct(ObjCBlockMember m1) {<br class="">   // CHECK: call void @_ZN15ObjCBlockMemberC1ERKS_<br class="">   ObjCBlockMember m2 = m1;<br class="">-  // CHECK-NEXT: call void @_ZN15ObjCBlockMemberD1Ev<br class="">+  // CHECK-NEXT: call void @_ZN15ObjCBlockMemberD1Ev(<br class="">+  // CHECK-NEXT: call void @_ZN15ObjCBlockMemberD1Ev(<br class="">   // CHECK-NEXT: ret void<br class=""> }<br class=""><br class="">@@ -87,6 +92,8 @@ void test_ObjCBlockMember_copy_cons<wbr class="">truct<br class=""> void test_ObjCBlockMember_copy_assi<wbr class="">gn(ObjCBlockMember m1, ObjCBlockMember m2) {<br class="">   // CHECK: {{call.*_ZN15ObjCBlockMemberaS<wbr class="">ERKS_}}<br class="">   m1 = m2;<br class="">+  // CHECK-NEXT: call void @_ZN15ObjCBlockMemberD1Ev(<br class="">+  // CHECK-NEXT: call void @_ZN15ObjCBlockMemberD1Ev(<br class="">   // CHECK-NEXT: ret void<br class=""> }<br class=""><br class=""><br class="">Copied: 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><span class="m_-7519891156417877842m_-3422063603182055068gmail-m_-8093432400557341289Apple-converted-space"> </span>(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="">URL:<span class="m_-7519891156417877842m_-3422063603182055068gmail-m_-8093432400557341289Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/objc-struct-cxx-abi.mm?p2=cfe/trunk/test/CodeGenObjCXX/objc-struct-cxx-abi.mm&p1=cfe/trunk/test/CodeGenObjCXX/trivial_abi.mm&r1=328730&r2=328731&rev=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/ll<wbr class="">vm-project/cfe/trunk/test/Code<wbr class="">GenObjCXX/objc-struct-cxx-abi.<wbr class="">mm?p2=cfe/trunk/test/CodeGenOb<wbr class="">jCXX/objc-struct-cxx-abi.mm&p1<wbr class="">=cfe/trunk/test/CodeGenObjCXX/<wbr class="">trivial_abi.mm&r1=328730&r2=32<wbr class="">8731&rev=328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/test/CodeGenObjCXX/<a href="http://trivial_abi.mm/" rel="noreferrer" target="_blank" class="">t<wbr class="">rivial_abi.mm</a><span class="m_-7519891156417877842m_-3422063603182055068gmail-m_-8093432400557341289Apple-converted-space"> </span>(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><span class="m_-7519891156417877842m_-3422063603182055068gmail-m_-8093432400557341289Apple-converted-space"> </span>Wed Mar 28 14:13:14 2018<br class="">@@ -1,27 +1,60 @@<br class=""> // RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fobjc-arc  -fobjc-weak -fobjc-runtime-has-weak -emit-llvm -o - %s | FileCheck %s<br class=""> // RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fobjc-arc  -fobjc-weak -fobjc-runtime-has-weak -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s<br class="">+// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fobjc-arc  -fobjc-weak -fobjc-runtime-has-weak -emit-llvm -o - -DTRIVIALABI %s | FileCheck %s<br class="">+// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fobjc-arc  -fobjc-weak -fobjc-runtime-has-weak -fclang-abi-compat=4.0 -emit-llvm -o - -DTRIVIALABI %s | FileCheck %s<br class="">+<br class="">+// Check that structs consisting solely of __strong or __weak pointer fields are<br class="">+// destructed in the callee function and structs consisting solely of __strong<br class="">+// pointer fields are passed directly.<br class=""><br class=""> // CHECK: %[[STRUCT_STRONGWEAK:.*]] = type { i8*, i8* }<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=""><br class="">+#ifdef TRIVIALABI<br class=""> struct __attribute__((trivial_abi)) StrongWeak {<br class="">+#else<br class="">+struct StrongWeak {<br class="">+#endif<br class="">   id fstrong;<br class="">   __weak id fweak;<br class=""> };<br class=""><br class="">+#ifdef TRIVIALABI<br class=""> struct __attribute__((trivial_abi)) Strong {<br class="">+#else<br class="">+struct Strong {<br class="">+#endif<br class="">   id fstrong;<br class=""> };<br class=""><br class=""> template<class T><br class="">+#ifdef TRIVIALABI<br class=""> struct __attribute__((trivial_abi)) S {<br class="">+#else<br class="">+struct S {<br class="">+#endif<br class="">   T a;<br class=""> };<br class=""><br class="">+struct NonTrivial {<br class="">+  NonTrivial();<br class="">+  NonTrivial(const NonTrivial &);<br class="">+  ~NonTrivial();<br class="">+  int *a;<br class="">+};<br class="">+<br class="">+// This struct is not passed directly nor destructed in the callee because f0<br class="">+// has type NonTrivial.<br class="">+struct ContainsNonTrivial {<br class="">+  NonTrivial f0;<br class="">+  id f1;<br class="">+};<br class="">+<br class=""> // CHECK: define void @_Z19testParamStrongWeak10Stro<wbr class="">ngWeak(%[[STRUCT_STRONGWEAK]]* %{{.*}})<br class="">-// CHECK-NOT: call<br class="">-// CHECK: ret void<br class="">+// CHECK: call %struct.StrongWeak* @_ZN10StrongWeakD1Ev(<br class="">+// CHECK-NEXT: ret void<br class=""><br class=""> void testParamStrongWeak(StrongWeak a) {<br class=""> }<br class="">@@ -33,7 +66,7 @@ void testParamStrongWeak(StrongWeak a) {<br class=""> // CHECK: %[[V0:.*]] = load %[[STRUCT_STRONGWEAK]]*, %[[STRUCT_STRONGWEAK]]** %[[A_ADDR]], align 8<br class=""> // CHECK: %[[CALL:.*]] = call %[[STRUCT_STRONGWEAK]]* @_ZN10StrongWeakC1ERKS_(%[[STR<wbr class="">UCT_STRONGWEAK]]* %[[AGG_TMP]], %[[STRUCT_STRONGWEAK]]* dereferenceable(16) %[[V0]])<br class=""> // CHECK: call void @_Z19testParamStrongWeak10Stro<wbr class="">ngWeak(%[[STRUCT_STRONGWEAK]]* %[[AGG_TMP]])<br class="">-// CHECK: %[[CALL1:.*]] = call %[[STRUCT_STRONGWEAK]]* @_ZN10StrongWeakD1Ev(%[[STRUCT<wbr class="">_STRONGWEAK]]* %[[AGG_TMP]])<br class="">+// CHECK-NOT: call<br class=""> // CHECK: ret void<br class=""><br class=""> void testCallStrongWeak(StrongWeak *a) {<br class="">@@ -96,8 +129,23 @@ Strong testReturnStrong(Strong *a) {<br class=""> }<br class=""><br class=""> // CHECK: define void @_Z21testParamWeakTemplate1SIU<wbr class="">6__weakP11objc_objectE(%[[STRU<wbr class="">CT_S]]* %{{.*}})<br class="">+// CHECK: call %struct.S* @_ZN1SIU6__weakP11objc_objectE<wbr class="">D1Ev(<br class="">+// CHECK-NEXT: ret void<br class="">+<br class="">+void testParamWeakTemplate(S<__weak id> a) {<br class="">+}<br class="">+<br class="">+// CHECK: define void @_Z27testParamContainsNonTrivi<wbr class="">al18ContainsNonTrivial(%[[STRU<wbr class="">CT_CONTAINSNONTRIVIAL]]* %{{.*}})<br class=""> // CHECK-NOT: call<br class=""> // CHECK: ret void<br class=""><br class="">-void testParamWeakTemplate(S<__weak id> a) {<br class="">+void testParamContainsNonTrivial(Co<wbr class="">ntainsNonTrivial a) {<br class="">+}<br class="">+<br class="">+// CHECK: define void @_Z26testCallContainsNonTrivia<wbr class="">lP18ContainsNonTrivial(<br class="">+// CHECK: call void @_Z27testParamContainsNonTrivi<wbr class="">al18ContainsNonTrivial(%[[STRU<wbr class="">CT_CONTAINSNONTRIVIAL]]* %{{.*}})<br class="">+// CHECK: call %struct.ContainsNonTrivial* @_ZN18ContainsNonTrivialD1Ev(%<wbr class="">[[STRUCT_CONTAINSNONTRIVIAL]]* %{{.*}})<br class="">+<br class="">+void testCallContainsNonTrivial(Con<wbr class="">tainsNonTrivial *a) {<br class="">+  testParamContainsNonTrivial(*a<wbr class="">);<br class=""> }<br class=""><br class="">Modified: 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="">URL:<span class="m_-7519891156417877842m_-3422063603182055068gmail-m_-8093432400557341289Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/property-dot-copy-elision.mm?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/ll<wbr class="">vm-project/cfe/trunk/test/Code<wbr class="">GenObjCXX/property-dot-copy-el<wbr class="">ision.mm?rev=328731&r1=328730&<wbr class="">r2=328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- 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><span class="m_-7519891156417877842m_-3422063603182055068gmail-m_-8093432400557341289Apple-converted-space"> </span>(o<wbr class="">riginal)<br class="">+++ 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><span class="m_-7519891156417877842m_-3422063603182055068gmail-m_-8093432400557341289Apple-converted-space"> </span>We<wbr class="">d Mar 28 14:13:14 2018<br class="">@@ -1,11 +1,13 @@<br class=""> // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -std=c++1z -fobjc-arc -o - %s | FileCheck %s<br class=""><br class=""> struct S0 {<br class="">+  ~S0();<br class="">   id f;<br class=""> };<br class=""><br class=""> struct S1 {<br class="">   S1();<br class="">+  ~S1();<br class="">   S1(S0);<br class="">   id f;<br class=""> };<br class=""><br class="">Removed: cfe/trunk/test/CodeGenObjCXX/<a href="http://trivial_abi.mm/" rel="noreferrer" target="_blank" class="">t<wbr class="">rivial_abi.mm</a><br class="">URL:<span class="m_-7519891156417877842m_-3422063603182055068gmail-m_-8093432400557341289Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/trivial_abi.mm?rev=328730&view=auto" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/ll<wbr class="">vm-project/cfe/trunk/test/Code<wbr class="">GenObjCXX/trivial_abi.mm?rev=3<wbr class="">28730&view=auto</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/test/CodeGenObjCXX/<a href="http://trivial_abi.mm/" rel="noreferrer" target="_blank" class="">t<wbr class="">rivial_abi.mm</a><span class="m_-7519891156417877842m_-3422063603182055068gmail-m_-8093432400557341289Apple-converted-space"> </span>(original)<br class="">+++ cfe/trunk/test/CodeGenObjCXX/<a href="http://trivial_abi.mm/" rel="noreferrer" target="_blank" class="">t<wbr class="">rivial_abi.mm</a><span class="m_-7519891156417877842m_-3422063603182055068gmail-m_-8093432400557341289Apple-converted-space"> </span>(removed)<br class="">@@ -1,103 +0,0 @@<br class="">-// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fobjc-arc  -fobjc-weak -fobjc-runtime-has-weak -emit-llvm -o - %s | FileCheck %s<br class="">-// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fobjc-arc  -fobjc-weak -fobjc-runtime-has-weak -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s<br class="">-<br class="">-// CHECK: %[[STRUCT_STRONGWEAK:.*]] = type { i8*, i8* }<br class="">-// CHECK: %[[STRUCT_STRONG:.*]] = type { i8* }<br class="">-// CHECK: %[[STRUCT_S:.*]] = type { i8* }<br class="">-<br class="">-struct __attribute__((trivial_abi)) StrongWeak {<br class="">-  id fstrong;<br class="">-  __weak id fweak;<br class="">-};<br class="">-<br class="">-struct __attribute__((trivial_abi)) Strong {<br class="">-  id fstrong;<br class="">-};<br class="">-<br class="">-template<class T><br class="">-struct __attribute__((trivial_abi)) S {<br class="">-  T a;<br class="">-};<br class="">-<br class="">-// CHECK: define void @_Z19testParamStrongWeak10Stro<wbr class="">ngWeak(%[[STRUCT_STRONGWEAK]]* %{{.*}})<br class="">-// CHECK-NOT: call<br class="">-// CHECK: ret void<br class="">-<br class="">-void testParamStrongWeak(StrongWeak a) {<br class="">-}<br class="">-<br class="">-// CHECK: define void @_Z18testCallStrongWeakP10Stro<wbr class="">ngWeak(%[[STRUCT_STRONGWEAK]]* %[[A:.*]])<br class="">-// CHECK: %[[A_ADDR:.*]] = alloca %[[STRUCT_STRONGWEAK]]*, align 8<br class="">-// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_STRONGWEAK]], align 8<br class="">-// CHECK: store %[[STRUCT_STRONGWEAK]]* %[[A]], %[[STRUCT_STRONGWEAK]]** %[[A_ADDR]], align 8<br class="">-// CHECK: %[[V0:.*]] = load %[[STRUCT_STRONGWEAK]]*, %[[STRUCT_STRONGWEAK]]** %[[A_ADDR]], align 8<br class="">-// CHECK: %[[CALL:.*]] = call %[[STRUCT_STRONGWEAK]]* @_ZN10StrongWeakC1ERKS_(%[[STR<wbr class="">UCT_STRONGWEAK]]* %[[AGG_TMP]], %[[STRUCT_STRONGWEAK]]* dereferenceable(16) %[[V0]])<br class="">-// CHECK: call void @_Z19testParamStrongWeak10Stro<wbr class="">ngWeak(%[[STRUCT_STRONGWEAK]]* %[[AGG_TMP]])<br class="">-// CHECK: %[[CALL1:.*]] = call %[[STRUCT_STRONGWEAK]]* @_ZN10StrongWeakD1Ev(%[[STRUCT<wbr class="">_STRONGWEAK]]* %[[AGG_TMP]])<br class="">-// CHECK: ret void<br class="">-<br class="">-void testCallStrongWeak(StrongWeak *a) {<br class="">-  testParamStrongWeak(*a);<br class="">-}<br class="">-<br class="">-// CHECK: define void @_Z20testReturnStrongWeakP10St<wbr class="">rongWeak(%[[STRUCT_STRONGWEAK:<wbr class="">.*]]* noalias sret %[[AGG_RESULT:.*]], %[[STRUCT_STRONGWEAK]]* %[[A:.*]])<br class="">-// CHECK: %[[A_ADDR:.*]] = alloca %[[STRUCT_STRONGWEAK]]*, align 8<br class="">-// CHECK: store %[[STRUCT_STRONGWEAK]]* %[[A]], %[[STRUCT_STRONGWEAK]]** %[[A_ADDR]], align 8<br class="">-// CHECK: %[[V0:.*]] = load %[[STRUCT_STRONGWEAK]]*, %[[STRUCT_STRONGWEAK]]** %[[A_ADDR]], align 8<br class="">-// CHECK: %[[CALL:.*]] = call %[[STRUCT_STRONGWEAK]]* @_ZN10StrongWeakC1ERKS_(%[[STR<wbr class="">UCT_STRONGWEAK]]* %[[AGG_RESULT]], %[[STRUCT_STRONGWEAK]]* dereferenceable(16) %[[V0]])<br class="">-// CHECK: ret void<br class="">-<br class="">-StrongWeak testReturnStrongWeak(StrongWea<wbr class="">k *a) {<br class="">-  return *a;<br class="">-}<br class="">-<br class="">-// CHECK: define void @_Z15testParamStrong6Strong(i6<wbr class="">4 %[[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="">-// CHECK: %[[COERCE_VAL_IP:.*]] = inttoptr i64 %[[A_COERCE]] to i8*<br class="">-// CHECK: store i8* %[[COERCE_VAL_IP]], i8** %[[COERCE_DIVE]], align 8<br class="">-// CHECK: %[[CALL:.*]] = call %[[STRUCT_STRONG]]* @_ZN6StrongD1Ev(%[[STRUCT_STRO<wbr class="">NG]]* %[[A]])<br class="">-// CHECK: ret void<br class="">-<br class="">-// CHECK: define linkonce_odr %[[STRUCT_STRONG]]* @_ZN6StrongD1Ev(<br class="">-<br class="">-void testParamStrong(Strong a) {<br class="">-}<br class="">-<br class="">-// CHECK: define void @_Z14testCallStrongP6Strong(%[<wbr class="">[STRUCT_STRONG]]* %[[A:.*]])<br class="">-// CHECK: %[[A_ADDR:.*]] = alloca %[[STRUCT_STRONG]]*, align 8<br class="">-// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_STRONG]], align 8<br class="">-// CHECK: store %[[STRUCT_STRONG]]* %[[A]], %[[STRUCT_STRONG]]** %[[A_ADDR]], align 8<br class="">-// CHECK: %[[V0:.*]] = load %[[STRUCT_STRONG]]*, %[[STRUCT_STRONG]]** %[[A_ADDR]], align 8<br class="">-// CHECK: %[[CALL:.*]] = call %[[STRUCT_STRONG]]* @_ZN6StrongC1ERKS_(%[[STRUCT_S<wbr class="">TRONG]]* %[[AGG_TMP]], %[[STRUCT_STRONG]]* dereferenceable(8) %[[V0]])<br class="">-// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], %[[STRUCT_STRONG]]* %[[AGG_TMP]], i32 0, i32 0<br class="">-// CHECK: %[[V1:.*]] = load i8*, i8** %[[COERCE_DIVE]], align 8<br class="">-// CHECK: %[[COERCE_VAL_PI:.*]] = ptrtoint i8* %[[V1]] to i64<br class="">-// CHECK: call void @_Z15testParamStrong6Strong(i6<wbr class="">4 %[[COERCE_VAL_PI]])<br class="">-// CHECK: ret void<br class="">-<br class="">-void testCallStrong(Strong *a) {<br class="">-  testParamStrong(*a);<br class="">-}<br class="">-<br class="">-// CHECK: define i64 @_Z16testReturnStrongP6Strong(<wbr class="">%[[STRUCT_STRONG]]* %[[A:.*]])<br class="">-// CHECK: %[[RETVAL:.*]] = alloca %[[STRUCT_STRONG]], align 8<br class="">-// CHECK: %[[A_ADDR:.*]] = alloca %[[STRUCT_STRONG]]*, align 8<br class="">-// CHECK: store %[[STRUCT_STRONG]]* %[[A]], %[[STRUCT_STRONG]]** %[[A_ADDR]], align 8<br class="">-// CHECK: %[[V0:.*]] = load %[[STRUCT_STRONG]]*, %[[STRUCT_STRONG]]** %[[A_ADDR]], align 8<br class="">-// CHECK: %[[CALL:.*]] = call %[[STRUCT_STRONG]]* @_ZN6StrongC1ERKS_(%[[STRUCT_S<wbr class="">TRONG]]* %[[RETVAL]], %[[STRUCT_STRONG]]* dereferenceable(8) %[[V0]])<br class="">-// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], %[[STRUCT_STRONG]]* %[[RETVAL]], i32 0, i32 0<br class="">-// CHECK: %[[V1:.*]] = load i8*, i8** %[[COERCE_DIVE]], align 8<br class="">-// CHECK: %[[COERCE_VAL_PI:.*]] = ptrtoint i8* %[[V1]] to i64<br class="">-// CHECK: ret i64 %[[COERCE_VAL_PI]]<br class="">-<br class="">-Strong testReturnStrong(Strong *a) {<br class="">-  return *a;<br class="">-}<br class="">-<br class="">-// CHECK: define void @_Z21testParamWeakTemplate1SIU<wbr class="">6__weakP11objc_objectE(%[[STRU<wbr class="">CT_S]]* %{{.*}})<br class="">-// CHECK-NOT: call<br class="">-// CHECK: ret void<br class="">-<br class="">-void testParamWeakTemplate(S<__weak id> a) {<br class="">-}<br class=""><br class=""><br class="">______________________________<wbr class="">_________________<br class="">cfe-commits mailing list<br class=""><a href="mailto:cfe-commits@lists.llvm.org" target="_blank" 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></blockquote></div></div></div></div></blockquote></div><br class=""></div></div></div></div><br class="">______________________________<wbr class="">_________________<br class="">cfe-commits mailing list<br class=""><a href="mailto:cfe-commits@lists.llvm.org" target="_blank" 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></blockquote></div></div></div></div></blockquote></div><br class=""></div></div></div><br class="">______________________________<wbr class="">_________________<br class="">cfe-commits mailing list<br class=""><a href="mailto:cfe-commits@lists.llvm.org" target="_blank" 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></blockquote></div></div></div></div></blockquote></div></div></div><br class=""></div><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></blockquote></div></div></div></div></blockquote></div></div></blockquote></div><br class=""></body></html>