On Sun, Jan 22, 2017 at 6:06 PM, Alexandre Oliva <aol...@redhat.com> wrote:
> On Jan 13, 2017, Jason Merrill <ja...@redhat.com> wrote:
>
>> On 09/23/2016 08:41 PM, Alexandre Oliva wrote:
>>> +static tree global_friend_list;
>
>> This should be a hash_set rather than a TREE_LIST.
>
> You sure?  At least in the libcc1 use scenario, this is going to have a
> single entry.  I didn't even have to make it a list, but I made it one
> because, well, I could :-)  A hash_set seems excessive, unless you
> envision other uses for it.

Well, in general TREE_LISTs are discouraged nowadays in favor of
hash_sets or VECs.  If it's a single entry, putting it there alone is
fine too.

>>> +  // FIXME: we need a more space-efficient representation for
>>> +  // oracle_looked_up.
>
>> A hash_set would work for that, too.
>
> I was hoping for an unused bit in IDENTIFIERs, but I guess that will do.
> I'm a bit concerned about the performance impact of this in all name
> lookups, though.  Just computing the hash for every lookup seems
> excessive, compared with testing a bit.  Unless...  I guess making it a
> hash_set*, NULL unless there is an Oracle, would alleviate this concern,
> making it cost only when it's in use.

Sounds good.

>>> +/* Exported wrapper for cp_literal_operator_id.  */
>>> +
>>> +tree
>>> +ansi_litopname (const char *name)
>>> +{
>>> +  return cp_literal_operator_id (name);
>>> +}
>
>> Why not export cp_literal_operator_id itself?
>
> My sense of aesthetics demanded a uniform set of exported names along
> with ansi_opname and ansi_assopname ;-)

Heh.  But I'd prefer to unify them in the other direction; use of
"ansi" is obsolete.

>>> +   If the newly-created namespace is to be an inline namespace, after
>>> +   push_namespace, get the nested namespace decl with
>>> +   get_current_binding_level, pop back to the enclosing namespace,
>>> +   call using_namespace with INLINE_P, and then push to the inline
>>> +   namespace again.  */
>
>> This seems like unnecessary contortions to expect of the caller
>> (i.e. GDB).  Let's add a new front end function to handle this.
>
> Heh, it's really nothing compared with some other contortions required
> to navigate binding levels, e.g. to reenter a function scope.
>
> I didn't want to add redundant functionality to the libcc1 API, and we'd
> need the ability to separate the introduction or reentry in a namespace,
> from a using directive with attribute strong.  And since inline
> namespaces use the same implementation as that, I figured it made sense
> to use the same interface for both.

> Besides, push_namespace is called a lot more often than using_namespace,
> so it makes sense to keep it simpler, and leave the extra parameter for
> the less common operation.
>
> Another argument to keep things as they are is that the inline-ness of a
> namespace is not a property related with entering the namespace, but
> rather with how names from it are brought into the other namespace.

Well, it's a property of the namespace.  But I guess I won't insist on this.

>>> +     As a general rule, before we can declare or define any local name
>>> +     with a discriminator, we have to at least declare any other
>>> +     occurrences of the same name in the same enclosing entity with
>>> +     lower or absent discriminator.
>
>> This seems unfortunate, wouldn't it be better to allow the plugin to
>> specify the discriminator directly?
>
> That would have required a major reworking of the internal handling of
> such discriminators, and it didn't seem worth the effort and risk of
> pushback, considering that libcc1 already requires all occurrences of a
> name to be defined at once.

Fair enough.

>>> +   Just entering the scope of the class containing member function f
>>> +   reactivates the names of its members, including the class name
>>> +   itself.  */
>
>> Does it reactivate the names of other declarations in scope in the
>> enclosing function, e.g. static local variables?
>
> My understanding is that anything local needs explicit reactivation when
> reentering a function scope.  That makes sense and is helpful for us,
> given that a local scope is not always a single scope; unlike namespace
> and class scopes, there could be multiple scopes within a function
> scope, and each would have a different set of active names.  The client
> has to select the active names upon function reentry.

OK.

>>> +/* Pop the namespace last entered with push_namespace, or class last
>>> +   entered with push_class, or function last entered with
>>> +   push_function, restoring the binding level in effect before the
>>> +   matching push_* call.  */
>>> +
>>> +GCC_METHOD0 (int /* bool */, pop_namespace)
>
>> This should have a different name, perhaps pop_last_entered_scope?
>
> It was introduced very early on, long before the need for exposing
> function scopes was realized and implemented.  GDB (branch) already had
> plenty of code using this primitive, so I didn't want to rename it, but
> if you insist in such spelling changes, I won't mind, and I guess GDB
> folks won't even.  It's not too late yet ;-)

Please.

>>> +/* Return the NAMESPACE_DECL, TYPE_DECL or FUNCTION_DECL of the
>>> +   binding level that would be popped by pop_namespace.  */
>>> +
>>> +GCC_METHOD0 (gcc_decl, get_current_binding_level)
>
>> Perhaps get_current_binding_level_decl?
>
> Ditto, except I'm not sure GDB already uses this one, so it's probably a
> much easier sell.

Please.

