aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend
diff options
context:
space:
mode:
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>2023-10-04 18:48:04 +0200
committerArthur Cohen <arthur.cohen@embecosm.com>2024-01-16 19:09:33 +0100
commit4ad869fadaf93bb2aee92c40da98ed011449b45a (patch)
tree3b25b39163bf5fde9beadf98a5df71a43a0b0ac5 /gcc/rust/backend
parentc0a7f3e67a428affcd508eb272034fceb7f2841f (diff)
downloadgcc-4ad869fadaf93bb2aee92c40da98ed011449b45a.zip
gcc-4ad869fadaf93bb2aee92c40da98ed011449b45a.tar.gz
gcc-4ad869fadaf93bb2aee92c40da98ed011449b45a.tar.bz2
gccrs: Put common functions in their own namespace
Half of the functions introduced recently had a similar goal while the other half had a similar goal too. Introducing some namespace to separate those will keep the code cleaner and avoid confusion. gcc/rust/ChangeLog: * backend/rust-compile.cc (build_attribute_array): Renamed from... (attribute_array): ...to attribute array. (build_derive_proc_macro): Likewise from... (derive_proc_macro): ... to derive_proc_macro. (build_bang_proc_macro): Likewise from... (bang_proc_macro): ...to bang_proc_macro. (build_attribute_proc_macro): Likewise from... (attribute_proc_macro): ... to attribute_proc_macro. (build_proc_macro_payload): Likewise from... (proc_macro_payload): to proc_macro_payload. (build_proc_macro): Likewise from... (proc_macro): ...to proc_macro. (build_proc_macro_buffer): Likewise from... (proc_macro_buffer): ... to proc_macro_buffer. (build_entrypoint): Likewise from... (entrypoint): ...to entrypoint. (init_derive_proc_macro): Renamed to it's shorter counterpart. (init_attribute_proc_macro): Likewise. (init_bang_proc_macro): Likewise. (init_proc_macro): Likewise. (initialize_proc_macro_array): Likewise. (proc_macro_array): Likewise. (CompileCrate::add_proc_macro_symbols): Update function calls. Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Diffstat (limited to 'gcc/rust/backend')
-rw-r--r--gcc/rust/backend/rust-compile.cc162
1 files changed, 102 insertions, 60 deletions
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index 3aee807..f400d69 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -56,11 +56,23 @@ CompileCrate::go ()
}
// This namespace brings multiple function to build and initialize multiple
-// structures that needs to get exposed in the final shared object binary.
+// structures that needs to get exposed in the final shared library for
+// procedural macro crates.
+//
+// The compiler needs some additional metadata to find which function correspond
+// to the desired macro. The library shall expose one entrypoint symbol leading
+// to those metadata which in turn lead to the correct function.
+// This namespace describes how to build and initialize those metadata
+// structures. Those structure should be kept in sync with the structures in
+// libproc_macro_internal/proc_macro.h describing how they should be read.
namespace {
+// Namespace containing all functions to build the different types.
+namespace build {
+
+// Build an array of attribute type for derive procedural macros.
tree
-build_attribute_array (std::vector<std::string> attributes)
+attribute_array (std::vector<std::string> attributes)
{
tree attribute_ptr = build_pointer_type (char_type_node);
tree attribute_type = build_qualified_type (attribute_ptr, TYPE_QUAL_CONST);
@@ -75,27 +87,26 @@ build_attribute_array (std::vector<std::string> attributes)
// std::uint64_t attr_size;
// TokenStream (fndecl*) (TokenStream);
// }
+// The resulting structure should be the same as `CustomDerive` in proc_macro.h
tree
-build_derive_proc_macro ()
+derive_proc_macro ()
{
tree char_ptr = build_pointer_type (char_type_node);
tree const_char_type = build_qualified_type (char_ptr, TYPE_QUAL_CONST);
- Backend::typed_identifier name_field
- = Backend::typed_identifier ("trait_name", const_char_type,
- BUILTINS_LOCATION);
+ auto name_field = Backend::typed_identifier ("trait_name", const_char_type,
+ BUILTINS_LOCATION);
tree handle_ptr = build_pointer_type (void_type_node);
- Backend::typed_identifier fndecl_field
+ auto fndecl_field
= Backend::typed_identifier ("fndecl", handle_ptr, BUILTINS_LOCATION);
tree attribute_ptr = build_pointer_type (const_ptr_type_node);
- Backend::typed_identifier attributes_field
+ auto attributes_field
= Backend::typed_identifier ("attributes", attribute_ptr,
BUILTINS_LOCATION);
- Backend::typed_identifier size_field
- = Backend::typed_identifier ("attr_size", unsigned_type_node,
- BUILTINS_LOCATION);
+ auto size_field = Backend::typed_identifier ("attr_size", unsigned_type_node,
+ BUILTINS_LOCATION);
return Backend::struct_type (
{name_field, attributes_field, size_field, fndecl_field});
@@ -107,8 +118,9 @@ build_derive_proc_macro ()
// const char *name;
// TokenStream (fndecl*) (TokenStream);
// }
+// The resulting structure should be the same as `Bang` in proc_macro.h
tree
-build_bang_proc_macro ()
+bang_proc_macro ()
{
tree char_ptr = build_pointer_type (char_type_node);
tree const_char_type = build_qualified_type (char_ptr, TYPE_QUAL_CONST);
@@ -131,24 +143,26 @@ build_bang_proc_macro ()
// const char *name;
// TokenStream (fndecl*) (TokenStream, TokenStream);
// }
+// The resulting structure should be the same as `Attribute` in proc_macro.h
tree
-build_attribute_proc_macro ()
+attribute_proc_macro ()
{
- return build_bang_proc_macro ();
+ return bang_proc_macro ();
}
+// Build the union of all macro types. The resulting type should have the exact
+// same representation as `ProcMacroPayload` in proc_macro.h
tree
-build_proc_macro_payload ()
+proc_macro_payload ()
{
- tree bang = build_bang_proc_macro ();
- tree attribute = build_attribute_proc_macro ();
- tree derive = build_derive_proc_macro ();
+ tree bang = bang_proc_macro ();
+ tree attribute = attribute_proc_macro ();
+ tree derive = derive_proc_macro ();
- Backend::typed_identifier bang_field
- = Backend::typed_identifier ("bang", bang, BUILTINS_LOCATION);
- Backend::typed_identifier attribute_field
+ auto bang_field = Backend::typed_identifier ("bang", bang, BUILTINS_LOCATION);
+ auto attribute_field
= Backend::typed_identifier ("attribute", attribute, BUILTINS_LOCATION);
- Backend::typed_identifier derive_field
+ auto derive_field
= Backend::typed_identifier ("custom_derive", derive, BUILTINS_LOCATION);
// We rely on the tag to represent the index of any union member. This means
@@ -164,53 +178,75 @@ build_proc_macro_payload ()
return Backend::union_type (fields);
}
-// Build the tagged union proc macro type
+// Build the tagged union proc macro type. This type contains a payload as well
+// as a tag to identify the contained member of the payload.
//
// struct {
// unsigned short tag;
// union { BangProcMacro , DeriveProcMacro, AttributeProcMacro} payload;
// }
tree
-build_proc_macro ()
+proc_macro ()
{
- auto union_field = build_proc_macro_payload ();
- Backend::typed_identifier payload_field
+ auto union_field = proc_macro_payload ();
+ auto payload_field
= Backend::typed_identifier ("payload", union_field, BUILTINS_LOCATION);
- Backend::typed_identifier tag_field
- = Backend::typed_identifier ("tag", short_unsigned_type_node,
- BUILTINS_LOCATION);
+ auto tag_field = Backend::typed_identifier ("tag", short_unsigned_type_node,
+ BUILTINS_LOCATION);
return Backend::struct_type ({tag_field, payload_field});
}
+// Build the `ProcmacroArray` structure
+//
+// struct {
+// std::uint64_t length;
+// Procmacro * macros;
+// }
tree
-build_proc_macro_buffer (tree proc_macro_type, size_t total_macro)
+proc_macro_buffer (tree proc_macro_type, size_t total_macro)
{
+ // FIXME: Add the array length, build a structure containing an array
return build_array_type_nelts (proc_macro_type, total_macro);
}
+// The entrypoint of a proc macro crate is a reference to the proc macro buffer
+// `ProcmacroArray` defined in proc_macro.h
tree
-build_entrypoint (tree proc_macro_buffer)
+entrypoint (tree proc_macro_buffer)
{
return build_reference_type_for_mode (proc_macro_buffer, E_VOIDmode, false);
}
+} // namespace build
+
+// Functions to init all proc macro trees with the correct values from some
+// macro information
+namespace init {
+
+// Initialize a derive proc macro structure
+// - Store the trait name
+// - Initialize the attribute array
+// - Store the attribute array size
+// - Store the address of the function
tree
-init_derive_proc_macro (Context *ctx, CustomDeriveInfo infos)
+derive_proc_macro (Context *ctx, CustomDeriveInfo infos)
{
- tree derive_proc_macro_type = build_derive_proc_macro ();
+ tree derive_proc_macro_type = build::derive_proc_macro ();
tree trait_name = build_string_literal (infos.trait_name.c_str ());
tree attribute_ptr;
if (infos.attributes.size () == 0)
{
+ // Set a null pointer if there is no attributes
attribute_ptr = HIRCompileBase::address_expression (null_pointer_node,
BUILTINS_LOCATION);
}
else
{
- tree attribute_array_type = build_attribute_array (infos.attributes);
+ // Initialize the attribute array
+ tree attribute_array_type = build::attribute_array (infos.attributes);
std::vector<tree> attr_ctors;
std::vector<unsigned long> indices;
@@ -255,10 +291,13 @@ init_derive_proc_macro (Context *ctx, CustomDeriveInfo infos)
BUILTINS_LOCATION);
}
+// Initialize an attribute proc macro structure.
+// - Store the name
+// - Store the address of the function
tree
-init_attribute_proc_macro (tree macro)
+attribute_proc_macro (tree macro)
{
- tree attribute_proc_macro_type = build_attribute_proc_macro ();
+ tree attribute_proc_macro_type = build::attribute_proc_macro ();
tree macro_name
= build_string_literal (IDENTIFIER_POINTER (DECL_NAME (macro)));
tree handle = HIRCompileBase::address_expression (macro, BUILTINS_LOCATION);
@@ -269,24 +308,27 @@ init_attribute_proc_macro (tree macro)
BUILTINS_LOCATION);
}
+// Initialize a bang proc macro structure.
+// - Store the name
+// - Store the address of the function
tree
-init_bang_proc_macro (tree macro)
+bang_proc_macro (tree macro)
{
// Attribute and bang proc macros have the same structure, they can be
// initialized with the same code.
- return init_attribute_proc_macro (macro);
+ return attribute_proc_macro (macro);
}
+// Initialize a proc macro structure from a given payload tree
tree
-init_proc_macro (tree payload, tree proc_macro_type,
- ProcMacro::ProcmacroTag tag)
+proc_macro (tree payload, tree proc_macro_type, ProcMacro::ProcmacroTag tag)
{
auto discriminant = static_cast<int> (tag);
tree macro_tag = build_int_cst (short_unsigned_type_node, discriminant);
tree payload_union
- = Backend::constructor_expression (build_proc_macro_payload (), false,
+ = Backend::constructor_expression (build::proc_macro_payload (), false,
{payload},
discriminant /* Union: member index */,
BUILTINS_LOCATION);
@@ -299,36 +341,35 @@ init_proc_macro (tree payload, tree proc_macro_type,
}
tree
-initialize_proc_macro_array (Context *ctx, tree proc_macro_buffer_type,
- tree proc_macro_type)
+proc_macro_array (Context *ctx, tree proc_macro_buffer_type,
+ tree proc_macro_type)
{
std::vector<unsigned long> indexes;
std::vector<tree> ctors;
size_t index = 0;
for (auto &macro : ctx->get_derive_proc_macros ())
{
- tree proc_macro = init_derive_proc_macro (ctx, macro);
- ctors.push_back (
- init_proc_macro (proc_macro, proc_macro_type,
- ProcMacro::ProcmacroTag::CUSTOM_DERIVE));
+ tree derive = derive_proc_macro (ctx, macro);
+ ctors.push_back (proc_macro (derive, proc_macro_type,
+ ProcMacro::ProcmacroTag::CUSTOM_DERIVE));
indexes.push_back (index);
index++;
}
for (auto &macro : ctx->get_attribute_proc_macros ())
{
- tree proc_macro = init_attribute_proc_macro (macro);
+ tree attr = attribute_proc_macro (macro);
- ctors.push_back (init_proc_macro (proc_macro, proc_macro_type,
- ProcMacro::ProcmacroTag::ATTR));
+ ctors.push_back (
+ proc_macro (attr, proc_macro_type, ProcMacro::ProcmacroTag::ATTR));
indexes.push_back (index);
index++;
}
for (auto &macro : ctx->get_bang_proc_macros ())
{
- tree proc_macro = init_bang_proc_macro (macro);
+ tree bang = bang_proc_macro (macro);
- ctors.push_back (init_proc_macro (proc_macro, proc_macro_type,
- ProcMacro::ProcmacroTag::BANG));
+ ctors.push_back (
+ proc_macro (bang, proc_macro_type, ProcMacro::ProcmacroTag::BANG));
indexes.push_back (index);
index++;
}
@@ -336,9 +377,12 @@ initialize_proc_macro_array (Context *ctx, tree proc_macro_buffer_type,
return Backend::array_constructor_expression (proc_macro_buffer_type, indexes,
ctors, BUILTINS_LOCATION);
}
+} // namespace init
} // namespace
+// Gather procedural macros and generate the metadata as well as the entrypoint
+// for a procedural macro crate.
void
CompileCrate::add_proc_macro_symbols ()
{
@@ -346,10 +390,9 @@ CompileCrate::add_proc_macro_symbols ()
+ ctx->get_bang_proc_macros ().size ()
+ ctx->get_derive_proc_macros ().size ();
- tree proc_macro_type = build_proc_macro ();
- tree proc_macro_buffer_type
- = build_proc_macro_buffer (proc_macro_type, total_macros);
- tree entrypoint_type = build_entrypoint (proc_macro_buffer_type);
+ tree pm_type = build::proc_macro ();
+ tree pm_buffer_type = build::proc_macro_buffer (pm_type, total_macros);
+ tree entrypoint_type = build::entrypoint (pm_buffer_type);
std::string decl_symbol_name = generate_proc_macro_decls_symbol (
0 /* FIXME: Change to stable crate id */);
@@ -365,12 +408,11 @@ CompileCrate::add_proc_macro_symbols ()
Bvariable *proc_macro_buffer
= Backend::global_variable (buffer_name.c_str (), buffer_name.c_str (),
- proc_macro_buffer_type, false /* internal */,
+ pm_buffer_type, false /* internal */,
true /* hidden */, false /* no gc */,
BUILTINS_LOCATION);
Backend::global_variable_set_init (
- proc_macro_buffer,
- initialize_proc_macro_array (ctx, proc_macro_buffer_type, proc_macro_type));
+ proc_macro_buffer, init::proc_macro_array (ctx, pm_buffer_type, pm_type));
ctx->push_var (proc_macro_buffer);
Backend::global_variable_set_init (