On Wed, Jan 21, 2026 at 06:36:46PM +0800, Jason Merrill wrote:
> On 1/21/26 3:58 AM, Marek Polacek wrote:
> > On Fri, Jan 09, 2026 at 01:27:44PM +0800, Jason Merrill wrote:
> > > On 1/9/26 3:24 AM, Marek Polacek wrote:
> > > > On Tue, Dec 16, 2025 at 10:48:40PM +0700, Jason Merrill wrote:
> > > > > On 11/15/25 8:36 AM, Marek Polacek wrote:
> > > > > > +/* Process std::meta::is_user_provided.
> > > > > > +   Returns: true if r represents a function that is user-provided.
> > > > > > +   Otherwise, false.  */
> > > > > > +
> > > > > > +static tree
> > > > > > +eval_is_user_provided (tree r)
> > > > > > +{
> > > > > > +  r = maybe_get_reflection_fndecl (r);
> > > > > > +  if (TREE_CODE (r) == FUNCTION_DECL
> > > > > > +      && user_provided_p (r)
> > > > > > +      // TODO: user_provided_p is false for non-members defaulted 
> > > > > > on
> > > > > > +      // first declaration.
> > > > > 
> > > > > Maybe we could set DECL_INITIALIZED_IN_CLASS_P for non-member 
> > > > > functions, too
> > > > > (and probably rename it).
> > > > 
> > > > I suppose, but I'd rather not do it as part of the Reflection patch.
> > > 
> > > Fair...
> > > 
> > > > > > +      && (!DECL_NAMESPACE_SCOPE_P (r) || !DECL_DELETED_FN (r)))
> > > 
> > > ...but then I'd rather not halfway work around the issue in the reflection
> > > patch, either.
> > 
> > I'm a little worried about changing DECL_INITIALIZED_IN_CLASS_P in
> > stage 4.  What if I opened an internal-improvement PR for this?
> 
> Actually I think we don't need to mess with DECL_INITIALIZED_IN_CLASS_P,
> because any function deleted after its first declaration is ill-formed
> rather than user-provided.
> 
> void f();
> void f() = delete; // error, not first declaration
> 
> so we can just fix user_provided_p.

Ah, I see now.  Patch posted:
<https://gcc.gnu.org/pipermail/gcc-patches/2026-January/706482.html>

> > > > > > +  if (TREE_CODE (r) == CONST_DECL)
> > > > > > +    return boolean_true_node;
> > > > > > +  else
> > > > > > +    return boolean_false_node;
> > > > > > +}
> > > > > > +
> > > > > > +/* Process std::meta::has_internal_linkage.
> > > > > > +   Returns: true if r represents a variable, function, type, 
> > > > > > template, or
> > > > > > +   namespace whose name has internal linkage.  Otherwise, false.  
> > > > > > */
> > > > > > +
> > > > > > +static tree
> > > > > > +eval_has_internal_linkage (tree r, reflect_kind kind)
> > > > > > +{
> > > > > > +  if (eval_is_variable (r, kind) == boolean_false_node
> > > > > > +      && eval_is_function (r) == boolean_false_node
> > > > > > +      && eval_is_type (r) == boolean_false_node
> > > > > > +      && eval_is_template (r) == boolean_false_node
> > > > > > +      && eval_is_namespace (r) == boolean_false_node)
> > > > > > +    return boolean_false_node;
> > > > > > +  r = maybe_get_reflection_fndecl (r);
> > > > > > +  r = STRIP_TEMPLATE (r);
> > > > > > +  if (TYPE_P (r))
> > > > > > +    {
> > > > > > +      if (TYPE_NAME (r) == NULL_TREE
> > > > > > +     || !DECL_P (TYPE_NAME (r))
> > > > > > +     || (!DECL_IMPLICIT_TYPEDEF_P (TYPE_NAME (r))
> > > > > > +         && TYPE_NAME (r) == TYPE_NAME (TYPE_MAIN_VARIANT (r))
> > > > > > +         && !TYPE_MAIN_DECL (r)))
> > > > > 
> > > > > It seems simpler to go directly to TYPE_NAME (TYPE_MAIN_VARIANT (r)) 
> > > > > to find
> > > > > the name with linkage, and probably also check OVERLOAD_TYPE_P.
> > > > 
> > > > I didn't understand this.
> > > 
> > > I was thinking type_linkage_name would be
> > > 
> > > if (!OVERLOAD_TYPE_P (t))
> > >    return NULL_TREE;
> > > return TYPE_NAME (TYPE_MAIN_VARIANT (t));
> > 
> > That breaks:
> > 
> >    struct cls { };
> >    using alias = cls;
> >    template<typename> struct cls_tmpl {};
> >    template<typename T> using cls_tmpl_alias = cls_tmpl<T>;
> > 
> >    static_assert (!has_linkage (^^alias));
> >    static_assert (!has_linkage (^^cls_tmpl_alias<int>));
> > 
> > Currently, for a RECORD_TYPE alias we return a TYPE_DECL alias,
> > but with this patch we return a TYPE_DECL cls (and same for the
> > alias template case).
> 
> Ah, so type_linkage_name isn't a great name, since what it does is specific
> to reflection alias handling.  What it does is filter out types with no
> name, a non-DECL name (which is probably unnecessary, such types shouldn't
> be exposed to user code), and typedefs for linkage purposes.
> 
> It seems clearer to return null for all typedef_variant_p rather than just
> for typedefs for linkage purposes.
> 
> So,
> 
> if (OVERLOAD_TYPE_P (t)
>     && !typedef_variant_p (t))
>   return TYPE_NAME (t);
> return NULL_TREE;

Patch posted:
<https://gcc.gnu.org/pipermail/gcc-patches/2026-January/706481.html>

Marek

Reply via email to