r367367 - [Sema] Actually map a variable template specialization from pattern to instantiation
Erik Pilkington via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 30 16:38:18 PDT 2019
Author: epilk
Date: Tue Jul 30 16:38:18 2019
New Revision: 367367
URL: http://llvm.org/viewvc/llvm-project?rev=367367&view=rev
Log:
[Sema] Actually map a variable template specialization from pattern to instantiation
We were previously just using a specialization in the class template instead of
creating a new specialization in the class instantiation.
Fixes llvm.org/PR42779.
Differential revision: https://reviews.llvm.org/D65359
Modified:
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
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=367367&r1=367366&r2=367367&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Jul 30 16:38:18 2019
@@ -8191,6 +8191,11 @@ public:
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);
Modified: cfe/trunk/lib/Sema/SemaExprMember.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprMember.cpp?rev=367367&r1=367366&r2=367367&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprMember.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprMember.cpp Tue Jul 30 16:38:18 2019
@@ -934,19 +934,19 @@ static bool IsInFnTryBlockHandler(const
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 @@ Sema::BuildMemberReferenceExpr(Expr *Bas
"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 @@ Sema::BuildMemberReferenceExpr(Expr *Bas
}
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,
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=367367&r1=367366&r2=367367&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Tue Jul 30 16:38:18 2019
@@ -5217,11 +5217,11 @@ DeclContext *Sema::FindInstantiatedConte
/// 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 @@ NamedDecl *Sema::FindInstantiatedDecl(So
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 @@ NamedDecl *Sema::FindInstantiatedDecl(So
// 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
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=367367&r1=367366&r2=367367&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp Tue Jul 30 16:38:18 2019
@@ -395,3 +395,32 @@ namespace dependent_static_var_template
}
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
More information about the cfe-commits
mailing list