diff options
author | Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> | 2023-07-11 14:41:33 +0200 |
---|---|---|
committer | P-E-P <32375388+P-E-P@users.noreply.github.com> | 2023-07-19 14:31:42 +0000 |
commit | 04c9af6d0f2d38504a5add30c44a348a91af4b57 (patch) | |
tree | 1b983541310108d0ad0639c6376e538d8db9131d /gcc | |
parent | 9378b267776a6cca2b1ea4545cc9e101e302e049 (diff) | |
download | gcc-04c9af6d0f2d38504a5add30c44a348a91af4b57.zip gcc-04c9af6d0f2d38504a5add30c44a348a91af4b57.tar.gz gcc-04c9af6d0f2d38504a5add30c44a348a91af4b57.tar.bz2 |
proc_macro: Add from string implementation
Add a callback registration function into the proc macro library so the
compiler can register it's own lexing/parsing functions on load.
gcc/rust/ChangeLog:
* expand/rust-proc-macro.cc (tokenstream_from_string): Add a
function that creates a tokenstream from a given string.
(load_macros_array): Add call to registration function.
ChangeLog:
* libgrust/libproc_macro/proc_macro.cc (proc_macro_register_from_str):
Add registration function.
* libgrust/libproc_macro/proc_macro.h (proc_macro_register_from_str):
Add registration function prototype.
* libgrust/libproc_macro/tokenstream.cc (TokenStream::make_tokenstream):
Add a new constructor from a string that uses the registered
callback.
(TokenStream__from_string): Add call to new constructor.
* libgrust/libproc_macro/tokenstream.h: Add registration
declaration.
* libgrust/libproc_macro/registration.h: New file.
Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/expand/rust-proc-macro.cc | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/gcc/rust/expand/rust-proc-macro.cc b/gcc/rust/expand/rust-proc-macro.cc index b68486e..6ba87b6 100644 --- a/gcc/rust/expand/rust-proc-macro.cc +++ b/gcc/rust/expand/rust-proc-macro.cc @@ -16,6 +16,8 @@ #include "rust-diagnostics.h" #include "rust-proc-macro.h" +#include "rust-lex.h" +#include "rust-token-converter.h" #ifndef _WIN32 #include <dlfcn.h> #endif @@ -24,6 +26,60 @@ namespace Rust { const std::string PROC_MACRO_DECL_PREFIX = "__gccrs_proc_macro_decls_"; +ProcMacro::TokenStream +tokenstream_from_string (std::string &data, bool &lex_error) +{ + // FIXME: Insert location pointing to call site in tokens + Lexer lex (data); + + std::vector<const_TokenPtr> tokens; + TokenPtr ptr; + for (ptr = lex.build_token (); + ptr != nullptr && ptr->get_id () != END_OF_FILE; + ptr = lex.build_token ()) + { + tokens.emplace_back (ptr); + } + + if (ptr == nullptr) + { + lex_error = true; + return ProcMacro::TokenStream::make_tokenstream (); + } + + lex_error = false; + return convert (tokens); +} + +static_assert ( + std::is_same<decltype (tokenstream_from_string) *, + ProcMacro::from_str_function_t>::value, + "Registration callback signature not synced, check proc macro internals."); + +template <typename Symbol, typename Callback> +bool +register_callback (void *handle, Symbol, std::string symbol_name, + Callback callback) +{ + void *addr = dlsym (handle, symbol_name.c_str ()); + if (addr == nullptr) + { + rust_error_at (Location (), + "Callback registration symbol (%s) missing from " + "proc macro, wrong version?", + symbol_name.c_str ()); + return false; + } + + auto storage = reinterpret_cast<Symbol *> (addr); + *storage = callback; + + return true; +} + +#define REGISTER_CALLBACK(HANDLE, SYMBOL, CALLBACK) \ + register_callback (HANDLE, SYMBOL, #SYMBOL, CALLBACK) + const ProcMacro::ProcmacroArray * load_macros_array (std::string path) { @@ -36,6 +92,10 @@ load_macros_array (std::string path) return nullptr; } + if (!REGISTER_CALLBACK (handle, __gccrs_pm_callback_from_str_fn, + tokenstream_from_string)) + return nullptr; + // FIXME: Add CrateStableId handling, right now all versions may be loaded, // even incompatible ones. return *reinterpret_cast<const ProcMacro::ProcmacroArray **> ( @@ -47,6 +107,8 @@ load_macros_array (std::string path) #endif } +#undef REGISTER_CALLBACK + const std::vector<ProcMacro::Procmacro> load_macros (std::string path) { |