Enable using bare attributes.

Useful for defining ops such as <dialect>.Const where multiple kinds of attributes are legal.

PiperOrigin-RevId: 224210511
This commit is contained in:
Jacques Pienaar 2018-12-05 13:25:44 -08:00 committed by jpienaar
parent b572322859
commit c143132a56
1 changed files with 28 additions and 11 deletions

View File

@ -60,6 +60,14 @@ inline auto formatv(StringRef fmt, Ts &&... vals) -> formatv_object<decltype(
std::make_tuple(detail::build_format_adapter(std::forward<Ts>(vals))...));
}
// Returns whether the record has a value of the given name that can be returned
// via getValueAsString.
static inline bool hasStringAttribute(const Record &record,
StringRef fieldName) {
auto valueInit = record.getValueInit(fieldName);
return isa<CodeInit>(valueInit) || isa<StringInit>(valueInit);
}
namespace {
// Simple RAII helper for defining ifdef-undef-endif scopes.
class IfDefScope {
@ -179,6 +187,14 @@ void OpEmitter::emitAttrGetters() {
}
// Emit normal emitter.
if (!hasStringAttribute(attr, "storageType")) {
// Handle the base case where there is no storage type specified.
os << " Attribute " << val.getName()
<< "() const {\n return getAttr(\"" << val.getName()
<< "\");\n }\n";
continue;
}
os << " " << attr.getValueAsString("returnType").trim() << ' '
<< val.getName() << "() const {\n";
@ -192,13 +208,11 @@ void OpEmitter::emitAttrGetters() {
}
void OpEmitter::emitBuilder() {
// If a custom builder is given then print that out instead.
auto valueInit = def.getValueInit("builder");
CodeInit *codeInit = dyn_cast<CodeInit>(valueInit);
if (!codeInit)
if (!hasStringAttribute(def, "builder"))
return;
auto builder = codeInit->getValue();
// If a custom builder is given then print that out instead.
auto builder = def.getValueAsString("builder");
if (!builder.empty()) {
os << builder << '\n';
return;
@ -215,14 +229,10 @@ void OpEmitter::emitCanonicalizationPatterns() {
}
void OpEmitter::emitParser() {
auto valueInit = def.getValueInit("parser");
CodeInit *codeInit = dyn_cast<CodeInit>(valueInit);
if (!codeInit)
if (!hasStringAttribute(def, "parser"))
return;
auto parser = codeInit->getValue();
os << " static bool parse(OpAsmParser *parser, OperationState *result) {"
<< "\n " << parser << "\n }\n";
<< "\n " << def.getValueAsString("parser") << "\n }\n";
}
void OpEmitter::emitPrinter() {
@ -255,6 +265,13 @@ void OpEmitter::emitVerifier() {
continue;
auto name = attr.first->getName();
if (!hasStringAttribute(*attr.second, "storageType")) {
os << " if (!this->getAttr(\"" << name
<< "\")) return emitOpError(\"requires attribute '" << name
<< "'\");\n";
continue;
}
os << " if (!this->getAttr(\"" << name << "\").dyn_cast_or_null<"
<< attr.second->getValueAsString("storageType").trim() << ">("
<< ")) return emitOpError(\"requires "