37 OpAsmParser &parser, Attribute &initialValue, TypeAttr typeAttr
39 if (parser.parseOptionalEqual()) {
43 Type specifiedType = typeAttr.getValue();
47 if (isa<FeltType>(specifiedType)) {
48 FeltConstAttr feltConstAttr;
49 if (parser.parseCustomAttributeWithFallback<FeltConstAttr>(feltConstAttr)) {
52 initialValue = feltConstAttr;
56 if (failed(parser.parseAttribute(initialValue, specifiedType))) {
63 OpAsmPrinter &p,
GlobalDefOp , Attribute initialValue, TypeAttr typeAttr
69 if (FeltConstAttr feltConstAttr = llvm::dyn_cast<FeltConstAttr>(initialValue)) {
70 p.printStrippedAttrOrType<FeltConstAttr>(feltConstAttr);
72 p.printAttributeWithoutType(initialValue);
85 EmitErrorFn errFn, Type rootType,
const Twine &aspect,
const Twine &expected,
const Twine &found
88 "with type ", rootType,
" expected ", expected,
" ", aspect,
" but found ", found
93 EmitErrorFn errFn, Type rootType,
const Twine &aspect,
const Twine &expected, Attribute found
95 return reportMismatch(errFn, rootType, aspect, expected, found.getAbstractAttribute().getName());
98LogicalResult ensureAttrTypeMatch(
99 Type type, Attribute valAttr,
const OwningEmitErrorFn &errFn, Type rootType,
const Twine &aspect
103 return errFn().append(
104 "attribute 'type' failed to satisfy constraint: type attribute of "
105 "any LLZK type except non-constant types"
108 if (type.isSignlessInteger(1)) {
109 if (IntegerAttr ia = llvm::dyn_cast<IntegerAttr>(valAttr)) {
110 APInt val = ia.getValue();
111 if (!val.isZero() && !val.isOne()) {
112 return errFn().append(
"integer constant out of range for attribute");
114 }
else if (!llvm::isa<BoolAttr>(valAttr)) {
115 return reportMismatch(errFn, rootType, aspect,
"builtin.bool or builtin.integer", valAttr);
117 }
else if (llvm::isa<IndexType>(type)) {
120 bool isBool = llvm::isa<BoolAttr>(valAttr);
121 if (isBool || !llvm::isa<IntegerAttr>(valAttr)) {
122 return reportMismatch(
123 errFn, rootType, aspect,
"builtin.index",
124 isBool ?
"builtin.bool" : valAttr.getAbstractAttribute().getName()
127 }
else if (llvm::isa<FeltType>(type)) {
128 if (!llvm::isa<FeltConstAttr, IntegerAttr>(valAttr)) {
129 return reportMismatch(errFn, rootType, aspect,
"felt.type", valAttr);
131 }
else if (llvm::isa<StringType>(type)) {
132 if (!llvm::isa<StringAttr>(valAttr)) {
133 return reportMismatch(errFn, rootType, aspect,
"builtin.string", valAttr);
135 }
else if (ArrayType arrTy = llvm::dyn_cast<ArrayType>(type)) {
136 if (ArrayAttr arrVal = llvm::dyn_cast<ArrayAttr>(valAttr)) {
138 assert(arrTy.hasStaticShape() &&
"implied by earlier isValidGlobalType() check");
139 int64_t expectedCount = arrTy.getNumElements();
140 size_t actualCount = arrVal.size();
141 if (std::cmp_not_equal(actualCount, expectedCount)) {
142 return reportMismatch(
143 errFn, rootType, Twine(aspect) +
" to contain " + Twine(expectedCount) +
" elements",
144 "builtin.array", Twine(actualCount)
150 bool hasFailure =
false;
151 Type expectedElemTy = arrTy.getElementType();
152 for (Attribute e : arrVal.getValue()) {
154 failed(ensureAttrTypeMatch(expectedElemTy, e, errFn, rootType,
"array element"));
160 return reportMismatch(errFn, rootType, aspect,
"builtin.array", valAttr);
163 return errFn().append(
"expected a valid LLZK type but found ", type);
174 return ensureAttrTypeMatch(ty, initValAttr, errFn, ty,
"attribute value");
178 return emitOpError(
"marked as 'const' must be assigned a value");
187FailureOr<SymbolLookupResult<GlobalDefOp>>
194FailureOr<SymbolLookupResult<GlobalDefOp>>
202 Type globalType = tgt->get().getType();
203 if (!
typesUnify(refOp.
getVal().getType(), globalType, tgt->getIncludeSymNames())) {
204 return refOp->emitOpError() <<
"has wrong type; expected " << globalType <<
", got "
205 << refOp.
getVal().getType();
213 if (failed(verifySymbolUsesImpl(*
this, tables))) {
221 auto tgt = verifySymbolUsesImpl(*
this, tables);
225 if (tgt->get().isConstant()) {
226 return emitOpError().append(