==== dwarf_output ==== The dwarf_output object will represent one DWARF file, output version. The dwarf_edit object is the model. Unlike dwarf_edit, dwarf_output and its constituent objects are not mutable (all const all the time). Instead, the *only* way to construct the dwarf_output object is with a copy constructor from a template-compatible object (dwarf or dwarf_edit). This does copy construction down the tree, resulting in a dwarf_output with trees and values that are all const. ==== collector ==== The "collector" is an object (and hierarchy of contained objects) that holds all the potentially shareable data for dwarf_output objects. The collector is separate from the object for an individual output file. This is in preparation for the "consolidated debug archive" idea, where there would be sharing across multiple DWARF "file"s. For the time being, the collector is only functioning as a subsidiary writer data structure for a single dwarf_output object for a single file. The collector keeps "append-only" sets of each type of object it manages. dwarf_output::type constructors work by inserting an object into the set, and returning a "const type &" reference pointing into the set. Thus it takes care of uniquifying automagically as it goes. At the top, there is a debug_info_entry set. This necessitates having a set for each constituent object that entails: * debug_info_entry * attributes (const unordered_set) * attribute/attr_value * string (use Ebl_Strtab) * line table * macinfo * ranges * location * constant_block Each of those types has an "unordered_set" object in the collector. Each type should have a hash function that returns a hash value stored at construction. The constructors for each type need to collect their constituent's hashes along the way, so by the time the object is constructed, its hash value is stored and later hash computations are free. The dwarf_output template copy constructors work by calling methods on the collector object that construct the corresponding collector datum object, insert it into the corresponding set (i.e. discard the new object if it's already in the set), and return a reference to the object in the set. The collector sets should also track for each object in the set how many duplicates of that object were inserted.