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_RedefString(std::string const &symName, std::shared_ptr<std::string> value);
|
||||
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);
|
||||
|
||||
// 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);
|
||||
|
||||
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());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -604,6 +604,9 @@ static uint32_t readBracketedMacroArgNum() {
|
||||
Symbol const *sym = sym_FindScopedValidSymbol(symName);
|
||||
|
||||
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());
|
||||
num = 0;
|
||||
symbolError = true;
|
||||
@@ -1209,6 +1212,9 @@ static std::shared_ptr<std::string> readInterpolation(size_t depth) {
|
||||
Symbol const *sym = sym_FindScopedValidSymbol(fmtBuf);
|
||||
|
||||
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());
|
||||
} else if (sym->type == SYM_EQUS) {
|
||||
auto buf = std::make_shared<std::string>();
|
||||
|
||||
@@ -1527,8 +1527,12 @@ string:
|
||||
| POP_SECTION LPAREN scoped_anon_id RPAREN {
|
||||
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());
|
||||
}
|
||||
Section const *section = sym->getSection();
|
||||
|
||||
if (!section)
|
||||
|
||||
@@ -82,6 +82,8 @@ void Expression::makeSymbol(std::string const &symName) {
|
||||
isSymbol = true;
|
||||
|
||||
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";
|
||||
sym = sym_Ref(symName);
|
||||
|
||||
@@ -122,7 +124,9 @@ void Expression::makeBankSymbol(std::string const &symName) {
|
||||
// Symbol's section is known and bank is fixed
|
||||
data = (int32_t)sym->getSection()->bank;
|
||||
} 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!
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "error.hpp"
|
||||
#include "helpers.hpp" // assume
|
||||
@@ -19,6 +20,7 @@
|
||||
using namespace std::literals;
|
||||
|
||||
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 Symbol *PCSymbol;
|
||||
@@ -158,11 +160,13 @@ Symbol const *sym_GetPC() {
|
||||
return PCSymbol;
|
||||
}
|
||||
|
||||
// Purge a symbol
|
||||
void sym_Purge(std::string const &symName) {
|
||||
Symbol *sym = sym_FindScopedValidSymbol(symName);
|
||||
|
||||
if (!sym) {
|
||||
if (sym_IsPurgedScoped(symName))
|
||||
error("'%s' was already purged\n", symName.c_str());
|
||||
else
|
||||
error("'%s' not defined\n", symName.c_str());
|
||||
} else if (sym->isBuiltin) {
|
||||
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
|
||||
if (sym->name == labelScope)
|
||||
labelScope = std::nullopt;
|
||||
purgedSymbols.emplace(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() {
|
||||
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)
|
||||
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());
|
||||
return 0;
|
||||
}
|
||||
@@ -242,6 +266,7 @@ static Symbol *createNonrelocSymbol(std::string const &symName, bool numeric) {
|
||||
|
||||
if (!sym) {
|
||||
sym = &createSymbol(symName);
|
||||
purgedSymbols.erase(sym->name);
|
||||
} else if (sym->isDefined()) {
|
||||
error("'%s' already defined at ", symName.c_str());
|
||||
dumpFilename(*sym);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
warning: local-purge.asm(7): [-Wpurge]
|
||||
Purging a label ".loc"
|
||||
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)!
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
warning: sym-collision.asm(20): [-Wpurge]
|
||||
Purging a label "dork"
|
||||
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)!
|
||||
|
||||
Reference in New Issue
Block a user