xref: /llvm-project/mlir/include/mlir/AsmParser/AsmParserState.h (revision 3bcc63e36ad4afc653ba2e2e92a553452252f92f)
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;
SMDefinitionSMDefinition37     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 {
ResultGroupDefinitionOperationDefinition::ResultGroupDefinition49       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 
OperationDefinitionOperationDefinition58     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 = {})
blockBlockDefinition83         : 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 = {})
nameAttributeAliasDefinition101         : 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 {
TypeAliasDefinitionTypeAliasDefinition116     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