Use FileStackNode constructor to avoid std::monostate possibility

This commit is contained in:
Rangi42
2024-03-05 14:19:23 -05:00
parent 74539f08ba
commit bd88787cb3
4 changed files with 42 additions and 68 deletions

View File

@@ -16,21 +16,22 @@
#include "asm/lexer.hpp" #include "asm/lexer.hpp"
struct FileStackNode { struct FileStackNode {
FileStackNode *parent; // Pointer to parent node, for error reporting
// Line at which the parent context was exited; meaningless for the root level
uint32_t lineNo;
bool referenced; // If referenced by a Symbol, Section, or Patch's `src`, don't `delete`!
uint32_t ID; // Set only if referenced: ID within the object file, -1 if not output yet
enum FileStackNodeType type; enum FileStackNodeType type;
std::variant< std::variant<
std::monostate, // Default constructed; `.type` and `.data` must be set manually
std::vector<uint32_t>, // NODE_REPT std::vector<uint32_t>, // NODE_REPT
std::string // NODE_FILE, NODE_MACRO std::string // NODE_FILE, NODE_MACRO
> >
data; data;
FileStackNode *parent; // Pointer to parent node, for error reporting
// Line at which the parent context was exited; meaningless for the root level
uint32_t lineNo;
// If referenced by a Symbol, Section, or Patch's `src`, don't `delete`!
bool referenced = false;
// Set only if referenced: ID within the object file, -1 if not output yet
uint32_t ID = -1;
// REPT iteration counts since last named node, in reverse depth order // REPT iteration counts since last named node, in reverse depth order
std::vector<uint32_t> &iters(); std::vector<uint32_t> &iters();
std::vector<uint32_t> const &iters() const; std::vector<uint32_t> const &iters() const;
@@ -38,6 +39,11 @@ struct FileStackNode {
std::string &name(); std::string &name();
std::string const &name() const; std::string const &name() const;
FileStackNode(
enum FileStackNodeType type_, std::variant<std::vector<uint32_t>, std::string> data_
)
: type(type_), data(data_) {};
void dump(uint32_t curLineNo) const; void dump(uint32_t curLineNo) const;
}; };

View File

@@ -38,10 +38,6 @@ extern bool disablePadding;
} while (0) } while (0)
struct FileStackNode { struct FileStackNode {
FileStackNode *parent;
// Line at which the parent context was exited; meaningless for the root level
uint32_t lineNo;
enum FileStackNodeType type; enum FileStackNodeType type;
std::variant< std::variant<
std::monostate, // Default constructed; `.type` and `.data` must be set manually std::monostate, // Default constructed; `.type` and `.data` must be set manually
@@ -50,6 +46,10 @@ struct FileStackNode {
> >
data; data;
FileStackNode *parent;
// Line at which the parent context was exited; meaningless for the root level
uint32_t lineNo;
// REPT iteration counts since last named node, in reverse depth order // REPT iteration counts since last named node, in reverse depth order
std::vector<uint32_t> &iters(); std::vector<uint32_t> &iters();
std::vector<uint32_t> const &iters() const; std::vector<uint32_t> const &iters() const;

View File

@@ -29,10 +29,10 @@ struct Context {
LexerState lexerState; LexerState lexerState;
uint32_t uniqueID; uint32_t uniqueID;
MacroArgs *macroArgs; // Macro args are *saved* here MacroArgs *macroArgs; // Macro args are *saved* here
uint32_t nbReptIters; uint32_t nbReptIters = 0;
bool isForLoop; bool isForLoop = false;
int32_t forValue; int32_t forValue = 0;
int32_t forStep; int32_t forStep = 0;
std::string forName; std::string forName;
}; };
@@ -108,8 +108,8 @@ FileStackNode *fstk_GetFileStack() {
// Mark node and all of its parents as referenced if not already so they don't get freed // Mark node and all of its parents as referenced if not already so they don't get freed
for (FileStackNode *node = topNode; node && !node->referenced; node = node->parent) { for (FileStackNode *node = topNode; node && !node->referenced; node = node->parent) {
node->ID = -1;
node->referenced = true; node->referenced = true;
node->ID = -1;
} }
return topNode; return topNode;
} }
@@ -200,6 +200,7 @@ bool yywrap() {
fatalerror("Failed to duplicate REPT file node: %s\n", strerror(errno)); fatalerror("Failed to duplicate REPT file node: %s\n", strerror(errno));
// Copy all info but the referencing // Copy all info but the referencing
context.fileInfo->referenced = false; context.fileInfo->referenced = false;
context.fileInfo->ID = -1;
} }
std::vector<uint32_t> &fileInfoIters = context.fileInfo->iters(); std::vector<uint32_t> &fileInfoIters = context.fileInfo->iters();
@@ -255,17 +256,11 @@ static Context &newContext(FileStackNode &fileInfo) {
// Save the current `\@` value, to be restored when this context ends // Save the current `\@` value, to be restored when this context ends
contextStack.top().uniqueID = macro_GetUniqueID(); contextStack.top().uniqueID = macro_GetUniqueID();
FileStackNode *parent = contextStack.top().fileInfo; fileInfo.parent = contextStack.top().fileInfo;
fileInfo.parent = parent;
fileInfo.lineNo = lexer_GetLineNo(); fileInfo.lineNo = lexer_GetLineNo();
fileInfo.referenced = false;
Context &context = contextStack.emplace(); Context &context = contextStack.emplace();
context.fileInfo = &fileInfo; context.fileInfo = &fileInfo;
context.isForLoop = false;
return context; return context;
} }
@@ -283,19 +278,16 @@ void fstk_RunInclude(char const *path) {
return; return;
} }
FileStackNode *fileInfo = new (std::nothrow) FileStackNode(); FileStackNode *fileInfo = new (std::nothrow) FileStackNode(NODE_FILE, *fullPath);
delete fullPath;
if (!fileInfo) { if (!fileInfo) {
error("Failed to alloc file info for INCLUDE: %s\n", strerror(errno)); error("Failed to alloc file info for INCLUDE: %s\n", strerror(errno));
return; return;
} }
fileInfo->type = NODE_FILE;
fileInfo->data = *fullPath;
delete fullPath;
uint32_t uniqueID = contextStack.top().uniqueID; uint32_t uniqueID = contextStack.top().uniqueID;
Context &context = newContext(*fileInfo);
Context &context = newContext(*fileInfo);
if (!lexer_OpenFile(context.lexerState, fileInfo->name().c_str())) if (!lexer_OpenFile(context.lexerState, fileInfo->name().c_str()))
fatalerror("Failed to set up lexer for file include\n"); fatalerror("Failed to set up lexer for file include\n");
lexer_SetStateAtEOL(&context.lexerState); lexer_SetStateAtEOL(&context.lexerState);
@@ -318,18 +310,14 @@ static void runPreIncludeFile() {
return; return;
} }
FileStackNode *fileInfo = new (std::nothrow) FileStackNode(); FileStackNode *fileInfo = new (std::nothrow) FileStackNode(NODE_FILE, *fullPath);
delete fullPath;
if (!fileInfo) { if (!fileInfo) {
error("Failed to alloc file info for pre-include: %s\n", strerror(errno)); error("Failed to alloc file info for pre-include: %s\n", strerror(errno));
return; return;
} }
fileInfo->type = NODE_FILE;
fileInfo->data = *fullPath;
delete fullPath;
Context &context = newContext(*fileInfo); Context &context = newContext(*fileInfo);
if (!lexer_OpenFile(context.lexerState, fileInfo->name().c_str())) if (!lexer_OpenFile(context.lexerState, fileInfo->name().c_str()))
fatalerror("Failed to set up lexer for file include\n"); fatalerror("Failed to set up lexer for file include\n");
lexer_SetState(&context.lexerState); lexer_SetState(&context.lexerState);
@@ -350,18 +338,14 @@ void fstk_RunMacro(char const *macroName, MacroArgs &args) {
} }
contextStack.top().macroArgs = macro_GetCurrentArgs(); contextStack.top().macroArgs = macro_GetCurrentArgs();
FileStackNode *fileInfo = new (std::nothrow) FileStackNode(); FileStackNode *fileInfo = new (std::nothrow) FileStackNode(NODE_MACRO, "");
if (!fileInfo) { if (!fileInfo) {
error("Failed to alloc file info for \"%s\": %s\n", macro->name, strerror(errno)); error("Failed to alloc file info for \"%s\": %s\n", macro->name, strerror(errno));
return; return;
} }
fileInfo->type = NODE_MACRO;
fileInfo->data = "";
// Print the name... // Print the name...
std::string &fileInfoName = fileInfo->name(); std::string &fileInfoName = fileInfo->name();
for (FileStackNode const *node = macro->src; node; node = node->parent) { for (FileStackNode const *node = macro->src; node; node = node->parent) {
if (node->type != NODE_REPT) { if (node->type != NODE_REPT) {
fileInfoName.append(node->name()); fileInfoName.append(node->name());
@@ -384,7 +368,6 @@ void fstk_RunMacro(char const *macroName, MacroArgs &args) {
Context &context = newContext(*fileInfo); Context &context = newContext(*fileInfo);
std::string_view *macroView = macro->getMacro(); std::string_view *macroView = macro->getMacro();
lexer_OpenFileView( lexer_OpenFileView(
context.lexerState, "MACRO", macroView->data(), macroView->size(), macro->fileLine context.lexerState, "MACRO", macroView->data(), macroView->size(), macro->fileLine
); );
@@ -394,18 +377,14 @@ void fstk_RunMacro(char const *macroName, MacroArgs &args) {
} }
static bool newReptContext(int32_t reptLineNo, char const *body, size_t size) { static bool newReptContext(int32_t reptLineNo, char const *body, size_t size) {
uint32_t reptDepth = contextStack.top().fileInfo->type == NODE_REPT FileStackNode *fileInfo = new (std::nothrow) FileStackNode(NODE_REPT, std::vector<uint32_t>{1});
? contextStack.top().fileInfo->iters().size()
: 0;
FileStackNode *fileInfo = new (std::nothrow) FileStackNode();
if (!fileInfo) { if (!fileInfo) {
error("Failed to alloc file info for REPT: %s\n", strerror(errno)); error("Failed to alloc file info for REPT: %s\n", strerror(errno));
return false; return false;
} }
fileInfo->type = NODE_REPT;
fileInfo->data = std::vector<uint32_t>{1}; if (contextStack.top().fileInfo->type == NODE_REPT
if (reptDepth) { && !contextStack.top().fileInfo->iters().empty()) {
// Append all parent iter counts // Append all parent iter counts
fileInfo->iters().insert( fileInfo->iters().insert(
fileInfo->iters().end(), RANGE(contextStack.top().fileInfo->iters()) fileInfo->iters().end(), RANGE(contextStack.top().fileInfo->iters())
@@ -413,13 +392,12 @@ static bool newReptContext(int32_t reptLineNo, char const *body, size_t size) {
} }
Context &context = newContext(*fileInfo); Context &context = newContext(*fileInfo);
// Correct our line number, which currently points to the `ENDR` line // Correct our line number, which currently points to the `ENDR` line
context.fileInfo->lineNo = reptLineNo; context.fileInfo->lineNo = reptLineNo;
lexer_OpenFileView(context.lexerState, "REPT", body, size, reptLineNo); lexer_OpenFileView(context.lexerState, "REPT", body, size, reptLineNo);
lexer_SetStateAtEOL(&context.lexerState); lexer_SetStateAtEOL(&context.lexerState);
context.uniqueID = macro_UseNewUniqueID(); context.uniqueID = macro_UseNewUniqueID();
return true; return true;
} }
@@ -497,28 +475,18 @@ void fstk_NewRecursionDepth(size_t newDepth) {
void fstk_Init(char const *mainPath, size_t maxDepth) { void fstk_Init(char const *mainPath, size_t maxDepth) {
Context &context = contextStack.emplace(); Context &context = contextStack.emplace();
if (!lexer_OpenFile(context.lexerState, mainPath)) if (!lexer_OpenFile(context.lexerState, mainPath))
fatalerror("Failed to open main file\n"); fatalerror("Failed to open main file\n");
lexer_SetState(&context.lexerState); lexer_SetState(&context.lexerState);
FileStackNode *fileInfo = new (std::nothrow) FileStackNode(); context.fileInfo = new (std::nothrow) FileStackNode(NODE_FILE, lexer_GetFileName());
if (!context.fileInfo)
if (!fileInfo)
fatalerror("Failed to allocate memory for main file info: %s\n", strerror(errno)); fatalerror("Failed to allocate memory for main file info: %s\n", strerror(errno));
fileInfo->type = NODE_FILE;
fileInfo->data = lexer_GetFileName();
// lineNo and nbReptIters are unused on the top-level context // lineNo and nbReptIters are unused on the top-level context
fileInfo->parent = nullptr; context.fileInfo->parent = nullptr;
fileInfo->lineNo = 0; // This still gets written to the object file, so init it context.fileInfo->lineNo = 0; // This still gets written to the object file, so init it
fileInfo->referenced = false;
context.fileInfo = fileInfo;
context.uniqueID = macro_UndefUniqueID(); context.uniqueID = macro_UndefUniqueID();
context.nbReptIters = 0;
context.forValue = 0;
context.forStep = 0;
context.isForLoop = false;
maxRecursionDepth = maxDepth; maxRecursionDepth = maxDepth;

View File

@@ -503,10 +503,10 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) {
// Since SDCC does not provide line info, everything will be reported as coming from the // Since SDCC does not provide line info, everything will be reported as coming from the
// object file. It's better than nothing. // object file. It's better than nothing.
nodes[fileID].push_back({ nodes[fileID].push_back({
.parent = nullptr,
.lineNo = 0,
.type = NODE_FILE, .type = NODE_FILE,
.data = fileName, .data = fileName,
.parent = nullptr,
.lineNo = 0,
}); });
std::vector<Symbol> &fileSymbols = symbolLists.emplace_front(); std::vector<Symbol> &fileSymbols = symbolLists.emplace_front();