Merge pull request #15275 from DougGregor/sr-7182-4.1

[4.1] [SR-7182] Allow ownership keywords on properties in @objc protocols.
diff --git a/lib/Demangling/Demangler.cpp b/lib/Demangling/Demangler.cpp
index 313c908..0434ff9 100644
--- a/lib/Demangling/Demangler.cpp
+++ b/lib/Demangling/Demangler.cpp
@@ -1952,10 +1952,10 @@
   NodePointer Context = popContext();
 
   NodePointer Subscript = createNode(Node::Kind::Subscript);
-  Subscript->addChild(Context, *this);
-  Subscript->addChild(Type, *this);
+  Subscript = addChild(Subscript, Context);
+  Subscript = addChild(Subscript, Type);
   if (PrivateName)
-    Subscript->addChild(PrivateName, *this);
+    Subscript = addChild(Subscript, PrivateName);
 
   return demangleAccessor(Subscript);
 }
diff --git a/lib/Demangling/NodePrinter.cpp b/lib/Demangling/NodePrinter.cpp
index 0c4c0fb..62ab571 100644
--- a/lib/Demangling/NodePrinter.cpp
+++ b/lib/Demangling/NodePrinter.cpp
@@ -541,7 +541,8 @@
   }
 
   void printFunctionType(NodePointer node) {
-    assert(node->getNumChildren() == 2 || node->getNumChildren() == 3);
+    if (node->getNumChildren() != 2 && node->getNumChildren() != 3)
+      return;
     unsigned startIndex = 0;
     bool throws = false;
     if (node->getNumChildren() == 3) {
@@ -1896,9 +1897,10 @@
   }
   if (TypePr != TypePrinting::NoType) {
     NodePointer type = Entity->getChild(1);
-    if (type->getKind() != Node::Kind::Type)
+    if (type->getKind() != Node::Kind::Type && Entity->getNumChildren() >= 3)
       type = Entity->getChild(2);
-    assert(type->getKind() == Node::Kind::Type);
+    if (type->getKind() != Node::Kind::Type)
+      return nullptr;
     type = type->getChild(0);
     if (TypePr == TypePrinting::FunctionStyle) {
       // We expect to see a function type here, but if we don't, use the colon.
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index 34752f7..651e2ab 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -1902,6 +1902,10 @@
         return emitFromValueWitnessTable(IGF.IGM.Context.TheEmptyTupleType);
       }
       case MetatypeRepresentation::Thick:
+        if (isa<ExistentialMetatypeType>(type)) {
+          return emitFromTypeMetadata(type);
+        }
+        // Otherwise, this is a metatype that looks like a pointer.
       case MetatypeRepresentation::ObjC:
         // Thick metatypes look like pointers with spare bits.
         return emitFromValueWitnessTable(
diff --git a/test/Demangle/Inputs/manglings.txt b/test/Demangle/Inputs/manglings.txt
index 6271e48..99ac249 100644
--- a/test/Demangle/Inputs/manglings.txt
+++ b/test/Demangle/Inputs/manglings.txt
@@ -278,4 +278,10 @@
 _T0So5GizmoC12modifyStringSQySSGAD_Si10withNumberSQyypG0D6FoobartFToTembnnnb_ ---> outlined bridged method (mbnnnb) of @objc __ObjC.Gizmo.modifyString(Swift.String!, withNumber: Swift.Int, withFoobar: Any!) -> Swift.String!
 _T04test1SVyxGAA1RA2A1ZRzAA1Y2ZZRpzl1A_AhaGPWT ---> {C} associated type witness table accessor for A.ZZ : test.Y in <A where A: test.Z, A.ZZ: test.Y> test.S<A> : test.R in test
 _T0s24_UnicodeScalarExceptions33_0E4228093681F6920F0AB2E48B4F1C69LLVACycfC ---> Swift.(_UnicodeScalarExceptions in _0E4228093681F6920F0AB2E48B4F1C69).init() -> Swift.(_UnicodeScalarExceptions in _0E4228093681F6920F0AB2E48B4F1C69)
+_$S10NibbleSort0A10CollectionVys6UInt64VAEcis ---> _$S10NibbleSort0A10CollectionVys6UInt64VAEcis
+_T0D ---> _T0D
+_T0s3SetVyxGs10CollectiotySivm ---> _T0s3SetVyxGs10CollectiotySivm
+_T0s18ReversedCollectionVyxGs04LazyB8ProtocolfC ---> _T0s18ReversedCollectionVyxGs04LazyB8ProtocolfC
+_T0iW ---> _T0iW
+_T0s5print_9separator10terminatoryypfC ---> _T0s5print_9separator10terminatoryypfC
 
diff --git a/test/IRGen/type_layout_reference_storage.swift b/test/IRGen/type_layout_reference_storage.swift
index e779a9c..b08c1f9 100644
--- a/test/IRGen/type_layout_reference_storage.swift
+++ b/test/IRGen/type_layout_reference_storage.swift
@@ -91,3 +91,21 @@
   // CHECK: store i8** getelementptr inbounds (i8*, i8** @_T0[[UNKNOWN]]SgXwWV, i32 9)
   weak            var uwi: Unknown!
 }
+
+
+public class Base {
+   var a: UInt32 = 0
+}
+
+// CHECK-LABEL: %swift.type* @create_generic_metadata_Derived(%swift.type_pattern*, i8**)
+// CHECK-NOT: store {{.*}}getelementptr{{.*}}T0BomWV
+// CHECK: call %swift.type* @{{.*}}type_layout_reference_storage1P_pXmTMa()
+// CHECK: store {{.*}}getelementptr{{.*}}T0BoWV
+// CHECK: ret
+public class Derived<T> : Base {
+  var type : P.Type
+  var k = C()
+  init(_ t: P.Type) {
+    type = t
+  }
+}
diff --git a/test/Interpreter/metatype.swift b/test/Interpreter/metatype.swift
new file mode 100644
index 0000000..f8efb06
--- /dev/null
+++ b/test/Interpreter/metatype.swift
@@ -0,0 +1,29 @@
+// RUN: %target-run-simple-swift | %FileCheck %s
+// REQUIRES: executable_test
+
+protocol Bar : class {
+}
+
+public class Foo : Bar {
+}
+
+public class Base {
+   final fileprivate(set) var a: UInt32 = 0
+}
+
+public class Derived<T> : Base {
+  final var type : Bar.Type
+  final var k = Foo()
+
+  init(_ t: Bar.Type, _ kl: Foo ) {
+    type = t
+    k = kl
+  }
+}
+
+public func dontCrash() {
+  // CHECK: Derived<Swift.Int>
+  print(Derived<Int>(Foo.self, Foo()))
+}
+
+dontCrash()