[C++ PATCH] __builtin_source_location ()
David Malcolm
dmalcolm@redhat.com
Fri Nov 15 14:05:00 GMT 2019
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...]
More information about the Gcc-patches
mailing list