[ObjC++] Make parameter passing and function return compatible with ObjC
    
ObjC and ObjC++ pass non-trivial structs in a way that is incompatible
with each other. For example:
    
typedef struct {
  id f0;
  __weak id f1;
} S;
    
// this code is compiled in c++.
extern "C" {
  void foo(S s);
}
    
void caller() {
  // the caller passes the parameter indirectly and destructs it.
  foo(S());
}
    
// this function is compiled in c.
// 'a' is passed directly and is destructed in the callee.
void foo(S a) {
}
    
This patch fixes the incompatibility by passing and returning structs
with __strong or weak fields using the C ABI in C++ mode. __strong and
__weak fields in a struct do not cause the struct to be destructed in
the caller and __strong fields do not cause the struct to be passed
indirectly.
    
Also, this patch fixes the microsoft ABI bug mentioned here:
    
https://reviews.llvm.org/D41039?id=128767#inline-364710
    
rdar://problem/38887866
    
Differential Revision: https://reviews.llvm.org/D44908

llvm-svn: 328731
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 77c06f2..ea96a07 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -2643,9 +2643,11 @@
 }
 
 bool ASTContext::isParamDestroyedInCallee(QualType T) const {
-  return getTargetInfo().getCXXABI().areArgsDestroyedLeftToRightInCallee() ||
-         T.hasTrivialABIOverride() ||
-         T.isDestructedType() == QualType::DK_nontrivial_c_struct;
+  if (getTargetInfo().getCXXABI().areArgsDestroyedLeftToRightInCallee())
+    return true;
+  if (const auto *RT = T->getBaseElementTypeUnsafe()->getAs<RecordType>())
+    return RT->getDecl()->isParamDestroyedInCallee();
+  return false;
 }
 
 /// getComplexType - Return the uniqued reference to the type for a complex
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index ed80dd8..4fb687d 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -3951,7 +3951,7 @@
       LoadedFieldsFromExternalStorage(false),
       NonTrivialToPrimitiveDefaultInitialize(false),
       NonTrivialToPrimitiveCopy(false), NonTrivialToPrimitiveDestroy(false),
-      CanPassInRegisters(true) {
+      CanPassInRegisters(true), ParamDestroyedInCallee(false) {
   assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
 }
 
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 2718723..1e1ee43 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -801,7 +801,17 @@
         struct DefinitionData &Data = data();
         Data.PlainOldData = false;
         Data.HasTrivialSpecialMembers = 0;
-        Data.HasTrivialSpecialMembersForCall = 0;
+
+        // __strong or __weak fields do not make special functions non-trivial
+        // for the purpose of calls.
+        Qualifiers::ObjCLifetime LT = T.getQualifiers().getObjCLifetime();
+        if (LT != Qualifiers::OCL_Strong && LT != Qualifiers::OCL_Weak)
+          data().HasTrivialSpecialMembersForCall = 0;
+
+        // Structs with __weak fields should never be passed directly.
+        if (LT == Qualifiers::OCL_Weak)
+          setCanPassInRegisters(false);
+
         Data.HasIrrelevantDestructor = false;
       } else if (!Context.getLangOpts().ObjCAutoRefCount) {
         setHasObjectMember(true);
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 2985aac..d8b9967 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2195,12 +2195,6 @@
   return false;
 }
 
-bool QualType::hasTrivialABIOverride() const {
-  if (const auto *RD = getTypePtr()->getAsCXXRecordDecl())
-    return RD->hasTrivialABIOverride();
-  return false;
-}
-
 bool QualType::isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const {
   return !Context.getLangOpts().ObjCAutoRefCount &&
          Context.getLangOpts().ObjCWeak &&