diff options
Diffstat (limited to 'lib/Sema/SemaTemplateDeduction.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 909 |
1 files changed, 513 insertions, 396 deletions
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index f8ee60251698..633b2837e1fe 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -1,60 +1,97 @@ -//===------- SemaTemplateDeduction.cpp - Template Argument Deduction ------===/ +//===- SemaTemplateDeduction.cpp - Template Argument Deduction ------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. -//===----------------------------------------------------------------------===/ // -// This file implements C++ template argument deduction. +//===----------------------------------------------------------------------===// // -//===----------------------------------------------------------------------===/ +// This file implements C++ template argument deduction. +// +//===----------------------------------------------------------------------===// #include "clang/Sema/TemplateDeduction.h" #include "TreeTransform.h" +#include "TypeLocBuilder.h" #include "clang/AST/ASTContext.h" #include "clang/AST/ASTLambda.h" -#include "clang/AST/DeclObjC.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclAccessPair.h" +#include "clang/AST/DeclBase.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/DeclarationName.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" -#include "clang/AST/StmtVisitor.h" -#include "clang/AST/TypeOrdering.h" -#include "clang/Sema/DeclSpec.h" +#include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/TemplateBase.h" +#include "clang/AST/TemplateName.h" +#include "clang/AST/Type.h" +#include "clang/AST/TypeLoc.h" +#include "clang/AST/UnresolvedSet.h" +#include "clang/Basic/AddressSpaces.h" +#include "clang/Basic/ExceptionSpecificationType.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/PartialDiagnostic.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Specifiers.h" +#include "clang/Sema/Ownership.h" #include "clang/Sema/Sema.h" #include "clang/Sema/Template.h" +#include "llvm/ADT/APInt.h" +#include "llvm/ADT/APSInt.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallBitVector.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/ErrorHandling.h" #include <algorithm> +#include <cassert> +#include <tuple> +#include <utility> namespace clang { - using namespace sema; - /// \brief Various flags that control template argument deduction. + + /// Various flags that control template argument deduction. /// /// These flags can be bitwise-OR'd together. enum TemplateDeductionFlags { - /// \brief No template argument deduction flags, which indicates the + /// No template argument deduction flags, which indicates the /// strictest results for template argument deduction (as used for, e.g., /// matching class template partial specializations). TDF_None = 0, - /// \brief Within template argument deduction from a function call, we are + + /// Within template argument deduction from a function call, we are /// matching with a parameter type for which the original parameter was /// a reference. TDF_ParamWithReferenceType = 0x1, - /// \brief Within template argument deduction from a function call, we + + /// Within template argument deduction from a function call, we /// are matching in a case where we ignore cv-qualifiers. TDF_IgnoreQualifiers = 0x02, - /// \brief Within template argument deduction from a function call, + + /// Within template argument deduction from a function call, /// we are matching in a case where we can perform template argument /// deduction from a template-id of a derived class of the argument type. TDF_DerivedClass = 0x04, - /// \brief Allow non-dependent types to differ, e.g., when performing + + /// Allow non-dependent types to differ, e.g., when performing /// template argument deduction from a function call where conversions /// may apply. TDF_SkipNonDependent = 0x08, - /// \brief Whether we are performing template argument deduction for + + /// Whether we are performing template argument deduction for /// parameters and arguments in a top-level template argument TDF_TopLevelParameterTypeList = 0x10, - /// \brief Within template argument deduction from overload resolution per + + /// Within template argument deduction from overload resolution per /// C++ [over.over] allow matching function types that are compatible in /// terms of noreturn and default calling convention adjustments, or /// similarly matching a declared template specialization against a @@ -62,12 +99,18 @@ namespace clang { /// deduction where the parameter is a function type that can be converted /// to the argument type. TDF_AllowCompatibleFunctionType = 0x20, + + /// Within template argument deduction for a conversion function, we are + /// matching with an argument type for which the original argument was + /// a reference. + TDF_ArgWithReferenceType = 0x40, }; } using namespace clang; +using namespace sema; -/// \brief Compare two APSInts, extending and switching the sign as +/// Compare two APSInts, extending and switching the sign as /// necessary to compare their values regardless of underlying type. static bool hasSameExtendedValue(llvm::APSInt X, llvm::APSInt Y) { if (Y.getBitWidth() > X.getBitWidth()) @@ -125,14 +168,14 @@ 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 +/// 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. static NonTypeTemplateParmDecl * getDeducedParameterFromExpr(TemplateDeductionInfo &Info, Expr *E) { // If we are within an alias template, the expression may have undergone // any number of parameter substitutions already. - while (1) { + while (true) { if (ImplicitCastExpr *IC = dyn_cast<ImplicitCastExpr>(E)) E = IC->getSubExpr(); else if (SubstNonTypeTemplateParmExpr *Subst = @@ -150,7 +193,7 @@ getDeducedParameterFromExpr(TemplateDeductionInfo &Info, Expr *E) { return nullptr; } -/// \brief Determine whether two declaration pointers refer to the same +/// Determine whether two declaration pointers refer to the same /// declaration. static bool isSameDeclaration(Decl *X, Decl *Y) { if (NamedDecl *NX = dyn_cast<NamedDecl>(X)) @@ -161,7 +204,7 @@ static bool isSameDeclaration(Decl *X, Decl *Y) { return X->getCanonicalDecl() == Y->getCanonicalDecl(); } -/// \brief Verify that the given, deduced template arguments are compatible. +/// Verify that the given, deduced template arguments are compatible. /// /// \returns The deduced template argument, or a NULL template argument if /// the deduced template arguments were incompatible. @@ -270,7 +313,7 @@ checkDeducedTemplateArguments(ASTContext &Context, return Y; } - // If we deduced two declarations, make sure they they refer to the + // If we deduced two declarations, make sure that they refer to the // same declaration. if (Y.getKind() == TemplateArgument::Declaration && isSameDeclaration(X.getAsDecl(), Y.getAsDecl())) @@ -297,7 +340,7 @@ checkDeducedTemplateArguments(ASTContext &Context, // All other combinations are incompatible. return DeducedTemplateArgument(); - case TemplateArgument::Pack: + case TemplateArgument::Pack: { if (Y.getKind() != TemplateArgument::Pack || X.pack_size() != Y.pack_size()) return DeducedTemplateArgument(); @@ -319,11 +362,12 @@ checkDeducedTemplateArguments(ASTContext &Context, TemplateArgument::CreatePackCopy(Context, NewPack), X.wasDeducedFromArrayBound() && Y.wasDeducedFromArrayBound()); } + } llvm_unreachable("Invalid TemplateArgument Kind!"); } -/// \brief Deduce the value of the given non-type template parameter +/// Deduce the value of the given non-type template parameter /// as the given deduced template argument. All non-type template parameter /// deduction is funneled through here. static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument( @@ -371,7 +415,7 @@ static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument( /*ArrayBound=*/NewDeduced.wasDeducedFromArrayBound()); } -/// \brief Deduce the value of the given non-type template parameter +/// Deduce the value of the given non-type template parameter /// from the given integral constant. static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument( Sema &S, TemplateParameterList *TemplateParams, @@ -385,7 +429,7 @@ static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument( ValueType, Info, Deduced); } -/// \brief Deduce the value of the given non-type template parameter +/// Deduce the value of the given non-type template parameter /// from the given null pointer template argument type. static Sema::TemplateDeductionResult DeduceNullPtrTemplateArgument( Sema &S, TemplateParameterList *TemplateParams, @@ -402,7 +446,7 @@ static Sema::TemplateDeductionResult DeduceNullPtrTemplateArgument( Value->getType(), Info, Deduced); } -/// \brief Deduce the value of the given non-type template parameter +/// Deduce the value of the given non-type template parameter /// from the given type- or value-dependent expression. /// /// \returns true if deduction succeeded, false otherwise. @@ -415,7 +459,7 @@ static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument( Value->getType(), Info, Deduced); } -/// \brief Deduce the value of the given non-type template parameter +/// Deduce the value of the given non-type template parameter /// from the given declaration. /// /// \returns true if deduction succeeded, false otherwise. @@ -475,7 +519,7 @@ DeduceTemplateArguments(Sema &S, return Sema::TDK_NonDeducedMismatch; } -/// \brief Deduce the template arguments by comparing the template parameter +/// Deduce the template arguments by comparing the template parameter /// type (which is a template-id) with the template argument type. /// /// \param S the Sema @@ -502,6 +546,10 @@ DeduceTemplateArguments(Sema &S, SmallVectorImpl<DeducedTemplateArgument> &Deduced) { assert(Arg.isCanonical() && "Argument type must be canonical"); + // Treat an injected-class-name as its underlying template-id. + if (auto *Injected = dyn_cast<InjectedClassNameType>(Arg)) + Arg = Injected->getInjectedSpecializationType(); + // Check whether the template argument is a dependent template-id. if (const TemplateSpecializationType *SpecArg = dyn_cast<TemplateSpecializationType>(Arg)) { @@ -556,7 +604,7 @@ DeduceTemplateArguments(Sema &S, Deduced, /*NumberOfArgumentsMustMatch=*/true); } -/// \brief Determines whether the given type is an opaque type that +/// Determines whether the given type is an opaque type that /// might be more qualified when instantiated. static bool IsPossiblyOpaquelyQualifiedType(QualType T) { switch (T->getTypeClass()) { @@ -580,30 +628,7 @@ static bool IsPossiblyOpaquelyQualifiedType(QualType T) { } } -/// \brief Retrieve the depth and index of a template parameter. -static std::pair<unsigned, unsigned> -getDepthAndIndex(NamedDecl *ND) { - if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ND)) - return std::make_pair(TTP->getDepth(), TTP->getIndex()); - - if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(ND)) - return std::make_pair(NTTP->getDepth(), NTTP->getIndex()); - - TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(ND); - return std::make_pair(TTP->getDepth(), TTP->getIndex()); -} - -/// \brief Retrieve the depth and index of an unexpanded parameter pack. -static std::pair<unsigned, unsigned> -getDepthAndIndex(UnexpandedParameterPack UPP) { - if (const TemplateTypeParmType *TTP - = UPP.first.dyn_cast<const TemplateTypeParmType *>()) - return std::make_pair(TTP->getDepth(), TTP->getIndex()); - - return getDepthAndIndex(UPP.first.get<NamedDecl *>()); -} - -/// \brief Helper function to build a TemplateParameter when we don't +/// Helper function to build a TemplateParameter when we don't /// know its type statically. static TemplateParameter makeTemplateParameter(Decl *D) { if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(D)) @@ -614,10 +639,21 @@ static TemplateParameter makeTemplateParameter(Decl *D) { return TemplateParameter(cast<TemplateTemplateParmDecl>(D)); } +/// If \p Param is an expanded parameter pack, get the number of expansions. +static Optional<unsigned> getExpandedPackSize(NamedDecl *Param) { + if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) + if (NTTP->isExpandedParameterPack()) + return NTTP->getNumExpansionTypes(); + + if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) + if (TTP->isExpandedParameterPack()) + return TTP->getNumExpansionTemplateParameters(); + + return None; +} + /// A pack that we're currently deducing. struct clang::DeducedPack { - DeducedPack(unsigned Index) : Index(Index), Outer(nullptr) {} - // The index of the pack. unsigned Index; @@ -632,17 +668,93 @@ struct clang::DeducedPack { SmallVector<DeducedTemplateArgument, 4> New; // The outer deduction for this pack, if any. - DeducedPack *Outer; + DeducedPack *Outer = nullptr; + + DeducedPack(unsigned Index) : Index(Index) {} }; namespace { + /// A scope in which we're performing pack deduction. class PackDeductionScope { public: + /// Prepare to deduce the packs named within Pattern. PackDeductionScope(Sema &S, TemplateParameterList *TemplateParams, SmallVectorImpl<DeducedTemplateArgument> &Deduced, TemplateDeductionInfo &Info, TemplateArgument Pattern) : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info) { + unsigned NumNamedPacks = addPacks(Pattern); + finishConstruction(NumNamedPacks); + } + + /// Prepare to directly deduce arguments of the parameter with index \p Index. + PackDeductionScope(Sema &S, TemplateParameterList *TemplateParams, + SmallVectorImpl<DeducedTemplateArgument> &Deduced, + TemplateDeductionInfo &Info, unsigned Index) + : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info) { + addPack(Index); + finishConstruction(1); + } + +private: + void addPack(unsigned Index) { + // 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(); + + // FIXME: What if we encounter multiple packs with different numbers of + // pre-expanded expansions? (This should already have been diagnosed + // during substitution.) + if (Optional<unsigned> ExpandedPackExpansions = + getExpandedPackSize(TemplateParams->getParam(Index))) + FixedNumExpansions = ExpandedPackExpansions; + + Packs.push_back(Pack); + } + + unsigned addPacks(TemplateArgument Pattern) { + // 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; + addPack(Index); + }; + + // 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()) + AddPack(Index); + } + assert(!Packs.empty() && "Pack expansion without unexpanded packs?"); + + unsigned NumNamedPacks = Packs.size(); + + // 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); + + return NumNamedPacks; + } + + void finishConstruction(unsigned NumNamedPacks) { // Dig out the partially-substituted pack, if there is one. const TemplateArgument *PartialPackArgs = nullptr; unsigned NumPartialPackArgs = 0; @@ -652,60 +764,29 @@ public: &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()) - AddPack(Index); + // This pack expansion will have been partially or fully expanded if + // it only names explicitly-specified parameter packs (including the + // partially-substituted one, if any). + bool IsExpanded = true; + for (unsigned I = 0; I != NumNamedPacks; ++I) { + if (Packs[I].Index >= Info.getNumExplicitArgs()) { + IsExpanded = false; + IsPartiallyExpanded = false; + break; + } + if (PartialPackDepthIndex == + std::make_pair(Info.getDeducedDepth(), Packs[I].Index)) { + IsPartiallyExpanded = true; } - 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); } + // Skip over the pack elements that were expanded into separate arguments. + // If we partially expanded, this is the number of partial arguments. + if (IsPartiallyExpanded) + PackElements += NumPartialPackArgs; + else if (IsExpanded) + PackElements += *FixedNumExpansions; + for (auto &Pack : Packs) { if (Info.PendingDeducedPacks.size() > Pack.Index) Pack.Outer = Info.PendingDeducedPacks[Pack.Index]; @@ -724,12 +805,13 @@ public: // 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) + if (!IsPartiallyExpanded) Deduced[Pack.Index] = Pack.New[PackElements]; } } } +public: ~PackDeductionScope() { for (auto &Pack : Packs) Info.PendingDeducedPacks[Pack.Index] = Pack.Outer; @@ -739,6 +821,18 @@ public: /// sequence of (prior) function parameters / template arguments. bool isPartiallyExpanded() { return IsPartiallyExpanded; } + /// Determine whether this pack expansion scope has a known, fixed arity. + /// This happens if it involves a pack from an outer template that has + /// (notionally) already been expanded. + bool hasFixedArity() { return FixedNumExpansions.hasValue(); } + + /// Determine whether the next element of the argument is still part of this + /// pack. This is the case unless the pack is already expanded to a fixed + /// length. + bool hasNextElement() { + return !FixedNumExpansions || *FixedNumExpansions > PackElements; + } + /// Move to deducing the next element in each pack that is being deduced. void nextPackElement() { // Capture the deduced template arguments for each parameter pack expanded @@ -761,16 +855,24 @@ public: ++PackElements; } - /// \brief Finish template argument deduction for a set of argument packs, + /// Finish template argument deduction for a set of argument packs, /// producing the argument packs and checking for consistency with prior /// deductions. - Sema::TemplateDeductionResult finish() { + Sema::TemplateDeductionResult + finish(bool TreatNoDeductionsAsNonDeduced = true) { // Build argument packs for each of the parameter packs expanded by this // pack expansion. for (auto &Pack : Packs) { // Put back the old value for this pack. Deduced[Pack.Index] = Pack.Saved; + // If we are deducing the size of this pack even if we didn't deduce any + // values for it, then make sure we build a pack of the right size. + // FIXME: Should we always deduce the size, even if the pack appears in + // a non-deduced context? + if (!TreatNoDeductionsAsNonDeduced) + Pack.New.resize(PackElements); + // Build or find a new value for this pack. DeducedTemplateArgument NewPack; if (PackElements && Pack.New.empty()) { @@ -826,14 +928,24 @@ public: Result = checkDeducedTemplateArguments(S.Context, OldPack, NewPack); } + NamedDecl *Param = TemplateParams->getParam(Pack.Index); if (Result.isNull()) { - Info.Param = - makeTemplateParameter(TemplateParams->getParam(Pack.Index)); + Info.Param = makeTemplateParameter(Param); Info.FirstArg = OldPack; Info.SecondArg = NewPack; return Sema::TDK_Inconsistent; } + // If we have a pre-expanded pack and we didn't deduce enough elements + // for it, fail deduction. + if (Optional<unsigned> Expansions = getExpandedPackSize(Param)) { + if (*Expansions != PackElements) { + Info.Param = makeTemplateParameter(Param); + Info.FirstArg = Result; + return Sema::TDK_IncompletePack; + } + } + *Loc = Result; } @@ -847,12 +959,15 @@ private: TemplateDeductionInfo &Info; unsigned PackElements = 0; bool IsPartiallyExpanded = false; + /// The number of expansions, if we have a fully-expanded pack in this scope. + Optional<unsigned> FixedNumExpansions; SmallVector<DeducedPack, 2> Packs; }; + } // namespace -/// \brief Deduce the template arguments by comparing the list of parameter +/// Deduce the template arguments by comparing the list of parameter /// types to the list of argument types, as in the parameter-type-lists of /// function types (C++ [temp.deduct.type]p10). /// @@ -891,12 +1006,6 @@ DeduceTemplateArguments(Sema &S, SmallVectorImpl<DeducedTemplateArgument> &Deduced, unsigned TDF, bool PartialOrdering = false) { - // Fast-path check to see if we have too many/too few arguments. - if (NumParams != NumArgs && - !(NumParams && isa<PackExpansionType>(Params[NumParams - 1])) && - !(NumArgs && isa<PackExpansionType>(Args[NumArgs - 1]))) - return Sema::TDK_MiscellaneousDeductionFailure; - // C++0x [temp.deduct.type]p10: // Similarly, if P has a form that contains (T), then each parameter type // Pi of the respective parameter-type- list of P is compared with the @@ -933,13 +1042,6 @@ DeduceTemplateArguments(Sema &S, continue; } - // C++0x [temp.deduct.type]p5: - // The non-deduced contexts are: - // - A function parameter pack that does not occur at the end of the - // parameter-declaration-clause. - if (ParamIdx + 1 < NumParams) - return Sema::TDK_Success; - // C++0x [temp.deduct.type]p10: // If the parameter-declaration corresponding to Pi is a function // parameter pack, then the type of its declarator- id is compared with @@ -950,15 +1052,43 @@ DeduceTemplateArguments(Sema &S, QualType Pattern = Expansion->getPattern(); PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern); - for (; ArgIdx < NumArgs; ++ArgIdx) { - // Deduce template arguments from the pattern. - if (Sema::TemplateDeductionResult Result - = DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, Pattern, - Args[ArgIdx], Info, Deduced, - TDF, PartialOrdering)) - return Result; + // A pack scope with fixed arity is not really a pack any more, so is not + // a non-deduced context. + if (ParamIdx + 1 == NumParams || PackScope.hasFixedArity()) { + for (; ArgIdx < NumArgs && PackScope.hasNextElement(); ++ArgIdx) { + // Deduce template arguments from the pattern. + if (Sema::TemplateDeductionResult Result + = DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, Pattern, + Args[ArgIdx], Info, Deduced, + TDF, PartialOrdering)) + return Result; - PackScope.nextPackElement(); + PackScope.nextPackElement(); + } + } else { + // C++0x [temp.deduct.type]p5: + // The non-deduced contexts are: + // - A function parameter pack that does not occur at the end of the + // parameter-declaration-clause. + // + // FIXME: There is no wording to say what we should do in this case. We + // choose to resolve this by applying the same rule that is applied for a + // function call: that is, deduce all contained packs to their + // explicitly-specified values (or to <> if there is no such value). + // + // This is seemingly-arbitrarily different from the case of a template-id + // with a non-trailing pack-expansion in its arguments, which renders the + // entire template-argument-list a non-deduced context. + + // If the parameter type contains an explicitly-specified pack that we + // could not expand, skip the number of parameters notionally created + // by the expansion. + Optional<unsigned> NumExpansions = Expansion->getNumExpansions(); + if (NumExpansions && !PackScope.isPartiallyExpanded()) { + for (unsigned I = 0; I != *NumExpansions && ArgIdx < NumArgs; + ++I, ++ArgIdx) + PackScope.nextPackElement(); + } } // Build argument packs for each of the parameter packs expanded by this @@ -974,8 +1104,10 @@ DeduceTemplateArguments(Sema &S, return Sema::TDK_Success; } -/// \brief Determine whether the parameter has qualifiers that are either -/// inconsistent with or a superset of the argument's qualifiers. +/// Determine whether the parameter has qualifiers that the argument +/// lacks. Put another way, determine whether there is no way to add +/// a deduced set of qualifiers to the ParamType that would result in +/// its qualifiers matching those of the ArgType. static bool hasInconsistentOrSupersetQualifiersOf(QualType ParamType, QualType ArgType) { Qualifiers ParamQs = ParamType.getQualifiers(); @@ -999,13 +1131,11 @@ static bool hasInconsistentOrSupersetQualifiersOf(QualType ParamType, ParamQs.hasObjCLifetime()) return true; - // CVR qualifier superset. - return (ParamQs.getCVRQualifiers() != ArgQs.getCVRQualifiers()) && - ((ParamQs.getCVRQualifiers() | ArgQs.getCVRQualifiers()) - == ParamQs.getCVRQualifiers()); + // CVR qualifiers inconsistent or a superset. + return (ParamQs.getCVRQualifiers() & ~ArgQs.getCVRQualifiers()) != 0; } -/// \brief Compare types for equality with respect to possibly compatible +/// Compare types for equality with respect to possibly compatible /// function types (noreturn adjustment, implicit calling conventions). If any /// of parameter and argument is not a function, just perform type comparison. /// @@ -1057,7 +1187,7 @@ static bool isForwardingReference(QualType Param, unsigned FirstInnerIndex) { return false; } -/// \brief Deduce the template arguments by comparing the parameter type and +/// Deduce the template arguments by comparing the parameter type and /// the argument type (C++ [temp.deduct.type]). /// /// \param S the semantic analysis object within which we are deducing @@ -1228,6 +1358,12 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, return Sema::TDK_Underqualified; } + // Do not match a function type with a cv-qualified type. + // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1584 + if (Arg->isFunctionType() && Param.hasQualifiers()) { + return Sema::TDK_NonDeducedMismatch; + } + assert(TemplateTypeParm->getDepth() == Info.getDeducedDepth() && "saw template type parameter with wrong depth"); assert(Arg != S.Context.OverloadTy && "Unresolved overloaded function"); @@ -1303,6 +1439,18 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, if (TDF & TDF_ParamWithReferenceType) { if (hasInconsistentOrSupersetQualifiersOf(Param, Arg)) return Sema::TDK_NonDeducedMismatch; + } else if (TDF & TDF_ArgWithReferenceType) { + // C++ [temp.deduct.conv]p4: + // If the original A is a reference type, A can be more cv-qualified + // than the deduced A + if (!Arg.getQualifiers().compatiblyIncludes(Param.getQualifiers())) + return Sema::TDK_NonDeducedMismatch; + + // Strip out all extra qualifiers from the argument to figure out the + // type we're converting to, prior to the qualification conversion. + Qualifiers Quals; + Arg = S.Context.getUnqualifiedArrayType(Arg, Quals); + Arg = S.Context.getQualifiedType(Arg, Param.getQualifiers()); } else if (!IsPossiblyOpaquelyQualifiedType(Param)) { if (Param.getCVRQualifiers() != Arg.getCVRQualifiers()) return Sema::TDK_NonDeducedMismatch; @@ -1353,7 +1501,7 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, case Type::Enum: case Type::ObjCObject: case Type::ObjCInterface: - case Type::ObjCObjectPointer: { + case Type::ObjCObjectPointer: if (TDF & TDF_SkipNonDependent) return Sema::TDK_Success; @@ -1363,7 +1511,6 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, } return Param == Arg? Sema::TDK_Success : Sema::TDK_NonDeducedMismatch; - } // _Complex T [placeholder extension] case Type::Complex: @@ -1557,7 +1704,7 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, "saw non-type template parameter with wrong depth"); llvm::APSInt Noexcept(1); - switch (FunctionProtoArg->canThrow(S.Context)) { + switch (FunctionProtoArg->canThrow()) { case CT_Cannot: Noexcept = 1; LLVM_FALLTHROUGH; @@ -1578,11 +1725,14 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, } } // FIXME: Detect non-deduced exception specification mismatches? + // + // Careful about [temp.deduct.call] and [temp.deduct.conv], which allow + // top-level differences in noexcept-specifications. return Sema::TDK_Success; } - case Type::InjectedClassName: { + case Type::InjectedClassName: // Treat a template's injected-class-name as if the template // specialization type had been used. Param = cast<InjectedClassNameType>(Param) @@ -1590,7 +1740,6 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, assert(isa<TemplateSpecializationType>(Param) && "injected class name is not a template specialization type"); LLVM_FALLTHROUGH; - } // template-name<T> (where template-name refers to a class template) // template-name<i> @@ -1788,6 +1937,54 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, return Sema::TDK_NonDeducedMismatch; } + case Type::DependentVector: { + const auto *VectorParam = cast<DependentVectorType>(Param); + + if (const auto *VectorArg = dyn_cast<VectorType>(Arg)) { + // Perform deduction on the element types. + if (Sema::TemplateDeductionResult Result = + DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, VectorParam->getElementType(), + VectorArg->getElementType(), Info, Deduced, TDF)) + return Result; + + // Perform deduction on the vector size, if we can. + NonTypeTemplateParmDecl *NTTP = + getDeducedParameterFromExpr(Info, VectorParam->getSizeExpr()); + if (!NTTP) + return Sema::TDK_Success; + + llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false); + ArgSize = VectorArg->getNumElements(); + // Note that we use the "array bound" rules here; just like in that + // case, we don't have any particular type for the vector size, but + // we can provide one if necessary. + return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, ArgSize, + S.Context.UnsignedIntTy, true, + Info, Deduced); + } + + if (const auto *VectorArg = dyn_cast<DependentVectorType>(Arg)) { + // Perform deduction on the element types. + if (Sema::TemplateDeductionResult Result = + DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, VectorParam->getElementType(), + VectorArg->getElementType(), Info, Deduced, TDF)) + return Result; + + // Perform deduction on the vector size, if we can. + NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr( + Info, VectorParam->getSizeExpr()); + if (!NTTP) + return Sema::TDK_Success; + + return DeduceNonTypeTemplateArgument( + S, TemplateParams, NTTP, VectorArg->getSizeExpr(), Info, Deduced); + } + + return Sema::TDK_NonDeducedMismatch; + } + // (clang extension) // // T __attribute__(((ext_vector_type(N)))) @@ -1992,7 +2189,7 @@ DeduceTemplateArguments(Sema &S, Info.SecondArg = Arg; return Sema::TDK_NonDeducedMismatch; - case TemplateArgument::Expression: { + case TemplateArgument::Expression: if (NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr(Info, Param.getAsExpr())) { if (Arg.getKind() == TemplateArgument::Integral) @@ -2021,7 +2218,7 @@ DeduceTemplateArguments(Sema &S, // Can't deduce anything, but that's okay. return Sema::TDK_Success; - } + case TemplateArgument::Pack: llvm_unreachable("Argument packs should be expanded by the caller!"); } @@ -2029,7 +2226,7 @@ DeduceTemplateArguments(Sema &S, llvm_unreachable("Invalid TemplateArgument Kind!"); } -/// \brief Determine whether there is a template argument to be used for +/// Determine whether there is a template argument to be used for /// deduction. /// /// This routine "expands" argument packs in-place, overriding its input @@ -2052,7 +2249,7 @@ static bool hasTemplateArgumentForDeduction(ArrayRef<TemplateArgument> &Args, return ArgIdx < Args.size(); } -/// \brief Determine whether the given set of template arguments has a pack +/// Determine whether the given set of template arguments has a pack /// expansion that is not the last template argument. static bool hasPackExpansionBeforeEnd(ArrayRef<TemplateArgument> Args) { bool FoundPackExpansion = false; @@ -2063,6 +2260,8 @@ static bool hasPackExpansionBeforeEnd(ArrayRef<TemplateArgument> Args) { if (A.getKind() == TemplateArgument::Pack) return hasPackExpansionBeforeEnd(A.pack_elements()); + // FIXME: If this is a fixed-arity pack expansion from an outer level of + // templates, it should not be treated as a pack expansion. if (A.isPackExpansion()) FoundPackExpansion = true; } @@ -2126,17 +2325,15 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, // template parameter packs expanded by Pi. TemplateArgument Pattern = Params[ParamIdx].getPackExpansionPattern(); - // FIXME: If there are no remaining arguments, we can bail out early - // and set any deduced parameter packs to an empty argument pack. - // The latter part of this is a (minor) correctness issue. - // Prepare to deduce the packs within the pattern. PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern); // Keep track of the deduced template arguments for each parameter pack // expanded by this pack expansion (the outer index) and for each // template argument (the inner SmallVectors). - for (; hasTemplateArgumentForDeduction(Args, ArgIdx); ++ArgIdx) { + for (; hasTemplateArgumentForDeduction(Args, ArgIdx) && + PackScope.hasNextElement(); + ++ArgIdx) { // Deduce template arguments from the pattern. if (Sema::TemplateDeductionResult Result = DeduceTemplateArguments(S, TemplateParams, Pattern, Args[ArgIdx], @@ -2167,7 +2364,7 @@ DeduceTemplateArguments(Sema &S, /*NumberOfArgumentsMustMatch*/false); } -/// \brief Determine whether two template arguments are the same. +/// Determine whether two template arguments are the same. static bool isSameTemplateArg(ASTContext &Context, TemplateArgument X, const TemplateArgument &Y, @@ -2228,7 +2425,7 @@ static bool isSameTemplateArg(ASTContext &Context, llvm_unreachable("Invalid TemplateArgument Kind!"); } -/// \brief Allocate a TemplateArgumentLoc where all locations have +/// Allocate a TemplateArgumentLoc where all locations have /// been initialized to the given location. /// /// \param Arg The template argument we are producing template argument @@ -2303,8 +2500,7 @@ Sema::getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, llvm_unreachable("Invalid TemplateArgument Kind!"); } - -/// \brief Convert the given deduced template argument and add it to the set of +/// Convert the given deduced template argument and add it to the set of /// fully-converted template arguments. static bool ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param, @@ -2409,6 +2605,16 @@ static Sema::TemplateDeductionResult ConvertDeducedTemplateArguments( for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) { NamedDecl *Param = TemplateParams->getParam(I); + // C++0x [temp.arg.explicit]p3: + // A trailing template parameter pack (14.5.3) not otherwise deduced will + // be deduced to an empty sequence of template arguments. + // FIXME: Where did the word "trailing" come from? + if (Deduced[I].isNull() && Param->isTemplateParameterPack()) { + if (auto Result = PackDeductionScope(S, TemplateParams, Deduced, Info, I) + .finish(/*TreatNoDeductionsAsNonDeduced*/false)) + return Result; + } + if (!Deduced[I].isNull()) { if (I < NumAlreadyConverted) { // We may have had explicitly-specified template arguments for a @@ -2443,40 +2649,6 @@ static Sema::TemplateDeductionResult ConvertDeducedTemplateArguments( continue; } - // C++0x [temp.arg.explicit]p3: - // A trailing template parameter pack (14.5.3) not otherwise deduced will - // be deduced to an empty sequence of template arguments. - // FIXME: Where did the word "trailing" come from? - if (Param->isTemplateParameterPack()) { - // We may have had explicitly-specified template arguments for this - // template parameter pack. If so, our empty deduction extends the - // explicitly-specified set (C++0x [temp.arg.explicit]p9). - const TemplateArgument *ExplicitArgs; - unsigned NumExplicitArgs; - if (CurrentInstantiationScope && - CurrentInstantiationScope->getPartiallySubstitutedPack( - &ExplicitArgs, &NumExplicitArgs) == Param) { - Builder.push_back(TemplateArgument( - llvm::makeArrayRef(ExplicitArgs, NumExplicitArgs))); - - // Forget the partially-substituted pack; its substitution is now - // complete. - CurrentInstantiationScope->ResetPartiallySubstitutedPack(); - } else { - // Go through the motions of checking the empty argument pack against - // the parameter pack. - DeducedTemplateArgument DeducedPack(TemplateArgument::getEmptyPack()); - if (ConvertDeducedTemplateArgument(S, Param, DeducedPack, Template, - Info, IsDeduced, Builder)) { - Info.Param = makeTemplateParameter(Param); - // FIXME: These template arguments are temporary. Free them! - Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder)); - return Sema::TDK_SubstitutionFailure; - } - } - continue; - } - // Substitute into the default template argument, if available. bool HasDefaultArg = false; TemplateDecl *TD = dyn_cast<TemplateDecl>(Template); @@ -2659,7 +2831,7 @@ static Sema::TemplateDeductionResult FinishTemplateArgumentDeduction( } -/// \brief Perform template argument deduction to determine whether +/// Perform template argument deduction to determine whether /// the given template arguments match the given class template /// partial specialization per C++ [temp.class.spec.match]. Sema::TemplateDeductionResult @@ -2702,7 +2874,7 @@ Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, *this, Partial, /*PartialOrdering=*/false, TemplateArgs, Deduced, Info); } -/// \brief Perform template argument deduction to determine whether +/// Perform template argument deduction to determine whether /// the given template arguments match the given variable template /// partial specialization per C++ [temp.class.spec.match]. Sema::TemplateDeductionResult @@ -2743,7 +2915,7 @@ Sema::DeduceTemplateArguments(VarTemplatePartialSpecializationDecl *Partial, *this, Partial, /*PartialOrdering=*/false, TemplateArgs, Deduced, Info); } -/// \brief Determine whether the given type T is a simple-template-id type. +/// Determine whether the given type T is a simple-template-id type. static bool isSimpleTemplateIdType(QualType T) { if (const TemplateSpecializationType *Spec = T->getAs<TemplateSpecializationType>()) @@ -2763,7 +2935,7 @@ static bool isSimpleTemplateIdType(QualType T) { return false; } -/// \brief Substitute the explicitly-provided template arguments into the +/// Substitute the explicitly-provided template arguments into the /// given function template according to C++ [temp.arg.explicit]. /// /// \param FunctionTemplate the function template into which the explicit @@ -2837,7 +3009,7 @@ Sema::SubstituteExplicitTemplateArguments( Trap.hasErrorOccurred()) { unsigned Index = Builder.size(); if (Index >= TemplateParams->size()) - Index = TemplateParams->size() - 1; + return TDK_SubstitutionFailure; Info.Param = makeTemplateParameter(TemplateParams->getParam(Index)); return TDK_InvalidExplicitArguments; } @@ -2846,7 +3018,7 @@ Sema::SubstituteExplicitTemplateArguments( // template arguments. TemplateArgumentList *ExplicitArgumentList = TemplateArgumentList::CreateCopy(Context, Builder); - Info.reset(ExplicitArgumentList); + Info.setExplicitArgs(ExplicitArgumentList); // Template argument deduction and the final substitution should be // done in the context of the templated declaration. Explicit @@ -2858,14 +3030,19 @@ Sema::SubstituteExplicitTemplateArguments( // note that the template argument pack is partially substituted and record // the explicit template arguments. They'll be used as part of deduction // for this template parameter pack. - for (unsigned I = 0, N = Builder.size(); I != N; ++I) { - const TemplateArgument &Arg = Builder[I]; + unsigned PartiallySubstitutedPackIndex = -1u; + if (!Builder.empty()) { + const TemplateArgument &Arg = Builder.back(); if (Arg.getKind() == TemplateArgument::Pack) { - CurrentInstantiationScope->SetPartiallySubstitutedPack( - TemplateParams->getParam(I), - Arg.pack_begin(), - Arg.pack_size()); - break; + auto *Param = TemplateParams->getParam(Builder.size() - 1); + // If this is a fully-saturated fixed-size pack, it should be + // fully-substituted, not partially-substituted. + Optional<unsigned> Expansions = getExpandedPackSize(Param); + if (!Expansions || Arg.pack_size() < *Expansions) { + PartiallySubstitutedPackIndex = Builder.size() - 1; + CurrentInstantiationScope->SetPartiallySubstitutedPack( + Param, Arg.pack_begin(), Arg.pack_size()); + } } } @@ -2955,13 +3132,13 @@ Sema::SubstituteExplicitTemplateArguments( // case, the empty template argument list <> itself may also be omitted. // // Take all of the explicitly-specified arguments and put them into - // the set of deduced template arguments. Explicitly-specified - // parameter packs, however, will be set to NULL since the deduction - // mechanisms handle explicitly-specified argument packs directly. + // the set of deduced template arguments. The partially-substituted + // parameter pack, however, will be set to NULL since the deduction + // mechanism handles the partially-substituted argument pack directly. Deduced.reserve(TemplateParams->size()); for (unsigned I = 0, N = ExplicitArgumentList->size(); I != N; ++I) { const TemplateArgument &Arg = ExplicitArgumentList->get(I); - if (Arg.getKind() == TemplateArgument::Pack) + if (I == PartiallySubstitutedPackIndex) Deduced.push_back(DeducedTemplateArgument()); else Deduced.push_back(Arg); @@ -2970,7 +3147,7 @@ Sema::SubstituteExplicitTemplateArguments( return TDK_Success; } -/// \brief Check whether the deduced argument type for a call to a function +/// Check whether the deduced argument type for a call to a function /// template matches the actual argument type per C++ [temp.deduct.call]p4. static Sema::TemplateDeductionResult CheckOriginalCallArgDeduction(Sema &S, TemplateDeductionInfo &Info, @@ -3080,7 +3257,7 @@ CheckOriginalCallArgDeduction(Sema &S, TemplateDeductionInfo &Info, return Sema::TDK_Success; if (A->isRecordType() && isSimpleTemplateIdType(OriginalParamType) && - S.IsDerivedFrom(SourceLocation(), A, DeducedA)) + S.IsDerivedFrom(Info.getLocation(), A, DeducedA)) return Sema::TDK_Success; return Failed(); @@ -3116,7 +3293,7 @@ static unsigned getPackIndexForParam(Sema &S, llvm_unreachable("parameter index would not be produced from template"); } -/// \brief Finish template argument deduction for a function template, +/// Finish template argument deduction for a function template, /// checking the deduced template arguments for completeness and forming /// the function template specialization. /// @@ -3267,13 +3444,14 @@ static QualType GetTypeOfFunction(Sema &S, const OverloadExpr::FindResult &R, // We may need to deduce the return type of the function now. if (S.getLangOpts().CPlusPlus14 && Fn->getReturnType()->isUndeducedType() && S.DeduceReturnType(Fn, R.Expression->getExprLoc(), /*Diagnose*/ false)) - return QualType(); + return {}; if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn)) if (Method->isInstance()) { // An instance method that's referenced in a form that doesn't // look like a member pointer is just invalid. - if (!R.HasFormOfMemberPointer) return QualType(); + if (!R.HasFormOfMemberPointer) + return {}; return S.Context.getMemberPointerType(Fn->getType(), S.Context.getTypeDeclType(Method->getParent()).getTypePtr()); @@ -3322,7 +3500,7 @@ ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams, S.resolveAddressOfOnlyViableOverloadCandidate(Arg, DAP)) return GetTypeOfFunction(S, R, Viable); - return QualType(); + return {}; } // Gather the explicit template arguments, if any. @@ -3339,7 +3517,7 @@ ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams, // function templates, the parameter is treated as a // non-deduced context. if (!Ovl->hasExplicitTemplateArgs()) - return QualType(); + return {}; // Otherwise, see if we can resolve a function type FunctionDecl *Specialization = nullptr; @@ -3379,14 +3557,15 @@ ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams, = DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, ParamType, ArgType, Info, Deduced, TDF); if (Result) continue; - if (!Match.isNull()) return QualType(); + if (!Match.isNull()) + return {}; Match = ArgType; } return Match; } -/// \brief Perform the adjustments to the parameter and argument types +/// Perform the adjustments to the parameter and argument types /// described in C++ [temp.deduct.call]. /// /// \returns true if the caller should not attempt to perform any template @@ -3493,7 +3672,7 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsFromCallArgument( SmallVectorImpl<Sema::OriginalCallArg> &OriginalCallArgs, bool DecomposedParam, unsigned ArgIdx, unsigned TDF); -/// \brief Attempt template argument deduction from an initializer list +/// Attempt template argument deduction from an initializer list /// deemed to be an argument in a function call. static Sema::TemplateDeductionResult DeduceFromInitializerList( Sema &S, TemplateParameterList *TemplateParams, QualType AdjustedParamType, @@ -3554,7 +3733,7 @@ static Sema::TemplateDeductionResult DeduceFromInitializerList( return Sema::TDK_Success; } -/// \brief Perform template argument deduction per [temp.deduct.call] for a +/// Perform template argument deduction per [temp.deduct.call] for a /// single parameter / argument pair. static Sema::TemplateDeductionResult DeduceTemplateArgumentsFromCallArgument( Sema &S, TemplateParameterList *TemplateParams, unsigned FirstInnerIndex, @@ -3587,7 +3766,7 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsFromCallArgument( ArgType, Info, Deduced, TDF); } -/// \brief Perform template argument deduction from a function call +/// Perform template argument deduction from a function call /// (C++ [temp.deduct.call]). /// /// \param FunctionTemplate the function template for which we are performing @@ -3725,8 +3904,9 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( // the length of the explicitly-specified pack if it's expanded by the // parameter pack and 0 otherwise, and we treat each deduction as a // non-deduced context. - if (ParamIdx + 1 == NumParamTypes) { - for (; ArgIdx < Args.size(); PackScope.nextPackElement(), ++ArgIdx) { + if (ParamIdx + 1 == NumParamTypes || PackScope.hasFixedArity()) { + for (; ArgIdx < Args.size() && PackScope.hasNextElement(); + PackScope.nextPackElement(), ++ArgIdx) { ParamTypesForArgChecking.push_back(ParamPattern); if (auto Result = DeduceCallArgument(ParamPattern, ArgIdx)) return Result; @@ -3753,10 +3933,16 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( return Result; } + // Capture the context in which the function call is made. This is the context + // that is needed when the accessibility of template arguments is checked. + DeclContext *CallingCtx = CurContext; + return FinishTemplateArgumentDeduction( FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info, - &OriginalCallArgs, PartialOverloading, - [&]() { return CheckNonDependent(ParamTypesForArgChecking); }); + &OriginalCallArgs, PartialOverloading, [&, CallingCtx]() { + ContextRAII SavedContext(*this, CallingCtx); + return CheckNonDependent(ParamTypesForArgChecking); + }); } QualType Sema::adjustCCAndNoReturn(QualType ArgFunctionType, @@ -3798,7 +3984,7 @@ QualType Sema::adjustCCAndNoReturn(QualType ArgFunctionType, ArgFunctionTypeP->getParamTypes(), EPI); } -/// \brief Deduce template arguments when taking the address of a function +/// Deduce template arguments when taking the address of a function /// template (C++ [temp.deduct.funcaddr]) or matching a specialization to /// a template. /// @@ -3940,118 +4126,7 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( return TDK_Success; } -/// \brief Given a function declaration (e.g. a generic lambda conversion -/// function) that contains an 'auto' in its result type, substitute it -/// with TypeToReplaceAutoWith. Be careful to pass in the type you want -/// to replace 'auto' with and not the actual result type you want -/// to set the function to. -static inline void -SubstAutoWithinFunctionReturnType(FunctionDecl *F, - QualType TypeToReplaceAutoWith, Sema &S) { - assert(!TypeToReplaceAutoWith->getContainedAutoType()); - QualType AutoResultType = F->getReturnType(); - assert(AutoResultType->getContainedAutoType()); - QualType DeducedResultType = S.SubstAutoType(AutoResultType, - TypeToReplaceAutoWith); - S.Context.adjustDeducedFunctionResultType(F, DeducedResultType); -} - -/// \brief Given a specialized conversion operator of a generic lambda -/// create the corresponding specializations of the call operator and -/// the static-invoker. If the return type of the call operator is auto, -/// deduce its return type and check if that matches the -/// return type of the destination function ptr. - -static inline Sema::TemplateDeductionResult -SpecializeCorrespondingLambdaCallOperatorAndInvoker( - CXXConversionDecl *ConversionSpecialized, - SmallVectorImpl<DeducedTemplateArgument> &DeducedArguments, - QualType ReturnTypeOfDestFunctionPtr, - TemplateDeductionInfo &TDInfo, - Sema &S) { - - CXXRecordDecl *LambdaClass = ConversionSpecialized->getParent(); - assert(LambdaClass && LambdaClass->isGenericLambda()); - - CXXMethodDecl *CallOpGeneric = LambdaClass->getLambdaCallOperator(); - QualType CallOpResultType = CallOpGeneric->getReturnType(); - const bool GenericLambdaCallOperatorHasDeducedReturnType = - CallOpResultType->getContainedAutoType(); - - FunctionTemplateDecl *CallOpTemplate = - CallOpGeneric->getDescribedFunctionTemplate(); - - FunctionDecl *CallOpSpecialized = nullptr; - // Use the deduced arguments of the conversion function, to specialize our - // generic lambda's call operator. - if (Sema::TemplateDeductionResult Result - = S.FinishTemplateArgumentDeduction(CallOpTemplate, - DeducedArguments, - 0, CallOpSpecialized, TDInfo)) - return Result; - - // If we need to deduce the return type, do so (instantiates the callop). - if (GenericLambdaCallOperatorHasDeducedReturnType && - CallOpSpecialized->getReturnType()->isUndeducedType()) - S.DeduceReturnType(CallOpSpecialized, - CallOpSpecialized->getPointOfInstantiation(), - /*Diagnose*/ true); - - // Check to see if the return type of the destination ptr-to-function - // matches the return type of the call operator. - if (!S.Context.hasSameType(CallOpSpecialized->getReturnType(), - ReturnTypeOfDestFunctionPtr)) - return Sema::TDK_NonDeducedMismatch; - // Since we have succeeded in matching the source and destination - // ptr-to-functions (now including return type), and have successfully - // specialized our corresponding call operator, we are ready to - // specialize the static invoker with the deduced arguments of our - // ptr-to-function. - FunctionDecl *InvokerSpecialized = nullptr; - FunctionTemplateDecl *InvokerTemplate = LambdaClass-> - getLambdaStaticInvoker()->getDescribedFunctionTemplate(); - -#ifndef NDEBUG - Sema::TemplateDeductionResult LLVM_ATTRIBUTE_UNUSED Result = -#endif - S.FinishTemplateArgumentDeduction(InvokerTemplate, DeducedArguments, 0, - InvokerSpecialized, TDInfo); - assert(Result == Sema::TDK_Success && - "If the call operator succeeded so should the invoker!"); - // Set the result type to match the corresponding call operator - // specialization's result type. - if (GenericLambdaCallOperatorHasDeducedReturnType && - InvokerSpecialized->getReturnType()->isUndeducedType()) { - // Be sure to get the type to replace 'auto' with and not - // the full result type of the call op specialization - // to substitute into the 'auto' of the invoker and conversion - // function. - // For e.g. - // int* (*fp)(int*) = [](auto* a) -> auto* { return a; }; - // We don't want to subst 'int*' into 'auto' to get int**. - - QualType TypeToReplaceAutoWith = CallOpSpecialized->getReturnType() - ->getContainedAutoType() - ->getDeducedType(); - SubstAutoWithinFunctionReturnType(InvokerSpecialized, - TypeToReplaceAutoWith, S); - SubstAutoWithinFunctionReturnType(ConversionSpecialized, - TypeToReplaceAutoWith, S); - } - - // Ensure that static invoker doesn't have a const qualifier. - // FIXME: When creating the InvokerTemplate in SemaLambda.cpp - // do not use the CallOperator's TypeSourceInfo which allows - // the const qualifier to leak through. - const FunctionProtoType *InvokerFPT = InvokerSpecialized-> - getType().getTypePtr()->castAs<FunctionProtoType>(); - FunctionProtoType::ExtProtoInfo EPI = InvokerFPT->getExtProtoInfo(); - EPI.TypeQuals = 0; - InvokerSpecialized->setType(S.Context.getFunctionType( - InvokerFPT->getReturnType(), InvokerFPT->getParamTypes(), EPI)); - return Sema::TDK_Success; -} -/// \brief Deduce template arguments for a templated conversion +/// Deduce template arguments for a templated conversion /// function (C++ [temp.deduct.conv]) and, if successful, produce a /// conversion function template specialization. Sema::TemplateDeductionResult @@ -4080,12 +4155,20 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *ConversionTemplate, // C++0x [temp.deduct.conv]p4: // [...] If A is a reference type, the type referred to by A is used // for type deduction. - if (const ReferenceType *ARef = A->getAs<ReferenceType>()) - A = ARef->getPointeeType().getUnqualifiedType(); + if (const ReferenceType *ARef = A->getAs<ReferenceType>()) { + A = ARef->getPointeeType(); + // We work around a defect in the standard here: cv-qualifiers are also + // removed from P and A in this case, unless P was a reference type. This + // seems to mostly match what other compilers are doing. + if (!FromType->getAs<ReferenceType>()) { + A = A.getUnqualifiedType(); + P = P.getUnqualifiedType(); + } + // C++ [temp.deduct.conv]p3: // // If A is not a reference type: - else { + } else { assert(!A->isReferenceType() && "Reference types were handled above"); // - If P is an array type, the pointer type produced by the @@ -4134,7 +4217,7 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *ConversionTemplate, // cv-qualified than the deduced A (i.e., the type referred to // by the reference) if (ToType->isReferenceType()) - TDF |= TDF_ParamWithReferenceType; + TDF |= TDF_ArgWithReferenceType; // - The deduced A can be another pointer or pointer to member // type that can be converted to A via a qualification // conversion. @@ -4158,39 +4241,10 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *ConversionTemplate, = FinishTemplateArgumentDeduction(ConversionTemplate, Deduced, 0, ConversionSpecialized, Info); Specialization = cast_or_null<CXXConversionDecl>(ConversionSpecialized); - - // If the conversion operator is being invoked on a lambda closure to convert - // to a ptr-to-function, use the deduced arguments from the conversion - // function to specialize the corresponding call operator. - // e.g., int (*fp)(int) = [](auto a) { return a; }; - if (Result == TDK_Success && isLambdaConversionOperator(ConversionGeneric)) { - - // Get the return type of the destination ptr-to-function we are converting - // to. This is necessary for matching the lambda call operator's return - // type to that of the destination ptr-to-function's return type. - assert(A->isPointerType() && - "Can only convert from lambda to ptr-to-function"); - const FunctionType *ToFunType = - A->getPointeeType().getTypePtr()->getAs<FunctionType>(); - const QualType DestFunctionPtrReturnType = ToFunType->getReturnType(); - - // Create the corresponding specializations of the call operator and - // the static-invoker; and if the return type is auto, - // deduce the return type and check if it matches the - // DestFunctionPtrReturnType. - // For instance: - // auto L = [](auto a) { return f(a); }; - // int (*fp)(int) = L; - // char (*fp2)(int) = L; <-- Not OK. - - Result = SpecializeCorrespondingLambdaCallOperatorAndInvoker( - Specialization, Deduced, DestFunctionPtrReturnType, - Info, *this); - } return Result; } -/// \brief Deduce template arguments for a function template when there is +/// Deduce template arguments for a function template when there is /// nothing to deduce against (C++0x [temp.arg.explicit]p3). /// /// \param FunctionTemplate the function template for which we are performing @@ -4225,12 +4279,14 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( } namespace { + /// 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 UseTypeSugar; + public: SubstituteDeducedTypeTransform(Sema &SemaRef, QualType Replacement, bool UseTypeSugar = true) @@ -4292,7 +4348,8 @@ namespace { return TransformType(TLB, TL); } }; -} + +} // namespace Sema::DeduceAutoResult Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init, QualType &Result, @@ -4326,7 +4383,7 @@ static bool diagnoseAutoDeductionFailure(Sema &S, } } -/// \brief Deduce the type for an auto type-specifier (C++11 [dcl.spec.auto]p6) +/// Deduce the type for an auto type-specifier (C++11 [dcl.spec.auto]p6) /// /// Note that this is done even if the initializer is dependent. (This is /// necessary to support partial ordering of templates using 'auto'.) @@ -4536,6 +4593,43 @@ bool Sema::DeduceReturnType(FunctionDecl *FD, SourceLocation Loc, bool Diagnose) { assert(FD->getReturnType()->isUndeducedType()); + // For a lambda's conversion operator, deduce any 'auto' or 'decltype(auto)' + // within the return type from the call operator's type. + if (isLambdaConversionOperator(FD)) { + CXXRecordDecl *Lambda = cast<CXXMethodDecl>(FD)->getParent(); + FunctionDecl *CallOp = Lambda->getLambdaCallOperator(); + + // For a generic lambda, instantiate the call operator if needed. + if (auto *Args = FD->getTemplateSpecializationArgs()) { + CallOp = InstantiateFunctionDeclaration( + CallOp->getDescribedFunctionTemplate(), Args, Loc); + if (!CallOp || CallOp->isInvalidDecl()) + return true; + + // We might need to deduce the return type by instantiating the definition + // of the operator() function. + if (CallOp->getReturnType()->isUndeducedType()) + InstantiateFunctionDefinition(Loc, CallOp); + } + + if (CallOp->isInvalidDecl()) + return true; + assert(!CallOp->getReturnType()->isUndeducedType() && + "failed to deduce lambda return type"); + + // Build the new return type from scratch. + QualType RetType = getLambdaConversionFunctionResultType( + CallOp->getType()->castAs<FunctionProtoType>()); + if (FD->getReturnType()->getAs<PointerType>()) + RetType = Context.getPointerType(RetType); + else { + assert(FD->getReturnType()->getAs<BlockPointerType>()); + RetType = Context.getBlockPointerType(RetType); + } + Context.adjustDeducedFunctionResultType(FD, RetType); + return false; + } + if (FD->getTemplateInstantiationPattern()) InstantiateFunctionDefinition(Loc, FD); @@ -4548,7 +4642,7 @@ bool Sema::DeduceReturnType(FunctionDecl *FD, SourceLocation Loc, return StillUndeduced; } -/// \brief If this is a non-static member function, +/// If this is a non-static member function, static void AddImplicitObjectParameterType(ASTContext &Context, CXXMethodDecl *Method, @@ -4570,7 +4664,7 @@ AddImplicitObjectParameterType(ASTContext &Context, ArgTypes.push_back(ArgTy); } -/// \brief Determine whether the function template \p FT1 is at least as +/// Determine whether the function template \p FT1 is at least as /// specialized as \p FT2. static bool isAtLeastAsSpecializedAs(Sema &S, SourceLocation Loc, @@ -4721,7 +4815,7 @@ static bool isAtLeastAsSpecializedAs(Sema &S, return true; } -/// \brief Determine whether this a function template whose parameter-type-list +/// Determine whether this a function template whose parameter-type-list /// ends with a function parameter pack. static bool isVariadicFunctionTemplate(FunctionTemplateDecl *FunTmpl) { FunctionDecl *Function = FunTmpl->getTemplatedDecl(); @@ -4742,7 +4836,7 @@ static bool isVariadicFunctionTemplate(FunctionTemplateDecl *FunTmpl) { return true; } -/// \brief Returns the more specialized function template according +/// Returns the more specialized function template according /// to the rules of function template partial ordering (C++ [temp.func.order]). /// /// \param FT1 the first function template @@ -4789,7 +4883,7 @@ Sema::getMoreSpecializedTemplate(FunctionTemplateDecl *FT1, return nullptr; } -/// \brief Determine if the two templates are equivalent. +/// Determine if the two templates are equivalent. static bool isSameTemplate(TemplateDecl *T1, TemplateDecl *T2) { if (T1 == T2) return true; @@ -4800,7 +4894,7 @@ static bool isSameTemplate(TemplateDecl *T1, TemplateDecl *T2) { return T1->getCanonicalDecl() == T2->getCanonicalDecl(); } -/// \brief Retrieve the most specialized of the given function template +/// Retrieve the most specialized of the given function template /// specializations. /// /// \param SpecBegin the start iterator of the function template @@ -4959,7 +5053,7 @@ static bool isAtLeastAsSpecializedAs(Sema &S, QualType T1, QualType T2, return true; } -/// \brief Returns the more specialized class template partial specialization +/// Returns the more specialized class template partial specialization /// according to the rules of partial ordering of class template partial /// specializations (C++ [temp.class.order]). /// @@ -5114,7 +5208,7 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs( return isAtLeastAsSpecializedAs(*this, PType, AType, AArg, Info); } -/// \brief Mark the template parameters that are used by the given +/// Mark the template parameters that are used by the given /// expression. static void MarkUsedTemplateParameters(ASTContext &Ctx, @@ -5128,7 +5222,7 @@ MarkUsedTemplateParameters(ASTContext &Ctx, // Skip through any implicit casts we added while type-checking, and any // substitutions performed by template alias expansion. - while (1) { + while (true) { if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) E = ICE->getSubExpr(); else if (const SubstNonTypeTemplateParmExpr *Subst = @@ -5158,7 +5252,7 @@ MarkUsedTemplateParameters(ASTContext &Ctx, MarkUsedTemplateParameters(Ctx, NTTP->getType(), OnlyDeduced, Depth, Used); } -/// \brief Mark the template parameters that are used by the given +/// Mark the template parameters that are used by the given /// nested name specifier. static void MarkUsedTemplateParameters(ASTContext &Ctx, @@ -5175,7 +5269,7 @@ MarkUsedTemplateParameters(ASTContext &Ctx, OnlyDeduced, Depth, Used); } -/// \brief Mark the template parameters that are used by the given +/// Mark the template parameters that are used by the given /// template name. static void MarkUsedTemplateParameters(ASTContext &Ctx, @@ -5200,7 +5294,7 @@ MarkUsedTemplateParameters(ASTContext &Ctx, Depth, Used); } -/// \brief Mark the template parameters that are used by the given +/// Mark the template parameters that are used by the given /// type. static void MarkUsedTemplateParameters(ASTContext &Ctx, QualType T, @@ -5271,6 +5365,14 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T, OnlyDeduced, Depth, Used); break; + case Type::DependentVector: { + const auto *VecType = cast<DependentVectorType>(T); + MarkUsedTemplateParameters(Ctx, VecType->getElementType(), OnlyDeduced, + Depth, Used); + MarkUsedTemplateParameters(Ctx, VecType->getSizeExpr(), OnlyDeduced, Depth, + Used); + break; + } case Type::DependentSizedExtVector: { const DependentSizedExtVectorType *VecType = cast<DependentSizedExtVectorType>(T); @@ -5296,9 +5398,24 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T, const FunctionProtoType *Proto = cast<FunctionProtoType>(T); MarkUsedTemplateParameters(Ctx, Proto->getReturnType(), OnlyDeduced, Depth, Used); - for (unsigned I = 0, N = Proto->getNumParams(); I != N; ++I) - MarkUsedTemplateParameters(Ctx, Proto->getParamType(I), OnlyDeduced, - Depth, Used); + for (unsigned I = 0, N = Proto->getNumParams(); I != N; ++I) { + // C++17 [temp.deduct.type]p5: + // The non-deduced contexts are: [...] + // -- A function parameter pack that does not occur at the end of the + // parameter-declaration-list. + if (!OnlyDeduced || I + 1 == N || + !Proto->getParamType(I)->getAs<PackExpansionType>()) { + MarkUsedTemplateParameters(Ctx, Proto->getParamType(I), OnlyDeduced, + Depth, Used); + } else { + // FIXME: C++17 [temp.deduct.call]p1: + // When a function parameter pack appears in a non-deduced context, + // the type of that pack is never deduced. + // + // We should also track a set of "never deduced" parameters, and + // subtract that from the list of deduced parameters after marking. + } + } if (auto *E = Proto->getNoexceptExpr()) MarkUsedTemplateParameters(Ctx, E, OnlyDeduced, Depth, Used); break; @@ -5453,7 +5570,7 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T, } } -/// \brief Mark the template parameters that are used by this +/// Mark the template parameters that are used by this /// template argument. static void MarkUsedTemplateParameters(ASTContext &Ctx, @@ -5496,7 +5613,7 @@ MarkUsedTemplateParameters(ASTContext &Ctx, } } -/// \brief Mark which template parameters can be deduced from a given +/// Mark which template parameters can be deduced from a given /// template argument list. /// /// \param TemplateArgs the template argument list from which template @@ -5522,7 +5639,7 @@ Sema::MarkUsedTemplateParameters(const TemplateArgumentList &TemplateArgs, Depth, Used); } -/// \brief Marks all of the template parameters that will be deduced by a +/// Marks all of the template parameters that will be deduced by a /// call to the given function template. void Sema::MarkDeducedTemplateParameters( ASTContext &Ctx, const FunctionTemplateDecl *FunctionTemplate, |