diff options
-rw-r--r-- | include/clang/Basic/Diagnostic.h | 19 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 14 | ||||
-rw-r--r-- | lib/Basic/Diagnostic.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/Sema.cpp | 157 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 3 | ||||
-rw-r--r-- | lib/Sema/SemaCXXScopeSpec.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 9 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 19 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 10 | ||||
-rw-r--r-- | test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp | 6 | ||||
-rw-r--r-- | test/SemaCXX/missing-members.cpp | 12 | ||||
-rw-r--r-- | test/SemaCXX/nested-name-spec.cpp | 12 | ||||
-rw-r--r-- | test/SemaTemplate/typename-specifier.cpp | 5 |
14 files changed, 147 insertions, 127 deletions
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h index 13596d7edf..380192e9da 100644 --- a/include/clang/Basic/Diagnostic.h +++ b/include/clang/Basic/Diagnostic.h @@ -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 llvm { } namespace clang { + class DeclContext; class DiagnosticBuilder; class DiagnosticClient; class IdentifierInfo; @@ -158,7 +160,8 @@ public: ak_qualtype, // QualType ak_declarationname, // DeclarationName ak_nameddecl, // NamedDecl * - ak_nestednamespec // NestedNameSpecifier * + ak_nestednamespec, // NestedNameSpecifier * + ak_declcontext // DeclContext * }; private: @@ -613,6 +616,20 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 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); diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 89700ab087..0aeefb3ee9 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1107,10 +1107,8 @@ def note_explicit_instantiation_candidate : Note< // 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 @@ def warn_subscript_is_char : Warning<"array subscript is of type 'char'">, 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< diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp index 19f43e36a2..4a29997a2c 100644 --- a/lib/Basic/Diagnostic.cpp +++ b/lib/Basic/Diagnostic.cpp @@ -802,6 +802,7 @@ FormatDiagnostic(llvm::SmallVectorImpl<char> &OutStr) const { 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); diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 3aae2563d1..c289abfea8 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -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 @@ static void ConvertArgToStringFn(Diagnostic::ArgumentKind Kind, intptr_t Val, 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 @@ static void ConvertArgToStringFn(Diagnostic::ArgumentKind Kind, intptr_t Val, 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 @@ NamedDecl *Sema::getCurFunctionOrMethodDecl() { 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; diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index fed2fbc081..465eca70ed 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -3720,9 +3720,6 @@ public: 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. diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp index 911cf67770..10c138c755 100644 --- a/lib/Sema/SemaCXXScopeSpec.cpp +++ b/lib/Sema/SemaCXXScopeSpec.cpp @@ -471,9 +471,7 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S, 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; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index a1582a900f..9f03cb284c 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -2229,10 +2229,9 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC, } } 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 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, // 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; diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 646ac75dd3..82cdd2f57a 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -2767,7 +2767,8 @@ NamedDecl *Sema::BuildUsingDeclaration(SourceLocation UsingLoc, 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; } diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index b7c2308541..194317ce23 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -802,12 +802,11 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, 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 @@ Sema::BuildMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, 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 @@ Sema::OwningExprResult Sema::ActOnBuiltinOffsetOf(Scope *S, = 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. diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 3ee15a5b4d..4a410ecb14 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -3903,10 +3903,7 @@ Sema::CheckTypenameType(NestedNameSpecifier *NNS, const IdentifierInfo &II, 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 @@ Sema::CheckTypenameType(NestedNameSpecifier *NNS, const IdentifierInfo &II, // 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; diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp index 04129f8091..a5877d281d 100644 --- a/test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp @@ -9,12 +9,12 @@ template<class T1> class A { 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}} diff --git a/test/SemaCXX/missing-members.cpp b/test/SemaCXX/missing-members.cpp index 5fd4c54c1d..28ad9a04e7 100644 --- a/test/SemaCXX/missing-members.cpp +++ b/test/SemaCXX/missing-members.cpp @@ -9,7 +9,7 @@ namespace A { 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 @@ namespace B { 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'}} }; diff --git a/test/SemaCXX/nested-name-spec.cpp b/test/SemaCXX/nested-name-spec.cpp index ffb20d2082..4ddf3bbce4 100644 --- a/test/SemaCXX/nested-name-spec.cpp +++ b/test/SemaCXX/nested-name-spec.cpp @@ -35,9 +35,9 @@ class C2 { 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 @@ class Operators { 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 @@ namespace A { 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); diff --git a/test/SemaTemplate/typename-specifier.cpp b/test/SemaTemplate/typename-specifier.cpp index d3fca3eaca..62795eb0ee 100644 --- a/test/SemaTemplate/typename-specifier.cpp +++ b/test/SemaTemplate/typename-specifier.cpp @@ -16,7 +16,7 @@ namespace N { 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 @@ void test(double d) { 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}} |