};
 
        struct Const;
+       struct AttrObject;
        struct Selection;
        struct Monitor;
        struct Design;
        }
 };
 
+struct RTLIL::AttrObject
+{
+       dict<RTLIL::IdString, RTLIL::Const> attributes;
+
+       void set_bool_attribute(RTLIL::IdString id);
+       bool get_bool_attribute(RTLIL::IdString id) const;
+       void set_strpool_attribute(RTLIL::IdString id, const pool<string> &data);
+       void add_strpool_attribute(RTLIL::IdString id, const pool<string> &data);
+       pool<string> get_strpool_attribute(RTLIL::IdString id) const;
+};
+
 struct RTLIL::SigChunk
 {
        RTLIL::Wire *wire;
        std::vector<RTLIL::Module*> selected_whole_modules_warn() const;
 };
 
-#define RTLIL_ATTRIBUTE_MEMBERS                                \
-       dict<RTLIL::IdString, RTLIL::Const> attributes;    \
-       void set_bool_attribute(RTLIL::IdString id) {          \
-               attributes[id] = RTLIL::Const(1);              \
-       }                                                      \
-       bool get_bool_attribute(RTLIL::IdString id) const {    \
-               if (attributes.count(id) == 0)                 \
-                       return false;                          \
-               return attributes.at(id).as_bool();            \
-       }
-
-struct RTLIL::Module
+struct RTLIL::Module : public RTLIL::AttrObject
 {
        unsigned int hashidx_;
        unsigned int hash() const { return hashidx_; }
        pool<RTLIL::IdString> avail_parameters;
        dict<RTLIL::IdString, RTLIL::Memory*> memories;
        dict<RTLIL::IdString, RTLIL::Process*> processes;
-       RTLIL_ATTRIBUTE_MEMBERS
 
        Module();
        virtual ~Module();
        RTLIL::SigBit Oai4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d);
 };
 
-struct RTLIL::Wire
+struct RTLIL::Wire : public RTLIL::AttrObject
 {
        unsigned int hashidx_;
        unsigned int hash() const { return hashidx_; }
        RTLIL::IdString name;
        int width, start_offset, port_id;
        bool port_input, port_output, upto;
-       RTLIL_ATTRIBUTE_MEMBERS
 };
 
-struct RTLIL::Memory
+struct RTLIL::Memory : public RTLIL::AttrObject
 {
        unsigned int hashidx_;
        unsigned int hash() const { return hashidx_; }
 
        RTLIL::IdString name;
        int width, start_offset, size;
-       RTLIL_ATTRIBUTE_MEMBERS
 };
 
-struct RTLIL::Cell
+struct RTLIL::Cell : public RTLIL::AttrObject
 {
        unsigned int hashidx_;
        unsigned int hash() const { return hashidx_; }
        RTLIL::IdString type;
        dict<RTLIL::IdString, RTLIL::SigSpec> connections_;
        dict<RTLIL::IdString, RTLIL::Const> parameters;
-       RTLIL_ATTRIBUTE_MEMBERS
 
        // access cell ports
        bool hasPort(RTLIL::IdString portname) const;
        RTLIL::CaseRule *clone() const;
 };
 
-struct RTLIL::SwitchRule
+struct RTLIL::SwitchRule : public RTLIL::AttrObject
 {
        RTLIL::SigSpec signal;
-       RTLIL_ATTRIBUTE_MEMBERS
        std::vector<RTLIL::CaseRule*> cases;
 
        ~SwitchRule();
        RTLIL::SyncRule *clone() const;
 };
 
-struct RTLIL::Process
+struct RTLIL::Process : public RTLIL::AttrObject
 {
        RTLIL::IdString name;
-       RTLIL_ATTRIBUTE_MEMBERS
        RTLIL::CaseRule root_case;
        std::vector<RTLIL::SyncRule*> syncs;
 
 
 
        for (int i = 0; i < GetSize(sig_y); i++) {
                RTLIL::Cell *gate = module->addCell(NEW_ID, "$_NOT_");
+               gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src"));
                gate->setPort("\\A", sig_a[i]);
                gate->setPort("\\Y", sig_y[i]);
        }
 
                for (int i = 0; i < GetSize(sig_y); i++) {
                        RTLIL::Cell *gate = module->addCell(NEW_ID, "$_NOT_");
+                       gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src"));
                        gate->setPort("\\A", sig_t[i]);
                        gate->setPort("\\Y", sig_y[i]);
                }
 
        for (int i = 0; i < GetSize(sig_y); i++) {
                RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
+               gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src"));
                gate->setPort("\\A", sig_a[i]);
                gate->setPort("\\B", sig_b[i]);
                gate->setPort("\\Y", sig_y[i]);
                        }
 
                        RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
+                       gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src"));
                        gate->setPort("\\A", sig_a[i]);
                        gate->setPort("\\B", sig_a[i+1]);
                        gate->setPort("\\Y", sig_t[i/2]);
        if (cell->type == "$reduce_xnor") {
                RTLIL::SigSpec sig_t = module->addWire(NEW_ID);
                RTLIL::Cell *gate = module->addCell(NEW_ID, "$_NOT_");
+               gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src"));
                gate->setPort("\\A", sig_a);
                gate->setPort("\\Y", sig_t);
                last_output_cell = gate;
        }
 }
 
