On Fri, 2019-11-15 at 13:28 +0100, Jakub Jelinek wrote: > On Thu, Nov 14, 2019 at 08:34:26PM +0100, Jakub Jelinek wrote: > > The following WIP patch implements __builtin_source_location (), > > which returns const void pointer to a std::source_location::__impl > > struct that is required to contain __file, __function, __line and > > __column > > fields, the first two with const char * type, the latter some > > integral type. > > Here is hopefully final version, with the hashing implemented, > __file renamed to __file_name and __function to __function_name to > match > how the standard names the methods and with testsuite coverage. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
[...snip...] > --- gcc/cp/cp-gimplify.c.jj 2019-11-15 00:37:14.511247252 +0100 > +++ gcc/cp/cp-gimplify.c 2019-11-15 11:23:50.574203292 +0100 [...] > @@ -2868,4 +2883,246 @@ process_stmt_hotness_attribute (tree std > return std_attrs; > } > > +/* Helper of fold_builtin_source_location, return the > + std::source_location::__impl type after performing verification > + on it. */ > + > +static tree > +get_source_location_impl (location_t loc) > +{ FWIW, I found this function confusing at first, and wondered what the purpose of LOC was (given that the function is building a type, rather than an instance of that type). Maybe add this to the leading comment: "LOC is used for reporting any errors." (and if so, perhaps replace the various "error" with "error_at", though that's rather academic). Maybe rename the function to "get_source_location_impl_type" to emphasize the distinction? Hope this is constructive Dave > + tree name = get_identifier ("source_location"); > + tree decl = lookup_qualified_name (std_node, name); > + if (TREE_CODE (decl) != TYPE_DECL) > + { > + auto_diagnostic_group d; > + if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST) > + qualified_name_lookup_error (std_node, name, decl, loc); > + else > + error ("%qD is not a type", decl); > + return error_mark_node; > + } > + name = get_identifier ("__impl"); > + tree type = TREE_TYPE (decl); > + decl = lookup_qualified_name (type, name); > + if (TREE_CODE (decl) != TYPE_DECL) > + { > + auto_diagnostic_group d; > + if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST) > + qualified_name_lookup_error (type, name, decl, loc); > + else > + error ("%qD is not a type", decl); > + return error_mark_node; > + } > + type = TREE_TYPE (decl); > + if (TREE_CODE (type) != RECORD_TYPE) > + { > + error ("%qD is not a class type", decl); > + return error_mark_node; > + } > + > + int cnt = 0; > + for (tree field = TYPE_FIELDS (type); > + (field = next_initializable_field (field)) != NULL_TREE; > + field = DECL_CHAIN (field)) > + { > + if (DECL_NAME (field) != NULL_TREE) > + { > + const char *n = IDENTIFIER_POINTER (DECL_NAME (field)); > + if (strcmp (n, "__file_name") == 0 > + || strcmp (n, "__function_name") == 0) > + { > + if (TREE_TYPE (field) != const_string_type_node) > + { > + error ("%qD does not have %<const char *%> type", > field); > + return error_mark_node; > + } > + cnt++; > + continue; > + } > + else if (strcmp (n, "__line") == 0 || strcmp (n, "__column") > == 0) > + { > + if (TREE_CODE (TREE_TYPE (field)) != INTEGER_TYPE) > + { > + error ("%qD does not have integral type", field); > + return error_mark_node; > + } > + cnt++; > + continue; > + } > + } > + cnt = 0; > + break; > + } > + if (cnt != 4) > + { > + error ("%<std::source_location::__impl%> does not contain only > " > + "non-static data members %<__file_name%>, > %<__function_name%>, " > + "%<__line%> and %<__column%>"); > + return error_mark_node; > + } > + return build_qualified_type (type, TYPE_QUAL_CONST); > +} [...snip...]