diff --git a/include/link/section.hpp b/include/link/section.hpp index 6e0a163b..fab4a8dd 100644 --- a/include/link/section.hpp +++ b/include/link/section.hpp @@ -49,6 +49,39 @@ struct Section { std::vector *fileSymbols; std::vector symbols; std::unique_ptr
nextPiece; // The next fragment or union "piece" of this section + +private: + // Template class for both const and non-const iterators over the "pieces" of this section + template + class PiecesIterable { + T *_firstPiece; + + class Iterator { + T *_piece; + + public: + explicit Iterator(T *piece) : _piece(piece) {} + + Iterator &operator++() { + _piece = _piece->nextPiece.get(); + return *this; + } + + T &operator*() const { return *_piece; } + + bool operator==(Iterator const &rhs) const { return _piece == rhs._piece; } + }; + + public: + explicit PiecesIterable(T *firstPiece) : _firstPiece(firstPiece) {} + + Iterator begin() { return Iterator(_firstPiece); } + Iterator end() { return Iterator(nullptr); } + }; + +public: + PiecesIterable
pieces() { return PiecesIterable(this); } + PiecesIterable
pieces() const { return PiecesIterable(this); } }; // Execute a callback for each section currently registered. diff --git a/src/asm/output.cpp b/src/asm/output.cpp index 0841b74d..93d88bae 100644 --- a/src/asm/output.cpp +++ b/src/asm/output.cpp @@ -223,12 +223,10 @@ void out_WriteObject() { putLong(fileStackNodes.size(), file); for (auto it = fileStackNodes.begin(); it != fileStackNodes.end(); ++it) { - FileStackNode const &node = **it; - - writeFileStackNode(node, file); + writeFileStackNode(**it, file); // The list is supposed to have decrementing IDs - assume(it + 1 == fileStackNodes.end() || it[1]->ID == node.ID - 1); + assume(it + 1 == fileStackNodes.end() || it[1]->ID == it[0]->ID - 1); } for (Symbol const *sym : objectSymbols) { diff --git a/src/link/assign.cpp b/src/link/assign.cpp index 8c488e48..160a1e9d 100644 --- a/src/link/assign.cpp +++ b/src/link/assign.cpp @@ -53,9 +53,9 @@ static void initFreeSpace() { static void assignSection(Section §ion, MemoryLocation const &location) { // Propagate the assigned location to all UNIONs/FRAGMENTs // so `jr` patches in them will have the correct offset - for (Section *piece = §ion; piece != nullptr; piece = piece->nextPiece.get()) { - piece->org = location.address; - piece->bank = location.bank; + for (Section &piece : section.pieces()) { + piece.org = location.address; + piece.bank = location.bank; } out_AddSection(section); } diff --git a/src/link/layout.cpp b/src/link/layout.cpp index 1e66c05b..89b51465 100644 --- a/src/link/layout.cpp +++ b/src/link/layout.cpp @@ -251,8 +251,8 @@ void layout_PlaceSection(std::string const &name, bool isOptional) { ); } else { // SDCC areas don't have a type assigned yet, so the linker script gives them one. - for (Section *piece = section; piece != nullptr; piece = piece->nextPiece.get()) { - piece->type = activeType; + for (Section &piece : section->pieces()) { + piece.type = activeType; } } } else if (section->type != activeType) { diff --git a/src/link/output.cpp b/src/link/output.cpp index 1141fa6b..7c7dfbf6 100644 --- a/src/link/output.cpp +++ b/src/link/output.cpp @@ -317,13 +317,13 @@ static bool compareSymbols(SortedSymbol const &sym1, SortedSymbol const &sym2) { template static void forEachSortedSection(SortedSections const &bankSections, F callback) { for (Section const *sect : bankSections.zeroLenSections) { - for (; sect != nullptr; sect = sect->nextPiece.get()) { - callback(*sect); + for (Section const &piece : sect->pieces()) { + callback(piece); } } for (Section const *sect : bankSections.sections) { - for (; sect != nullptr; sect = sect->nextPiece.get()) { - callback(*sect); + for (Section const &piece : sect->pieces()) { + callback(piece); } } } @@ -433,31 +433,32 @@ uint16_t forEachSection(SortedSections const §List, F callback) { return used; } -static void writeMapSymbols(Section const *sect) { - uint16_t org = sect->org; - - for (bool announced = true; sect != nullptr; sect = sect->nextPiece.get(), announced = false) { - for (Symbol *sym : sect->symbols) { +static void writeMapSymbols(Section const §) { + bool announced = true; + for (Section const &piece : sect.pieces()) { + for (Symbol *sym : piece.symbols) { // Don't output symbols that begin with an illegal character if (sym->name.empty() || !startsIdentifier(sym->name[0])) { continue; } // Announce this "piece" before its contents if (!announced) { - if (sect->modifier == SECTION_UNION) { + assume(sect.modifier == piece.modifier); + if (sect.modifier == SECTION_UNION) { fputs("\t ; Next union\n", mapFile); - } else if (sect->modifier == SECTION_FRAGMENT) { + } else if (sect.modifier == SECTION_FRAGMENT) { fputs("\t ; Next fragment\n", mapFile); } announced = true; } assume(std::holds_alternative