Implement initial support for function attributes, including parser, printer,
resolver support.
Still TODO are verifier support (to make sure you don't use an attribute for a
function in another module) and the TODO in ModuleParser::finalizeModule that I
will handle in the next patch.
PiperOrigin-RevId: 209361648
diff --git a/lib/IR/StandardOps.cpp b/lib/IR/StandardOps.cpp
index 723dcc2..6d8c366 100644
--- a/lib/IR/StandardOps.cpp
+++ b/lib/IR/StandardOps.cpp
@@ -204,16 +204,25 @@
void ConstantOp::print(OpAsmPrinter *p) const {
*p << "constant " << *getValue();
p->printOptionalAttrDict(getAttrs(), /*elidedAttrs=*/"value");
- *p << " : " << *getType();
+
+ if (!isa<FunctionAttr>(getValue()))
+ *p << " : " << *getType();
}
bool ConstantOp::parse(OpAsmParser *parser, OperationState *result) {
Attribute *valueAttr;
Type *type;
- return parser->parseAttribute(valueAttr, "value", result->attributes) ||
- parser->parseOptionalAttributeDict(result->attributes) ||
- parser->parseColonType(type) ||
+ if (parser->parseAttribute(valueAttr, "value", result->attributes) ||
+ parser->parseOptionalAttributeDict(result->attributes))
+ return true;
+
+ // 'constant' taking a function reference doesn't get a redundant type
+ // specifier. The attribute itself carries it.
+ if (auto *fnAttr = dyn_cast<FunctionAttr>(valueAttr))
+ return parser->addTypeToList(fnAttr->getValue()->getType(), result->types);
+
+ return parser->parseColonType(type) ||
parser->addTypeToList(type, result->types);
}
@@ -244,7 +253,9 @@
}
if (isa<FunctionType>(type)) {
- // TODO: Verify a function attr.
+ if (!isa<FunctionAttr>(value))
+ return "requires 'value' to be a function reference";
+ return nullptr;
}
return "requires a result type that aligns with the 'value' attribute";