Show fixit for unqualified calls to methods of dependent bases

when the calling site is a member function template.

Effectively reverts r111675.

llvm-svn: 159004
This commit is contained in:
Nico Weber 2012-06-22 16:39:39 +00:00
parent c5c4e96f3e
commit 3c10fb1d8e
2 changed files with 33 additions and 30 deletions

View File

@ -1477,36 +1477,40 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
if (getLangOpts().MicrosoftMode)
diagnostic = diag::warn_found_via_dependent_bases_lookup;
if (isInstance) {
Diag(R.getNameLoc(), diagnostic) << Name
<< FixItHint::CreateInsertion(R.getNameLoc(), "this->");
UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>(
CallsUndergoingInstantiation.back()->getCallee());
CXXMethodDecl *DepMethod = cast_or_null<CXXMethodDecl>(
CurMethod->getInstantiatedFromMemberFunction());
if (DepMethod) {
Diag(R.getNameLoc(), diagnostic) << Name
<< FixItHint::CreateInsertion(R.getNameLoc(), "this->");
QualType DepThisType = DepMethod->getThisType(Context);
CheckCXXThisCapture(R.getNameLoc());
CXXThisExpr *DepThis = new (Context) CXXThisExpr(
R.getNameLoc(), DepThisType, false);
TemplateArgumentListInfo TList;
if (ULE->hasExplicitTemplateArgs())
ULE->copyTemplateArgumentsInto(TList);
CXXScopeSpec SS;
SS.Adopt(ULE->getQualifierLoc());
CXXDependentScopeMemberExpr *DepExpr =
CXXDependentScopeMemberExpr::Create(
Context, DepThis, DepThisType, true, SourceLocation(),
SS.getWithLocInContext(Context),
ULE->getTemplateKeywordLoc(), 0,
R.getLookupNameInfo(),
ULE->hasExplicitTemplateArgs() ? &TList : 0);
CallsUndergoingInstantiation.back()->setCallee(DepExpr);
} else {
// FIXME: we should be able to handle this case too. It is correct
// to add this-> here. This is a workaround for PR7947.
Diag(R.getNameLoc(), diagnostic) << Name;
}
CXXMethodDecl *DepMethod;
if (CurMethod->getTemplatedKind() ==
FunctionDecl::TK_FunctionTemplateSpecialization)
DepMethod = cast<CXXMethodDecl>(CurMethod->getPrimaryTemplate()->
getInstantiatedFromMemberTemplate()->getTemplatedDecl());
else
DepMethod = cast<CXXMethodDecl>(
CurMethod->getInstantiatedFromMemberFunction());
assert(DepMethod && "No template pattern found");
QualType DepThisType = DepMethod->getThisType(Context);
CheckCXXThisCapture(R.getNameLoc());
CXXThisExpr *DepThis = new (Context) CXXThisExpr(
R.getNameLoc(), DepThisType, false);
TemplateArgumentListInfo TList;
if (ULE->hasExplicitTemplateArgs())
ULE->copyTemplateArgumentsInto(TList);
CXXScopeSpec SS;
SS.Adopt(ULE->getQualifierLoc());
CXXDependentScopeMemberExpr *DepExpr =
CXXDependentScopeMemberExpr::Create(
Context, DepThis, DepThisType, true, SourceLocation(),
SS.getWithLocInContext(Context),
ULE->getTemplateKeywordLoc(), 0,
R.getLookupNameInfo(),
ULE->hasExplicitTemplateArgs() ? &TList : 0);
CallsUndergoingInstantiation.back()->setCallee(DepExpr);
} else {
Diag(R.getNameLoc(), diagnostic) << Name;
}

View File

@ -1,7 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
// We don't expect a fix-it to be applied in this case. Clang used to crash
// trying to recover while adding 'this->' before Work(x);
// Clang used to crash trying to recover while adding 'this->' before Work(x);
template <typename> struct A {
static void Work(int); // expected-note{{must qualify identifier}}