On Wed, Oct 3, 2018 at 7:11 PM Marek Polacek <[email protected]> wrote:
>
> On Wed, Oct 03, 2018 at 10:24:52AM -0400, Jason Merrill wrote:
> > On Tue, Oct 2, 2018 at 5:25 PM Marek Polacek <[email protected]> wrote:
> > >
> > > On Mon, Oct 01, 2018 at 07:47:10PM -0400, Jason Merrill wrote:
> > > > On Mon, Oct 1, 2018 at 6:41 PM Marek Polacek <[email protected]> wrote:
> > > > >
> > > > > This patch implements C++20 explicit(bool), as described in:
> > > > > <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0892r2.html>.
> > > > >
> > > > > I tried to follow the noexcept specifier implementation where I
> > > > > could, which
> > > > > made the non-template parts of this fairly easy. To make
> > > > > explicit(expr) work
> > > > > with dependent expressions, I had to add DECL_EXPLICIT_SPEC to
> > > > > lang_decl_fn,
> > > > > which serves as a vessel to get the explicit-specifier to
> > > > > tsubst_function_decl
> > > > > where I substitute the dependent arguments.
> > > >
> > > > What's the impact of that on memory consumption? I'm nervous about
> > > > adding another word to most functions when it's not useful to most of
> > > > them. For several similar things we've been using hash tables on the
> > > > side.
> > >
> > > Yeah, that is a fair concern. I'm not sure if I know of a good way to
> > > measure
> > > it. I took wide-int.ii and ran /usr/bin/time -v ./cc1plus; then it's
> > > roughly
> > > Maximum resident set size (kbytes): 95020
> > > vs.
> > > Maximum resident set size (kbytes): 95272
> > > which doesn't seem too bad but I don't know if it proves anything.
> > >
> > > If we went with the hash table, would it work like this?
> > > 1) have a hash table mapping decls (key) to explicit-specifiers
> > > 2) instead of setting DECL_EXPLICIT_SPEC put the parsed explicit-specifier
> > > into the table
> > > 3) in tsubst_function_decl look if the fn decl is associated with any
> > > explicit-specifier, if it is, substitute it, and set
> > > DECL_NONCONVERTING_P
> > > accordingly.
> >
> > Yes. I think you want to use tree_cache_map so you don't have to
> > worry about removing entries from the table if the decl is GC'd.
>
> Done (along with the bit idea).
It occurs to me that it might be better to put all these sorts of
things in DECL_ATTRIBUTES instead, but that's definitely a question
for another day.
> + /* [dcl.fct.spec]
> + "the constant-expression, if supplied, shall be a contextually
> + converted constant expression of type bool." */
> + expr = build_explicit_specifier (expr, tf_warning_or_error);
> + /* We could evaluate it -- mark the decl as appropriate. */
> + if (expr == boolean_true_node)
> + set_and_check_decl_spec_loc (decl_specs, ds_explicit, token);
> + else if (explicit_specifier)
> + /* The expression was value-dependent. Remember it so that we can
> + substitute it later. */
> + *explicit_specifier = expr;
What if expr == boolean_false_node?
> + /* Handle explicit(dependent-expr). */
> + if (DECL_HAS_DEPENDENT_EXPLICIT_SPEC_P (t))
> + {
> + tree spec = lookup_explicit_specifier (t);
> + spec = tsubst_copy_and_build (spec, args, complain, in_decl,
> + /*function_p=*/false,
> + /*i_c_e_p=*/true);
> + spec = build_explicit_specifier (spec, complain);
> + DECL_NONCONVERTING_P (t) = (spec == boolean_true_node);
> + }
What if spec is still dependent, e.g. after partial substitution of a
member template?
Jason