aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-08-30 00:54:35 +0000
committerAnders Carlsson <andersca@mac.com>2009-08-30 00:54:35 +0000
commitf4d84b663ef7dda959cbe45561d90e59760cbb74 (patch)
tree95264df5081c6303058ad1348caa0d2fd6aa2348 /lib
parentaf496acbae62ad51bf42b40eea8ea8ebe48c5dbb (diff)
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80469 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Sema/Sema.cpp25
-rw-r--r--lib/Sema/Sema.h3
-rw-r--r--lib/Sema/SemaCXXScopeSpec.cpp2
-rw-r--r--lib/Sema/SemaDecl.cpp6
-rw-r--r--lib/Sema/SemaDeclCXX.cpp2
-rw-r--r--lib/Sema/SemaExpr.cpp14
6 files changed, 42 insertions, 10 deletions
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 0d9ad12eda..f291be1abb 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -345,6 +345,31 @@ 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)
+ << 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;
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index f3d202c2ff..0e45fe7f15 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -3461,6 +3461,9 @@ public:
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:
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index 2d89cfa072..3172c0aa52 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -311,7 +311,7 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
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;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 3eece142e9..4d05144918 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -2205,8 +2205,10 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
}
} 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();
}
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 6d32f3fdbf..1aac43c169 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -2189,7 +2189,7 @@ NamedDecl *Sema::BuildUsingDeclaration(SourceLocation UsingLoc,
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;
}
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index cfb9eb658d..f304ac3094 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -789,10 +789,12 @@ 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())
- 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 @@ Sema::BuildMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
}
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 @@ Sema::OwningExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
.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.