[clang] 4a56470 - Revert "Clang: fix AST representation of expanded template arguments."

Matheus Izvekov via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 26 04:11:52 PDT 2022


Author: Matheus Izvekov
Date: 2022-08-26T13:09:55+02:00
New Revision: 4a56470d0dcd2b6183e7aaf929995b01d986c216

URL: https://github.com/llvm/llvm-project/commit/4a56470d0dcd2b6183e7aaf929995b01d986c216
DIFF: https://github.com/llvm/llvm-project/commit/4a56470d0dcd2b6183e7aaf929995b01d986c216.diff

LOG: Revert "Clang: fix AST representation of expanded template arguments."

This reverts commit 1d1a56929b725f9a79d98877f12d0a14f8418b38.

Added: 
    

Modified: 
    clang/include/clang/AST/ASTContext.h
    clang/include/clang/AST/JSONNodeDumper.h
    clang/include/clang/AST/TextNodeDumper.h
    clang/include/clang/AST/Type.h
    clang/include/clang/AST/TypeProperties.td
    clang/lib/AST/ASTContext.cpp
    clang/lib/AST/ASTImporter.cpp
    clang/lib/AST/ASTStructuralEquivalence.cpp
    clang/lib/AST/JSONNodeDumper.cpp
    clang/lib/AST/TextNodeDumper.cpp
    clang/lib/AST/Type.cpp
    clang/lib/Sema/SemaTemplateInstantiate.cpp
    clang/lib/Sema/TreeTransform.h
    clang/test/AST/ast-dump-template-decls.cpp
    clang/unittests/AST/ASTImporterTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 2d533b49114b6..eb52bf5c736a0 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1614,8 +1614,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
                                    QualType Wrapped);
 
   QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
-                                        QualType Replacement,
-                                        Optional<unsigned> PackIndex) const;
+                                        QualType Replacement) const;
   QualType getSubstTemplateTypeParmPackType(
                                           const TemplateTypeParmType *Replaced,
                                             const TemplateArgument &ArgPack);

diff  --git a/clang/include/clang/AST/JSONNodeDumper.h b/clang/include/clang/AST/JSONNodeDumper.h
index 3597903695797..a5575d7fd441e 100644
--- a/clang/include/clang/AST/JSONNodeDumper.h
+++ b/clang/include/clang/AST/JSONNodeDumper.h
@@ -220,7 +220,6 @@ class JSONNodeDumper
   void VisitUnaryTransformType(const UnaryTransformType *UTT);
   void VisitTagType(const TagType *TT);
   void VisitTemplateTypeParmType(const TemplateTypeParmType *TTPT);
-  void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *STTPT);
   void VisitAutoType(const AutoType *AT);
   void VisitTemplateSpecializationType(const TemplateSpecializationType *TST);
   void VisitInjectedClassNameType(const InjectedClassNameType *ICNT);

diff  --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h
index e6853b12ae7e5..2e4bcdd27a8ab 100644
--- a/clang/include/clang/AST/TextNodeDumper.h
+++ b/clang/include/clang/AST/TextNodeDumper.h
@@ -317,7 +317,6 @@ class TextNodeDumper
   void VisitUnaryTransformType(const UnaryTransformType *T);
   void VisitTagType(const TagType *T);
   void VisitTemplateTypeParmType(const TemplateTypeParmType *T);
-  void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T);
   void VisitAutoType(const AutoType *T);
   void VisitDeducedTemplateSpecializationType(
       const DeducedTemplateSpecializationType *T);

diff  --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index f46224ff3d703..88e2fb338a328 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -1793,18 +1793,6 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
     unsigned NumArgs;
   };
 
-  class SubstTemplateTypeParmTypeBitfields {
-    friend class SubstTemplateTypeParmType;
-
-    unsigned : NumTypeBits;
-
-    /// Represents the index within a pack if this represents a substitution
-    /// from a pack expansion.
-    /// Positive non-zero number represents the index + 1.
-    /// Zero means this is not substituted from an expansion.
-    unsigned PackIndex;
-  };
-
   class SubstTemplateTypeParmPackTypeBitfields {
     friend class SubstTemplateTypeParmPackType;
 
@@ -1887,7 +1875,6 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
     ElaboratedTypeBitfields ElaboratedTypeBits;
     VectorTypeBitfields VectorTypeBits;
     SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits;
-    SubstTemplateTypeParmTypeBitfields SubstTemplateTypeParmTypeBits;
     TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
     DependentTemplateSpecializationTypeBitfields
       DependentTemplateSpecializationTypeBits;
@@ -4991,12 +4978,9 @@ class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode {
   // The original type parameter.
   const TemplateTypeParmType *Replaced;
 
-  SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon,
-                            Optional<unsigned> PackIndex)
+  SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon)
       : Type(SubstTemplateTypeParm, Canon, Canon->getDependence()),
