diff --git a/include/asm/fstack.hpp b/include/asm/fstack.hpp index 81011242..5811938e 100644 --- a/include/asm/fstack.hpp +++ b/include/asm/fstack.hpp @@ -42,7 +42,7 @@ struct FileStackNode { FileStackNode(FileStackNodeType type_, std::variant, std::string> data_) : type(type_), data(data_){}; - void dump(uint32_t curLineNo) const; + std::string const &dump(uint32_t curLineNo) const; }; #define DEFAULT_MAX_DEPTH 64 diff --git a/include/link/main.hpp b/include/link/main.hpp index e7eba9c8..f2ea3cef 100644 --- a/include/link/main.hpp +++ b/include/link/main.hpp @@ -56,7 +56,7 @@ struct FileStackNode { std::string &name(); std::string const &name() const; - std::string const *dumpFileStack() const; + std::string const &dump(uint32_t curLineNo) const; }; void warning(FileStackNode const *where, uint32_t lineNo, char const *fmt, ...) diff --git a/src/asm/fstack.cpp b/src/asm/fstack.cpp index 04d69ede..a1539ede 100644 --- a/src/asm/fstack.cpp +++ b/src/asm/fstack.cpp @@ -12,6 +12,7 @@ #include #include "error.hpp" +#include "helpers.hpp" #include "platform.hpp" // S_ISDIR (stat macro) #include "asm/fstack.hpp" @@ -60,32 +61,28 @@ std::string const &FileStackNode::name() const { return std::get(data); } -static char const *dumpNodeAndParents(FileStackNode const &node) { - char const *name; - - if (node.type == NODE_REPT) { - assert(node.parent); // REPT nodes should always have a parent - std::vector const &nodeIters = node.iters(); - - name = dumpNodeAndParents(*node.parent); - fprintf(stderr, "(%" PRIu32 ") -> %s", node.lineNo, name); - for (uint32_t i = nodeIters.size(); i--;) - fprintf(stderr, "::REPT~%" PRIu32, nodeIters[i]); - } else { - name = node.name().c_str(); - if (node.parent) { - dumpNodeAndParents(*node.parent); - fprintf(stderr, "(%" PRIu32 ") -> %s", node.lineNo, name); - } else { - fputs(name, stderr); - } - } - return name; -} - -void FileStackNode::dump(uint32_t curLineNo) const { - dumpNodeAndParents(*this); +std::string const &FileStackNode::dump(uint32_t curLineNo) const { + std::string const &topName = std::visit(Visitor{ + [this](std::vector const &iters) -> std::string const & { + assert(this->parent); // REPT nodes use their parent's name + std::string const &lastName = this->parent->dump(this->lineNo); + fprintf(stderr, " -> %s", lastName.c_str()); + for (uint32_t i = iters.size(); i--;) + fprintf(stderr, "::REPT~%" PRIu32, iters[i]); + return lastName; + }, + [this](std::string const &name) -> std::string const & { + if (this->parent) { + this->parent->dump(this->lineNo); + fprintf(stderr, " -> %s", name.c_str()); + } else { + fputs(name.c_str(), stderr); + } + return name; + }, + }, data); fprintf(stderr, "(%" PRIu32 ")", curLineNo); + return topName; } void fstk_DumpCurrent() { diff --git a/src/link/main.cpp b/src/link/main.cpp index c46f4992..e164db3f 100644 --- a/src/link/main.cpp +++ b/src/link/main.cpp @@ -65,27 +65,31 @@ std::string const &FileStackNode::name() const { return std::get(data); } -// Helper function to dump a file stack to stderr -std::string const *FileStackNode::dumpFileStack() const { - std::string const *lastName; - - if (parent) { - lastName = parent->dumpFileStack(); - // REPT nodes use their parent's name - if (type != NODE_REPT) - lastName = &name(); - fprintf(stderr, "(%" PRIu32 ") -> %s", lineNo, lastName->c_str()); - if (type == NODE_REPT) { - for (uint32_t iter : iters()) +std::string const &FileStackNode::dump(uint32_t curLineNo) const { + std::string const &topName = std::visit(Visitor{ + [this](std::vector const &iters) -> std::string const & { + assert(this->parent); // REPT nodes use their parent's name + std::string const &lastName = this->parent->dump(this->lineNo); + fprintf(stderr, " -> %s", lastName.c_str()); + for (uint32_t iter : iters) fprintf(stderr, "::REPT~%" PRIu32, iter); - } - } else { - assert(type != NODE_REPT); - lastName = &name(); - fputs(lastName->c_str(), stderr); - } - - return lastName; + return lastName; + }, + [this](std::string const &name) -> std::string const & { + if (this->parent) { + this->parent->dump(this->lineNo); + fprintf(stderr, " -> %s", name.c_str()); + } else { + fputs(name.c_str(), stderr); + } + return name; + }, + [](std::monostate) -> std::string const & { + unreachable_(); // This should not be possible + }, + }, data); + fprintf(stderr, "(%" PRIu32 ")", curLineNo); + return topName; } void printDiag( @@ -94,8 +98,8 @@ void printDiag( fputs(type, stderr); fputs(": ", stderr); if (where) { - where->dumpFileStack(); - fprintf(stderr, "(%" PRIu32 "): ", lineNo); + where->dump(lineNo); + fputs(": ", stderr); } vfprintf(stderr, fmt, args); putc('\n', stderr); diff --git a/src/link/symbol.cpp b/src/link/symbol.cpp index 32c75024..a7f320b6 100644 --- a/src/link/symbol.cpp +++ b/src/link/symbol.cpp @@ -29,10 +29,10 @@ void sym_AddSymbol(Symbol &symbol) { // Check if the symbol already exists if (Symbol *other = sym_GetSymbol(symbol.name); other) { fprintf(stderr, "error: \"%s\" both in %s from ", symbol.name.c_str(), symbol.objFileName); - symbol.src->dumpFileStack(); - fprintf(stderr, "(%" PRIu32 ") and in %s from ", symbol.lineNo, other->objFileName); - other->src->dumpFileStack(); - fprintf(stderr, "(%" PRIu32 ")\n", other->lineNo); + symbol.src->dump(symbol.lineNo); + fprintf(stderr, " and in %s from ", other->objFileName); + other->src->dump(other->lineNo); + fputc('\n', stderr); exit(1); }