diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-05-11 02:43:08 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-05-11 02:43:08 +0000 |
commit | 7981004eb7bdb6db6c3a1f7bc644acca997dc53f (patch) | |
tree | f57396e21aafc9c14f35bed1d2ddbf600f8122b5 /clang/lib/Sema/SemaExprMember.cpp | |
parent | 82de4e6b9337d55e66b80d1b4c82dd7c413fe8e3 (diff) | |
download | bcm5719-llvm-7981004eb7bdb6db6c3a1f7bc644acca997dc53f.tar.gz bcm5719-llvm-7981004eb7bdb6db6c3a1f7bc644acca997dc53f.zip |
Improve diagnostics and error recovery for template name lookup.
For 'x::template y', consistently give a "no member named 'y' in 'x'"
diagnostic if there is no such member, and give a 'template keyword not
followed by a template' name error if there is such a member but it's not a
template. In the latter case, add a note pointing at the non-template.
Don't suggest inserting a 'template' keyword in 'X::Y<' if X is dependent
if the lookup of X::Y was actually not a dependent lookup and found only
non-templates.
llvm-svn: 332076
Diffstat (limited to 'clang/lib/Sema/SemaExprMember.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExprMember.cpp | 35 |
1 files changed, 19 insertions, 16 deletions
diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp index 2e099ad6c67..c91b15e29fc 100644 --- a/clang/lib/Sema/SemaExprMember.cpp +++ b/clang/lib/Sema/SemaExprMember.cpp @@ -640,6 +640,7 @@ static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R, const RecordType *RTy, SourceLocation OpLoc, bool IsArrow, CXXScopeSpec &SS, bool HasTemplateArgs, + SourceLocation TemplateKWLoc, TypoExpr *&TE) { SourceRange BaseRange = BaseExpr ? BaseExpr->getSourceRange() : SourceRange(); RecordDecl *RDecl = RTy->getDecl(); @@ -649,13 +650,13 @@ static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R, BaseRange)) return true; - if (HasTemplateArgs) { + if (HasTemplateArgs || TemplateKWLoc.isValid()) { // LookupTemplateName doesn't expect these both to exist simultaneously. QualType ObjectType = SS.isSet() ? QualType() : QualType(RTy, 0); bool MOUS; - SemaRef.LookupTemplateName(R, nullptr, SS, ObjectType, false, MOUS); - return false; + return SemaRef.LookupTemplateName(R, nullptr, SS, ObjectType, false, MOUS, + TemplateKWLoc); } DeclContext *DC = RDecl; @@ -733,7 +734,8 @@ static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R, static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, ExprResult &BaseExpr, bool &IsArrow, SourceLocation OpLoc, CXXScopeSpec &SS, - Decl *ObjCImpDecl, bool HasTemplateArgs); + Decl *ObjCImpDecl, bool HasTemplateArgs, + SourceLocation TemplateKWLoc); ExprResult Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType, @@ -761,7 +763,7 @@ Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType, if (IsArrow) RecordTy = RecordTy->getAs<PointerType>()->getPointeeType(); if (LookupMemberExprInRecord( *this, R, nullptr, RecordTy->getAs<RecordType>(), OpLoc, IsArrow, - SS, TemplateKWLoc.isValid() || TemplateArgs != nullptr, TE)) + SS, TemplateArgs != nullptr, TemplateKWLoc, TE)) return ExprError(); if (TE) return TE; @@ -772,7 +774,7 @@ Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType, ExprResult Result = LookupMemberExpr(*this, R, BaseResult, IsArrow, OpLoc, SS, ExtraArgs ? ExtraArgs->ObjCImpDecl : nullptr, - TemplateKWLoc.isValid() || TemplateArgs != nullptr); + TemplateArgs != nullptr, TemplateKWLoc); if (BaseResult.isInvalid()) return ExprError(); @@ -1226,7 +1228,8 @@ Sema::PerformMemberExprBaseConversion(Expr *Base, bool IsArrow) { static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, ExprResult &BaseExpr, bool &IsArrow, SourceLocation OpLoc, CXXScopeSpec &SS, - Decl *ObjCImpDecl, bool HasTemplateArgs) { + Decl *ObjCImpDecl, bool HasTemplateArgs, + SourceLocation TemplateKWLoc) { assert(BaseExpr.get() && "no base expression"); // Perform default conversions. @@ -1276,8 +1279,8 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, // Handle field access to simple records. if (const RecordType *RTy = BaseType->getAs<RecordType>()) { TypoExpr *TE = nullptr; - if (LookupMemberExprInRecord(S, R, BaseExpr.get(), RTy, - OpLoc, IsArrow, SS, HasTemplateArgs, TE)) + if (LookupMemberExprInRecord(S, R, BaseExpr.get(), RTy, OpLoc, IsArrow, SS, + HasTemplateArgs, TemplateKWLoc, TE)) return ExprError(); // Returning valid-but-null is how we indicate to the caller that @@ -1315,7 +1318,7 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, OpLoc, S.Context.getObjCClassType()); if (ShouldTryAgainWithRedefinitionType(S, BaseExpr)) return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, - ObjCImpDecl, HasTemplateArgs); + ObjCImpDecl, HasTemplateArgs, TemplateKWLoc); goto fail; } @@ -1509,7 +1512,7 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, // use the 'id' redefinition in this case. if (IsArrow && ShouldTryAgainWithRedefinitionType(S, BaseExpr)) return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, - ObjCImpDecl, HasTemplateArgs); + ObjCImpDecl, HasTemplateArgs, TemplateKWLoc); return ExprError(S.Diag(MemberLoc, diag::err_property_not_found) << MemberName << BaseType); @@ -1522,7 +1525,7 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, if (!MD) { if (ShouldTryAgainWithRedefinitionType(S, BaseExpr)) return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, - ObjCImpDecl, HasTemplateArgs); + ObjCImpDecl, HasTemplateArgs, TemplateKWLoc); goto fail; } @@ -1564,7 +1567,7 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, if (ShouldTryAgainWithRedefinitionType(S, BaseExpr)) return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, - ObjCImpDecl, HasTemplateArgs); + ObjCImpDecl, HasTemplateArgs, TemplateKWLoc); return ExprError(S.Diag(MemberLoc, diag::err_property_not_found) << MemberName << BaseType); @@ -1609,7 +1612,7 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, BaseExpr = S.ImpCastExprToType( BaseExpr.get(), S.Context.getObjCSelRedefinitionType(), CK_BitCast); return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, - ObjCImpDecl, HasTemplateArgs); + ObjCImpDecl, HasTemplateArgs, TemplateKWLoc); } // Failure cases. @@ -1632,7 +1635,7 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, // Recurse as an -> access. IsArrow = true; return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, - ObjCImpDecl, HasTemplateArgs); + ObjCImpDecl, HasTemplateArgs, TemplateKWLoc); } } @@ -1646,7 +1649,7 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, return ExprError(); BaseExpr = S.DefaultFunctionArrayConversion(BaseExpr.get()); return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, - ObjCImpDecl, HasTemplateArgs); + ObjCImpDecl, HasTemplateArgs, TemplateKWLoc); } S.Diag(OpLoc, diag::err_typecheck_member_reference_struct_union) |