[cfe-commits] r84028 - in /cfe/trunk: include/clang/Basic/Diagnostic.h include/clang/Basic/DiagnosticSemaKinds.td lib/Basic/Diagnostic.cpp lib/Sema/Sema.cpp lib/Sema/Sema.h lib/Sema/SemaCXXScopeSpec.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaTemplate.cpp test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp test/SemaCXX/missing-members.cpp test/SemaCXX/nested-name-spec.cpp test/SemaTemplate/typename-specifier.cpp

Douglas Gregor dgregor at apple.com
Tue Oct 13 14:16:45 PDT 2009


Author: dgregor
Date: Tue Oct 13 16:16:44 2009
New Revision: 84028

URL: http://llvm.org/viewvc/llvm-project?rev=84028&view=rev
Log:
Unify our diagnostic printing for errors of the form, "we didn't like
what we found when we looked into <blah>", where <blah> is a
DeclContext*. We can now format DeclContext*'s in nice ways, e.g.,
"namespace N", "the global namespace", "'class Foo'".

This is part of PR3990, but we're not quite there yet.


Modified:
    cfe/trunk/include/clang/Basic/Diagnostic.h
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Basic/Diagnostic.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp
    cfe/trunk/test/SemaCXX/missing-members.cpp
    cfe/trunk/test/SemaCXX/nested-name-spec.cpp
    cfe/trunk/test/SemaTemplate/typename-specifier.cpp

Modified: cfe/trunk/include/clang/Basic/Diagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Diagnostic.h?rev=84028&r1=84027&r2=84028&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/Diagnostic.h (original)
+++ cfe/trunk/include/clang/Basic/Diagnostic.h Tue Oct 13 16:16:44 2009
@@ -15,6 +15,7 @@
 #define LLVM_CLANG_DIAGNOSTIC_H
 
 #include "clang/Basic/SourceLocation.h"
+#include "llvm/Support/type_traits.h"
 #include <string>
 #include <vector>
 #include <cassert>
@@ -24,6 +25,7 @@
 }
 
 namespace clang {
+  class DeclContext;
   class DiagnosticBuilder;
   class DiagnosticClient;
   class IdentifierInfo;
@@ -158,7 +160,8 @@
     ak_qualtype,        // QualType
     ak_declarationname, // DeclarationName
     ak_nameddecl,       // NamedDecl *
-    ak_nestednamespec   // NestedNameSpecifier *
+    ak_nestednamespec,  // NestedNameSpecifier *
+    ak_declcontext      // DeclContext *
   };
 
 private:
@@ -613,6 +616,20 @@
   return DB;
 }
 