-static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig)
+static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLIL::Cell *cell)
 {
        while (sig.size() > 1)
        {
                        }
 
                        RTLIL::Cell *gate = module->addCell(NEW_ID, "$_OR_");
+                       gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src"));
                        gate->setPort("\\A", sig[i]);
                        gate->setPort("\\B", sig[i+1]);
                        gate->setPort("\\Y", sig_t[i/2]);
 void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell)
 {
        RTLIL::SigSpec sig_a = cell->getPort("\\A");
-       logic_reduce(module, sig_a);
+       logic_reduce(module, sig_a, cell);
 
        RTLIL::SigSpec sig_y = cell->getPort("\\Y");
 
        }
 
        RTLIL::Cell *gate = module->addCell(NEW_ID, "$_NOT_");
+       gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src"));
        gate->setPort("\\A", sig_a);
        gate->setPort("\\Y", sig_y);
 }
 void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell)
 {
        RTLIL::SigSpec sig_a = cell->getPort("\\A");
-       logic_reduce(module, sig_a);
+       logic_reduce(module, sig_a, cell);
 
        RTLIL::SigSpec sig_b = cell->getPort("\\B");
-       logic_reduce(module, sig_b);
+       logic_reduce(module, sig_b, cell);
 
        RTLIL::SigSpec sig_y = cell->getPort("\\Y");
 
        log_assert(!gate_type.empty());
 
        RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
+       gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src"));
        gate->setPort("\\A", sig_a);
        gate->setPort("\\B", sig_b);
        gate->setPort("\\Y", sig_y);
 
        RTLIL::SigSpec xor_out = module->addWire(NEW_ID, std::max(GetSize(sig_a), GetSize(sig_b)));
        RTLIL::Cell *xor_cell = module->addXor(NEW_ID, sig_a, sig_b, xor_out, is_signed);
+       xor_cell->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src"));
        simplemap_bitop(module, xor_cell);
        module->remove(xor_cell);
 
        RTLIL::SigSpec reduce_out = is_ne ? sig_y : module->addWire(NEW_ID);
        RTLIL::Cell *reduce_cell = module->addReduceOr(NEW_ID, xor_out, reduce_out);
+       reduce_cell->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src"));
        simplemap_reduce(module, reduce_cell);
        module->remove(reduce_cell);
 
        if (!is_ne) {
                RTLIL::Cell *not_cell = module->addLogicNot(NEW_ID, reduce_out, sig_y);
+               not_cell->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src"));
                simplemap_lognot(module, not_cell);
                module->remove(not_cell);
        }
 
        for (int i = 0; i < GetSize(sig_y); i++) {
                RTLIL::Cell *gate = module->addCell(NEW_ID, "$_MUX_");
+               gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src"));
                gate->setPort("\\A", sig_a[i]);
                gate->setPort("\\B", sig_b[i]);
                gate->setPort("\\S", cell->getPort("\\S"));
 
        for (int i = 0; i < width; i++) {
                RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
+               gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src"));
                gate->setPort("\\S", sig_s[i]);
                gate->setPort("\\R", sig_r[i]);
                gate->setPort("\\Q", sig_q[i]);
 
        for (int i = 0; i < width; i++) {
                RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
+               gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src"));
                gate->setPort("\\C", sig_clk);
                gate->setPort("\\D", sig_d[i]);
                gate->setPort("\\Q", sig_q[i]);
 
        for (int i = 0; i < width; i++) {
                RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
+               gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src"));
                gate->setPort("\\C", sig_clk);
                gate->setPort("\\E", sig_en);
                gate->setPort("\\D", sig_d[i]);
 
        for (int i = 0; i < width; i++) {
                RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
+               gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src"));
                gate->setPort("\\C", sig_clk);
                gate->setPort("\\S", sig_s[i]);
                gate->setPort("\\R", sig_r[i]);
 
        for (int i = 0; i < width; i++) {
                RTLIL::Cell *gate = module->addCell(NEW_ID, rst_val.at(i) == RTLIL::State::S1 ? gate_type_1 : gate_type_0);
+               gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src"));
                gate->setPort("\\C", sig_clk);
                gate->setPort("\\R", sig_rst);
                gate->setPort("\\D", sig_d[i]);
 
        for (int i = 0; i < width; i++) {
                RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
+               gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src"));
                gate->setPort("\\E", sig_en);
                gate->setPort("\\D", sig_d[i]);
                gate->setPort("\\Q", sig_q[i]);