[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