summaryrefslogtreecommitdiff
path: root/tools/dump_hirfile/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/dump_hirfile/main.cpp')
-rw-r--r--tools/dump_hirfile/main.cpp327
1 files changed, 327 insertions, 0 deletions
diff --git a/tools/dump_hirfile/main.cpp b/tools/dump_hirfile/main.cpp
new file mode 100644
index 00000000..47436950
--- /dev/null
+++ b/tools/dump_hirfile/main.cpp
@@ -0,0 +1,327 @@
+#include <hir/hir.hpp>
+#include <hir/item_path.hpp>
+#include <hir/main_bindings.hpp>
+#include <macro_rules/macro_rules.hpp>
+#include <mir/mir.hpp>
+#include <mir/operations.hpp> // MIR_Dump_Fcn
+
+int g_debug_indent_level = 0;
+
+struct Args
+{
+ Args(int argc, const char* const argv[]);
+
+ ::std::string infile;
+};
+
+struct Dumper
+{
+ struct Filters {
+ struct Types {
+ bool macros = true;
+ bool functions = true;
+ bool statics = true;
+ bool types = true;
+ bool traits = true;
+ } types;
+ bool public_only = false;
+ bool no_body = false;
+ } filters;
+
+ void dump_crate(const char* name, const ::HIR::Crate& crate) const;
+ void dump_module(::HIR::ItemPath ip, const ::HIR::Publicity& pub, const ::HIR::Module& mod) const;
+ void dump_function(::HIR::ItemPath ip, const ::HIR::Publicity& pub, const ::HIR::Function& fcn, int indent=0) const;
+ void dump_trait(::HIR::ItemPath ip, const ::HIR::Publicity& pub, const ::HIR::Trait& trait, int indent=0) const;
+};
+
+int main(int argc, const char* argv[])
+{
+ Args args(argc, argv);
+ Dumper dumper;
+
+ dumper.filters.types.functions = true;
+
+ auto hir = HIR_Deserialise(args.infile);
+ dumper.dump_crate("", *hir);
+}
+namespace {
+ template<typename T, typename Fcn>
+ void dump_impl_group(const ::HIR::Crate::ImplGroup<T>& ig, Fcn cb)
+ {
+ for(const auto& named_il : ig.named)
+ {
+ for(const auto& impl : named_il.second)
+ {
+ cb(*impl);
+ }
+ }
+ for(const auto& impl : ig.non_named)
+ {
+ cb(*impl);
+ }
+ for(const auto& impl : ig.generic)
+ {
+ cb(*impl);
+ }
+ }
+}
+void Dumper::dump_crate(const char* name, const ::HIR::Crate& crate) const
+{
+ // Dump macros
+ for(const auto& mac : crate.m_exported_macros)
+ {
+ ::std::cout << "macro_rules! " << mac.first << "{" << std::endl;
+ for(const auto& arm : mac.second->m_rules)
+ {
+ ::std::cout << " (";
+ for(const auto& pat : arm.m_pattern)
+ {
+ TU_MATCH_HDRA( (pat), {)
+ TU_ARMA(End, e)
+ ::std::cout << " EOS";
+ TU_ARMA(LoopStart, e)
+ ::std::cout << " (";
+ TU_ARMA(LoopNext, e)
+ ::std::cout << " ^";
+ TU_ARMA(LoopEnd, e)
+ ::std::cout << " )";
+ TU_ARMA(Jump, e)
+ ::std::cout << " <" << e.jump_target;
+ TU_ARMA(ExpectTok, e)
+ ::std::cout << " =" << e;
+ TU_ARMA(ExpectPat, e)
+ ::std::cout << " " << e.idx << "=" << e.type;
+ TU_ARMA(If, e) {
+ ::std::cout << " ?" << (e.is_equal ? "" : "!") << "{";
+ for(const auto& ent : e.ents) {
+ if(ent.ty == MacroPatEnt::PAT_TOKEN)
+ ::std::cout << " =" << ent.tok;
+ else
+ ::std::cout << " " << ent.ty;
+ }
+ ::std::cout << "}->" << e.jump_target;
+ }
+ }
+ }
+ ::std::cout << " ) => {\n";
+ // TODO: Macro expansion
+ ::std::cout << " }\n";
+ }
+ ::std::cout << "}\n";
+ ::std::cout << ::std::endl;
+ }
+
+ this->dump_module(::HIR::ItemPath(name), ::HIR::Publicity::new_global(), crate.m_root_module);
+
+ for(const auto& i : crate.m_trait_impls)
+ {
+ dump_impl_group(i.second, [&](const ::HIR::TraitImpl& ti) {
+ auto root_ip = ::HIR::ItemPath(ti.m_type, i.first, ti.m_trait_args);
+ ::std::cout << "impl" << ti.m_params.fmt_args() << " " << i.first << ti.m_trait_args << " for " << ti.m_type << "\n";
+ ::std::cout << " where" << ti.m_params.fmt_bounds() << "\n";
+ ::std::cout << "{" << ::std::endl;
+ if( this->filters.types.functions )
+ {
+ for(const auto& m : ti.m_methods)
+ {
+ this->dump_function(root_ip + m.first, ::HIR::Publicity::new_global(), m.second.data, 1);
+ }
+ }
+ ::std::cout << "}" << ::std::endl;
+ });
+ }
+
+ dump_impl_group(crate.m_type_impls, [&](const auto& i) {
+ auto root_ip = ::HIR::ItemPath(i.m_type);
+ ::std::cout << "impl" << i.m_params.fmt_args() << " " << i.m_type << "\n";
+ ::std::cout << " where" << i.m_params.fmt_bounds() << "\n";
+ ::std::cout << "{" << ::std::endl;
+ if( this->filters.types.functions )
+ {
+ for(const auto& m : i.m_methods)
+ {
+ this->dump_function(root_ip + m.first, ::HIR::Publicity::new_global(), m.second.data, 1);
+ }
+ }
+ ::std::cout << "}" << ::std::endl;
+ });
+}
+void Dumper::dump_module(::HIR::ItemPath ip, const ::HIR::Publicity& pub, const ::HIR::Module& mod) const
+{
+ if( filters.public_only && !pub.is_global() )
+ {
+ return ;
+ }
+ ::std::cout << "// mod " << ip << ::std::endl;
+ for(const auto& i : mod.m_mod_items)
+ {
+ auto sub_ip = ip + i.first;
+ //::std::cout << "// " << i.second->ent.tagstr() << " " << sub_ip << "\n";
+ TU_MATCH_HDRA( (i.second->ent), {)
+ TU_ARMA(Module, e) {
+ this->dump_module(sub_ip, i.second->publicity, e);
+ }
+ TU_ARMA(Import, e) {
+ //this->dump_mod_import(sub_ip, e);
+ }
+ TU_ARMA(TypeAlias, e) {
+ //this->dump_type_alias(sub_ip, e);
+ }
+ TU_ARMA(ExternType, e) {
+ //this->dump_ext_type(sub_ip, e);
+ }
+ TU_ARMA(Enum, e) {
+ //this->dump_enum(sub_ip, e);
+ }
+ TU_ARMA(Struct, e) {
+ //this->dump_enum(sub_ip, e);
+ }
+ TU_ARMA(Union, e) {
+ //this->dump_trait(sub_ip, e);
+ }
+ TU_ARMA(Trait, e) {
+ this->dump_trait(sub_ip, i.second->publicity, e);
+ }
+ }
+ }
+ for(const auto& i : mod.m_value_items)
+ {
+ auto sub_ip = ip + i.first;
+ //::std::cout << "// " << i.second->ent.tagstr() << " " << sub_ip << "\n";
+ TU_MATCH_HDRA( (i.second->ent), {)
+ TU_ARMA(Import, e) {
+ //this->dump_val_import(sub_ip, e);
+ }
+ TU_ARMA(Constant, e) {
+ //this->dump_constant(sub_ip, e);
+ }
+ TU_ARMA(Static, e) {
+ //this->dump_constant(sub_ip, e);
+ }
+ TU_ARMA(StructConstant, e) {
+ //this->dump_constant(sub_ip, e);
+ }
+ TU_ARMA(StructConstructor, e) {
+ //this->dump_constant(sub_ip, e);
+ }
+ TU_ARMA(Function, e) {
+ this->dump_function(sub_ip, i.second->publicity, e);
+ }
+ }
+ }
+}
+void Dumper::dump_function(::HIR::ItemPath ip, const ::HIR::Publicity& pub, const ::HIR::Function& fcn, int nindent/*=0*/) const
+{
+ auto indent = RepeatLitStr { " ", nindent };
+ if( !this->filters.types.functions ) {
+ return ;
+ }
+ if( filters.public_only && !pub.is_global() ) {
+ return ;
+ }
+ ::std::cout << indent << "fn " << ip << fcn.m_params.fmt_args() << "(";
+ ::std::cout << " )";
+ if( fcn.m_code.m_mir )
+ {
+ ::std::cout << "\n";
+ ::std::cout << indent << "{\n";
+ if( filters.no_body ) {
+ ::std::cout << indent << "...\n";
+ }
+ else {
+ MIR_Dump_Fcn(::std::cout, *fcn.m_code.m_mir, nindent+1);
+ }
+ ::std::cout << indent << "}\n";
+ ::std::cout << ::std::endl;
+ }
+ else
+ {
+ ::std::cout << ";" << ::std::endl;
+ }
+}
+void Dumper::dump_trait(::HIR::ItemPath ip, const ::HIR::Publicity& pub, const ::HIR::Trait& trait, int nindent/*=0*/) const
+{
+ auto indent = RepeatLitStr { " ", nindent };
+ if( !this->filters.types.functions ) {
+ return ;
+ }
+ if( !filters.public_only && !pub.is_global() ) {
+ return ;
+ }
+ ::std::cout << indent << "trait " << ip << trait.m_params.fmt_args() << "\n";
+ ::std::cout << indent << "{\n";
+ auto indent2 = RepeatLitStr { " ", nindent+1 };
+ // ...
+ ::std::cout << indent << "}\n";
+ ::std::cout << ::std::endl;
+}
+
+bool debug_enabled()
+{
+ return false;
+}
+::std::ostream& debug_output(int indent, const char* function)
+{
+ return ::std::cout << "- " << RepeatLitStr { " ", indent } << function << ": ";
+}
+
+Args::Args(int argc, const char* const argv[])
+{
+ this->infile = argv[1];
+}
+
+// TODO: This is copy-pasted from src/main.cpp, should live somewhere better
+::std::ostream& operator<<(::std::ostream& os, const FmtEscaped& x)
+{
+ os << ::std::hex;
+ for(auto s = x.s; *s != '\0'; s ++)
+ {
+ switch(*s)
+ {
+ case '\0': os << "\\0"; break;
+ case '\n': os << "\\n"; break;
+ case '\\': os << "\\\\"; break;
+ case '"': os << "\\\""; break;
+ default:
+ uint8_t v = *s;
+ if( v < 0x80 )
+ {
+ if( v < ' ' || v > 0x7F )
+ os << "\\u{" << ::std::hex << (unsigned int)v << "}";
+ else
+ os << v;
+ }
+ else if( v < 0xC0 )
+ ;
+ else if( v < 0xE0 )
+ {
+ uint32_t val = (uint32_t)(v & 0x1F) << 6;
+ v = (uint8_t)*++s; if( (v & 0xC0) != 0x80 ) { s--; continue ; } val |= (uint32_t)v << 6;
+ os << "\\u{" << ::std::hex << val << "}";
+ }
+ else if( v < 0xF0 )
+ {
+ uint32_t val = (uint32_t)(v & 0x0F) << 12;
+ v = (uint8_t)*++s; if( (v & 0xC0) != 0x80 ) { s--; continue ; } val |= (uint32_t)v << 12;
+ v = (uint8_t)*++s; if( (v & 0xC0) != 0x80 ) { s--; continue ; } val |= (uint32_t)v << 6;
+ os << "\\u{" << ::std::hex << val << "}";
+ }
+ else if( v < 0xF8 )
+ {
+ uint32_t val = (uint32_t)(v & 0x07) << 18;
+ v = (uint8_t)*++s; if( (v & 0xC0) != 0x80 ) { s--; continue ; } val |= (uint32_t)v << 18;
+ v = (uint8_t)*++s; if( (v & 0xC0) != 0x80 ) { s--; continue ; } val |= (uint32_t)v << 12;
+ v = (uint8_t)*++s; if( (v & 0xC0) != 0x80 ) { s--; continue ; } val |= (uint32_t)v << 6;
+ os << "\\u{" << ::std::hex << val << "}";
+ }
+ break;
+ }
+ }
+ os << ::std::dec;
+ return os;
+}
+
+MIR::EnumCachePtr::~EnumCachePtr()
+{
+ assert(!this->p);
+}