mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Add -B/--backtrace option to RGBASM and RGBLINK (#1787)
This commit is contained in:
1
Makefile
1
Makefile
@@ -83,6 +83,7 @@ src/asm/lexer.o src/asm/main.o: src/asm/parser.hpp
|
|||||||
rgblink_obj := \
|
rgblink_obj := \
|
||||||
${common_obj} \
|
${common_obj} \
|
||||||
src/link/assign.o \
|
src/link/assign.o \
|
||||||
|
src/link/fstack.o \
|
||||||
src/link/lexer.o \
|
src/link/lexer.o \
|
||||||
src/link/layout.o \
|
src/link/layout.o \
|
||||||
src/link/main.o \
|
src/link/main.o \
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ _rgbasm_completions() {
|
|||||||
[V]="version:normal"
|
[V]="version:normal"
|
||||||
[W]="warning:warning"
|
[W]="warning:warning"
|
||||||
[w]=":normal"
|
[w]=":normal"
|
||||||
|
[B]="backtrace:unk"
|
||||||
[b]="binary-digits:unk"
|
[b]="binary-digits:unk"
|
||||||
[D]="define:unk"
|
[D]="define:unk"
|
||||||
[E]="export-all:normal"
|
[E]="export-all:normal"
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ _rgblink_completions() {
|
|||||||
[W]="warning:warning"
|
[W]="warning:warning"
|
||||||
[M]="no-sym-in-map:normal"
|
[M]="no-sym-in-map:normal"
|
||||||
[d]="dmg:normal"
|
[d]="dmg:normal"
|
||||||
|
[B]="backtrace:unk"
|
||||||
[l]="linkerscript:glob-*"
|
[l]="linkerscript:glob-*"
|
||||||
[m]="map:glob-*.map"
|
[m]="map:glob-*.map"
|
||||||
[n]="sym:glob-*.sym"
|
[n]="sym:glob-*.sym"
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ local args=(
|
|||||||
'(-v --verbose)'{-v,--verbose}'[Enable verbose output]'
|
'(-v --verbose)'{-v,--verbose}'[Enable verbose output]'
|
||||||
-w'[Disable all warnings]'
|
-w'[Disable all warnings]'
|
||||||
|
|
||||||
|
'(-B --backtrace)'{-B,--backtrace}'+[Set backtrace depth or style]:depth:'
|
||||||
'(-b --binary-digits)'{-b,--binary-digits}'+[Change chars for binary constants]:digit spec:'
|
'(-b --binary-digits)'{-b,--binary-digits}'+[Change chars for binary constants]:digit spec:'
|
||||||
--color'[Whether to use color in output]:color:(auto always never)'
|
--color'[Whether to use color in output]:color:(auto always never)'
|
||||||
'*'{-D,--define}'+[Define a string symbol]:name + value (default 1):'
|
'*'{-D,--define}'+[Define a string symbol]:name + value (default 1):'
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ local args=(
|
|||||||
'(-w --wramx)'{-w,--wramx}'[Disable WRAM banking]'
|
'(-w --wramx)'{-w,--wramx}'[Disable WRAM banking]'
|
||||||
'(-x --nopad)'{-x,--nopad}'[Disable padding the end of the final file]'
|
'(-x --nopad)'{-x,--nopad}'[Disable padding the end of the final file]'
|
||||||
|
|
||||||
|
'(-B --backtrace)'{-B,--backtrace}'+[Set backtrace depth or style]:depth:'
|
||||||
--color'[Whether to use color in output]:color:(auto always never)'
|
--color'[Whether to use color in output]:color:(auto always never)'
|
||||||
'(-l --linkerscript)'{-l,--linkerscript}"+[Use a linker script]:linker script:_files -g '*.link'"
|
'(-l --linkerscript)'{-l,--linkerscript}"+[Use a linker script]:linker script:_files -g '*.link'"
|
||||||
'(-M --no-sym-in-map)'{-M,--no-sym-in-map}'[Do not output symbol names in map file]'
|
'(-M --no-sym-in-map)'{-M,--no-sym-in-map}'[Do not output symbol names in map file]'
|
||||||
|
|||||||
@@ -43,7 +43,8 @@ struct FileStackNode {
|
|||||||
FileStackNode(FileStackNodeType type_, std::variant<std::vector<uint32_t>, std::string> data_)
|
FileStackNode(FileStackNodeType type_, std::variant<std::vector<uint32_t>, std::string> data_)
|
||||||
: type(type_), data(data_) {}
|
: type(type_), data(data_) {}
|
||||||
|
|
||||||
std::string const &dump(uint32_t curLineNo) const;
|
void printBacktrace(uint32_t curLineNo) const;
|
||||||
|
std::vector<std::pair<std::string, uint32_t>> backtrace(uint32_t curLineNo) const;
|
||||||
std::string reptChain() const;
|
std::string reptChain() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -51,7 +52,7 @@ struct MacroArgs;
|
|||||||
|
|
||||||
void fstk_VerboseOutputConfig();
|
void fstk_VerboseOutputConfig();
|
||||||
|
|
||||||
bool fstk_DumpCurrent();
|
void fstk_TraceCurrent();
|
||||||
std::shared_ptr<FileStackNode> fstk_GetFileStack();
|
std::shared_ptr<FileStackNode> fstk_GetFileStack();
|
||||||
std::shared_ptr<std::string> fstk_GetUniqueIDStr();
|
std::shared_ptr<std::string> fstk_GetUniqueIDStr();
|
||||||
MacroArgs *fstk_GetCurrentMacroArgs();
|
MacroArgs *fstk_GetCurrentMacroArgs();
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ void lexer_ReachELSEBlock();
|
|||||||
|
|
||||||
void lexer_CheckRecursionDepth();
|
void lexer_CheckRecursionDepth();
|
||||||
uint32_t lexer_GetLineNo();
|
uint32_t lexer_GetLineNo();
|
||||||
void lexer_DumpStringExpansions();
|
void lexer_TraceStringExpansions();
|
||||||
|
|
||||||
struct Capture {
|
struct Capture {
|
||||||
uint32_t lineNo;
|
uint32_t lineNo;
|
||||||
|
|||||||
@@ -74,11 +74,10 @@ void fatal(char const *fmt, ...);
|
|||||||
[[gnu::format(printf, 1, 2)]]
|
[[gnu::format(printf, 1, 2)]]
|
||||||
void error(char const *fmt, ...);
|
void error(char const *fmt, ...);
|
||||||
|
|
||||||
// Used for errors that make it impossible to assemble correctly, but don't
|
// Used for errors that handle their own backtrace output. The code will fail
|
||||||
// affect the following code. The code will fail to assemble but the user will
|
// to assemble but the user will get a list of all errors at the end, making it
|
||||||
// get a list of all errors at the end, making it easier to fix all of them at
|
// easier to fix all of them at once.
|
||||||
// once.
|
void errorNoTrace(std::function<void()> callback);
|
||||||
void error(std::function<void()> callback);
|
|
||||||
|
|
||||||
void requireZeroErrors();
|
void requireZeroErrors();
|
||||||
|
|
||||||
|
|||||||
@@ -53,12 +53,15 @@ struct DiagnosticsState {
|
|||||||
bool warningsAreErrors = false;
|
bool warningsAreErrors = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static constexpr uint64_t TRACE_COLLAPSE = UINT64_MAX;
|
||||||
|
|
||||||
template<typename L, typename W>
|
template<typename L, typename W>
|
||||||
struct Diagnostics {
|
struct Diagnostics {
|
||||||
std::vector<WarningFlag<L>> metaWarnings;
|
std::vector<WarningFlag<L>> metaWarnings;
|
||||||
std::vector<WarningFlag<L>> warningFlags;
|
std::vector<WarningFlag<L>> warningFlags;
|
||||||
std::vector<ParamWarning<W>> paramWarnings;
|
std::vector<ParamWarning<W>> paramWarnings;
|
||||||
DiagnosticsState<W> state;
|
DiagnosticsState<W> state;
|
||||||
|
uint64_t traceDepth;
|
||||||
uint64_t nbErrors;
|
uint64_t nbErrors;
|
||||||
|
|
||||||
void incrementErrors() {
|
void incrementErrors() {
|
||||||
|
|||||||
38
include/link/fstack.hpp
Normal file
38
include/link/fstack.hpp
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#ifndef RGBDS_LINK_FSTACK_HPP
|
||||||
|
#define RGBDS_LINK_FSTACK_HPP
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string>
|
||||||
|
#include <variant>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "linkdefs.hpp"
|
||||||
|
|
||||||
|
struct FileStackNode {
|
||||||
|
FileStackNodeType type;
|
||||||
|
std::variant<
|
||||||
|
std::monostate, // Default constructed; `.type` and `.data` must be set manually
|
||||||
|
std::vector<uint32_t>, // NODE_REPT
|
||||||
|
std::string // NODE_FILE, NODE_MACRO
|
||||||
|
>
|
||||||
|
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
|
||||||
|
std::vector<uint32_t> &iters() { return std::get<std::vector<uint32_t>>(data); }
|
||||||
|
std::vector<uint32_t> const &iters() const { return std::get<std::vector<uint32_t>>(data); }
|
||||||
|
// File name for files, file::macro name for macros
|
||||||
|
std::string &name() { return std::get<std::string>(data); }
|
||||||
|
std::string const &name() const { return std::get<std::string>(data); }
|
||||||
|
|
||||||
|
void printBacktrace(uint32_t curLineNo) const;
|
||||||
|
std::vector<std::pair<std::string, uint32_t>> backtrace(uint32_t curLineNo) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RGBDS_LINK_FSTACK_HPP
|
||||||
@@ -4,13 +4,6 @@
|
|||||||
#define RGBDS_LINK_MAIN_HPP
|
#define RGBDS_LINK_MAIN_HPP
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <string>
|
|
||||||
#include <variant>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "linkdefs.hpp"
|
|
||||||
#include "verbosity.hpp"
|
|
||||||
|
|
||||||
struct Options {
|
struct Options {
|
||||||
bool isDmgMode; // -d
|
bool isDmgMode; // -d
|
||||||
@@ -32,27 +25,4 @@ struct Options {
|
|||||||
|
|
||||||
extern Options options;
|
extern Options options;
|
||||||
|
|
||||||
struct FileStackNode {
|
|
||||||
FileStackNodeType type;
|
|
||||||
std::variant<
|
|
||||||
std::monostate, // Default constructed; `.type` and `.data` must be set manually
|
|
||||||
std::vector<uint32_t>, // NODE_REPT
|
|
||||||
std::string // NODE_FILE, NODE_MACRO
|
|
||||||
>
|
|
||||||
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
|
|
||||||
std::vector<uint32_t> &iters() { return std::get<std::vector<uint32_t>>(data); }
|
|
||||||
std::vector<uint32_t> const &iters() const { return std::get<std::vector<uint32_t>>(data); }
|
|
||||||
// File name for files, file::macro name for macros
|
|
||||||
std::string &name() { return std::get<std::string>(data); }
|
|
||||||
std::string const &name() const { return std::get<std::string>(data); }
|
|
||||||
|
|
||||||
std::string const &dump(uint32_t curLineNo) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // RGBDS_LINK_MAIN_HPP
|
#endif // RGBDS_LINK_MAIN_HPP
|
||||||
|
|||||||
@@ -44,6 +44,6 @@ void sym_AddSymbol(Symbol &symbol);
|
|||||||
// Finds a symbol in all the defined symbols.
|
// Finds a symbol in all the defined symbols.
|
||||||
Symbol *sym_GetSymbol(std::string const &name);
|
Symbol *sym_GetSymbol(std::string const &name);
|
||||||
|
|
||||||
void sym_DumpLocalAliasedSymbols(std::string const &name);
|
void sym_TraceLocalAliasedSymbols(std::string const &name);
|
||||||
|
|
||||||
#endif // RGBDS_LINK_SYMBOL_HPP
|
#endif // RGBDS_LINK_SYMBOL_HPP
|
||||||
|
|||||||
@@ -8,9 +8,12 @@
|
|||||||
|
|
||||||
#include "diagnostics.hpp"
|
#include "diagnostics.hpp"
|
||||||
|
|
||||||
#define warningAt(where, ...) warning(where.src, where.lineNo, __VA_ARGS__)
|
#define warningAt(where, ...) warning((where).src, (where).lineNo, __VA_ARGS__)
|
||||||
#define errorAt(where, ...) error(where.src, where.lineNo, __VA_ARGS__)
|
#define errorAt(where, ...) error((where).src, (where).lineNo, __VA_ARGS__)
|
||||||
#define fatalAt(where, ...) fatal(where.src, where.lineNo, __VA_ARGS__)
|
#define fatalAt(where, ...) fatal((where).src, (where).lineNo, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define fatalTwoAt(where1, where2, ...) \
|
||||||
|
fatalTwo(*(where1).src, (where1).lineNo, *(where2).src, (where2).lineNo, __VA_ARGS__)
|
||||||
|
|
||||||
enum WarningLevel {
|
enum WarningLevel {
|
||||||
LEVEL_DEFAULT, // Warnings that are enabled by default
|
LEVEL_DEFAULT, // Warnings that are enabled by default
|
||||||
@@ -46,8 +49,6 @@ void warning(char const *fmt, ...);
|
|||||||
void error(FileStackNode const *src, uint32_t lineNo, char const *fmt, ...);
|
void error(FileStackNode const *src, uint32_t lineNo, char const *fmt, ...);
|
||||||
[[gnu::format(printf, 1, 2)]]
|
[[gnu::format(printf, 1, 2)]]
|
||||||
void error(char const *fmt, ...);
|
void error(char const *fmt, ...);
|
||||||
[[gnu::format(printf, 1, 2)]]
|
|
||||||
void errorNoDump(char const *fmt, ...);
|
|
||||||
|
|
||||||
void scriptError(char const *name, uint32_t lineNo, char const *fmt, va_list args);
|
void scriptError(char const *name, uint32_t lineNo, char const *fmt, va_list args);
|
||||||
|
|
||||||
@@ -56,6 +57,16 @@ void fatal(FileStackNode const *src, uint32_t lineNo, char const *fmt, ...);
|
|||||||
[[gnu::format(printf, 1, 2), noreturn]]
|
[[gnu::format(printf, 1, 2), noreturn]]
|
||||||
void fatal(char const *fmt, ...);
|
void fatal(char const *fmt, ...);
|
||||||
|
|
||||||
|
[[gnu::format(printf, 5, 6), noreturn]]
|
||||||
|
void fatalTwo(
|
||||||
|
FileStackNode const &src1,
|
||||||
|
uint32_t lineNo1,
|
||||||
|
FileStackNode const &src2,
|
||||||
|
uint32_t lineNo2,
|
||||||
|
char const *fmt,
|
||||||
|
...
|
||||||
|
);
|
||||||
|
|
||||||
void requireZeroErrors();
|
void requireZeroErrors();
|
||||||
|
|
||||||
#endif // RGBDS_LINK_WARNING_HPP
|
#endif // RGBDS_LINK_WARNING_HPP
|
||||||
|
|||||||
10
man/rgbasm.1
10
man/rgbasm.1
@@ -9,6 +9,7 @@
|
|||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl EhVvw
|
.Op Fl EhVvw
|
||||||
|
.Op Fl B Ar depth
|
||||||
.Op Fl b Ar chars
|
.Op Fl b Ar chars
|
||||||
.Op Fl \-color Ar when
|
.Op Fl \-color Ar when
|
||||||
.Op Fl D Ar name Ns Op = Ns Ar value
|
.Op Fl D Ar name Ns Op = Ns Ar value
|
||||||
@@ -52,6 +53,15 @@ is invalid because it could also be
|
|||||||
.Fl \-version .
|
.Fl \-version .
|
||||||
The arguments are as follows:
|
The arguments are as follows:
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
|
.It Fl B Ar depth , Fl \-backtrace Ar depth
|
||||||
|
Specifies the maximum depth for which
|
||||||
|
.Nm
|
||||||
|
will print location backtraces for warnings or errors.
|
||||||
|
Deeper backtraces than that will be abbreviated.
|
||||||
|
.Fl B Ar 0
|
||||||
|
allows unlimited-depth backtraces.
|
||||||
|
.Fl B Ar collapse
|
||||||
|
will print the entire location trace on one line.
|
||||||
.It Fl b Ar chars , Fl \-binary-digits Ar chars
|
.It Fl b Ar chars , Fl \-binary-digits Ar chars
|
||||||
Allow two characters to be used for binary constants in addition to the default
|
Allow two characters to be used for binary constants in addition to the default
|
||||||
.Sq 0
|
.Sq 0
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl dhMtVvwx
|
.Op Fl dhMtVvwx
|
||||||
|
.Op Fl B Ar depth
|
||||||
.Op Fl \-color Ar when
|
.Op Fl \-color Ar when
|
||||||
.Op Fl l Ar linker_script
|
.Op Fl l Ar linker_script
|
||||||
.Op Fl m Ar map_file
|
.Op Fl m Ar map_file
|
||||||
@@ -64,6 +65,15 @@ is invalid because it could also be
|
|||||||
.Fl \-version .
|
.Fl \-version .
|
||||||
The arguments are as follows:
|
The arguments are as follows:
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
|
.It Fl B Ar depth , Fl \-backtrace Ar depth
|
||||||
|
Specifies the maximum depth for which
|
||||||
|
.Nm
|
||||||
|
will print location backtraces for warnings or errors.
|
||||||
|
Deeper backtraces than that will be abbreviated.
|
||||||
|
.Fl B Ar 0
|
||||||
|
allows unlimited-depth backtraces.
|
||||||
|
.Fl B Ar collapse
|
||||||
|
will print the entire location trace on one line.
|
||||||
.It Fl \-color Ar when
|
.It Fl \-color Ar when
|
||||||
Specify when to highlight warning and error messages with color:
|
Specify when to highlight warning and error messages with color:
|
||||||
.Ql always ,
|
.Ql always ,
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ set(rgbasm_src
|
|||||||
set(rgblink_src
|
set(rgblink_src
|
||||||
"${BISON_LINKER_SCRIPT_PARSER_OUTPUT_SOURCE}"
|
"${BISON_LINKER_SCRIPT_PARSER_OUTPUT_SOURCE}"
|
||||||
"link/assign.cpp"
|
"link/assign.cpp"
|
||||||
|
"link/fstack.cpp"
|
||||||
"link/lexer.cpp"
|
"link/lexer.cpp"
|
||||||
"link/layout.cpp"
|
"link/layout.cpp"
|
||||||
"link/main.cpp"
|
"link/main.cpp"
|
||||||
|
|||||||
@@ -60,42 +60,79 @@ std::string FileStackNode::reptChain() const {
|
|||||||
return chain;
|
return chain;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string const &FileStackNode::dump(uint32_t curLineNo) const {
|
std::vector<std::pair<std::string, uint32_t>> FileStackNode::backtrace(uint32_t curLineNo) const {
|
||||||
if (std::holds_alternative<std::vector<uint32_t>>(data)) {
|
if (std::holds_alternative<std::vector<uint32_t>>(data)) {
|
||||||
assume(parent); // REPT nodes use their parent's name
|
assume(parent); // REPT nodes use their parent's name
|
||||||
std::string const &lastName = parent->dump(lineNo);
|
std::vector<std::pair<std::string, uint32_t>> nodes = parent->backtrace(lineNo);
|
||||||
style_Set(stderr, STYLE_CYAN, false);
|
assume(!nodes.empty());
|
||||||
fputs(" -> ", stderr);
|
nodes.emplace_back(nodes.back().first + reptChain(), curLineNo);
|
||||||
style_Set(stderr, STYLE_CYAN, true);
|
return nodes;
|
||||||
fputs(lastName.c_str(), stderr);
|
} else if (parent) {
|
||||||
fputs(reptChain().c_str(), stderr);
|
std::vector<std::pair<std::string, uint32_t>> nodes = parent->backtrace(lineNo);
|
||||||
style_Set(stderr, STYLE_CYAN, false);
|
nodes.emplace_back(name(), curLineNo);
|
||||||
fprintf(stderr, "(%" PRIu32 ")", curLineNo);
|
return nodes;
|
||||||
style_Reset(stderr);
|
|
||||||
return lastName;
|
|
||||||
} else {
|
} else {
|
||||||
if (parent) {
|
return {
|
||||||
parent->dump(lineNo);
|
{name(), curLineNo}
|
||||||
style_Set(stderr, STYLE_CYAN, false);
|
};
|
||||||
fputs(" -> ", stderr);
|
|
||||||
}
|
|
||||||
std::string const &nodeName = name();
|
|
||||||
style_Set(stderr, STYLE_CYAN, true);
|
|
||||||
fputs(nodeName.c_str(), stderr);
|
|
||||||
style_Set(stderr, STYLE_CYAN, false);
|
|
||||||
fprintf(stderr, "(%" PRIu32 ")", curLineNo);
|
|
||||||
style_Reset(stderr);
|
|
||||||
return nodeName;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fstk_DumpCurrent() {
|
static void printNode(std::pair<std::string, uint32_t> const &node) {
|
||||||
if (lexer_AtTopLevel()) {
|
style_Set(stderr, STYLE_CYAN, true);
|
||||||
return false;
|
fputs(node.first.c_str(), stderr);
|
||||||
|
style_Set(stderr, STYLE_CYAN, false);
|
||||||
|
fprintf(stderr, "(%" PRIu32 ")", node.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileStackNode::printBacktrace(uint32_t curLineNo) const {
|
||||||
|
std::vector<std::pair<std::string, uint32_t>> nodes = backtrace(curLineNo);
|
||||||
|
size_t n = nodes.size();
|
||||||
|
|
||||||
|
if (warnings.traceDepth == TRACE_COLLAPSE) {
|
||||||
|
fputs(" ", stderr); // Just three spaces; the fourth will be handled by the loop
|
||||||
|
for (size_t i = 0; i < n; ++i) {
|
||||||
|
style_Reset(stderr);
|
||||||
|
fprintf(stderr, " %s ", i == 0 ? "at" : "<-");
|
||||||
|
printNode(nodes[n - i - 1]);
|
||||||
}
|
}
|
||||||
|
putc('\n', stderr);
|
||||||
|
} else if (warnings.traceDepth == 0 || static_cast<size_t>(warnings.traceDepth) >= n) {
|
||||||
|
for (size_t i = 0; i < n; ++i) {
|
||||||
|
style_Reset(stderr);
|
||||||
|
fprintf(stderr, " %s ", i == 0 ? "at" : "<-");
|
||||||
|
printNode(nodes[n - i - 1]);
|
||||||
|
putc('\n', stderr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
size_t last = warnings.traceDepth / 2;
|
||||||
|
size_t first = warnings.traceDepth - last;
|
||||||
|
size_t skipped = n - warnings.traceDepth;
|
||||||
|
for (size_t i = 0; i < first; ++i) {
|
||||||
|
style_Reset(stderr);
|
||||||
|
fprintf(stderr, " %s ", i == 0 ? "at" : "<-");
|
||||||
|
printNode(nodes[n - i - 1]);
|
||||||
|
putc('\n', stderr);
|
||||||
|
}
|
||||||
|
style_Reset(stderr);
|
||||||
|
fprintf(stderr, " ...%zu more%s\n", skipped, last ? "..." : "");
|
||||||
|
for (size_t i = n - last; i < n; ++i) {
|
||||||
|
style_Reset(stderr);
|
||||||
|
fputs(" <- ", stderr);
|
||||||
|
printNode(nodes[n - i - 1]);
|
||||||
|
putc('\n', stderr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
style_Reset(stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fstk_TraceCurrent() {
|
||||||
|
if (!lexer_AtTopLevel()) {
|
||||||
assume(!contextStack.empty());
|
assume(!contextStack.empty());
|
||||||
contextStack.top().fileInfo->dump(lexer_GetLineNo());
|
contextStack.top().fileInfo->printBacktrace(lexer_GetLineNo());
|
||||||
return true;
|
}
|
||||||
|
lexer_TraceStringExpansions();
|
||||||
}
|
}
|
||||||
|
|
||||||
// LCOV_EXCL_START
|
// LCOV_EXCL_START
|
||||||
|
|||||||
@@ -838,16 +838,16 @@ uint32_t lexer_GetLineNo() {
|
|||||||
return lexerState->lineNo;
|
return lexerState->lineNo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lexer_DumpStringExpansions() {
|
void lexer_TraceStringExpansions() {
|
||||||
if (!lexerState) {
|
if (!lexerState) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Expansion &exp : lexerState->expansions) {
|
for (Expansion &exp : lexerState->expansions) {
|
||||||
// Only register EQUS expansions, not string args
|
// Only print EQUS expansions, not string args
|
||||||
if (exp.name) {
|
if (exp.name) {
|
||||||
style_Set(stderr, STYLE_CYAN, false);
|
style_Set(stderr, STYLE_CYAN, false);
|
||||||
fputs("while expanding symbol \"", stderr);
|
fputs(" while expanding symbol \"", stderr);
|
||||||
style_Set(stderr, STYLE_CYAN, true);
|
style_Set(stderr, STYLE_CYAN, true);
|
||||||
fputs(exp.name->c_str(), stderr);
|
fputs(exp.name->c_str(), stderr);
|
||||||
style_Set(stderr, STYLE_CYAN, false);
|
style_Set(stderr, STYLE_CYAN, false);
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ static char const *dependFileName = nullptr;
|
|||||||
static std::unordered_map<std::string, std::vector<StateFeature>> stateFileSpecs; // -s
|
static std::unordered_map<std::string, std::vector<StateFeature>> stateFileSpecs; // -s
|
||||||
|
|
||||||
// Short options
|
// Short options
|
||||||
static char const *optstring = "b:D:Eg:hI:M:o:P:p:Q:r:s:VvW:wX:";
|
static char const *optstring = "B:b:D:Eg:hI:M:o:P:p:Q:r:s:VvW:wX:";
|
||||||
|
|
||||||
// Variables for the long-only options
|
// Variables for the long-only options
|
||||||
static int longOpt; // `--color` and variants of `-M`
|
static int longOpt; // `--color` and variants of `-M`
|
||||||
@@ -47,6 +47,7 @@ static int longOpt; // `--color` and variants of `-M`
|
|||||||
// This is because long opt matching, even to a single char, is prioritized
|
// This is because long opt matching, even to a single char, is prioritized
|
||||||
// over short opt matching.
|
// over short opt matching.
|
||||||
static option const longopts[] = {
|
static option const longopts[] = {
|
||||||
|
{"backtrace", required_argument, nullptr, 'B'},
|
||||||
{"binary-digits", required_argument, nullptr, 'b'},
|
{"binary-digits", required_argument, nullptr, 'b'},
|
||||||
{"define", required_argument, nullptr, 'D'},
|
{"define", required_argument, nullptr, 'D'},
|
||||||
{"export-all", no_argument, nullptr, 'E'},
|
{"export-all", no_argument, nullptr, 'E'},
|
||||||
@@ -77,7 +78,7 @@ static option const longopts[] = {
|
|||||||
static Usage usage = {
|
static Usage usage = {
|
||||||
.name = "rgbasm",
|
.name = "rgbasm",
|
||||||
.flags = {
|
.flags = {
|
||||||
"[-EhVvw]", "[-b chars]", "[-D name[=value]]", "[-g chars]", "[-I path]",
|
"[-EhVvw]", "[-B depth]", "[-b chars]", "[-D name[=value]]", "[-g chars]", "[-I path]",
|
||||||
"[-M depend_file]", "[-MC]", "[-MG]", "[-MP]", "[-MT target_file]", "[-MQ target_file]",
|
"[-M depend_file]", "[-MC]", "[-MG]", "[-MP]", "[-MT target_file]", "[-MQ target_file]",
|
||||||
"[-o out_file]", "[-P include_file]", "[-p pad_value]", "[-Q precision]", "[-r depth]",
|
"[-o out_file]", "[-P include_file]", "[-p pad_value]", "[-Q precision]", "[-r depth]",
|
||||||
"[-s features:state_file]", "[-W warning]", "[-X max_errors]", "<file>",
|
"[-s features:state_file]", "[-W warning]", "[-X max_errors]", "<file>",
|
||||||
@@ -215,7 +216,6 @@ static void verboseOutputConfig(int argc, char *argv[]) {
|
|||||||
if (options.generatePhonyDeps) {
|
if (options.generatePhonyDeps) {
|
||||||
fputs("\tGenerate phony dependencies\n", stderr);
|
fputs("\tGenerate phony dependencies\n", stderr);
|
||||||
}
|
}
|
||||||
// [-MG] [-MC]
|
|
||||||
}
|
}
|
||||||
fputs("Ready.\n", stderr);
|
fputs("Ready.\n", stderr);
|
||||||
|
|
||||||
@@ -303,6 +303,24 @@ int main(int argc, char *argv[]) {
|
|||||||
switch (ch) {
|
switch (ch) {
|
||||||
char *endptr;
|
char *endptr;
|
||||||
|
|
||||||
|
case 'B': {
|
||||||
|
if (!strcasecmp(musl_optarg, "collapse")) {
|
||||||
|
warnings.traceDepth = TRACE_COLLAPSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
warnings.traceDepth = strtoul(musl_optarg, &endptr, 0);
|
||||||
|
|
||||||
|
if (musl_optarg[0] == '\0' || *endptr != '\0') {
|
||||||
|
fatal("Invalid argument for option 'B'");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (warnings.traceDepth >= UINT64_MAX) {
|
||||||
|
fatal("Argument for option 'B' is too large");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 'b':
|
case 'b':
|
||||||
if (strlen(musl_optarg) == 2) {
|
if (strlen(musl_optarg) == 2) {
|
||||||
opt_B(musl_optarg);
|
opt_B(musl_optarg);
|
||||||
|
|||||||
@@ -281,9 +281,12 @@ static void mergeSections(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SECTION_NORMAL:
|
case SECTION_NORMAL:
|
||||||
sectError([&]() {
|
errorNoTrace([&]() {
|
||||||
fputs("Section already defined previously at ", stderr);
|
fputs("Section already defined\n", stderr);
|
||||||
sect.src->dump(sect.fileLine);
|
fstk_TraceCurrent();
|
||||||
|
fputs(" and also:\n", stderr);
|
||||||
|
sect.src->printBacktrace(sect.fileLine);
|
||||||
|
++nbSectErrors;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,14 +113,15 @@ std::shared_ptr<std::string> Symbol::getEqus() const {
|
|||||||
return std::get<std::shared_ptr<std::string>>(data);
|
return std::get<std::shared_ptr<std::string>>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dumpFilename(Symbol const &sym) {
|
// Meant to be called last in an `errorNoTrace` callback
|
||||||
fputs(" at ", stderr);
|
static void printBacktraces(Symbol const &sym) {
|
||||||
|
putc('\n', stderr);
|
||||||
|
fstk_TraceCurrent();
|
||||||
|
fputs(" and also:\n", stderr);
|
||||||
if (sym.src) {
|
if (sym.src) {
|
||||||
sym.src->dump(sym.fileLine);
|
sym.src->printBacktrace(sym.fileLine);
|
||||||
} else if (sym.isBuiltin) {
|
|
||||||
fputs("<builtin>", stderr);
|
|
||||||
} else {
|
} else {
|
||||||
fputs("<command-line>", stderr);
|
fprintf(stderr, " at <%s>\n", sym.isBuiltin ? "builtin" : "command-line");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,37 +142,52 @@ static bool isValidIdentifier(std::string const &s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void alreadyDefinedError(Symbol const &sym, char const *asType) {
|
static void alreadyDefinedError(Symbol const &sym, char const *asType) {
|
||||||
if (sym.isBuiltin && !sym_FindScopedValidSymbol(sym.name)) {
|
auto suggestion = [&]() {
|
||||||
// `DEF()` would return false, so we should not claim the symbol is already defined
|
std::string s;
|
||||||
error("'%s' is reserved for a built-in symbol", sym.name.c_str());
|
if (auto const &contents = sym.type == SYM_EQUS ? sym.getEqus() : nullptr;
|
||||||
|
contents && isValidIdentifier(*contents)) {
|
||||||
|
s.append(" (should it be {interpolated} to define its contents \"");
|
||||||
|
s.append(*contents);
|
||||||
|
s.append("\"?)");
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (sym.isBuiltin) {
|
||||||
|
if (sym_FindScopedValidSymbol(sym.name)) {
|
||||||
|
if (std::string s = suggestion(); asType) {
|
||||||
|
error("'%s' already defined as built-in %s%s", sym.name.c_str(), asType, s.c_str());
|
||||||
} else {
|
} else {
|
||||||
error([&]() {
|
error("'%s' already defined as built-in%s", sym.name.c_str(), s.c_str());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// `DEF()` would return false, so we should not claim the symbol is already defined,
|
||||||
|
// nor suggest to interpolate it
|
||||||
|
if (asType) {
|
||||||
|
error("'%s' is reserved for a built-in %s symbol", sym.name.c_str(), asType);
|
||||||
|
} else {
|
||||||
|
error("'%s' is reserved for a built-in symbol", sym.name.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errorNoTrace([&]() {
|
||||||
fprintf(stderr, "'%s' already defined", sym.name.c_str());
|
fprintf(stderr, "'%s' already defined", sym.name.c_str());
|
||||||
if (asType) {
|
if (asType) {
|
||||||
fprintf(stderr, " as %s", asType);
|
fprintf(stderr, " as %s", asType);
|
||||||
}
|
}
|
||||||
dumpFilename(sym);
|
fputs(suggestion().c_str(), stderr);
|
||||||
if (sym.type != SYM_EQUS) {
|
printBacktraces(sym);
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (std::string const &contents = *sym.getEqus(); isValidIdentifier(contents)) {
|
|
||||||
fprintf(
|
|
||||||
stderr,
|
|
||||||
"\n (should it be {interpolated} to define its contents \"%s\"?)",
|
|
||||||
contents.c_str()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void redefinedError(Symbol const &sym) {
|
static void redefinedError(Symbol const &sym) {
|
||||||
assume(sym.isBuiltin);
|
assume(sym.isBuiltin);
|
||||||
if (!sym_FindScopedValidSymbol(sym.name)) {
|
if (sym_FindScopedValidSymbol(sym.name)) {
|
||||||
|
error("Built-in symbol '%s' cannot be redefined", sym.name.c_str());
|
||||||
|
} else {
|
||||||
// `DEF()` would return false, so we should not imply the symbol is already defined
|
// `DEF()` would return false, so we should not imply 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 {
|
|
||||||
error("Built-in symbol '%s' cannot be redefined", sym.name.c_str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,9 +392,9 @@ 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
|
||||||
error([&]() {
|
errorNoTrace([&]() {
|
||||||
fprintf(stderr, "'%s' already referenced", symName.c_str());
|
fprintf(stderr, "'%s' already referenced", symName.c_str());
|
||||||
dumpFilename(*sym);
|
printBacktraces(*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!
|
||||||
}
|
}
|
||||||
@@ -444,9 +460,9 @@ 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 {
|
||||||
error([&]() {
|
errorNoTrace([&]() {
|
||||||
fprintf(stderr, "'%s' already referenced", symName.c_str());
|
fprintf(stderr, "'%s' already referenced", symName.c_str());
|
||||||
dumpFilename(*sym);
|
printBacktraces(*sym);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ Diagnostics<WarningLevel, WarningID> warnings = {
|
|||||||
{WARNING_UNMAPPED_CHAR_1, WARNING_UNMAPPED_CHAR_2, 1},
|
{WARNING_UNMAPPED_CHAR_1, WARNING_UNMAPPED_CHAR_2, 1},
|
||||||
},
|
},
|
||||||
.state = DiagnosticsState<WarningID>(),
|
.state = DiagnosticsState<WarningID>(),
|
||||||
|
.traceDepth = 0,
|
||||||
.nbErrors = 0,
|
.nbErrors = 0,
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
@@ -74,19 +75,16 @@ static void printDiag(
|
|||||||
) {
|
) {
|
||||||
style_Set(stderr, color, true);
|
style_Set(stderr, color, true);
|
||||||
fprintf(stderr, "%s: ", type);
|
fprintf(stderr, "%s: ", type);
|
||||||
if (fstk_DumpCurrent()) {
|
|
||||||
putc(':', stderr);
|
|
||||||
if (flagfmt) {
|
|
||||||
style_Set(stderr, color, true);
|
|
||||||
fprintf(stderr, flagfmt, flag);
|
|
||||||
}
|
|
||||||
fputs("\n ", stderr);
|
|
||||||
}
|
|
||||||
style_Reset(stderr);
|
style_Reset(stderr);
|
||||||
vfprintf(stderr, fmt, args);
|
vfprintf(stderr, fmt, args);
|
||||||
|
if (flagfmt) {
|
||||||
|
style_Set(stderr, color, true);
|
||||||
|
putc(' ', stderr);
|
||||||
|
fprintf(stderr, flagfmt, flag);
|
||||||
|
}
|
||||||
putc('\n', stderr);
|
putc('\n', stderr);
|
||||||
|
|
||||||
lexer_DumpStringExpansions();
|
fstk_TraceCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void incrementErrors() {
|
static void incrementErrors() {
|
||||||
@@ -117,16 +115,11 @@ void error(char const *fmt, ...) {
|
|||||||
incrementErrors();
|
incrementErrors();
|
||||||
}
|
}
|
||||||
|
|
||||||
void error(std::function<void()> callback) {
|
void errorNoTrace(std::function<void()> callback) {
|
||||||
style_Set(stderr, STYLE_RED, true);
|
style_Set(stderr, STYLE_RED, true);
|
||||||
fputs("error: ", stderr);
|
fputs("error: ", stderr);
|
||||||
if (fstk_DumpCurrent()) {
|
|
||||||
fputs(":\n ", stderr);
|
|
||||||
}
|
|
||||||
style_Reset(stderr);
|
style_Reset(stderr);
|
||||||
callback();
|
callback();
|
||||||
putc('\n', stderr);
|
|
||||||
lexer_DumpStringExpansions();
|
|
||||||
|
|
||||||
incrementErrors();
|
incrementErrors();
|
||||||
}
|
}
|
||||||
@@ -167,11 +160,11 @@ void warning(WarningID id, char const *fmt, ...) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WarningBehavior::ENABLED:
|
case WarningBehavior::ENABLED:
|
||||||
printDiag(fmt, args, "warning", STYLE_YELLOW, " [-W%s]", flag);
|
printDiag(fmt, args, "warning", STYLE_YELLOW, "[-W%s]", flag);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WarningBehavior::ERROR:
|
case WarningBehavior::ERROR:
|
||||||
printDiag(fmt, args, "error", STYLE_RED, " [-Werror=%s]", flag);
|
printDiag(fmt, args, "error", STYLE_RED, "[-Werror=%s]", flag);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ Diagnostics<WarningLevel, WarningID> warnings = {
|
|||||||
},
|
},
|
||||||
.paramWarnings = {},
|
.paramWarnings = {},
|
||||||
.state = DiagnosticsState<WarningID>(),
|
.state = DiagnosticsState<WarningID>(),
|
||||||
|
.traceDepth = 0,
|
||||||
.nbErrors = 0,
|
.nbErrors = 0,
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ Diagnostics<WarningLevel, WarningID> warnings = {
|
|||||||
},
|
},
|
||||||
.paramWarnings = {},
|
.paramWarnings = {},
|
||||||
.state = DiagnosticsState<WarningID>(),
|
.state = DiagnosticsState<WarningID>(),
|
||||||
|
.traceDepth = 0,
|
||||||
.nbErrors = 0,
|
.nbErrors = 0,
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|||||||
80
src/link/fstack.cpp
Normal file
80
src/link/fstack.cpp
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
#include "link/fstack.hpp"
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "style.hpp"
|
||||||
|
|
||||||
|
#include "link/warning.hpp"
|
||||||
|
|
||||||
|
std::vector<std::pair<std::string, uint32_t>> FileStackNode::backtrace(uint32_t curLineNo) const {
|
||||||
|
if (std::holds_alternative<std::vector<uint32_t>>(data)) {
|
||||||
|
assume(parent); // REPT nodes use their parent's name
|
||||||
|
std::vector<std::pair<std::string, uint32_t>> nodes = parent->backtrace(lineNo);
|
||||||
|
assume(!nodes.empty());
|
||||||
|
std::string reptChain = nodes.back().first;
|
||||||
|
for (uint32_t iter : iters()) {
|
||||||
|
reptChain.append("::REPT~");
|
||||||
|
reptChain.append(std::to_string(iter));
|
||||||
|
}
|
||||||
|
nodes.emplace_back(reptChain, curLineNo);
|
||||||
|
return nodes;
|
||||||
|
} else if (parent) {
|
||||||
|
std::vector<std::pair<std::string, uint32_t>> nodes = parent->backtrace(lineNo);
|
||||||
|
nodes.emplace_back(name(), curLineNo);
|
||||||
|
return nodes;
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
{name(), curLineNo}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printNode(std::pair<std::string, uint32_t> const &node) {
|
||||||
|
style_Set(stderr, STYLE_CYAN, true);
|
||||||
|
fputs(node.first.c_str(), stderr);
|
||||||
|
style_Set(stderr, STYLE_CYAN, false);
|
||||||
|
fprintf(stderr, "(%" PRIu32 ")", node.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileStackNode::printBacktrace(uint32_t curLineNo) const {
|
||||||
|
std::vector<std::pair<std::string, uint32_t>> nodes = backtrace(curLineNo);
|
||||||
|
size_t n = nodes.size();
|
||||||
|
|
||||||
|
if (warnings.traceDepth == TRACE_COLLAPSE) {
|
||||||
|
fputs(" ", stderr); // Just three spaces; the fourth will be handled by the loop
|
||||||
|
for (size_t i = 0; i < n; ++i) {
|
||||||
|
style_Reset(stderr);
|
||||||
|
fprintf(stderr, " %s ", i == 0 ? "at" : "<-");
|
||||||
|
printNode(nodes[n - i - 1]);
|
||||||
|
}
|
||||||
|
putc('\n', stderr);
|
||||||
|
} else if (warnings.traceDepth == 0 || static_cast<size_t>(warnings.traceDepth) >= n) {
|
||||||
|
for (size_t i = 0; i < n; ++i) {
|
||||||
|
style_Reset(stderr);
|
||||||
|
fprintf(stderr, " %s ", i == 0 ? "at" : "<-");
|
||||||
|
printNode(nodes[n - i - 1]);
|
||||||
|
putc('\n', stderr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
size_t last = warnings.traceDepth / 2;
|
||||||
|
size_t first = warnings.traceDepth - last;
|
||||||
|
size_t skipped = n - warnings.traceDepth;
|
||||||
|
for (size_t i = 0; i < first; ++i) {
|
||||||
|
style_Reset(stderr);
|
||||||
|
fprintf(stderr, " %s ", i == 0 ? "at" : "<-");
|
||||||
|
printNode(nodes[n - i - 1]);
|
||||||
|
putc('\n', stderr);
|
||||||
|
}
|
||||||
|
style_Reset(stderr);
|
||||||
|
fprintf(stderr, " ...%zu more%s\n", skipped, last ? "..." : "");
|
||||||
|
for (size_t i = n - last; i < n; ++i) {
|
||||||
|
style_Reset(stderr);
|
||||||
|
fputs(" <- ", stderr);
|
||||||
|
printNode(nodes[n - i - 1]);
|
||||||
|
putc('\n', stderr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
style_Reset(stderr);
|
||||||
|
}
|
||||||
@@ -36,7 +36,7 @@ Options options;
|
|||||||
static char const *linkerScriptName = nullptr; // -l
|
static char const *linkerScriptName = nullptr; // -l
|
||||||
|
|
||||||
// Short options
|
// Short options
|
||||||
static char const *optstring = "dhl:m:Mn:O:o:p:S:tVvW:wx";
|
static char const *optstring = "B:dhl:m:Mn:O:o:p:S:tVvW:wx";
|
||||||
|
|
||||||
// Variables for the long-only options
|
// Variables for the long-only options
|
||||||
static int longOpt; // `--color`
|
static int longOpt; // `--color`
|
||||||
@@ -49,6 +49,7 @@ static int longOpt; // `--color`
|
|||||||
// This is because long opt matching, even to a single char, is prioritized
|
// This is because long opt matching, even to a single char, is prioritized
|
||||||
// over short opt matching.
|
// over short opt matching.
|
||||||
static option const longopts[] = {
|
static option const longopts[] = {
|
||||||
|
{"backtrace", required_argument, nullptr, 'B'},
|
||||||
{"dmg", no_argument, nullptr, 'd'},
|
{"dmg", no_argument, nullptr, 'd'},
|
||||||
{"help", no_argument, nullptr, 'h'},
|
{"help", no_argument, nullptr, 'h'},
|
||||||
{"linkerscript", required_argument, nullptr, 'l'},
|
{"linkerscript", required_argument, nullptr, 'l'},
|
||||||
@@ -73,8 +74,8 @@ static option const longopts[] = {
|
|||||||
static Usage usage = {
|
static Usage usage = {
|
||||||
.name = "rgblink",
|
.name = "rgblink",
|
||||||
.flags = {
|
.flags = {
|
||||||
"[-dhMtVvwx]", "[-l script]", "[-m map_file]", "[-n sym_file]", "[-O overlay_file]",
|
"[-dhMtVvwx]", "[-B depth]", "[-l script]", "[-m map_file]", "[-n sym_file]",
|
||||||
"[-o out_file]", "[-p pad_value]", "[-S spec]", "<file> ...",
|
"[-O overlay_file]", "[-o out_file]", "[-p pad_value]", "[-S spec]", "<file> ...",
|
||||||
},
|
},
|
||||||
.options = {
|
.options = {
|
||||||
{{"-l", "--linkerscript <path>"}, {"set the input linker script"}},
|
{{"-l", "--linkerscript <path>"}, {"set the input linker script"}},
|
||||||
@@ -180,37 +181,6 @@ static void verboseOutputConfig(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
// LCOV_EXCL_STOP
|
// LCOV_EXCL_STOP
|
||||||
|
|
||||||
std::string const &FileStackNode::dump(uint32_t curLineNo) const {
|
|
||||||
if (std::holds_alternative<std::vector<uint32_t>>(data)) {
|
|
||||||
assume(parent); // REPT nodes use their parent's name
|
|
||||||
std::string const &lastName = parent->dump(lineNo);
|
|
||||||
style_Set(stderr, STYLE_CYAN, false);
|
|
||||||
fputs(" -> ", stderr);
|
|
||||||
style_Set(stderr, STYLE_CYAN, true);
|
|
||||||
fputs(lastName.c_str(), stderr);
|
|
||||||
for (uint32_t iter : iters()) {
|
|
||||||
fprintf(stderr, "::REPT~%" PRIu32, iter);
|
|
||||||
}
|
|
||||||
style_Set(stderr, STYLE_CYAN, false);
|
|
||||||
fprintf(stderr, "(%" PRIu32 ")", curLineNo);
|
|
||||||
style_Reset(stderr);
|
|
||||||
return lastName;
|
|
||||||
} else {
|
|
||||||
if (parent) {
|
|
||||||
parent->dump(lineNo);
|
|
||||||
style_Set(stderr, STYLE_CYAN, false);
|
|
||||||
fputs(" -> ", stderr);
|
|
||||||
}
|
|
||||||
std::string const &nodeName = name();
|
|
||||||
style_Set(stderr, STYLE_CYAN, true);
|
|
||||||
fputs(nodeName.c_str(), stderr);
|
|
||||||
style_Set(stderr, STYLE_CYAN, false);
|
|
||||||
fprintf(stderr, "(%" PRIu32 ")", curLineNo);
|
|
||||||
style_Reset(stderr);
|
|
||||||
return nodeName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void parseScrambleSpec(char *spec) {
|
static void parseScrambleSpec(char *spec) {
|
||||||
// clang-format off: vertically align nested initializers
|
// clang-format off: vertically align nested initializers
|
||||||
static UpperMap<std::pair<uint16_t *, uint16_t>> scrambleSpecs{
|
static UpperMap<std::pair<uint16_t *, uint16_t>> scrambleSpecs{
|
||||||
@@ -325,6 +295,21 @@ int main(int argc, char *argv[]) {
|
|||||||
// Parse options
|
// Parse options
|
||||||
for (int ch; (ch = musl_getopt_long_only(argc, argv, optstring, longopts, nullptr)) != -1;) {
|
for (int ch; (ch = musl_getopt_long_only(argc, argv, optstring, longopts, nullptr)) != -1;) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
|
case 'B': {
|
||||||
|
if (!strcasecmp(musl_optarg, "collapse")) {
|
||||||
|
warnings.traceDepth = TRACE_COLLAPSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
char *endptr;
|
||||||
|
warnings.traceDepth = strtoul(musl_optarg, &endptr, 0);
|
||||||
|
if (musl_optarg[0] == '\0' || *endptr != '\0') {
|
||||||
|
fatal("Invalid argument for option 'B'");
|
||||||
|
}
|
||||||
|
if (warnings.traceDepth >= UINT64_MAX) {
|
||||||
|
fatal("Argument for option 'B' is too large");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 'd':
|
case 'd':
|
||||||
options.isDmgMode = true;
|
options.isDmgMode = true;
|
||||||
options.isWRAM0Mode = true;
|
options.isWRAM0Mode = true;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "version.hpp"
|
#include "version.hpp"
|
||||||
|
|
||||||
#include "link/assign.hpp"
|
#include "link/assign.hpp"
|
||||||
|
#include "link/fstack.hpp"
|
||||||
#include "link/main.hpp"
|
#include "link/main.hpp"
|
||||||
#include "link/patch.hpp"
|
#include "link/patch.hpp"
|
||||||
#include "link/sdas_obj.hpp"
|
#include "link/sdas_obj.hpp"
|
||||||
|
|||||||
@@ -428,7 +428,7 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
|||||||
}
|
}
|
||||||
} else if (Symbol const *symbol = getSymbol(fileSymbols, value); !symbol) {
|
} else if (Symbol const *symbol = getSymbol(fileSymbols, value); !symbol) {
|
||||||
errorAt(patch, "Undefined symbol \"%s\"", fileSymbols[value].name.c_str());
|
errorAt(patch, "Undefined symbol \"%s\"", fileSymbols[value].name.c_str());
|
||||||
sym_DumpLocalAliasedSymbols(fileSymbols[value].name);
|
sym_TraceLocalAliasedSymbols(fileSymbols[value].name);
|
||||||
isError = true;
|
isError = true;
|
||||||
} else if (std::holds_alternative<Label>(symbol->data)) {
|
} else if (std::holds_alternative<Label>(symbol->data)) {
|
||||||
Label const &label = std::get<Label>(symbol->data);
|
Label const &label = std::get<Label>(symbol->data);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "platform.hpp"
|
#include "platform.hpp"
|
||||||
|
|
||||||
#include "link/assign.hpp"
|
#include "link/assign.hpp"
|
||||||
|
#include "link/fstack.hpp"
|
||||||
#include "link/main.hpp"
|
#include "link/main.hpp"
|
||||||
#include "link/section.hpp"
|
#include "link/section.hpp"
|
||||||
#include "link/symbol.hpp"
|
#include "link/symbol.hpp"
|
||||||
@@ -280,7 +281,7 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector<Symbol> &f
|
|||||||
// The following is required for fragment offsets to be reliably predicted
|
// The following is required for fragment offsets to be reliably predicted
|
||||||
for (FileSection &entry : fileSections) {
|
for (FileSection &entry : fileSections) {
|
||||||
if (!strcmp(token, entry.section->name.c_str())) {
|
if (!strcmp(token, entry.section->name.c_str())) {
|
||||||
fatalAt(where, "Area \"%s\" already defined earlier", token);
|
fatalAt(where, "Area \"%s\" already defined", token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
char const *sectName = token; // We'll deal with the section's name depending on type
|
char const *sectName = token; // We'll deal with the section's name depending on type
|
||||||
@@ -422,14 +423,14 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector<Symbol> &f
|
|||||||
|| (symbolSection && !symbolSection->isAddressFixed)) {
|
|| (symbolSection && !symbolSection->isAddressFixed)) {
|
||||||
sym_AddSymbol(symbol); // This will error out
|
sym_AddSymbol(symbol); // This will error out
|
||||||
} else if (otherValue != symbolValue) {
|
} else if (otherValue != symbolValue) {
|
||||||
errorNoDump(
|
fatalTwoAt(
|
||||||
"\"%s\" is defined as %" PRId32 " at ", symbol.name.c_str(), symbolValue
|
symbol,
|
||||||
|
*other,
|
||||||
|
"\"%s\" is defined as %" PRId32 ", but was already defined as %" PRId32,
|
||||||
|
symbol.name.c_str(),
|
||||||
|
symbolValue,
|
||||||
|
otherValue
|
||||||
);
|
);
|
||||||
symbol.src->dump(symbol.lineNo);
|
|
||||||
fprintf(stderr, ", but as %" PRId32 " at ", otherValue);
|
|
||||||
other->src->dump(other->lineNo);
|
|
||||||
putc('\n', stderr);
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Add a new definition
|
// Add a new definition
|
||||||
|
|||||||
@@ -24,30 +24,28 @@ void sect_ForEach(void (*callback)(Section &)) {
|
|||||||
static void checkAgainstFixedAddress(Section const &target, Section const &other, uint16_t org) {
|
static void checkAgainstFixedAddress(Section const &target, Section const &other, uint16_t org) {
|
||||||
if (target.isAddressFixed) {
|
if (target.isAddressFixed) {
|
||||||
if (target.org != org) {
|
if (target.org != org) {
|
||||||
errorNoDump(
|
fatalTwoAt(
|
||||||
"Section \"%s\" is defined with address $%04" PRIx16 " at ",
|
target,
|
||||||
|
other,
|
||||||
|
"Section \"%s\" is defined with address $%04" PRIx16
|
||||||
|
", but also with address $%04" PRIx16,
|
||||||
target.name.c_str(),
|
target.name.c_str(),
|
||||||
target.org
|
target.org,
|
||||||
|
other.org
|
||||||
);
|
);
|
||||||
target.src->dump(target.lineNo);
|
|
||||||
fprintf(stderr, ", but with address $%04" PRIx16 " at ", other.org);
|
|
||||||
other.src->dump(other.lineNo);
|
|
||||||
putc('\n', stderr);
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
} else if (target.isAlignFixed) {
|
} else if (target.isAlignFixed) {
|
||||||
if ((org - target.alignOfs) & target.alignMask) {
|
if ((org - target.alignOfs) & target.alignMask) {
|
||||||
errorNoDump(
|
fatalTwoAt(
|
||||||
"Section \"%s\" is defined with %d-byte alignment (offset %" PRIu16 ") at ",
|
target,
|
||||||
|
other,
|
||||||
|
"Section \"%s\" is defined with %d-byte alignment (offset %" PRIu16
|
||||||
|
"), but also with address $%04" PRIx16,
|
||||||
target.name.c_str(),
|
target.name.c_str(),
|
||||||
target.alignMask + 1,
|
target.alignMask + 1,
|
||||||
target.alignOfs
|
target.alignOfs,
|
||||||
|
other.org
|
||||||
);
|
);
|
||||||
target.src->dump(target.lineNo);
|
|
||||||
fprintf(stderr, ", but with address $%04" PRIx16 " at ", other.org);
|
|
||||||
other.src->dump(other.lineNo);
|
|
||||||
putc('\n', stderr);
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,41 +53,31 @@ static void checkAgainstFixedAddress(Section const &target, Section const &other
|
|||||||
static bool checkAgainstFixedAlign(Section const &target, Section const &other, int32_t ofs) {
|
static bool checkAgainstFixedAlign(Section const &target, Section const &other, int32_t ofs) {
|
||||||
if (target.isAddressFixed) {
|
if (target.isAddressFixed) {
|
||||||
if ((target.org - ofs) & other.alignMask) {
|
if ((target.org - ofs) & other.alignMask) {
|
||||||
errorNoDump(
|
fatalTwoAt(
|
||||||
"Section \"%s\" is defined with address $%04" PRIx16 " at ",
|
target,
|
||||||
|
other,
|
||||||
|
"Section \"%s\" is defined with address $%04" PRIx16
|
||||||
|
", but also with %d-byte alignment (offset %" PRIu16 ")",
|
||||||
target.name.c_str(),
|
target.name.c_str(),
|
||||||
target.org
|
target.org,
|
||||||
);
|
|
||||||
target.src->dump(target.lineNo);
|
|
||||||
fprintf(
|
|
||||||
stderr,
|
|
||||||
", but with %d-byte alignment (offset %" PRIu16 ") at ",
|
|
||||||
other.alignMask + 1,
|
other.alignMask + 1,
|
||||||
other.alignOfs
|
other.alignOfs
|
||||||
);
|
);
|
||||||
other.src->dump(other.lineNo);
|
|
||||||
putc('\n', stderr);
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} else if (target.isAlignFixed
|
} else if (target.isAlignFixed
|
||||||
&& (other.alignMask & target.alignOfs) != (target.alignMask & ofs)) {
|
&& (other.alignMask & target.alignOfs) != (target.alignMask & ofs)) {
|
||||||
errorNoDump(
|
fatalTwoAt(
|
||||||
"Section \"%s\" is defined with %d-byte alignment (offset %" PRIu16 ") at ",
|
target,
|
||||||
|
other,
|
||||||
|
"Section \"%s\" is defined with %d-byte alignment (offset %" PRIu16
|
||||||
|
"), but also with %d-byte alignment (offset %" PRIu16 ")",
|
||||||
target.name.c_str(),
|
target.name.c_str(),
|
||||||
target.alignMask + 1,
|
target.alignMask + 1,
|
||||||
target.alignOfs
|
target.alignOfs,
|
||||||
);
|
|
||||||
target.src->dump(target.lineNo);
|
|
||||||
fprintf(
|
|
||||||
stderr,
|
|
||||||
", but with %d-byte alignment (offset %" PRIu16 ") at ",
|
|
||||||
other.alignMask + 1,
|
other.alignMask + 1,
|
||||||
other.alignOfs
|
other.alignOfs
|
||||||
);
|
);
|
||||||
other.src->dump(other.lineNo);
|
|
||||||
putc('\n', stderr);
|
|
||||||
exit(1);
|
|
||||||
} else {
|
} else {
|
||||||
return !target.isAlignFixed || (other.alignMask > target.alignMask);
|
return !target.isAlignFixed || (other.alignMask > target.alignMask);
|
||||||
}
|
}
|
||||||
@@ -129,34 +117,25 @@ static void checkFragmentCompat(Section &target, Section &other) {
|
|||||||
|
|
||||||
static void mergeSections(Section &target, std::unique_ptr<Section> &&other) {
|
static void mergeSections(Section &target, std::unique_ptr<Section> &&other) {
|
||||||
if (target.modifier != other->modifier) {
|
if (target.modifier != other->modifier) {
|
||||||
errorNoDump(
|
fatalTwoAt(
|
||||||
"Section \"%s\" is defined as SECTION %s at ",
|
target,
|
||||||
|
*other,
|
||||||
|
"Section \"%s\" is defined as SECTION %s, but also as SECTION %s",
|
||||||
target.name.c_str(),
|
target.name.c_str(),
|
||||||
sectionModNames[target.modifier]
|
sectionModNames[target.modifier],
|
||||||
|
sectionModNames[other->modifier]
|
||||||
);
|
);
|
||||||
target.src->dump(target.lineNo);
|
|
||||||
fprintf(stderr, ", but as SECTION %s at ", sectionModNames[other->modifier]);
|
|
||||||
other->src->dump(other->lineNo);
|
|
||||||
putc('\n', stderr);
|
|
||||||
exit(1);
|
|
||||||
} else if (other->modifier == SECTION_NORMAL) {
|
} else if (other->modifier == SECTION_NORMAL) {
|
||||||
errorNoDump("Section \"%s\" is defined at ", target.name.c_str());
|
fatalTwoAt(target, *other, "Section \"%s\" is already defined", target.name.c_str());
|
||||||
target.src->dump(target.lineNo);
|
|
||||||
fputs(", but also at ", stderr);
|
|
||||||
other->src->dump(other->lineNo);
|
|
||||||
putc('\n', stderr);
|
|
||||||
exit(1);
|
|
||||||
} else if (target.type != other->type) {
|
} else if (target.type != other->type) {
|
||||||
errorNoDump(
|
fatalTwoAt(
|
||||||
"Section \"%s\" is defined with type %s at ",
|
target,
|
||||||
|
*other,
|
||||||
|
"Section \"%s\" is defined with type %s, but also with type %s",
|
||||||
target.name.c_str(),
|
target.name.c_str(),
|
||||||
sectionTypeInfo[target.type].name.c_str()
|
sectionTypeInfo[target.type].name.c_str(),
|
||||||
|
sectionTypeInfo[other->type].name.c_str()
|
||||||
);
|
);
|
||||||
target.src->dump(target.lineNo);
|
|
||||||
fprintf(stderr, ", but with type %s at ", sectionTypeInfo[other->type].name.c_str());
|
|
||||||
other->src->dump(other->lineNo);
|
|
||||||
putc('\n', stderr);
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (other->isBankFixed) {
|
if (other->isBankFixed) {
|
||||||
@@ -164,16 +143,14 @@ static void mergeSections(Section &target, std::unique_ptr<Section> &&other) {
|
|||||||
target.isBankFixed = true;
|
target.isBankFixed = true;
|
||||||
target.bank = other->bank;
|
target.bank = other->bank;
|
||||||
} else if (target.bank != other->bank) {
|
} else if (target.bank != other->bank) {
|
||||||
errorNoDump(
|
fatalTwoAt(
|
||||||
"Section \"%s\" is defined with bank %" PRIu32 " at ",
|
target,
|
||||||
|
*other,
|
||||||
|
"Section \"%s\" is defined with bank %" PRIu32 ", but also with bank %" PRIu32,
|
||||||
target.name.c_str(),
|
target.name.c_str(),
|
||||||
target.bank
|
target.bank,
|
||||||
|
other->bank
|
||||||
);
|
);
|
||||||
target.src->dump(target.lineNo);
|
|
||||||
fprintf(stderr, ", but with bank %" PRIu32 " at ", other->bank);
|
|
||||||
other->src->dump(other->lineNo);
|
|
||||||
putc('\n', stderr);
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#include "helpers.hpp" // assume
|
#include "helpers.hpp" // assume
|
||||||
|
|
||||||
#include "link/main.hpp"
|
#include "link/fstack.hpp"
|
||||||
#include "link/section.hpp"
|
#include "link/section.hpp"
|
||||||
#include "link/warning.hpp"
|
#include "link/warning.hpp"
|
||||||
|
|
||||||
@@ -39,24 +39,16 @@ void sym_AddSymbol(Symbol &symbol) {
|
|||||||
|
|
||||||
// Check if the symbol already exists with a different value
|
// Check if the symbol already exists with a different value
|
||||||
if (other && !(symValue && otherValue && *symValue == *otherValue)) {
|
if (other && !(symValue && otherValue && *symValue == *otherValue)) {
|
||||||
errorNoDump("\"%s\" is defined as ", symbol.name.c_str());
|
std::string symDef = symValue ? std::to_string(*symValue) : "a label";
|
||||||
if (symValue) {
|
std::string otherDef = otherValue ? std::to_string(*otherValue) : "another label";
|
||||||
fprintf(stderr, "%" PRId32, *symValue);
|
fatalTwoAt(
|
||||||
} else {
|
symbol,
|
||||||
fputs("a label", stderr);
|
*other,
|
||||||
}
|
"\"%s\" is defined as %s, but also as %s",
|
||||||
fputs(" at ", stderr);
|
symbol.name.c_str(),
|
||||||
symbol.src->dump(symbol.lineNo);
|
symDef.c_str(),
|
||||||
fputs(", but as ", stderr);
|
otherDef.c_str()
|
||||||
if (otherValue) {
|
);
|
||||||
fprintf(stderr, "%" PRId32, *otherValue);
|
|
||||||
} else {
|
|
||||||
fputs("another label", stderr);
|
|
||||||
}
|
|
||||||
fputs(" at ", stderr);
|
|
||||||
other->src->dump(other->lineNo);
|
|
||||||
putc('\n', stderr);
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not, add it (potentially replacing the previous same-value symbol)
|
// If not, add it (potentially replacing the previous same-value symbol)
|
||||||
@@ -68,29 +60,28 @@ Symbol *sym_GetSymbol(std::string const &name) {
|
|||||||
return search != symbols.end() ? search->second : nullptr;
|
return search != symbols.end() ? search->second : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sym_DumpLocalAliasedSymbols(std::string const &name) {
|
void sym_TraceLocalAliasedSymbols(std::string const &name) {
|
||||||
std::vector<Symbol *> const &locals = localSymbols[name];
|
std::vector<Symbol *> const &locals = localSymbols[name];
|
||||||
int count = 0;
|
if (locals.empty()) {
|
||||||
for (Symbol *local : locals) {
|
return;
|
||||||
if (count++ == 3) {
|
}
|
||||||
size_t remaining = locals.size() - 3;
|
|
||||||
bool plural = remaining != 1;
|
bool plural = locals.size() != 1;
|
||||||
fprintf(
|
fprintf(
|
||||||
stderr,
|
stderr,
|
||||||
" ...and %zu more symbol%s with that name %s defined but not exported\n",
|
" %zu symbol%s with that name %s defined but not exported:\n",
|
||||||
remaining,
|
locals.size(),
|
||||||
plural ? "s" : "",
|
plural ? "s" : "",
|
||||||
plural ? "are" : "is"
|
plural ? "are" : "is"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
for (Symbol *local : locals) {
|
||||||
|
assume(local->src);
|
||||||
|
local->src->printBacktrace(local->lineNo);
|
||||||
|
if (++count == 3 && locals.size() > 3) {
|
||||||
|
fprintf(stderr, " ...and %zu more\n", locals.size() - 3);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fprintf(
|
|
||||||
stderr,
|
|
||||||
" A %s with that name is defined but not exported at ",
|
|
||||||
std::holds_alternative<Label>(local->data) ? "label" : "constant"
|
|
||||||
);
|
|
||||||
assume(local->src);
|
|
||||||
local->src->dump(local->lineNo);
|
|
||||||
putc('\n', stderr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#include "style.hpp"
|
#include "style.hpp"
|
||||||
|
|
||||||
#include "link/main.hpp"
|
#include "link/fstack.hpp"
|
||||||
|
|
||||||
// clang-format off: nested initializers
|
// clang-format off: nested initializers
|
||||||
Diagnostics<WarningLevel, WarningID> warnings = {
|
Diagnostics<WarningLevel, WarningID> warnings = {
|
||||||
@@ -25,6 +25,7 @@ Diagnostics<WarningLevel, WarningID> warnings = {
|
|||||||
},
|
},
|
||||||
.paramWarnings = {},
|
.paramWarnings = {},
|
||||||
.state = DiagnosticsState<WarningID>(),
|
.state = DiagnosticsState<WarningID>(),
|
||||||
|
.traceDepth = 0,
|
||||||
.nbErrors = 0,
|
.nbErrors = 0,
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
@@ -41,18 +42,18 @@ static void printDiag(
|
|||||||
) {
|
) {
|
||||||
style_Set(stderr, color, true);
|
style_Set(stderr, color, true);
|
||||||
fprintf(stderr, "%s: ", type);
|
fprintf(stderr, "%s: ", type);
|
||||||
if (src) {
|
|
||||||
src->dump(lineNo);
|
|
||||||
fputs(": ", stderr);
|
|
||||||
}
|
|
||||||
if (flagfmt) {
|
|
||||||
style_Set(stderr, color, true);
|
|
||||||
fprintf(stderr, flagfmt, flag);
|
|
||||||
fputs("\n ", stderr);
|
|
||||||
}
|
|
||||||
style_Reset(stderr);
|
style_Reset(stderr);
|
||||||
vfprintf(stderr, fmt, args);
|
vfprintf(stderr, fmt, args);
|
||||||
|
if (flagfmt) {
|
||||||
|
style_Set(stderr, color, true);
|
||||||
|
putc(' ', stderr);
|
||||||
|
fprintf(stderr, flagfmt, flag);
|
||||||
|
}
|
||||||
putc('\n', stderr);
|
putc('\n', stderr);
|
||||||
|
|
||||||
|
if (src) {
|
||||||
|
src->printBacktrace(lineNo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[[noreturn]]
|
[[noreturn]]
|
||||||
@@ -101,26 +102,15 @@ void error(char const *fmt, ...) {
|
|||||||
warnings.incrementErrors();
|
warnings.incrementErrors();
|
||||||
}
|
}
|
||||||
|
|
||||||
void errorNoDump(char const *fmt, ...) {
|
|
||||||
va_list args;
|
|
||||||
style_Set(stderr, STYLE_RED, true);
|
|
||||||
fputs("error: ", stderr);
|
|
||||||
style_Reset(stderr);
|
|
||||||
va_start(args, fmt);
|
|
||||||
vfprintf(stderr, fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
warnings.incrementErrors();
|
|
||||||
}
|
|
||||||
|
|
||||||
void scriptError(char const *name, uint32_t lineNo, char const *fmt, va_list args) {
|
void scriptError(char const *name, uint32_t lineNo, char const *fmt, va_list args) {
|
||||||
style_Set(stderr, STYLE_RED, true);
|
style_Set(stderr, STYLE_RED, true);
|
||||||
fputs("error: ", stderr);
|
fputs("error: ", stderr);
|
||||||
style_Set(stderr, STYLE_CYAN, true);
|
style_Set(stderr, STYLE_CYAN, true);
|
||||||
fputs(name, stderr);
|
fputs(name, stderr);
|
||||||
style_Set(stderr, STYLE_CYAN, false);
|
style_Set(stderr, STYLE_CYAN, false);
|
||||||
fprintf(stderr, "(%" PRIu32 "): ", lineNo);
|
fprintf(stderr, "(%" PRIu32 ")", lineNo);
|
||||||
style_Reset(stderr);
|
style_Reset(stderr);
|
||||||
|
fputs(": ", stderr);
|
||||||
vfprintf(stderr, fmt, args);
|
vfprintf(stderr, fmt, args);
|
||||||
putc('\n', stderr);
|
putc('\n', stderr);
|
||||||
|
|
||||||
@@ -149,6 +139,32 @@ void fatal(char const *fmt, ...) {
|
|||||||
abortLinking(nullptr);
|
abortLinking(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[noreturn]]
|
||||||
|
void fatalTwo(
|
||||||
|
FileStackNode const &src1,
|
||||||
|
uint32_t lineNo1,
|
||||||
|
FileStackNode const &src2,
|
||||||
|
uint32_t lineNo2,
|
||||||
|
char const *fmt,
|
||||||
|
...
|
||||||
|
) {
|
||||||
|
va_list args;
|
||||||
|
style_Set(stderr, STYLE_RED, true);
|
||||||
|
fputs("FATAL: ", stderr);
|
||||||
|
style_Reset(stderr);
|
||||||
|
va_start(args, fmt);
|
||||||
|
vfprintf(stderr, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
putc('\n', stderr);
|
||||||
|
|
||||||
|
src1.printBacktrace(lineNo1);
|
||||||
|
fputs(" and also:\n", stderr);
|
||||||
|
src2.printBacktrace(lineNo2);
|
||||||
|
|
||||||
|
warnings.incrementErrors();
|
||||||
|
abortLinking(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
void requireZeroErrors() {
|
void requireZeroErrors() {
|
||||||
if (warnings.nbErrors != 0) {
|
if (warnings.nbErrors != 0) {
|
||||||
abortLinking("failed");
|
abortLinking("failed");
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
error: align-large-ofs.asm(2):
|
error: The absolute alignment offset (2) must be less than alignment size (2)
|
||||||
The absolute alignment offset (2) must be less than alignment size (2)
|
at align-large-ofs.asm(2)
|
||||||
Assembly aborted with 1 error!
|
Assembly aborted with 1 error!
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
error: align-large.asm(1):
|
error: Alignment must be between 0 and 16, not 17
|
||||||
Alignment must be between 0 and 16, not 17
|
at align-large.asm(1)
|
||||||
error: align-large.asm(2):
|
error: Alignment must be between 0 and 16, not 17
|
||||||
Alignment must be between 0 and 16, not 17
|
at align-large.asm(2)
|
||||||
Assembly aborted with 2 errors!
|
Assembly aborted with 2 errors!
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
error: align-offset.asm(4):
|
error: The absolute alignment offset (18) must be less than alignment size (16)
|
||||||
The absolute alignment offset (18) must be less than alignment size (16)
|
at align-offset.asm(4)
|
||||||
error: align-offset.asm(6):
|
error: The absolute alignment offset (20) must be less than alignment size (16)
|
||||||
The absolute alignment offset (20) must be less than alignment size (16)
|
at align-offset.asm(6)
|
||||||
Assembly aborted with 2 errors!
|
Assembly aborted with 2 errors!
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
error: align-pc-outside-section.asm(1):
|
error: Cannot output data outside of a SECTION
|
||||||
Cannot output data outside of a SECTION
|
at align-pc-outside-section.asm(1)
|
||||||
Assembly aborted with 1 error!
|
Assembly aborted with 1 error!
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
error: align-unattainable.asm(3):
|
error: Section "X"'s alignment cannot be attained in WRAM0
|
||||||
Section "X"'s alignment cannot be attained in WRAM0
|
at align-unattainable.asm(3)
|
||||||
Assembly aborted with 1 error!
|
Assembly aborted with 1 error!
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
error: anon-label-bad.asm(2):
|
error: Label "!0" created outside of a SECTION
|
||||||
Label "!0" created outside of a SECTION
|
at anon-label-bad.asm(2)
|
||||||
error: anon-label-bad.asm(6):
|
error: Reference to anonymous label 2 before, when only 1 has been created so far
|
||||||
Reference to anonymous label 2 before, when only 1 has been created so far
|
at anon-label-bad.asm(6)
|
||||||
error: anon-label-bad.asm(9):
|
error: syntax error, unexpected anonymous label
|
||||||
syntax error, unexpected anonymous label
|
at anon-label-bad.asm(9)
|
||||||
error: anon-label-bad.asm(10):
|
error: syntax error, unexpected anonymous label, expecting symbol or label or local label
|
||||||
syntax error, unexpected anonymous label, expecting symbol or label or local label
|
at anon-label-bad.asm(10)
|
||||||
error: anon-label-bad.asm(22):
|
error: syntax error, unexpected ::
|
||||||
syntax error, unexpected ::
|
at anon-label-bad.asm(22)
|
||||||
Assembly aborted with 5 errors!
|
Assembly aborted with 5 errors!
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
FATAL: assert-fatal.asm(1):
|
FATAL: Assertion failed: there are four lights
|
||||||
Assertion failed: there are four lights
|
at assert-fatal.asm(1)
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
error: assert-nosect-bank.asm(1):
|
error: PC has no bank outside of a section
|
||||||
PC has no bank outside of a section
|
at assert-nosect-bank.asm(1)
|
||||||
Assembly aborted with 1 error!
|
Assembly aborted with 1 error!
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
error: assert.asm(4):
|
error: Assertion failed
|
||||||
Assertion failed
|
at assert.asm(4)
|
||||||
error: assert.asm(7):
|
error: Assertion failed: @ ain't 0 now? (Hint: it's $1)
|
||||||
Assertion failed: @ ain't 0 now? (Hint: it's $1)
|
at assert.asm(7)
|
||||||
warning: assert.asm(10): [-Wassert]
|
warning: Assertion failed [-Wassert]
|
||||||
Assertion failed
|
at assert.asm(10)
|
||||||
error: assert.asm(18):
|
error: Expected constant expression: 'FloatingBase' is not constant at assembly time
|
||||||
Expected constant expression: 'FloatingBase' is not constant at assembly time
|
at assert.asm(18)
|
||||||
error: assert.asm(18):
|
error: Assertion failed
|
||||||
Assertion failed
|
at assert.asm(18)
|
||||||
FATAL: assert.asm(21):
|
FATAL: Assertion failed
|
||||||
Assertion failed
|
at assert.asm(21)
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
error: assert@-no-sect.asm(1):
|
error: PC has no value outside of a section
|
||||||
PC has no value outside of a section
|
at assert@-no-sect.asm(1)
|
||||||
Assembly aborted with 1 error!
|
Assembly aborted with 1 error!
|
||||||
|
|||||||
15
test/asm/backtrace-depth.asm
Normal file
15
test/asm/backtrace-depth.asm
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
macro careful
|
||||||
|
if _NARG == 20
|
||||||
|
warn "You're in too deep!"
|
||||||
|
else
|
||||||
|
careful \#, deeper
|
||||||
|
endc
|
||||||
|
endm
|
||||||
|
careful surface
|
||||||
|
|
||||||
|
macro recurse
|
||||||
|
recurse
|
||||||
|
endm
|
||||||
|
rept 3
|
||||||
|
recurse
|
||||||
|
endr
|
||||||
14
test/asm/backtrace-depth.err
Normal file
14
test/asm/backtrace-depth.err
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
warning: You're in too deep! [-Wuser]
|
||||||
|
at backtrace-depth.asm::careful(3)
|
||||||
|
<- backtrace-depth.asm::careful(5)
|
||||||
|
<- backtrace-depth.asm::careful(5)
|
||||||
|
...16 more...
|
||||||
|
<- backtrace-depth.asm::careful(5)
|
||||||
|
<- backtrace-depth.asm(8)
|
||||||
|
FATAL: Recursion limit (64) exceeded
|
||||||
|
at backtrace-depth.asm::recurse(11)
|
||||||
|
<- backtrace-depth.asm::recurse(11)
|
||||||
|
<- backtrace-depth.asm::recurse(11)
|
||||||
|
...60 more...
|
||||||
|
<- backtrace-depth.asm::REPT~1(14)
|
||||||
|
<- backtrace-depth.asm(13)
|
||||||
1
test/asm/backtrace-depth.flags
Normal file
1
test/asm/backtrace-depth.flags
Normal file
@@ -0,0 +1 @@
|
|||||||
|
-B 5
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
error: bad-precision.asm(1):
|
error: Fixed-point precision must be between 1 and 31, not 42
|
||||||
Fixed-point precision must be between 1 and 31, not 42
|
at bad-precision.asm(1)
|
||||||
Assembly aborted with 1 error!
|
Assembly aborted with 1 error!
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
error: bank.asm(13) -> bank.asm::def_sect(8):
|
error: Expected constant expression: Section "ROMX_ok1"'s bank is not known
|
||||||
Expected constant expression: Section "ROMX_ok1"'s bank is not known
|
at bank.asm::def_sect(8) <- bank.asm(13)
|
||||||
error: bank.asm(13) -> bank.asm::def_sect(8):
|
error: Expected constant expression: "Label_u3"'s bank is not known
|
||||||
Expected constant expression: "Label_u3"'s bank is not known
|
at bank.asm::def_sect(8) <- bank.asm(13)
|
||||||
error: bank.asm(15) -> bank.asm::def_sect(8):
|
error: Expected constant expression: Section "ROMX_bad"'s bank is not known
|
||||||
Expected constant expression: Section "ROMX_bad"'s bank is not known
|
at bank.asm::def_sect(8) <- bank.asm(15)
|
||||||
error: bank.asm(15) -> bank.asm::def_sect(8):
|
error: Expected constant expression: "Label_u5"'s bank is not known
|
||||||
Expected constant expression: "Label_u5"'s bank is not known
|
at bank.asm::def_sect(8) <- bank.asm(15)
|
||||||
error: bank.asm(17) -> bank.asm::def_sect(8):
|
error: Expected constant expression: Section "VRAM_bad"'s bank is not known
|
||||||
Expected constant expression: Section "VRAM_bad"'s bank is not known
|
at bank.asm::def_sect(8) <- bank.asm(17)
|
||||||
error: bank.asm(17) -> bank.asm::def_sect(8):
|
error: Expected constant expression: "Label_u7"'s bank is not known
|
||||||
Expected constant expression: "Label_u7"'s bank is not known
|
at bank.asm::def_sect(8) <- bank.asm(17)
|
||||||
error: bank.asm(19) -> bank.asm::def_sect(8):
|
error: Expected constant expression: Section "SRAM_bad"'s bank is not known
|
||||||
Expected constant expression: Section "SRAM_bad"'s bank is not known
|
at bank.asm::def_sect(8) <- bank.asm(19)
|
||||||
error: bank.asm(19) -> bank.asm::def_sect(8):
|
error: Expected constant expression: "Label_u9"'s bank is not known
|
||||||
Expected constant expression: "Label_u9"'s bank is not known
|
at bank.asm::def_sect(8) <- bank.asm(19)
|
||||||
error: bank.asm(22) -> bank.asm::def_sect(8):
|
error: Expected constant expression: Section "WRAMX_bad"'s bank is not known
|
||||||
Expected constant expression: Section "WRAMX_bad"'s bank is not known
|
at bank.asm::def_sect(8) <- bank.asm(22)
|
||||||
error: bank.asm(22) -> bank.asm::def_sect(8):
|
error: Expected constant expression: "Label_u12"'s bank is not known
|
||||||
Expected constant expression: "Label_u12"'s bank is not known
|
at bank.asm::def_sect(8) <- bank.asm(22)
|
||||||
error: bank.asm(26):
|
error: BANK argument must be a label
|
||||||
BANK argument must be a label
|
at bank.asm(26)
|
||||||
Assembly aborted with 11 errors!
|
Assembly aborted with 11 errors!
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
warning: block-comment-contents-error.asm(1): [-Wnested-comment]
|
warning: /* in block comment [-Wnested-comment]
|
||||||
/* in block comment
|
at block-comment-contents-error.asm(1)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
error: block-comment-termination-error.asm(1):
|
error: Unterminated block comment
|
||||||
Unterminated block comment
|
at block-comment-termination-error.asm(1)
|
||||||
error: block-comment-termination-error.asm(1):
|
error: syntax error, unexpected end of buffer
|
||||||
syntax error, unexpected end of buffer
|
at block-comment-termination-error.asm(1)
|
||||||
Assembly aborted with 2 errors!
|
Assembly aborted with 2 errors!
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
error: blue-paint.asm(9) -> blue-paint.asm::arg_to_arg(7):
|
error: Invalid character '3' after line continuation
|
||||||
Invalid character '3' after line continuation
|
at blue-paint.asm::arg_to_arg(7) <- blue-paint.asm(9)
|
||||||
error: blue-paint.asm(9) -> blue-paint.asm::arg_to_arg(7):
|
error: syntax error, unexpected number
|
||||||
syntax error, unexpected number
|
at blue-paint.asm::arg_to_arg(7) <- blue-paint.asm(9)
|
||||||
error: blue-paint.asm(9) -> blue-paint.asm::arg_to_arg(7):
|
error: Invalid character '}'
|
||||||
Invalid character '}'
|
at blue-paint.asm::arg_to_arg(7) <- blue-paint.asm(9)
|
||||||
error: blue-paint.asm(15) -> blue-paint.asm::arg_to_interp(13):
|
error: Invalid character '{'
|
||||||
Invalid character '{'
|
at blue-paint.asm::arg_to_interp(13) <- blue-paint.asm(15)
|
||||||
error: blue-paint.asm(15) -> blue-paint.asm::arg_to_interp(13):
|
error: Invalid character '}'
|
||||||
Invalid character '}'
|
at blue-paint.asm::arg_to_interp(13) <- blue-paint.asm(15)
|
||||||
error: blue-paint.asm(26) -> blue-paint.asm::endless(24):
|
error: Invalid character '1' after line continuation
|
||||||
Invalid character '1' after line continuation
|
at blue-paint.asm::endless(24) <- blue-paint.asm(26)
|
||||||
error: blue-paint.asm(26) -> blue-paint.asm::endless(24):
|
error: syntax error, unexpected number
|
||||||
syntax error, unexpected number
|
at blue-paint.asm::endless(24) <- blue-paint.asm(26)
|
||||||
FATAL: blue-paint.asm(30):
|
FATAL: Recursion limit (5) exceeded
|
||||||
Recursion limit (5) exceeded
|
at blue-paint.asm(30)
|
||||||
while expanding symbol "infinite"
|
while expanding symbol "infinite"
|
||||||
while expanding symbol "infinite"
|
while expanding symbol "infinite"
|
||||||
while expanding symbol "infinite"
|
while expanding symbol "infinite"
|
||||||
while expanding symbol "infinite"
|
while expanding symbol "infinite"
|
||||||
while expanding symbol "infinite"
|
while expanding symbol "infinite"
|
||||||
while expanding symbol "infinite"
|
while expanding symbol "infinite"
|
||||||
while expanding symbol "infinite"
|
while expanding symbol "infinite"
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
error: bracketed-macro-args.asm(33) -> bracketed-macro-args.asm::bad(26):
|
error: Bracketed symbol "nonnumeric" is not numeric
|
||||||
Bracketed symbol "nonnumeric" is not numeric
|
at bracketed-macro-args.asm::bad(26) <- bracketed-macro-args.asm(33)
|
||||||
error: bracketed-macro-args.asm(33) -> bracketed-macro-args.asm::bad(27):
|
error: Invalid bracketed macro argument '\<0>'
|
||||||
Invalid bracketed macro argument '\<0>'
|
at bracketed-macro-args.asm::bad(27) <- bracketed-macro-args.asm(33)
|
||||||
error: bracketed-macro-args.asm(33) -> bracketed-macro-args.asm::bad(28):
|
error: Bracketed symbol "undefined" does not exist
|
||||||
Bracketed symbol "undefined" does not exist
|
at bracketed-macro-args.asm::bad(28) <- bracketed-macro-args.asm(33)
|
||||||
error: bracketed-macro-args.asm(33) -> bracketed-macro-args.asm::bad(29):
|
error: Macro argument '\<2>' not defined
|
||||||
Macro argument '\<2>' not defined
|
at bracketed-macro-args.asm::bad(29) <- bracketed-macro-args.asm(33)
|
||||||
error: bracketed-macro-args.asm(33) -> bracketed-macro-args.asm::bad(30):
|
error: Macro argument '\<2>' not defined
|
||||||
Macro argument '\<2>' not defined
|
at bracketed-macro-args.asm::bad(30) <- bracketed-macro-args.asm(33)
|
||||||
error: bracketed-macro-args.asm(39) -> bracketed-macro-args.asm::toolong(36):
|
error: Bracketed symbol "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" does not exist
|
||||||
Bracketed symbol "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" does not exist
|
at bracketed-macro-args.asm::toolong(36) <- bracketed-macro-args.asm(39)
|
||||||
Assembly aborted with 6 errors!
|
Assembly aborted with 6 errors!
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
error: bracketed-symbols.asm(16):
|
error: Formatting string as type 'X'
|
||||||
Formatting string as type 'X'
|
at bracketed-symbols.asm(16)
|
||||||
error: bracketed-symbols.asm(20):
|
error: "Label" does not have a constant value
|
||||||
"Label" does not have a constant value
|
at bracketed-symbols.asm(20)
|
||||||
error: bracketed-symbols.asm(21):
|
error: PC does not have a constant value; the current section is not fixed
|
||||||
PC does not have a constant value; the current section is not fixed
|
at bracketed-symbols.asm(21)
|
||||||
Assembly aborted with 3 errors!
|
Assembly aborted with 3 errors!
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
warning: break.asm(9): [-Wuser]
|
warning: done 5 [-Wuser]
|
||||||
done 5
|
at break.asm(9)
|
||||||
warning: break.asm(28): [-Wuser]
|
warning: OK [-Wuser]
|
||||||
OK
|
at break.asm(28)
|
||||||
error: break.asm(29):
|
error: BREAK can only be used inside a REPT/FOR block
|
||||||
BREAK can only be used inside a REPT/FOR block
|
at break.asm(29)
|
||||||
FATAL: break.asm(30) -> break.asm::REPT~1(34):
|
FATAL: Ended block with 1 unterminated IF construct
|
||||||
Ended block with 1 unterminated IF construct
|
at break.asm::REPT~1(34) <- break.asm(30)
|
||||||
|
|||||||
@@ -1,57 +1,57 @@
|
|||||||
error: builtin-overwrite.asm(36) -> builtin-overwrite.asm::tickle(5):
|
error: Built-in symbol '__UTC_YEAR__' cannot be purged
|
||||||
Built-in symbol '__UTC_YEAR__' cannot be purged
|
at builtin-overwrite.asm::tickle(5) <- builtin-overwrite.asm(36)
|
||||||
error: builtin-overwrite.asm(36) -> builtin-overwrite.asm::tickle(6):
|
error: Built-in symbol '__UTC_YEAR__' cannot be purged
|
||||||
Built-in symbol '__UTC_YEAR__' cannot be purged
|
at builtin-overwrite.asm::tickle(6) <- builtin-overwrite.asm(36)
|
||||||
error: builtin-overwrite.asm(36) -> builtin-overwrite.asm::tickle(9):
|
error: '__UTC_YEAR__' already defined as built-in
|
||||||
'__UTC_YEAR__' already defined at <builtin>
|
at builtin-overwrite.asm::tickle(9) <- builtin-overwrite.asm(36)
|
||||||
error: builtin-overwrite.asm(36) -> builtin-overwrite.asm::tickle(10):
|
error: '__UTC_YEAR__' already defined as built-in
|
||||||
'__UTC_YEAR__' already defined at <builtin>
|
at builtin-overwrite.asm::tickle(10) <- builtin-overwrite.asm(36)
|
||||||
error: builtin-overwrite.asm(36) -> builtin-overwrite.asm::tickle(13):
|
error: '__UTC_YEAR__' already defined as built-in constant
|
||||||
'__UTC_YEAR__' already defined as constant at <builtin>
|
at builtin-overwrite.asm::tickle(13) <- builtin-overwrite.asm(36)
|
||||||
error: builtin-overwrite.asm(36) -> builtin-overwrite.asm::tickle(14):
|
error: '__UTC_YEAR__' already defined as built-in constant
|
||||||
'__UTC_YEAR__' already defined as constant at <builtin>
|
at builtin-overwrite.asm::tickle(14) <- builtin-overwrite.asm(36)
|
||||||
error: builtin-overwrite.asm(36) -> builtin-overwrite.asm::tickle(17):
|
error: '__UTC_YEAR__' already defined as built-in
|
||||||
'__UTC_YEAR__' already defined at <builtin>
|
at builtin-overwrite.asm::tickle(17) <- builtin-overwrite.asm(36)
|
||||||
error: builtin-overwrite.asm(36) -> builtin-overwrite.asm::tickle(18):
|
error: '__UTC_YEAR__' already defined as built-in
|
||||||
'__UTC_YEAR__' already defined at <builtin>
|
at builtin-overwrite.asm::tickle(18) <- builtin-overwrite.asm(36)
|
||||||
error: builtin-overwrite.asm(36) -> builtin-overwrite.asm::tickle(21):
|
error: '__UTC_YEAR__' already defined as built-in constant
|
||||||
'__UTC_YEAR__' already defined as constant at <builtin>
|
at builtin-overwrite.asm::tickle(21) <- builtin-overwrite.asm(36)
|
||||||
error: builtin-overwrite.asm(36) -> builtin-overwrite.asm::tickle(22):
|
error: '__UTC_YEAR__' already defined as built-in constant
|
||||||
'__UTC_YEAR__' already defined as constant at <builtin>
|
at builtin-overwrite.asm::tickle(22) <- builtin-overwrite.asm(36)
|
||||||
error: builtin-overwrite.asm(36) -> builtin-overwrite.asm::tickle(25):
|
error: Built-in symbol '__UTC_YEAR__' cannot be redefined
|
||||||
Built-in symbol '__UTC_YEAR__' cannot be redefined
|
at builtin-overwrite.asm::tickle(25) <- builtin-overwrite.asm(36)
|
||||||
error: builtin-overwrite.asm(36) -> builtin-overwrite.asm::tickle(26):
|
error: Built-in symbol '__UTC_YEAR__' cannot be redefined
|
||||||
Built-in symbol '__UTC_YEAR__' cannot be redefined
|
at builtin-overwrite.asm::tickle(26) <- builtin-overwrite.asm(36)
|
||||||
error: builtin-overwrite.asm(36) -> builtin-overwrite.asm::tickle(29):
|
error: '__UTC_YEAR__' already defined as built-in non-EQUS
|
||||||
'__UTC_YEAR__' already defined as non-EQUS at <builtin>
|
at builtin-overwrite.asm::tickle(29) <- builtin-overwrite.asm(36)
|
||||||
error: builtin-overwrite.asm(36) -> builtin-overwrite.asm::tickle(30):
|
error: '__UTC_YEAR__' already defined as built-in non-EQUS
|
||||||
'__UTC_YEAR__' already defined as non-EQUS at <builtin>
|
at builtin-overwrite.asm::tickle(30) <- builtin-overwrite.asm(36)
|
||||||
error: builtin-overwrite.asm(37) -> builtin-overwrite.asm::tickle(5):
|
error: Built-in symbol '__ISO_8601_UTC__' cannot be purged
|
||||||
Built-in symbol '__ISO_8601_UTC__' cannot be purged
|
at builtin-overwrite.asm::tickle(5) <- builtin-overwrite.asm(37)
|
||||||
error: builtin-overwrite.asm(37) -> builtin-overwrite.asm::tickle(6):
|
error: Built-in symbol '__ISO_8601_UTC__' cannot be purged
|
||||||
Built-in symbol '__ISO_8601_UTC__' cannot be purged
|
at builtin-overwrite.asm::tickle(6) <- builtin-overwrite.asm(37)
|
||||||
error: builtin-overwrite.asm(37) -> builtin-overwrite.asm::tickle(9):
|
error: '__ISO_8601_UTC__' already defined as built-in
|
||||||
'__ISO_8601_UTC__' already defined at <builtin>
|
at builtin-overwrite.asm::tickle(9) <- builtin-overwrite.asm(37)
|
||||||
error: builtin-overwrite.asm(37) -> builtin-overwrite.asm::tickle(10):
|
error: '__ISO_8601_UTC__' already defined as built-in
|
||||||
'__ISO_8601_UTC__' already defined at <builtin>
|
at builtin-overwrite.asm::tickle(10) <- builtin-overwrite.asm(37)
|
||||||
error: builtin-overwrite.asm(37) -> builtin-overwrite.asm::tickle(13):
|
error: '__ISO_8601_UTC__' already defined as built-in constant
|
||||||
'__ISO_8601_UTC__' already defined as constant at <builtin>
|
at builtin-overwrite.asm::tickle(13) <- builtin-overwrite.asm(37)
|
||||||
error: builtin-overwrite.asm(37) -> builtin-overwrite.asm::tickle(14):
|
error: '__ISO_8601_UTC__' already defined as built-in constant
|
||||||
'__ISO_8601_UTC__' already defined as constant at <builtin>
|
at builtin-overwrite.asm::tickle(14) <- builtin-overwrite.asm(37)
|
||||||
error: builtin-overwrite.asm(37) -> builtin-overwrite.asm::tickle(17):
|
error: '__ISO_8601_UTC__' already defined as built-in
|
||||||
'__ISO_8601_UTC__' already defined at <builtin>
|
at builtin-overwrite.asm::tickle(17) <- builtin-overwrite.asm(37)
|
||||||
error: builtin-overwrite.asm(37) -> builtin-overwrite.asm::tickle(18):
|
error: '__ISO_8601_UTC__' already defined as built-in
|
||||||
'__ISO_8601_UTC__' already defined at <builtin>
|
at builtin-overwrite.asm::tickle(18) <- builtin-overwrite.asm(37)
|
||||||
error: builtin-overwrite.asm(37) -> builtin-overwrite.asm::tickle(21):
|
error: '__ISO_8601_UTC__' already defined as built-in constant
|
||||||
'__ISO_8601_UTC__' already defined as constant at <builtin>
|
at builtin-overwrite.asm::tickle(21) <- builtin-overwrite.asm(37)
|
||||||
error: builtin-overwrite.asm(37) -> builtin-overwrite.asm::tickle(22):
|
error: '__ISO_8601_UTC__' already defined as built-in constant
|
||||||
'__ISO_8601_UTC__' already defined as constant at <builtin>
|
at builtin-overwrite.asm::tickle(22) <- builtin-overwrite.asm(37)
|
||||||
error: builtin-overwrite.asm(37) -> builtin-overwrite.asm::tickle(25):
|
error: '__ISO_8601_UTC__' already defined as built-in non-EQU
|
||||||
'__ISO_8601_UTC__' already defined as non-EQU at <builtin>
|
at builtin-overwrite.asm::tickle(25) <- builtin-overwrite.asm(37)
|
||||||
error: builtin-overwrite.asm(37) -> builtin-overwrite.asm::tickle(26):
|
error: '__ISO_8601_UTC__' already defined as built-in non-EQU
|
||||||
'__ISO_8601_UTC__' already defined as non-EQU at <builtin>
|
at builtin-overwrite.asm::tickle(26) <- builtin-overwrite.asm(37)
|
||||||
error: builtin-overwrite.asm(37) -> builtin-overwrite.asm::tickle(29):
|
error: Built-in symbol '__ISO_8601_UTC__' cannot be redefined
|
||||||
Built-in symbol '__ISO_8601_UTC__' cannot be redefined
|
at builtin-overwrite.asm::tickle(29) <- builtin-overwrite.asm(37)
|
||||||
error: builtin-overwrite.asm(37) -> builtin-overwrite.asm::tickle(30):
|
error: Built-in symbol '__ISO_8601_UTC__' cannot be redefined
|
||||||
Built-in symbol '__ISO_8601_UTC__' cannot be redefined
|
at builtin-overwrite.asm::tickle(30) <- builtin-overwrite.asm(37)
|
||||||
Assembly aborted with 28 errors!
|
Assembly aborted with 28 errors!
|
||||||
|
|||||||
@@ -1,33 +1,33 @@
|
|||||||
error: builtin-reserved.asm(3):
|
error: Undefined symbol '_NARG'
|
||||||
Undefined symbol '_NARG'
|
at builtin-reserved.asm(3)
|
||||||
error: builtin-reserved.asm(5):
|
error: '_NARG' is reserved for a built-in symbol
|
||||||
'_NARG' is reserved for a built-in symbol
|
at builtin-reserved.asm(5)
|
||||||
error: builtin-reserved.asm(6):
|
error: '_NARG' is reserved for a built-in symbol
|
||||||
'_NARG' is reserved for a built-in symbol
|
at builtin-reserved.asm(6)
|
||||||
error: builtin-reserved.asm(8):
|
error: '_NARG' is reserved for a built-in constant symbol
|
||||||
'_NARG' is reserved for a built-in symbol
|
at builtin-reserved.asm(8)
|
||||||
error: builtin-reserved.asm(9):
|
error: '_NARG' is reserved for a built-in constant symbol
|
||||||
'_NARG' is reserved for a built-in symbol
|
at builtin-reserved.asm(9)
|
||||||
error: builtin-reserved.asm(11):
|
error: '_NARG' is reserved for a built-in symbol
|
||||||
'_NARG' is reserved for a built-in symbol
|
at builtin-reserved.asm(11)
|
||||||
error: builtin-reserved.asm(12):
|
error: '_NARG' is reserved for a built-in non-EQUS symbol
|
||||||
'_NARG' is reserved for a built-in symbol
|
at builtin-reserved.asm(12)
|
||||||
error: builtin-reserved.asm(15):
|
error: '_NARG' is reserved for a built-in symbol
|
||||||
'_NARG' is reserved for a built-in symbol
|
at builtin-reserved.asm(15)
|
||||||
error: builtin-reserved.asm(20):
|
error: Undefined symbol '.'
|
||||||
Undefined symbol '.'
|
at builtin-reserved.asm(20)
|
||||||
error: builtin-reserved.asm(22):
|
error: '.' is reserved for a built-in symbol
|
||||||
'.' is reserved for a built-in symbol
|
at builtin-reserved.asm(22)
|
||||||
error: builtin-reserved.asm(23):
|
error: '.' is reserved for a built-in non-EQU symbol
|
||||||
'.' is reserved for a built-in symbol
|
at builtin-reserved.asm(23)
|
||||||
error: builtin-reserved.asm(25):
|
error: '.' is reserved for a built-in constant symbol
|
||||||
'.' is reserved for a built-in symbol
|
at builtin-reserved.asm(25)
|
||||||
error: builtin-reserved.asm(26):
|
error: '.' is reserved for a built-in constant symbol
|
||||||
'.' is reserved for a built-in symbol
|
at builtin-reserved.asm(26)
|
||||||
error: builtin-reserved.asm(28):
|
error: '.' is reserved for a built-in symbol
|
||||||
'.' is reserved for a built-in symbol
|
at builtin-reserved.asm(28)
|
||||||
error: builtin-reserved.asm(29):
|
error: '.' is reserved for a built-in symbol
|
||||||
'.' is reserved for a built-in symbol
|
at builtin-reserved.asm(29)
|
||||||
error: builtin-reserved.asm(32):
|
error: "." has no value outside of a label scope
|
||||||
"." has no value outside of a label scope
|
at builtin-reserved.asm(32)
|
||||||
Assembly aborted with 16 errors!
|
Assembly aborted with 16 errors!
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
warning: bytelen-strbyte.asm(35): [-Wbuiltin-args]
|
warning: STRBYTE: Index starts at 0 [-Wbuiltin-args]
|
||||||
STRBYTE: Index starts at 0
|
at bytelen-strbyte.asm(35)
|
||||||
warning: bytelen-strbyte.asm(36): [-Wbuiltin-args]
|
warning: STRBYTE: Index 10 is past the end of the string [-Wbuiltin-args]
|
||||||
STRBYTE: Index 10 is past the end of the string
|
at bytelen-strbyte.asm(36)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
error: character-escape-at-end.asm(1):
|
error: Illegal character escape at end of input
|
||||||
Illegal character escape at end of input
|
at character-escape-at-end.asm(1)
|
||||||
error: character-escape-at-end.asm(1):
|
error: Unterminated string
|
||||||
Unterminated string
|
at character-escape-at-end.asm(1)
|
||||||
Assembly aborted with 2 errors!
|
Assembly aborted with 2 errors!
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
error: character-escapes.asm(10) -> character-escapes.asm::m(6):
|
error: Illegal character escape 'z'
|
||||||
Illegal character escape 'z'
|
at character-escapes.asm::m(6) <- character-escapes.asm(10)
|
||||||
error: character-escapes.asm(10) -> character-escapes.asm::m(7):
|
error: Invalid character '\' in bracketed macro argument
|
||||||
Invalid character '\' in bracketed macro argument
|
at character-escapes.asm::m(7) <- character-escapes.asm(10)
|
||||||
error: character-escapes.asm(10) -> character-escapes.asm::m(8):
|
error: Invalid character '\t' in bracketed macro argument
|
||||||
Invalid character '\t' in bracketed macro argument
|
at character-escapes.asm::m(8) <- character-escapes.asm(10)
|
||||||
Assembly aborted with 3 errors!
|
Assembly aborted with 3 errors!
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
warning: character-literals.asm(31) -> character-literals.asm::char(13): [-Wunmapped-char]
|
warning: Unmapped character '?' [-Wunmapped-char]
|
||||||
Unmapped character '?'
|
at character-literals.asm::char(13) <- character-literals.asm(31)
|
||||||
error: character-literals.asm(32) -> character-literals.asm::char(13):
|
error: Character literals must be a single charmap unit
|
||||||
Character literals must be a single charmap unit
|
at character-literals.asm::char(13) <- character-literals.asm(32)
|
||||||
error: character-literals.asm(33) -> character-literals.asm::char(13):
|
error: Character literals must be a single charmap unit
|
||||||
Character literals must be a single charmap unit
|
at character-literals.asm::char(13) <- character-literals.asm(33)
|
||||||
warning: character-literals.asm(34) -> character-literals.asm::char(13): [-Wunmapped-char]
|
warning: Unmapped character '\n' [-Wunmapped-char]
|
||||||
Unmapped character '\n'
|
at character-literals.asm::char(13) <- character-literals.asm(34)
|
||||||
warning: character-literals.asm(34) -> character-literals.asm::char(13): [-Wunmapped-char]
|
warning: Unmapped character '\r' [-Wunmapped-char]
|
||||||
Unmapped character '\r'
|
at character-literals.asm::char(13) <- character-literals.asm(34)
|
||||||
warning: character-literals.asm(34) -> character-literals.asm::char(13): [-Wunmapped-char]
|
warning: Unmapped character '\t' [-Wunmapped-char]
|
||||||
Unmapped character '\t'
|
at character-literals.asm::char(13) <- character-literals.asm(34)
|
||||||
error: character-literals.asm(34) -> character-literals.asm::char(13):
|
error: Character literals must be a single charmap unit
|
||||||
Character literals must be a single charmap unit
|
at character-literals.asm::char(13) <- character-literals.asm(34)
|
||||||
error: character-literals.asm(35):
|
error: Unterminated character
|
||||||
Unterminated character
|
at character-literals.asm(35)
|
||||||
error: character-literals.asm(35):
|
error: Character literals must be a single charmap unit
|
||||||
Character literals must be a single charmap unit
|
at character-literals.asm(35)
|
||||||
Assembly aborted with 5 errors!
|
Assembly aborted with 5 errors!
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
error: charmap-empty.asm(1):
|
error: Cannot map an empty string
|
||||||
Cannot map an empty string
|
at charmap-empty.asm(1)
|
||||||
error: charmap-empty.asm(2):
|
error: syntax error, unexpected end of line
|
||||||
syntax error, unexpected end of line
|
at charmap-empty.asm(2)
|
||||||
Assembly aborted with 2 errors!
|
Assembly aborted with 2 errors!
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
error: charmap-inheritance.asm(26):
|
error: Base charmap 'eggs' doesn't exist
|
||||||
Base charmap 'eggs' doesn't exist
|
at charmap-inheritance.asm(26)
|
||||||
Assembly aborted with 1 error!
|
Assembly aborted with 1 error!
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
error: charsize.asm(17):
|
error: CHARSIZE: No character mapping for ""
|
||||||
CHARSIZE: No character mapping for ""
|
at charsize.asm(17)
|
||||||
error: charsize.asm(18):
|
error: CHARSIZE: No character mapping for "hello world"
|
||||||
CHARSIZE: No character mapping for "hello world"
|
at charsize.asm(18)
|
||||||
error: charsize.asm(19):
|
error: CHARSIZE: No character mapping for "abcdef"
|
||||||
CHARSIZE: No character mapping for "abcdef"
|
at charsize.asm(19)
|
||||||
error: charsize.asm(20):
|
error: CHARSIZE: No character mapping for "é"
|
||||||
CHARSIZE: No character mapping for "é"
|
at charsize.asm(20)
|
||||||
Assembly aborted with 4 errors!
|
Assembly aborted with 4 errors!
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
error: charval.asm(23):
|
error: CHARVAL: Character mapping for "b" must have a single value
|
||||||
CHARVAL: Character mapping for "b" must have a single value
|
at charval.asm(23)
|
||||||
error: charval.asm(24):
|
error: CHARVAL: No character mapping for "ab"
|
||||||
CHARVAL: No character mapping for "ab"
|
at charval.asm(24)
|
||||||
error: charval.asm(25):
|
error: CHARVAL: No character mapping for "abc"
|
||||||
CHARVAL: No character mapping for "abc"
|
at charval.asm(25)
|
||||||
error: charval.asm(26):
|
error: CHARVAL: No character mapping for "cd"
|
||||||
CHARVAL: No character mapping for "cd"
|
at charval.asm(26)
|
||||||
error: charval.asm(27):
|
error: CHARVAL: No character mapping for "xyz"
|
||||||
CHARVAL: No character mapping for "xyz"
|
at charval.asm(27)
|
||||||
warning: charval.asm(28): [-Wbuiltin-args]
|
warning: CHARVAL: Index starts at 0 [-Wbuiltin-args]
|
||||||
CHARVAL: Index starts at 0
|
at charval.asm(28)
|
||||||
warning: charval.asm(29): [-Wbuiltin-args]
|
warning: CHARVAL: Index 10 is past the end of the character mapping [-Wbuiltin-args]
|
||||||
CHARVAL: Index 10 is past the end of the character mapping
|
at charval.asm(29)
|
||||||
Assembly aborted with 5 errors!
|
Assembly aborted with 5 errors!
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
error: code-after-endm-endr-endc.asm(6):
|
error: syntax error, unexpected PRINTLN, expecting end of line or end of buffer or end of fragment literal
|
||||||
syntax error, unexpected PRINTLN, expecting end of line or end of buffer or end of fragment literal
|
at code-after-endm-endr-endc.asm(6)
|
||||||
error: code-after-endm-endr-endc.asm(7):
|
error: Undefined macro "mac"
|
||||||
Undefined macro "mac"
|
at code-after-endm-endr-endc.asm(7)
|
||||||
error: code-after-endm-endr-endc.asm(12):
|
error: syntax error, unexpected PRINTLN, expecting end of line or end of buffer or end of fragment literal
|
||||||
syntax error, unexpected PRINTLN, expecting end of line or end of buffer or end of fragment literal
|
at code-after-endm-endr-endc.asm(12)
|
||||||
error: code-after-endm-endr-endc.asm(17):
|
error: syntax error, unexpected PRINTLN, expecting end of line
|
||||||
syntax error, unexpected PRINTLN, expecting end of line
|
at code-after-endm-endr-endc.asm(17)
|
||||||
error: code-after-endm-endr-endc.asm(19):
|
error: syntax error, unexpected PRINTLN, expecting end of line or end of buffer or end of fragment literal
|
||||||
syntax error, unexpected PRINTLN, expecting end of line or end of buffer or end of fragment literal
|
at code-after-endm-endr-endc.asm(19)
|
||||||
error: code-after-endm-endr-endc.asm(23):
|
error: syntax error, unexpected PRINTLN, expecting end of line
|
||||||
syntax error, unexpected PRINTLN, expecting end of line
|
at code-after-endm-endr-endc.asm(23)
|
||||||
error: code-after-endm-endr-endc.asm(25):
|
error: syntax error, unexpected PRINTLN, expecting end of line or end of buffer or end of fragment literal
|
||||||
syntax error, unexpected PRINTLN, expecting end of line or end of buffer or end of fragment literal
|
at code-after-endm-endr-endc.asm(25)
|
||||||
Assembly aborted with 7 errors!
|
Assembly aborted with 7 errors!
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
error: command-line-symbols.asm(3):
|
error: 'FOO' already defined (should it be {interpolated} to define its contents "hello"?)
|
||||||
'FOO' already defined at <command-line>
|
at command-line-symbols.asm(3)
|
||||||
(should it be {interpolated} to define its contents "hello"?)
|
and also:
|
||||||
|
at <command-line>
|
||||||
Assembly aborted with 1 error!
|
Assembly aborted with 1 error!
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
error: compound-assignment.asm(35):
|
error: Expected constant expression: 'UnDeFiNeD' is not constant at assembly time
|
||||||
Expected constant expression: 'UnDeFiNeD' is not constant at assembly time
|
at compound-assignment.asm(35)
|
||||||
Assembly aborted with 1 error!
|
Assembly aborted with 1 error!
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
error: const-and.asm(2):
|
error: PC has no value outside of a section
|
||||||
PC has no value outside of a section
|
at const-and.asm(2)
|
||||||
error: const-and.asm(11):
|
error: Expected constant expression: 'Aligned' is not constant at assembly time
|
||||||
Expected constant expression: 'Aligned' is not constant at assembly time
|
at const-and.asm(11)
|
||||||
error: const-and.asm(17):
|
error: Expected constant expression: PC is not constant at assembly time
|
||||||
Expected constant expression: PC is not constant at assembly time
|
at const-and.asm(17)
|
||||||
error: const-and.asm(20):
|
error: Expected constant expression: 'Floating' is not constant at assembly time
|
||||||
Expected constant expression: 'Floating' is not constant at assembly time
|
at const-and.asm(20)
|
||||||
Assembly aborted with 4 errors!
|
Assembly aborted with 4 errors!
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
error: const-not.asm(3):
|
error: Assertion failed
|
||||||
Assertion failed
|
at const-not.asm(3)
|
||||||
Assembly aborted with 1 error!
|
Assembly aborted with 1 error!
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
error: const-zero.asm(21) -> const-zero.asm::test_or(14):
|
error: Expected constant expression: PC is not constant at assembly time
|
||||||
Expected constant expression: PC is not constant at assembly time
|
at const-zero.asm::test_or(14) <- const-zero.asm(21)
|
||||||
Assembly aborted with 1 error!
|
Assembly aborted with 1 error!
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
warning: continues-after-missing-include/a.asm(7): [-Wuser]
|
warning: still going! [-Wuser]
|
||||||
still going!
|
at continues-after-missing-include/a.asm(7)
|
||||||
warning: continues-after-missing-include/a.asm(9): [-Wuser]
|
warning: and going! [-Wuser]
|
||||||
and going!
|
at continues-after-missing-include/a.asm(9)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
warning: correct-line-number.asm(5): [-Wuser]
|
warning: Am I geting ahead of myself? [-Wuser]
|
||||||
Am I geting ahead of myself?
|
at correct-line-number.asm(5)
|
||||||
warning: correct-line-number.asm(11): [-Wuser]
|
warning: Hopefully not. [-Wuser]
|
||||||
Hopefully not.
|
at correct-line-number.asm(11)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
error: data-in-ram.asm(2):
|
error: Section 'code' cannot contain code or data (not ROM0 or ROMX)
|
||||||
Section 'code' cannot contain code or data (not ROM0 or ROMX)
|
at data-in-ram.asm(2)
|
||||||
error: data-in-ram.asm(4):
|
error: Section 'data' cannot contain code or data (not ROM0 or ROMX)
|
||||||
Section 'data' cannot contain code or data (not ROM0 or ROMX)
|
at data-in-ram.asm(4)
|
||||||
Assembly aborted with 2 errors!
|
Assembly aborted with 2 errors!
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
warning: date-time.asm(2): [-Wobsolete]
|
warning: `__DATE__` is deprecated; use `__ISO_8601_LOCAL__` [-Wobsolete]
|
||||||
`__DATE__` is deprecated; use `__ISO_8601_LOCAL__`
|
at date-time.asm(2)
|
||||||
warning: date-time.asm(3): [-Wobsolete]
|
warning: `__TIME__` is deprecated; use `__ISO_8601_LOCAL__` [-Wobsolete]
|
||||||
`__TIME__` is deprecated; use `__ISO_8601_LOCAL__`
|
at date-time.asm(3)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
error: def-scoped.asm(10):
|
error: syntax error, unexpected local label, expecting symbol
|
||||||
syntax error, unexpected local label, expecting symbol
|
at def-scoped.asm(10)
|
||||||
error: def-scoped.asm(13):
|
error: syntax error, unexpected local label, expecting symbol
|
||||||
syntax error, unexpected local label, expecting symbol
|
at def-scoped.asm(13)
|
||||||
error: def-scoped.asm(16):
|
error: syntax error, unexpected local label, expecting symbol
|
||||||
syntax error, unexpected local label, expecting symbol
|
at def-scoped.asm(16)
|
||||||
Assembly aborted with 3 errors!
|
Assembly aborted with 3 errors!
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
error: def.asm(23):
|
error: 'constant' already defined
|
||||||
'constant' already defined at def.asm(10)
|
at def.asm(23)
|
||||||
error: def.asm(35):
|
and also:
|
||||||
'mac' already defined as non-EQU at def.asm(32)
|
at def.asm(10)
|
||||||
error: def.asm(38):
|
error: 'mac' already defined as non-EQU
|
||||||
'name' already defined at def.asm(37)
|
at def.asm(35)
|
||||||
(should it be {interpolated} to define its contents "constant2"?)
|
and also:
|
||||||
error: def.asm(42):
|
at def.asm(32)
|
||||||
'name' already defined at def.asm(40)
|
error: 'name' already defined (should it be {interpolated} to define its contents "constant2"?)
|
||||||
(should it be {interpolated} to define its contents "mac2"?)
|
at def.asm(38)
|
||||||
|
and also:
|
||||||
|
at def.asm(37)
|
||||||
|
error: 'name' already defined (should it be {interpolated} to define its contents "mac2"?)
|
||||||
|
at def.asm(42)
|
||||||
|
and also:
|
||||||
|
at def.asm(40)
|
||||||
Assembly aborted with 4 errors!
|
Assembly aborted with 4 errors!
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
warning: Invalid warning flag parameter "truncation=256"; capping at maximum 2
|
warning: Invalid warning flag parameter "truncation=256"; capping at maximum 2
|
||||||
warning: diagnostic-parameter-cap.asm(3): [-Wtruncation]
|
warning: Expression must be 8-bit; use LOW() to force 8-bit [-Wtruncation]
|
||||||
Expression must be 8-bit; use LOW() to force 8-bit
|
at diagnostic-parameter-cap.asm(3)
|
||||||
warning: diagnostic-parameter-cap.asm(4): [-Wtruncation]
|
warning: Expression must be 8-bit; use LOW() to force 8-bit [-Wtruncation]
|
||||||
Expression must be 8-bit; use LOW() to force 8-bit
|
at diagnostic-parameter-cap.asm(4)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
error: diff-marks.asm(2):
|
error: syntax error, unexpected - at the beginning of the line (is it a leftover diff mark?)
|
||||||
syntax error, unexpected - at the beginning of the line (is it a leftover diff mark?)
|
at diff-marks.asm(2)
|
||||||
error: diff-marks.asm(3):
|
error: syntax error, unexpected + at the beginning of the line (is it a leftover diff mark?)
|
||||||
syntax error, unexpected + at the beginning of the line (is it a leftover diff mark?)
|
at diff-marks.asm(3)
|
||||||
Assembly aborted with 2 errors!
|
Assembly aborted with 2 errors!
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
FATAL: divzero-instr.asm(2):
|
FATAL: Division by zero
|
||||||
Division by zero
|
at divzero-instr.asm(2)
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
FATAL: divzero-section-bank.asm(1):
|
FATAL: Division by zero
|
||||||
Division by zero
|
at divzero-section-bank.asm(1)
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
error: double-purge.asm(3):
|
error: Undefined symbol 'n' was already purged
|
||||||
Undefined symbol 'n' was already purged
|
at double-purge.asm(3)
|
||||||
Assembly aborted with 1 error!
|
Assembly aborted with 1 error!
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
error: ds-bad.asm(3):
|
error: Expected constant expression: 'unknown' is not constant at assembly time
|
||||||
Expected constant expression: 'unknown' is not constant at assembly time
|
at ds-bad.asm(3)
|
||||||
warning: ds-bad.asm(4): [-Wtruncation]
|
warning: Expression must be 8-bit; use LOW() to force 8-bit [-Wtruncation]
|
||||||
Expression must be 8-bit; use LOW() to force 8-bit
|
at ds-bad.asm(4)
|
||||||
Assembly aborted with 1 error!
|
Assembly aborted with 1 error!
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
error: duplicate-section.asm(4):
|
error: Section already defined
|
||||||
Section already defined previously at duplicate-section.asm(2)
|
at duplicate-section.asm(4)
|
||||||
FATAL: duplicate-section.asm(4):
|
and also:
|
||||||
Cannot create section "sec" (1 error)
|
at duplicate-section.asm(2)
|
||||||
|
FATAL: Cannot create section "sec" (1 error)
|
||||||
|
at duplicate-section.asm(4)
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
FATAL: elif-after-else.asm(14):
|
FATAL: Found ELIF after an ELSE block
|
||||||
Found ELIF after an ELSE block
|
at elif-after-else.asm(14)
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
FATAL: elif-after-taken-if.asm(21):
|
FATAL: Division by zero
|
||||||
Division by zero
|
at elif-after-taken-if.asm(21)
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
FATAL: elif-outside-if.asm(1):
|
FATAL: Found ELIF outside of an IF construct
|
||||||
Found ELIF outside of an IF construct
|
at elif-outside-if.asm(1)
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
FATAL: else-outside-if.asm(1):
|
FATAL: Found ELSE outside of an IF construct
|
||||||
Found ELSE outside of an IF construct
|
at else-outside-if.asm(1)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
warning: empty-data-directive.asm(6): [-Wempty-data-directive]
|
warning: DB directive without data in ROM [-Wempty-data-directive]
|
||||||
DB directive without data in ROM
|
at empty-data-directive.asm(6)
|
||||||
warning: empty-data-directive.asm(7): [-Wempty-data-directive]
|
warning: DW directive without data in ROM [-Wempty-data-directive]
|
||||||
DW directive without data in ROM
|
at empty-data-directive.asm(7)
|
||||||
warning: empty-data-directive.asm(8): [-Wempty-data-directive]
|
warning: DL directive without data in ROM [-Wempty-data-directive]
|
||||||
DL directive without data in ROM
|
at empty-data-directive.asm(8)
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
FATAL: empty-local-purged.asm(3):
|
FATAL: Unqualified local label '.test' in main scope
|
||||||
Unqualified local label '.test' in main scope
|
at empty-local-purged.asm(3)
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
FATAL: empty-local-referenced.asm(3):
|
FATAL: 'Referenced.' is a nonsensical reference to an empty local label
|
||||||
'Referenced.' is a nonsensical reference to an empty local label
|
at empty-local-referenced.asm(3)
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
FATAL: empty-local-used.asm(4):
|
FATAL: 'Label.' is a nonsensical reference to an empty local label
|
||||||
'Label.' is a nonsensical reference to an empty local label
|
at empty-local-used.asm(4)
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
FATAL: empty-local.asm(4):
|
FATAL: 'Label.' is a nonsensical reference to an empty local label
|
||||||
'Label.' is a nonsensical reference to an empty local label
|
at empty-local.asm(4)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
error: empty-raw-identifier.asm(5) -> empty-raw-identifier.asm::macro(3):
|
error: Invalid character '?' in bracketed macro argument
|
||||||
Invalid character '?' in bracketed macro argument
|
at empty-raw-identifier.asm::macro(3) <- empty-raw-identifier.asm(5)
|
||||||
error: empty-raw-identifier.asm(5) -> empty-raw-identifier.asm::macro(3):
|
error: Empty raw symbol in bracketed macro argument
|
||||||
Empty raw symbol in bracketed macro argument
|
at empty-raw-identifier.asm::macro(3) <- empty-raw-identifier.asm(5)
|
||||||
Assembly aborted with 2 errors!
|
Assembly aborted with 2 errors!
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
warning: empty-strings.asm(5): [-Wobsolete]
|
warning: Treating strings as numbers is deprecated [-Wobsolete]
|
||||||
Treating strings as numbers is deprecated
|
at empty-strings.asm(5)
|
||||||
error: empty-strings.asm(5):
|
error: Strings as numbers must be a single charmap unit
|
||||||
Strings as numbers must be a single charmap unit
|
at empty-strings.asm(5)
|
||||||
Assembly aborted with 1 error!
|
Assembly aborted with 1 error!
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
FATAL: endc-outside-if.asm(1):
|
FATAL: Found ENDC outside of an IF construct
|
||||||
Found ENDC outside of an IF construct
|
at endc-outside-if.asm(1)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
warning: endsection-in-load.asm(3): [-Wunterminated-load]
|
warning: `LOAD` block without `ENDL` terminated by `ENDSECTION` [-Wunterminated-load]
|
||||||
`LOAD` block without `ENDL` terminated by `ENDSECTION`
|
at endsection-in-load.asm(3)
|
||||||
error: endsection-in-load.asm(4):
|
error: Found `ENDL` outside of a `LOAD` block
|
||||||
Found `ENDL` outside of a `LOAD` block
|
at endsection-in-load.asm(4)
|
||||||
Assembly aborted with 1 error!
|
Assembly aborted with 1 error!
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
FATAL: endsection-in-union.asm(3):
|
FATAL: Cannot end the section within a UNION
|
||||||
Cannot end the section within a UNION
|
at endsection-in-union.asm(3)
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
FATAL: endsection-outside-section.asm(1):
|
FATAL: Cannot end the section outside of a SECTION
|
||||||
Cannot end the section outside of a SECTION
|
at endsection-outside-section.asm(1)
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
error: endsection.asm(4):
|
error: Cannot output data outside of a SECTION
|
||||||
Cannot output data outside of a SECTION
|
at endsection.asm(4)
|
||||||
Assembly aborted with 1 error!
|
Assembly aborted with 1 error!
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
warning: equs-newline.asm(3): [-Wuser]
|
warning: First [-Wuser]
|
||||||
First
|
at equs-newline.asm(3)
|
||||||
while expanding symbol "ACT"
|
while expanding symbol "ACT"
|
||||||
warning: equs-newline.asm(3): [-Wuser]
|
warning: Second [-Wuser]
|
||||||
Second
|
at equs-newline.asm(3)
|
||||||
warning: equs-newline.asm(4): [-Wuser]
|
warning: Third [-Wuser]
|
||||||
Third
|
at equs-newline.asm(4)
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
warning: equs-purge.asm(2): [-Wuser]
|
warning: Crash? [-Wuser]
|
||||||
Crash?
|
at equs-purge.asm(2)
|
||||||
while expanding symbol "BYE"
|
while expanding symbol "BYE"
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user