-        Replaced(Param) {
-    SubstTemplateTypeParmTypeBits.PackIndex = PackIndex ? *PackIndex + 1 : 0;
-  }
+        Replaced(Param) {}
 
 public:
   /// Gets the template parameter that was substituted for.
@@ -5010,25 +4994,18 @@ class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode {
     return getCanonicalTypeInternal();
   }
 
-  Optional<unsigned> getPackIndex() const {
-    if (SubstTemplateTypeParmTypeBits.PackIndex == 0)
-      return None;
-    return SubstTemplateTypeParmTypeBits.PackIndex - 1;
-  }
-
   bool isSugared() const { return true; }
   QualType desugar() const { return getReplacementType(); }
 
   void Profile(llvm::FoldingSetNodeID &ID) {
-    Profile(ID, getReplacedParameter(), getReplacementType(), getPackIndex());
+    Profile(ID, getReplacedParameter(), getReplacementType());
   }
 
   static void Profile(llvm::FoldingSetNodeID &ID,
                       const TemplateTypeParmType *Replaced,
-                      QualType Replacement, Optional<unsigned> PackIndex) {
+                      QualType Replacement) {
     ID.AddPointer(Replaced);
     ID.AddPointer(Replacement.getAsOpaquePtr());
-    ID.AddInteger(PackIndex ? *PackIndex - 1 : 0);
   }
 
   static bool classof(const Type *T) {

diff  --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td
index aa8bb79fc4706..c46b0bd68cadc 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -734,15 +734,12 @@ let Class = SubstTemplateTypeParmType in {
   def : Property<"replacementType", QualType> {
     let Read = [{ node->getReplacementType() }];
   }
-  def : Property<"PackIndex", Optional<UInt32>> {
-    let Read = [{ node->getPackIndex() }];
-  }
 
   def : Creator<[{
     // The call to getCanonicalType here existed in ASTReader.cpp, too.
     return ctx.getSubstTemplateTypeParmType(
         cast<TemplateTypeParmType>(replacedParameter),
-        ctx.getCanonicalType(replacementType), PackIndex);
+        ctx.getCanonicalType(replacementType));
   }]>;
 }
 

diff  --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 8cc70fdc75d15..52e7eeca665ab 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -4747,20 +4747,19 @@ QualType ASTContext::getBTFTagAttributedType(const BTFTypeTagAttr *BTFAttr,
 /// Retrieve a substitution-result type.
 QualType
 ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm,
-                                         QualType Replacement,
-                                         Optional<unsigned> PackIndex) const {
+                                         QualType Replacement) const {
   assert(Replacement.isCanonical()
          && "replacement types must always be canonical");
 
   llvm::FoldingSetNodeID ID;
-  SubstTemplateTypeParmType::Profile(ID, Parm, Replacement, PackIndex);
+  SubstTemplateTypeParmType::Profile(ID, Parm, Replacement);
   void *InsertPos = nullptr;
   SubstTemplateTypeParmType *SubstParm
     = SubstTemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
 
   if (!SubstParm) {
     SubstParm = new (*this, TypeAlignment)
-        SubstTemplateTypeParmType(Parm, Replacement, PackIndex);
+      SubstTemplateTypeParmType(Parm, Replacement);
     Types.push_back(SubstParm);
     SubstTemplateTypeParmTypes.InsertNode(SubstParm, InsertPos);
   }

diff  --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 827185e349e0a..c368a61577cba 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -1530,8 +1530,7 @@ ExpectedType ASTNodeImporter::VisitSubstTemplateTypeParmType(
     return ToReplacementTypeOrErr.takeError();
 
   return Importer.getToContext().getSubstTemplateTypeParmType(
-      *ReplacedOrErr, ToReplacementTypeOrErr->getCanonicalType(),
-      T->getPackIndex());
+      *ReplacedOrErr, ToReplacementTypeOrErr->getCanonicalType());
 }
 
 ExpectedType ASTNodeImporter::VisitSubstTemplateTypeParmPackType(

diff  --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp
index 7e6055d4ffa95..8c7a2d5f89756 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -1062,8 +1062,6 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
     if (!IsStructurallyEquivalent(Context, Subst1->getReplacementType(),
                                   Subst2->getReplacementType()))
       return false;
-    if (Subst1->getPackIndex() != Subst2->getPackIndex())
-      return false;
     break;
   }
 

