diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaTemplateDeduction.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaTemplateDeduction.cpp | 384 |
1 files changed, 241 insertions, 143 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateDeduction.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateDeduction.cpp index 93e796ee9668..ebdf6dd57fc5 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -112,6 +112,15 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, SmallVectorImpl<DeducedTemplateArgument> &Deduced, bool NumberOfArgumentsMustMatch); +static void MarkUsedTemplateParameters(ASTContext &Ctx, + const TemplateArgument &TemplateArg, + bool OnlyDeduced, unsigned Depth, + llvm::SmallBitVector &Used); + +static void MarkUsedTemplateParameters(ASTContext &Ctx, QualType T, + bool OnlyDeduced, unsigned Level, + llvm::SmallBitVector &Deduced); + /// \brief If the given expression is of a form that permits the deduction /// of a non-type template parameter, return the declaration of that /// non-type template parameter. @@ -334,12 +343,24 @@ static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument( if (!S.getLangOpts().CPlusPlus1z) return Sema::TDK_Success; + if (NTTP->isExpandedParameterPack()) + // FIXME: We may still need to deduce parts of the type here! But we + // don't have any way to find which slice of the type to use, and the + // type stored on the NTTP itself is nonsense. Perhaps the type of an + // expanded NTTP should be a pack expansion type? + return Sema::TDK_Success; + + // Get the type of the parameter for deduction. + QualType ParamType = NTTP->getType(); + if (auto *Expansion = dyn_cast<PackExpansionType>(ParamType)) + ParamType = Expansion->getPattern(); + // FIXME: It's not clear how deduction of a parameter of reference // type from an argument (of non-reference type) should be performed. // For now, we just remove reference types from both sides and let // the final check for matching types sort out the mess. return DeduceTemplateArgumentsByTypeMatch( - S, TemplateParams, NTTP->getType().getNonReferenceType(), + S, TemplateParams, ParamType.getNonReferenceType(), ValueType.getNonReferenceType(), Info, Deduced, TDF_SkipNonDependent, /*PartialOrdering=*/false, /*ArrayBound=*/NewDeduced.wasDeducedFromArrayBound()); @@ -617,29 +638,68 @@ public: SmallVectorImpl<DeducedTemplateArgument> &Deduced, TemplateDeductionInfo &Info, TemplateArgument Pattern) : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info) { + // Dig out the partially-substituted pack, if there is one. + const TemplateArgument *PartialPackArgs = nullptr; + unsigned NumPartialPackArgs = 0; + std::pair<unsigned, unsigned> PartialPackDepthIndex(-1u, -1u); + if (auto *Scope = S.CurrentInstantiationScope) + if (auto *Partial = Scope->getPartiallySubstitutedPack( + &PartialPackArgs, &NumPartialPackArgs)) + PartialPackDepthIndex = getDepthAndIndex(Partial); + // Compute the set of template parameter indices that correspond to // parameter packs expanded by the pack expansion. { llvm::SmallBitVector SawIndices(TemplateParams->size()); + + auto AddPack = [&](unsigned Index) { + if (SawIndices[Index]) + return; + SawIndices[Index] = true; + + // Save the deduced template argument for the parameter pack expanded + // by this pack expansion, then clear out the deduction. + DeducedPack Pack(Index); + Pack.Saved = Deduced[Index]; + Deduced[Index] = TemplateArgument(); + + Packs.push_back(Pack); + }; + + // First look for unexpanded packs in the pattern. SmallVector<UnexpandedParameterPack, 2> Unexpanded; S.collectUnexpandedParameterPacks(Pattern, Unexpanded); for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) { unsigned Depth, Index; std::tie(Depth, Index) = getDepthAndIndex(Unexpanded[I]); - if (Depth == Info.getDeducedDepth() && !SawIndices[Index]) { - SawIndices[Index] = true; - - // Save the deduced template argument for the parameter pack expanded - // by this pack expansion, then clear out the deduction. - DeducedPack Pack(Index); - Pack.Saved = Deduced[Index]; - Deduced[Index] = TemplateArgument(); - - Packs.push_back(Pack); - } + if (Depth == Info.getDeducedDepth()) + AddPack(Index); } + assert(!Packs.empty() && "Pack expansion without unexpanded packs?"); + + // This pack expansion will have been partially expanded iff the only + // unexpanded parameter pack within it is the partially-substituted pack. + IsPartiallyExpanded = + Packs.size() == 1 && + PartialPackDepthIndex == + std::make_pair(Info.getDeducedDepth(), Packs.front().Index); + + // Skip over the pack elements that were expanded into separate arguments. + if (IsPartiallyExpanded) + PackElements += NumPartialPackArgs; + + // We can also have deduced template parameters that do not actually + // appear in the pattern, but can be deduced by it (the type of a non-type + // template parameter pack, in particular). These won't have prevented us + // from partially expanding the pack. + llvm::SmallBitVector Used(TemplateParams->size()); + MarkUsedTemplateParameters(S.Context, Pattern, /*OnlyDeduced*/true, + Info.getDeducedDepth(), Used); + for (int Index = Used.find_first(); Index != -1; + Index = Used.find_next(Index)) + if (TemplateParams->getParam(Index)->isParameterPack()) + AddPack(Index); } - assert(!Packs.empty() && "Pack expansion without unexpanded packs?"); for (auto &Pack : Packs) { if (Info.PendingDeducedPacks.size() > Pack.Index) @@ -648,18 +708,19 @@ public: Info.PendingDeducedPacks.resize(Pack.Index + 1); Info.PendingDeducedPacks[Pack.Index] = &Pack; - if (S.CurrentInstantiationScope) { - // If the template argument pack was explicitly specified, add that to - // the set of deduced arguments. - const TemplateArgument *ExplicitArgs; - unsigned NumExplicitArgs; - NamedDecl *PartiallySubstitutedPack = - S.CurrentInstantiationScope->getPartiallySubstitutedPack( - &ExplicitArgs, &NumExplicitArgs); - if (PartiallySubstitutedPack && - getDepthAndIndex(PartiallySubstitutedPack) == - std::make_pair(Info.getDeducedDepth(), Pack.Index)) - Pack.New.append(ExplicitArgs, ExplicitArgs + NumExplicitArgs); + if (PartialPackDepthIndex == + std::make_pair(Info.getDeducedDepth(), Pack.Index)) { + Pack.New.append(PartialPackArgs, PartialPackArgs + NumPartialPackArgs); + // We pre-populate the deduced value of the partially-substituted + // pack with the specified value. This is not entirely correct: the + // value is supposed to have been substituted, not deduced, but the + // cases where this is observable require an exact type match anyway. + // + // FIXME: If we could represent a "depth i, index j, pack elem k" + // parameter, we could substitute the partially-substituted pack + // everywhere and avoid this. + if (Pack.New.size() > PackElements) + Deduced[Pack.Index] = Pack.New[PackElements]; } } } @@ -671,16 +732,7 @@ public: /// Determine whether this pack has already been partially expanded into a /// sequence of (prior) function parameters / template arguments. - bool isPartiallyExpanded() { - if (Packs.size() != 1 || !S.CurrentInstantiationScope) - return false; - - auto *PartiallySubstitutedPack = - S.CurrentInstantiationScope->getPartiallySubstitutedPack(); - return PartiallySubstitutedPack && - getDepthAndIndex(PartiallySubstitutedPack) == - std::make_pair(Info.getDeducedDepth(), Packs.front().Index); - } + bool isPartiallyExpanded() { return IsPartiallyExpanded; } /// Move to deducing the next element in each pack that is being deduced. void nextPackElement() { @@ -692,8 +744,13 @@ public: if (!Pack.New.empty() || !DeducedArg.isNull()) { while (Pack.New.size() < PackElements) Pack.New.push_back(DeducedTemplateArgument()); - Pack.New.push_back(DeducedArg); - DeducedArg = DeducedTemplateArgument(); + if (Pack.New.size() == PackElements) + Pack.New.push_back(DeducedArg); + else + Pack.New[PackElements] = DeducedArg; + DeducedArg = Pack.New.size() > PackElements + 1 + ? Pack.New[PackElements + 1] + : DeducedTemplateArgument(); } } ++PackElements; @@ -730,6 +787,11 @@ public: std::copy(Pack.New.begin(), Pack.New.end(), ArgumentPack); NewPack = DeducedTemplateArgument( TemplateArgument(llvm::makeArrayRef(ArgumentPack, Pack.New.size())), + // FIXME: This is wrong, it's possible that some pack elements are + // deduced from an array bound and others are not: + // template<typename ...T, T ...V> void g(const T (&...p)[V]); + // g({1, 2, 3}, {{}, {}}); + // ... should deduce T = {int, size_t (from array bound)}. Pack.New[0].wasDeducedFromArrayBound()); } @@ -779,6 +841,7 @@ private: SmallVectorImpl<DeducedTemplateArgument> &Deduced; TemplateDeductionInfo &Info; unsigned PackElements = 0; + bool IsPartiallyExpanded = false; SmallVector<DeducedPack, 2> Packs; }; @@ -963,6 +1026,32 @@ bool Sema::isSameOrCompatibleFunctionType(CanQualType Param, return Param == Arg; } +/// Get the index of the first template parameter that was originally from the +/// innermost template-parameter-list. This is 0 except when we concatenate +/// the template parameter lists of a class template and a constructor template +/// when forming an implicit deduction guide. +static unsigned getFirstInnerIndex(FunctionTemplateDecl *FTD) { + auto *Guide = dyn_cast<CXXDeductionGuideDecl>(FTD->getTemplatedDecl()); + if (!Guide || !Guide->isImplicit()) + return 0; + return Guide->getDeducedTemplate()->getTemplateParameters()->size(); +} + +/// Determine whether a type denotes a forwarding reference. +static bool isForwardingReference(QualType Param, unsigned FirstInnerIndex) { + // C++1z [temp.deduct.call]p3: + // A forwarding reference is an rvalue reference to a cv-unqualified + // template parameter that does not represent a template parameter of a + // class template. + if (auto *ParamRef = Param->getAs<RValueReferenceType>()) { + if (ParamRef->getPointeeType().getQualifiers()) + return false; + auto *TypeParm = ParamRef->getPointeeType()->getAs<TemplateTypeParmType>(); + return TypeParm && TypeParm->getIndex() >= FirstInnerIndex; + } + return false; +} + /// \brief Deduce the template arguments by comparing the parameter type and /// the argument type (C++ [temp.deduct.type]). /// @@ -1083,21 +1172,15 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, // taking the address of a function template (14.8.2.2) or when deducing // template arguments from a function declaration (14.8.2.6) and Pi and // Ai are parameters of the top-level parameter-type-list of P and A, - // respectively, Pi is adjusted if it is an rvalue reference to a - // cv-unqualified template parameter and Ai is an lvalue reference, in + // respectively, Pi is adjusted if it is a forwarding reference and Ai + // is an lvalue reference, in // which case the type of Pi is changed to be the template parameter // type (i.e., T&& is changed to simply T). [ Note: As a result, when // Pi is T&& and Ai is X&, the adjusted Pi will be T, causing T to be // deduced as X&. - end note ] TDF &= ~TDF_TopLevelParameterTypeList; - - if (const RValueReferenceType *ParamRef - = Param->getAs<RValueReferenceType>()) { - if (isa<TemplateTypeParmType>(ParamRef->getPointeeType()) && - !ParamRef->getPointeeType().getQualifiers()) - if (Arg->isLValueReferenceType()) - Param = ParamRef->getPointeeType(); - } + if (isForwardingReference(Param, 0) && Arg->isLValueReferenceType()) + Param = Param->getPointeeType(); } } @@ -1723,6 +1806,7 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, case Type::Decltype: case Type::UnaryTransform: case Type::Auto: + case Type::DeducedTemplateSpecialization: case Type::DependentTemplateSpecialization: case Type::PackExpansion: case Type::Pipe: @@ -2335,7 +2419,7 @@ static Sema::TemplateDeductionResult ConvertDeducedTemplateArguments( return Sema::TDK_Success; } -DeclContext *getAsDeclContextOrEnclosing(Decl *D) { +static DeclContext *getAsDeclContextOrEnclosing(Decl *D) { if (auto *DC = dyn_cast<DeclContext>(D)) return DC; return D->getDeclContext(); @@ -2363,7 +2447,8 @@ FinishTemplateArgumentDeduction( SmallVectorImpl<DeducedTemplateArgument> &Deduced, TemplateDeductionInfo &Info) { // Unevaluated SFINAE context. - EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated); + EnterExpressionEvaluationContext Unevaluated( + S, Sema::ExpressionEvaluationContext::Unevaluated); Sema::SFINAETrap Trap(S); Sema::ContextRAII SavedContext(S, getAsDeclContextOrEnclosing(Partial)); @@ -2435,13 +2520,14 @@ FinishTemplateArgumentDeduction( /// Complete template argument deduction for a class or variable template, /// when partial ordering against a partial specialization. // FIXME: Factor out duplication with partial specialization version above. -Sema::TemplateDeductionResult FinishTemplateArgumentDeduction( +static Sema::TemplateDeductionResult FinishTemplateArgumentDeduction( Sema &S, TemplateDecl *Template, bool PartialOrdering, const TemplateArgumentList &TemplateArgs, SmallVectorImpl<DeducedTemplateArgument> &Deduced, TemplateDeductionInfo &Info) { // Unevaluated SFINAE context. - EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated); + EnterExpressionEvaluationContext Unevaluated( + S, Sema::ExpressionEvaluationContext::Unevaluated); Sema::SFINAETrap Trap(S); Sema::ContextRAII SavedContext(S, getAsDeclContextOrEnclosing(Template)); @@ -2491,7 +2577,8 @@ Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, // list (14.8.2). // Unevaluated SFINAE context. - EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); + EnterExpressionEvaluationContext Unevaluated( + *this, Sema::ExpressionEvaluationContext::Unevaluated); SFINAETrap Trap(*this); SmallVector<DeducedTemplateArgument, 4> Deduced; @@ -2533,7 +2620,8 @@ Sema::DeduceTemplateArguments(VarTemplatePartialSpecializationDecl *Partial, // list (14.8.2). // Unevaluated SFINAE context. - EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); + EnterExpressionEvaluationContext Unevaluated( + *this, Sema::ExpressionEvaluationContext::Unevaluated); SFINAETrap Trap(*this); SmallVector<DeducedTemplateArgument, 4> Deduced; @@ -2565,12 +2653,6 @@ static bool isSimpleTemplateIdType(QualType T) { return false; } -static void -MarkUsedTemplateParameters(ASTContext &Ctx, QualType T, - bool OnlyDeduced, - unsigned Level, - llvm::SmallBitVector &Deduced); - /// \brief Substitute the explicitly-provided template arguments into the /// given function template according to C++ [temp.arg.explicit]. /// @@ -2619,7 +2701,8 @@ Sema::SubstituteExplicitTemplateArguments( } // Unevaluated SFINAE context. - EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); + EnterExpressionEvaluationContext Unevaluated( + *this, Sema::ExpressionEvaluationContext::Unevaluated); SFINAETrap Trap(*this); // C++ [temp.arg.explicit]p3: @@ -2633,18 +2716,15 @@ Sema::SubstituteExplicitTemplateArguments( // explicitly-specified template arguments against this function template, // and then substitute them into the function parameter types. SmallVector<TemplateArgument, 4> DeducedArgs; - InstantiatingTemplate Inst(*this, Info.getLocation(), FunctionTemplate, - DeducedArgs, - ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution, - Info); + InstantiatingTemplate Inst( + *this, Info.getLocation(), FunctionTemplate, DeducedArgs, + CodeSynthesisContext::ExplicitTemplateArgumentSubstitution, Info); if (Inst.isInvalid()) return TDK_InstantiationDepth; - if (CheckTemplateArgumentList(FunctionTemplate, - SourceLocation(), - ExplicitTemplateArgs, - true, - Builder) || Trap.hasErrorOccurred()) { + if (CheckTemplateArgumentList(FunctionTemplate, SourceLocation(), + ExplicitTemplateArgs, true, Builder, false) || + Trap.hasErrorOccurred()) { unsigned Index = Builder.size(); if (Index >= TemplateParams->size()) Index = TemplateParams->size() - 1; @@ -2920,16 +3000,16 @@ Sema::TemplateDeductionResult Sema::FinishTemplateArgumentDeduction( SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs, bool PartialOverloading, llvm::function_ref<bool()> CheckNonDependent) { // Unevaluated SFINAE context. - EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); + EnterExpressionEvaluationContext Unevaluated( + *this, Sema::ExpressionEvaluationContext::Unevaluated); SFINAETrap Trap(*this); // Enter a new template instantiation context while we instantiate the // actual function declaration. SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end()); - InstantiatingTemplate Inst(*this, Info.getLocation(), FunctionTemplate, - DeducedArgs, - ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution, - Info); + InstantiatingTemplate Inst( + *this, Info.getLocation(), FunctionTemplate, DeducedArgs, + CodeSynthesisContext::DeducedTemplateArgumentSubstitution, Info); if (Inst.isInvalid()) return TDK_InstantiationDepth; @@ -3186,12 +3266,9 @@ ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams, /// \returns true if the caller should not attempt to perform any template /// argument deduction based on this P/A pair because the argument is an /// overloaded function set that could not be resolved. -static bool AdjustFunctionParmAndArgTypesForDeduction(Sema &S, - TemplateParameterList *TemplateParams, - QualType &ParamType, - QualType &ArgType, - Expr *Arg, - unsigned &TDF) { +static bool AdjustFunctionParmAndArgTypesForDeduction( + Sema &S, TemplateParameterList *TemplateParams, unsigned FirstInnerIndex, + QualType &ParamType, QualType &ArgType, Expr *Arg, unsigned &TDF) { // C++0x [temp.deduct.call]p3: // If P is a cv-qualified type, the top level cv-qualifiers of P's type // are ignored for type deduction. @@ -3222,13 +3299,10 @@ static bool AdjustFunctionParmAndArgTypesForDeduction(Sema &S, ArgType = Arg->getType(); } - // C++0x [temp.deduct.call]p3: - // If P is an rvalue reference to a cv-unqualified template - // parameter and the argument is an lvalue, the type "lvalue - // reference to A" is used in place of A for type deduction. - if (ParamRefType->isRValueReferenceType() && - !ParamType.getQualifiers() && - isa<TemplateTypeParmType>(ParamType) && + // C++1z [temp.deduct.call]p3: + // If P is a forwarding reference and the argument is an lvalue, the type + // "lvalue reference to A" is used in place of A for type deduction. + if (isForwardingReference(QualType(ParamRefType, 0), FirstInnerIndex) && Arg->isLValue()) ArgType = S.Context.getLValueReferenceType(ArgType); } else { @@ -3287,8 +3361,8 @@ hasDeducibleTemplateParameters(Sema &S, FunctionTemplateDecl *FunctionTemplate, QualType T); static Sema::TemplateDeductionResult DeduceTemplateArgumentsFromCallArgument( - Sema &S, TemplateParameterList *TemplateParams, QualType ParamType, - Expr *Arg, TemplateDeductionInfo &Info, + Sema &S, TemplateParameterList *TemplateParams, unsigned FirstInnerIndex, + QualType ParamType, Expr *Arg, TemplateDeductionInfo &Info, SmallVectorImpl<DeducedTemplateArgument> &Deduced, SmallVectorImpl<Sema::OriginalCallArg> &OriginalCallArgs, bool DecomposedParam, unsigned ArgIdx, unsigned TDF); @@ -3326,7 +3400,7 @@ static Sema::TemplateDeductionResult DeduceFromInitializerList( if (ElTy->isDependentType()) { for (Expr *E : ILE->inits()) { if (auto Result = DeduceTemplateArgumentsFromCallArgument( - S, TemplateParams, ElTy, E, Info, Deduced, OriginalCallArgs, true, + S, TemplateParams, 0, ElTy, E, Info, Deduced, OriginalCallArgs, true, ArgIdx, TDF)) return Result; } @@ -3340,10 +3414,12 @@ static Sema::TemplateDeductionResult DeduceFromInitializerList( getDeducedParameterFromExpr(Info, DependentArrTy->getSizeExpr())) { // We can perform template argument deduction for the given non-type // template parameter. - llvm::APInt Size(S.Context.getIntWidth(NTTP->getType()), - ILE->getNumInits()); + // C++ [temp.deduct.type]p13: + // The type of N in the type T[N] is std::size_t. + QualType T = S.Context.getSizeType(); + llvm::APInt Size(S.Context.getIntWidth(T), ILE->getNumInits()); if (auto Result = DeduceNonTypeTemplateArgument( - S, TemplateParams, NTTP, llvm::APSInt(Size), NTTP->getType(), + S, TemplateParams, NTTP, llvm::APSInt(Size), T, /*ArrayBound=*/true, Info, Deduced)) return Result; } @@ -3355,8 +3431,8 @@ static Sema::TemplateDeductionResult DeduceFromInitializerList( /// \brief Perform template argument deduction per [temp.deduct.call] for a /// single parameter / argument pair. static Sema::TemplateDeductionResult DeduceTemplateArgumentsFromCallArgument( - Sema &S, TemplateParameterList *TemplateParams, QualType ParamType, - Expr *Arg, TemplateDeductionInfo &Info, + Sema &S, TemplateParameterList *TemplateParams, unsigned FirstInnerIndex, + QualType ParamType, Expr *Arg, TemplateDeductionInfo &Info, SmallVectorImpl<DeducedTemplateArgument> &Deduced, SmallVectorImpl<Sema::OriginalCallArg> &OriginalCallArgs, bool DecomposedParam, unsigned ArgIdx, unsigned TDF) { @@ -3365,8 +3441,8 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsFromCallArgument( // If P is a reference type [...] // If P is a cv-qualified type [...] - if (AdjustFunctionParmAndArgTypesForDeduction(S, TemplateParams, ParamType, - ArgType, Arg, TDF)) + if (AdjustFunctionParmAndArgTypesForDeduction( + S, TemplateParams, FirstInnerIndex, ParamType, ArgType, Arg, TDF)) return Sema::TDK_Success; // If [...] the argument is a non-empty initializer list [...] @@ -3422,6 +3498,8 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( FunctionDecl *Function = FunctionTemplate->getTemplatedDecl(); unsigned NumParams = Function->getNumParams(); + unsigned FirstInnerIndex = getFirstInnerIndex(FunctionTemplate); + // C++ [temp.deduct.call]p1: // Template argument deduction is done by comparing each function template // parameter type (call it P) with the type of the corresponding argument @@ -3476,7 +3554,7 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( // ... with the type of the corresponding argument return DeduceTemplateArgumentsFromCallArgument( - *this, TemplateParams, ParamType, Args[ArgIdx], Info, Deduced, + *this, TemplateParams, FirstInnerIndex, ParamType, Args[ArgIdx], Info, Deduced, OriginalCallArgs, /*Decomposed*/false, ArgIdx, /*TDF*/ 0); }; @@ -3659,7 +3737,8 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( } // Unevaluated SFINAE context. - EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); + EnterExpressionEvaluationContext Unevaluated( + *this, Sema::ExpressionEvaluationContext::Unevaluated); SFINAETrap Trap(*this); Deduced.resize(TemplateParams->size()); @@ -3907,7 +3986,8 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *ConversionTemplate, } // Unevaluated SFINAE context. - EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); + EnterExpressionEvaluationContext Unevaluated( + *this, Sema::ExpressionEvaluationContext::Unevaluated); SFINAETrap Trap(*this); // C++ [temp.deduct.conv]p1: @@ -4020,17 +4100,26 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( } namespace { - /// Substitute the 'auto' type specifier within a type for a given replacement - /// type. - class SubstituteAutoTransform : - public TreeTransform<SubstituteAutoTransform> { + /// Substitute the 'auto' specifier or deduced template specialization type + /// specifier within a type for a given replacement type. + class SubstituteDeducedTypeTransform : + public TreeTransform<SubstituteDeducedTypeTransform> { QualType Replacement; - bool UseAutoSugar; + bool UseTypeSugar; public: - SubstituteAutoTransform(Sema &SemaRef, QualType Replacement, - bool UseAutoSugar = true) - : TreeTransform<SubstituteAutoTransform>(SemaRef), - Replacement(Replacement), UseAutoSugar(UseAutoSugar) {} + SubstituteDeducedTypeTransform(Sema &SemaRef, QualType Replacement, + bool UseTypeSugar = true) + : TreeTransform<SubstituteDeducedTypeTransform>(SemaRef), + Replacement(Replacement), UseTypeSugar(UseTypeSugar) {} + + QualType TransformDesugared(TypeLocBuilder &TLB, DeducedTypeLoc TL) { + assert(isa<TemplateTypeParmType>(Replacement) && + "unexpected unsugared replacement kind"); + QualType Result = Replacement; + TemplateTypeParmTypeLoc NewTL = TLB.push<TemplateTypeParmTypeLoc>(Result); + NewTL.setNameLoc(TL.getNameLoc()); + return Result; + } QualType TransformAutoType(TypeLocBuilder &TLB, AutoTypeLoc TL) { // If we're building the type pattern to deduce against, don't wrap the @@ -4040,21 +4129,29 @@ namespace { // auto &&lref = lvalue; // must transform into "rvalue reference to T" not "rvalue reference to // auto type deduced as T" in order for [temp.deduct.call]p3 to apply. - if (!UseAutoSugar) { - assert(isa<TemplateTypeParmType>(Replacement) && - "unexpected unsugared replacement kind"); - QualType Result = Replacement; - TemplateTypeParmTypeLoc NewTL = - TLB.push<TemplateTypeParmTypeLoc>(Result); - NewTL.setNameLoc(TL.getNameLoc()); - return Result; - } else { - QualType Result = SemaRef.Context.getAutoType( - Replacement, TL.getTypePtr()->getKeyword(), Replacement.isNull()); - AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result); - NewTL.setNameLoc(TL.getNameLoc()); - return Result; - } + // + // FIXME: Is this still necessary? + if (!UseTypeSugar) + return TransformDesugared(TLB, TL); + + QualType Result = SemaRef.Context.getAutoType( + Replacement, TL.getTypePtr()->getKeyword(), Replacement.isNull()); + auto NewTL = TLB.push<AutoTypeLoc>(Result); + NewTL.setNameLoc(TL.getNameLoc()); + return Result; + } + + QualType TransformDeducedTemplateSpecializationType( + TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) { + if (!UseTypeSugar) + return TransformDesugared(TLB, TL); + + QualType Result = SemaRef.Context.getDeducedTemplateSpecializationType( + TL.getTypePtr()->getTemplateName(), + Replacement, Replacement.isNull()); + auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(Result); + NewTL.setNameLoc(TL.getNameLoc()); + return Result; } ExprResult TransformLambdaExpr(LambdaExpr *E) { @@ -4105,7 +4202,7 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result, if (!DependentDeductionDepth && (Type.getType()->isDependentType() || Init->isTypeDependent())) { - Result = SubstituteAutoTransform(*this, QualType()).Apply(Type); + Result = SubstituteDeducedTypeTransform(*this, QualType()).Apply(Type); assert(!Result.isNull() && "substituting DependentTy can't fail"); return DAR_Succeeded; } @@ -4128,7 +4225,7 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result, return DAR_FailedAlreadyDiagnosed; // FIXME: Support a non-canonical deduced type for 'auto'. Deduced = Context.getCanonicalType(Deduced); - Result = SubstituteAutoTransform(*this, Deduced).Apply(Type); + Result = SubstituteDeducedTypeTransform(*this, Deduced).Apply(Type); if (Result.isNull()) return DAR_FailedAlreadyDiagnosed; return DAR_Succeeded; @@ -4153,7 +4250,7 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result, Loc, Loc, TemplParamPtr, Loc, nullptr); QualType FuncParam = - SubstituteAutoTransform(*this, TemplArg, /*UseAutoSugar*/false) + SubstituteDeducedTypeTransform(*this, TemplArg, /*UseTypeSugar*/false) .Apply(Type); assert(!FuncParam.isNull() && "substituting template parameter for 'auto' failed"); @@ -4168,7 +4265,7 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result, // might acquire a matching type in the instantiation. auto DeductionFailed = [&]() -> DeduceAutoResult { if (Init->isTypeDependent()) { - Result = SubstituteAutoTransform(*this, QualType()).Apply(Type); + Result = SubstituteDeducedTypeTransform(*this, QualType()).Apply(Type); assert(!Result.isNull() && "substituting DependentTy can't fail"); return DAR_Succeeded; } @@ -4187,7 +4284,7 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result, for (unsigned i = 0, e = InitList->getNumInits(); i < e; ++i) { if (DeduceTemplateArgumentsFromCallArgument( - *this, TemplateParamsSt.get(), TemplArg, InitList->getInit(i), + *this, TemplateParamsSt.get(), 0, TemplArg, InitList->getInit(i), Info, Deduced, OriginalCallArgs, /*Decomposed*/ true, /*ArgIdx*/ 0, /*TDF*/ 0)) return DeductionFailed(); @@ -4199,7 +4296,7 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result, } if (DeduceTemplateArgumentsFromCallArgument( - *this, TemplateParamsSt.get(), FuncParam, Init, Info, Deduced, + *this, TemplateParamsSt.get(), 0, FuncParam, Init, Info, Deduced, OriginalCallArgs, /*Decomposed*/ false, /*ArgIdx*/ 0, /*TDF*/ 0)) return DeductionFailed(); } @@ -4216,7 +4313,7 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result, return DAR_FailedAlreadyDiagnosed; } - Result = SubstituteAutoTransform(*this, DeducedType).Apply(Type); + Result = SubstituteDeducedTypeTransform(*this, DeducedType).Apply(Type); if (Result.isNull()) return DAR_FailedAlreadyDiagnosed; @@ -4239,15 +4336,22 @@ QualType Sema::SubstAutoType(QualType TypeWithAuto, QualType TypeToReplaceAuto) { if (TypeToReplaceAuto->isDependentType()) TypeToReplaceAuto = QualType(); - return SubstituteAutoTransform(*this, TypeToReplaceAuto) + return SubstituteDeducedTypeTransform(*this, TypeToReplaceAuto) .TransformType(TypeWithAuto); } -TypeSourceInfo* Sema::SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, - QualType TypeToReplaceAuto) { +TypeSourceInfo *Sema::SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, + QualType TypeToReplaceAuto) { if (TypeToReplaceAuto->isDependentType()) TypeToReplaceAuto = QualType(); - return SubstituteAutoTransform(*this, TypeToReplaceAuto) + return SubstituteDeducedTypeTransform(*this, TypeToReplaceAuto) + .TransformType(TypeWithAuto); +} + +QualType Sema::ReplaceAutoType(QualType TypeWithAuto, + QualType TypeToReplaceAuto) { + return SubstituteDeducedTypeTransform(*this, TypeToReplaceAuto, + /*UseTypeSugar*/ false) .TransformType(TypeWithAuto); } @@ -4848,13 +4952,6 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs( return isAtLeastAsSpecializedAs(*this, PType, AType, AArg, Info); } -static void -MarkUsedTemplateParameters(ASTContext &Ctx, - const TemplateArgument &TemplateArg, - bool OnlyDeduced, - unsigned Depth, - llvm::SmallBitVector &Used); - /// \brief Mark the template parameters that are used by the given /// expression. static void @@ -5154,8 +5251,9 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T, break; case Type::Auto: + case Type::DeducedTemplateSpecialization: MarkUsedTemplateParameters(Ctx, - cast<AutoType>(T)->getDeducedType(), + cast<DeducedType>(T)->getDeducedType(), OnlyDeduced, Depth, Used); // None of these types have any template parameters in them. |