On Sat, 13 Dec 2025, Jason Merrill wrote:

> On 12/12/25 10:39 PM, Patrick Palka wrote:
> > We currently have 7 different tag_types, but our TYPENAME_TYPE
> > representation only differentiates between four of them:
> > class/enum/union/typename.  This patch makes our representation and
> > cache of TYPENAME_TYPE remember the tag_type fully so that later
> > substitution/resolution of the TYPENAME_TYPE is sound.
> 
> What do you mean by "sound"?  This only makes a difference for
> -Wmismatched-tags, right?

True for record_type vs class_type which we now differentiate.

But I there's also scope_type tag_type which our current representation
of TYPENAME_TYPE can't encode, and so we effectively encode as
none_type.  But scope_type indicates a type-only lookup context unlike
none_type.

So building a TYPENAME_TYPE with tag_type=scope_type and then resolving
it (i.e. build_typename_type + make_typename_type) is different from
just doing the lookup immediately (i.e. just make_typename_type)
because we don't know the lookup is type-only anymore.

> 
> > +/* Set the tag type of the given TYPENAME_TYPE.  */
> > +
> > +inline void
> > +set_typename_tag_type (tree t, tag_types tag)
> > +{
> 
> Maybe assert that 'tag' fits in 3 bits?
> 
> > +  TYPENAME_TYPE_TAG_BIT_0 (t) = (tag >> 0) & 1;
> > +  TYPENAME_TYPE_TAG_BIT_1 (t) = (tag >> 1) & 1;
> > +  TYPENAME_TYPE_TAG_BIT_2 (t) = (tag >> 2) & 1;
> > +}
> > +
> >   /* The various kinds of lvalues we distinguish.  */
> >   enum cp_lvalue_kind_flags {
> >     clk_none = 0,     /* Things that are not an lvalue.  */
> > diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc
> > index ae899ec9f770..1359aaab7229 100644
> > --- a/gcc/cp/error.cc
> > +++ b/gcc/cp/error.cc
> > @@ -824,7 +824,7 @@ dump_type (cxx_pretty_printer *pp, tree t, int flags)
> >         pp_cxx_cv_qualifier_seq (pp, t);
> >         pp_cxx_ws_string (pp,
> >                      TYPENAME_IS_ENUM_P (t) ? "enum"
> > -                    : TYPENAME_IS_CLASS_P (t) ? "class"
> > +                    : TYPENAME_IS_CLASS_OR_STRUCT_P (t) ? "class"
> >                      : TYPENAME_IS_UNION_P (t) ? "union"
> >                      : "typename");
> 
> If we're going to represent struct vs class, let's also print it here.
> 
> Jason
> 
> 

Reply via email to