This revision was automatically updated to reflect the committed changes. Closed by commit rL367367: [Sema] Actually map a variable template specialization from pattern to… (authored by epilk, committed by ). Herald added a project: LLVM. Herald added a subscriber: llvm-commits.
Changed prior to commit: https://reviews.llvm.org/D65359?vs=212027&id=212468#toc Repository: rL LLVM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D65359/new/ https://reviews.llvm.org/D65359 Files: cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Sema/SemaExprMember.cpp cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
Index: cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp =================================================================== --- cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp +++ cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp @@ -395,3 +395,32 @@ } int &t = B::template n; // expected-error {{use of variable template 'n' requires template arguments}} } + +#ifndef PRECXX11 +namespace template_vars_in_template { +template <int> struct TakesInt {}; + +template <class T2> +struct S { + template <class T1> + static constexpr int v = 42; + + template <class T> + void mf() { + constexpr int val = v<T>; + } + + void mf2() { + constexpr int val = v<char>; + TakesInt<val> ti; + (void)ti.x; // expected-error{{no member named 'x' in 'template_vars_in_template::TakesInt<42>'}} + } +}; + +void useit() { + S<int> x; + x.mf<double>(); + x.mf2(); // expected-note{{in instantiation of member function 'template_vars_in_template::S<int>::mf2' requested here}} +} +} +#endif Index: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -5217,11 +5217,11 @@ /// template struct X<int>; /// \endcode /// -/// In the instantiation of <tt>X<int>::getKind()</tt>, we need to map the -/// \p EnumConstantDecl for \p KnownValue (which refers to -/// <tt>X<T>::<Kind>::KnownValue</tt>) to its instantiation -/// (<tt>X<int>::<Kind>::KnownValue</tt>). \p FindInstantiatedDecl performs -/// this mapping from within the instantiation of <tt>X<int></tt>. +/// In the instantiation of X<int>::getKind(), we need to map the \p +/// EnumConstantDecl for \p KnownValue (which refers to +/// X<T>::<Kind>::KnownValue) to its instantiation (X<int>::<Kind>::KnownValue). +/// \p FindInstantiatedDecl performs this mapping from within the instantiation +/// of X<int>. NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, const MultiLevelTemplateArgumentList &TemplateArgs, bool FindingInstantiatedContext) { @@ -5312,20 +5312,6 @@ return cast<LabelDecl>(Inst); } - // For variable template specializations, update those that are still - // type-dependent. - if (VarTemplateSpecializationDecl *VarSpec = - dyn_cast<VarTemplateSpecializationDecl>(D)) { - bool InstantiationDependent = false; - const TemplateArgumentListInfo &VarTemplateArgs = - VarSpec->getTemplateArgsInfo(); - if (TemplateSpecializationType::anyDependentTemplateArguments( - VarTemplateArgs, InstantiationDependent)) - D = cast<NamedDecl>( - SubstDecl(D, VarSpec->getDeclContext(), TemplateArgs)); - return D; - } - if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) { if (!Record->isDependentContext()) return D; @@ -5450,11 +5436,23 @@ // find it. Does that ever matter? if (auto Name = D->getDeclName()) { DeclarationNameInfo NameInfo(Name, D->getLocation()); - Name = SubstDeclarationNameInfo(NameInfo, TemplateArgs).getName(); + DeclarationNameInfo NewNameInfo = + SubstDeclarationNameInfo(NameInfo, TemplateArgs); + Name = NewNameInfo.getName(); if (!Name) return nullptr; DeclContext::lookup_result Found = ParentDC->lookup(Name); - Result = findInstantiationOf(Context, D, Found.begin(), Found.end()); + + if (auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(D)) { + VarTemplateDecl *Templ = cast_or_null<VarTemplateDecl>( + findInstantiationOf(Context, VTSD->getSpecializedTemplate(), + Found.begin(), Found.end())); + if (!Templ) + return nullptr; + Result = getVarTemplateSpecialization( + Templ, &VTSD->getTemplateArgsInfo(), NewNameInfo, SourceLocation()); + } else + Result = findInstantiationOf(Context, D, Found.begin(), Found.end()); } else { // Since we don't have a name for the entity we're looking for, // our only option is to walk through all of the declarations to Index: cfe/trunk/lib/Sema/SemaExprMember.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaExprMember.cpp +++ cfe/trunk/lib/Sema/SemaExprMember.cpp @@ -934,19 +934,19 @@ return false; } -static VarDecl * -getVarTemplateSpecialization(Sema &S, VarTemplateDecl *VarTempl, +VarDecl * +Sema::getVarTemplateSpecialization(VarTemplateDecl *VarTempl, const TemplateArgumentListInfo *TemplateArgs, const DeclarationNameInfo &MemberNameInfo, SourceLocation TemplateKWLoc) { if (!TemplateArgs) { - S.diagnoseMissingTemplateArguments(TemplateName(VarTempl), - MemberNameInfo.getBeginLoc()); + diagnoseMissingTemplateArguments(TemplateName(VarTempl), + MemberNameInfo.getBeginLoc()); return nullptr; } - DeclResult VDecl = S.CheckVarTemplateId( - VarTempl, TemplateKWLoc, MemberNameInfo.getLoc(), *TemplateArgs); + DeclResult VDecl = CheckVarTemplateId(VarTempl, TemplateKWLoc, + MemberNameInfo.getLoc(), *TemplateArgs); if (VDecl.isInvalid()) return nullptr; VarDecl *Var = cast<VarDecl>(VDecl.get()); @@ -1095,7 +1095,7 @@ "How did we get template arguments here sans a variable template"); if (isa<VarTemplateDecl>(MemberDecl)) { MemberDecl = getVarTemplateSpecialization( - *this, cast<VarTemplateDecl>(MemberDecl), TemplateArgs, + cast<VarTemplateDecl>(MemberDecl), TemplateArgs, R.getLookupNameInfo(), TemplateKWLoc); if (!MemberDecl) return ExprError(); @@ -1160,7 +1160,7 @@ } if (VarTemplateDecl *VarTempl = dyn_cast<VarTemplateDecl>(MemberDecl)) { if (VarDecl *Var = getVarTemplateSpecialization( - *this, VarTempl, TemplateArgs, MemberNameInfo, TemplateKWLoc)) + VarTempl, TemplateArgs, MemberNameInfo, TemplateKWLoc)) return BuildMemberExpr( BaseExpr, IsArrow, OpLoc, &SS, TemplateKWLoc, Var, FoundDecl, /*HadMultipleCandidates=*/false, MemberNameInfo, Index: cfe/trunk/include/clang/Sema/Sema.h =================================================================== --- cfe/trunk/include/clang/Sema/Sema.h +++ cfe/trunk/include/clang/Sema/Sema.h @@ -8191,6 +8191,11 @@ LocalInstantiationScope *StartingScope, bool InstantiatingVarTemplate = false, VarTemplateSpecializationDecl *PrevVTSD = nullptr); + + VarDecl *getVarTemplateSpecialization( + VarTemplateDecl *VarTempl, const TemplateArgumentListInfo *TemplateArgs, + const DeclarationNameInfo &MemberNameInfo, SourceLocation TemplateKWLoc); + void InstantiateVariableInitializer( VarDecl *Var, VarDecl *OldVar, const MultiLevelTemplateArgumentList &TemplateArgs);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits