diff --git a/mlir/test/mlir-tblgen/op-attribute.td b/mlir/test/mlir-tblgen/op-attribute.td --- a/mlir/test/mlir-tblgen/op-attribute.td +++ b/mlir/test/mlir-tblgen/op-attribute.td @@ -52,6 +52,16 @@ // DEF-NEXT: auto attr = cAttrAttr() // DEF-NEXT: return attr ? Optional(attr.some-convert-from-storage()) : (llvm::None); +// Test setter methods +// --- + +// DEF: void AOp::aAttrAttr(some-attr-kind attr) { +// DEF-NEXT: this->setAttr("aAttr", attr); +// DEF: void AOp::bAttrAttr(some-attr-kind attr) { +// DEF-NEXT: this->setAttr("bAttr", attr); +// DEF: void AOp::cAttrAttr(some-attr-kind attr) { +// DEF-NEXT: this->setAttr("cAttr", attr); + // Test build methods // --- diff --git a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp --- a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp +++ b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp @@ -171,6 +171,9 @@ // Generates getters for the attributes. void genAttrGetters(); + // Generates setter for the attributes. + void genAttrSetters(); + // Generates getters for named operands. void genNamedOperandGetters(); @@ -300,6 +303,7 @@ genNamedResultGetters(); genNamedRegionGetters(); genAttrGetters(); + genAttrSetters(); genBuilder(); genParser(); genPrinter(); @@ -381,6 +385,25 @@ } } +void OpEmitter::genAttrSetters() { + // Generate raw named setter type. This is a wrapper class that allows setting + // to the attributes via setters instead of having to use the string interface + // for better compile time verification. + auto emitAttrWithStorageType = [&](StringRef name, Attribute attr) { + auto &method = opClass.newMethod("void", (name + "Attr").str(), + (attr.getStorageType() + " attr").str()); + auto &body = method.body(); + body << " this->setAttr(\"" << name << "\", attr);"; + }; + + for (auto &namedAttr : op.getAttributes()) { + const auto &name = namedAttr.name; + const auto &attr = namedAttr.attr; + if (!attr.isDerivedAttr()) + emitAttrWithStorageType(name, attr); + } +} + // Generates the named operand getter methods for the given Operator `op` and // puts them in `opClass`. Uses `rangeType` as the return type of getters that // return a range of operands (individual operands are `Value ` and each