>>> +   The TARGET decl names the qualifying scope (foo:: above) and the
>>> +   identifier (bar), but that does not mean that only TARGET will be
>>> +   brought into the current scope: all bindings of TARGET's identifier
>>> +   in the qualifying scope will be brought in.
>
>> This seems wrong; for namespace-scope using-declarations, only the
>> declarations in scope at the point of the using-declaration are
>> imported.  Since DWARF represents each imported declaration
>> individually, I would think that we would want the plugin to import
>> them one at a time.
>
> What you say is true, but GCC doesn't offer functionality for that
> AFAICT, and the caller can always arrange for only the bindings that
> should be brought in by the using declarations to be defined at the time
> the using declaration is introduced, so I left it at that so as to
> minimize the changes to GCC proper.

Fair enough, but then why pass a decl?  Passing scope and identifier
would seem cleaner if that's what you mean.

>>> For operator functions, set GCC_CP_FLAG_SPECIAL_FUNCTION in
>>> +   SYM_KIND, in addition to any other applicable flags, and pass as
>>> +   NAME a string starting with the two-character mangling for operator
>>> +   name
>
>> Perhaps the compiler side should handle this transparently?
>
> Sorry, I don't understand what you're suggesting.  Can you please
> elaborate?

I mean have the compiler recognize that the name is magic and infer
that it's a special function.

>>> +/* Supply the ADDRESS of one of the multiple clones of constructor or
>>> +   destructor CDTOR.  The clone is selected using the following
>>> +   name mangling conventions:
>
>> The comment doesn't say what argument NAME should be.
>
> Fixed thusly:
>
>    The clone is The clone is specified by NAME, using the following name
>    mangling conventions

Without the duplicate "The clone is", I hope? :)

>>> +   The [CD]4 manglings (and symbol definitions) are non-standard, but
>>> +   GCC uses them in some cases: rather than assuming they are
>>> +   in-charge or not-in-charge, they test the implicit argument that
>>> +   the others ignore to tell how to behave.  These are defined in very
>>> +   rare cases of virtual inheritance and cdtor prototypes.  */
>
>> These are used instead of cloning when we can't just use aliases.
>
> You mean this should go in instead of 'These are defined in ...', right?

Yes.

>>> +GCC_METHOD5 (gcc_type, new_template_typename_parm,
>
>> s/typename/type/
>
> The purpose behind this choice was to avoid the unwanted "template type"
> grouping.  I figured "typename" would convey the correct concept, even
> before the "new_template_*_parm" pattern could be formed.  Hmm...  I
> wonder if I should have made it new_*_template_parm instead...

Sure, that would be even better.

>>> +GCC_METHOD2 (gcc_type, new_dependent_typespec,
>
>> "typespec" usually means type-specifier.
>
> Oops ;-)
>
>> How about new_dependent_type_template_id?
>
> Or new_dependent[_template]_specialization?  I think I'd rather use the
> term 'specialization' because I've used it in other primitives and in
> the documentation, whereas it would be the only use of 'id'.

Well, a template-id is the syntactic term for combining a template
name and some template arguments, which seems like what this function
is doing.  A template-id names a specialization, but isn't quite the
same.

>>> +GCC_METHOD5 (gcc_expr, new_dependent_value_expr,
>
>> I don't think you need "value" here.  Nor in the other *_value_expr names.
>
> That was to distinguish it from type expressions.  I was concerned it
> could be misused to construct

I don't know what you mean by "type expressions".

>>> +/* Build a gcc_expr that denotes the conversion of an expression list
>>> +   VALUES to TYPE, with ("tl") or without ("cv") braces, or a braced
>>> +   initializer list of unspecified type (e.g., a component of another
>>> +   braced initializer list; pass "il" for CONV_OP, and NULL for
>>> +   TYPE).  */
>
>>> +GCC_METHOD3 (gcc_expr, values_expr,
>
>> Hmm, it seems like you're conflating two things here: the expressions,
>> and the conversions.  I'd suggest functional_cast_expr, but handling a
>> plain braced-init-list through the same interface is surprising.
>
> The reason they ended up in the same spot is that I grouped the various
> kinds of expressions according to the meta-types of the operands, so all
> of the expressions that took a list of expressions (values), with or
> without a type, ended up in the same API entry point.

Hmm, OK.  Maybe expression_list_expr?

>>> +GCC_METHOD4 (gcc_expr, alloc_expr,
>
>> new_expr?
>
> new_ would be confusing, for it was used as a prefix for entry points
> that introduce new classes, new fields, etc.
>
>> This leads me to notice that some of the entry points start with
>> "new_", some start with "build_", and some have no prefix.  Is this
>> intentional?
>
> The 'build_' ones were inherited from the libcc1 API for C.  The major
> API departure from C's build_decl made me rename it to new_decl, and
> then I followed the new_ pattern when introducing other names.  IOW, no
> strong reasons, just ones that offer insights into the development
> history of the API.  I guess we could change them all to build_, and use
> new_ for alloc_expr, but I'm hesitant, because of the inconvenience this
> might cause to the GDB folks that may have already got used to this
> admittedly inconsistent convention.

Better to fix an inconsistent API now than leave it to confuse future
developers, I would think.

Jason

Reply via email to