/// possibly checking well-formedness of the template arguments. It does not
/// imply the declaration of any entity.
///
+ /// \param SS The scope specifier that may precede the template name.
+ ///
/// \param Template A template whose specialization results in a
/// function or a dependent template.
- virtual OwningExprResult ActOnTemplateIdExpr(TemplateTy Template,
+ ///
+ /// \param TemplateNameLoc The location of the template name.
+ ///
+ /// \param LAngleLoc The location of the left angle bracket ('<') that starts
+ /// the template argument list.
+ ///
+ /// \param TemplateArgs The template arguments in the template argument list,
+ /// which may be empty.
+ ///
+ /// \param TemplateArgLocs The locations of the template arguments.
+ ///
+ /// \param RAngleLoc The location of the right angle bracket ('>') that
+ /// closes the template argument list.
+ virtual OwningExprResult ActOnTemplateIdExpr(const CXXScopeSpec &SS,
+ TemplateTy Template,
SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
ASTTemplateArgsPtr TemplateArgs,
TemplateId->NumArgs);
OwningExprResult Result
- = Actions.ActOnTemplateIdExpr(TemplateTy::make(TemplateId->Template),
+ = Actions.ActOnTemplateIdExpr(SS,
+ TemplateTy::make(TemplateId->Template),
TemplateId->TemplateNameLoc,
TemplateId->LAngleLoc,
TemplateArgsPtr,
DeclSpec::TST TagSpec,
SourceLocation TagLoc);
- OwningExprResult BuildTemplateIdExpr(TemplateName Template,
+ OwningExprResult BuildTemplateIdExpr(NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ TemplateName Template,
SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc);
- virtual OwningExprResult ActOnTemplateIdExpr(TemplateTy Template,
+ virtual OwningExprResult ActOnTemplateIdExpr(const CXXScopeSpec &SS,
+ TemplateTy Template,
SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
ASTTemplateArgsPtr TemplateArgs,
return ElabType.getAsOpaquePtr();
}
-Sema::OwningExprResult Sema::BuildTemplateIdExpr(TemplateName Template,
+Sema::OwningExprResult Sema::BuildTemplateIdExpr(NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ TemplateName Template,
SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
const TemplateArgument *TemplateArgs,
if (!D)
D = Template.getAsOverloadedFunctionDecl();
+ CXXScopeSpec SS;
+ SS.setRange(QualifierRange);
+ SS.setScopeRep(Qualifier);
QualType ThisType, MemberType;
- if (D && isImplicitMemberReference(/*FIXME:??*/0, D, TemplateNameLoc,
+ if (D && isImplicitMemberReference(&SS, D, TemplateNameLoc,
ThisType, MemberType)) {
Expr *This = new (Context) CXXThisExpr(SourceLocation(), ThisType);
return Owned(MemberExpr::Create(Context, This, true,
- /*FIXME:*/0, /*FIXME:*/SourceRange(),
+ Qualifier, QualifierRange,
D, TemplateNameLoc, true,
LAngleLoc, TemplateArgs,
NumTemplateArgs, RAngleLoc,
Context.OverloadTy));
}
- return Owned(TemplateIdRefExpr::Create(Context,
- /*FIXME: New type?*/Context.OverloadTy,
- /*FIXME: Necessary?*/0,
- /*FIXME: Necessary?*/SourceRange(),
+ return Owned(TemplateIdRefExpr::Create(Context, Context.OverloadTy,
+ Qualifier, QualifierRange,
Template, TemplateNameLoc, LAngleLoc,
TemplateArgs,
NumTemplateArgs, RAngleLoc));
}
-Sema::OwningExprResult Sema::ActOnTemplateIdExpr(TemplateTy TemplateD,
+Sema::OwningExprResult Sema::ActOnTemplateIdExpr(const CXXScopeSpec &SS,
+ TemplateTy TemplateD,
SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
ASTTemplateArgsPtr TemplateArgsIn,
translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
TemplateArgsIn.release();
- return BuildTemplateIdExpr(Template, TemplateNameLoc, LAngleLoc,
+ return BuildTemplateIdExpr((NestedNameSpecifier *)SS.getScopeRep(),
+ SS.getRange(),
+ Template, TemplateNameLoc, LAngleLoc,
TemplateArgs.data(), TemplateArgs.size(),
RAngleLoc);
}
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildTemplateIdExpr(TemplateName Template,
+ OwningExprResult RebuildTemplateIdExpr(NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ TemplateName Template,
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc) {
- return getSema().BuildTemplateIdExpr(Template, TemplateLoc,
+ return getSema().BuildTemplateIdExpr(Qualifier, QualifierRange,
+ Template, TemplateLoc,
LAngleLoc,
TemplateArgs, NumTemplateArgs,
RAngleLoc);
TreeTransform<Derived>::TransformUnresolvedDeclRefExpr(
UnresolvedDeclRefExpr *E) {
NestedNameSpecifier *NNS
- = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
- E->getQualifierRange());
+ = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
+ E->getQualifierRange());
if (!NNS)
return SemaRef.ExprError();
if (Template.isNull())
return SemaRef.ExprError();
+ NestedNameSpecifier *Qualifier = 0;
+ if (E->getQualifier()) {
+ Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
+ E->getQualifierRange());
+ if (!Qualifier)
+ return SemaRef.ExprError();
+ }
+
llvm::SmallVector<TemplateArgument, 4> TransArgs;
for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
TemplateArgument TransArg
// FIXME: It's possible that we'll find out now that the template name
// actually refers to a type, in which case the caller is actually dealing
// with a functional cast. Give a reasonable error message!
- return getDerived().RebuildTemplateIdExpr(Template, E->getTemplateNameLoc(),
+ return getDerived().RebuildTemplateIdExpr(Qualifier, E->getQualifierRange(),
+ Template, E->getTemplateNameLoc(),
E->getLAngleLoc(),
TransArgs.data(),
TransArgs.size(),