[ClangImporter] Handle inheritance from a class/protocol composition (#12067)

This is legal Objective-C code:

    typedef NSBar <NSFooing> BarAndFoo
    @interface MyBaz : BarAndFoo
    @end

    // Equivalent
    @interface MyBaz : NSBar <NSFooing>
    @end

In Swift 3, we usually handled these by just dropping the protocol
part, making everything appear to work. (The protocols get added to
the class later, without looking at sugar.) However, in Swift 4, we
started supporting these compositions directly* and suddenly
inheriting from them didn't work (read: crashed the compiler). As an
extra twist, even Swift 3 can hit the problem case when the base type
is NSObject, because we figured 'id <NSObject, NSFooing>' was a better
approximation of 'NSObject <NSFooing> *' than 'NSObject *' was.

Fix this by just ignoring protocols when looking for a superclass. As
mentioned, we attach those separately anyway, so we aren't losing any
information.

* This isn't exactly true; there's still a difference between
'NSBar <NSFooing>' and 'NSBar <NSFooing> *'. Jacopo Andrea Giola fixed
a previous issue with this in a598277ad. But Swift doesn't do anything
meaningful with the first form, so it usually just pretends it's the
second.

rdar://problem/34586035
diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp
index ca99376..16f22e8 100644
--- a/lib/ClangImporter/ImportDecl.cpp
+++ b/lib/ClangImporter/ImportDecl.cpp
@@ -4341,9 +4341,10 @@
       SmallVector<TypeLoc, 4> inheritedTypes;
       Type superclassType;
       if (decl->getSuperClass()) {
-        auto clangSuperclassType =
-          Impl.getClangASTContext().getObjCObjectPointerType(
-              clang::QualType(decl->getSuperClassType(), 0));
+        clang::QualType clangSuperclassType =
+          decl->getSuperClassType()->stripObjCKindOfTypeAndQuals(clangCtx);
+        clangSuperclassType =
+          clangCtx.getObjCObjectPointerType(clangSuperclassType);
         superclassType = Impl.importType(clangSuperclassType,
                                          ImportTypeKind::Abstract,
                                          isInSystemModule(dc),
diff --git a/test/ClangImporter/Inputs/custom-modules/SubclassExistentialsExtra.h b/test/ClangImporter/Inputs/custom-modules/SubclassExistentialsExtra.h
new file mode 100644
index 0000000..0ff6e95
--- /dev/null
+++ b/test/ClangImporter/Inputs/custom-modules/SubclassExistentialsExtra.h
@@ -0,0 +1,12 @@
+@import Foundation;
+
+@interface SomeSpecificSubclass : NSObject
+@end
+
+typedef NSObject <NSCopying> CopyableNSObjectBase;
+typedef SomeSpecificSubclass <NSCopying> CopyableSpecificBase;
+
+@interface CompositionSubObject : CopyableNSObjectBase
+@end
+@interface CompositionSubSpecific : CopyableSpecificBase
+@end
diff --git a/test/ClangImporter/Inputs/custom-modules/module.map b/test/ClangImporter/Inputs/custom-modules/module.map
index 9177b5c..9b5c8c4 100644
--- a/test/ClangImporter/Inputs/custom-modules/module.map
+++ b/test/ClangImporter/Inputs/custom-modules/module.map
@@ -140,6 +140,11 @@
   export *
 }
 
+module SubclassExistentialsExtra {
+  header "SubclassExistentialsExtra.h"
+  export *
+}
+
 module SwiftPrivateAttr {
   header "SwiftPrivateAttr.h"
 }
diff --git a/test/ClangImporter/subclass_existentials.swift b/test/ClangImporter/subclass_existentials.swift
index 690d30c..15a085f 100644
--- a/test/ClangImporter/subclass_existentials.swift
+++ b/test/ClangImporter/subclass_existentials.swift
@@ -1,8 +1,9 @@
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify -o - -primary-file %s -swift-version 4
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify -o - -primary-file %s -swift-version 4 -I %S/Inputs/custom-modules/
 
 // REQUIRES: objc_interop
 
 import Foundation
+import SubclassExistentialsExtra
 
 class SwiftLaundryService : NSLaundry {
   var g: (Garment & Coat)? = nil
@@ -39,3 +40,12 @@
 // Make sure the method lookup is not ambiguous
 
 _ = Coat.fashionStatement.wear()
+
+
+func testInheritanceFromComposition(_ object: CompositionSubObject, _ specific: CompositionSubSpecific) {
+  let _: NSObject = object
+  let _: NSCopying = object
+
+  let _: SomeSpecificSubclass = specific
+  let _: NSCopying = specific
+}
diff --git a/test/ClangImporter/subclass_existentials_swift3.swift b/test/ClangImporter/subclass_existentials_swift3.swift
index 7b1c955..4e24b33 100644
--- a/test/ClangImporter/subclass_existentials_swift3.swift
+++ b/test/ClangImporter/subclass_existentials_swift3.swift
@@ -1,8 +1,9 @@
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify -o - -primary-file %s -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify -o - -primary-file %s -swift-version 3 -I %S/Inputs/custom-modules/
 
 // REQUIRES: objc_interop
 
 import Foundation
+import SubclassExistentialsExtra
 
 // FIXME: Consider better diagnostics here.
 
@@ -34,3 +35,11 @@
     return g!
   }
 }
+
+func testInheritanceFromComposition(_ object: CompositionSubObject, _ specific: CompositionSubSpecific) {
+  let _: NSObject = object
+  let _: NSCopying = object
+
+  let _: SomeSpecificSubclass = specific
+  let _: NSCopying = specific
+}