]> granicus.if.org Git - clang/commitdiff
Test explicit specialization for all of the various cases where
authorDouglas Gregor <dgregor@apple.com>
Tue, 6 Oct 2009 21:27:51 +0000 (21:27 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 6 Oct 2009 21:27:51 +0000 (21:27 +0000)
explicit specializations can occur. Also, fix a minor recovery bug
where we should allow declarations coming from the parser to be NULL.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83416 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplate.cpp
test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp [new file with mode: 0644]

index d12ec9318af903fb53b5af168d2272d38e37c773..02c3e43b333e625b71e9a25ef7c4dfdfc5bf32b1 100644 (file)
@@ -257,7 +257,7 @@ bool Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl) {
 /// the parameter D to reference the templated declaration and return a pointer
 /// to the template declaration. Otherwise, do nothing to D and return null.
 TemplateDecl *Sema::AdjustDeclIfTemplate(DeclPtrTy &D) {
-  if (TemplateDecl *Temp = dyn_cast<TemplateDecl>(D.getAs<Decl>())) {
+  if (TemplateDecl *Temp = dyn_cast_or_null<TemplateDecl>(D.getAs<Decl>())) {
     D = DeclPtrTy::make(Temp->getTemplatedDecl());
     return Temp;
   }
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp
new file mode 100644 (file)
index 0000000..f3d0709
--- /dev/null
@@ -0,0 +1,97 @@
+// RUN: clang-cc -fsyntax-only %s
+
+// This test creates cases where implicit instantiations of various entities
+// would cause a diagnostic, but provides expliict specializations for those
+// entities that avoid the diagnostic. The intent is to verify that 
+struct NonDefaultConstructible {
+  NonDefaultConstructible(int);
+};
+
+
+// C++ [temp.expl.spec]p1:
+//   An explicit specialization of any of the following:
+
+//     -- function template
+template<typename T> void f0(T) {
+  T t;
+}
+
+template<> void f0(NonDefaultConstructible) { }
+
+void test_f0(NonDefaultConstructible NDC) {
+  f0(NDC);
+}
+
+//     -- class template
+template<typename T>
+struct X0 {
+  static T member;
+  
+  void f1(T t) {
+    t = 17;
+  }
+  
+  struct Inner : public T { };
+  
+  template<typename U>
+  struct InnerTemplate : public T { };
+  
+  template<typename U>
+  void ft1(T t, U u);
+};
+
+template<typename T> 
+template<typename U>
+void X0<T>::ft1(T t, U u) {
+  t = u;
+}
+
+template<typename T> T X0<T>::member;
+
+template<> struct X0<void> { };
+X0<void> test_X0;
+  
+
+//     -- member function of a class template
+template<> void X0<void*>::f1(void *) { }
+
+void test_spec(X0<void*> xvp, void *vp) {
+  xvp.f1(vp);
+}
+
+//     -- static data member of a class template
+template<> 
+NonDefaultConstructible X0<NonDefaultConstructible>::member = 17;
+
+NonDefaultConstructible &get_static_member() {
+  return X0<NonDefaultConstructible>::member;
+}
+
+//    -- member class of a class template
+template<>
+struct X0<void*>::Inner { };
+
+X0<void*>::Inner inner0;
+
+//    -- member class template of a class template
+template<>
+template<>
+struct X0<void*>::InnerTemplate<int> { };
+
+X0<void*>::InnerTemplate<int> inner_template0;
+
+//    -- member function template of a class template
+template<>
+template<>
+void X0<void*>::ft1(void*, const void*) { }
+
+void test_func_template(X0<void *> xvp, void *vp, const void *cvp) {
+  xvp.ft1(vp, cvp);
+}
+
+// example from the standard:
+template<class T> class stream;
+template<> class stream<char> { /* ... */ };
+template<class T> class Array { /* ... */ }; 
+template<class T> void sort(Array<T>& v) { /* ... */ }
+template<> void sort<char*>(Array<char*>&) ;