@@ -2251,6 +2251,14 @@ bool VarDecl::checkInitIsICE() const {
2251
2251
return Eval->IsICE ;
2252
2252
}
2253
2253
2254
+ template <typename DeclT>
2255
+ static DeclT *getDefinitionOrSelf (DeclT *D) {
2256
+ assert (D);
2257
+ if (auto *Def = D->getDefinition ())
2258
+ return Def;
2259
+ return D;
2260
+ }
2261
+
2254
2262
VarDecl *VarDecl::getTemplateInstantiationPattern () const {
2255
2263
// If it's a variable template specialization, find the template or partial
2256
2264
// specialization from which it was instantiated.
@@ -2262,7 +2270,7 @@ VarDecl *VarDecl::getTemplateInstantiationPattern() const {
2262
2270
break ;
2263
2271
VTD = NewVTD;
2264
2272
}
2265
- return VTD->getTemplatedDecl ()-> getDefinition ( );
2273
+ return getDefinitionOrSelf ( VTD->getTemplatedDecl ());
2266
2274
}
2267
2275
if (auto *VTPSD =
2268
2276
From.dyn_cast <VarTemplatePartialSpecializationDecl *>()) {
@@ -2271,7 +2279,7 @@ VarDecl *VarDecl::getTemplateInstantiationPattern() const {
2271
2279
break ;
2272
2280
VTPSD = NewVTPSD;
2273
2281
}
2274
- return VTPSD-> getDefinition ( );
2282
+ return getDefinitionOrSelf<VarDecl>(VTPSD );
2275
2283
}
2276
2284
}
2277
2285
@@ -2280,23 +2288,18 @@ VarDecl *VarDecl::getTemplateInstantiationPattern() const {
2280
2288
VarDecl *VD = getInstantiatedFromStaticDataMember ();
2281
2289
while (auto *NewVD = VD->getInstantiatedFromStaticDataMember ())
2282
2290
VD = NewVD;
2283
- return VD-> getDefinition ( );
2291
+ return getDefinitionOrSelf (VD );
2284
2292
}
2285
2293
}
2286
2294
2287
2295
if (VarTemplateDecl *VarTemplate = getDescribedVarTemplate ()) {
2288
-
2289
2296
while (VarTemplate->getInstantiatedFromMemberTemplate ()) {
2290
2297
if (VarTemplate->isMemberSpecialization ())
2291
2298
break ;
2292
2299
VarTemplate = VarTemplate->getInstantiatedFromMemberTemplate ();
2293
2300
}
2294
2301
2295
- assert ((!VarTemplate->getTemplatedDecl () ||
2296
- !isTemplateInstantiation (getTemplateSpecializationKind ())) &&
2297
- " couldn't find pattern for variable instantiation" );
2298
-
2299
- return VarTemplate->getTemplatedDecl ();
2302
+ return getDefinitionOrSelf (VarTemplate->getTemplatedDecl ());
2300
2303
}
2301
2304
return nullptr ;
2302
2305
}
@@ -3198,9 +3201,12 @@ bool FunctionDecl::isTemplateInstantiation() const {
3198
3201
3199
3202
FunctionDecl *FunctionDecl::getTemplateInstantiationPattern () const {
3200
3203
// Handle class scope explicit specialization special case.
3201
- if (getTemplateSpecializationKind () == TSK_ExplicitSpecialization)
3202
- return getClassScopeSpecializationPattern ();
3203
-
3204
+ if (getTemplateSpecializationKind () == TSK_ExplicitSpecialization) {
3205
+ if (auto *Spec = getClassScopeSpecializationPattern ())
3206
+ return getDefinitionOrSelf (Spec);
3207
+ return nullptr ;
3208
+ }
3209
+
3204
3210
// If this is a generic lambda call operator specialization, its
3205
3211
// instantiation pattern is always its primary template's pattern
3206
3212
// even if its primary template was instantiated from another
@@ -3212,16 +3218,10 @@ FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const {
3212
3218
3213
3219
if (isGenericLambdaCallOperatorSpecialization (
3214
3220
dyn_cast<CXXMethodDecl>(this ))) {
3215
- assert (getPrimaryTemplate () && " A generic lambda specialization must be "
3216
- " generated from a primary call operator "
3217
- " template" );
3218
- assert (getPrimaryTemplate ()->getTemplatedDecl ()->getBody () &&
3219
- " A generic lambda call operator template must always have a body - "
3220
- " even if instantiated from a prototype (i.e. as written) member "
3221
- " template" );
3222
- return getPrimaryTemplate ()->getTemplatedDecl ();
3221
+ assert (getPrimaryTemplate () && " not a generic lambda call operator?" );
3222
+ return getDefinitionOrSelf (getPrimaryTemplate ()->getTemplatedDecl ());
3223
3223
}
3224
-
3224
+
3225
3225
if (FunctionTemplateDecl *Primary = getPrimaryTemplate ()) {
3226
3226
while (Primary->getInstantiatedFromMemberTemplate ()) {
3227
3227
// If we have hit a point where the user provided a specialization of
@@ -3230,11 +3230,14 @@ FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const {
3230
3230
break ;
3231
3231
Primary = Primary->getInstantiatedFromMemberTemplate ();
3232
3232
}
3233
-
3234
- return Primary->getTemplatedDecl ();
3233
+
3234
+ return getDefinitionOrSelf ( Primary->getTemplatedDecl () );
3235
3235
}
3236
-
3237
- return getInstantiatedFromMemberFunction ();
3236
+
3237
+ if (auto *MFD = getInstantiatedFromMemberFunction ())
3238
+ return getDefinitionOrSelf (MFD);
3239
+
3240
+ return nullptr ;
3238
3241
}
3239
3242
3240
3243
FunctionTemplateDecl *FunctionDecl::getPrimaryTemplate () const {
@@ -3778,7 +3781,7 @@ EnumDecl *EnumDecl::getTemplateInstantiationPattern() const {
3778
3781
EnumDecl *ED = getInstantiatedFromMemberEnum ();
3779
3782
while (auto *NewED = ED->getInstantiatedFromMemberEnum ())
3780
3783
ED = NewED;
3781
- return ED ;
3784
+ return getDefinitionOrSelf (ED) ;
3782
3785
}
3783
3786
}
3784
3787
0 commit comments