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