mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-23 03:22:08 +00:00
Miscellaneous updates
This commit is contained in:
@@ -3,6 +3,8 @@
|
|||||||
#ifndef RGBDS_ASM_WARNING_HPP
|
#ifndef RGBDS_ASM_WARNING_HPP
|
||||||
#define RGBDS_ASM_WARNING_HPP
|
#define RGBDS_ASM_WARNING_HPP
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include "diagnostics.hpp"
|
#include "diagnostics.hpp"
|
||||||
|
|
||||||
extern unsigned int nbErrors, maxErrors;
|
extern unsigned int nbErrors, maxErrors;
|
||||||
@@ -78,7 +80,6 @@ void error(char const *fmt, ...);
|
|||||||
// affect the following code. The code will fail to assemble but the user will
|
// affect the following code. The code will fail to assemble but the user will
|
||||||
// get a list of all errors at the end, making it easier to fix all of them at
|
// get a list of all errors at the end, making it easier to fix all of them at
|
||||||
// once.
|
// once.
|
||||||
[[gnu::format(printf, 1, 2)]]
|
void error(std::function<void()> callback);
|
||||||
void errorNoNewline(char const *fmt, ...);
|
|
||||||
|
|
||||||
#endif // RGBDS_ASM_WARNING_HPP
|
#endif // RGBDS_ASM_WARNING_HPP
|
||||||
|
|||||||
@@ -552,7 +552,7 @@ void out_WriteState(std::string name, std::vector<StateFeature> const &features)
|
|||||||
for (StateFeature feature : features) {
|
for (StateFeature feature : features) {
|
||||||
fprintf(file, "\n; %s\n", dumpHeadings[feature]);
|
fprintf(file, "\n; %s\n", dumpHeadings[feature]);
|
||||||
if (!dumpFuncs[feature](file)) {
|
if (!dumpFuncs[feature](file)) {
|
||||||
fprintf(file, "; No values\n");
|
fputs("; No values\n", file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -256,10 +256,10 @@ static void mergeSections(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SECTION_NORMAL:
|
case SECTION_NORMAL:
|
||||||
errorNoNewline("Section already defined previously at ");
|
sectError([&]() {
|
||||||
|
fputs("Section already defined previously at ", stderr);
|
||||||
sect.src->dump(sect.fileLine);
|
sect.src->dump(sect.fileLine);
|
||||||
putc('\n', stderr);
|
});
|
||||||
nbSectErrors++;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,11 +115,10 @@ static void dumpFilename(Symbol const &sym) {
|
|||||||
fputs(" at ", stderr);
|
fputs(" at ", stderr);
|
||||||
if (sym.src) {
|
if (sym.src) {
|
||||||
sym.src->dump(sym.fileLine);
|
sym.src->dump(sym.fileLine);
|
||||||
putc('\n', stderr);
|
|
||||||
} else if (sym.isBuiltin) {
|
} else if (sym.isBuiltin) {
|
||||||
fputs("<builtin>\n", stderr);
|
fputs("<builtin>", stderr);
|
||||||
} else {
|
} else {
|
||||||
fputs("<command-line>\n", stderr);
|
fputs("<command-line>", stderr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +143,8 @@ static void alreadyDefinedError(Symbol const &sym, char const *asType) {
|
|||||||
// `DEF()` would return false, so we should not claim the symbol is already defined
|
// `DEF()` would return false, so we should not claim the symbol is already defined
|
||||||
error("'%s' is reserved for a built-in symbol", sym.name.c_str());
|
error("'%s' is reserved for a built-in symbol", sym.name.c_str());
|
||||||
} else {
|
} else {
|
||||||
errorNoNewline("'%s' already defined", sym.name.c_str());
|
error([&]() {
|
||||||
|
fprintf(stderr, "'%s' already defined", sym.name.c_str());
|
||||||
if (asType) {
|
if (asType) {
|
||||||
fprintf(stderr, " as %s", asType);
|
fprintf(stderr, " as %s", asType);
|
||||||
}
|
}
|
||||||
@@ -153,11 +153,12 @@ static void alreadyDefinedError(Symbol const &sym, char const *asType) {
|
|||||||
if (std::string const &contents = *sym.getEqus(); isValidIdentifier(contents)) {
|
if (std::string const &contents = *sym.getEqus(); isValidIdentifier(contents)) {
|
||||||
fprintf(
|
fprintf(
|
||||||
stderr,
|
stderr,
|
||||||
" (should it be {interpolated} to define its contents \"%s\"?)\n",
|
"\n (should it be {interpolated} to define its contents \"%s\"?)",
|
||||||
contents.c_str()
|
contents.c_str()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,8 +373,10 @@ static Symbol *createNonrelocSymbol(std::string const &symName, bool numeric) {
|
|||||||
return nullptr; // Don't allow overriding the symbol, that'd be bad!
|
return nullptr; // Don't allow overriding the symbol, that'd be bad!
|
||||||
} else if (!numeric) {
|
} else if (!numeric) {
|
||||||
// The symbol has already been referenced, but it's not allowed
|
// The symbol has already been referenced, but it's not allowed
|
||||||
errorNoNewline("'%s' already referenced", symName.c_str());
|
error([&]() {
|
||||||
|
fprintf(stderr, "'%s' already referenced", symName.c_str());
|
||||||
dumpFilename(*sym);
|
dumpFilename(*sym);
|
||||||
|
});
|
||||||
return nullptr; // Don't allow overriding the symbol, that'd be bad!
|
return nullptr; // Don't allow overriding the symbol, that'd be bad!
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,8 +441,10 @@ Symbol *sym_RedefString(std::string const &symName, std::shared_ptr<std::string>
|
|||||||
if (sym->isDefined()) {
|
if (sym->isDefined()) {
|
||||||
alreadyDefinedError(*sym, "non-EQUS");
|
alreadyDefinedError(*sym, "non-EQUS");
|
||||||
} else {
|
} else {
|
||||||
errorNoNewline("'%s' already referenced", symName.c_str());
|
error([&]() {
|
||||||
|
fprintf(stderr, "'%s' already referenced", symName.c_str());
|
||||||
dumpFilename(*sym);
|
dumpFilename(*sym);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
} else if (sym->isBuiltin) {
|
} else if (sym->isBuiltin) {
|
||||||
|
|||||||
@@ -78,13 +78,7 @@ static void printDiag(
|
|||||||
lexer_DumpStringExpansions();
|
lexer_DumpStringExpansions();
|
||||||
}
|
}
|
||||||
|
|
||||||
void error(char const *fmt, ...) {
|
static void incrementErrors() {
|
||||||
va_list args;
|
|
||||||
|
|
||||||
va_start(args, fmt);
|
|
||||||
printDiag(fmt, args, "error", ":", nullptr);
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
// This intentionally makes 0 act as "unlimited" (or at least "limited to sizeof(unsigned)")
|
// This intentionally makes 0 act as "unlimited" (or at least "limited to sizeof(unsigned)")
|
||||||
nbErrors++;
|
nbErrors++;
|
||||||
if (nbErrors == maxErrors) {
|
if (nbErrors == maxErrors) {
|
||||||
@@ -97,26 +91,25 @@ void error(char const *fmt, ...) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void errorNoNewline(char const *fmt, ...) {
|
void error(char const *fmt, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
printDiag(fmt, args, "error", ":", nullptr);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
incrementErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
void error(std::function<void()> callback) {
|
||||||
fputs("error: ", stderr);
|
fputs("error: ", stderr);
|
||||||
fstk_DumpCurrent();
|
fstk_DumpCurrent();
|
||||||
fputs(":\n ", stderr);
|
fputs(":\n ", stderr);
|
||||||
va_start(args, fmt);
|
callback();
|
||||||
vfprintf(stderr, fmt, args);
|
putc('\n', stderr);
|
||||||
va_end(args);
|
lexer_DumpStringExpansions();
|
||||||
|
|
||||||
// This intentionally makes 0 act as "unlimited" (or at least "limited to sizeof(unsigned)")
|
incrementErrors();
|
||||||
nbErrors++;
|
|
||||||
if (nbErrors == maxErrors) {
|
|
||||||
errx(
|
|
||||||
"The maximum of %u error%s was reached (configure with \"-X/--max-errors\"); assembly "
|
|
||||||
"aborted!",
|
|
||||||
maxErrors,
|
|
||||||
maxErrors == 1 ? "" : "s"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[[noreturn]]
|
[[noreturn]]
|
||||||
|
|||||||
@@ -551,7 +551,7 @@ std::tuple<std::vector<size_t>, size_t>
|
|||||||
// LCOV_EXCL_START
|
// LCOV_EXCL_START
|
||||||
if (options.verbosity >= Options::VERB_INTERM) {
|
if (options.verbosity >= Options::VERB_INTERM) {
|
||||||
for (auto &&assignment : assignments) {
|
for (auto &&assignment : assignments) {
|
||||||
fprintf(stderr, "{ ");
|
fputs("{ ", stderr);
|
||||||
for (auto &&attrs : assignment) {
|
for (auto &&attrs : assignment) {
|
||||||
fprintf(stderr, "[%zu] ", attrs.protoPalIndex);
|
fprintf(stderr, "[%zu] ", attrs.protoPalIndex);
|
||||||
for (auto &&colorIndex : protoPalettes[attrs.protoPalIndex]) {
|
for (auto &&colorIndex : protoPalettes[attrs.protoPalIndex]) {
|
||||||
@@ -570,7 +570,7 @@ std::tuple<std::vector<size_t>, size_t>
|
|||||||
// LCOV_EXCL_START
|
// LCOV_EXCL_START
|
||||||
if (options.verbosity >= Options::VERB_INTERM) {
|
if (options.verbosity >= Options::VERB_INTERM) {
|
||||||
for (auto &&assignment : assignments) {
|
for (auto &&assignment : assignments) {
|
||||||
fprintf(stderr, "{ ");
|
fputs("{ ", stderr);
|
||||||
for (auto &&attrs : assignment) {
|
for (auto &&attrs : assignment) {
|
||||||
fprintf(stderr, "[%zu] ", attrs.protoPalIndex);
|
fprintf(stderr, "[%zu] ", attrs.protoPalIndex);
|
||||||
for (auto &&colorIndex : protoPalettes[attrs.protoPalIndex]) {
|
for (auto &&colorIndex : protoPalettes[attrs.protoPalIndex]) {
|
||||||
|
|||||||
@@ -392,7 +392,7 @@ void assign_AssignSections() {
|
|||||||
// Overlaying requires only fully-constrained sections
|
// Overlaying requires only fully-constrained sections
|
||||||
verbosePrint("Assigning other sections...\n");
|
verbosePrint("Assigning other sections...\n");
|
||||||
if (overlayFileName) {
|
if (overlayFileName) {
|
||||||
fprintf(stderr, "FATAL: All sections must be fixed when using an overlay file");
|
fputs("FATAL: All sections must be fixed when using an overlay file", stderr);
|
||||||
uint8_t nbSections = 0;
|
uint8_t nbSections = 0;
|
||||||
for (int8_t constraints = BANK_CONSTRAINED | ALIGN_CONSTRAINED; constraints >= 0;
|
for (int8_t constraints = BANK_CONSTRAINED | ALIGN_CONSTRAINED; constraints >= 0;
|
||||||
constraints--) {
|
constraints--) {
|
||||||
|
|||||||
@@ -480,9 +480,9 @@ static void writeMapBank(SortedSections const §List, SectionType type, uint3
|
|||||||
if (sect->nextu) {
|
if (sect->nextu) {
|
||||||
// Announce the following "piece"
|
// Announce the following "piece"
|
||||||
if (sect->nextu->modifier == SECTION_UNION) {
|
if (sect->nextu->modifier == SECTION_UNION) {
|
||||||
fprintf(mapFile, "\t ; Next union\n");
|
fputs("\t ; Next union\n", mapFile);
|
||||||
} else if (sect->nextu->modifier == SECTION_FRAGMENT) {
|
} else if (sect->nextu->modifier == SECTION_FRAGMENT) {
|
||||||
fprintf(mapFile, "\t ; Next fragment\n");
|
fputs("\t ; Next fragment\n", mapFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
test/asm/error-limit.asm
Normal file
2
test/asm/error-limit.asm
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
def x equ 1
|
||||||
|
def x equ 2
|
||||||
3
test/asm/error-limit.err
Normal file
3
test/asm/error-limit.err
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
error: error-limit.asm(2):
|
||||||
|
'x' already defined at error-limit.asm(1)
|
||||||
|
error: The maximum of 1 error was reached (configure with "-X/--max-errors"); assembly aborted!
|
||||||
1
test/asm/error-limit.flags
Normal file
1
test/asm/error-limit.flags
Normal file
@@ -0,0 +1 @@
|
|||||||
|
-Weverything -X 1
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
; no digits
|
; no digits
|
||||||
def x = $
|
def x = $
|
||||||
def x = `
|
def x = `
|
||||||
|
def x = 0b
|
||||||
|
def x = 0o
|
||||||
|
def x = 0x
|
||||||
|
|
||||||
; too large
|
; too large
|
||||||
def x = 9_876_543_210
|
def x = 9_876_543_210
|
||||||
|
|||||||
@@ -2,18 +2,24 @@ error: invalid-numbers.asm(2):
|
|||||||
Invalid integer constant, no digits after '$'
|
Invalid integer constant, no digits after '$'
|
||||||
error: invalid-numbers.asm(3):
|
error: invalid-numbers.asm(3):
|
||||||
Invalid graphics constant, no digits after '`'
|
Invalid graphics constant, no digits after '`'
|
||||||
warning: invalid-numbers.asm(6): [-Wlarge-constant]
|
error: invalid-numbers.asm(4):
|
||||||
Integer constant is too large
|
Invalid integer constant, no digits after '%'
|
||||||
warning: invalid-numbers.asm(7): [-Wlarge-constant]
|
error: invalid-numbers.asm(5):
|
||||||
Integer constant is too large
|
Invalid integer constant, no digits after '&'
|
||||||
warning: invalid-numbers.asm(8): [-Wlarge-constant]
|
error: invalid-numbers.asm(6):
|
||||||
Integer constant is too large
|
Invalid integer constant, no digits after '$'
|
||||||
warning: invalid-numbers.asm(9): [-Wlarge-constant]
|
warning: invalid-numbers.asm(9): [-Wlarge-constant]
|
||||||
Integer constant is too large
|
Integer constant is too large
|
||||||
warning: invalid-numbers.asm(10): [-Wlarge-constant]
|
warning: invalid-numbers.asm(10): [-Wlarge-constant]
|
||||||
|
Integer constant is too large
|
||||||
|
warning: invalid-numbers.asm(11): [-Wlarge-constant]
|
||||||
|
Integer constant is too large
|
||||||
|
warning: invalid-numbers.asm(12): [-Wlarge-constant]
|
||||||
|
Integer constant is too large
|
||||||
|
warning: invalid-numbers.asm(13): [-Wlarge-constant]
|
||||||
Magnitude of fixed-point constant is too large
|
Magnitude of fixed-point constant is too large
|
||||||
error: invalid-numbers.asm(13):
|
|
||||||
Invalid fixed-point constant, no significant digits after 'q'
|
|
||||||
error: invalid-numbers.asm(16):
|
error: invalid-numbers.asm(16):
|
||||||
|
Invalid fixed-point constant, no significant digits after 'q'
|
||||||
|
error: invalid-numbers.asm(19):
|
||||||
Fixed-point constant precision must be between 1 and 31
|
Fixed-point constant precision must be between 1 and 31
|
||||||
error: Assembly aborted (4 errors)!
|
error: Assembly aborted (7 errors)!
|
||||||
|
|||||||
3
test/asm/invalid-param.asm
Normal file
3
test/asm/invalid-param.asm
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
section "test", rom0
|
||||||
|
ld a, 256
|
||||||
|
ld a, -129
|
||||||
5
test/asm/invalid-param.err
Normal file
5
test/asm/invalid-param.err
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
warning: Invalid parameter 99 for warning flag "truncation"; capping at maximum 2
|
||||||
|
warning: invalid-param.asm(2): [-Wtruncation]
|
||||||
|
Expression must be 8-bit; use LOW() to force 8-bit
|
||||||
|
warning: invalid-param.asm(3): [-Wtruncation]
|
||||||
|
Expression must be 8-bit; use LOW() to force 8-bit
|
||||||
1
test/asm/invalid-param.flags
Normal file
1
test/asm/invalid-param.flags
Normal file
@@ -0,0 +1 @@
|
|||||||
|
-Weverything -Wtruncation=99
|
||||||
Reference in New Issue
Block a user