@@ -12154,33 +12154,31 @@ static bool isStdClassTemplate(Sema &S, QualType SugaredType, QualType *TypeArg,
12154
12154
};
12155
12155
12156
12156
ClassTemplateDecl *Template = nullptr;
12157
- const TemplateArgument *Arguments = nullptr;
12158
-
12159
- QualType Ty = S.Context.getCanonicalType(SugaredType);
12160
- if (const RecordType *RT = Ty->getAs<RecordType>()) {
12161
- ClassTemplateSpecializationDecl *Specialization =
12162
- dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl());
12163
- if (!Specialization) {
12164
- ReportMatchingNameAsMalformed(RT->getDecl());
12165
- return false;
12166
- }
12167
-
12168
- Template = Specialization->getSpecializedTemplate();
12169
- Arguments = Specialization->getTemplateArgs().data();
12170
- } else {
12171
- const TemplateSpecializationType *TST = nullptr;
12172
- if (auto *ICN = Ty->getAs<InjectedClassNameType>())
12173
- TST = ICN->getInjectedTST();
12174
- else
12175
- TST = Ty->getAs<TemplateSpecializationType>();
12157
+ ArrayRef<TemplateArgument> Arguments;
12158
+ {
12159
+ const TemplateSpecializationType *TST =
12160
+ SugaredType->getAsNonAliasTemplateSpecializationType();
12161
+ if (!TST)
12162
+ if (const auto *ICN = SugaredType->getAs<InjectedClassNameType>())
12163
+ TST = ICN->getInjectedTST();
12176
12164
if (TST) {
12177
12165
Template = dyn_cast_or_null<ClassTemplateDecl>(
12178
12166
TST->getTemplateName().getAsTemplateDecl());
12179
- Arguments = TST->template_arguments().begin();
12167
+ Arguments = TST->template_arguments();
12168
+ } else if (const RecordType *RT = SugaredType->getAs<RecordType>()) {
12169
+ ClassTemplateSpecializationDecl *Specialization =
12170
+ dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl());
12171
+ if (!Specialization) {
12172
+ ReportMatchingNameAsMalformed(RT->getDecl());
12173
+ return false;
12174
+ }
12175
+ Template = Specialization->getSpecializedTemplate();
12176
+ Arguments = Specialization->getTemplateArgs().asArray();
12180
12177
}
12181
12178
}
12179
+
12182
12180
if (!Template) {
12183
- ReportMatchingNameAsMalformed(Ty ->getAsTagDecl());
12181
+ ReportMatchingNameAsMalformed(SugaredType ->getAsTagDecl());
12184
12182
return false;
12185
12183
}
12186
12184
@@ -12200,7 +12198,8 @@ static bool isStdClassTemplate(Sema &S, QualType SugaredType, QualType *TypeArg,
12200
12198
// template?
12201
12199
TemplateParameterList *Params = Template->getTemplateParameters();
12202
12200
if (Params->getMinRequiredArguments() != 1 ||
12203
- !isa<TemplateTypeParmDecl>(Params->getParam(0))) {
12201
+ !isa<TemplateTypeParmDecl>(Params->getParam(0)) ||
12202
+ Params->getParam(0)->isTemplateParameterPack()) {
12204
12203
if (MalformedDecl)
12205
12204
*MalformedDecl = TemplateClass;
12206
12205
return false;
@@ -12214,8 +12213,21 @@ static bool isStdClassTemplate(Sema &S, QualType SugaredType, QualType *TypeArg,
12214
12213
return false;
12215
12214
12216
12215
// This is an instance of std::{ClassName}. Find the argument type.
12217
- if (TypeArg)
12218
- *TypeArg = Arguments[0].getAsType();
12216
+ if (TypeArg) {
12217
+ QualType ArgType = Arguments[0].getAsType();
12218
+ // FIXME: Since TST only has as-written arguments, we have to perform the
12219
+ // only kind of conversion applicable to type arguments; in Objective-C ARC:
12220
+ // - If an explicitly-specified template argument type is a lifetime type
12221
+ // with no lifetime qualifier, the __strong lifetime qualifier is
12222
+ // inferred.
12223
+ if (S.getLangOpts().ObjCAutoRefCount && ArgType->isObjCLifetimeType() &&
12224
+ !ArgType.getObjCLifetime()) {
12225
+ Qualifiers Qs;
12226
+ Qs.setObjCLifetime(Qualifiers::OCL_Strong);
12227
+ ArgType = S.Context.getQualifiedType(ArgType, Qs);
12228
+ }
12229
+ *TypeArg = ArgType;
12230
+ }
12219
12231
12220
12232
return true;
12221
12233
}
0 commit comments