+// Adds a DeclContext to the diagnostic. The enable_if template magic is here
+// so that we only match those arguments that are (statically) DeclContexts;
+// other arguments that derive from DeclContext (e.g., RecordDecls) will not
+// match.
+template<typename T>
+inline
+typename llvm::enable_if<llvm::is_same<T, DeclContext>, 
+                         const DiagnosticBuilder &>::type
+operator<<(const DiagnosticBuilder &DB, T *DC) {
+  DB.AddTaggedVal(reinterpret_cast<intptr_t>(DC),
+                  Diagnostic::ak_declcontext);
+  return DB;
+}
+  
 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
                                            const SourceRange &R) {
   DB.AddSourceRange(R);

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=84028&r1=84027&r2=84028&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Oct 13 16:16:44 2009
@@ -1107,10 +1107,8 @@
   
 // C++ typename-specifiers
 def err_typename_nested_not_found : Error<"no type named %0 in %1">;
-def err_typename_nested_not_found_global : Error<
-    "no type named %0 in the global namespace">;
 def err_typename_nested_not_type : Error<
-    "typename specifier refers to non-type member %0">;
+    "typename specifier refers to non-type member %0 in %1">;
 def note_typename_refers_here : Note<
     "referenced member %0 is declared here">;
 
@@ -1405,17 +1403,11 @@
   InGroup<CharSubscript>, DefaultIgnore;
 
 def err_typecheck_incomplete_tag : Error<"incomplete definition of type %0">;
-def err_typecheck_no_member_deprecated : Error<"no member named %0">;
-def err_typecheck_record_no_member : Error<
-  "no member named %0 in %select{struct|union|class|enum}1 %q2">;
-def err_typecheck_namespace_no_member : Error<
-  "no member named %0 in namespace %q1">;
-def err_typecheck_global_namespace_no_member : Error<
-  "no member named %0 in the global namespace">;
+def err_no_member : Error<"no member named %0 in %1">;
 
 def err_member_redeclared : Error<"class member cannot be redeclared">;
 def err_member_def_does_not_match : Error<
-  "out-of-line definition does not match any declaration in %0">;
+  "out-of-line definition of %0 does not match any declaration in %1">;
 def err_nonstatic_member_out_of_line : Error<
   "non-static data member defined out-of-line">;
 def err_qualified_typedef_declarator : Error<

Modified: cfe/trunk/lib/Basic/Diagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Diagnostic.cpp?rev=84028&r1=84027&r2=84028&view=diff

==============================================================================
--- cfe/trunk/lib/Basic/Diagnostic.cpp (original)
+++ cfe/trunk/lib/Basic/Diagnostic.cpp Tue Oct 13 16:16:44 2009
@@ -802,6 +802,7 @@
     case Diagnostic::ak_declarationname:
     case Diagnostic::ak_nameddecl:
     case Diagnostic::ak_nestednamespec:
+    case Diagnostic::ak_declcontext:
       getDiags()->ConvertArgToString(getArgKind(ArgNo), getRawArg(ArgNo),
                                      Modifier, ModifierLen,
                                      Argument, ArgumentLen, OutStr);

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=84028&r1=84027&r2=84028&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Tue Oct 13 16:16:44 2009
@@ -23,6 +23,54 @@
 #include "clang/Basic/TargetInfo.h"
 using namespace clang;
 
+/// \brief Convert the given type to a string suitable for printing as part of 
+/// a diagnostic. 
+///
+/// \param Context the context in which the type was allocated
+/// \param Ty the type to print
+static std::string ConvertTypeToDiagnosticString(ASTContext &Context,
+                                                 QualType Ty) {
+  // FIXME: Playing with std::string is really slow.
+  std::string S = Ty.getAsString(Context.PrintingPolicy);
+  
+  // If this is a sugared type (like a typedef, typeof, etc), then unwrap one
+  // level of the sugar so that the type is more obvious to the user.
+  QualType DesugaredTy = Ty.getDesugaredType();
+  
+  if (Ty != DesugaredTy &&
+      // If the desugared type is a vector type, we don't want to expand it,
+      // it will turn into an attribute mess. People want their "vec4".
+      !isa<VectorType>(DesugaredTy) &&
+      
+      // Don't aka just because we saw an elaborated type...
+      (!isa<ElaboratedType>(Ty) ||
+       cast<ElaboratedType>(Ty)->desugar() != DesugaredTy) &&
+      
+      // ...or a qualified name type...
+      (!isa<QualifiedNameType>(Ty) ||
+       cast<QualifiedNameType>(Ty)->desugar() != DesugaredTy) &&
+      
+      // ...or a non-dependent template specialization.
+      (!isa<TemplateSpecializationType>(Ty) || Ty->isDependentType()) &&
+      
+      // Don't desugar magic Objective-C types.
+      Ty.getUnqualifiedType() != Context.getObjCIdType() &&
+      Ty.getUnqualifiedType() != Context.getObjCClassType() &&
+      Ty.getUnqualifiedType() != Context.getObjCSelType() &&
+      Ty.getUnqualifiedType() != Context.getObjCProtoType() &&
+      
+      // Not va_list.
+      Ty.getUnqualifiedType() != Context.getBuiltinVaListType()) {
+    S = "'"+S+"' (aka '";
+    S += DesugaredTy.getAsString(Context.PrintingPolicy);
+    S += "')";
+    return S;
+  }
+
+  S = "'" + S + "'";
+  return S;
+}
+                                       
 /// ConvertQualTypeToStringFn - This function is used to pretty print the
 /// specified QualType as a string in diagnostics.
 static void ConvertArgToStringFn(Diagnostic::ArgumentKind Kind, intptr_t Val,
@@ -33,50 +81,14 @@
   ASTContext &Context = *static_cast<ASTContext*>(Cookie);
 
   std::string S;
+  bool NeedQuotes = true;
   if (Kind == Diagnostic::ak_qualtype) {
     assert(ModLen == 0 && ArgLen == 0 &&
            "Invalid modifier for QualType argument");
 
     QualType Ty(QualType::getFromOpaquePtr(reinterpret_cast<void*>(Val)));
-
-    // FIXME: Playing with std::string is really slow.
-    S = Ty.getAsString(Context.PrintingPolicy);
-
-    // If this is a sugared type (like a typedef, typeof, etc), then unwrap one
-    // level of the sugar so that the type is more obvious to the user.
-    QualType DesugaredTy = Ty.getDesugaredType();
-
-    if (Ty != DesugaredTy &&
-        // If the desugared type is a vector type, we don't want to expand it,
-        // it will turn into an attribute mess. People want their "vec4".
-        !isa<VectorType>(DesugaredTy) &&
-
-        // Don't aka just because we saw an elaborated type...
-        (!isa<ElaboratedType>(Ty) ||
-         cast<ElaboratedType>(Ty)->desugar() != DesugaredTy) &&
-
-        // ...or a qualified name type...
-        (!isa<QualifiedNameType>(Ty) ||
-         cast<QualifiedNameType>(Ty)->desugar() != DesugaredTy) &&
-
-        // ...or a non-dependent template specialization.
-        (!isa<TemplateSpecializationType>(Ty) || Ty->isDependentType()) &&
-
-        // Don't desugar magic Objective-C types.
-        Ty.getUnqualifiedType() != Context.getObjCIdType() &&
-        Ty.getUnqualifiedType() != Context.getObjCClassType() &&
-        Ty.getUnqualifiedType() != Context.getObjCSelType() &&
-        Ty.getUnqualifiedType() != Context.getObjCProtoType() &&
-
-        // Not va_list.
-        Ty.getUnqualifiedType() != Context.getBuiltinVaListType()) {
-      S = "'"+S+"' (aka '";
-      S += DesugaredTy.getAsString(Context.PrintingPolicy);
-      S += "')";
-      Output.append(S.begin(), S.end());
-      return;
-    }
-
+    S = ConvertTypeToDiagnosticString(Context, Ty);
+    NeedQuotes = false;
   } else if (Kind == Diagnostic::ak_declarationname) {
 
     DeclarationName N = DeclarationName::getFromOpaqueInteger(Val);
@@ -101,16 +113,50 @@
     reinterpret_cast<NamedDecl*>(Val)->getNameForDiagnostic(S,
                                                          Context.PrintingPolicy,
                                                             Qualified);
-  } else {
+  } else if (Kind == Diagnostic::ak_nestednamespec) {
     llvm::raw_string_ostream OS(S);
-    assert(Kind == Diagnostic::ak_nestednamespec);
     reinterpret_cast<NestedNameSpecifier*> (Val)->print(OS,
                                                         Context.PrintingPolicy);
+  } else {
+    assert(Kind == Diagnostic::ak_declcontext);
+    DeclContext *DC = reinterpret_cast<DeclContext *> (Val);
+    NeedQuotes = false;
+    if (!DC) {
+      assert(false && "Should never have a null declaration context");
+      S = "unknown context";
+    } else if (DC->isTranslationUnit()) {
+      // FIXME: Get these strings from some localized place
+      if (Context.getLangOptions().CPlusPlus)
+        S = "the global namespace";
+      else
+        S = "the global scope";
+    } else if (TypeDecl *Type = dyn_cast<TypeDecl>(DC)) {
+      S = ConvertTypeToDiagnosticString(Context, Context.getTypeDeclType(Type));
+      NeedQuotes = false;
+    } else {
+      // FIXME: Get these strings from some localized place
+      NamedDecl *ND = cast<NamedDecl>(DC);
+      if (isa<NamespaceDecl>(ND))
+        S += "namespace ";
+      else if (isa<ObjCMethodDecl>(ND))
+        S += "method ";
+      else if (isa<FunctionDecl>(ND))
+        S += "function ";
+
+      S += "'";
+      ND->getNameForDiagnostic(S, Context.PrintingPolicy, true);
+      S += "'";
+      NeedQuotes = false;
+    }
   }
 
-  Output.push_back('\'');
+  if (NeedQuotes)
+    Output.push_back('\'');
+  
   Output.append(S.begin(), S.end());
-  Output.push_back('\'');
+  
+  if (NeedQuotes)
+    Output.push_back('\'');
 }
 
 
@@ -363,31 +409,6 @@
   return 0;
 }
 
