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.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67826 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Douglas Gregor 2009-03-27 06:00:30 +00:00
Родитель 73b6a441ea
Коммит 214f31a347
3 изменённых файлов: 30 добавлений и 3 удалений

Просмотреть файл

@ -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">;

Просмотреть файл

@ -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

Просмотреть файл

@ -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}}
}