Implement basic parsing and semantic analysis for explicit
specialization of class templates, e.g.,

  template<typename T> class X;

  template<> class X<int> { /* blah */ };

Each specialization is a different *Decl node (naturally), and can
have different members. We keep track of forward declarations and
definitions as for other class/struct/union types.

This is only the basic framework: we still have to deal with checking
the template headers properly, improving recovery when there are
failures, handling nested name specifiers, etc.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64848 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/SemaTemplate/class-template-spec.cpp b/test/SemaTemplate/class-template-spec.cpp
new file mode 100644
index 0000000..db67598
--- /dev/null
+++ b/test/SemaTemplate/class-template-spec.cpp
@@ -0,0 +1,31 @@
+// RUN: clang -fsyntax-only -verify %s
+template<typename T, typename U = int> class A;
+
+template<> class A<double, double>; // expected-note{{forward declaration}}
+
+template<> class A<float, float> {  // expected-note{{previous definition}}
+  int x;
+};
+
+template<> class A<float> { // expected-note{{previous definition}}
+  int y;
+};
+
+int test_specs(A<float, float> *a1, A<float, int> *a2) {
+  return a1->x + a2->y;
+}
+
+int test_incomplete_specs(A<double, double> *a1, 
+                          A<double> *a2) // FIXME: expected-note{{forward declaration}}
+{
+  (void)a1->x; // expected-error{{incomplete definition of type 'A<double, double>'}}
+  (void)a2->x; // expected-error{{incomplete definition of type 'A<double>'}}
+}
+
+typedef float FLOAT;
+
+template<> class A<float, FLOAT>;
+
+template<> class A<FLOAT, float> { }; // expected-error{{redefinition}}
+
+template<> class A<float, int> { }; // expected-error{{redefinition}}