Implement the basics of implicit instantiation of class templates, in
response to attempts to diagnose an "incomplete" type. This will force
us to use DiagnoseIncompleteType more regularly (rather than looking at
isIncompleteType), but that's also a good thing.

Implicit instantiation is still very simplistic, and will create a new
definition for the class template specialization (as it should) but it
only actually instantiates the base classes and attaches
those. Actually instantiating class members will follow. 

Also, instantiate the types of non-type template parameters before
checking them,  allowing, e.g., 

  template<typename T, T Value> struct Constant; 
 
to work properly.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65924 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/SemaTemplate/class-template-id-2.cpp b/test/SemaTemplate/class-template-id-2.cpp
index dee4735..3014208 100644
--- a/test/SemaTemplate/class-template-id-2.cpp
+++ b/test/SemaTemplate/class-template-id-2.cpp
@@ -1,16 +1,17 @@
 // RUN: clang -fsyntax-only -verify %s
 namespace N {
-  template<typename T> class A; 
+  template<typename T> class A { };
 
   template<> class A<int> { };
 
+  template<> class A<float>; // expected-note{{forward declaration of 'class A'}}
+
   class B : public A<int> { };
 }
 
 class C1 : public N::A<int> { };
 
-class C2 : public N::A<float> { }; // expected-error{{base class has incomplete type}} \
-           // FIXME: expected-note{{forward declaration of 'class A'}}
+class C2 : public N::A<float> { }; // expected-error{{base class has incomplete type}}
 
 struct D1 {
   operator N::A<int>();
diff --git a/test/SemaTemplate/class-template-spec.cpp b/test/SemaTemplate/class-template-spec.cpp
index e490083..023ba38 100644
--- a/test/SemaTemplate/class-template-spec.cpp
+++ b/test/SemaTemplate/class-template-spec.cpp
@@ -1,5 +1,5 @@
 // RUN: clang -fsyntax-only -verify %s
-template<typename T, typename U = int> struct A; // expected-note{{template is declared here}}
+template<typename T, typename U = int> struct A; // expected-note 2{{template is declared here}}
 
 template<> struct A<double, double>; // expected-note{{forward declaration}}
 
@@ -16,10 +16,10 @@
 }
 
 int test_incomplete_specs(A<double, double> *a1, 
-                          A<double> *a2) // FIXME: expected-note{{forward declaration}}
+                          A<double> *a2)
 {
   (void)a1->x; // expected-error{{incomplete definition of type 'A<double, double>'}}
-  (void)a2->x; // expected-error{{incomplete definition of type 'A<double>'}}
+  (void)a2->x; // expected-error{{implicit instantiation of undefined template 'struct A'}}
 }
 
 typedef float FLOAT;
diff --git a/test/SemaTemplate/instantiation-default-2.cpp b/test/SemaTemplate/instantiation-default-2.cpp
new file mode 100644
index 0000000..e91a98e
--- /dev/null
+++ b/test/SemaTemplate/instantiation-default-2.cpp
@@ -0,0 +1,18 @@
+// RUN: clang -fsyntax-only -verify %s
+
+template<typename T, T Value> struct Constant; // expected-note{{template parameter is declared here}} \
+// FIXME: bad location expected-error{{a non-type template parameter cannot have type 'float'}}
+
+Constant<int, 5> *c1;
+
+int x;
+float f(int, double);
+
+Constant<int&, x> *c2;
+Constant<int*, &x> *c3;
+Constant<float (*)(int, double), f> *c4;
+Constant<float (*)(int, double), &f> *c5;
+
+Constant<float (*)(int, int), f> *c6; // expected-error{{non-type template argument of type 'float (*)(int, double)' cannot be converted to a value of type 'float (*)(int, int)'}}
+
+Constant<float, 0> *c7;