r261506 - Fix PR24473 : Teach clang to remember to substitute into member variable templates referred to within dependent qualified ids.
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Sun Feb 21 20:06:26 PST 2016
On 21 Feb 2016 6:29 p.m., "Faisal Vali via cfe-commits" <
cfe-commits at lists.llvm.org> wrote:
>
> Author: faisalv
> Date: Sun Feb 21 20:24:29 2016
> New Revision: 261506
>
> URL: http://llvm.org/viewvc/llvm-project?rev=261506&view=rev
> Log:
> Fix PR24473 : Teach clang to remember to substitute into member variable
templates referred to within dependent qualified ids.
>
> In passing also fix a semi-related bug that allows access to variable
templates through member access notation.
>
>
> Modified:
> cfe/trunk/lib/Sema/SemaExprMember.cpp
> cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
>
> Modified: cfe/trunk/lib/Sema/SemaExprMember.cpp
> URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprMember.cpp?rev=261506&r1=261505&r2=261506&view=diff
>
==============================================================================
> --- cfe/trunk/lib/Sema/SemaExprMember.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExprMember.cpp Sun Feb 21 20:24:29 2016
> @@ -902,6 +902,32 @@ static bool IsInFnTryBlockHandler(const
> return false;
> }
>
> +static VarDecl *
> +getVarTemplateSpecialization(Sema &S, VarTemplateDecl *VarTempl,
> + const TemplateArgumentListInfo *TemplateArgs,
> + const DeclarationNameInfo &MemberNameInfo,
> + SourceLocation TemplateKWLoc) {
> +
> + if (!TemplateArgs) {
> + S.Diag(MemberNameInfo.getBeginLoc(), diag::err_template_decl_ref)
> + << /*Variable template*/ 1 << MemberNameInfo.getName()
> + << MemberNameInfo.getSourceRange();
> +
> + S.Diag(VarTempl->getLocation(), diag::note_template_decl_here);
> +
> + return nullptr;
> + }
> + DeclResult VDecl = S.CheckVarTemplateId(
> + VarTempl, TemplateKWLoc, MemberNameInfo.getLoc(), *TemplateArgs);
> + if (VDecl.isInvalid())
> + return nullptr;
> + VarDecl *Var = cast<VarDecl>(VDecl.get());
> + if (!Var->getTemplateSpecializationKind())
> + Var->setTemplateSpecializationKind(TSK_ImplicitInstantiation,
> + MemberNameInfo.getLoc());
> + return Var;
> +}
> +
> ExprResult
> Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,
> SourceLocation OpLoc, bool IsArrow,
> @@ -1069,9 +1095,20 @@ Sema::BuildMemberReferenceExpr(Expr *Bas
> // Handle the implicit-member-access case.
> if (!BaseExpr) {
> // If this is not an instance member, convert to a non-member access.
> - if (!MemberDecl->isCXXInstanceMember())
> + if (!MemberDecl->isCXXInstanceMember()) {
> + // If this is a variable template, get the instantiated variable
> + // declaration corresponding to the supplied template arguments
> + // (while emitting diagnostics as necessary) that will be
referenced
> + // by this expression.
> + if (isa<VarTemplateDecl>(MemberDecl)) {
> + MemberDecl = getVarTemplateSpecialization(
> + *this, cast<VarTemplateDecl>(MemberDecl), TemplateArgs,
> + R.getLookupNameInfo(), TemplateKWLoc);
> + if (!MemberDecl)
> + return ExprError();
> + }
> return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(),
MemberDecl);
Does this properly preserve the template argument list as written?
> -
> + }
> SourceLocation Loc = R.getNameLoc();
> if (SS.getRange().isValid())
> Loc = SS.getRange().getBegin();
> @@ -1127,6 +1164,15 @@ Sema::BuildMemberReferenceExpr(Expr *Bas
> TemplateKWLoc, Enum, FoundDecl,
MemberNameInfo,
> Enum->getType(), VK_RValue, OK_Ordinary);
> }
> + if (VarTemplateDecl *VarTempl = dyn_cast<VarTemplateDecl>(MemberDecl))
{
> + if (VarDecl *Var = getVarTemplateSpecialization(
> + *this, VarTempl, TemplateArgs, MemberNameInfo,
TemplateKWLoc))
> + return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, OpLoc,
SS,
> + TemplateKWLoc, Var, FoundDecl,
MemberNameInfo,
> + Var->getType().getNonReferenceType(),
VK_LValue,
> + OK_Ordinary);
> + return ExprError();
> + }
>
> // We found something that we didn't expect. Complain.
> if (isa<TypeDecl>(MemberDecl))
>
> Modified: cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
> URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp?rev=261506&r1=261505&r2=261506&view=diff
>
==============================================================================
> --- cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
(original)
> +++ cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp Sun Feb
21 20:24:29 2016
> @@ -1,6 +1,6 @@
> // RUN: %clang_cc1 -verify -fsyntax-only %s -Wno-c++11-extensions
-Wno-c++1y-extensions -DPRECXX11
> // RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only
-Wno-c++1y-extensions %s
> -// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s
> +// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s -DCPP1Y
>
> #define CONST const
>
> @@ -338,3 +338,47 @@ namespace b20896909 {
> A<int> ai; // expected-note {{in instantiation of}}
> }
> }
> +namespace member_access_is_ok {
> +#ifdef CPP1Y
> + namespace ns1 {
> + struct A {
> + template<class T, T N> constexpr static T Var = N;
> + };
> + static_assert(A{}.Var<int,5> == 5,"");
> + } // end ns1
> +#endif // CPP1Y
> +
> +namespace ns2 {
> + template<class T> struct A {
> + template<class U, T N, U M> static T&& Var;
> + };
> + template<class T> template<class U, T N, U M> T&& A<T>::Var = T(N + M);
> + int *AV = &A<int>().Var<char, 5, 'A'>;
> +
> +} //end ns2
> +} // end ns member_access_is_ok
> +
> +#ifdef CPP1Y
> +namespace PR24473 {
> +struct Value
> +{
> + template<class T>
> + static constexpr T value = 0;
> +};
> +
> +template<typename TValue>
> +struct Something
> +{
> + void foo() {
> + static_assert(TValue::template value<int> == 0, ""); // error
> + }
> +};
> +
> +int main() {
> + Something<Value>{}.foo();
> + return 0;
> +}
> +
> +} // end ns PR24473
> +#endif // CPP1Y
> +
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160221/b03107b5/attachment.html>
More information about the cfe-commits
mailing list