[cfe-commits] r123425 - in /cfe/trunk: include/clang/AST/ include/clang/Serialization/ lib/AST/ lib/Sema/ lib/Serialization/ test/CXX/temp/temp.decls/temp.variadic/

Matt Beaumont-Gay matthewbg at google.com
Thu Jan 13 20:19:34 PST 2011


On Thu, Jan 13, 2011 at 18:55, Douglas Gregor <dgregor at apple.com> wrote:
> Author: dgregor
> Date: Thu Jan 13 20:55:32 2011
> New Revision: 123425
>
> URL: http://llvm.org/viewvc/llvm-project?rev=123425&view=rev
> Log:
> Start implementing support for substitution into pack expansions that
> involve template parameter packs at multiple template levels that
> occur within the signatures members of class templates (and partial
> specializations thereof). This is a work-in-progress that is deficient
> in several ways, notably:
>  - It only works for template type parameter packs, but we need to
>  also support non-type template parameter packs and template template
>  parameter packs.
>  - It doesn't keep track of the lengths of the substituted argument
>  packs in the expansion, so it can't properly diagnose length
>  mismatches.
>
> However, this is a concrete step in the right direction.
>
> Modified:
>    cfe/trunk/include/clang/AST/ASTContext.h
>    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
>    cfe/trunk/include/clang/AST/Type.h
>    cfe/trunk/include/clang/AST/TypeLoc.h
>    cfe/trunk/include/clang/AST/TypeNodes.def
>    cfe/trunk/include/clang/Serialization/ASTBitCodes.h
>    cfe/trunk/lib/AST/ASTContext.cpp
>    cfe/trunk/lib/AST/ItaniumMangle.cpp
>    cfe/trunk/lib/AST/MicrosoftMangle.cpp
>    cfe/trunk/lib/AST/Type.cpp
>    cfe/trunk/lib/AST/TypePrinter.cpp
>    cfe/trunk/lib/Sema/SemaTemplate.cpp
>    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
>    cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp
>    cfe/trunk/lib/Sema/TreeTransform.h
>    cfe/trunk/lib/Serialization/ASTReader.cpp
>    cfe/trunk/lib/Serialization/ASTWriter.cpp
>    cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp
>
> Modified: cfe/trunk/include/clang/AST/ASTContext.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=123425&r1=123424&r2=123425&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/ASTContext.h (original)
> +++ cfe/trunk/include/clang/AST/ASTContext.h Thu Jan 13 20:55:32 2011
> @@ -102,6 +102,8 @@
>   mutable llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
>   mutable llvm::FoldingSet<SubstTemplateTypeParmType>
>     SubstTemplateTypeParmTypes;
> +  mutable llvm::FoldingSet<SubstTemplateTypeParmPackType>
> +    SubstTemplateTypeParmPackTypes;
>   mutable llvm::ContextualFoldingSet<TemplateSpecializationType, ASTContext&>
>     TemplateSpecializationTypes;
>   mutable llvm::FoldingSet<ParenType> ParenTypes;
> @@ -664,6 +666,9 @@
>
>   QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
>                                         QualType Replacement) const;
> +  QualType getSubstTemplateTypeParmPackType(
> +                                          const TemplateTypeParmType *Replaced,
> +                                            const TemplateArgument &ArgPack);
>
>   QualType getTemplateTypeParmType(unsigned Depth, unsigned Index,
>                                    bool ParameterPack,
>
> Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=123425&r1=123424&r2=123425&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
> +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Thu Jan 13 20:55:32 2011
> @@ -718,6 +718,7 @@
>  DEF_TRAVERSE_TYPE(EnumType, { })
>  DEF_TRAVERSE_TYPE(TemplateTypeParmType, { })
>  DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, { })
> +DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, { })
>
>  DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
>     TRY_TO(TraverseTemplateName(T->getTemplateName()));
> @@ -925,6 +926,7 @@
>  DEF_TRAVERSE_TYPELOC(EnumType, { })
>  DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, { })
>  DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, { })
> +DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, { })
>
>  // FIXME: use the loc for the template name?
>  DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
>
> Modified: cfe/trunk/include/clang/AST/Type.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=123425&r1=123424&r2=123425&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/Type.h (original)
> +++ cfe/trunk/include/clang/AST/Type.h Thu Jan 13 20:55:32 2011
> @@ -2860,6 +2860,59 @@
>   static bool classof(const SubstTemplateTypeParmType *T) { return true; }
>  };
>
> +/// \brief Represents the result of substituting a set of types for a template
> +/// type parameter pack.
> +///
> +/// When a pack expansion in the source code contains multiple parameter packs
> +/// and those parameter packs correspond to different levels of template
> +/// parameter lists, this type node is used to represent a template type
> +/// parameter pack from an outer level, which has already had its argument pack
> +/// substituted but that still lives within a pack expansion that itself
> +/// could not be instantiated. When actually performing a substitution into
> +/// that pack expansion (e.g., when all template parameters have corresponding
> +/// arguments), this type will be replaced with the \c SubstTemplateTypeParmType
> +/// at the current pack substitution index.
> +class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
> +  /// \brief The original type parameter.
> +  const TemplateTypeParmType *Replaced;
> +
> +  /// \brief A pointer to the set of template arguments that this
> +  /// parameter pack is instantiated with.
> +  const TemplateArgument *Arguments;
> +
> +  /// \brief The number of template arguments in \c Arguments.
> +  unsigned NumArguments;
> +
> +  SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param,
> +                                QualType Canon,
> +                                const TemplateArgument &ArgPack);
> +
> +  friend class ASTContext;
> +
> +public:
> +  IdentifierInfo *getName() const { return Replaced->getName(); }
> +
> +  /// Gets the template parameter that was substituted for.
> +  const TemplateTypeParmType *getReplacedParameter() const {
> +    return Replaced;
> +  }
> +
> +  bool isSugared() const { return false; }
> +  QualType desugar() const { return QualType(this, 0); }
> +
> +  TemplateArgument getArgumentPack() const;
> +
> +  void Profile(llvm::FoldingSetNodeID &ID);
> +  static void Profile(llvm::FoldingSetNodeID &ID,
> +                      const TemplateTypeParmType *Replaced,
> +                      const TemplateArgument &ArgPack);
> +
> +  static bool classof(const Type *T) {
> +    return T->getTypeClass() == SubstTemplateTypeParmPack;
> +  }
> +  static bool classof(const SubstTemplateTypeParmPackType *T) { return true; }
> +};
> +
>  /// \brief Represents the type of a template specialization as written
>  /// in the source code.
>  ///
>
> Modified: cfe/trunk/include/clang/AST/TypeLoc.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=123425&r1=123424&r2=123425&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/TypeLoc.h (original)
> +++ cfe/trunk/include/clang/AST/TypeLoc.h Thu Jan 13 20:55:32 2011
> @@ -592,6 +592,13 @@
>                                      SubstTemplateTypeParmType> {
>  };
>
> +  /// \brief Wrapper for substituted template type parameters.
> +class SubstTemplateTypeParmPackTypeLoc :
> +    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
> +                                     SubstTemplateTypeParmPackTypeLoc,
> +                                     SubstTemplateTypeParmPackType> {
> +};
> +
>  struct AttributedLocInfo {
>   union {
>     Expr *ExprOperand;
>
> Modified: cfe/trunk/include/clang/AST/TypeNodes.def
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeNodes.def?rev=123425&r1=123424&r2=123425&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/TypeNodes.def (original)
> +++ cfe/trunk/include/clang/AST/TypeNodes.def Thu Jan 13 20:55:32 2011
> @@ -91,6 +91,7 @@
>  NON_CANONICAL_TYPE(Attributed, Type)
>  DEPENDENT_TYPE(TemplateTypeParm, Type)
>  NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)
> +DEPENDENT_TYPE(SubstTemplateTypeParmPack, Type)

A couple of switch statements need cases for SubstTemplateTypeParmPack:

tools/clang/lib/AST/ASTImporter.cpp:379:11: error: enumeration value
'SubstTemplateTypeParmPack' not handled in switch [-Wswitch-enum]
  switch (TC) {
          ^

tools/clang/lib/Sema/SemaTemplateDeduction.cpp:3448:12: error:
enumeration value 'SubstTemplateTypeParmPack' not handled in switch
[-Wswitch-enum]
  switch (T->getTypeClass()) {
           ^

Want me to just add "default: assert(0 && ...)" for now?

>  NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
>  DEPENDENT_TYPE(InjectedClassName, Type)
>  DEPENDENT_TYPE(DependentName, Type)
>
> Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=123425&r1=123424&r2=123425&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
> +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Thu Jan 13 20:55:32 2011
> @@ -555,7 +555,9 @@
>       /// \brief A PackExpansionType record.
>       TYPE_PACK_EXPANSION           = 35,
>       /// \brief An AttributedType record.
> -      TYPE_ATTRIBUTED               = 36
> +      TYPE_ATTRIBUTED               = 36,
> +      /// \brief A SubstTemplateTypeParmPackType record.
> +      TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK = 37
>     };
>
>     /// \brief The type IDs for special types constructed by semantic
>
> Modified: cfe/trunk/lib/AST/ASTContext.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=123425&r1=123424&r2=123425&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/ASTContext.cpp (original)
> +++ cfe/trunk/lib/AST/ASTContext.cpp Thu Jan 13 20:55:32 2011
> @@ -1932,6 +1932,42 @@
>   return QualType(SubstParm, 0);
>  }
>
> +/// \brief Retrieve a
> +QualType ASTContext::getSubstTemplateTypeParmPackType(
> +                                          const TemplateTypeParmType *Parm,
> +                                              const TemplateArgument &ArgPack) {
> +#ifndef NDEBUG
> +  for (TemplateArgument::pack_iterator P = ArgPack.pack_begin(),
> +                                    PEnd = ArgPack.pack_end();
> +       P != PEnd; ++P) {
> +    assert(P->getKind() == TemplateArgument::Type &&"Pack contains a non-type");
> +    assert(P->getAsType().isCanonical() && "Pack contains non-canonical type");
> +  }
> +#endif
> +
> +  llvm::FoldingSetNodeID ID;
> +  SubstTemplateTypeParmPackType::Profile(ID, Parm, ArgPack);
> +  void *InsertPos = 0;
> +  if (SubstTemplateTypeParmPackType *SubstParm
> +        = SubstTemplateTypeParmPackTypes.FindNodeOrInsertPos(ID, InsertPos))
> +    return QualType(SubstParm, 0);
> +
> +  QualType Canon;
> +  if (!Parm->isCanonicalUnqualified()) {
> +    Canon = getCanonicalType(QualType(Parm, 0));
> +    Canon = getSubstTemplateTypeParmPackType(cast<TemplateTypeParmType>(Canon),
> +                                             ArgPack);
> +    SubstTemplateTypeParmPackTypes.FindNodeOrInsertPos(ID, InsertPos);
> +  }
> +
> +  SubstTemplateTypeParmPackType *SubstParm
> +    = new (*this, TypeAlignment) SubstTemplateTypeParmPackType(Parm, Canon,
> +                                                               ArgPack);
> +  Types.push_back(SubstParm);
> +  SubstTemplateTypeParmTypes.InsertNode(SubstParm, InsertPos);
> +  return QualType(SubstParm, 0);
> +}
> +
>  /// \brief Retrieve the template type parameter type for a template
>  /// parameter or parameter pack with the given depth, index, and (optionally)
>  /// name.
>
> Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=123425&r1=123424&r2=123425&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
> +++ cfe/trunk/lib/AST/ItaniumMangle.cpp Thu Jan 13 20:55:32 2011
> @@ -1383,6 +1383,11 @@
>   mangleTemplateParameter(T->getIndex());
>  }
>
> +// <type>           ::= <template-param>
> +void CXXNameMangler::mangleType(const SubstTemplateTypeParmPackType *T) {
> +  mangleTemplateParameter(T->getReplacedParameter()->getIndex());
> +}
> +
>  // <type> ::= P <type>   # pointer-to
>  void CXXNameMangler::mangleType(const PointerType *T) {
>   Out << 'P';
>
> Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=123425&r1=123424&r2=123425&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
> +++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Thu Jan 13 20:55:32 2011
> @@ -1011,6 +1011,12 @@
>   assert(false && "Don't know how to mangle TemplateTypeParmTypes yet!");
>  }
>
> +void MicrosoftCXXNameMangler::mangleType(
> +                                       const SubstTemplateTypeParmPackType *T) {
> +  assert(false &&
> +         "Don't know how to mangle SubstTemplateTypeParmPackTypes yet!");
> +}
> +
>  // <type> ::= <pointer-type>
>  // <pointer-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers> <type>
>  void MicrosoftCXXNameMangler::mangleType(const PointerType *T) {
>
> Modified: cfe/trunk/lib/AST/Type.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=123425&r1=123424&r2=123425&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/Type.cpp (original)
> +++ cfe/trunk/lib/AST/Type.cpp Thu Jan 13 20:55:32 2011
> @@ -1244,6 +1244,34 @@
>   return isa<EnumDecl>(TT->getDecl());
>  }
>
> +SubstTemplateTypeParmPackType::
> +SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param,
> +                              QualType Canon,
> +                              const TemplateArgument &ArgPack)
> +  : Type(SubstTemplateTypeParmPack, Canon, true, false, true), Replaced(Param),
> +    Arguments(ArgPack.pack_begin()), NumArguments(ArgPack.pack_size())
> +{
> +}
> +
> +TemplateArgument SubstTemplateTypeParmPackType::getArgumentPack() const {
> +  return TemplateArgument(Arguments, NumArguments);
> +}
> +
> +void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID) {
> +  Profile(ID, getReplacedParameter(), getArgumentPack());
> +}
> +
> +void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID,
> +                                           const TemplateTypeParmType *Replaced,
> +                                            const TemplateArgument &ArgPack) {
> +  ID.AddPointer(Replaced);
> +  ID.AddInteger(ArgPack.pack_size());
> +  for (TemplateArgument::pack_iterator P = ArgPack.pack_begin(),
> +                                    PEnd = ArgPack.pack_end();
> +       P != PEnd; ++P)
> +    ID.AddPointer(P->getAsType().getAsOpaquePtr());
> +}
> +
>  bool TemplateSpecializationType::
>  anyDependentTemplateArguments(const TemplateArgumentListInfo &Args) {
>   return anyDependentTemplateArguments(Args.getArgumentArray(), Args.size());
>
> Modified: cfe/trunk/lib/AST/TypePrinter.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=123425&r1=123424&r2=123425&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/TypePrinter.cpp (original)
> +++ cfe/trunk/lib/AST/TypePrinter.cpp Thu Jan 13 20:55:32 2011
> @@ -568,6 +568,12 @@
>   print(T->getReplacementType(), S);
>  }
>
> +void TypePrinter::printSubstTemplateTypeParmPack(
> +                                        const SubstTemplateTypeParmPackType *T,
> +                                             std::string &S) {
> +  printTemplateTypeParm(T->getReplacedParameter(), S);
> +}
> +
>  void TypePrinter::printTemplateSpecialization(
>                                             const TemplateSpecializationType *T,
>                                               std::string &S) {
>
> Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=123425&r1=123424&r2=123425&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Jan 13 20:55:32 2011
> @@ -2713,6 +2713,11 @@
>   return false;
>  }
>
> +bool UnnamedLocalNoLinkageFinder::VisitSubstTemplateTypeParmPackType(
> +                                        const SubstTemplateTypeParmPackType *) {
> +  return false;
> +}
> +
>  bool UnnamedLocalNoLinkageFinder::VisitTemplateSpecializationType(
>                                             const TemplateSpecializationType*) {
>   return false;
>
> Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=123425&r1=123424&r2=123425&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Thu Jan 13 20:55:32 2011
> @@ -712,6 +712,12 @@
>     QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
>                                            TemplateTypeParmTypeLoc TL);
>
> +    /// \brief Transforms an already-substituted template type parameter pack
> +    /// into either itself (if we aren't substituting into its pack expansion)
> +    /// or the appropriate substituted argument.
> +    QualType TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,
> +                                           SubstTemplateTypeParmPackTypeLoc TL);
> +
>     ExprResult TransformCallExpr(CallExpr *CE) {
>       getSema().CallsUndergoingInstantiation.push_back(CE);
>       ExprResult Result =
> @@ -1024,10 +1030,15 @@
>              "Missing argument pack");
>
>       if (getSema().ArgumentPackSubstitutionIndex == -1) {
> -        // FIXME: Variadic templates fun case.
> -        getSema().Diag(TL.getSourceRange().getBegin(),
> -                       diag::err_pack_expansion_mismatch_unsupported);
> -        return QualType();
> +        // We have the template argument pack, but we're not expanding the
> +        // enclosing pack expansion yet. Just save the template argument
> +        // pack for later substitution.
> +        QualType Result
> +          = getSema().Context.getSubstTemplateTypeParmPackType(T, Arg);
> +        SubstTemplateTypeParmPackTypeLoc NewTL
> +          = TLB.push<SubstTemplateTypeParmPackTypeLoc>(Result);
> +        NewTL.setNameLoc(TL.getNameLoc());
> +        return Result;
>       }
>
>       assert(getSema().ArgumentPackSubstitutionIndex < (int)Arg.pack_size());
> @@ -1063,6 +1074,32 @@
>   return Result;
>  }
>
> +QualType
> +TemplateInstantiator::TransformSubstTemplateTypeParmPackType(
> +                                                            TypeLocBuilder &TLB,
> +                                         SubstTemplateTypeParmPackTypeLoc TL) {
> +  if (getSema().ArgumentPackSubstitutionIndex == -1) {
> +    // We aren't expanding the parameter pack, so just return ourselves.
> +    SubstTemplateTypeParmPackTypeLoc NewTL
> +      = TLB.push<SubstTemplateTypeParmPackTypeLoc>(TL.getType());
> +    NewTL.setNameLoc(TL.getNameLoc());
> +    return TL.getType();
> +  }
> +
> +  const TemplateArgument &ArgPack = TL.getTypePtr()->getArgumentPack();
> +  unsigned Index = (unsigned)getSema().ArgumentPackSubstitutionIndex;
> +  assert(Index < ArgPack.pack_size() && "Substitution index out-of-range");
> +
> +  QualType Result = ArgPack.pack_begin()[Index].getAsType();
> +  Result = getSema().Context.getSubstTemplateTypeParmType(
> +                                      TL.getTypePtr()->getReplacedParameter(),
> +                                                          Result);
> +  SubstTemplateTypeParmTypeLoc NewTL
> +    = TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
> +  NewTL.setNameLoc(TL.getNameLoc());
> +  return Result;
> +}
> +
>  /// \brief Perform substitution on the type T with a given set of template
>  /// arguments.
>  ///
>
> Modified: cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp?rev=123425&r1=123424&r2=123425&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp Thu Jan 13 20:55:32 2011
> @@ -456,6 +456,10 @@
>   std::pair<IdentifierInfo *, SourceLocation> FirstPack;
>   bool HaveFirstPack = false;
>
> +  // FIXME: Variadic templates. Even if we don't expand, we'd still like to
> +  // return the number of expansions back to the caller, perhaps as an
> +  // llvm::Optional, so that it can be embedded in the pack expansion. This
> +  // is important for the multi-level substitution case.
>   for (unsigned I = 0; I != NumUnexpanded; ++I) {
>     // Compute the depth and index for this parameter pack.
>     unsigned Depth;
>
> Modified: cfe/trunk/lib/Sema/TreeTransform.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=123425&r1=123424&r2=123425&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/TreeTransform.h (original)
> +++ cfe/trunk/lib/Sema/TreeTransform.h Thu Jan 13 20:55:32 2011
> @@ -3927,6 +3927,13 @@
>  }
>
>  template<typename Derived>
> +QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
> +                                          TypeLocBuilder &TLB,
> +                                          SubstTemplateTypeParmPackTypeLoc TL) {
> +  return TransformTypeSpecType(TLB, TL);
> +}
> +
> +template<typename Derived>
>  QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
>                                                         TypeLocBuilder &TLB,
>                                            TemplateSpecializationTypeLoc TL) {
>
> Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=123425&r1=123424&r2=123425&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTReader.cpp Thu Jan 13 20:55:32 2011
> @@ -2997,6 +2997,15 @@
>                                             Replacement);
>   }
>
> +  case TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK: {
> +    unsigned Idx = 0;
> +    QualType Parm = GetType(Record[Idx++]);
> +    TemplateArgument ArgPack = ReadTemplateArgument(*Loc.F, Record, Idx);
> +    return Context->getSubstTemplateTypeParmPackType(
> +                                               cast<TemplateTypeParmType>(Parm),
> +                                                     ArgPack);
> +  }
> +
>   case TYPE_INJECTED_CLASS_NAME: {
>     CXXRecordDecl *D = cast<CXXRecordDecl>(GetDecl(Record[0]));
>     QualType TST = GetType(Record[1]); // probably derivable
> @@ -3233,6 +3242,10 @@
>                                             SubstTemplateTypeParmTypeLoc TL) {
>   TL.setNameLoc(ReadSourceLocation(Record, Idx));
>  }
> +void TypeLocReader::VisitSubstTemplateTypeParmPackTypeLoc(
> +                                          SubstTemplateTypeParmPackTypeLoc TL) {
> +  TL.setNameLoc(ReadSourceLocation(Record, Idx));
> +}
>  void TypeLocReader::VisitTemplateSpecializationTypeLoc(
>                                            TemplateSpecializationTypeLoc TL) {
>   TL.setTemplateNameLoc(ReadSourceLocation(Record, Idx));
>
> Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=123425&r1=123424&r2=123425&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Thu Jan 13 20:55:32 2011
> @@ -244,6 +244,14 @@
>  }
>
>  void
> +ASTTypeWriter::VisitSubstTemplateTypeParmPackType(
> +                                      const SubstTemplateTypeParmPackType *T) {
> +  Writer.AddTypeRef(QualType(T->getReplacedParameter(), 0), Record);
> +  Writer.AddTemplateArgument(T->getArgumentPack(), Record);
> +  Code = TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK;
> +}
> +
> +void
>  ASTTypeWriter::VisitTemplateSpecializationType(
>                                        const TemplateSpecializationType *T) {
>   Record.push_back(T->isDependentType());
> @@ -491,6 +499,10 @@
>                                             SubstTemplateTypeParmTypeLoc TL) {
>   Writer.AddSourceLocation(TL.getNameLoc(), Record);
>  }
> +void TypeLocWriter::VisitSubstTemplateTypeParmPackTypeLoc(
> +                                          SubstTemplateTypeParmPackTypeLoc TL) {
> +  Writer.AddSourceLocation(TL.getNameLoc(), Record);
> +}
>  void TypeLocWriter::VisitTemplateSpecializationTypeLoc(
>                                            TemplateSpecializationTypeLoc TL) {
>   Writer.AddSourceLocation(TL.getTemplateNameLoc(), Record);
>
> Modified: cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp?rev=123425&r1=123424&r2=123425&view=diff
> ==============================================================================
> --- cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp (original)
> +++ cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp Thu Jan 13 20:55:32 2011
> @@ -11,3 +11,23 @@
>  void test_X0() {
>   X0<int>().f<1, 2, 3, 4, 5>();
>  }
> +
> +namespace PacksAtDifferentLevels {
> +  template<typename...> struct tuple { };
> +  template<typename T, typename U> struct pair { };
> +
> +  template<typename ...Types>
> +  struct X {
> +    template<typename> struct Inner;
> +
> +    template<typename ...YTypes>
> +    struct Inner<tuple<pair<Types, YTypes>...> > {
> +      static const unsigned zero = sizeof...(Types) - sizeof...(YTypes);
> +    };
> +  };
> +
> +  int check0[X<short, int, long>::Inner<tuple<pair<short, unsigned short>,
> +                                             pair<int, unsigned int>,
> +                                             pair<long, unsigned long>>
> +                                       >::zero == 0? 1 : -1];
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>




More information about the cfe-commits mailing list