Don't automatically assume that an id-expression refers to a
ValueDecl, because that isn't always the case in ill-formed
code. Diagnose a common mistake (forgetting to provide a template
argument list for a class template, PR5655) and dyn_cast so that we
handle the general problem of referring to a non-value declaration
gracefully.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90239 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index f161cb5..e27b82d 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -489,8 +489,8 @@
   // C++0x CWG Issue #817 indicates that [[final]] classes shouldn't be bases.
   if (CXXBaseDecl->hasAttr<FinalAttr>()) {
     Diag(BaseLoc, diag::err_final_base) << BaseType.getAsString();
-    Diag(CXXBaseDecl->getLocation(), diag::note_previous_class_decl)
-      << BaseType.getAsString();
+    Diag(CXXBaseDecl->getLocation(), diag::note_previous_decl)
+      << BaseType;
     return 0;
   }
 
@@ -1284,7 +1284,7 @@
           Diag(Constructor->getLocation(), diag::err_missing_default_ctor)
             << (int)IsImplicitConstructor << Context.getTagDeclType(ClassDecl)
             << 0 << VBase->getType();
-          Diag(VBaseDecl->getLocation(), diag::note_previous_class_decl)
+          Diag(VBaseDecl->getLocation(), diag::note_previous_decl)
             << Context.getTagDeclType(VBaseDecl);
           HadError = true;
           continue;
@@ -1332,7 +1332,7 @@
           Diag(Constructor->getLocation(), diag::err_missing_default_ctor)
             << (int)IsImplicitConstructor << Context.getTagDeclType(ClassDecl)
             << 0 << Base->getType();
-          Diag(BaseDecl->getLocation(), diag::note_previous_class_decl)
+          Diag(BaseDecl->getLocation(), diag::note_previous_decl)
             << Context.getTagDeclType(BaseDecl);
           HadError = true;
           continue;
@@ -1399,7 +1399,7 @@
           << (int)IsImplicitConstructor << Context.getTagDeclType(ClassDecl)
           << 1 << (*Field)->getDeclName();
         Diag(Field->getLocation(), diag::note_field_decl);
-        Diag(RT->getDecl()->getLocation(), diag::note_previous_class_decl)
+        Diag(RT->getDecl()->getLocation(), diag::note_previous_decl)
           << Context.getTagDeclType(RT->getDecl());
         HadError = true;
         continue;
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index f653cf6..bf14d0d 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1246,7 +1246,23 @@
   if (CheckDeclInExpr(*this, Loc, D))
     return ExprError();
 
-  ValueDecl *VD = cast<ValueDecl>(D);
+  if (TemplateDecl *Template = dyn_cast<TemplateDecl>(D)) {
+    // Specifically diagnose references to class templates that are missing
+    // a template argument list.
+    Diag(Loc, diag::err_template_decl_ref)
+      << Template << SS.getRange();
+    Diag(Template->getLocation(), diag::note_template_decl_here);
+    return ExprError();
+  }
+
+  // Make sure that we're referring to a value.
+  ValueDecl *VD = dyn_cast<ValueDecl>(D);
+  if (!VD) {
+    Diag(Loc, diag::err_ref_non_value) 
+      << D << SS.getRange();
+    Diag(D->getLocation(), diag::note_previous_decl);
+    return ExprError();
+  }
 
   // Check whether this declaration can be used. Note that we suppress
   // this check when we're going to perform argument-dependent lookup