diff  --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp
index ae9c85e7542b3..a05c1f9208ee6 100644
--- a/clang/lib/AST/JSONNodeDumper.cpp
+++ b/clang/lib/AST/JSONNodeDumper.cpp
@@ -683,12 +683,6 @@ void JSONNodeDumper::VisitTemplateTypeParmType(
   JOS.attribute("decl", createBareDeclRef(TTPT->getDecl()));
 }
 
-void JSONNodeDumper::VisitSubstTemplateTypeParmType(
-    const SubstTemplateTypeParmType *STTPT) {
-  if (auto PackIndex = STTPT->getPackIndex())
-    JOS.attribute("pack_index", *PackIndex);
-}
-
 void JSONNodeDumper::VisitAutoType(const AutoType *AT) {
   JOS.attribute("undeduced", !AT->isDeduced());
   switch (AT->getKeyword()) {

diff  --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index f9f149bc883f6..73ba0b6329f1d 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -1570,12 +1570,6 @@ void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
   dumpDeclRef(T->getDecl());
 }
 
-void TextNodeDumper::VisitSubstTemplateTypeParmType(
-    const SubstTemplateTypeParmType *T) {
-  if (auto PackIndex = T->getPackIndex())
-    OS << " pack_index " << *PackIndex;
-}
-
 void TextNodeDumper::VisitAutoType(const AutoType *T) {
   if (T->isDecltypeAuto())
     OS << " decltype(auto)";

diff  --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 8534e575b466b..136af191f3c04 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -1167,7 +1167,7 @@ struct SimpleTransformVisitor : public TypeVisitor<Derived, QualType> {
       return QualType(T, 0);
 
     return Ctx.getSubstTemplateTypeParmType(T->getReplacedParameter(),
-                                            replacementType, T->getPackIndex());
+                                            replacementType);
   }
 
   // FIXME: Non-trivial to implement, but important for C++

diff  --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 1dd4baf901827..6d2498ae74f9f 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1813,7 +1813,6 @@ TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB,
       return NewT;
     }
 
-    Optional<unsigned> PackIndex;
     if (T->isParameterPack()) {
       assert(Arg.getKind() == TemplateArgument::Pack &&
              "Missing argument pack");
@@ -1831,7 +1830,6 @@ TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB,
       }
 
       Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
-      PackIndex = getSema().ArgumentPackSubstitutionIndex;
     }
 
     assert(Arg.getKind() == TemplateArgument::Type &&
@@ -1840,8 +1838,8 @@ TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB,
     QualType Replacement = Arg.getAsType();
 
     // TODO: only do this uniquing once, at the start of instantiation.
-    QualType Result = getSema().Context.getSubstTemplateTypeParmType(
-        T, Replacement, PackIndex);
+    QualType Result
+      = getSema().Context.getSubstTemplateTypeParmType(T, Replacement);
     SubstTemplateTypeParmTypeLoc NewTL
       = TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
     NewTL.setNameLoc(TL.getNameLoc());
@@ -1879,10 +1877,11 @@ TemplateInstantiator::TransformSubstTemplateTypeParmPackType(
 
   TemplateArgument Arg = TL.getTypePtr()->getArgumentPack();
   Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
+  QualType Result = Arg.getAsType();
 
-  QualType Result = getSema().Context.getSubstTemplateTypeParmType(
-      TL.getTypePtr()->getReplacedParameter(), Arg.getAsType(),
-      getSema().ArgumentPackSubstitutionIndex);
+  Result = getSema().Context.getSubstTemplateTypeParmType(
+                                      TL.getTypePtr()->getReplacedParameter(),
+                                                          Result);
   SubstTemplateTypeParmTypeLoc NewTL
     = TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
   NewTL.setNameLoc(TL.getNameLoc());

diff  --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 9fde9ce8582d1..2ebd5f79eabd9 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -4852,8 +4852,7 @@ QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
         Replacement = SemaRef.Context.getQualifiedType(
             Replacement.getUnqualifiedType(), Qs);
         T = SemaRef.Context.getSubstTemplateTypeParmType(
-            SubstTypeParam->getReplacedParameter(), Replacement,
-            SubstTypeParam->getPackIndex());
+            SubstTypeParam->getReplacedParameter(), Replacement);
       } else if ((AutoTy = dyn_cast<AutoType>(T)) && AutoTy->isDeduced()) {
         // 'auto' types behave the same way as template parameters.
         QualType Deduced = AutoTy->getDeducedType();
@@ -6410,8 +6409,9 @@ QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
 
   // Always canonicalize the replacement type.
   Replacement = SemaRef.Context.getCanonicalType(Replacement);
-  QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
-      T->getReplacedParameter(), Replacement, T->getPackIndex());
+  QualType Result
+    = SemaRef.Context.getSubstTemplateTypeParmType(T->getReplacedParameter(),
+                                                   Replacement);
 
   // Propagate type-source information.
   SubstTemplateTypeParmTypeLoc NewTL

