]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: simplify member template substitution
authorJason Merrill <jason@redhat.com>
Tue, 2 May 2023 18:54:46 +0000 (14:54 -0400)
committerJason Merrill <jason@redhat.com>
Tue, 2 May 2023 22:53:06 +0000 (18:53 -0400)
I noticed that for member class templates of a class template we were
unnecessarily substituting both the template and its type.  Avoiding that
duplication speeds compilation of this silly testcase from ~12s to ~9s on my
laptop.  It's unlikely to make a difference on any real code, but the
simplification is also nice.

We still need to clear CLASSTYPE_USE_TEMPLATE on the partial instantiation
of the template class, but it makes more sense to do that in
tsubst_template_decl anyway.

  #define NC(X) \
    template <class U> struct X##1; \
    template <class U> struct X##2; \
    template <class U> struct X##3; \
    template <class U> struct X##4; \
    template <class U> struct X##5; \
    template <class U> struct X##6;
  #define NC2(X) NC(X##a) NC(X##b) NC(X##c) NC(X##d) NC(X##e) NC(X##f)
  #define NC3(X) NC2(X##A) NC2(X##B) NC2(X##C) NC2(X##D) NC2(X##E)
  template <int I> struct A
  {
    NC3(am)
  };
  template <class...Ts> void sink(Ts...);
  template <int...Is> void g()
  {
    sink(A<Is>()...);
  }
  template <int I> void f()
  {
    g<__integer_pack(I)...>();
  }
  int main()
  {
    f<1000>();
  }

gcc/cp/ChangeLog:

* pt.cc (instantiate_class_template): Skip the RECORD_TYPE
of a class template.
(tsubst_template_decl): Clear CLASSTYPE_USE_TEMPLATE.

gcc/cp/pt.cc

index 3f1cf139bbd82fa87bacf34ad603f57f8705835c..471fc20bc5b9ae1cfb7ccc114d89fbb1db56832a 100644 (file)
@@ -12285,21 +12285,13 @@ instantiate_class_template (tree type)
                   Ignore it; it will be regenerated when needed.  */
                continue;
 
-             bool class_template_p = (TREE_CODE (t) != ENUMERAL_TYPE
-                                      && TYPE_LANG_SPECIFIC (t)
-                                      && CLASSTYPE_IS_TEMPLATE (t));
-
-             /* If the member is a class template, then -- even after
-                substitution -- there may be dependent types in the
-                template argument list for the class.  We increment
-                PROCESSING_TEMPLATE_DECL so that dependent_type_p, as
-                that function will assume that no types are dependent
-                when outside of a template.  */
-             if (class_template_p)
-               ++processing_template_decl;
+             /* If the member is a class template, we've
+                already substituted its type.  */
+             if (CLASS_TYPE_P (t)
+                 && CLASSTYPE_IS_TEMPLATE (t))
+               continue;
+
              tree newtag = tsubst (t, args, tf_error, NULL_TREE);
-             if (class_template_p)
-               --processing_template_decl;
              if (newtag == error_mark_node)
                continue;
 
@@ -12307,19 +12299,6 @@ instantiate_class_template (tree type)
                {
                  tree name = TYPE_IDENTIFIER (t);
 
-                 if (class_template_p)
-                   /* Unfortunately, lookup_template_class sets
-                      CLASSTYPE_IMPLICIT_INSTANTIATION for a partial
-                      instantiation (i.e., for the type of a member
-                      template class nested within a template class.)
-                      This behavior is required for
-                      maybe_process_partial_specialization to work
-                      correctly, but is not accurate in this case;
-                      the TAG is not an instantiation of anything.
-                      (The corresponding TEMPLATE_DECL is an
-                      instantiation, but the TYPE is not.) */
-                   CLASSTYPE_USE_TEMPLATE (newtag) = 0;
-
                  /* Now, install the tag.  We don't use pushtag
                     because that does too much work -- creating an
                     implicit typedef, which we've already done.  */
@@ -14750,7 +14729,10 @@ tsubst_template_decl (tree t, tree args, tsubst_flags_t complain,
       /* For a partial specialization, we need to keep pointing to
         the primary template.  */
       if (!DECL_TEMPLATE_SPECIALIZATION (t))
-       CLASSTYPE_TI_TEMPLATE (inner) = r;
+       {
+         CLASSTYPE_TI_TEMPLATE (inner) = r;
+         CLASSTYPE_USE_TEMPLATE (inner) = 0;
+       }
 
       DECL_TI_ARGS (r) = CLASSTYPE_TI_ARGS (inner);
       inner = TYPE_MAIN_DECL (inner);