forked from OSchip/llvm-project
Suggest adding 'typename' when it would make the compiler
accept the template argument expression as a type. llvm-svn: 157085
This commit is contained in:
parent
90830703b2
commit
864d0b002c
|
@ -2361,6 +2361,8 @@ def note_template_decl_here : Note<"template is declared here">;
|
|||
def note_member_of_template_here : Note<"member is declared here">;
|
||||
def err_template_arg_must_be_type : Error<
|
||||
"template argument for template type parameter must be a type">;
|
||||
def err_template_arg_must_be_type_suggest : Error<
|
||||
"template argument for template type parameter must be a type; did you forget 'typename'?">;
|
||||
def err_template_arg_must_be_expr : Error<
|
||||
"template argument for non-type template parameter must be an expression">;
|
||||
def err_template_arg_nontype_ambig : Error<
|
||||
|
|
|
@ -2438,6 +2438,45 @@ bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
|
|||
|
||||
return true;
|
||||
}
|
||||
case TemplateArgument::Expression: {
|
||||
// We have a template type parameter but the template argument is an
|
||||
// expression; see if maybe it is missing the "typename" keyword.
|
||||
CXXScopeSpec SS;
|
||||
DeclarationNameInfo NameInfo;
|
||||
|
||||
if (DeclRefExpr *ArgExpr = dyn_cast<DeclRefExpr>(Arg.getAsExpr())) {
|
||||
SS.Adopt(ArgExpr->getQualifierLoc());
|
||||
NameInfo = ArgExpr->getNameInfo();
|
||||
} else if (DependentScopeDeclRefExpr *ArgExpr =
|
||||
dyn_cast<DependentScopeDeclRefExpr>(Arg.getAsExpr())) {
|
||||
SS.Adopt(ArgExpr->getQualifierLoc());
|
||||
NameInfo = ArgExpr->getNameInfo();
|
||||
} else if (CXXDependentScopeMemberExpr *ArgExpr =
|
||||
dyn_cast<CXXDependentScopeMemberExpr>(Arg.getAsExpr())) {
|
||||
SS.Adopt(ArgExpr->getQualifierLoc());
|
||||
NameInfo = ArgExpr->getMemberNameInfo();
|
||||
}
|
||||
|
||||
if (NameInfo.getName()) {
|
||||
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) {
|
||||
SourceLocation Loc = AL.getSourceRange().getBegin();
|
||||
Diag(Loc, diag::err_template_arg_must_be_type_suggest);
|
||||
Diag(Param->getLocation(), diag::note_template_param_here);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// fallthrough
|
||||
}
|
||||
default: {
|
||||
// We have a template type parameter but the template argument
|
||||
// is not a type.
|
||||
|
|
|
@ -115,3 +115,37 @@ namespace PR10925 {
|
|||
using typename BasicGeometry<mydim, int>::operator[]; // expected-error {{typename is allowed for identifiers only}}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
namespace missing_typename {
|
||||
template <class T1, class T2> struct pair {}; // expected-note 5 {{template parameter is declared here}}
|
||||
|
||||
template <class T1, class T2>
|
||||
struct map {
|
||||
typedef T1* iterator;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class ExampleClass1 {
|
||||
struct ExampleItem;
|
||||
|
||||
|
||||
struct ExampleItemSet {
|
||||
typedef ExampleItem* iterator;
|
||||
};
|
||||
|
||||
void foo() {
|
||||
pair<ExampleItemSet::iterator, int> i; // expected-error {{template argument for template type parameter must be a type; did you forget 'typename'?}}
|
||||
}
|
||||
pair<ExampleItemSet::iterator, int> elt; // expected-error {{template argument for template type parameter must be a type; did you forget 'typename'?}}
|
||||
|
||||
|
||||
typedef map<int, ExampleItem*> ExampleItemMap;
|
||||
|
||||
static void bar() {
|
||||
pair<ExampleItemMap::iterator, int> i; // expected-error {{template argument for template type parameter must be a type; did you forget 'typename'?}}
|
||||
}
|
||||
pair<ExampleItemMap::iterator, int> entry; // expected-error {{template argument for template type parameter must be a type; did you forget 'typename'?}}
|
||||
pair<bar, int> foobar; // expected-error {{template argument for template type parameter must be a type}}
|
||||
};
|
||||
} // namespace missing_typename
|
||||
|
|
Loading…
Reference in New Issue