// TODO: fixit for inserting 'Base<T>::' in the other cases.
// Actually quite difficult!
if (isInstance) {
- Diag(R.getNameLoc(), diagnostic) << Name
- << FixItHint::CreateInsertion(R.getNameLoc(), "this->");
-
UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>(
CallsUndergoingInstantiation.back()->getCallee());
- CXXMethodDecl *DepMethod = cast<CXXMethodDecl>(
+ CXXMethodDecl *DepMethod = cast_or_null<CXXMethodDecl>(
CurMethod->getInstantiatedFromMemberFunction());
- QualType DepThisType = DepMethod->getThisType(Context);
- CXXThisExpr *DepThis = new (Context) CXXThisExpr(R.getNameLoc(),
- DepThisType, false);
- TemplateArgumentListInfo TList;
- if (ULE->hasExplicitTemplateArgs())
- ULE->copyTemplateArgumentsInto(TList);
- CXXDependentScopeMemberExpr *DepExpr =
- CXXDependentScopeMemberExpr::Create(
- Context, DepThis, DepThisType, true, SourceLocation(),
- ULE->getQualifier(), ULE->getQualifierRange(), NULL,
- R.getLookupNameInfo(), &TList);
- CallsUndergoingInstantiation.back()->setCallee(DepExpr);
+ if (DepMethod) {
+ Diag(R.getNameLoc(), diagnostic) << Name
+ << FixItHint::CreateInsertion(R.getNameLoc(), "this->");
+ QualType DepThisType = DepMethod->getThisType(Context);
+ CXXThisExpr *DepThis = new (Context) CXXThisExpr(
+ R.getNameLoc(), DepThisType, false);
+ TemplateArgumentListInfo TList;
+ if (ULE->hasExplicitTemplateArgs())
+ ULE->copyTemplateArgumentsInto(TList);
+ CXXDependentScopeMemberExpr *DepExpr =
+ CXXDependentScopeMemberExpr::Create(
+ Context, DepThis, DepThisType, true, SourceLocation(),
+ ULE->getQualifier(), ULE->getQualifierRange(), NULL,
+ R.getLookupNameInfo(), &TList);
+ 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;
+ }
} else {
Diag(R.getNameLoc(), diagnostic) << Name;
}
--- /dev/null
+// 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);
+
+template <typename> struct A {
+ static void Work(int); // expected-note{{must qualify identifier}}
+};
+
+template <typename T> struct B : public A<T> {
+ template <typename T2> B(T2 x) {
+ Work(x); // expected-error{{use of undeclared identifier}}
+ }
+};
+
+void Test() {
+ B<int> b(0); // expected-note{{in instantiation of function template}}
+}
+