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 op, Attribute initialValue, TypeAttr typeAttr
69 if (FeltConstAttr feltConstAttr = llvm::dyn_cast<FeltConstAttr>(initialValue)) {
70 p.printStrippedAttrOrType<FeltConstAttr>(feltConstAttr);
72 p.printAttributeWithoutType(initialValue);
84inline InFlightDiagnostic reportMismatch(
85 EmitErrorFn errFn, Type rootType,
const Twine &aspect,
const Twine &expected,
const Twine &found
87 return errFn().append(
88 "with type ", rootType,
" expected ", expected,
" ", aspect,
" but found ", found
92inline InFlightDiagnostic reportMismatch(
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(
"attribute 'type' failed to satisfy constraint: type attribute of "
104 "any LLZK type except non-constant types");
106 if (type.isSignlessInteger(1)) {
107 if (IntegerAttr ia = llvm::dyn_cast<IntegerAttr>(valAttr)) {
108 APInt val = ia.getValue();
109 if (!val.isZero() && !val.isOne()) {
110 return errFn().append(
"integer constant out of range for attribute");
112 }
else if (!llvm::isa<BoolAttr>(valAttr)) {
113 return reportMismatch(errFn, rootType, aspect,
"builtin.bool or builtin.integer", valAttr);
115 }
else if (llvm::isa<IndexType>(type)) {
118 bool isBool = llvm::isa<BoolAttr>(valAttr);
119 if (isBool || !llvm::isa<IntegerAttr>(valAttr)) {
120 return reportMismatch(
121 errFn, rootType, aspect,
"builtin.index",
122 isBool ?
"builtin.bool" : valAttr.getAbstractAttribute().getName()
125 }
else if (llvm::isa<FeltType>(type)) {
126 if (!llvm::isa<FeltConstAttr, IntegerAttr>(valAttr)) {
127 return reportMismatch(errFn, rootType, aspect,
"felt.type", valAttr);
129 }
else if (llvm::isa<StringType>(type)) {
130 if (!llvm::isa<StringAttr>(valAttr)) {
131 return reportMismatch(errFn, rootType, aspect,
"builtin.string", valAttr);
133 }
else if (ArrayType arrTy = llvm::dyn_cast<ArrayType>(type)) {
134 if (ArrayAttr arrVal = llvm::dyn_cast<ArrayAttr>(valAttr)) {
136 assert(arrTy.hasStaticShape() &&
"implied by earlier isValidGlobalType() check");
137 int64_t expectedCount = arrTy.getNumElements();
138 size_t actualCount = arrVal.size();
139 if (std::cmp_not_equal(actualCount, expectedCount)) {
140 return reportMismatch(
141 errFn, rootType, Twine(aspect) +
" to contain " + Twine(expectedCount) +
" elements",
142 "builtin.array", Twine(actualCount)
148 bool hasFailure =
false;
149 Type expectedElemTy = arrTy.getElementType();
150 for (Attribute e : arrVal.getValue()) {
152 failed(ensureAttrTypeMatch(expectedElemTy, e, errFn, rootType,
"array element"));
158 return reportMismatch(errFn, rootType, aspect,
"builtin.array", valAttr);
161 return errFn().append(
"expected a valid LLZK type but found ", type);
172 return ensureAttrTypeMatch(ty, initValAttr, errFn, ty,
"attribute value");
176 return emitOpError(
"marked as 'const' must be assigned a value");
185FailureOr<SymbolLookupResult<GlobalDefOp>>
192FailureOr<SymbolLookupResult<GlobalDefOp>>
200 Type globalType = tgt->get().getType();
201 if (!
typesUnify(refOp.
getVal().getType(), globalType, tgt->getIncludeSymNames())) {
202 return refOp->emitOpError() <<
"has wrong type; expected " << globalType <<
", got "
203 << refOp.
getVal().getType();
211 if (failed(verifySymbolUsesImpl(*
this, tables))) {
219 auto tgt = verifySymbolUsesImpl(*
this, tables);
223 if (tgt->get().isConstant()) {
224 return emitOpError().append(