forked from OSchip/llvm-project
Fix up the 'typename' suggestion logic introduced in r157085, based on
feedback from Doug Gregor. llvm-svn: 158185
This commit is contained in:
parent
f76568591c
commit
055e9479eb
|
@ -2453,22 +2453,20 @@ bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
|
|||
NameInfo = ArgExpr->getNameInfo();
|
||||
} else if (CXXDependentScopeMemberExpr *ArgExpr =
|
||||
dyn_cast<CXXDependentScopeMemberExpr>(Arg.getAsExpr())) {
|
||||
SS.Adopt(ArgExpr->getQualifierLoc());
|
||||
NameInfo = ArgExpr->getMemberNameInfo();
|
||||
if (ArgExpr->isImplicitAccess()) {
|
||||
SS.Adopt(ArgExpr->getQualifierLoc());
|
||||
NameInfo = ArgExpr->getMemberNameInfo();
|
||||
}
|
||||
}
|
||||
|
||||
if (NameInfo.getName()) {
|
||||
if (NameInfo.getName().isIdentifier()) {
|
||||
LookupResult Result(*this, NameInfo, LookupOrdinaryName);
|
||||
LookupParsedName(Result, CurScope, &SS);
|
||||
|
||||
bool CouldBeType = Result.getResultKind() ==
|
||||
LookupResult::NotFoundInCurrentInstantiation;
|
||||
|
||||
for (LookupResult::iterator I = Result.begin(), IEnd = Result.end();
|
||||
!CouldBeType && I != IEnd; ++I) {
|
||||
CouldBeType = isa<TypeDecl>(*I);
|
||||
}
|
||||
if (CouldBeType) {
|
||||
if (Result.getAsSingle<TypeDecl>() ||
|
||||
Result.getResultKind() ==
|
||||
LookupResult::NotFoundInCurrentInstantiation) {
|
||||
// FIXME: Add a FixIt and fix up the template argument for recovery.
|
||||
SourceLocation Loc = AL.getSourceRange().getBegin();
|
||||
Diag(Loc, diag::err_template_arg_must_be_type_suggest);
|
||||
Diag(Param->getLocation(), diag::note_template_param_here);
|
||||
|
|
|
@ -118,7 +118,7 @@ namespace PR10925 {
|
|||
|
||||
|
||||
namespace missing_typename {
|
||||
template <class T1, class T2> struct pair {}; // expected-note 5 {{template parameter is declared here}}
|
||||
template <class T1, class T2> struct pair {}; // expected-note 7 {{template parameter is declared here}}
|
||||
|
||||
template <class T1, class T2>
|
||||
struct map {
|
||||
|
@ -132,10 +132,13 @@ class ExampleClass1 {
|
|||
|
||||
struct ExampleItemSet {
|
||||
typedef ExampleItem* iterator;
|
||||
ExampleItem* operator[](unsigned);
|
||||
};
|
||||
|
||||
void foo() {
|
||||
pair<ExampleItemSet::iterator, int> i; // expected-error {{template argument for template type parameter must be a type; did you forget 'typename'?}}
|
||||
pair<this->ExampleItemSet::iterator, int> i; // expected-error-re {{template argument for template type parameter must be a type$}}
|
||||
pair<ExampleItemSet::operator[], int> i; // expected-error-re {{template argument for template type parameter must be a type$}}
|
||||
}
|
||||
pair<ExampleItemSet::iterator, int> elt; // expected-error {{template argument for template type parameter must be a type; did you forget 'typename'?}}
|
||||
|
||||
|
|
Loading…
Reference in New Issue