diff  --git a/clang/test/AST/ast-dump-template-decls.cpp b/clang/test/AST/ast-dump-template-decls.cpp
index bc0f2211820e3..13050eee7aeda 100644
--- a/clang/test/AST/ast-dump-template-decls.cpp
+++ b/clang/test/AST/ast-dump-template-decls.cpp
@@ -136,13 +136,13 @@ template <typename... Cs> struct foo {
 };
 using t1 = foo<int, short>::bind<char, float>;
 // CHECK:      TemplateSpecializationType 0x{{[^ ]*}} 'Y<char, float, int, short>' sugar Y
-// CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'char' sugar pack_index 0
+// CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'char' sugar
 // CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack
-// CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar pack_index 1
+// CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar
 // CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack
-// CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar pack_index 2
+// CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar
 // CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack
-// CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'short' sugar pack_index 3
+// CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'short' sugar
 // CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack
 
 template <typename... T> struct D {
@@ -152,13 +152,13 @@ using t2 = D<float, char>::B<int, short>;
 // CHECK:      TemplateSpecializationType 0x{{[^ ]*}} 'B<int, short>' sugar alias B
 // CHECK:      FunctionProtoType 0x{{[^ ]*}} 'int (int (*)(float, int), int (*)(char, short))' cdecl
 // CHECK:      FunctionProtoType 0x{{[^ ]*}} 'int (float, int)' cdecl
-// CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar pack_index 0
+// CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar
 // CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'T' dependent contains_unexpanded_pack depth 0 index 0 pack
-// CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar pack_index 0
+// CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar
 // CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'U' dependent contains_unexpanded_pack depth 0 index 0 pack
 // CHECK:      FunctionProtoType 0x{{[^ ]*}} 'int (char, short)' cdecl
-// CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'char' sugar pack_index 1
+// CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'char' sugar
 // CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'T' dependent contains_unexpanded_pack depth 0 index 0 pack
-// CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'short' sugar pack_index 1
+// CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'short' sugar
 // CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'U' dependent contains_unexpanded_pack depth 0 index 0 pack
 } // namespace PR56099

diff  --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp
index d553eecbc7f44..d9b7883119345 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -4793,44 +4793,6 @@ TEST_P(ASTImporterOptionSpecificTestBase,
       ToD2->getDeclContext(), ToD2->getTemplateParameters()->getParam(0)));
 }
 
-TEST_P(ASTImporterOptionSpecificTestBase, ImportSubstTemplateTypeParmType) {
-  constexpr auto Code = R"(
-    template <class A1, class... A2> struct A {
-      using B = A1(A2...);
-    };
-    template struct A<void, char, float, int, short>;
-    )";
-  Decl *FromTU = getTuDecl(Code, Lang_CXX11, "input.cpp");
-  auto *FromClass = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
-      FromTU, classTemplateSpecializationDecl());
-
-  auto testType = [&](ASTContext &Ctx, const char *Name,
-                      llvm::Optional<unsigned> PackIndex) {
-    const auto *Subst = selectFirst<SubstTemplateTypeParmType>(
-        "sttp", match(substTemplateTypeParmType(
-                          hasReplacementType(hasCanonicalType(asString(Name))))
-                          .bind("sttp"),
-                      Ctx));
-    const char *ExpectedTemplateParamName = PackIndex ? "A2" : "A1";
-    ASSERT_TRUE(Subst);
-    ASSERT_EQ(Subst->getReplacedParameter()->getIdentifier()->getName(),
-              ExpectedTemplateParamName);
-    ASSERT_EQ(Subst->getPackIndex(), PackIndex);
-  };
-  auto tests = [&](ASTContext &Ctx) {
-    testType(Ctx, "void", None);
-    testType(Ctx, "char", 0);
-    testType(Ctx, "float", 1);
-    testType(Ctx, "int", 2);
-    testType(Ctx, "short", 3);
-  };
-
-  tests(FromTU->getASTContext());
-
-  ClassTemplateSpecializationDecl *ToClass = Import(FromClass, Lang_CXX11);
-  tests(ToClass->getASTContext());
-}
-
 const AstTypeMatcher<SubstTemplateTypeParmPackType>
     substTemplateTypeParmPackType;
 


        


More information about the cfe-commits mailing list