1//===-- SubElementInterfaces.td - Sub-Element Interfaces ---*- tablegen -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains a set of interfaces that can be used to interface with
10// sub-elements, e.g. held attributes and types, of a composite attribute or
11// type.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef MLIR_IR_SUBELEMENTINTERFACES_TD_
16#define MLIR_IR_SUBELEMENTINTERFACES_TD_
17
18include "mlir/IR/OpBase.td"
19
20//===----------------------------------------------------------------------===//
21// SubElementInterfaceBase
22//===----------------------------------------------------------------------===//
23
24class SubElementInterfaceBase<string interfaceName, string attrOrType,
25                              string derivedValue> {
26  string cppNamespace = "::mlir";
27
28  list<InterfaceMethod> methods = [
29    InterfaceMethod<
30      /*desc=*/[{
31        Walk all of the immediately nested sub-attributes and sub-types. This
32        method does not recurse into sub elements.
33      }], "void", "walkImmediateSubElements",
34      (ins "llvm::function_ref<void(mlir::Attribute)>":$walkAttrsFn,
35           "llvm::function_ref<void(mlir::Type)>":$walkTypesFn)
36    >,
37    InterfaceMethod<
38      /*desc=*/[{
39        Replace the immediately nested sub-attributes and sub-types with those provided.
40        The order of the provided elements is derived from the order of the elements
41        returned by the callbacks of `walkImmediateSubElements`. The element at index 0
42        would replace the very first attribute given by `walkImmediateSubElements`.
43        On success, the new instance with the values replaced is returned. If replacement
44        fails, nullptr is returned.
45      }], attrOrType, "replaceImmediateSubElements", (ins
46        "::llvm::ArrayRef<::mlir::Attribute>":$replAttrs,
47        "::llvm::ArrayRef<::mlir::Type>":$replTypes
48      )>,
49  ];
50
51  code extraClassDeclaration = [{
52    /// Walk all of the held sub-attributes and sub-types.
53    void walkSubElements(llvm::function_ref<void(mlir::Attribute)> walkAttrsFn,
54                         llvm::function_ref<void(mlir::Type)> walkTypesFn);
55
56    /// Recursively replace all of the nested sub-attributes and sub-types using the
57    /// provided map functions. Returns nullptr in the case of failure.
58    }] # attrOrType # [{ replaceSubElements(
59      llvm::function_ref<mlir::Attribute(mlir::Attribute)> replaceAttrFn,
60      llvm::function_ref<mlir::Type(mlir::Type)> replaceTypeFn
61    );
62  }];
63  code extraTraitClassDeclaration = [{
64    /// Walk all of the held sub-attributes and sub-types.
65    void walkSubElements(llvm::function_ref<void(mlir::Attribute)> walkAttrsFn,
66                         llvm::function_ref<void(mlir::Type)> walkTypesFn) {
67      }] # interfaceName # " interface(" # derivedValue # [{);
68      interface.walkSubElements(walkAttrsFn, walkTypesFn);
69    }
70
71    /// Recursively replace all of the nested sub-attributes and sub-types using the
72    /// provided map functions. Returns nullptr in the case of failure.
73    }] # attrOrType # [{ replaceSubElements(
74      llvm::function_ref<mlir::Attribute(mlir::Attribute)> replaceAttrFn,
75      llvm::function_ref<mlir::Type(mlir::Type)> replaceTypeFn) {
76      }] # interfaceName # " interface(" # derivedValue # [{);
77      return interface.replaceSubElements(replaceAttrFn, replaceTypeFn);
78    }
79
80    /// Recursively replace all of the nested sub-attributes and sub-types using the
81    /// provided map functions. Returns nullptr in the case of failure.
82    }] # attrOrType # [{ replaceImmediateSubElements(
83      llvm::ArrayRef<mlir::Attribute> replAttrs,
84      llvm::function_ref<mlir::Type(mlir::Type)> replTypes) {
85      return nullptr;
86    }
87  }];
88  code extraSharedClassDeclaration = [{
89    /// Walk all of the held sub-attributes.
90    void walkSubAttrs(llvm::function_ref<void(mlir::Attribute)> walkFn) {
91      walkSubElements(walkFn, /*walkTypesFn=*/[](mlir::Type) {});
92    }
93    /// Walk all of the held sub-types.
94    void walkSubTypes(llvm::function_ref<void(mlir::Type)> walkFn) {
95      walkSubElements(/*walkAttrsFn=*/[](mlir::Attribute) {}, walkFn);
96    }
97
98    /// Recursively replace all of the nested sub-attributes using the provided
99    /// map function. Returns nullptr in the case of failure.
100    }] # attrOrType # [{ replaceSubElements(
101      llvm::function_ref<mlir::Attribute(mlir::Attribute)> replaceAttrFn) {
102      return replaceSubElements(
103        replaceAttrFn, [](mlir::Type type) { return type; });
104    }
105    /// Recursively replace all of the nested sub-types using the provided map
106    /// function. Returns nullptr in the case of failure.
107    }] # attrOrType # [{ replaceSubElements(
108      llvm::function_ref<mlir::Type(mlir::Type)> replaceTypeFn) {
109      return replaceSubElements(
110        [](mlir::Attribute attr) { return attr; }, replaceTypeFn);
111    }
112  }];
113}
114
115//===----------------------------------------------------------------------===//
116// SubElementAttrInterface
117//===----------------------------------------------------------------------===//
118
119def SubElementAttrInterface
120    : AttrInterface<"SubElementAttrInterface">,
121      SubElementInterfaceBase<"SubElementAttrInterface", "::mlir::Attribute",
122                              "$_attr"> {
123  let description = [{
124    An interface used to query and manipulate sub-elements, such as sub-types
125    and sub-attributes of a composite attribute.
126  }];
127}
128
129//===----------------------------------------------------------------------===//
130// SubElementTypeInterface
131//===----------------------------------------------------------------------===//
132
133def SubElementTypeInterface
134    : TypeInterface<"SubElementTypeInterface">,
135      SubElementInterfaceBase<"SubElementTypeInterface", "::mlir::Type",
136                              "$_type"> {
137  let description = [{
138    An interface used to query and manipulate sub-elements, such as sub-types
139    and sub-attributes of a composite type.
140  }];
141}
142
143#endif // MLIR_IR_SUBELEMENTINTERFACES_TD_
144