Fix implementation of C11 6.2.7/4 and C++11 [dcl.array]p3:

When a local extern declaration redeclares some other entity, the type of that
entity is merged with the prior type if the prior declaration is visible (in C)
or is declared in the same scope (in C++).

 - Make LookupRedeclarationWithLinkage actually work in C++, use it in the right
   set of cases, and make it track whether it found a shadowed declaration.
 - Track whether we found a declaration in the same scope (for C++) including
   across serialization and template instantiation.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@188307 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Sema/extern-redecl.c b/test/Sema/extern-redecl.c
index e9a4c57..6bdb66e 100644
--- a/test/Sema/extern-redecl.c
+++ b/test/Sema/extern-redecl.c
@@ -62,3 +62,27 @@
   void *(*_malloc)() = &malloc;
   float *(*_calloc)() = &calloc;
 }
+
+void test6() {
+  extern int test6_array1[100];
+  extern int test6_array2[100];
+  void test6_fn1(int*);
+  void test6_fn2(int*);
+  {
+    // Types are only merged from visible declarations.
+    char test6_array2;
+    char test6_fn2;
+    {
+      extern int test6_array1[];
+      extern int test6_array2[];
+      (void)sizeof(test6_array1); // ok
+      (void)sizeof(test6_array2); // expected-error {{incomplete type}}
+
+      void test6_fn1();
+      void test6_fn2();
+      test6_fn1(1.2); // expected-error {{passing 'double' to parameter of incompatible type 'int *'}}
+      // FIXME: This is valid, but we should warn on it.
+      test6_fn2(1.2);
+    }
+  }
+}