///
/// \param EnteringContext whether we are entering the context of this
/// template.
- virtual TemplateTy ActOnDependentTemplateName(Scope *S,
+ ///
+ /// \param Template Will be set to the dependent template name, on success.
+ ///
+ /// \returns The kind of template name that was produced. Generally, this will
+ /// be \c TNK_Dependent_template_name. However, if the nested-name-specifier
+ /// is not dependent, or refers to the current instantiation, then we may
+ /// be able to resolve the template kind more specifically.
+ virtual TemplateNameKind ActOnDependentTemplateName(Scope *S,
SourceLocation TemplateKWLoc,
CXXScopeSpec &SS,
UnqualifiedId &Name,
TypeTy *ObjectType,
- bool EnteringContext) {
- return TemplateTy();
+ bool EnteringContext,
+ TemplateTy &Template) {
+ return TNK_Non_template;
}
/// \brief Process the declaration or definition of an explicit
// Commit to parsing the template-id.
TPA.Commit();
- TemplateTy Template
- = Actions.ActOnDependentTemplateName(CurScope, TemplateKWLoc, SS,
- TemplateName,
- ObjectType, EnteringContext);
- if (!Template)
- return true;
- if (AnnotateTemplateIdToken(Template, TNK_Dependent_template_name,
- &SS, TemplateName, TemplateKWLoc, false))
+ TemplateTy Template;
+ if (TemplateNameKind TNK = Actions.ActOnDependentTemplateName(CurScope,
+ TemplateKWLoc,
+ SS,
+ TemplateName,
+ ObjectType,
+ EnteringContext,
+ Template)) {
+ if (AnnotateTemplateIdToken(Template, TNK, &SS, TemplateName,
+ TemplateKWLoc, false))
+ return true;
+ } else
return true;
continue;
<< II.getName()
<< FixItHint::CreateInsertion(Tok.getLocation(), "template ");
- Template = Actions.ActOnDependentTemplateName(CurScope,
- Tok.getLocation(), SS,
- TemplateName, ObjectType,
- EnteringContext);
- if (!Template.get())
+ if (TemplateNameKind TNK
+ = Actions.ActOnDependentTemplateName(CurScope,
+ Tok.getLocation(), SS,
+ TemplateName, ObjectType,
+ EnteringContext, Template)) {
+ // Consume the identifier.
+ ConsumeToken();
+ if (AnnotateTemplateIdToken(Template, TNK, &SS, TemplateName,
+ SourceLocation(), false))
+ return true;
+ }
+ else
return true;
-
- // Consume the identifier.
- ConsumeToken();
- if (AnnotateTemplateIdToken(Template, TNK_Dependent_template_name, &SS,
- TemplateName, SourceLocation(), false))
- return true;
-
+
continue;
}
}
case UnqualifiedId::IK_OperatorFunctionId:
case UnqualifiedId::IK_LiteralOperatorId:
if (AssumeTemplateId) {
- Template = Actions.ActOnDependentTemplateName(CurScope, TemplateKWLoc, SS,
- Id, ObjectType,
- EnteringContext);
- TNK = TNK_Dependent_template_name;
- if (!Template.get())
- return true;
+ TNK = Actions.ActOnDependentTemplateName(CurScope, TemplateKWLoc, SS,
+ Id, ObjectType, EnteringContext,
+ Template);
+ if (TNK == TNK_Non_template)
+ return true;
} else {
bool MemberOfUnknownSpecialization;
TNK = Actions.isTemplateName(CurScope, SS, Id, ObjectType,
Diag(Id.StartLocation, diag::err_missing_dependent_template_keyword)
<< Name
<< FixItHint::CreateInsertion(Id.StartLocation, "template ");
- Template = Actions.ActOnDependentTemplateName(CurScope, TemplateKWLoc,
- SS, Id, ObjectType,
- EnteringContext);
- TNK = TNK_Dependent_template_name;
- if (!Template.get())
+ TNK = Actions.ActOnDependentTemplateName(CurScope, TemplateKWLoc,
+ SS, Id, ObjectType,
+ EnteringContext, Template);
+ if (TNK == TNK_Non_template)
return true;
}
}
bool MemberOfUnknownSpecialization;
TemplateName.setIdentifier(Name, NameLoc);
if (ObjectType) {
- Template = Actions.ActOnDependentTemplateName(CurScope, TemplateKWLoc, SS,
- TemplateName, ObjectType,
- EnteringContext);
- TNK = TNK_Dependent_template_name;
- if (!Template.get())
+ TNK = Actions.ActOnDependentTemplateName(CurScope, TemplateKWLoc, SS,
+ TemplateName, ObjectType,
+ EnteringContext, Template);
+ if (TNK == TNK_Non_template)
return true;
} else {
TNK = Actions.isTemplateName(CurScope, SS, TemplateName, ObjectType,
// If the next token signals the end of a template argument,
// then we have a dependent template name that could be a template
// template argument.
- if (isEndOfTemplateArgument(Tok)) {
- TemplateTy Template
- = Actions.ActOnDependentTemplateName(CurScope, TemplateLoc, SS, Name,
- /*ObjectType=*/0,
- /*EnteringContext=*/false);
- if (Template.get())
- return ParsedTemplateArgument(SS, Template, Name.StartLocation);
- }
- }
+ TemplateTy Template;
+ if (isEndOfTemplateArgument(Tok) &&
+ Actions.ActOnDependentTemplateName(CurScope, TemplateLoc, SS, Name,
+ /*ObjectType=*/0,
+ /*EnteringContext=*/false,
+ Template))
+ return ParsedTemplateArgument(SS, Template, Name.StartLocation);
+ }
} else if (Tok.is(tok::identifier)) {
// We may have a (non-dependent) template name.
TemplateTy Template;
SourceLocation NameLoc,
const TemplateArgumentListInfo &TemplateArgs);
- virtual TemplateTy ActOnDependentTemplateName(Scope *S,
- SourceLocation TemplateKWLoc,
- CXXScopeSpec &SS,
- UnqualifiedId &Name,
- TypeTy *ObjectType,
- bool EnteringContext);
+ virtual TemplateNameKind ActOnDependentTemplateName(Scope *S,
+ SourceLocation TemplateKWLoc,
+ CXXScopeSpec &SS,
+ UnqualifiedId &Name,
+ TypeTy *ObjectType,
+ bool EnteringContext,
+ TemplateTy &Template);
bool CheckClassTemplatePartialSpecializationArgs(
TemplateParameterList *TemplateParams,
/// example, given "MetaFun::template apply", the scope specifier \p
/// SS will be "MetaFun::", \p TemplateKWLoc contains the location
/// of the "template" keyword, and "apply" is the \p Name.
-Sema::TemplateTy
-Sema::ActOnDependentTemplateName(Scope *S, SourceLocation TemplateKWLoc,
- CXXScopeSpec &SS,
- UnqualifiedId &Name,
- TypeTy *ObjectType,
- bool EnteringContext) {
+TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S,
+ SourceLocation TemplateKWLoc,
+ CXXScopeSpec &SS,
+ UnqualifiedId &Name,
+ TypeTy *ObjectType,
+ bool EnteringContext,
+ TemplateTy &Result) {
if (TemplateKWLoc.isValid() && S && !S->getTemplateParamParent() &&
!getLangOptions().CPlusPlus0x)
Diag(TemplateKWLoc, diag::ext_template_outside_of_template)
// dependent name. C++ DR468 relaxed this requirement (the
// "template" keyword is now permitted). We follow the C++0x
// rules, even in C++03 mode with a warning, retroactively applying the DR.
- TemplateTy Template;
bool MemberOfUnknownSpecialization;
TemplateNameKind TNK = isTemplateName(0, SS, Name, ObjectType,
- EnteringContext, Template,
+ EnteringContext, Result,
MemberOfUnknownSpecialization);
if (TNK == TNK_Non_template && LookupCtx->isDependentContext() &&
isa<CXXRecordDecl>(LookupCtx) &&
cast<CXXRecordDecl>(LookupCtx)->hasAnyDependentBases()) {
- // This is a dependent template.
+ // This is a dependent template. Handle it below.
} else if (TNK == TNK_Non_template) {
Diag(Name.getSourceRange().getBegin(),
diag::err_template_kw_refers_to_non_template)
<< GetNameFromUnqualifiedId(Name)
<< Name.getSourceRange()
<< TemplateKWLoc;
- return TemplateTy();
+ return TNK_Non_template;
} else {
// We found something; return it.
- return Template;
+ return TNK;
}
}
switch (Name.getKind()) {
case UnqualifiedId::IK_Identifier:
- return TemplateTy::make(Context.getDependentTemplateName(Qualifier,
- Name.Identifier));
+ Result = TemplateTy::make(Context.getDependentTemplateName(Qualifier,
+ Name.Identifier));
+ return TNK_Dependent_template_name;
case UnqualifiedId::IK_OperatorFunctionId:
- return TemplateTy::make(Context.getDependentTemplateName(Qualifier,
+ Result = TemplateTy::make(Context.getDependentTemplateName(Qualifier,
Name.OperatorFunctionId.Operator));
+ return TNK_Dependent_template_name;
case UnqualifiedId::IK_LiteralOperatorId:
assert(false && "We don't support these; Parse shouldn't have allowed propagation");
<< GetNameFromUnqualifiedId(Name)
<< Name.getSourceRange()
<< TemplateKWLoc;
- return TemplateTy();
+ return TNK_Non_template;
}
bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
SS.setScopeRep(Qualifier);
UnqualifiedId Name;
Name.setIdentifier(&II, /*FIXME:*/getDerived().getBaseLocation());
- return getSema().ActOnDependentTemplateName(/*Scope=*/0,
- /*FIXME:*/getDerived().getBaseLocation(),
- SS,
- Name,
- ObjectType.getAsOpaquePtr(),
- /*EnteringContext=*/false)
- .template getAsVal<TemplateName>();
+ Sema::TemplateTy Template;
+ getSema().ActOnDependentTemplateName(/*Scope=*/0,
+ /*FIXME:*/getDerived().getBaseLocation(),
+ SS,
+ Name,
+ ObjectType.getAsOpaquePtr(),
+ /*EnteringContext=*/false,
+ Template);
+ return Template.template getAsVal<TemplateName>();
}
template<typename Derived>
SourceLocation SymbolLocations[3]; // FIXME: Bogus location information.
Name.setOperatorFunctionId(/*FIXME:*/getDerived().getBaseLocation(),
Operator, SymbolLocations);
- return getSema().ActOnDependentTemplateName(/*Scope=*/0,
+ Sema::TemplateTy Template;
+ getSema().ActOnDependentTemplateName(/*Scope=*/0,
/*FIXME:*/getDerived().getBaseLocation(),
- SS,
- Name,
- ObjectType.getAsOpaquePtr(),
- /*EnteringContext=*/false)
- .template getAsVal<TemplateName>();
+ SS,
+ Name,
+ ObjectType.getAsOpaquePtr(),
+ /*EnteringContext=*/false,
+ Template);
+ return Template.template getAsVal<TemplateName>();
}
template<typename Derived>
M::Promote<int>::type *ret_intptr3(int* ip) { return ip; }
M::template Promote<int>::type *ret_intptr4(int* ip) { return ip; } // expected-warning{{'template' keyword outside of a template}}
+ M::template Promote<int> pi; // expected-warning{{'template' keyword outside of a template}}
}
N::M::Promote<int>::type *ret_intptr5(int* ip) { return ip; }