-void Sema::DiagnoseMissingMember(SourceLocation MemberLoc,
-                                 DeclarationName Member,
-                                 NestedNameSpecifier *NNS, SourceRange Range) {
-  switch (NNS->getKind()) {
-  default: assert(0 && "Unexpected nested name specifier kind!");
-  case NestedNameSpecifier::TypeSpec: {
-    const Type *Ty = Context.getCanonicalType(NNS->getAsType());
-    RecordDecl *RD = cast<RecordType>(Ty)->getDecl();
-    Diag(MemberLoc, diag::err_typecheck_record_no_member)
-      << Member << RD->getTagKind() << RD << Range;
-    break;
-  }
-  case NestedNameSpecifier::Namespace: {
-    Diag(MemberLoc, diag::err_typecheck_namespace_no_member)
-       << Member << NNS->getAsNamespace() << Range;
-    break;
-  }
-  case NestedNameSpecifier::Global: {
-    Diag(MemberLoc, diag::err_typecheck_global_namespace_no_member)
-      << Member << Range;
-    break;
-  }
-  }
-}
-
 Sema::SemaDiagnosticBuilder::~SemaDiagnosticBuilder() {
   if (!this->Emit())
     return;

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=84028&r1=84027&r2=84028&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Oct 13 16:16:44 2009
@@ -3720,9 +3720,6 @@
                       QualType FieldTy, const Expr *BitWidth,
                       bool *ZeroWidth = 0);
 
