From: Douglas Gregor Date: Thu, 22 Oct 2009 17:20:55 +0000 (+0000) Subject: When building and instantiating a template-id reference expression, such as X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f17bb74e74aca9bb0525d2249041ab65c7d1fd48;p=clang When building and instantiating a template-id reference expression, such as N::f keep track of the full nested-name-specifier. This is mainly QoI and relatively hard to test; will try to come up with a printing-based test once we also retain the explicit template arguments past overload resolution. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84869 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index cefd512aee..050b3f42e4 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -1719,9 +1719,25 @@ public: /// 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, diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index 325f085a49..fa651569f8 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -356,7 +356,8 @@ Parser::OwningExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) { TemplateId->NumArgs); OwningExprResult Result - = Actions.ActOnTemplateIdExpr(TemplateTy::make(TemplateId->Template), + = Actions.ActOnTemplateIdExpr(SS, + TemplateTy::make(TemplateId->Template), TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, TemplateArgsPtr, diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index e636563aa3..074a6fcb62 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -2529,14 +2529,17 @@ public: 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, diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index c691cd93a0..0f223208a9 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -1251,7 +1251,9 @@ Sema::TypeResult Sema::ActOnTagTemplateIdType(TypeResult TypeResult, 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, @@ -1267,28 +1269,30 @@ Sema::OwningExprResult Sema::BuildTemplateIdExpr(TemplateName Template, 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, @@ -1301,7 +1305,9 @@ Sema::OwningExprResult Sema::ActOnTemplateIdExpr(TemplateTy TemplateD, 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); } diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 53aef9fdef..5f06ce5e35 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -1445,13 +1445,16 @@ public: /// /// 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); @@ -4369,8 +4372,8 @@ Sema::OwningExprResult TreeTransform::TransformUnresolvedDeclRefExpr( UnresolvedDeclRefExpr *E) { NestedNameSpecifier *NNS - = getDerived().TransformNestedNameSpecifier(E->getQualifier(), - E->getQualifierRange()); + = getDerived().TransformNestedNameSpecifier(E->getQualifier(), + E->getQualifierRange()); if (!NNS) return SemaRef.ExprError(); @@ -4399,6 +4402,14 @@ TreeTransform::TransformTemplateIdRefExpr(TemplateIdRefExpr *E) { 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 TransArgs; for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) { TemplateArgument TransArg @@ -4415,7 +4426,8 @@ TreeTransform::TransformTemplateIdRefExpr(TemplateIdRefExpr *E) { // 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(),