diff options
Diffstat (limited to 'lib/Sema/SemaTemplateDeduction.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 124 |
1 files changed, 95 insertions, 29 deletions
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index d68e464..9500ec3 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -137,8 +137,17 @@ DeduceTemplateArguments(Sema &S, /// of a non-type template parameter, return the declaration of that /// non-type template parameter. static NonTypeTemplateParmDecl *getDeducedParameterFromExpr(Expr *E) { - if (ImplicitCastExpr *IC = dyn_cast<ImplicitCastExpr>(E)) - E = IC->getSubExpr(); + // If we are within an alias template, the expression may have undergone + // any number of parameter substitutions already. + while (1) { + if (ImplicitCastExpr *IC = dyn_cast<ImplicitCastExpr>(E)) + E = IC->getSubExpr(); + else if (SubstNonTypeTemplateParmExpr *Subst = + dyn_cast<SubstNonTypeTemplateParmExpr>(E)) + E = Subst->getReplacement(); + else + break; + } if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) return dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()); @@ -193,7 +202,7 @@ checkDeducedTemplateArguments(ASTContext &Context, if (Y.getKind() == TemplateArgument::Expression || Y.getKind() == TemplateArgument::Declaration || (Y.getKind() == TemplateArgument::Integral && - hasSameExtendedValue(*X.getAsIntegral(), *Y.getAsIntegral()))) + hasSameExtendedValue(X.getAsIntegral(), Y.getAsIntegral()))) return DeducedTemplateArgument(X, X.wasDeducedFromArrayBound() && Y.wasDeducedFromArrayBound()); @@ -293,7 +302,8 @@ DeduceNonTypeTemplateArgument(Sema &S, assert(NTTP->getDepth() == 0 && "Cannot deduce non-type template argument with depth > 0"); - DeducedTemplateArgument NewDeduced(Value, ValueType, DeducedFromArrayBound); + DeducedTemplateArgument NewDeduced(S.Context, Value, ValueType, + DeducedFromArrayBound); DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context, Deduced[NTTP->getIndex()], NewDeduced); @@ -1595,7 +1605,7 @@ DeduceTemplateArguments(Sema &S, case TemplateArgument::Integral: if (Arg.getKind() == TemplateArgument::Integral) { - if (hasSameExtendedValue(*Param.getAsIntegral(), *Arg.getAsIntegral())) + if (hasSameExtendedValue(Param.getAsIntegral(), Arg.getAsIntegral())) return Sema::TDK_Success; Info.FirstArg = Param; @@ -1618,7 +1628,7 @@ DeduceTemplateArguments(Sema &S, = getDeducedParameterFromExpr(Param.getAsExpr())) { if (Arg.getKind() == TemplateArgument::Integral) return DeduceNonTypeTemplateArgument(S, NTTP, - *Arg.getAsIntegral(), + Arg.getAsIntegral(), Arg.getIntegralType(), /*ArrayBound=*/false, Info, Deduced); @@ -1867,7 +1877,7 @@ static bool isSameTemplateArg(ASTContext &Context, Y.getAsTemplateOrTemplatePattern()).getAsVoidPointer(); case TemplateArgument::Integral: - return *X.getAsIntegral() == *Y.getAsIntegral(); + return X.getAsIntegral() == Y.getAsIntegral(); case TemplateArgument::Expression: { llvm::FoldingSetNodeID XID, YID; @@ -1898,7 +1908,7 @@ static bool isSameTemplateArg(ASTContext &Context, /// /// \param S The semantic analysis object. /// -/// \param The template argument we are producing template argument +/// \param Arg The template argument we are producing template argument /// location information for. /// /// \param NTTPType For a declaration template argument, the type of @@ -2171,8 +2181,9 @@ Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, TemplateArgs, Info, Deduced)) return Result; + SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end()); InstantiatingTemplate Inst(*this, Partial->getLocation(), Partial, - Deduced.data(), Deduced.size(), Info); + DeducedArgs, Info); if (Inst) return TDK_InstantiationDepth; @@ -2198,7 +2209,7 @@ static bool isSimpleTemplateIdType(QualType T) { /// \param FunctionTemplate the function template into which the explicit /// template arguments will be substituted. /// -/// \param ExplicitTemplateArguments the explicitly-specified template +/// \param ExplicitTemplateArgs the explicitly-specified template /// arguments. /// /// \param Deduced the deduced template arguments, which will be populated @@ -2256,8 +2267,9 @@ Sema::SubstituteExplicitTemplateArguments( // Enter a new template instantiation context where we check the // explicitly-specified template arguments against this function template, // and then substitute them into the function parameter types. + SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end()); InstantiatingTemplate Inst(*this, FunctionTemplate->getLocation(), - FunctionTemplate, Deduced.data(), Deduced.size(), + FunctionTemplate, DeducedArgs, ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution, Info); if (Inst) @@ -2424,6 +2436,16 @@ CheckOriginalCallArgDeduction(Sema &S, Sema::OriginalCallArg OriginalArg, Qualifiers AQuals = A.getQualifiers(); Qualifiers DeducedAQuals = DeducedA.getQualifiers(); + + // Under Objective-C++ ARC, the deduced type may have implicitly been + // given strong lifetime. If so, update the original qualifiers to + // include this strong lifetime. + if (S.getLangOpts().ObjCAutoRefCount && + DeducedAQuals.getObjCLifetime() == Qualifiers::OCL_Strong && + AQuals.getObjCLifetime() == Qualifiers::OCL_None) { + AQuals.setObjCLifetime(Qualifiers::OCL_Strong); + } + if (AQuals == DeducedAQuals) { // Qualifiers match; there's nothing to do. } else if (!DeducedAQuals.compatiblyIncludes(AQuals)) { @@ -2502,8 +2524,9 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate, // Enter a new template instantiation context while we instantiate the // actual function declaration. + SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end()); InstantiatingTemplate Inst(*this, FunctionTemplate->getLocation(), - FunctionTemplate, Deduced.data(), Deduced.size(), + FunctionTemplate, DeducedArgs, ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution, Info); if (Inst) @@ -2825,9 +2848,7 @@ static bool AdjustFunctionParmAndArgTypesForDeduction(Sema &S, QualType PointeeType = ParamRefType->getPointeeType(); // If the argument has incomplete array type, try to complete it's type. - if (ArgType->isIncompleteArrayType() && - !S.RequireCompleteExprType(Arg, S.PDiag(), - std::make_pair(SourceLocation(), S.PDiag()))) + if (ArgType->isIncompleteArrayType() && !S.RequireCompleteExprType(Arg, 0)) ArgType = Arg->getType(); // [C++0x] If P is an rvalue reference to a cv-unqualified @@ -2966,7 +2987,7 @@ DeduceTemplateArgumentByListElement(Sema &S, /// \param FunctionTemplate the function template for which we are performing /// template argument deduction. /// -/// \param ExplicitTemplateArguments the explicit template arguments provided +/// \param ExplicitTemplateArgs the explicit template arguments provided /// for this call. /// /// \param Args the function call arguments @@ -3226,7 +3247,7 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, /// \param FunctionTemplate the function template for which we are performing /// template argument deduction. /// -/// \param ExplicitTemplateArguments the explicitly-specified template +/// \param ExplicitTemplateArgs the explicitly-specified template /// arguments. /// /// \param ArgFunctionType the function type that will be used as the @@ -3409,7 +3430,7 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, /// \param FunctionTemplate the function template for which we are performing /// template argument deduction. /// -/// \param ExplicitTemplateArguments the explicitly-specified template +/// \param ExplicitTemplateArgs the explicitly-specified template /// arguments. /// /// \param Specialization if template argument deduction was successful, @@ -3465,6 +3486,41 @@ namespace { return E; } }; + + /// Determine whether the specified type (which contains an 'auto' type + /// specifier) is dependent. This is not trivial, because the 'auto' specifier + /// itself claims to be type-dependent. + bool isDependentAutoType(QualType Ty) { + while (1) { + QualType Pointee = Ty->getPointeeType(); + if (!Pointee.isNull()) { + Ty = Pointee; + } else if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>()){ + if (MPT->getClass()->isDependentType()) + return true; + Ty = MPT->getPointeeType(); + } else if (const FunctionProtoType *FPT = Ty->getAs<FunctionProtoType>()){ + for (FunctionProtoType::arg_type_iterator I = FPT->arg_type_begin(), + E = FPT->arg_type_end(); + I != E; ++I) + if ((*I)->isDependentType()) + return true; + Ty = FPT->getResultType(); + } else if (Ty->isDependentSizedArrayType()) { + return true; + } else if (const ArrayType *AT = Ty->getAsArrayTypeUnsafe()) { + Ty = AT->getElementType(); + } else if (Ty->getAs<DependentSizedExtVectorType>()) { + return true; + } else if (const VectorType *VT = Ty->getAs<VectorType>()) { + Ty = VT->getElementType(); + } else { + break; + } + } + assert(Ty->getAs<AutoType>() && "didn't find 'auto' in auto type"); + return false; + } } /// \brief Deduce the type for an auto type-specifier (C++0x [dcl.spec.auto]p6) @@ -3487,7 +3543,7 @@ Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init, Init = result.take(); } - if (Init->isTypeDependent()) { + if (Init->isTypeDependent() || isDependentAutoType(Type->getType())) { Result = Type; return DAR_Succeeded; } @@ -3518,10 +3574,10 @@ Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init, TemplateDeductionInfo Info(Context, Loc); - InitListExpr * InitList = dyn_cast<InitListExpr>(Init); + InitListExpr *InitList = dyn_cast<InitListExpr>(Init); if (InitList) { for (unsigned i = 0, e = InitList->getNumInits(); i < e; ++i) { - if (DeduceTemplateArgumentByListElement(*this, &TemplateParams, + if (DeduceTemplateArgumentByListElement(*this, &TemplateParams, TemplArg, InitList->getInit(i), Info, Deduced, TDF)) @@ -3532,7 +3588,7 @@ Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init, FuncParam, InitType, Init, TDF)) return DAR_Failed; - + if (DeduceTemplateArgumentsByTypeMatch(*this, &TemplateParams, FuncParam, InitType, Info, Deduced, TDF)) return DAR_Failed; @@ -4075,8 +4131,9 @@ Sema::getMoreSpecializedPartialSpecialization( /*PartialOrdering=*/true, /*RefParamComparisons=*/0); if (Better1) { + SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(),Deduced.end()); InstantiatingTemplate Inst(*this, PS2->getLocation(), PS2, - Deduced.data(), Deduced.size(), Info); + DeducedArgs, Info); Better1 = !::FinishTemplateArgumentDeduction(*this, PS2, PS1->getTemplateArgs(), Deduced, Info); @@ -4091,8 +4148,9 @@ Sema::getMoreSpecializedPartialSpecialization( /*PartialOrdering=*/true, /*RefParamComparisons=*/0); if (Better2) { + SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(),Deduced.end()); InstantiatingTemplate Inst(*this, PS1->getLocation(), PS1, - Deduced.data(), Deduced.size(), Info); + DeducedArgs, Info); Better2 = !::FinishTemplateArgumentDeduction(*this, PS1, PS2->getTemplateArgs(), Deduced, Info); @@ -4123,9 +4181,17 @@ MarkUsedTemplateParameters(ASTContext &Ctx, if (const PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(E)) E = Expansion->getPattern(); - // Skip through any implicit casts we added while type-checking. - while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) - E = ICE->getSubExpr(); + // Skip through any implicit casts we added while type-checking, and any + // substitutions performed by template alias expansion. + while (1) { + if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) + E = ICE->getSubExpr(); + else if (const SubstNonTypeTemplateParmExpr *Subst = + dyn_cast<SubstNonTypeTemplateParmExpr>(E)) + E = Subst->getReplacement(); + else + break; + } // FIXME: if !OnlyDeduced, we have to walk the whole subexpression to // find other occurrences of template parameters. @@ -4456,13 +4522,13 @@ MarkUsedTemplateParameters(ASTContext &Ctx, } } -/// \brief Mark the template parameters can be deduced by the given +/// \brief Mark which template parameters can be deduced from a given /// template argument list. /// /// \param TemplateArgs the template argument list from which template /// parameters will be deduced. /// -/// \param Deduced a bit vector whose elements will be set to \c true +/// \param Used a bit vector whose elements will be set to \c true /// to indicate when the corresponding template parameter will be /// deduced. void |