-  void DiagnoseMissingMember(SourceLocation MemberLoc, DeclarationName Member,
-                             NestedNameSpecifier *NNS, SourceRange Range);
-
   /// adjustFunctionParamType - Converts the type of a function parameter to a
   // type that can be passed as an argument type to
   /// ASTContext::getFunctionType.

Modified: cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp?rev=84028&r1=84027&r2=84028&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp Tue Oct 13 16:16:44 2009
@@ -471,9 +471,7 @@
   if (SD)
     DiagID = diag::err_expected_class_or_namespace;
   else if (SS.isSet()) {
-    DiagnoseMissingMember(IdLoc, DeclarationName(&II),
-                          (NestedNameSpecifier *)SS.getScopeRep(),
-                          SS.getRange());
+    Diag(IdLoc, diag::err_no_member) << &II << LookupCtx << SS.getRange();
     return 0;
   } else
     DiagID = diag::err_undeclared_var_use;

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=84028&r1=84027&r2=84028&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Oct 13 16:16:44 2009
@@ -2229,10 +2229,9 @@
     }
   } else if (D.getCXXScopeSpec().isSet()) {
     // No previous declaration in the qualifying scope.
-    NestedNameSpecifier *NNS =
-      (NestedNameSpecifier *)D.getCXXScopeSpec().getScopeRep();
-    DiagnoseMissingMember(D.getIdentifierLoc(), Name, NNS,
-                          D.getCXXScopeSpec().getRange());
+    Diag(D.getIdentifierLoc(), diag::err_no_member)
+      << Name << computeDeclContext(D.getCXXScopeSpec(), true)
+      << D.getCXXScopeSpec().getRange();
     NewVD->setInvalidDecl();
   }
 
@@ -2844,7 +2843,7 @@
       // matches (e.g., those that differ only in cv-qualifiers and
       // whether the parameter types are references).
       Diag(D.getIdentifierLoc(), diag::err_member_def_does_not_match)
