diff options
author | Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> | 2023-10-04 18:48:04 +0200 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2024-01-16 19:09:33 +0100 |
commit | 4ad869fadaf93bb2aee92c40da98ed011449b45a (patch) | |
tree | 3b25b39163bf5fde9beadf98a5df71a43a0b0ac5 /gcc/rust/backend | |
parent | c0a7f3e67a428affcd508eb272034fceb7f2841f (diff) | |
download | gcc-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.cc | 162 |
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 ¯o : 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 ¯o : 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 ¯o : 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 ( |