Merge remote-tracking branch 'origin/swift-4.1-branch' into stable
diff --git a/lib/Index/USRGeneration.cpp b/lib/Index/USRGeneration.cpp
index c4fe737..e3371bb 100644
--- a/lib/Index/USRGeneration.cpp
+++ b/lib/Index/USRGeneration.cpp
@@ -753,8 +753,12 @@
     if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) {
       Out << 'F';
       VisitType(FT->getReturnType());
-      for (const auto &I : FT->param_types())
+      Out << '(';
+      for (const auto &I : FT->param_types()) {
+        Out << '#';
         VisitType(I);
+      }
+      Out << ')';
       if (FT->isVariadic())
         Out << '.';
       return;
@@ -815,6 +819,25 @@
       T = VT->getElementType();
       continue;
     }
+    if (const auto *const AT = dyn_cast<ArrayType>(T)) {
+      Out << '{';
+      switch (AT->getSizeModifier()) {
+      case ArrayType::Static:
+        Out << 's';
+        break;
+      case ArrayType::Star:
+        Out << '*';
+        break;
+      case ArrayType::Normal:
+        Out << 'n';
+        break;
+      }
+      if (const auto *const CAT = dyn_cast<ConstantArrayType>(T))
+        Out << CAT->getSize();
+
+      T = AT->getElementType();
+      continue;
+    }
 
     // Unhandled type.
     Out << ' ';
diff --git a/test/Index/USR/array-type.cpp b/test/Index/USR/array-type.cpp
new file mode 100644
index 0000000..40ff20d
--- /dev/null
+++ b/test/Index/USR/array-type.cpp
@@ -0,0 +1,11 @@
+// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s
+
+// Function template specializations differing in array type parameter should have unique USRs.
+
+template<class buffer> void foo(buffer);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n16C>#*C#
+template<> void foo<char[16]>(char[16]);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n32C>#*C#
+template<> void foo<char[32]>(char[32]);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n64C>#*C#
+template<> void foo<char[64]>(char[64]);
diff --git a/test/Index/USR/func-type.cpp b/test/Index/USR/func-type.cpp
new file mode 100644
index 0000000..ff1cd37
--- /dev/null
+++ b/test/Index/USR/func-type.cpp
@@ -0,0 +1,18 @@
+// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s
+
+// Functions taking function pointer parameters with different signatures should result in unique USRs.
+
+typedef void (*_VoidToVoidPtr_)();
+typedef void (*_IntToVoidPtr_)( int );
+typedef _VoidToVoidPtr_ (*IntTo_VoidToVoidPtr_Ptr)( int );
+typedef _IntToVoidPtr_ (*VoidTo_IntToVoidPtr_Ptr)();
+
+void Func( IntTo_VoidToVoidPtr_Ptr );
+// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv()(#I)# |
+void Func( VoidTo_IntToVoidPtr_Ptr );
+// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I)()# |
+
+void Func( void (* (*)(int, int))(int, int) );
+// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I#I)(#I#I)# |
+void Func( void (* (*)(int, int, int))(int) );
+// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I)(#I#I#I)# |