1 | //===- AsmParserState.h -----------------------------------------*- C++ -*-===// |
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 | #ifndef MLIR_ASMPARSER_ASMPARSERSTATE_H |
10 | #define MLIR_ASMPARSER_ASMPARSERSTATE_H |
11 | |
12 | #include "mlir/IR/Attributes.h" |
13 | #include "mlir/IR/Types.h" |
14 | #include "llvm/Support/SMLoc.h" |
15 | #include <cstddef> |
16 | |
17 | namespace mlir { |
18 | class Block; |
19 | class BlockArgument; |
20 | class FileLineColLoc; |
21 | class Operation; |
22 | class OperationName; |
23 | class SymbolRefAttr; |
24 | class Value; |
25 | |
26 | /// This class represents state from a parsed MLIR textual format string. It is |
27 | /// useful for building additional analysis and language utilities on top of |
28 | /// textual MLIR. This should generally not be used for traditional compilation. |
29 | class AsmParserState { |
30 | public: |
31 | /// This class represents a definition within the source manager, containing |
32 | /// it's defining location and locations of any uses. SMDefinitions are only |
33 | /// provided for entities that have uses within an input file, e.g. SSA |
34 | /// values, Blocks, and Symbols. |
35 | struct SMDefinition { |
36 | SMDefinition() = default; |
37 | SMDefinition(SMRange loc) : loc(loc) {} |
38 | |
39 | /// The source location of the definition. |
40 | SMRange loc; |
41 | /// The source location of all uses of the definition. |
42 | SmallVector<SMRange> uses; |
43 | }; |
44 | |
45 | /// This class represents the information for an operation definition within |
46 | /// an input file. |
47 | struct OperationDefinition { |
48 | struct ResultGroupDefinition { |
49 | ResultGroupDefinition(unsigned index, SMRange loc) |
50 | : startIndex(index), definition(loc) {} |
51 | |
52 | /// The result number that starts this group. |
53 | unsigned startIndex; |
54 | /// The source definition of the result group. |
55 | SMDefinition definition; |
56 | }; |
57 | |
58 | OperationDefinition(Operation *op, SMRange loc, SMLoc endLoc) |
59 | : op(op), loc(loc), scopeLoc(loc.Start, endLoc) {} |
60 | |
61 | /// The operation representing this definition. |
62 | Operation *op; |
63 | |
64 | /// The source location for the operation, i.e. the location of its name. |
65 | SMRange loc; |
66 | |
67 | /// The full source range of the operation definition, i.e. a range |
68 | /// encompassing the start and end of the full operation definition. |
69 | SMRange scopeLoc; |
70 | |
71 | /// Source definitions for any result groups of this operation. |
72 | SmallVector<ResultGroupDefinition> resultGroups; |
73 | |
74 | /// If this operation is a symbol operation, this vector contains symbol |
75 | /// uses of this operation. |
76 | SmallVector<SMRange> symbolUses; |
77 | }; |
78 | |
79 | /// This class represents the information for a block definition within the |
80 | /// input file. |
81 | struct BlockDefinition { |
82 | BlockDefinition(Block *block, SMRange loc = {}) |
83 | : block(block), definition(loc) {} |
84 | |
85 | /// The block representing this definition. |
86 | Block *block; |
87 | |
88 | /// The source location for the block, i.e. the location of its name, and |
89 | /// any uses it has. |
90 | SMDefinition definition; |
91 | |
92 | /// Source definitions for any arguments of this block. |
93 | SmallVector<SMDefinition> arguments; |
94 | }; |
95 | |
96 | /// This class represents the information for an attribute alias definition |
97 | /// within the input file. |
98 | struct AttributeAliasDefinition { |
99 | AttributeAliasDefinition(StringRef name, SMRange loc = {}, |
100 | Attribute value = {}) |
101 | : name(name), definition(loc), value(value) {} |
102 | |
103 | /// The name of the attribute alias. |
104 | StringRef name; |
105 | |
106 | /// The source location for the alias. |
107 | SMDefinition definition; |
108 | |
109 | /// The value of the alias. |
110 | Attribute value; |
111 | }; |
112 | |
113 | /// This class represents the information for type definition within the input |
114 | /// file. |
115 | struct TypeAliasDefinition { |
116 | TypeAliasDefinition(StringRef name, SMRange loc, Type value) |
117 | : name(name), definition(loc), value(value) {} |
118 | |
119 | /// The name of the attribute alias. |
120 | StringRef name; |
121 | |
122 | /// The source location for the alias. |
123 | SMDefinition definition; |
124 | |
125 | /// The value of the alias. |
126 | Type value; |
127 | }; |
128 | |
129 | AsmParserState(); |
130 | ~AsmParserState(); |
131 | AsmParserState &operator=(AsmParserState &&other); |
132 | |
133 | //===--------------------------------------------------------------------===// |
134 | // Access State |
135 | //===--------------------------------------------------------------------===// |
136 | |
137 | using BlockDefIterator = llvm::pointee_iterator< |
138 | ArrayRef<std::unique_ptr<BlockDefinition>>::iterator>; |
139 | using OperationDefIterator = llvm::pointee_iterator< |
140 | ArrayRef<std::unique_ptr<OperationDefinition>>::iterator>; |
141 | using AttributeDefIterator = llvm::pointee_iterator< |
142 | ArrayRef<std::unique_ptr<AttributeAliasDefinition>>::iterator>; |
143 | using TypeDefIterator = llvm::pointee_iterator< |
144 | ArrayRef<std::unique_ptr<TypeAliasDefinition>>::iterator>; |
145 | |
146 | /// Return a range of the BlockDefinitions held by the current parser state. |
147 | iterator_range<BlockDefIterator> getBlockDefs() const; |
148 | |
149 | /// Return the definition for the given block, or nullptr if the given |
150 | /// block does not have a definition. |
151 | const BlockDefinition *getBlockDef(Block *block) const; |
152 | |
153 | /// Return a range of the OperationDefinitions held by the current parser |
154 | /// state. |
155 | iterator_range<OperationDefIterator> getOpDefs() const; |
156 | |
157 | /// Return the definition for the given operation, or nullptr if the given |
158 | /// operation does not have a definition. |
159 | const OperationDefinition *getOpDef(Operation *op) const; |
160 | |
161 | /// Return a range of the AttributeAliasDefinitions held by the current parser |
162 | /// state. |
163 | iterator_range<AttributeDefIterator> getAttributeAliasDefs() const; |
164 | |
165 | /// Return the definition for the given attribute alias, or nullptr if the |
166 | /// given alias does not have a definition. |
167 | const AttributeAliasDefinition *getAttributeAliasDef(StringRef name) const; |
168 | |
169 | /// Return a range of the TypeAliasDefinitions held by the current parser |
170 | /// state. |
171 | iterator_range<TypeDefIterator> getTypeAliasDefs() const; |
172 | |
173 | /// Return the definition for the given type alias, or nullptr if the given |
174 | /// alias does not have a definition. |
175 | const TypeAliasDefinition *getTypeAliasDef(StringRef name) const; |
176 | |
177 | /// Returns (heuristically) the range of an identifier given a SMLoc |
178 | /// corresponding to the start of an identifier location. |
179 | static SMRange convertIdLocToRange(SMLoc loc); |
180 | |
181 | //===--------------------------------------------------------------------===// |
182 | // Populate State |
183 | //===--------------------------------------------------------------------===// |
184 | |
185 | /// Initialize the state in preparation for populating more parser state under |
186 | /// the given top-level operation. |
187 | void initialize(Operation *topLevelOp); |
188 | |
189 | /// Finalize any in-progress parser state under the given top-level operation. |
190 | void finalize(Operation *topLevelOp); |
191 | |
192 | /// Start a definition for an operation with the given name. |
193 | void startOperationDefinition(const OperationName &opName); |
194 | |
195 | /// Finalize the most recently started operation definition. |
196 | void finalizeOperationDefinition( |
197 | Operation *op, SMRange nameLoc, SMLoc endLoc, |
198 | ArrayRef<std::pair<unsigned, SMLoc>> resultGroups = std::nullopt); |
199 | |
200 | /// Start a definition for a region nested under the current operation. |
201 | void startRegionDefinition(); |
202 | |
203 | /// Finalize the most recently started region definition. |
204 | void finalizeRegionDefinition(); |
205 | |
206 | /// Add a definition of the given entity. |
207 | void addDefinition(Block *block, SMLoc location); |
208 | void addDefinition(BlockArgument blockArg, SMLoc location); |
209 | void addAttrAliasDefinition(StringRef name, SMRange location, |
210 | Attribute value); |
211 | void addTypeAliasDefinition(StringRef name, SMRange location, Type value); |
212 | |
213 | /// Add a source uses of the given value. |
214 | void addUses(Value value, ArrayRef<SMLoc> locations); |
215 | void addUses(Block *block, ArrayRef<SMLoc> locations); |
216 | void addAttrAliasUses(StringRef name, SMRange locations); |
217 | void addTypeAliasUses(StringRef name, SMRange locations); |
218 | |
219 | /// Add source uses for all the references nested under `refAttr`. The |
220 | /// provided `locations` should match 1-1 with the number of references in |
221 | /// `refAttr`, i.e.: |
222 | /// nestedReferences.size() + /*leafReference=*/1 == refLocations.size() |
223 | void addUses(SymbolRefAttr refAttr, ArrayRef<SMRange> refLocations); |
224 | |
225 | /// Refine the `oldValue` to the `newValue`. This is used to indicate that |
226 | /// `oldValue` was a placeholder, and the uses of it should really refer to |
227 | /// `newValue`. |
228 | void refineDefinition(Value oldValue, Value newValue); |
229 | |
230 | private: |
231 | struct Impl; |
232 | |
233 | /// A pointer to the internal implementation of this class. |
234 | std::unique_ptr<Impl> impl; |
235 | }; |
236 | |
237 | } // namespace mlir |
238 | |
239 | #endif // MLIR_ASMPARSER_ASMPARSERSTATE_H |
240 | |