diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 16 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 9 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 34 | ||||
-rw-r--r-- | lib/Sema/TypeLocBuilder.h | 1 |
4 files changed, 51 insertions, 9 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index b8caad8af5..fa2182a2aa 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -2357,8 +2357,20 @@ bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param, return true; // Add the converted template type argument. - Converted.push_back( - TemplateArgument(Context.getCanonicalType(Arg.getAsType()))); + QualType ArgType = Context.getCanonicalType(Arg.getAsType()); + + // Objective-C ARC: + // If an explicitly-specified template argument type is a lifetime type + // with no lifetime qualifier, the __strong lifetime qualifier is inferred. + if (getLangOptions().ObjCAutoRefCount && + ArgType->isObjCLifetimeType() && + !ArgType.getObjCLifetime()) { + Qualifiers Qs; + Qs.setObjCLifetime(Qualifiers::OCL_Strong); + ArgType = Context.getQualifiedType(ArgType, Qs); + } + + Converted.push_back(TemplateArgument(ArgType)); return false; } diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index af359316da..b5e9c25d85 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -1016,6 +1016,15 @@ DeduceTemplateArguments(Sema &S, DeducedQs.removeAddressSpace(); if (ParamQs.hasObjCLifetime()) DeducedQs.removeObjCLifetime(); + + // Objective-C ARC: + // If template deduction would produce an argument type with lifetime type + // but no lifetime qualifier, the __strong lifetime qualifier is inferred. + if (S.getLangOptions().ObjCAutoRefCount && + DeducedType->isObjCLifetimeType() && + !DeducedQs.hasObjCLifetime()) + DeducedQs.setObjCLifetime(Qualifiers::OCL_Strong); + DeducedType = S.Context.getQualifiedType(DeducedType.getUnqualifiedType(), DeducedQs); diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index ba4ee3426a..d33e7a5c4c 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -3173,12 +3173,34 @@ TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB, return Result; // Suppress Objective-C lifetime qualifiers if they don't make sense for the - // resulting type or if the resulting type already has one. - if (Quals.hasObjCLifetime() && - (Result.getObjCLifetime() || - (!Result->isObjCLifetimeType() && !Result->isDependentType()))) - Quals.removeObjCLifetime(); - + // resulting type. + if (Quals.hasObjCLifetime()) { + if (!Result->isObjCLifetimeType() && !Result->isDependentType()) + Quals.removeObjCLifetime(); + else if (Result.getObjCLifetime() && + Result.getObjCLifetime() != Quals.getObjCLifetime()) { + // Objective-C ARC: + // A lifetime qualifier applied to a substituted template parameter + // overrides the lifetime qualifier from the template argument. + if (const SubstTemplateTypeParmType *SubstTypeParam + = dyn_cast<SubstTemplateTypeParmType>(Result)) { + QualType Replacement = SubstTypeParam->getReplacementType(); + Qualifiers Qs = Replacement.getQualifiers(); + Qs.removeObjCLifetime(); + Replacement + = SemaRef.Context.getQualifiedType(Replacement.getUnqualifiedType(), + Qs); + Result = SemaRef.Context.getSubstTemplateTypeParmType( + SubstTypeParam->getReplacedParameter(), + Replacement); + TLB.TypeWasModifiedSafely(Result); + } else { + // Otherwise, drop the new qualifier. + // FIXME: I don't recall the justification for this! + Quals.removeObjCLifetime(); + } + } + } if (!Quals.empty()) { Result = SemaRef.BuildQualifiedType(Result, T.getBeginLoc(), Quals); TLB.push<QualifiedTypeLoc>(Result); diff --git a/lib/Sema/TypeLocBuilder.h b/lib/Sema/TypeLocBuilder.h index f0944f1205..792bd1fc72 100644 --- a/lib/Sema/TypeLocBuilder.h +++ b/lib/Sema/TypeLocBuilder.h @@ -91,7 +91,6 @@ class TypeLocBuilder { /// modified in some safe way that doesn't affect type-location information. void TypeWasModifiedSafely(QualType T) { #ifndef NDEBUG - assert(T.getLocalUnqualifiedType() == LastTy.getLocalUnqualifiedType()); LastTy = T; #endif } |