Rip out the existing retroactive abstract-class usage checker,
which in a fit of zeal wanted to walk the entire translation unit,
and replace it with a new checker that walks the types of declarations
nested within the class.  Also, look into templates when doing this.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111357 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/SemaCXX/abstract.cpp b/test/SemaCXX/abstract.cpp
index f64fda4..e448f17 100644
--- a/test/SemaCXX/abstract.cpp
+++ b/test/SemaCXX/abstract.cpp
@@ -67,20 +67,23 @@
   virtual void f() = 0; // expected-note {{pure virtual function 'f'}}
 };
 
+// Diagnosing in these cases is prohibitively expensive.  We still
+// diagnose at the function definition, of course.
+
 class Abstract;
 
-void t7(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}}
+void t7(Abstract a);
 
 void t8() {
-  void h(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}}
+  void h(Abstract a);
 }
 
 namespace N {
-void h(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}}
+void h(Abstract a);
 }
 
 class Abstract {
-  virtual void f() = 0; // expected-note {{pure virtual function 'f'}}
+  virtual void f() = 0;
 };
 
 // <rdar://problem/6854087>
@@ -186,3 +189,19 @@
     C c;
   }
 }
+
+// rdar://problem/8302168
+namespace test2 {
+  struct X1 {
+    virtual void xfunc(void) = 0;  // expected-note {{pure virtual function}}
+    void g(X1 parm7);        // expected-error {{parameter type 'test2::X1' is an abstract class}}
+    void g(X1 parm8[2]);     // expected-error {{array of abstract class type 'test2::X1'}}
+  };
+
+  template <int N>
+  struct X2 {
+    virtual void xfunc(void) = 0;  // expected-note {{pure virtual function}}
+    void g(X2 parm10);        // expected-error {{parameter type 'X2<N>' is an abstract class}}
+    void g(X2 parm11[2]);     // expected-error {{array of abstract class type 'X2<N>'}}
+  };
+}