[cfe-commits] r80469 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/Sema.cpp lib/Sema/Sema.h lib/Sema/SemaCXXScopeSpec.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp test/SemaCXX/missing-members.cpp
Anders Carlsson
andersca at mac.com
Sat Aug 29 17:54:36 PDT 2009
Author: andersca
Date: Sat Aug 29 19:54:35 2009
New Revision: 80469
URL: http://llvm.org/viewvc/llvm-project?rev=80469&view=rev
Log:
Improve diagnostics for missing members. This renames the err_typecheck_no_member to err_typecheck_no_member_deprecated. The idea is that err_typecheck_no_member_deprecated should be phased out and any call sites that reference it should call DiagnoseMissingMember instead.
Added:
cfe/trunk/test/SemaCXX/missing-members.cpp
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
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
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=80469&r1=80468&r2=80469&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sat Aug 29 19:54:35 2009
@@ -1296,7 +1296,14 @@
"perhaps you meant to call this function with '()'?">;
def err_typecheck_incomplete_tag : Error<"incomplete definition of type %0">;
-def err_typecheck_no_member : Error<"no member named %0">;
+def err_typecheck_no_member_deprecated : Error<"no member named %0">;
+def err_typecheck_record_no_member : Error<
+ "%select{struct|union|class}0 %q1 has no member named %2">;
+def err_typecheck_namespace_no_member : Error<
+ "namespace %q0 has no member named %1">;
+def err_typecheck_global_scope_no_member : Error<
+ "the global scope has no member named %0">;
+
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">;
Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=80469&r1=80468&r2=80469&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Sat Aug 29 19:54:35 2009
@@ -345,6 +345,31 @@
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)
+ << RD->getTagKind() << RD << Member << Range;
+ break;
+ }
+ case NestedNameSpecifier::Namespace: {
+ Diag(MemberLoc, diag::err_typecheck_namespace_no_member)
+ << NNS->getAsNamespace() << Member << Range;
+ break;
+ }
+ case NestedNameSpecifier::Global: {
+ Diag(MemberLoc, diag::err_typecheck_global_scope_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=80469&r1=80468&r2=80469&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Sat Aug 29 19:54:35 2009
@@ -3461,6 +3461,9 @@
QualType FieldTy, const Expr *BitWidth,
bool *ZeroWidth = 0);
+ void DiagnoseMissingMember(SourceLocation MemberLoc, DeclarationName Member,
+ NestedNameSpecifier *NNS, SourceRange Range);
+
//===--------------------------------------------------------------------===//
// Extra semantic analysis beyond the C type system
private:
Modified: cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp?rev=80469&r1=80468&r2=80469&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp Sat Aug 29 19:54:35 2009
@@ -311,7 +311,7 @@
if (SD)
DiagID = diag::err_expected_class_or_namespace;
else if (SS.isSet())
- DiagID = diag::err_typecheck_no_member;
+ DiagID = diag::err_typecheck_no_member_deprecated;
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=80469&r1=80468&r2=80469&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sat Aug 29 19:54:35 2009
@@ -2205,8 +2205,10 @@
}
} else if (D.getCXXScopeSpec().isSet()) {
// No previous declaration in the qualifying scope.
- Diag(D.getIdentifierLoc(), diag::err_typecheck_no_member)
- << Name << D.getCXXScopeSpec().getRange();
+ NestedNameSpecifier *NNS =
+ (NestedNameSpecifier *)D.getCXXScopeSpec().getScopeRep();
+ DiagnoseMissingMember(D.getIdentifierLoc(), Name, NNS,
+ D.getCXXScopeSpec().getRange());
NewVD->setInvalidDecl();
}
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=80469&r1=80468&r2=80469&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Sat Aug 29 19:54:35 2009
@@ -2189,7 +2189,7 @@
Name, LookupOrdinaryName);
if (!R) {
- Diag(IdentLoc, diag::err_typecheck_no_member) << Name << SS.getRange();
+ Diag(IdentLoc, diag::err_typecheck_no_member_deprecated) << Name << 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=80469&r1=80468&r2=80469&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Aug 29 19:54:35 2009
@@ -789,10 +789,12 @@
else {
// If this name wasn't predeclared and if this is not a function call,
// diagnose the problem.
- if (SS && !SS->isEmpty())
- return ExprError(Diag(Loc, diag::err_typecheck_no_member)
- << Name << SS->getRange());
- else if (Name.getNameKind() == DeclarationName::CXXOperatorName ||
+ if (SS && !SS->isEmpty()) {
+ DiagnoseMissingMember(Loc, Name,
+ (NestedNameSpecifier *)SS->getScopeRep(),
+ SS->getRange());
+ return ExprError();
+ } else if (Name.getNameKind() == DeclarationName::CXXOperatorName ||
Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
return ExprError(Diag(Loc, diag::err_undeclared_use)
<< Name.getAsString());
@@ -2088,7 +2090,7 @@
}
if (!Result)
- return ExprError(Diag(MemberLoc, diag::err_typecheck_no_member)
+ return ExprError(Diag(MemberLoc, diag::err_typecheck_no_member_deprecated)
<< MemberName << BaseExpr->getSourceRange());
if (Result.isAmbiguous()) {
DiagnoseAmbiguousLookup(Result, MemberName, MemberLoc,
@@ -5475,7 +5477,7 @@
.getAsDecl());
// FIXME: Leaks Res
if (!MemberDecl)
- return ExprError(Diag(BuiltinLoc, diag::err_typecheck_no_member)
+ return ExprError(Diag(BuiltinLoc, diag::err_typecheck_no_member_deprecated)
<< OC.U.IdentInfo << SourceRange(OC.LocStart, OC.LocEnd));
// FIXME: C++: Verify that MemberDecl isn't a static field.
Added: cfe/trunk/test/SemaCXX/missing-members.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/missing-members.cpp?rev=80469&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/missing-members.cpp (added)
+++ cfe/trunk/test/SemaCXX/missing-members.cpp Sat Aug 29 19:54:35 2009
@@ -0,0 +1,20 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+namespace A {
+ namespace B {
+ class C { };
+ struct S { };
+ union U { };
+ }
+}
+
+void f() {
+ A::B::i; // expected-error {{namespace 'A::B' has no member named 'i'}}
+ A::B::C::i; // expected-error {{class 'A::B::C' has no member named 'i'}}
+ ::i; // expected-error {{the global scope has no member named 'i'}}
+}
+
+int A::B::i = 10; // expected-error {{namespace 'A::B' has no member named 'i'}}
+int A::B::C::i = 10; // expected-error {{class 'A::B::C' has no member named 'i'}}
+int A::B::S::i = 10; // expected-error {{struct 'A::B::S' has no member named 'i'}}
+int A::B::U::i = 10; // expected-error {{union 'A::B::U' has no member named 'i'}}
+
More information about the cfe-commits
mailing list