From 52d872b36d7fda733273d70100d21b16506f1647 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 11 Jun 2017 11:34:16 +0800 Subject: Parse - Support chaining of spans (for macro expansions) --- src/macro_rules/eval.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/macro_rules/eval.cpp') diff --git a/src/macro_rules/eval.cpp b/src/macro_rules/eval.cpp index 18ef563e..1bac45ee 100644 --- a/src/macro_rules/eval.cpp +++ b/src/macro_rules/eval.cpp @@ -618,9 +618,9 @@ bool Macro_TryPatternCap(TokenStream& lex, MacroPatEnt::Type type) switch(type) { case MacroPatEnt::PAT_TOKEN: - BUG(lex.getPosition(), ""); + BUG(lex.point_span(), ""); case MacroPatEnt::PAT_LOOP: - BUG(lex.getPosition(), ""); + BUG(lex.point_span(), ""); case MacroPatEnt::PAT_BLOCK: return LOOK_AHEAD(lex) == TOK_BRACE_OPEN || LOOK_AHEAD(lex) == TOK_INTERPOLATED_BLOCK; case MacroPatEnt::PAT_IDENT: @@ -651,7 +651,7 @@ bool Macro_TryPatternCap(TokenStream& lex, MacroPatEnt::Type type) case MacroPatEnt::PAT_ITEM: return is_token_item( LOOK_AHEAD(lex) ); } - BUG(lex.getPosition(), ""); + BUG(lex.point_span(), "Fell through"); } bool Macro_TryPattern(TokenStream& lex, const MacroPatEnt& pat) { @@ -680,9 +680,9 @@ InterpolatedFragment Macro_HandlePatternCap(TokenStream& lex, MacroPatEnt::Type switch(type) { case MacroPatEnt::PAT_TOKEN: - BUG(lex.getPosition(), "Encountered PAT_TOKEN when handling capture"); + BUG(lex.point_span(), "Encountered PAT_TOKEN when handling capture"); case MacroPatEnt::PAT_LOOP: - BUG(lex.getPosition(), "Encountered PAT_LOOP when handling capture"); + BUG(lex.point_span(), "Encountered PAT_LOOP when handling capture"); case MacroPatEnt::PAT_TT: if( GET_TOK(tok, lex) == TOK_EOF ) -- cgit v1.2.3 From b3af24cd9e3715097997c8215f82f1184586f542 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 11 Jun 2017 21:03:45 +0800 Subject: Expand - Make file!/line! get the invocation location of a macro --- src/expand/file_line.cpp | 17 ++++++++++++++--- src/expand/macro_rules.cpp | 5 ----- src/expand/macro_rules.hpp | 2 -- src/expand/mod.cpp | 5 +++-- src/macro_rules/eval.cpp | 15 +++++++++++---- src/macro_rules/macro_rules.hpp | 2 +- 6 files changed, 29 insertions(+), 17 deletions(-) (limited to 'src/macro_rules/eval.cpp') diff --git a/src/expand/file_line.cpp b/src/expand/file_line.cpp index 8dfb7e6d..7e117993 100644 --- a/src/expand/file_line.cpp +++ b/src/expand/file_line.cpp @@ -9,12 +9,23 @@ #include "../parse/common.hpp" #include "../parse/ttstream.hpp" +namespace { + const Span& get_top_span(const Span& sp) { + if( sp.outer_span ) { + return get_top_span(*sp.outer_span); + } + else { + return sp; + } + } +} + class CExpanderFile: public ExpandProcMacro { ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override { - return box$( TTStreamO(TokenTree(Token(TOK_STRING, sp.filename.c_str()))) ); + return box$( TTStreamO(TokenTree(Token(TOK_STRING, get_top_span(sp).filename.c_str()))) ); } }; @@ -23,7 +34,7 @@ class CExpanderLine: { ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override { - return box$( TTStreamO(TokenTree(Token((uint64_t)sp.start_line, CORETYPE_U32))) ); + return box$( TTStreamO(TokenTree(Token((uint64_t)get_top_span(sp).start_line, CORETYPE_U32))) ); } }; @@ -32,7 +43,7 @@ class CExpanderColumn: { ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override { - return box$( TTStreamO(TokenTree(Token((uint64_t)sp.start_ofs, CORETYPE_U32))) ); + return box$( TTStreamO(TokenTree(Token((uint64_t)get_top_span(sp).start_ofs, CORETYPE_U32))) ); } }; diff --git a/src/expand/macro_rules.cpp b/src/expand/macro_rules.cpp index 338edd12..0375f430 100644 --- a/src/expand/macro_rules.cpp +++ b/src/expand/macro_rules.cpp @@ -169,11 +169,6 @@ class CMacroReexportHandler: } }; -::std::unique_ptr Macro_Invoke(const char* name, const MacroRules& rules, TokenTree tt, AST::Module& mod) -{ - return Macro_InvokeRules(name, rules, mv$(tt), mod); -} - STATIC_MACRO("macro_rules", CMacroRulesExpander); STATIC_DECORATOR("macro_use", CMacroUseHandler); diff --git a/src/expand/macro_rules.hpp b/src/expand/macro_rules.hpp index b5f09f1c..00332dd5 100644 --- a/src/expand/macro_rules.hpp +++ b/src/expand/macro_rules.hpp @@ -12,5 +12,3 @@ namespace AST { class TokenTree; class TokenStream; class MacroRules; - -extern ::std::unique_ptr Macro_Invoke(const char* name, const MacroRules& rules, TokenTree tt, AST::Module& mod); diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index 38e40347..5c3be722 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -11,6 +11,7 @@ #include #include #include "macro_rules.hpp" +#include "../macro_rules/macro_rules.hpp" #include "../parse/common.hpp" // For reparse from macros #include #include "cfg.hpp" @@ -115,7 +116,7 @@ void Expand_Attrs(::AST::MetaItems& attrs, AttrStage stage, ::AST::Crate& crate if( input_ident != "" ) ERROR(mi_span, E0000, "macro_rules! macros can't take an ident"); - auto e = Macro_Invoke(name.c_str(), *mr.data, mv$(input_tt), mod); + auto e = Macro_InvokeRules(name.c_str(), *mr.data, mi_span, mv$(input_tt), mod); return e; } } @@ -134,7 +135,7 @@ void Expand_Attrs(::AST::MetaItems& attrs, AttrStage stage, ::AST::Crate& crate } if( last_mac ) { - auto e = Macro_Invoke(name.c_str(), *last_mac, mv$(input_tt), mod); + auto e = Macro_InvokeRules(name.c_str(), *last_mac, mi_span, mv$(input_tt), mod); return e; } } diff --git a/src/macro_rules/eval.cpp b/src/macro_rules/eval.cpp index 1bac45ee..fffe9b68 100644 --- a/src/macro_rules/eval.cpp +++ b/src/macro_rules/eval.cpp @@ -577,6 +577,7 @@ class MacroExpander: const RcString m_macro_filename; const ::std::string m_crate_name; + ::std::shared_ptr m_invocation_span; ParameterMappings m_mappings; MacroExpandState m_state; @@ -588,9 +589,10 @@ class MacroExpander: public: MacroExpander(const MacroExpander& x) = delete; - MacroExpander(const ::std::string& macro_name, const Ident::Hygiene& parent_hygiene, const ::std::vector& contents, ParameterMappings mappings, ::std::string crate_name): + MacroExpander(const ::std::string& macro_name, const Span& sp, const Ident::Hygiene& parent_hygiene, const ::std::vector& contents, ParameterMappings mappings, ::std::string crate_name): m_macro_filename( FMT("Macro:" << macro_name) ), m_crate_name( mv$(crate_name) ), + m_invocation_span( new Span(sp) ), m_mappings( mv$(mappings) ), m_state( contents, m_mappings ), m_hygiene( Ident::Hygiene::new_scope_chained(parent_hygiene) ) @@ -598,6 +600,7 @@ public: } Position getPosition() const override; + ::std::shared_ptr outerSpan() const override; Ident::Hygiene realGetHygiene() const override; Token realGetToken() override; }; @@ -722,7 +725,7 @@ InterpolatedFragment Macro_HandlePatternCap(TokenStream& lex, MacroPatEnt::Type } /// Parse the input TokenTree according to the `macro_rules!` patterns and return a token stream of the replacement -::std::unique_ptr Macro_InvokeRules(const char *name, const MacroRules& rules, TokenTree input, AST::Module& mod) +::std::unique_ptr Macro_InvokeRules(const char *name, const MacroRules& rules, const Span& sp, TokenTree input, AST::Module& mod) { TRACE_FUNCTION_F("'" << name << "', " << input); @@ -741,7 +744,7 @@ InterpolatedFragment Macro_HandlePatternCap(TokenStream& lex, MacroPatEnt::Type // Run through the expansion counting the number of times each fragment is used Macro_InvokeRules_CountSubstUses(bound_tts, rule.m_contents); - TokenStream* ret_ptr = new MacroExpander(name, rules.m_hygiene, rule.m_contents, mv$(bound_tts), rules.m_source_crate); + TokenStream* ret_ptr = new MacroExpander(name, sp, rules.m_hygiene, rule.m_contents, mv$(bound_tts), rules.m_source_crate); return ::std::unique_ptr( ret_ptr ); } @@ -1065,9 +1068,13 @@ void Macro_InvokeRules_CountSubstUses(ParameterMappings& bound_tts, const ::std: Position MacroExpander::getPosition() const { - // TODO: Return a far better span - invocaion location? + // TODO: Return the attached position of the last fetched token return Position(m_macro_filename, 0, m_state.top_pos()); } +::std::shared_ptr MacroExpander::outerSpan() const +{ + return m_invocation_span; +} Ident::Hygiene MacroExpander::realGetHygiene() const { if( m_ttstream ) diff --git a/src/macro_rules/macro_rules.hpp b/src/macro_rules/macro_rules.hpp index aed0e8ce..2a588a78 100644 --- a/src/macro_rules/macro_rules.hpp +++ b/src/macro_rules/macro_rules.hpp @@ -156,7 +156,7 @@ public: SERIALISABLE_PROTOTYPES(); }; -extern ::std::unique_ptr Macro_InvokeRules(const char *name, const MacroRules& rules, TokenTree input, AST::Module& mod); +extern ::std::unique_ptr Macro_InvokeRules(const char *name, const MacroRules& rules, const Span& sp, TokenTree input, AST::Module& mod); extern MacroRulesPtr Parse_MacroRules(TokenStream& lex); #endif // MACROS_HPP_INCLUDED -- cgit v1.2.3