1//===-- Types.td -------------------------------------------*- tablegen -*-===//
3// Part of the LLZK Project, under the Apache License v2.0.
4// See LICENSE.txt for license information.
5// Copyright 2025 Veridise Inc.
6// SPDX-License-Identifier: Apache-2.0
8//===----------------------------------------------------------------------===//
10#ifndef LLZK_STRUCT_TYPES
11#define LLZK_STRUCT_TYPES
13include "llzk/Dialect/Shared/Types.td"
14include "llzk/Dialect/Struct/IR/Dialect.td"
16include "mlir/IR/AttrTypeBase.td"
17include "mlir/IR/BuiltinTypes.td"
18include "mlir/Interfaces/MemorySlotInterfaces.td"
19include "mlir/IR/BuiltinTypeInterfaces.td"
21class StructDialectType<string name, string typeMnemonic,
22 list<Trait> traits = []>
23 : TypeDef<StructDialect, name, traits> {
24 let mnemonic = typeMnemonic;
27def LLZK_StructType : StructDialectType<"Struct", "type"> {
28 let summary = "circuit component";
30 Type of a `struct` op instance. Struct values are identity-bearing, pointer-like
31 handles to mutable component instances rather than bags of member values. Copying
32 a struct value copies the handle and preserves the identity of the referenced
33 component; it does not duplicate the component's members, signals, or tables.
35 For structs that contain template parameters,
36 the type must contain a list of attributes that instantiate the template
37 parameters, one per parameter. Each attribute must be one of the following:
38 - IntegerAttr (with IndexType), specifying a fixed parameter value; the
39 wildcard (`?`) is not allowed
40 - SymbolRefAttr, specifying a parameter value defined by a struct parameter
42 - AffineMapAttr, for an array of struct elements whose template parameters
43 vary based on some fixed pattern.
44 - TypeAttr, for specifying a type parameter.
47 // Type for struct `A` with no parameters.
50 // Type for struct `B` with IntegerAttr and SymbolRefAttr parameters.
51 !struct.type<@B<[5, @C]>>
53 // Type for struct `C` with TypeAttr and IntegerAttr parameters.
54 !struct.type<@C<[!felt.type, 24]>>
60 "::mlir::SymbolRefAttr",
61 "Fully-qualified name of the struct definition.">:$nameRef,
62 OptionalParameter<"::mlir::ArrayAttr", "Struct parameters">:$params);
65 [{ `<` $nameRef ( `<` custom<TemplateParams>($params)^ `>` )? `>` }];
67 let genVerifyDecl = 1;
69 let skipDefaultBuilders = 1;
70 let builders = [TypeBuilderWithInferredContext<
71 (ins "::mlir::SymbolRefAttr":$structName), [{
72 return $_get(structName.getContext(), structName, ::mlir::ArrayAttr());
74 TypeBuilderWithInferredContext<
75 (ins "::mlir::SymbolRefAttr":$structName,
76 "::mlir::ArrayAttr":$params),
78 ::mlir::MLIRContext *ctx = structName.getContext();
80 OwningEmitErrorFn emitErrorFn = ::llzk::wrapNullableInFlightDiagnostic(emitError, ctx);
81 auto paramsRes = forceIntAttrTypes(params.getValue(), emitErrorFn);
82 if(::mlir::failed(paramsRes)) { return StructType(); }
83 params = ::mlir::ArrayAttr::get(ctx, *paramsRes);
85 return $_get(ctx, structName, params);
87 TypeBuilderWithInferredContext<
88 (ins "::mlir::SymbolRefAttr":$structName,
89 "::llvm::ArrayRef<::mlir::Attribute>":$paramsRef),
91 ::mlir::MLIRContext *ctx = structName.getContext();
92 OwningEmitErrorFn emitErrorFn = ::llzk::wrapNullableInFlightDiagnostic(emitError, ctx);
93 auto paramsRes = forceIntAttrTypes(paramsRef, emitErrorFn);
94 if(::mlir::failed(paramsRes)) { return StructType(); }
95 return $_get(ctx, structName, ::mlir::ArrayAttr::get(ctx, *paramsRes));
98 let extraClassDeclaration = [{
99 /// Gets the `struct` op that defines this struct. Provided `op` is
100 /// used as a starting point for the lookup. Should not be assumed to
101 /// be non-`null` as we don't verify all types during verification.
102 ::mlir::FailureOr<SymbolLookupResult<StructDefOp>> getDefinition
103 (::mlir::SymbolTableCollection &symbolTable, ::mlir::Operation *op, bool reportMissing = true) const;
105 // Verifies that this type references a valid struct, relative to the given `op`.
106 ::mlir::LogicalResult verifySymbolRef(::mlir::SymbolTableCollection &symbolTable, ::mlir::Operation *op);
108 /// Returns wether the struct this type refers to has members marked as columns.
109 /// A lookup is necessary first and will forward the failure state if it fails.
110 mlir::LogicalResult hasColumns(mlir::SymbolTableCollection &symbolTable, mlir::Operation *op) const;
113 let extraClassDefinition = [{
115 /// This definition of `emitError` is used by the `get()` functions generated by the
116 /// custom builders for this type. The `getChecked()` functions generated by those same
117 /// builders have a parameter with this same name that shadows this definition so the
118 /// `getChecked()` versions will use the function supplied via the parameter. Regardless,
119 /// `wrapNullableInFlightDiagnostic()` checks for `nullptr` and generates a default if
120 /// necessary. This approach, although a bit hacky, allows a legitimate error function to
121 /// be used whenever available, only reverting to a default in the `get()` function.
122 const ::llvm::function_ref<::mlir::InFlightDiagnostic()> emitError = nullptr;
127#endif // LLZK_STRUCT_TYPES