summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-03-27 06:00:30 +0000
committerDouglas Gregor <dgregor@apple.com>2009-03-27 06:00:30 +0000
commit0b08ba44a1ff2b61f5a0c247c4948c830ef31b01 (patch)
treea1a6152d840fce61e5e1c9278069e8ee84b613b0 /clang
parent17e28b7a54c60f080ded0a0633a1f5157b6b6e24 (diff)
downloadbcm5719-llvm-0b08ba44a1ff2b61f5a0c247c4948c830ef31b01.tar.gz
bcm5719-llvm-0b08ba44a1ff2b61f5a0c247c4948c830ef31b01.zip
If the user is trying to apply the -> or . member reference operator
to a function or function pointer, it's probably because the user forgot to put in parentheses () to call the function. llvm-svn: 67826
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td3
-rw-r--r--clang/lib/Sema/SemaExpr.cpp19
-rw-r--r--clang/test/SemaCXX/member-expr.cpp11
3 files changed, 30 insertions, 3 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 62647ff51c5..05b8f512e18 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -872,6 +872,9 @@ def err_typecheck_member_reference_type : Error<
"cannot refer to type member %0 with '%select{.|->}1'">;
def err_typecheck_member_reference_unknown : Error<
"cannot refer to member %0 with '%select{.|->}1'">;
+def note_member_reference_needs_call : Note<
+ "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_member_redeclared : Error<"class member cannot be redeclared">;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 8922abd20b9..8b646e9943f 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2101,9 +2101,22 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
MemberLoc));
}
- return ExprError(Diag(MemberLoc,
- diag::err_typecheck_member_reference_struct_union)
- << BaseType << BaseExpr->getSourceRange());
+ Diag(MemberLoc, diag::err_typecheck_member_reference_struct_union)
+ << BaseType << BaseExpr->getSourceRange();
+
+ // If the user is trying to apply -> or . to a function or function
+ // pointer, it's probably because they forgot parentheses to call
+ // the function. Suggest the addition of those parentheses.
+ if (BaseType == Context.OverloadTy ||
+ BaseType->isFunctionType() ||
+ (BaseType->isPointerType() &&
+ BaseType->getAsPointerType()->isFunctionType())) {
+ SourceLocation Loc = PP.getLocForEndOfToken(BaseExpr->getLocEnd());
+ Diag(Loc, diag::note_member_reference_needs_call)
+ << CodeModificationHint::CreateInsertion(Loc, "()");
+ }
+
+ return ExprError();
}
/// ConvertArgumentsForCall - Converts the arguments specified in
diff --git a/clang/test/SemaCXX/member-expr.cpp b/clang/test/SemaCXX/member-expr.cpp
index 58e5be955f6..60ee10df7f6 100644
--- a/clang/test/SemaCXX/member-expr.cpp
+++ b/clang/test/SemaCXX/member-expr.cpp
@@ -20,3 +20,14 @@ void test(X* xp, X x) {
float f1 = x.g();
float f2 = xp->g();
}
+
+struct A {
+ int f0;
+};
+struct B {
+ A *f0();
+};
+int f0(B *b) {
+ return b->f0->f0; // expected-error{{member reference base type 'struct A *(void)' is not a structure or union}} \
+ // expected-note{{perhaps you meant to call this function}}
+}
OpenPOWER on IntegriCloud