@@ -12154,33 +12154,31 @@ static bool isStdClassTemplate(Sema &S, QualType SugaredType, QualType *TypeArg,
1215412154 };
1215512155
1215612156 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();
1217612164 if (TST) {
1217712165 Template = dyn_cast_or_null<ClassTemplateDecl>(
1217812166 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();
1218012177 }
1218112178 }
12179+
1218212180 if (!Template) {
12183- ReportMatchingNameAsMalformed(Ty ->getAsTagDecl());
12181+ ReportMatchingNameAsMalformed(SugaredType ->getAsTagDecl());
1218412182 return false;
1218512183 }
1218612184
@@ -12200,7 +12198,8 @@ static bool isStdClassTemplate(Sema &S, QualType SugaredType, QualType *TypeArg,
1220012198 // template?
1220112199 TemplateParameterList *Params = Template->getTemplateParameters();
1220212200 if (Params->getMinRequiredArguments() != 1 ||
12203- !isa<TemplateTypeParmDecl>(Params->getParam(0))) {
12201+ !isa<TemplateTypeParmDecl>(Params->getParam(0)) ||
12202+ Params->getParam(0)->isTemplateParameterPack()) {
1220412203 if (MalformedDecl)
1220512204 *MalformedDecl = TemplateClass;
1220612205 return false;
@@ -12214,8 +12213,21 @@ static bool isStdClassTemplate(Sema &S, QualType SugaredType, QualType *TypeArg,
1221412213 return false;
1221512214
1221612215 // 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+ }
1221912231
1222012232 return true;
1222112233}
0 commit comments