mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-23 11:32:07 +00:00
Use std::get_if instead of std::visit (#1367)
`std::visit` is (arguably) cleaner code, but older versions of gcc and clang (not very old; the ones packaged with Ubuntu 22.04 LTS) compile them as tables of function pointers, instead of efficient jump tables.
This commit is contained in:
@@ -66,31 +66,25 @@ std::string const &FileStackNode::name() const {
|
||||
}
|
||||
|
||||
std::string const &FileStackNode::dump(uint32_t curLineNo) const {
|
||||
Visitor visitor{
|
||||
[this](std::vector<uint32_t> const &iters) -> std::string const & {
|
||||
assert(this->parent); // REPT nodes use their parent's name
|
||||
std::string const &lastName = this->parent->dump(this->lineNo);
|
||||
fprintf(stderr, " -> %s", lastName.c_str());
|
||||
for (uint32_t iter : iters)
|
||||
fprintf(stderr, "::REPT~%" PRIu32, iter);
|
||||
return lastName;
|
||||
},
|
||||
[this](std::string const &name) -> std::string const & {
|
||||
if (this->parent) {
|
||||
this->parent->dump(this->lineNo);
|
||||
fprintf(stderr, " -> %s", name.c_str());
|
||||
} else {
|
||||
fputs(name.c_str(), stderr);
|
||||
}
|
||||
return name;
|
||||
},
|
||||
[](std::monostate) -> std::string const & {
|
||||
unreachable_(); // This should not be possible
|
||||
},
|
||||
};
|
||||
std::string const &topName = std::visit(visitor, data);
|
||||
fprintf(stderr, "(%" PRIu32 ")", curLineNo);
|
||||
return topName;
|
||||
if (std::holds_alternative<std::vector<uint32_t>>(data)) {
|
||||
assert(parent); // REPT nodes use their parent's name
|
||||
std::string const &lastName = parent->dump(lineNo);
|
||||
fputs(" -> ", stderr);
|
||||
fputs(lastName.c_str(), stderr);
|
||||
for (uint32_t iter : iters())
|
||||
fprintf(stderr, "::REPT~%" PRIu32, iter);
|
||||
fprintf(stderr, "(%" PRIu32 ")", curLineNo);
|
||||
return lastName;
|
||||
} else {
|
||||
if (parent) {
|
||||
parent->dump(lineNo);
|
||||
fputs(" -> ", stderr);
|
||||
}
|
||||
std::string const &nodeName = name();
|
||||
fputs(nodeName.c_str(), stderr);
|
||||
fprintf(stderr, "(%" PRIu32 ")", curLineNo);
|
||||
return nodeName;
|
||||
}
|
||||
}
|
||||
|
||||
void printDiag(
|
||||
|
||||
@@ -564,7 +564,7 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) {
|
||||
|
||||
if (symbol.type == SYMTYPE_EXPORT)
|
||||
sym_AddSymbol(symbol);
|
||||
if (Label *label = std::get_if<Label>(&symbol.data); label)
|
||||
if (auto *label = std::get_if<Label>(&symbol.data); label)
|
||||
nbSymPerSect[label->sectionID]++;
|
||||
}
|
||||
|
||||
@@ -603,7 +603,7 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) {
|
||||
|
||||
// Give symbols' section pointers to their sections
|
||||
for (uint32_t i = 0; i < nbSymbols; i++) {
|
||||
if (Label *label = std::get_if<Label>(&fileSymbols[i].data); label) {
|
||||
if (auto *label = std::get_if<Label>(&fileSymbols[i].data); label) {
|
||||
Section *section = fileSections[label->sectionID].get();
|
||||
|
||||
label->section = section;
|
||||
@@ -620,7 +620,7 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) {
|
||||
// This has to run **after** all the `sect_AddSection()` calls,
|
||||
// so that `sect_GetSection()` will work
|
||||
for (uint32_t i = 0; i < nbSymbols; i++) {
|
||||
if (Label *label = std::get_if<Label>(&fileSymbols[i].data); label) {
|
||||
if (auto *label = std::get_if<Label>(&fileSymbols[i].data); label) {
|
||||
if (Section *section = label->section; section->modifier != SECTION_NORMAL) {
|
||||
if (section->modifier == SECTION_FRAGMENT)
|
||||
// Add the fragment's offset to the symbol's
|
||||
|
||||
@@ -218,7 +218,7 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
||||
);
|
||||
isError = true;
|
||||
value = 1;
|
||||
} else if (Label const *label = std::get_if<Label>(&symbol->data); label) {
|
||||
} else if (auto *label = std::get_if<Label>(&symbol->data); label) {
|
||||
value = label->section->bank;
|
||||
} else {
|
||||
error(
|
||||
@@ -383,16 +383,11 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
||||
fileSymbols[value].name.c_str()
|
||||
);
|
||||
isError = true;
|
||||
} else if (auto *label = std::get_if<Label>(&symbol->data); label) {
|
||||
value = label->section->org + label->offset;
|
||||
} else {
|
||||
value = std::visit(
|
||||
Visitor{
|
||||
[](int32_t val) -> int32_t { return val; },
|
||||
[](Label label) -> int32_t {
|
||||
return label.section->org + label.offset;
|
||||
},
|
||||
},
|
||||
symbol->data
|
||||
);
|
||||
assert(std::holds_alternative<int32_t>(symbol->data));
|
||||
value = std::get<int32_t>(symbol->data);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -392,16 +392,14 @@ void sdobj_ReadFile(FileStackNode const &where, FILE *file, std::vector<Symbol>
|
||||
if (other) {
|
||||
// The same symbol can only be defined twice if neither
|
||||
// definition is in a floating section
|
||||
auto visitor = Visitor{
|
||||
[](int32_t value) -> std::tuple<Section *, int32_t> {
|
||||
return {nullptr, value};
|
||||
},
|
||||
[](Label label) -> std::tuple<Section *, int32_t> {
|
||||
return {label.section, label.offset};
|
||||
},
|
||||
auto checkSymbol = [](Symbol const &sym) -> std::tuple<Section *, int32_t> {
|
||||
if (auto *label = std::get_if<Label>(&sym.data); label)
|
||||
return {label->section, label->offset};
|
||||
assert(std::holds_alternative<int32_t>(sym.data));
|
||||
return {nullptr, std::get<int32_t>(sym.data)};
|
||||
};
|
||||
auto [symbolSection, symbolValue] = std::visit(visitor, symbol.data);
|
||||
auto [otherSection, otherValue] = std::visit(visitor, other->data);
|
||||
auto [symbolSection, symbolValue] = checkSymbol(symbol);
|
||||
auto [otherSection, otherValue] = checkSymbol(*other);
|
||||
|
||||
if ((otherSection && !otherSection->isAddressFixed)
|
||||
|| (symbolSection && !symbolSection->isAddressFixed)) {
|
||||
|
||||
@@ -27,8 +27,8 @@ Label const &Symbol::label() const {
|
||||
|
||||
void sym_AddSymbol(Symbol &symbol) {
|
||||
Symbol *other = sym_GetSymbol(symbol.name);
|
||||
int32_t const *symValue = std::get_if<int32_t>(&symbol.data);
|
||||
int32_t const *otherValue = other ? std::get_if<int32_t>(&other->data) : nullptr;
|
||||
auto *symValue = std::get_if<int32_t>(&symbol.data);
|
||||
auto *otherValue = other ? std::get_if<int32_t>(&other->data) : nullptr;
|
||||
|
||||
// Check if the symbol already exists with a different value
|
||||
if (other && !(symValue && otherValue && *symValue == *otherValue)) {
|
||||
|
||||
Reference in New Issue
Block a user