mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Error messages note when a symbol has been purged (#1453)
This commit is contained in:
@@ -95,6 +95,8 @@ Symbol *sym_Ref(std::string const &symName);
|
|||||||
Symbol *sym_AddString(std::string const &symName, std::shared_ptr<std::string> value);
|
Symbol *sym_AddString(std::string const &symName, std::shared_ptr<std::string> value);
|
||||||
Symbol *sym_RedefString(std::string const &symName, std::shared_ptr<std::string> value);
|
Symbol *sym_RedefString(std::string const &symName, std::shared_ptr<std::string> value);
|
||||||
void sym_Purge(std::string const &symName);
|
void sym_Purge(std::string const &symName);
|
||||||
|
bool sym_IsPurgedExact(std::string const &symName);
|
||||||
|
bool sym_IsPurgedScoped(std::string const &symName);
|
||||||
void sym_Init(time_t now);
|
void sym_Init(time_t now);
|
||||||
|
|
||||||
// Functions to save and restore the current symbol scope.
|
// Functions to save and restore the current symbol scope.
|
||||||
|
|||||||
@@ -333,6 +333,9 @@ void fstk_RunMacro(std::string const ¯oName, std::shared_ptr<MacroArgs> macr
|
|||||||
Symbol *macro = sym_FindExactSymbol(macroName);
|
Symbol *macro = sym_FindExactSymbol(macroName);
|
||||||
|
|
||||||
if (!macro) {
|
if (!macro) {
|
||||||
|
if (sym_IsPurgedExact(macroName))
|
||||||
|
error("Macro \"%s\" not defined; it was purged\n", macroName.c_str());
|
||||||
|
else
|
||||||
error("Macro \"%s\" not defined\n", macroName.c_str());
|
error("Macro \"%s\" not defined\n", macroName.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -604,6 +604,9 @@ static uint32_t readBracketedMacroArgNum() {
|
|||||||
Symbol const *sym = sym_FindScopedValidSymbol(symName);
|
Symbol const *sym = sym_FindScopedValidSymbol(symName);
|
||||||
|
|
||||||
if (!sym) {
|
if (!sym) {
|
||||||
|
if (sym_IsPurgedScoped(symName))
|
||||||
|
error("Bracketed symbol \"%s\" does not exist; it was purged\n", symName.c_str());
|
||||||
|
else
|
||||||
error("Bracketed symbol \"%s\" does not exist\n", symName.c_str());
|
error("Bracketed symbol \"%s\" does not exist\n", symName.c_str());
|
||||||
num = 0;
|
num = 0;
|
||||||
symbolError = true;
|
symbolError = true;
|
||||||
@@ -1209,6 +1212,9 @@ static std::shared_ptr<std::string> readInterpolation(size_t depth) {
|
|||||||
Symbol const *sym = sym_FindScopedValidSymbol(fmtBuf);
|
Symbol const *sym = sym_FindScopedValidSymbol(fmtBuf);
|
||||||
|
|
||||||
if (!sym || !sym->isDefined()) {
|
if (!sym || !sym->isDefined()) {
|
||||||
|
if (sym_IsPurgedScoped(fmtBuf))
|
||||||
|
error("Interpolated symbol \"%s\" does not exist; it was purged\n", fmtBuf.c_str());
|
||||||
|
else
|
||||||
error("Interpolated symbol \"%s\" does not exist\n", fmtBuf.c_str());
|
error("Interpolated symbol \"%s\" does not exist\n", fmtBuf.c_str());
|
||||||
} else if (sym->type == SYM_EQUS) {
|
} else if (sym->type == SYM_EQUS) {
|
||||||
auto buf = std::make_shared<std::string>();
|
auto buf = std::make_shared<std::string>();
|
||||||
|
|||||||
@@ -1527,8 +1527,12 @@ string:
|
|||||||
| POP_SECTION LPAREN scoped_anon_id RPAREN {
|
| POP_SECTION LPAREN scoped_anon_id RPAREN {
|
||||||
Symbol *sym = sym_FindScopedValidSymbol($3);
|
Symbol *sym = sym_FindScopedValidSymbol($3);
|
||||||
|
|
||||||
if (!sym)
|
if (!sym) {
|
||||||
|
if (sym_IsPurgedScoped($3))
|
||||||
|
fatalerror("Unknown symbol \"%s\"; it was purged\n", $3.c_str());
|
||||||
|
else
|
||||||
fatalerror("Unknown symbol \"%s\"\n", $3.c_str());
|
fatalerror("Unknown symbol \"%s\"\n", $3.c_str());
|
||||||
|
}
|
||||||
Section const *section = sym->getSection();
|
Section const *section = sym->getSection();
|
||||||
|
|
||||||
if (!section)
|
if (!section)
|
||||||
|
|||||||
@@ -82,6 +82,8 @@ void Expression::makeSymbol(std::string const &symName) {
|
|||||||
isSymbol = true;
|
isSymbol = true;
|
||||||
|
|
||||||
data = sym_IsPC(sym) ? "PC is not constant at assembly time"
|
data = sym_IsPC(sym) ? "PC is not constant at assembly time"
|
||||||
|
: sym_IsPurgedScoped(symName)
|
||||||
|
? "'"s + symName + "' is not constant at assembly time; it was purged"
|
||||||
: "'"s + symName + "' is not constant at assembly time";
|
: "'"s + symName + "' is not constant at assembly time";
|
||||||
sym = sym_Ref(symName);
|
sym = sym_Ref(symName);
|
||||||
|
|
||||||
@@ -122,7 +124,9 @@ void Expression::makeBankSymbol(std::string const &symName) {
|
|||||||
// Symbol's section is known and bank is fixed
|
// Symbol's section is known and bank is fixed
|
||||||
data = (int32_t)sym->getSection()->bank;
|
data = (int32_t)sym->getSection()->bank;
|
||||||
} else {
|
} else {
|
||||||
data = "\""s + symName + "\"'s bank is not known";
|
data = sym_IsPurgedScoped(symName)
|
||||||
|
? "\""s + symName + "\"'s bank is not known; it was purged"
|
||||||
|
: "\""s + symName + "\"'s bank is not known";
|
||||||
|
|
||||||
size_t nameLen = sym->name.length() + 1; // Room for NUL!
|
size_t nameLen = sym->name.length() + 1; // Room for NUL!
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
#include "error.hpp"
|
#include "error.hpp"
|
||||||
#include "helpers.hpp" // assume
|
#include "helpers.hpp" // assume
|
||||||
@@ -19,6 +20,7 @@
|
|||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
|
|
||||||
std::unordered_map<std::string, Symbol> symbols;
|
std::unordered_map<std::string, Symbol> symbols;
|
||||||
|
std::unordered_set<std::string> purgedSymbols;
|
||||||
|
|
||||||
static std::optional<std::string> labelScope = std::nullopt; // Current section's label scope
|
static std::optional<std::string> labelScope = std::nullopt; // Current section's label scope
|
||||||
static Symbol *PCSymbol;
|
static Symbol *PCSymbol;
|
||||||
@@ -158,11 +160,13 @@ Symbol const *sym_GetPC() {
|
|||||||
return PCSymbol;
|
return PCSymbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Purge a symbol
|
|
||||||
void sym_Purge(std::string const &symName) {
|
void sym_Purge(std::string const &symName) {
|
||||||
Symbol *sym = sym_FindScopedValidSymbol(symName);
|
Symbol *sym = sym_FindScopedValidSymbol(symName);
|
||||||
|
|
||||||
if (!sym) {
|
if (!sym) {
|
||||||
|
if (sym_IsPurgedScoped(symName))
|
||||||
|
error("'%s' was already purged\n", symName.c_str());
|
||||||
|
else
|
||||||
error("'%s' not defined\n", symName.c_str());
|
error("'%s' not defined\n", symName.c_str());
|
||||||
} else if (sym->isBuiltin) {
|
} else if (sym->isBuiltin) {
|
||||||
error("Built-in symbol '%s' cannot be purged\n", symName.c_str());
|
error("Built-in symbol '%s' cannot be purged\n", symName.c_str());
|
||||||
@@ -176,10 +180,27 @@ void sym_Purge(std::string const &symName) {
|
|||||||
// Do not keep a reference to the label's name after purging it
|
// Do not keep a reference to the label's name after purging it
|
||||||
if (sym->name == labelScope)
|
if (sym->name == labelScope)
|
||||||
labelScope = std::nullopt;
|
labelScope = std::nullopt;
|
||||||
|
purgedSymbols.emplace(sym->name);
|
||||||
symbols.erase(sym->name);
|
symbols.erase(sym->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sym_IsPurgedExact(std::string const &symName) {
|
||||||
|
return purgedSymbols.find(symName) != purgedSymbols.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sym_IsPurgedScoped(std::string const &symName) {
|
||||||
|
if (size_t dotPos = symName.find('.'); dotPos != std::string::npos) {
|
||||||
|
// Check for a nonsensical reference to a nested scoped symbol
|
||||||
|
if (symName.find('.', dotPos + 1) != std::string::npos)
|
||||||
|
return false;
|
||||||
|
// If auto-scoped local label, expand the name
|
||||||
|
if (dotPos == 0 && labelScope)
|
||||||
|
return sym_IsPurgedExact(*labelScope + symName);
|
||||||
|
}
|
||||||
|
return sym_IsPurgedExact(symName);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t sym_GetPCValue() {
|
uint32_t sym_GetPCValue() {
|
||||||
Section const *sect = sect_GetSymbolSection();
|
Section const *sect = sect_GetSymbolSection();
|
||||||
|
|
||||||
@@ -218,6 +239,9 @@ uint32_t sym_GetConstantValue(std::string const &symName) {
|
|||||||
if (Symbol const *sym = sym_FindScopedSymbol(symName); sym)
|
if (Symbol const *sym = sym_FindScopedSymbol(symName); sym)
|
||||||
return sym->getConstantValue();
|
return sym->getConstantValue();
|
||||||
|
|
||||||
|
if (sym_IsPurgedScoped(symName))
|
||||||
|
error("'%s' not defined; it was purged\n", symName.c_str());
|
||||||
|
else
|
||||||
error("'%s' not defined\n", symName.c_str());
|
error("'%s' not defined\n", symName.c_str());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -242,6 +266,7 @@ static Symbol *createNonrelocSymbol(std::string const &symName, bool numeric) {
|
|||||||
|
|
||||||
if (!sym) {
|
if (!sym) {
|
||||||
sym = &createSymbol(symName);
|
sym = &createSymbol(symName);
|
||||||
|
purgedSymbols.erase(sym->name);
|
||||||
} else if (sym->isDefined()) {
|
} else if (sym->isDefined()) {
|
||||||
error("'%s' already defined at ", symName.c_str());
|
error("'%s' already defined at ", symName.c_str());
|
||||||
dumpFilename(*sym);
|
dumpFilename(*sym);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
warning: local-purge.asm(7): [-Wpurge]
|
warning: local-purge.asm(7): [-Wpurge]
|
||||||
Purging a label ".loc"
|
Purging a label ".loc"
|
||||||
error: local-purge.asm(8):
|
error: local-purge.asm(8):
|
||||||
Interpolated symbol ".loc" does not exist
|
Interpolated symbol ".loc" does not exist; it was purged
|
||||||
error: Assembly aborted (1 error)!
|
error: Assembly aborted (1 error)!
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
warning: sym-collision.asm(20): [-Wpurge]
|
warning: sym-collision.asm(20): [-Wpurge]
|
||||||
Purging a label "dork"
|
Purging a label "dork"
|
||||||
error: sym-collision.asm(25):
|
error: sym-collision.asm(25):
|
||||||
Interpolated symbol "dork" does not exist
|
Interpolated symbol "dork" does not exist; it was purged
|
||||||
error: Assembly aborted (1 error)!
|
error: Assembly aborted (1 error)!
|
||||||
|
|||||||
Reference in New Issue
Block a user