-        << cast<NamedDecl>(DC) << D.getCXXScopeSpec().getRange();
+        << Name << DC << D.getCXXScopeSpec().getRange();
       NewFD->setInvalidDecl();
 
       LookupResult Prev;

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=84028&r1=84027&r2=84028&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Oct 13 16:16:44 2009
@@ -2767,7 +2767,8 @@
   LookupQualifiedName(R, LookupContext, Name, LookupOrdinaryName);
 
   if (R.empty()) {
-    DiagnoseMissingMember(IdentLoc, Name, NNS, SS.getRange());
+    Diag(IdentLoc, diag::err_no_member) 
+      << Name << LookupContext << SS.getRange();
     return 0;
   }
 

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=84028&r1=84027&r2=84028&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Oct 13 16:16:44 2009
@@ -802,12 +802,11 @@
     else {
       // If this name wasn't predeclared and if this is not a function call,
       // diagnose the problem.
-      if (SS && !SS->isEmpty()) {
-        DiagnoseMissingMember(Loc, Name,
-                              (NestedNameSpecifier *)SS->getScopeRep(),
-                              SS->getRange());
-        return ExprError();
-      } else if (Name.getNameKind() == DeclarationName::CXXOperatorName ||
+      if (SS && !SS->isEmpty())
+        return ExprError(Diag(Loc, diag::err_no_member)
+                           << Name << computeDeclContext(*SS, false)
+                           << SS->getRange());
+      else if (Name.getNameKind() == DeclarationName::CXXOperatorName ||
                Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
         return ExprError(Diag(Loc, diag::err_undeclared_use)
           << Name.getAsString());
@@ -2185,8 +2184,8 @@
     LookupQualifiedName(Result, DC, MemberName, LookupMemberName, false);
 
     if (Result.empty())
-      return ExprError(Diag(MemberLoc, diag::err_typecheck_no_member_deprecated)
-               << MemberName << BaseExpr->getSourceRange());
+      return ExprError(Diag(MemberLoc, diag::err_no_member)
+               << MemberName << DC << BaseExpr->getSourceRange());
     if (Result.isAmbiguous()) {
       DiagnoseAmbiguousLookup(Result, MemberName, MemberLoc,
                               BaseExpr->getSourceRange());
@@ -5689,8 +5688,8 @@
         = dyn_cast_or_null<FieldDecl>(R.getAsSingleDecl(Context));
       // FIXME: Leaks Res
       if (!MemberDecl)
-        return ExprError(Diag(BuiltinLoc, diag::err_typecheck_no_member_deprecated)
-         << OC.U.IdentInfo << SourceRange(OC.LocStart, OC.LocEnd));
+        return ExprError(Diag(BuiltinLoc, diag::err_no_member)
+         << OC.U.IdentInfo << RD << SourceRange(OC.LocStart, OC.LocEnd));
 
       // FIXME: C++: Verify that MemberDecl isn't a static field.
       // FIXME: Verify that MemberDecl isn't a bitfield.

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=84028&r1=84027&r2=84028&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue Oct 13 16:16:44 2009
@@ -3903,10 +3903,7 @@
   Decl *Referenced = 0;
   switch (Result.getKind()) {
   case LookupResult::NotFound:
-    if (Ctx->isTranslationUnit())
-      DiagID = diag::err_typename_nested_not_found_global;
-    else
-      DiagID = diag::err_typename_nested_not_found;
+    DiagID = diag::err_typename_nested_not_found;
     break;
 
   case LookupResult::Found:
@@ -3933,10 +3930,7 @@
 
   // If we get here, it's because name lookup did not find a
   // type. Emit an appropriate diagnostic and return an error.
-  if (NamedDecl *NamedCtx = dyn_cast<NamedDecl>(Ctx))
-    Diag(Range.getEnd(), DiagID) << Range << Name << NamedCtx;
-  else
-    Diag(Range.getEnd(), DiagID) << Range << Name;
+  Diag(Range.getEnd(), DiagID) << Range << Name << Ctx;
   if (Referenced)
     Diag(Referenced->getLocation(), diag::note_typename_refers_here)
       << Name;

Modified: cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp?rev=84028&r1=84027&r2=84028&view=diff

==============================================================================
--- cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp Tue Oct 13 16:16:44 2009
@@ -9,12 +9,12 @@
 template<> template<class X>
 class A<long>::B { }; 
 
-// FIXME: If we make the explicit specialization of A<long>::B, above, into
-// a specialization of A<int>::B, our diagnostic is correct but not very 
-// helpful.
 template<> template<> template<class T>
   void A<int>::B<double>::mf1(T t) { } 
 
+template<> template<> template<class T>
+void A<long>::B<double>::mf1(T t) { } // expected-error{{does not match}}
+
 // FIXME: This diagnostic could probably be better.
 template<class Y> template<>
   void A<Y>::B<double>::mf2() { } // expected-error{{does not refer}}

Modified: cfe/trunk/test/SemaCXX/missing-members.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/missing-members.cpp?rev=84028&r1=84027&r2=84028&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/missing-members.cpp (original)
+++ cfe/trunk/test/SemaCXX/missing-members.cpp Tue Oct 13 16:16:44 2009
@@ -9,7 +9,7 @@
 
 void f() {
   A::B::i; // expected-error {{no member named 'i' in namespace 'A::B'}}
-  A::B::C::i; // expected-error {{no member named 'i' in class 'A::B::C'}}
+  A::B::C::i; // expected-error {{no member named 'i' in 'class A::B::C'}}
   ::i; // expected-error {{no member named 'i' in the global namespace}}
 }
 
@@ -19,18 +19,18 @@
 
 void g() {
   A::B::D::E; // expected-error {{no member named 'D' in namespace 'A::B'}}
-  B::B::C::D; // expected-error {{no member named 'C' in class 'B::B'}}
+  B::B::C::D; // expected-error {{no member named 'C' in 'class B::B'}}
   ::C::D; // expected-error {{no member named 'C' in the global namespace}}
 }
 
 int A::B::i = 10; // expected-error {{no member named 'i' in namespace 'A::B'}}
-int A::B::C::i = 10; // expected-error {{no member named 'i' in class 'A::B::C'}}
-int A::B::S::i = 10; // expected-error {{no member named 'i' in struct 'A::B::S'}}
-int A::B::U::i = 10; // expected-error {{no member named 'i' in union 'A::B::U'}}
+int A::B::C::i = 10; // expected-error {{no member named 'i' in 'class A::B::C'}}
+int A::B::S::i = 10; // expected-error {{no member named 'i' in 'struct A::B::S'}}
+int A::B::U::i = 10; // expected-error {{no member named 'i' in 'union A::B::U'}}
 
 using A::B::D; // expected-error {{no member named 'D' in namespace 'A::B'}}
 
 struct S : A::B::C { 
-  using A::B::C::f; // expected-error {{no member named 'f' in class 'A::B::C'}}
+  using A::B::C::f; // expected-error {{no member named 'f' in 'class A::B::C'}}
   
 };

Modified: cfe/trunk/test/SemaCXX/nested-name-spec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nested-name-spec.cpp?rev=84028&r1=84027&r2=84028&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/nested-name-spec.cpp (original)
+++ cfe/trunk/test/SemaCXX/nested-name-spec.cpp Tue Oct 13 16:16:44 2009
@@ -35,9 +35,9 @@
   int x;
 };
 
-void C2::m() const { } // expected-error{{out-of-line definition does not match any declaration in 'C2'}}
+void C2::m() const { } // expected-error{{out-of-line definition of 'm' does not match any declaration in 'class C2'}}
 
-void C2::f(int) { } // expected-error{{out-of-line definition does not match any declaration in 'C2'}}
+void C2::f(int) { } // expected-error{{out-of-line definition of 'f' does not match any declaration in 'class C2'}}
 
 void C2::m() {
   x = 0;
@@ -125,7 +125,7 @@
   operator bool();
 };
 
-Operators Operators::operator+(const Operators&) { // expected-error{{out-of-line definition does not match any declaration in 'Operators'}}
+Operators Operators::operator+(const Operators&) { // expected-error{{out-of-line definition of 'operator+' does not match any declaration in 'class Operators'}}
   Operators ops;
   return ops;
 }
@@ -143,13 +143,13 @@
   void g(int&); // expected-note{{member declaration nearly matches}}
 } 
 
-void A::f() {} // expected-error{{out-of-line definition does not match any declaration in 'A'}}
+void A::f() {} // expected-error{{out-of-line definition of 'f' does not match any declaration in namespace 'A'}}
 
-void A::g(const int&) { } // expected-error{{out-of-line definition does not match any declaration in 'A'}}
+void A::g(const int&) { } // expected-error{{out-of-line definition of 'g' does not match any declaration in namespace 'A'}}
 
 struct Struct { };
 
-void Struct::f() { } // expected-error{{out-of-line definition does not match any declaration in 'Struct'}}
+void Struct::f() { } // expected-error{{out-of-line definition of 'f' does not match any declaration in 'struct Struct'}}
 
 void global_func(int);
 void global_func2(int);

Modified: cfe/trunk/test/SemaTemplate/typename-specifier.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/typename-specifier.cpp?rev=84028&r1=84027&r2=84028&view=diff

==============================================================================
--- cfe/trunk/test/SemaTemplate/typename-specifier.cpp (original)
+++ cfe/trunk/test/SemaTemplate/typename-specifier.cpp Tue Oct 13 16:16:44 2009
@@ -16,7 +16,7 @@
 int i;
 
 typename N::A::type *ip1 = &i;
-typename N::B::type *ip2 = &i; // expected-error{{ no type named 'type' in 'B'}}
+typename N::B::type *ip2 = &i; // expected-error{{no type named 'type' in 'struct N::B'}}
 typename N::C::type *ip3 = &i; // expected-error{{typename specifier refers to non-type member 'type'}}
 
 void test(double d) {
@@ -33,7 +33,8 @@
 namespace N {
   template<typename T>
   struct X {
-    typedef typename T::type type; // expected-error 2{{no type named 'type' in 'B'}} \
+    typedef typename T::type type; // expected-error {{no type named 'type' in 'struct N::B'}} \
+    // expected-error {{no type named 'type' in 'struct B'}} \
     // FIXME: location info for error above isn't very good \
     // expected-error 2{{typename specifier refers to non-type member 'type'}} \
     // expected-error{{type 'int' cannot be used prior to '::' because it has no members}}





More information about the cfe-commits mailing list