summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2019-03-23 16:07:27 +0800
committerJohn Hodge <tpg@ucc.asn.au>2019-03-23 16:07:27 +0800
commit129e7c0d3e91ee3fdf6835464bf8ec97f2ffc9a5 (patch)
tree3929492633fba4e55d6616ae598355ac9d0992c1
parente65566c6fcf645f28560b226ab93c9e52bdbf2a7 (diff)
downloadmrust-129e7c0d3e91ee3fdf6835464bf8ec97f2ffc9a5.tar.gz
Tools - add a hacky crate metadata dump tool (macros only currently)
-rw-r--r--tools/dump_hirfile/Makefile56
-rw-r--r--tools/dump_hirfile/main.cpp128
2 files changed, 184 insertions, 0 deletions
diff --git a/tools/dump_hirfile/Makefile b/tools/dump_hirfile/Makefile
new file mode 100644
index 00000000..10fb8e81
--- /dev/null
+++ b/tools/dump_hirfile/Makefile
@@ -0,0 +1,56 @@
+#
+ifeq ($(OS),Windows_NT)
+ EXESUF ?= .exe
+endif
+EXESUF ?=
+
+V ?= @
+
+OBJDIR := .obj/
+
+BIN := ../bin/dump_hirfile$(EXESUF)
+OBJS := main.o
+OBJS += debug.o rc_string.o span.o ident.o
+OBJS += parse/parseerror.o # Why is this needed? ast/path.cpp uses it in binding
+OBJS += hir/hir.o hir/type.o hir/deserialise.o hir/serialise_lowlevel.o
+OBJS += hir/crate_ptr.o hir/generic_params.o hir/path.o hir/pattern.o hir/expr_ptr.o
+OBJS += hir/expr.o # Why is this needed?
+OBJS += parse/token.o parse/tokentree.o parse/tokenstream.o
+OBJS += ast/ast.o ast/expr.o ast/path.o ast/types.o ast/pattern.o
+OBJS += mir/mir.o mir/mir_ptr.o
+OBJS += macro_rules/mod.o
+
+LINKFLAGS := -g -lpthread -lz
+CXXFLAGS := -Wall -std=c++14 -g -O2
+CXXFLAGS += -I ../common -I ../../src -I ../../src/include
+
+OBJS := $(OBJS:%=$(OBJDIR)%)
+
+.PHONY: all clean
+
+all: $(BIN)
+
+clean:
+ rm $(BIN) $(OBJS)
+
+$(BIN): $(OBJS) ../bin/common_lib.a
+ @mkdir -p $(dir $@)
+ @echo [CXX] -o $@
+ $V$(CXX) -o $@ $(OBJS) ../bin/common_lib.a $(LINKFLAGS)
+
+$(OBJDIR)%.o: %.cpp
+ @mkdir -p $(dir $@)
+ @echo [CXX] $<
+ $V$(CXX) -o $@ -c $< $(CXXFLAGS) -MMD -MP -MF $@.dep
+
+$(OBJDIR)%.o: ../../src/%.cpp
+ @mkdir -p $(dir $@)
+ @echo [CXX] $<
+ $V$(CXX) -o $@ -c $< $(CXXFLAGS) -MMD -MP -MF $@.dep
+
+../bin/common_lib.a: $(wildcard ../common/*.* ../common/Makefile)
+ make -C ../common
+
+-include $(OBJS:%.o=%.o.dep)
+
+
diff --git a/tools/dump_hirfile/main.cpp b/tools/dump_hirfile/main.cpp
new file mode 100644
index 00000000..df3e48df
--- /dev/null
+++ b/tools/dump_hirfile/main.cpp
@@ -0,0 +1,128 @@
+#include <hir/hir.hpp>
+#include <hir/main_bindings.hpp>
+#include <macro_rules/macro_rules.hpp>
+
+int g_debug_indent_level = 0;
+
+struct Args
+{
+ Args(int argc, const char* const argv[]);
+
+ ::std::string infile;
+};
+
+int main(int argc, const char* argv[])
+{
+ Args args(argc, argv);
+
+ auto hir = HIR_Deserialise(args.infile, "");
+
+ // Dump macros
+ for(const auto& mac : hir->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 << " ) => {" << ::std::endl;
+ // TODO...
+ ::std::cout << " }" << ::std::endl;
+ }
+ ::std::cout << "}" << ::std::endl;
+ ::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;
+}