On Wed, Oct 3, 2018 at 7:11 PM Marek Polacek <pola...@redhat.com> 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 <pola...@redhat.com> 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 <pola...@redhat.com> 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