Complain if we're entering the context of a dependent nested-name-specifier but
authorDouglas Gregor <dgregor@apple.com>
Wed, 22 Jul 2009 00:28:09 +0000 (00:28 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 22 Jul 2009 00:28:09 +0000 (00:28 +0000)
cannot match that nested-name-specifier to a class template or class template
partial specialization.

llvm-svn: 76704

clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaCXXScopeSpec.cpp
clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp

index f225b7e80831994db2d2862f0843c3bfb489766f..5a8ffb1bb7c9ac7affdf4ea72661f568c6f4e399 100644 (file)
@@ -793,7 +793,7 @@ def err_template_arg_not_pointer_to_member_form : Error<
 def err_template_arg_extra_parens : Error<
   "non-type template argument cannot be surrounded by parentheses">;
 
-// C++ class template specialization
+// C++ class template specializations and out-of-line definitions
 def err_template_spec_needs_header : Error<
   "template specialization requires 'template<>'">;
 def err_template_spec_needs_template_parameters : Error<
@@ -802,6 +802,9 @@ def err_template_spec_needs_template_parameters : Error<
 def err_template_spec_extra_headers : Error<
   "extraneous template parameter list in template specialization or "
   "out-of-line template definition">;
+def err_template_qualified_declarator_no_match : Error<
+  "nested name specifier '%0' for declaration does not refer to a class "
+  "template or class template partial specialization">;
 def err_template_spec_decl_out_of_scope_global : Error<
   "class template %select{|partial }0specialization of %1 must occur in the "
   "global scope">;
index 7db0da45535e106a18b76d51d8f7f9ce8da68b2d..cf73725e7f36536579d6604feed19114d188160b 100644 (file)
@@ -17,6 +17,7 @@
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/Parse/DeclSpec.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/raw_ostream.h"
 using namespace clang;
 
 /// \brief Compute the DeclContext that is associated with the given
@@ -48,7 +49,7 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS,
     if (EnteringContext) {
       // We are entering the context of the nested name specifier, so try to
       // match the nested name specifier to either a primary class template
-      // or a class template partial specialization
+      // or a class template partial specialization.
       if (const TemplateSpecializationType *SpecType
             = dyn_cast_or_null<TemplateSpecializationType>(NNS->getAsType())) {
         if (ClassTemplateDecl *ClassTemplate 
@@ -64,6 +65,17 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS,
           // FIXME: Class template partial specializations
         }
       }
+      
+      std::string NNSString;
+      {
+        llvm::raw_string_ostream OS(NNSString);
+        NNS->print(OS, Context.PrintingPolicy);
+      }
+      
+      // FIXME: Allow us to pass a nested-name-specifier to Diag?
+      Diag(SS.getRange().getBegin(), 
+           diag::err_template_qualified_declarator_no_match)
+        << NNSString << SS.getRange();
     }
     
     return 0;
index 6979b4135c8fafb9a08b03408dd14cd8840cdfd3..c1da8a1f4804d5a5f7992fedbb7c996dcccadc0d 100644 (file)
@@ -12,6 +12,7 @@ public:
   void f1(size_type) const;
   void f2(size_type) const;
   void f3(size_type) const;
+  void f4() ;
   
   T value;
 };
@@ -36,6 +37,9 @@ template<class X, class Y, class Z> // expected-error{{too many template paramet
 void X0<X, Y>::f3(size_type) const {
 }
 
+template<class X, class Y> 
+void X0<Y, X>::f4() { } // expected-error{{does not refer to}}
+
 // FIXME: error message should probably say, "redefinition of 'X0<T, U>::f0'"
 // rather than just "redefinition of 'f0'"
 template<typename T, typename U>