1 //===- Parser.cpp ---------------------------------------------------------===// 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 #include "mlir/Tools/PDLL/Parser/Parser.h" 10 #include "Lexer.h" 11 #include "mlir/Support/LogicalResult.h" 12 #include "mlir/TableGen/Argument.h" 13 #include "mlir/TableGen/Attribute.h" 14 #include "mlir/TableGen/Constraint.h" 15 #include "mlir/TableGen/Format.h" 16 #include "mlir/TableGen/Operator.h" 17 #include "mlir/Tools/PDLL/AST/Context.h" 18 #include "mlir/Tools/PDLL/AST/Diagnostic.h" 19 #include "mlir/Tools/PDLL/AST/Nodes.h" 20 #include "mlir/Tools/PDLL/AST/Types.h" 21 #include "mlir/Tools/PDLL/ODS/Constraint.h" 22 #include "mlir/Tools/PDLL/ODS/Context.h" 23 #include "mlir/Tools/PDLL/ODS/Operation.h" 24 #include "mlir/Tools/PDLL/Parser/CodeComplete.h" 25 #include "llvm/ADT/StringExtras.h" 26 #include "llvm/ADT/TypeSwitch.h" 27 #include "llvm/Support/FormatVariadic.h" 28 #include "llvm/Support/ManagedStatic.h" 29 #include "llvm/Support/SaveAndRestore.h" 30 #include "llvm/Support/ScopedPrinter.h" 31 #include "llvm/TableGen/Error.h" 32 #include "llvm/TableGen/Parser.h" 33 #include <string> 34 35 using namespace mlir; 36 using namespace mlir::pdll; 37 38 //===----------------------------------------------------------------------===// 39 // Parser 40 //===----------------------------------------------------------------------===// 41 42 namespace { 43 class Parser { 44 public: 45 Parser(ast::Context &ctx, llvm::SourceMgr &sourceMgr, 46 CodeCompleteContext *codeCompleteContext) 47 : ctx(ctx), lexer(sourceMgr, ctx.getDiagEngine(), codeCompleteContext), 48 curToken(lexer.lexToken()), valueTy(ast::ValueType::get(ctx)), 49 valueRangeTy(ast::ValueRangeType::get(ctx)), 50 typeTy(ast::TypeType::get(ctx)), 51 typeRangeTy(ast::TypeRangeType::get(ctx)), 52 attrTy(ast::AttributeType::get(ctx)), 53 codeCompleteContext(codeCompleteContext) {} 54 55 /// Try to parse a new module. Returns nullptr in the case of failure. 56 FailureOr<ast::Module *> parseModule(); 57 58 private: 59 /// The current context of the parser. It allows for the parser to know a bit 60 /// about the construct it is nested within during parsing. This is used 61 /// specifically to provide additional verification during parsing, e.g. to 62 /// prevent using rewrites within a match context, matcher constraints within 63 /// a rewrite section, etc. 64 enum class ParserContext { 65 /// The parser is in the global context. 66 Global, 67 /// The parser is currently within a Constraint, which disallows all types 68 /// of rewrites (e.g. `erase`, `replace`, calls to Rewrites, etc.). 69 Constraint, 70 /// The parser is currently within the matcher portion of a Pattern, which 71 /// is allows a terminal operation rewrite statement but no other rewrite 72 /// transformations. 73 PatternMatch, 74 /// The parser is currently within a Rewrite, which disallows calls to 75 /// constraints, requires operation expressions to have names, etc. 76 Rewrite, 77 }; 78 79 //===--------------------------------------------------------------------===// 80 // Parsing 81 //===--------------------------------------------------------------------===// 82 83 /// Push a new decl scope onto the lexer. 84 ast::DeclScope *pushDeclScope() { 85 ast::DeclScope *newScope = 86 new (scopeAllocator.Allocate()) ast::DeclScope(curDeclScope); 87 return (curDeclScope = newScope); 88 } 89 void pushDeclScope(ast::DeclScope *scope) { curDeclScope = scope; } 90 91 /// Pop the last decl scope from the lexer. 92 void popDeclScope() { curDeclScope = curDeclScope->getParentScope(); } 93 94 /// Parse the body of an AST module. 95 LogicalResult parseModuleBody(SmallVectorImpl<ast::Decl *> &decls); 96 97 /// Try to convert the given expression to `type`. Returns failure and emits 98 /// an error if a conversion is not viable. On failure, `noteAttachFn` is 99 /// invoked to attach notes to the emitted error diagnostic. On success, 100 /// `expr` is updated to the expression used to convert to `type`. 101 LogicalResult convertExpressionTo( 102 ast::Expr *&expr, ast::Type type, 103 function_ref<void(ast::Diagnostic &diag)> noteAttachFn = {}); 104 105 /// Given an operation expression, convert it to a Value or ValueRange 106 /// typed expression. 107 ast::Expr *convertOpToValue(const ast::Expr *opExpr); 108 109 /// Lookup ODS information for the given operation, returns nullptr if no 110 /// information is found. 111 const ods::Operation *lookupODSOperation(Optional<StringRef> opName) { 112 return opName ? ctx.getODSContext().lookupOperation(*opName) : nullptr; 113 } 114 115 //===--------------------------------------------------------------------===// 116 // Directives 117 118 LogicalResult parseDirective(SmallVectorImpl<ast::Decl *> &decls); 119 LogicalResult parseInclude(SmallVectorImpl<ast::Decl *> &decls); 120 LogicalResult parseTdInclude(StringRef filename, SMRange fileLoc, 121 SmallVectorImpl<ast::Decl *> &decls); 122 123 /// Process the records of a parsed tablegen include file. 124 void processTdIncludeRecords(llvm::RecordKeeper &tdRecords, 125 SmallVectorImpl<ast::Decl *> &decls); 126 127 /// Create a user defined native constraint for a constraint imported from 128 /// ODS. 129 template <typename ConstraintT> 130 ast::Decl *createODSNativePDLLConstraintDecl(StringRef name, 131 StringRef codeBlock, SMRange loc, 132 ast::Type type); 133 template <typename ConstraintT> 134 ast::Decl * 135 createODSNativePDLLConstraintDecl(const tblgen::Constraint &constraint, 136 SMRange loc, ast::Type type); 137 138 //===--------------------------------------------------------------------===// 139 // Decls 140 141 /// This structure contains the set of pattern metadata that may be parsed. 142 struct ParsedPatternMetadata { 143 Optional<uint16_t> benefit; 144 bool hasBoundedRecursion = false; 145 }; 146 147 FailureOr<ast::Decl *> parseTopLevelDecl(); 148 FailureOr<ast::NamedAttributeDecl *> 149 parseNamedAttributeDecl(Optional<StringRef> parentOpName); 150 151 /// Parse an argument variable as part of the signature of a 152 /// UserConstraintDecl or UserRewriteDecl. 153 FailureOr<ast::VariableDecl *> parseArgumentDecl(); 154 155 /// Parse a result variable as part of the signature of a UserConstraintDecl 156 /// or UserRewriteDecl. 157 FailureOr<ast::VariableDecl *> parseResultDecl(unsigned resultNum); 158 159 /// Parse a UserConstraintDecl. `isInline` signals if the constraint is being 160 /// defined in a non-global context. 161 FailureOr<ast::UserConstraintDecl *> 162 parseUserConstraintDecl(bool isInline = false); 163 164 /// Parse an inline UserConstraintDecl. An inline decl is one defined in a 165 /// non-global context, such as within a Pattern/Constraint/etc. 166 FailureOr<ast::UserConstraintDecl *> parseInlineUserConstraintDecl(); 167 168 /// Parse a PDLL (i.e. non-native) UserRewriteDecl whose body is defined using 169 /// PDLL constructs. 170 FailureOr<ast::UserConstraintDecl *> parseUserPDLLConstraintDecl( 171 const ast::Name &name, bool isInline, 172 ArrayRef<ast::VariableDecl *> arguments, ast::DeclScope *argumentScope, 173 ArrayRef<ast::VariableDecl *> results, ast::Type resultType); 174 175 /// Parse a parseUserRewriteDecl. `isInline` signals if the rewrite is being 176 /// defined in a non-global context. 177 FailureOr<ast::UserRewriteDecl *> parseUserRewriteDecl(bool isInline = false); 178 179 /// Parse an inline UserRewriteDecl. An inline decl is one defined in a 180 /// non-global context, such as within a Pattern/Rewrite/etc. 181 FailureOr<ast::UserRewriteDecl *> parseInlineUserRewriteDecl(); 182 183 /// Parse a PDLL (i.e. non-native) UserRewriteDecl whose body is defined using 184 /// PDLL constructs. 185 FailureOr<ast::UserRewriteDecl *> parseUserPDLLRewriteDecl( 186 const ast::Name &name, bool isInline, 187 ArrayRef<ast::VariableDecl *> arguments, ast::DeclScope *argumentScope, 188 ArrayRef<ast::VariableDecl *> results, ast::Type resultType); 189 190 /// Parse either a UserConstraintDecl or UserRewriteDecl. These decls have 191 /// effectively the same syntax, and only differ on slight semantics (given 192 /// the different parsing contexts). 193 template <typename T, typename ParseUserPDLLDeclFnT> 194 FailureOr<T *> parseUserConstraintOrRewriteDecl( 195 ParseUserPDLLDeclFnT &&parseUserPDLLFn, ParserContext declContext, 196 StringRef anonymousNamePrefix, bool isInline); 197 198 /// Parse a native (i.e. non-PDLL) UserConstraintDecl or UserRewriteDecl. 199 /// These decls have effectively the same syntax. 200 template <typename T> 201 FailureOr<T *> parseUserNativeConstraintOrRewriteDecl( 202 const ast::Name &name, bool isInline, 203 ArrayRef<ast::VariableDecl *> arguments, 204 ArrayRef<ast::VariableDecl *> results, ast::Type resultType); 205 206 /// Parse the functional signature (i.e. the arguments and results) of a 207 /// UserConstraintDecl or UserRewriteDecl. 208 LogicalResult parseUserConstraintOrRewriteSignature( 209 SmallVectorImpl<ast::VariableDecl *> &arguments, 210 SmallVectorImpl<ast::VariableDecl *> &results, 211 ast::DeclScope *&argumentScope, ast::Type &resultType); 212 213 /// Validate the return (which if present is specified by bodyIt) of a 214 /// UserConstraintDecl or UserRewriteDecl. 215 LogicalResult validateUserConstraintOrRewriteReturn( 216 StringRef declType, ast::CompoundStmt *body, 217 ArrayRef<ast::Stmt *>::iterator bodyIt, 218 ArrayRef<ast::Stmt *>::iterator bodyE, 219 ArrayRef<ast::VariableDecl *> results, ast::Type &resultType); 220 221 FailureOr<ast::CompoundStmt *> 222 parseLambdaBody(function_ref<LogicalResult(ast::Stmt *&)> processStatementFn, 223 bool expectTerminalSemicolon = true); 224 FailureOr<ast::CompoundStmt *> parsePatternLambdaBody(); 225 FailureOr<ast::Decl *> parsePatternDecl(); 226 LogicalResult parsePatternDeclMetadata(ParsedPatternMetadata &metadata); 227 228 /// Check to see if a decl has already been defined with the given name, if 229 /// one has emit and error and return failure. Returns success otherwise. 230 LogicalResult checkDefineNamedDecl(const ast::Name &name); 231 232 /// Try to define a variable decl with the given components, returns the 233 /// variable on success. 234 FailureOr<ast::VariableDecl *> 235 defineVariableDecl(StringRef name, SMRange nameLoc, ast::Type type, 236 ast::Expr *initExpr, 237 ArrayRef<ast::ConstraintRef> constraints); 238 FailureOr<ast::VariableDecl *> 239 defineVariableDecl(StringRef name, SMRange nameLoc, ast::Type type, 240 ArrayRef<ast::ConstraintRef> constraints); 241 242 /// Parse the constraint reference list for a variable decl. 243 LogicalResult parseVariableDeclConstraintList( 244 SmallVectorImpl<ast::ConstraintRef> &constraints); 245 246 /// Parse the expression used within a type constraint, e.g. Attr<type-expr>. 247 FailureOr<ast::Expr *> parseTypeConstraintExpr(); 248 249 /// Try to parse a single reference to a constraint. `typeConstraint` is the 250 /// location of a previously parsed type constraint for the entity that will 251 /// be constrained by the parsed constraint. `existingConstraints` are any 252 /// existing constraints that have already been parsed for the same entity 253 /// that will be constrained by this constraint. `allowInlineTypeConstraints` 254 /// allows the use of inline Type constraints, e.g. `Value<valueType: Type>`. 255 /// If `allowNonCoreConstraints` is true, then complex (e.g. user defined 256 /// constraints) may be used with the variable. 257 FailureOr<ast::ConstraintRef> 258 parseConstraint(Optional<SMRange> &typeConstraint, 259 ArrayRef<ast::ConstraintRef> existingConstraints, 260 bool allowInlineTypeConstraints, 261 bool allowNonCoreConstraints); 262 263 /// Try to parse the constraint for a UserConstraintDecl/UserRewriteDecl 264 /// argument or result variable. The constraints for these variables do not 265 /// allow inline type constraints, and only permit a single constraint. 266 FailureOr<ast::ConstraintRef> parseArgOrResultConstraint(); 267 268 //===--------------------------------------------------------------------===// 269 // Exprs 270 271 FailureOr<ast::Expr *> parseExpr(); 272 273 /// Identifier expressions. 274 FailureOr<ast::Expr *> parseAttributeExpr(); 275 FailureOr<ast::Expr *> parseCallExpr(ast::Expr *parentExpr); 276 FailureOr<ast::Expr *> parseDeclRefExpr(StringRef name, SMRange loc); 277 FailureOr<ast::Expr *> parseIdentifierExpr(); 278 FailureOr<ast::Expr *> parseInlineConstraintLambdaExpr(); 279 FailureOr<ast::Expr *> parseInlineRewriteLambdaExpr(); 280 FailureOr<ast::Expr *> parseMemberAccessExpr(ast::Expr *parentExpr); 281 FailureOr<ast::OpNameDecl *> parseOperationName(bool allowEmptyName = false); 282 FailureOr<ast::OpNameDecl *> parseWrappedOperationName(bool allowEmptyName); 283 FailureOr<ast::Expr *> parseOperationExpr(); 284 FailureOr<ast::Expr *> parseTupleExpr(); 285 FailureOr<ast::Expr *> parseTypeExpr(); 286 FailureOr<ast::Expr *> parseUnderscoreExpr(); 287 288 //===--------------------------------------------------------------------===// 289 // Stmts 290 291 FailureOr<ast::Stmt *> parseStmt(bool expectTerminalSemicolon = true); 292 FailureOr<ast::CompoundStmt *> parseCompoundStmt(); 293 FailureOr<ast::EraseStmt *> parseEraseStmt(); 294 FailureOr<ast::LetStmt *> parseLetStmt(); 295 FailureOr<ast::ReplaceStmt *> parseReplaceStmt(); 296 FailureOr<ast::ReturnStmt *> parseReturnStmt(); 297 FailureOr<ast::RewriteStmt *> parseRewriteStmt(); 298 299 //===--------------------------------------------------------------------===// 300 // Creation+Analysis 301 //===--------------------------------------------------------------------===// 302 303 //===--------------------------------------------------------------------===// 304 // Decls 305 306 /// Try to extract a callable from the given AST node. Returns nullptr on 307 /// failure. 308 ast::CallableDecl *tryExtractCallableDecl(ast::Node *node); 309 310 /// Try to create a pattern decl with the given components, returning the 311 /// Pattern on success. 312 FailureOr<ast::PatternDecl *> 313 createPatternDecl(SMRange loc, const ast::Name *name, 314 const ParsedPatternMetadata &metadata, 315 ast::CompoundStmt *body); 316 317 /// Build the result type for a UserConstraintDecl/UserRewriteDecl given a set 318 /// of results, defined as part of the signature. 319 ast::Type 320 createUserConstraintRewriteResultType(ArrayRef<ast::VariableDecl *> results); 321 322 /// Create a PDLL (i.e. non-native) UserConstraintDecl or UserRewriteDecl. 323 template <typename T> 324 FailureOr<T *> createUserPDLLConstraintOrRewriteDecl( 325 const ast::Name &name, ArrayRef<ast::VariableDecl *> arguments, 326 ArrayRef<ast::VariableDecl *> results, ast::Type resultType, 327 ast::CompoundStmt *body); 328 329 /// Try to create a variable decl with the given components, returning the 330 /// Variable on success. 331 FailureOr<ast::VariableDecl *> 332 createVariableDecl(StringRef name, SMRange loc, ast::Expr *initializer, 333 ArrayRef<ast::ConstraintRef> constraints); 334 335 /// Create a variable for an argument or result defined as part of the 336 /// signature of a UserConstraintDecl/UserRewriteDecl. 337 FailureOr<ast::VariableDecl *> 338 createArgOrResultVariableDecl(StringRef name, SMRange loc, 339 const ast::ConstraintRef &constraint); 340 341 /// Validate the constraints used to constraint a variable decl. 342 /// `inferredType` is the type of the variable inferred by the constraints 343 /// within the list, and is updated to the most refined type as determined by 344 /// the constraints. Returns success if the constraint list is valid, failure 345 /// otherwise. If `allowNonCoreConstraints` is true, then complex (e.g. user 346 /// defined constraints) may be used with the variable. 347 LogicalResult 348 validateVariableConstraints(ArrayRef<ast::ConstraintRef> constraints, 349 ast::Type &inferredType, 350 bool allowNonCoreConstraints = true); 351 /// Validate a single reference to a constraint. `inferredType` contains the 352 /// currently inferred variabled type and is refined within the type defined 353 /// by the constraint. Returns success if the constraint is valid, failure 354 /// otherwise. If `allowNonCoreConstraints` is true, then complex (e.g. user 355 /// defined constraints) may be used with the variable. 356 LogicalResult validateVariableConstraint(const ast::ConstraintRef &ref, 357 ast::Type &inferredType, 358 bool allowNonCoreConstraints = true); 359 LogicalResult validateTypeConstraintExpr(const ast::Expr *typeExpr); 360 LogicalResult validateTypeRangeConstraintExpr(const ast::Expr *typeExpr); 361 362 //===--------------------------------------------------------------------===// 363 // Exprs 364 365 FailureOr<ast::CallExpr *> 366 createCallExpr(SMRange loc, ast::Expr *parentExpr, 367 MutableArrayRef<ast::Expr *> arguments); 368 FailureOr<ast::DeclRefExpr *> createDeclRefExpr(SMRange loc, ast::Decl *decl); 369 FailureOr<ast::DeclRefExpr *> 370 createInlineVariableExpr(ast::Type type, StringRef name, SMRange loc, 371 ArrayRef<ast::ConstraintRef> constraints); 372 FailureOr<ast::MemberAccessExpr *> 373 createMemberAccessExpr(ast::Expr *parentExpr, StringRef name, SMRange loc); 374 375 /// Validate the member access `name` into the given parent expression. On 376 /// success, this also returns the type of the member accessed. 377 FailureOr<ast::Type> validateMemberAccess(ast::Expr *parentExpr, 378 StringRef name, SMRange loc); 379 FailureOr<ast::OperationExpr *> 380 createOperationExpr(SMRange loc, const ast::OpNameDecl *name, 381 MutableArrayRef<ast::Expr *> operands, 382 MutableArrayRef<ast::NamedAttributeDecl *> attributes, 383 MutableArrayRef<ast::Expr *> results); 384 LogicalResult 385 validateOperationOperands(SMRange loc, Optional<StringRef> name, 386 const ods::Operation *odsOp, 387 MutableArrayRef<ast::Expr *> operands); 388 LogicalResult validateOperationResults(SMRange loc, Optional<StringRef> name, 389 const ods::Operation *odsOp, 390 MutableArrayRef<ast::Expr *> results); 391 LogicalResult validateOperationOperandsOrResults( 392 StringRef groupName, SMRange loc, Optional<SMRange> odsOpLoc, 393 Optional<StringRef> name, MutableArrayRef<ast::Expr *> values, 394 ArrayRef<ods::OperandOrResult> odsValues, ast::Type singleTy, 395 ast::Type rangeTy); 396 FailureOr<ast::TupleExpr *> createTupleExpr(SMRange loc, 397 ArrayRef<ast::Expr *> elements, 398 ArrayRef<StringRef> elementNames); 399 400 //===--------------------------------------------------------------------===// 401 // Stmts 402 403 FailureOr<ast::EraseStmt *> createEraseStmt(SMRange loc, ast::Expr *rootOp); 404 FailureOr<ast::ReplaceStmt *> 405 createReplaceStmt(SMRange loc, ast::Expr *rootOp, 406 MutableArrayRef<ast::Expr *> replValues); 407 FailureOr<ast::RewriteStmt *> 408 createRewriteStmt(SMRange loc, ast::Expr *rootOp, 409 ast::CompoundStmt *rewriteBody); 410 411 //===--------------------------------------------------------------------===// 412 // Code Completion 413 //===--------------------------------------------------------------------===// 414 415 /// The set of various code completion methods. Every completion method 416 /// returns `failure` to stop the parsing process after providing completion 417 /// results. 418 419 LogicalResult codeCompleteMemberAccess(ast::Expr *parentExpr); 420 LogicalResult codeCompleteAttributeName(Optional<StringRef> opName); 421 LogicalResult codeCompleteConstraintName(ast::Type inferredType, 422 bool allowNonCoreConstraints, 423 bool allowInlineTypeConstraints); 424 LogicalResult codeCompleteDialectName(); 425 LogicalResult codeCompleteOperationName(StringRef dialectName); 426 LogicalResult codeCompletePatternMetadata(); 427 428 //===--------------------------------------------------------------------===// 429 // Lexer Utilities 430 //===--------------------------------------------------------------------===// 431 432 /// If the current token has the specified kind, consume it and return true. 433 /// If not, return false. 434 bool consumeIf(Token::Kind kind) { 435 if (curToken.isNot(kind)) 436 return false; 437 consumeToken(kind); 438 return true; 439 } 440 441 /// Advance the current lexer onto the next token. 442 void consumeToken() { 443 assert(curToken.isNot(Token::eof, Token::error) && 444 "shouldn't advance past EOF or errors"); 445 curToken = lexer.lexToken(); 446 } 447 448 /// Advance the current lexer onto the next token, asserting what the expected 449 /// current token is. This is preferred to the above method because it leads 450 /// to more self-documenting code with better checking. 451 void consumeToken(Token::Kind kind) { 452 assert(curToken.is(kind) && "consumed an unexpected token"); 453 consumeToken(); 454 } 455 456 /// Reset the lexer to the location at the given position. 457 void resetToken(SMRange tokLoc) { 458 lexer.resetPointer(tokLoc.Start.getPointer()); 459 curToken = lexer.lexToken(); 460 } 461 462 /// Consume the specified token if present and return success. On failure, 463 /// output a diagnostic and return failure. 464 LogicalResult parseToken(Token::Kind kind, const Twine &msg) { 465 if (curToken.getKind() != kind) 466 return emitError(curToken.getLoc(), msg); 467 consumeToken(); 468 return success(); 469 } 470 LogicalResult emitError(SMRange loc, const Twine &msg) { 471 lexer.emitError(loc, msg); 472 return failure(); 473 } 474 LogicalResult emitError(const Twine &msg) { 475 return emitError(curToken.getLoc(), msg); 476 } 477 LogicalResult emitErrorAndNote(SMRange loc, const Twine &msg, SMRange noteLoc, 478 const Twine ¬e) { 479 lexer.emitErrorAndNote(loc, msg, noteLoc, note); 480 return failure(); 481 } 482 483 //===--------------------------------------------------------------------===// 484 // Fields 485 //===--------------------------------------------------------------------===// 486 487 /// The owning AST context. 488 ast::Context &ctx; 489 490 /// The lexer of this parser. 491 Lexer lexer; 492 493 /// The current token within the lexer. 494 Token curToken; 495 496 /// The most recently defined decl scope. 497 ast::DeclScope *curDeclScope = nullptr; 498 llvm::SpecificBumpPtrAllocator<ast::DeclScope> scopeAllocator; 499 500 /// The current context of the parser. 501 ParserContext parserContext = ParserContext::Global; 502 503 /// Cached types to simplify verification and expression creation. 504 ast::Type valueTy, valueRangeTy; 505 ast::Type typeTy, typeRangeTy; 506 ast::Type attrTy; 507 508 /// A counter used when naming anonymous constraints and rewrites. 509 unsigned anonymousDeclNameCounter = 0; 510 511 /// The optional code completion context. 512 CodeCompleteContext *codeCompleteContext; 513 }; 514 } // namespace 515 516 FailureOr<ast::Module *> Parser::parseModule() { 517 SMLoc moduleLoc = curToken.getStartLoc(); 518 pushDeclScope(); 519 520 // Parse the top-level decls of the module. 521 SmallVector<ast::Decl *> decls; 522 if (failed(parseModuleBody(decls))) 523 return popDeclScope(), failure(); 524 525 popDeclScope(); 526 return ast::Module::create(ctx, moduleLoc, decls); 527 } 528 529 LogicalResult Parser::parseModuleBody(SmallVectorImpl<ast::Decl *> &decls) { 530 while (curToken.isNot(Token::eof)) { 531 if (curToken.is(Token::directive)) { 532 if (failed(parseDirective(decls))) 533 return failure(); 534 continue; 535 } 536 537 FailureOr<ast::Decl *> decl = parseTopLevelDecl(); 538 if (failed(decl)) 539 return failure(); 540 decls.push_back(*decl); 541 } 542 return success(); 543 } 544 545 ast::Expr *Parser::convertOpToValue(const ast::Expr *opExpr) { 546 return ast::AllResultsMemberAccessExpr::create(ctx, opExpr->getLoc(), opExpr, 547 valueRangeTy); 548 } 549 550 LogicalResult Parser::convertExpressionTo( 551 ast::Expr *&expr, ast::Type type, 552 function_ref<void(ast::Diagnostic &diag)> noteAttachFn) { 553 ast::Type exprType = expr->getType(); 554 if (exprType == type) 555 return success(); 556 557 auto emitConvertError = [&]() -> ast::InFlightDiagnostic { 558 ast::InFlightDiagnostic diag = ctx.getDiagEngine().emitError( 559 expr->getLoc(), llvm::formatv("unable to convert expression of type " 560 "`{0}` to the expected type of " 561 "`{1}`", 562 exprType, type)); 563 if (noteAttachFn) 564 noteAttachFn(*diag); 565 return diag; 566 }; 567 568 if (auto exprOpType = exprType.dyn_cast<ast::OperationType>()) { 569 // Two operation types are compatible if they have the same name, or if the 570 // expected type is more general. 571 if (auto opType = type.dyn_cast<ast::OperationType>()) { 572 if (opType.getName()) 573 return emitConvertError(); 574 return success(); 575 } 576 577 // An operation can always convert to a ValueRange. 578 if (type == valueRangeTy) { 579 expr = ast::AllResultsMemberAccessExpr::create(ctx, expr->getLoc(), expr, 580 valueRangeTy); 581 return success(); 582 } 583 584 // Allow conversion to a single value by constraining the result range. 585 if (type == valueTy) { 586 // If the operation is registered, we can verify if it can ever have a 587 // single result. 588 Optional<StringRef> opName = exprOpType.getName(); 589 if (const ods::Operation *odsOp = lookupODSOperation(opName)) { 590 if (odsOp->getResults().empty()) { 591 return emitConvertError()->attachNote( 592 llvm::formatv("see the definition of `{0}`, which was defined " 593 "with zero results", 594 odsOp->getName()), 595 odsOp->getLoc()); 596 } 597 598 unsigned numSingleResults = llvm::count_if( 599 odsOp->getResults(), [](const ods::OperandOrResult &result) { 600 return result.getVariableLengthKind() == 601 ods::VariableLengthKind::Single; 602 }); 603 if (numSingleResults > 1) { 604 return emitConvertError()->attachNote( 605 llvm::formatv("see the definition of `{0}`, which was defined " 606 "with at least {1} results", 607 odsOp->getName(), numSingleResults), 608 odsOp->getLoc()); 609 } 610 } 611 612 expr = ast::AllResultsMemberAccessExpr::create(ctx, expr->getLoc(), expr, 613 valueTy); 614 return success(); 615 } 616 return emitConvertError(); 617 } 618 619 // FIXME: Decide how to allow/support converting a single result to multiple, 620 // and multiple to a single result. For now, we just allow Single->Range, 621 // but this isn't something really supported in the PDL dialect. We should 622 // figure out some way to support both. 623 if ((exprType == valueTy || exprType == valueRangeTy) && 624 (type == valueTy || type == valueRangeTy)) 625 return success(); 626 if ((exprType == typeTy || exprType == typeRangeTy) && 627 (type == typeTy || type == typeRangeTy)) 628 return success(); 629 630 // Handle tuple types. 631 if (auto exprTupleType = exprType.dyn_cast<ast::TupleType>()) { 632 auto tupleType = type.dyn_cast<ast::TupleType>(); 633 if (!tupleType || tupleType.size() != exprTupleType.size()) 634 return emitConvertError(); 635 636 // Build a new tuple expression using each of the elements of the current 637 // tuple. 638 SmallVector<ast::Expr *> newExprs; 639 for (unsigned i = 0, e = exprTupleType.size(); i < e; ++i) { 640 newExprs.push_back(ast::MemberAccessExpr::create( 641 ctx, expr->getLoc(), expr, llvm::to_string(i), 642 exprTupleType.getElementTypes()[i])); 643 644 auto diagFn = [&](ast::Diagnostic &diag) { 645 diag.attachNote(llvm::formatv("when converting element #{0} of `{1}`", 646 i, exprTupleType)); 647 if (noteAttachFn) 648 noteAttachFn(diag); 649 }; 650 if (failed(convertExpressionTo(newExprs.back(), 651 tupleType.getElementTypes()[i], diagFn))) 652 return failure(); 653 } 654 expr = ast::TupleExpr::create(ctx, expr->getLoc(), newExprs, 655 tupleType.getElementNames()); 656 return success(); 657 } 658 659 return emitConvertError(); 660 } 661 662 //===----------------------------------------------------------------------===// 663 // Directives 664 665 LogicalResult Parser::parseDirective(SmallVectorImpl<ast::Decl *> &decls) { 666 StringRef directive = curToken.getSpelling(); 667 if (directive == "#include") 668 return parseInclude(decls); 669 670 return emitError("unknown directive `" + directive + "`"); 671 } 672 673 LogicalResult Parser::parseInclude(SmallVectorImpl<ast::Decl *> &decls) { 674 SMRange loc = curToken.getLoc(); 675 consumeToken(Token::directive); 676 677 // Parse the file being included. 678 if (!curToken.isString()) 679 return emitError(loc, 680 "expected string file name after `include` directive"); 681 SMRange fileLoc = curToken.getLoc(); 682 std::string filenameStr = curToken.getStringValue(); 683 StringRef filename = filenameStr; 684 consumeToken(); 685 686 // Check the type of include. If ending with `.pdll`, this is another pdl file 687 // to be parsed along with the current module. 688 if (filename.endswith(".pdll")) { 689 if (failed(lexer.pushInclude(filename))) 690 return emitError(fileLoc, 691 "unable to open include file `" + filename + "`"); 692 693 // If we added the include successfully, parse it into the current module. 694 // Make sure to save the current token so that we can restore it when we 695 // finish parsing the nested file. 696 Token oldToken = curToken; 697 curToken = lexer.lexToken(); 698 LogicalResult result = parseModuleBody(decls); 699 curToken = oldToken; 700 return result; 701 } 702 703 // Otherwise, this must be a `.td` include. 704 if (filename.endswith(".td")) 705 return parseTdInclude(filename, fileLoc, decls); 706 707 return emitError(fileLoc, 708 "expected include filename to end with `.pdll` or `.td`"); 709 } 710 711 LogicalResult Parser::parseTdInclude(StringRef filename, llvm::SMRange fileLoc, 712 SmallVectorImpl<ast::Decl *> &decls) { 713 llvm::SourceMgr &parserSrcMgr = lexer.getSourceMgr(); 714 715 // This class provides a context argument for the llvm::SourceMgr diagnostic 716 // handler. 717 struct DiagHandlerContext { 718 Parser &parser; 719 StringRef filename; 720 llvm::SMRange loc; 721 } handlerContext{*this, filename, fileLoc}; 722 723 // Set the diagnostic handler for the tablegen source manager. 724 llvm::SrcMgr.setDiagHandler( 725 [](const llvm::SMDiagnostic &diag, void *rawHandlerContext) { 726 auto *ctx = reinterpret_cast<DiagHandlerContext *>(rawHandlerContext); 727 (void)ctx->parser.emitError( 728 ctx->loc, 729 llvm::formatv("error while processing include file `{0}`: {1}", 730 ctx->filename, diag.getMessage())); 731 }, 732 &handlerContext); 733 734 // Use the source manager to open the file, but don't yet add it. 735 std::string includedFile; 736 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> includeBuffer = 737 parserSrcMgr.OpenIncludeFile(filename.str(), includedFile); 738 if (!includeBuffer) 739 return emitError(fileLoc, "unable to open include file `" + filename + "`"); 740 741 auto processFn = [&](llvm::RecordKeeper &records) { 742 processTdIncludeRecords(records, decls); 743 744 // After we are done processing, move all of the tablegen source buffers to 745 // the main parser source mgr. This allows for directly using source 746 // locations from the .td files without needing to remap them. 747 parserSrcMgr.takeSourceBuffersFrom(llvm::SrcMgr); 748 return false; 749 }; 750 if (llvm::TableGenParseFile(std::move(*includeBuffer), 751 parserSrcMgr.getIncludeDirs(), processFn)) 752 return failure(); 753 754 return success(); 755 } 756 757 void Parser::processTdIncludeRecords(llvm::RecordKeeper &tdRecords, 758 SmallVectorImpl<ast::Decl *> &decls) { 759 // Return the length kind of the given value. 760 auto getLengthKind = [](const auto &value) { 761 if (value.isOptional()) 762 return ods::VariableLengthKind::Optional; 763 return value.isVariadic() ? ods::VariableLengthKind::Variadic 764 : ods::VariableLengthKind::Single; 765 }; 766 767 // Insert a type constraint into the ODS context. 768 ods::Context &odsContext = ctx.getODSContext(); 769 auto addTypeConstraint = [&](const tblgen::NamedTypeConstraint &cst) 770 -> const ods::TypeConstraint & { 771 return odsContext.insertTypeConstraint(cst.constraint.getDefName(), 772 cst.constraint.getSummary(), 773 cst.constraint.getCPPClassName()); 774 }; 775 auto convertLocToRange = [&](llvm::SMLoc loc) -> llvm::SMRange { 776 return {loc, llvm::SMLoc::getFromPointer(loc.getPointer() + 1)}; 777 }; 778 779 // Process the parsed tablegen records to build ODS information. 780 /// Operations. 781 for (llvm::Record *def : tdRecords.getAllDerivedDefinitions("Op")) { 782 tblgen::Operator op(def); 783 784 bool inserted = false; 785 ods::Operation *odsOp = nullptr; 786 std::tie(odsOp, inserted) = 787 odsContext.insertOperation(op.getOperationName(), op.getSummary(), 788 op.getDescription(), op.getLoc().front()); 789 790 // Ignore operations that have already been added. 791 if (!inserted) 792 continue; 793 794 for (const tblgen::NamedAttribute &attr : op.getAttributes()) { 795 odsOp->appendAttribute( 796 attr.name, attr.attr.isOptional(), 797 odsContext.insertAttributeConstraint(attr.attr.getAttrDefName(), 798 attr.attr.getSummary(), 799 attr.attr.getStorageType())); 800 } 801 for (const tblgen::NamedTypeConstraint &operand : op.getOperands()) { 802 odsOp->appendOperand(operand.name, getLengthKind(operand), 803 addTypeConstraint(operand)); 804 } 805 for (const tblgen::NamedTypeConstraint &result : op.getResults()) { 806 odsOp->appendResult(result.name, getLengthKind(result), 807 addTypeConstraint(result)); 808 } 809 } 810 /// Attr constraints. 811 for (llvm::Record *def : tdRecords.getAllDerivedDefinitions("Attr")) { 812 if (!def->isAnonymous() && !curDeclScope->lookup(def->getName())) { 813 decls.push_back( 814 createODSNativePDLLConstraintDecl<ast::AttrConstraintDecl>( 815 tblgen::AttrConstraint(def), 816 convertLocToRange(def->getLoc().front()), attrTy)); 817 } 818 } 819 /// Type constraints. 820 for (llvm::Record *def : tdRecords.getAllDerivedDefinitions("Type")) { 821 if (!def->isAnonymous() && !curDeclScope->lookup(def->getName())) { 822 decls.push_back( 823 createODSNativePDLLConstraintDecl<ast::TypeConstraintDecl>( 824 tblgen::TypeConstraint(def), 825 convertLocToRange(def->getLoc().front()), typeTy)); 826 } 827 } 828 /// Interfaces. 829 ast::Type opTy = ast::OperationType::get(ctx); 830 for (llvm::Record *def : tdRecords.getAllDerivedDefinitions("Interface")) { 831 StringRef name = def->getName(); 832 if (def->isAnonymous() || curDeclScope->lookup(name) || 833 def->isSubClassOf("DeclareInterfaceMethods")) 834 continue; 835 SMRange loc = convertLocToRange(def->getLoc().front()); 836 837 StringRef className = def->getValueAsString("cppClassName"); 838 StringRef cppNamespace = def->getValueAsString("cppNamespace"); 839 std::string codeBlock = 840 llvm::formatv("llvm::isa<{0}::{1}>(self)", cppNamespace, className) 841 .str(); 842 843 if (def->isSubClassOf("OpInterface")) { 844 decls.push_back(createODSNativePDLLConstraintDecl<ast::OpConstraintDecl>( 845 name, codeBlock, loc, opTy)); 846 } else if (def->isSubClassOf("AttrInterface")) { 847 decls.push_back( 848 createODSNativePDLLConstraintDecl<ast::AttrConstraintDecl>( 849 name, codeBlock, loc, attrTy)); 850 } else if (def->isSubClassOf("TypeInterface")) { 851 decls.push_back( 852 createODSNativePDLLConstraintDecl<ast::TypeConstraintDecl>( 853 name, codeBlock, loc, typeTy)); 854 } 855 } 856 } 857 858 template <typename ConstraintT> 859 ast::Decl * 860 Parser::createODSNativePDLLConstraintDecl(StringRef name, StringRef codeBlock, 861 SMRange loc, ast::Type type) { 862 // Build the single input parameter. 863 ast::DeclScope *argScope = pushDeclScope(); 864 auto *paramVar = ast::VariableDecl::create( 865 ctx, ast::Name::create(ctx, "self", loc), type, 866 /*initExpr=*/nullptr, ast::ConstraintRef(ConstraintT::create(ctx, loc))); 867 argScope->add(paramVar); 868 popDeclScope(); 869 870 // Build the native constraint. 871 auto *constraintDecl = ast::UserConstraintDecl::createNative( 872 ctx, ast::Name::create(ctx, name, loc), paramVar, 873 /*results=*/llvm::None, codeBlock, ast::TupleType::get(ctx)); 874 curDeclScope->add(constraintDecl); 875 return constraintDecl; 876 } 877 878 template <typename ConstraintT> 879 ast::Decl * 880 Parser::createODSNativePDLLConstraintDecl(const tblgen::Constraint &constraint, 881 SMRange loc, ast::Type type) { 882 // Format the condition template. 883 tblgen::FmtContext fmtContext; 884 fmtContext.withSelf("self"); 885 std::string codeBlock = 886 tblgen::tgfmt(constraint.getConditionTemplate(), &fmtContext); 887 888 return createODSNativePDLLConstraintDecl<ConstraintT>(constraint.getDefName(), 889 codeBlock, loc, type); 890 } 891 892 //===----------------------------------------------------------------------===// 893 // Decls 894 895 FailureOr<ast::Decl *> Parser::parseTopLevelDecl() { 896 FailureOr<ast::Decl *> decl; 897 switch (curToken.getKind()) { 898 case Token::kw_Constraint: 899 decl = parseUserConstraintDecl(); 900 break; 901 case Token::kw_Pattern: 902 decl = parsePatternDecl(); 903 break; 904 case Token::kw_Rewrite: 905 decl = parseUserRewriteDecl(); 906 break; 907 default: 908 return emitError("expected top-level declaration, such as a `Pattern`"); 909 } 910 if (failed(decl)) 911 return failure(); 912 913 // If the decl has a name, add it to the current scope. 914 if (const ast::Name *name = (*decl)->getName()) { 915 if (failed(checkDefineNamedDecl(*name))) 916 return failure(); 917 curDeclScope->add(*decl); 918 } 919 return decl; 920 } 921 922 FailureOr<ast::NamedAttributeDecl *> 923 Parser::parseNamedAttributeDecl(Optional<StringRef> parentOpName) { 924 // Check for name code completion. 925 if (curToken.is(Token::code_complete)) 926 return codeCompleteAttributeName(parentOpName); 927 928 std::string attrNameStr; 929 if (curToken.isString()) 930 attrNameStr = curToken.getStringValue(); 931 else if (curToken.is(Token::identifier) || curToken.isKeyword()) 932 attrNameStr = curToken.getSpelling().str(); 933 else 934 return emitError("expected identifier or string attribute name"); 935 const auto &name = ast::Name::create(ctx, attrNameStr, curToken.getLoc()); 936 consumeToken(); 937 938 // Check for a value of the attribute. 939 ast::Expr *attrValue = nullptr; 940 if (consumeIf(Token::equal)) { 941 FailureOr<ast::Expr *> attrExpr = parseExpr(); 942 if (failed(attrExpr)) 943 return failure(); 944 attrValue = *attrExpr; 945 } else { 946 // If there isn't a concrete value, create an expression representing a 947 // UnitAttr. 948 attrValue = ast::AttributeExpr::create(ctx, name.getLoc(), "unit"); 949 } 950 951 return ast::NamedAttributeDecl::create(ctx, name, attrValue); 952 } 953 954 FailureOr<ast::CompoundStmt *> Parser::parseLambdaBody( 955 function_ref<LogicalResult(ast::Stmt *&)> processStatementFn, 956 bool expectTerminalSemicolon) { 957 consumeToken(Token::equal_arrow); 958 959 // Parse the single statement of the lambda body. 960 SMLoc bodyStartLoc = curToken.getStartLoc(); 961 pushDeclScope(); 962 FailureOr<ast::Stmt *> singleStatement = parseStmt(expectTerminalSemicolon); 963 bool failedToParse = 964 failed(singleStatement) || failed(processStatementFn(*singleStatement)); 965 popDeclScope(); 966 if (failedToParse) 967 return failure(); 968 969 SMRange bodyLoc(bodyStartLoc, curToken.getStartLoc()); 970 return ast::CompoundStmt::create(ctx, bodyLoc, *singleStatement); 971 } 972 973 FailureOr<ast::VariableDecl *> Parser::parseArgumentDecl() { 974 // Ensure that the argument is named. 975 if (curToken.isNot(Token::identifier) && !curToken.isDependentKeyword()) 976 return emitError("expected identifier argument name"); 977 978 // Parse the argument similarly to a normal variable. 979 StringRef name = curToken.getSpelling(); 980 SMRange nameLoc = curToken.getLoc(); 981 consumeToken(); 982 983 if (failed( 984 parseToken(Token::colon, "expected `:` before argument constraint"))) 985 return failure(); 986 987 FailureOr<ast::ConstraintRef> cst = parseArgOrResultConstraint(); 988 if (failed(cst)) 989 return failure(); 990 991 return createArgOrResultVariableDecl(name, nameLoc, *cst); 992 } 993 994 FailureOr<ast::VariableDecl *> Parser::parseResultDecl(unsigned resultNum) { 995 // Check to see if this result is named. 996 if (curToken.is(Token::identifier) || curToken.isDependentKeyword()) { 997 // Check to see if this name actually refers to a Constraint. 998 ast::Decl *existingDecl = curDeclScope->lookup(curToken.getSpelling()); 999 if (isa_and_nonnull<ast::ConstraintDecl>(existingDecl)) { 1000 // If yes, and this is a Rewrite, give a nice error message as non-Core 1001 // constraints are not supported on Rewrite results. 1002 if (parserContext == ParserContext::Rewrite) { 1003 return emitError( 1004 "`Rewrite` results are only permitted to use core constraints, " 1005 "such as `Attr`, `Op`, `Type`, `TypeRange`, `Value`, `ValueRange`"); 1006 } 1007 1008 // Otherwise, parse this as an unnamed result variable. 1009 } else { 1010 // If it wasn't a constraint, parse the result similarly to a variable. If 1011 // there is already an existing decl, we will emit an error when defining 1012 // this variable later. 1013 StringRef name = curToken.getSpelling(); 1014 SMRange nameLoc = curToken.getLoc(); 1015 consumeToken(); 1016 1017 if (failed(parseToken(Token::colon, 1018 "expected `:` before result constraint"))) 1019 return failure(); 1020 1021 FailureOr<ast::ConstraintRef> cst = parseArgOrResultConstraint(); 1022 if (failed(cst)) 1023 return failure(); 1024 1025 return createArgOrResultVariableDecl(name, nameLoc, *cst); 1026 } 1027 } 1028 1029 // If it isn't named, we parse the constraint directly and create an unnamed 1030 // result variable. 1031 FailureOr<ast::ConstraintRef> cst = parseArgOrResultConstraint(); 1032 if (failed(cst)) 1033 return failure(); 1034 1035 return createArgOrResultVariableDecl("", cst->referenceLoc, *cst); 1036 } 1037 1038 FailureOr<ast::UserConstraintDecl *> 1039 Parser::parseUserConstraintDecl(bool isInline) { 1040 // Constraints and rewrites have very similar formats, dispatch to a shared 1041 // interface for parsing. 1042 return parseUserConstraintOrRewriteDecl<ast::UserConstraintDecl>( 1043 [&](auto &&...args) { 1044 return this->parseUserPDLLConstraintDecl(args...); 1045 }, 1046 ParserContext::Constraint, "constraint", isInline); 1047 } 1048 1049 FailureOr<ast::UserConstraintDecl *> Parser::parseInlineUserConstraintDecl() { 1050 FailureOr<ast::UserConstraintDecl *> decl = 1051 parseUserConstraintDecl(/*isInline=*/true); 1052 if (failed(decl) || failed(checkDefineNamedDecl((*decl)->getName()))) 1053 return failure(); 1054 1055 curDeclScope->add(*decl); 1056 return decl; 1057 } 1058 1059 FailureOr<ast::UserConstraintDecl *> Parser::parseUserPDLLConstraintDecl( 1060 const ast::Name &name, bool isInline, 1061 ArrayRef<ast::VariableDecl *> arguments, ast::DeclScope *argumentScope, 1062 ArrayRef<ast::VariableDecl *> results, ast::Type resultType) { 1063 // Push the argument scope back onto the list, so that the body can 1064 // reference arguments. 1065 pushDeclScope(argumentScope); 1066 1067 // Parse the body of the constraint. The body is either defined as a compound 1068 // block, i.e. `{ ... }`, or a lambda body, i.e. `=> <expr>`. 1069 ast::CompoundStmt *body; 1070 if (curToken.is(Token::equal_arrow)) { 1071 FailureOr<ast::CompoundStmt *> bodyResult = parseLambdaBody( 1072 [&](ast::Stmt *&stmt) -> LogicalResult { 1073 ast::Expr *stmtExpr = dyn_cast<ast::Expr>(stmt); 1074 if (!stmtExpr) { 1075 return emitError(stmt->getLoc(), 1076 "expected `Constraint` lambda body to contain a " 1077 "single expression"); 1078 } 1079 stmt = ast::ReturnStmt::create(ctx, stmt->getLoc(), stmtExpr); 1080 return success(); 1081 }, 1082 /*expectTerminalSemicolon=*/!isInline); 1083 if (failed(bodyResult)) 1084 return failure(); 1085 body = *bodyResult; 1086 } else { 1087 FailureOr<ast::CompoundStmt *> bodyResult = parseCompoundStmt(); 1088 if (failed(bodyResult)) 1089 return failure(); 1090 body = *bodyResult; 1091 1092 // Verify the structure of the body. 1093 auto bodyIt = body->begin(), bodyE = body->end(); 1094 for (; bodyIt != bodyE; ++bodyIt) 1095 if (isa<ast::ReturnStmt>(*bodyIt)) 1096 break; 1097 if (failed(validateUserConstraintOrRewriteReturn( 1098 "Constraint", body, bodyIt, bodyE, results, resultType))) 1099 return failure(); 1100 } 1101 popDeclScope(); 1102 1103 return createUserPDLLConstraintOrRewriteDecl<ast::UserConstraintDecl>( 1104 name, arguments, results, resultType, body); 1105 } 1106 1107 FailureOr<ast::UserRewriteDecl *> Parser::parseUserRewriteDecl(bool isInline) { 1108 // Constraints and rewrites have very similar formats, dispatch to a shared 1109 // interface for parsing. 1110 return parseUserConstraintOrRewriteDecl<ast::UserRewriteDecl>( 1111 [&](auto &&...args) { return this->parseUserPDLLRewriteDecl(args...); }, 1112 ParserContext::Rewrite, "rewrite", isInline); 1113 } 1114 1115 FailureOr<ast::UserRewriteDecl *> Parser::parseInlineUserRewriteDecl() { 1116 FailureOr<ast::UserRewriteDecl *> decl = 1117 parseUserRewriteDecl(/*isInline=*/true); 1118 if (failed(decl) || failed(checkDefineNamedDecl((*decl)->getName()))) 1119 return failure(); 1120 1121 curDeclScope->add(*decl); 1122 return decl; 1123 } 1124 1125 FailureOr<ast::UserRewriteDecl *> Parser::parseUserPDLLRewriteDecl( 1126 const ast::Name &name, bool isInline, 1127 ArrayRef<ast::VariableDecl *> arguments, ast::DeclScope *argumentScope, 1128 ArrayRef<ast::VariableDecl *> results, ast::Type resultType) { 1129 // Push the argument scope back onto the list, so that the body can 1130 // reference arguments. 1131 curDeclScope = argumentScope; 1132 ast::CompoundStmt *body; 1133 if (curToken.is(Token::equal_arrow)) { 1134 FailureOr<ast::CompoundStmt *> bodyResult = parseLambdaBody( 1135 [&](ast::Stmt *&statement) -> LogicalResult { 1136 if (isa<ast::OpRewriteStmt>(statement)) 1137 return success(); 1138 1139 ast::Expr *statementExpr = dyn_cast<ast::Expr>(statement); 1140 if (!statementExpr) { 1141 return emitError( 1142 statement->getLoc(), 1143 "expected `Rewrite` lambda body to contain a single expression " 1144 "or an operation rewrite statement; such as `erase`, " 1145 "`replace`, or `rewrite`"); 1146 } 1147 statement = 1148 ast::ReturnStmt::create(ctx, statement->getLoc(), statementExpr); 1149 return success(); 1150 }, 1151 /*expectTerminalSemicolon=*/!isInline); 1152 if (failed(bodyResult)) 1153 return failure(); 1154 body = *bodyResult; 1155 } else { 1156 FailureOr<ast::CompoundStmt *> bodyResult = parseCompoundStmt(); 1157 if (failed(bodyResult)) 1158 return failure(); 1159 body = *bodyResult; 1160 } 1161 popDeclScope(); 1162 1163 // Verify the structure of the body. 1164 auto bodyIt = body->begin(), bodyE = body->end(); 1165 for (; bodyIt != bodyE; ++bodyIt) 1166 if (isa<ast::ReturnStmt>(*bodyIt)) 1167 break; 1168 if (failed(validateUserConstraintOrRewriteReturn("Rewrite", body, bodyIt, 1169 bodyE, results, resultType))) 1170 return failure(); 1171 return createUserPDLLConstraintOrRewriteDecl<ast::UserRewriteDecl>( 1172 name, arguments, results, resultType, body); 1173 } 1174 1175 template <typename T, typename ParseUserPDLLDeclFnT> 1176 FailureOr<T *> Parser::parseUserConstraintOrRewriteDecl( 1177 ParseUserPDLLDeclFnT &&parseUserPDLLFn, ParserContext declContext, 1178 StringRef anonymousNamePrefix, bool isInline) { 1179 SMRange loc = curToken.getLoc(); 1180 consumeToken(); 1181 llvm::SaveAndRestore<ParserContext> saveCtx(parserContext, declContext); 1182 1183 // Parse the name of the decl. 1184 const ast::Name *name = nullptr; 1185 if (curToken.isNot(Token::identifier)) { 1186 // Only inline decls can be un-named. Inline decls are similar to "lambdas" 1187 // in C++, so being unnamed is fine. 1188 if (!isInline) 1189 return emitError("expected identifier name"); 1190 1191 // Create a unique anonymous name to use, as the name for this decl is not 1192 // important. 1193 std::string anonName = 1194 llvm::formatv("<anonymous_{0}_{1}>", anonymousNamePrefix, 1195 anonymousDeclNameCounter++) 1196 .str(); 1197 name = &ast::Name::create(ctx, anonName, loc); 1198 } else { 1199 // If a name was provided, we can use it directly. 1200 name = &ast::Name::create(ctx, curToken.getSpelling(), curToken.getLoc()); 1201 consumeToken(Token::identifier); 1202 } 1203 1204 // Parse the functional signature of the decl. 1205 SmallVector<ast::VariableDecl *> arguments, results; 1206 ast::DeclScope *argumentScope; 1207 ast::Type resultType; 1208 if (failed(parseUserConstraintOrRewriteSignature(arguments, results, 1209 argumentScope, resultType))) 1210 return failure(); 1211 1212 // Check to see which type of constraint this is. If the constraint contains a 1213 // compound body, this is a PDLL decl. 1214 if (curToken.isAny(Token::l_brace, Token::equal_arrow)) 1215 return parseUserPDLLFn(*name, isInline, arguments, argumentScope, results, 1216 resultType); 1217 1218 // Otherwise, this is a native decl. 1219 return parseUserNativeConstraintOrRewriteDecl<T>(*name, isInline, arguments, 1220 results, resultType); 1221 } 1222 1223 template <typename T> 1224 FailureOr<T *> Parser::parseUserNativeConstraintOrRewriteDecl( 1225 const ast::Name &name, bool isInline, 1226 ArrayRef<ast::VariableDecl *> arguments, 1227 ArrayRef<ast::VariableDecl *> results, ast::Type resultType) { 1228 // If followed by a string, the native code body has also been specified. 1229 std::string codeStrStorage; 1230 Optional<StringRef> optCodeStr; 1231 if (curToken.isString()) { 1232 codeStrStorage = curToken.getStringValue(); 1233 optCodeStr = codeStrStorage; 1234 consumeToken(); 1235 } else if (isInline) { 1236 return emitError(name.getLoc(), 1237 "external declarations must be declared in global scope"); 1238 } 1239 if (failed(parseToken(Token::semicolon, 1240 "expected `;` after native declaration"))) 1241 return failure(); 1242 // TODO: PDL should be able to support constraint results in certain 1243 // situations, we should revise this. 1244 if (std::is_same<ast::UserConstraintDecl, T>::value && !results.empty()) { 1245 return emitError( 1246 "native Constraints currently do not support returning results"); 1247 } 1248 return T::createNative(ctx, name, arguments, results, optCodeStr, resultType); 1249 } 1250 1251 LogicalResult Parser::parseUserConstraintOrRewriteSignature( 1252 SmallVectorImpl<ast::VariableDecl *> &arguments, 1253 SmallVectorImpl<ast::VariableDecl *> &results, 1254 ast::DeclScope *&argumentScope, ast::Type &resultType) { 1255 // Parse the argument list of the decl. 1256 if (failed(parseToken(Token::l_paren, "expected `(` to start argument list"))) 1257 return failure(); 1258 1259 argumentScope = pushDeclScope(); 1260 if (curToken.isNot(Token::r_paren)) { 1261 do { 1262 FailureOr<ast::VariableDecl *> argument = parseArgumentDecl(); 1263 if (failed(argument)) 1264 return failure(); 1265 arguments.emplace_back(*argument); 1266 } while (consumeIf(Token::comma)); 1267 } 1268 popDeclScope(); 1269 if (failed(parseToken(Token::r_paren, "expected `)` to end argument list"))) 1270 return failure(); 1271 1272 // Parse the results of the decl. 1273 pushDeclScope(); 1274 if (consumeIf(Token::arrow)) { 1275 auto parseResultFn = [&]() -> LogicalResult { 1276 FailureOr<ast::VariableDecl *> result = parseResultDecl(results.size()); 1277 if (failed(result)) 1278 return failure(); 1279 results.emplace_back(*result); 1280 return success(); 1281 }; 1282 1283 // Check for a list of results. 1284 if (consumeIf(Token::l_paren)) { 1285 do { 1286 if (failed(parseResultFn())) 1287 return failure(); 1288 } while (consumeIf(Token::comma)); 1289 if (failed(parseToken(Token::r_paren, "expected `)` to end result list"))) 1290 return failure(); 1291 1292 // Otherwise, there is only one result. 1293 } else if (failed(parseResultFn())) { 1294 return failure(); 1295 } 1296 } 1297 popDeclScope(); 1298 1299 // Compute the result type of the decl. 1300 resultType = createUserConstraintRewriteResultType(results); 1301 1302 // Verify that results are only named if there are more than one. 1303 if (results.size() == 1 && !results.front()->getName().getName().empty()) { 1304 return emitError( 1305 results.front()->getLoc(), 1306 "cannot create a single-element tuple with an element label"); 1307 } 1308 return success(); 1309 } 1310 1311 LogicalResult Parser::validateUserConstraintOrRewriteReturn( 1312 StringRef declType, ast::CompoundStmt *body, 1313 ArrayRef<ast::Stmt *>::iterator bodyIt, 1314 ArrayRef<ast::Stmt *>::iterator bodyE, 1315 ArrayRef<ast::VariableDecl *> results, ast::Type &resultType) { 1316 // Handle if a `return` was provided. 1317 if (bodyIt != bodyE) { 1318 // Emit an error if we have trailing statements after the return. 1319 if (std::next(bodyIt) != bodyE) { 1320 return emitError( 1321 (*std::next(bodyIt))->getLoc(), 1322 llvm::formatv("`return` terminated the `{0}` body, but found " 1323 "trailing statements afterwards", 1324 declType)); 1325 } 1326 1327 // Otherwise if a return wasn't provided, check that no results are 1328 // expected. 1329 } else if (!results.empty()) { 1330 return emitError( 1331 {body->getLoc().End, body->getLoc().End}, 1332 llvm::formatv("missing return in a `{0}` expected to return `{1}`", 1333 declType, resultType)); 1334 } 1335 return success(); 1336 } 1337 1338 FailureOr<ast::CompoundStmt *> Parser::parsePatternLambdaBody() { 1339 return parseLambdaBody([&](ast::Stmt *&statement) -> LogicalResult { 1340 if (isa<ast::OpRewriteStmt>(statement)) 1341 return success(); 1342 return emitError( 1343 statement->getLoc(), 1344 "expected Pattern lambda body to contain a single operation " 1345 "rewrite statement, such as `erase`, `replace`, or `rewrite`"); 1346 }); 1347 } 1348 1349 FailureOr<ast::Decl *> Parser::parsePatternDecl() { 1350 SMRange loc = curToken.getLoc(); 1351 consumeToken(Token::kw_Pattern); 1352 llvm::SaveAndRestore<ParserContext> saveCtx(parserContext, 1353 ParserContext::PatternMatch); 1354 1355 // Check for an optional identifier for the pattern name. 1356 const ast::Name *name = nullptr; 1357 if (curToken.is(Token::identifier)) { 1358 name = &ast::Name::create(ctx, curToken.getSpelling(), curToken.getLoc()); 1359 consumeToken(Token::identifier); 1360 } 1361 1362 // Parse any pattern metadata. 1363 ParsedPatternMetadata metadata; 1364 if (consumeIf(Token::kw_with) && failed(parsePatternDeclMetadata(metadata))) 1365 return failure(); 1366 1367 // Parse the pattern body. 1368 ast::CompoundStmt *body; 1369 1370 // Handle a lambda body. 1371 if (curToken.is(Token::equal_arrow)) { 1372 FailureOr<ast::CompoundStmt *> bodyResult = parsePatternLambdaBody(); 1373 if (failed(bodyResult)) 1374 return failure(); 1375 body = *bodyResult; 1376 } else { 1377 if (curToken.isNot(Token::l_brace)) 1378 return emitError("expected `{` or `=>` to start pattern body"); 1379 FailureOr<ast::CompoundStmt *> bodyResult = parseCompoundStmt(); 1380 if (failed(bodyResult)) 1381 return failure(); 1382 body = *bodyResult; 1383 1384 // Verify the body of the pattern. 1385 auto bodyIt = body->begin(), bodyE = body->end(); 1386 for (; bodyIt != bodyE; ++bodyIt) { 1387 if (isa<ast::ReturnStmt>(*bodyIt)) { 1388 return emitError((*bodyIt)->getLoc(), 1389 "`return` statements are only permitted within a " 1390 "`Constraint` or `Rewrite` body"); 1391 } 1392 // Break when we've found the rewrite statement. 1393 if (isa<ast::OpRewriteStmt>(*bodyIt)) 1394 break; 1395 } 1396 if (bodyIt == bodyE) { 1397 return emitError(loc, 1398 "expected Pattern body to terminate with an operation " 1399 "rewrite statement, such as `erase`"); 1400 } 1401 if (std::next(bodyIt) != bodyE) { 1402 return emitError((*std::next(bodyIt))->getLoc(), 1403 "Pattern body was terminated by an operation " 1404 "rewrite statement, but found trailing statements"); 1405 } 1406 } 1407 1408 return createPatternDecl(loc, name, metadata, body); 1409 } 1410 1411 LogicalResult 1412 Parser::parsePatternDeclMetadata(ParsedPatternMetadata &metadata) { 1413 Optional<SMRange> benefitLoc; 1414 Optional<SMRange> hasBoundedRecursionLoc; 1415 1416 do { 1417 // Handle metadata code completion. 1418 if (curToken.is(Token::code_complete)) 1419 return codeCompletePatternMetadata(); 1420 1421 if (curToken.isNot(Token::identifier)) 1422 return emitError("expected pattern metadata identifier"); 1423 StringRef metadataStr = curToken.getSpelling(); 1424 SMRange metadataLoc = curToken.getLoc(); 1425 consumeToken(Token::identifier); 1426 1427 // Parse the benefit metadata: benefit(<integer-value>) 1428 if (metadataStr == "benefit") { 1429 if (benefitLoc) { 1430 return emitErrorAndNote(metadataLoc, 1431 "pattern benefit has already been specified", 1432 *benefitLoc, "see previous definition here"); 1433 } 1434 if (failed(parseToken(Token::l_paren, 1435 "expected `(` before pattern benefit"))) 1436 return failure(); 1437 1438 uint16_t benefitValue = 0; 1439 if (curToken.isNot(Token::integer)) 1440 return emitError("expected integral pattern benefit"); 1441 if (curToken.getSpelling().getAsInteger(/*Radix=*/10, benefitValue)) 1442 return emitError( 1443 "expected pattern benefit to fit within a 16-bit integer"); 1444 consumeToken(Token::integer); 1445 1446 metadata.benefit = benefitValue; 1447 benefitLoc = metadataLoc; 1448 1449 if (failed( 1450 parseToken(Token::r_paren, "expected `)` after pattern benefit"))) 1451 return failure(); 1452 continue; 1453 } 1454 1455 // Parse the bounded recursion metadata: recursion 1456 if (metadataStr == "recursion") { 1457 if (hasBoundedRecursionLoc) { 1458 return emitErrorAndNote( 1459 metadataLoc, 1460 "pattern recursion metadata has already been specified", 1461 *hasBoundedRecursionLoc, "see previous definition here"); 1462 } 1463 metadata.hasBoundedRecursion = true; 1464 hasBoundedRecursionLoc = metadataLoc; 1465 continue; 1466 } 1467 1468 return emitError(metadataLoc, "unknown pattern metadata"); 1469 } while (consumeIf(Token::comma)); 1470 1471 return success(); 1472 } 1473 1474 FailureOr<ast::Expr *> Parser::parseTypeConstraintExpr() { 1475 consumeToken(Token::less); 1476 1477 FailureOr<ast::Expr *> typeExpr = parseExpr(); 1478 if (failed(typeExpr) || 1479 failed(parseToken(Token::greater, 1480 "expected `>` after variable type constraint"))) 1481 return failure(); 1482 return typeExpr; 1483 } 1484 1485 LogicalResult Parser::checkDefineNamedDecl(const ast::Name &name) { 1486 assert(curDeclScope && "defining decl outside of a decl scope"); 1487 if (ast::Decl *lastDecl = curDeclScope->lookup(name.getName())) { 1488 return emitErrorAndNote( 1489 name.getLoc(), "`" + name.getName() + "` has already been defined", 1490 lastDecl->getName()->getLoc(), "see previous definition here"); 1491 } 1492 return success(); 1493 } 1494 1495 FailureOr<ast::VariableDecl *> 1496 Parser::defineVariableDecl(StringRef name, SMRange nameLoc, ast::Type type, 1497 ast::Expr *initExpr, 1498 ArrayRef<ast::ConstraintRef> constraints) { 1499 assert(curDeclScope && "defining variable outside of decl scope"); 1500 const ast::Name &nameDecl = ast::Name::create(ctx, name, nameLoc); 1501 1502 // If the name of the variable indicates a special variable, we don't add it 1503 // to the scope. This variable is local to the definition point. 1504 if (name.empty() || name == "_") { 1505 return ast::VariableDecl::create(ctx, nameDecl, type, initExpr, 1506 constraints); 1507 } 1508 if (failed(checkDefineNamedDecl(nameDecl))) 1509 return failure(); 1510 1511 auto *varDecl = 1512 ast::VariableDecl::create(ctx, nameDecl, type, initExpr, constraints); 1513 curDeclScope->add(varDecl); 1514 return varDecl; 1515 } 1516 1517 FailureOr<ast::VariableDecl *> 1518 Parser::defineVariableDecl(StringRef name, SMRange nameLoc, ast::Type type, 1519 ArrayRef<ast::ConstraintRef> constraints) { 1520 return defineVariableDecl(name, nameLoc, type, /*initExpr=*/nullptr, 1521 constraints); 1522 } 1523 1524 LogicalResult Parser::parseVariableDeclConstraintList( 1525 SmallVectorImpl<ast::ConstraintRef> &constraints) { 1526 Optional<SMRange> typeConstraint; 1527 auto parseSingleConstraint = [&] { 1528 FailureOr<ast::ConstraintRef> constraint = parseConstraint( 1529 typeConstraint, constraints, /*allowInlineTypeConstraints=*/true, 1530 /*allowNonCoreConstraints=*/true); 1531 if (failed(constraint)) 1532 return failure(); 1533 constraints.push_back(*constraint); 1534 return success(); 1535 }; 1536 1537 // Check to see if this is a single constraint, or a list. 1538 if (!consumeIf(Token::l_square)) 1539 return parseSingleConstraint(); 1540 1541 do { 1542 if (failed(parseSingleConstraint())) 1543 return failure(); 1544 } while (consumeIf(Token::comma)); 1545 return parseToken(Token::r_square, "expected `]` after constraint list"); 1546 } 1547 1548 FailureOr<ast::ConstraintRef> 1549 Parser::parseConstraint(Optional<SMRange> &typeConstraint, 1550 ArrayRef<ast::ConstraintRef> existingConstraints, 1551 bool allowInlineTypeConstraints, 1552 bool allowNonCoreConstraints) { 1553 auto parseTypeConstraint = [&](ast::Expr *&typeExpr) -> LogicalResult { 1554 if (!allowInlineTypeConstraints) { 1555 return emitError( 1556 curToken.getLoc(), 1557 "inline `Attr`, `Value`, and `ValueRange` type constraints are not " 1558 "permitted on arguments or results"); 1559 } 1560 if (typeConstraint) 1561 return emitErrorAndNote( 1562 curToken.getLoc(), 1563 "the type of this variable has already been constrained", 1564 *typeConstraint, "see previous constraint location here"); 1565 FailureOr<ast::Expr *> constraintExpr = parseTypeConstraintExpr(); 1566 if (failed(constraintExpr)) 1567 return failure(); 1568 typeExpr = *constraintExpr; 1569 typeConstraint = typeExpr->getLoc(); 1570 return success(); 1571 }; 1572 1573 SMRange loc = curToken.getLoc(); 1574 switch (curToken.getKind()) { 1575 case Token::kw_Attr: { 1576 consumeToken(Token::kw_Attr); 1577 1578 // Check for a type constraint. 1579 ast::Expr *typeExpr = nullptr; 1580 if (curToken.is(Token::less) && failed(parseTypeConstraint(typeExpr))) 1581 return failure(); 1582 return ast::ConstraintRef( 1583 ast::AttrConstraintDecl::create(ctx, loc, typeExpr), loc); 1584 } 1585 case Token::kw_Op: { 1586 consumeToken(Token::kw_Op); 1587 1588 // Parse an optional operation name. If the name isn't provided, this refers 1589 // to "any" operation. 1590 FailureOr<ast::OpNameDecl *> opName = 1591 parseWrappedOperationName(/*allowEmptyName=*/true); 1592 if (failed(opName)) 1593 return failure(); 1594 1595 return ast::ConstraintRef(ast::OpConstraintDecl::create(ctx, loc, *opName), 1596 loc); 1597 } 1598 case Token::kw_Type: 1599 consumeToken(Token::kw_Type); 1600 return ast::ConstraintRef(ast::TypeConstraintDecl::create(ctx, loc), loc); 1601 case Token::kw_TypeRange: 1602 consumeToken(Token::kw_TypeRange); 1603 return ast::ConstraintRef(ast::TypeRangeConstraintDecl::create(ctx, loc), 1604 loc); 1605 case Token::kw_Value: { 1606 consumeToken(Token::kw_Value); 1607 1608 // Check for a type constraint. 1609 ast::Expr *typeExpr = nullptr; 1610 if (curToken.is(Token::less) && failed(parseTypeConstraint(typeExpr))) 1611 return failure(); 1612 1613 return ast::ConstraintRef( 1614 ast::ValueConstraintDecl::create(ctx, loc, typeExpr), loc); 1615 } 1616 case Token::kw_ValueRange: { 1617 consumeToken(Token::kw_ValueRange); 1618 1619 // Check for a type constraint. 1620 ast::Expr *typeExpr = nullptr; 1621 if (curToken.is(Token::less) && failed(parseTypeConstraint(typeExpr))) 1622 return failure(); 1623 1624 return ast::ConstraintRef( 1625 ast::ValueRangeConstraintDecl::create(ctx, loc, typeExpr), loc); 1626 } 1627 1628 case Token::kw_Constraint: { 1629 // Handle an inline constraint. 1630 FailureOr<ast::UserConstraintDecl *> decl = parseInlineUserConstraintDecl(); 1631 if (failed(decl)) 1632 return failure(); 1633 return ast::ConstraintRef(*decl, loc); 1634 } 1635 case Token::identifier: { 1636 StringRef constraintName = curToken.getSpelling(); 1637 consumeToken(Token::identifier); 1638 1639 // Lookup the referenced constraint. 1640 ast::Decl *cstDecl = curDeclScope->lookup<ast::Decl>(constraintName); 1641 if (!cstDecl) { 1642 return emitError(loc, "unknown reference to constraint `" + 1643 constraintName + "`"); 1644 } 1645 1646 // Handle a reference to a proper constraint. 1647 if (auto *cst = dyn_cast<ast::ConstraintDecl>(cstDecl)) 1648 return ast::ConstraintRef(cst, loc); 1649 1650 return emitErrorAndNote( 1651 loc, "invalid reference to non-constraint", cstDecl->getLoc(), 1652 "see the definition of `" + constraintName + "` here"); 1653 } 1654 // Handle single entity constraint code completion. 1655 case Token::code_complete: { 1656 // Try to infer the current type for use by code completion. 1657 ast::Type inferredType; 1658 if (failed(validateVariableConstraints(existingConstraints, inferredType, 1659 allowNonCoreConstraints))) 1660 return failure(); 1661 1662 return codeCompleteConstraintName(inferredType, allowNonCoreConstraints, 1663 allowInlineTypeConstraints); 1664 } 1665 default: 1666 break; 1667 } 1668 return emitError(loc, "expected identifier constraint"); 1669 } 1670 1671 FailureOr<ast::ConstraintRef> Parser::parseArgOrResultConstraint() { 1672 // Constraint arguments may apply more complex constraints via the arguments. 1673 bool allowNonCoreConstraints = parserContext == ParserContext::Constraint; 1674 1675 Optional<SMRange> typeConstraint; 1676 return parseConstraint(typeConstraint, /*existingConstraints=*/llvm::None, 1677 /*allowInlineTypeConstraints=*/false, 1678 allowNonCoreConstraints); 1679 } 1680 1681 //===----------------------------------------------------------------------===// 1682 // Exprs 1683 1684 FailureOr<ast::Expr *> Parser::parseExpr() { 1685 if (curToken.is(Token::underscore)) 1686 return parseUnderscoreExpr(); 1687 1688 // Parse the LHS expression. 1689 FailureOr<ast::Expr *> lhsExpr; 1690 switch (curToken.getKind()) { 1691 case Token::kw_attr: 1692 lhsExpr = parseAttributeExpr(); 1693 break; 1694 case Token::kw_Constraint: 1695 lhsExpr = parseInlineConstraintLambdaExpr(); 1696 break; 1697 case Token::identifier: 1698 lhsExpr = parseIdentifierExpr(); 1699 break; 1700 case Token::kw_op: 1701 lhsExpr = parseOperationExpr(); 1702 break; 1703 case Token::kw_Rewrite: 1704 lhsExpr = parseInlineRewriteLambdaExpr(); 1705 break; 1706 case Token::kw_type: 1707 lhsExpr = parseTypeExpr(); 1708 break; 1709 case Token::l_paren: 1710 lhsExpr = parseTupleExpr(); 1711 break; 1712 default: 1713 return emitError("expected expression"); 1714 } 1715 if (failed(lhsExpr)) 1716 return failure(); 1717 1718 // Check for an operator expression. 1719 while (true) { 1720 switch (curToken.getKind()) { 1721 case Token::dot: 1722 lhsExpr = parseMemberAccessExpr(*lhsExpr); 1723 break; 1724 case Token::l_paren: 1725 lhsExpr = parseCallExpr(*lhsExpr); 1726 break; 1727 default: 1728 return lhsExpr; 1729 } 1730 if (failed(lhsExpr)) 1731 return failure(); 1732 } 1733 } 1734 1735 FailureOr<ast::Expr *> Parser::parseAttributeExpr() { 1736 SMRange loc = curToken.getLoc(); 1737 consumeToken(Token::kw_attr); 1738 1739 // If we aren't followed by a `<`, the `attr` keyword is treated as a normal 1740 // identifier. 1741 if (!consumeIf(Token::less)) { 1742 resetToken(loc); 1743 return parseIdentifierExpr(); 1744 } 1745 1746 if (!curToken.isString()) 1747 return emitError("expected string literal containing MLIR attribute"); 1748 std::string attrExpr = curToken.getStringValue(); 1749 consumeToken(); 1750 1751 if (failed( 1752 parseToken(Token::greater, "expected `>` after attribute literal"))) 1753 return failure(); 1754 return ast::AttributeExpr::create(ctx, loc, attrExpr); 1755 } 1756 1757 FailureOr<ast::Expr *> Parser::parseCallExpr(ast::Expr *parentExpr) { 1758 SMRange loc = curToken.getLoc(); 1759 consumeToken(Token::l_paren); 1760 1761 // Parse the arguments of the call. 1762 SmallVector<ast::Expr *> arguments; 1763 if (curToken.isNot(Token::r_paren)) { 1764 do { 1765 FailureOr<ast::Expr *> argument = parseExpr(); 1766 if (failed(argument)) 1767 return failure(); 1768 arguments.push_back(*argument); 1769 } while (consumeIf(Token::comma)); 1770 } 1771 loc.End = curToken.getEndLoc(); 1772 if (failed(parseToken(Token::r_paren, "expected `)` after argument list"))) 1773 return failure(); 1774 1775 return createCallExpr(loc, parentExpr, arguments); 1776 } 1777 1778 FailureOr<ast::Expr *> Parser::parseDeclRefExpr(StringRef name, SMRange loc) { 1779 ast::Decl *decl = curDeclScope->lookup(name); 1780 if (!decl) 1781 return emitError(loc, "undefined reference to `" + name + "`"); 1782 1783 return createDeclRefExpr(loc, decl); 1784 } 1785 1786 FailureOr<ast::Expr *> Parser::parseIdentifierExpr() { 1787 StringRef name = curToken.getSpelling(); 1788 SMRange nameLoc = curToken.getLoc(); 1789 consumeToken(); 1790 1791 // Check to see if this is a decl ref expression that defines a variable 1792 // inline. 1793 if (consumeIf(Token::colon)) { 1794 SmallVector<ast::ConstraintRef> constraints; 1795 if (failed(parseVariableDeclConstraintList(constraints))) 1796 return failure(); 1797 ast::Type type; 1798 if (failed(validateVariableConstraints(constraints, type))) 1799 return failure(); 1800 return createInlineVariableExpr(type, name, nameLoc, constraints); 1801 } 1802 1803 return parseDeclRefExpr(name, nameLoc); 1804 } 1805 1806 FailureOr<ast::Expr *> Parser::parseInlineConstraintLambdaExpr() { 1807 FailureOr<ast::UserConstraintDecl *> decl = parseInlineUserConstraintDecl(); 1808 if (failed(decl)) 1809 return failure(); 1810 1811 return ast::DeclRefExpr::create(ctx, (*decl)->getLoc(), *decl, 1812 ast::ConstraintType::get(ctx)); 1813 } 1814 1815 FailureOr<ast::Expr *> Parser::parseInlineRewriteLambdaExpr() { 1816 FailureOr<ast::UserRewriteDecl *> decl = parseInlineUserRewriteDecl(); 1817 if (failed(decl)) 1818 return failure(); 1819 1820 return ast::DeclRefExpr::create(ctx, (*decl)->getLoc(), *decl, 1821 ast::RewriteType::get(ctx)); 1822 } 1823 1824 FailureOr<ast::Expr *> Parser::parseMemberAccessExpr(ast::Expr *parentExpr) { 1825 SMRange loc = curToken.getLoc(); 1826 consumeToken(Token::dot); 1827 1828 // Check for code completion of the member name. 1829 if (curToken.is(Token::code_complete)) 1830 return codeCompleteMemberAccess(parentExpr); 1831 1832 // Parse the member name. 1833 Token memberNameTok = curToken; 1834 if (memberNameTok.isNot(Token::identifier, Token::integer) && 1835 !memberNameTok.isKeyword()) 1836 return emitError(loc, "expected identifier or numeric member name"); 1837 StringRef memberName = memberNameTok.getSpelling(); 1838 consumeToken(); 1839 1840 return createMemberAccessExpr(parentExpr, memberName, loc); 1841 } 1842 1843 FailureOr<ast::OpNameDecl *> Parser::parseOperationName(bool allowEmptyName) { 1844 SMRange loc = curToken.getLoc(); 1845 1846 // Check for code completion for the dialect name. 1847 if (curToken.is(Token::code_complete)) 1848 return codeCompleteDialectName(); 1849 1850 // Handle the case of an no operation name. 1851 if (curToken.isNot(Token::identifier) && !curToken.isKeyword()) { 1852 if (allowEmptyName) 1853 return ast::OpNameDecl::create(ctx, SMRange()); 1854 return emitError("expected dialect namespace"); 1855 } 1856 StringRef name = curToken.getSpelling(); 1857 consumeToken(); 1858 1859 // Otherwise, this is a literal operation name. 1860 if (failed(parseToken(Token::dot, "expected `.` after dialect namespace"))) 1861 return failure(); 1862 1863 // Check for code completion for the operation name. 1864 if (curToken.is(Token::code_complete)) 1865 return codeCompleteOperationName(name); 1866 1867 if (curToken.isNot(Token::identifier) && !curToken.isKeyword()) 1868 return emitError("expected operation name after dialect namespace"); 1869 1870 name = StringRef(name.data(), name.size() + 1); 1871 do { 1872 name = StringRef(name.data(), name.size() + curToken.getSpelling().size()); 1873 loc.End = curToken.getEndLoc(); 1874 consumeToken(); 1875 } while (curToken.isAny(Token::identifier, Token::dot) || 1876 curToken.isKeyword()); 1877 return ast::OpNameDecl::create(ctx, ast::Name::create(ctx, name, loc)); 1878 } 1879 1880 FailureOr<ast::OpNameDecl *> 1881 Parser::parseWrappedOperationName(bool allowEmptyName) { 1882 if (!consumeIf(Token::less)) 1883 return ast::OpNameDecl::create(ctx, SMRange()); 1884 1885 FailureOr<ast::OpNameDecl *> opNameDecl = parseOperationName(allowEmptyName); 1886 if (failed(opNameDecl)) 1887 return failure(); 1888 1889 if (failed(parseToken(Token::greater, "expected `>` after operation name"))) 1890 return failure(); 1891 return opNameDecl; 1892 } 1893 1894 FailureOr<ast::Expr *> Parser::parseOperationExpr() { 1895 SMRange loc = curToken.getLoc(); 1896 consumeToken(Token::kw_op); 1897 1898 // If it isn't followed by a `<`, the `op` keyword is treated as a normal 1899 // identifier. 1900 if (curToken.isNot(Token::less)) { 1901 resetToken(loc); 1902 return parseIdentifierExpr(); 1903 } 1904 1905 // Parse the operation name. The name may be elided, in which case the 1906 // operation refers to "any" operation(i.e. a difference between `MyOp` and 1907 // `Operation*`). Operation names within a rewrite context must be named. 1908 bool allowEmptyName = parserContext != ParserContext::Rewrite; 1909 FailureOr<ast::OpNameDecl *> opNameDecl = 1910 parseWrappedOperationName(allowEmptyName); 1911 if (failed(opNameDecl)) 1912 return failure(); 1913 Optional<StringRef> opName = (*opNameDecl)->getName(); 1914 1915 // Functor used to create an implicit range variable, used for implicit "all" 1916 // operand or results variables. 1917 auto createImplicitRangeVar = [&](ast::ConstraintDecl *cst, ast::Type type) { 1918 FailureOr<ast::VariableDecl *> rangeVar = 1919 defineVariableDecl("_", loc, type, ast::ConstraintRef(cst, loc)); 1920 assert(succeeded(rangeVar) && "expected range variable to be valid"); 1921 return ast::DeclRefExpr::create(ctx, loc, *rangeVar, type); 1922 }; 1923 1924 // Check for the optional list of operands. 1925 SmallVector<ast::Expr *> operands; 1926 if (!consumeIf(Token::l_paren)) { 1927 // If the operand list isn't specified and we are in a match context, define 1928 // an inplace unconstrained operand range corresponding to all of the 1929 // operands of the operation. This avoids treating zero operands the same 1930 // way as "unconstrained operands". 1931 if (parserContext != ParserContext::Rewrite) { 1932 operands.push_back(createImplicitRangeVar( 1933 ast::ValueRangeConstraintDecl::create(ctx, loc), valueRangeTy)); 1934 } 1935 } else if (!consumeIf(Token::r_paren)) { 1936 // If the operand list was specified and non-empty, parse the operands. 1937 do { 1938 FailureOr<ast::Expr *> operand = parseExpr(); 1939 if (failed(operand)) 1940 return failure(); 1941 operands.push_back(*operand); 1942 } while (consumeIf(Token::comma)); 1943 1944 if (failed(parseToken(Token::r_paren, 1945 "expected `)` after operation operand list"))) 1946 return failure(); 1947 } 1948 1949 // Check for the optional list of attributes. 1950 SmallVector<ast::NamedAttributeDecl *> attributes; 1951 if (consumeIf(Token::l_brace)) { 1952 do { 1953 FailureOr<ast::NamedAttributeDecl *> decl = 1954 parseNamedAttributeDecl(opName); 1955 if (failed(decl)) 1956 return failure(); 1957 attributes.emplace_back(*decl); 1958 } while (consumeIf(Token::comma)); 1959 1960 if (failed(parseToken(Token::r_brace, 1961 "expected `}` after operation attribute list"))) 1962 return failure(); 1963 } 1964 1965 // Check for the optional list of result types. 1966 SmallVector<ast::Expr *> resultTypes; 1967 if (consumeIf(Token::arrow)) { 1968 if (failed(parseToken(Token::l_paren, 1969 "expected `(` before operation result type list"))) 1970 return failure(); 1971 1972 // Handle the case of an empty result list. 1973 if (!consumeIf(Token::r_paren)) { 1974 do { 1975 FailureOr<ast::Expr *> resultTypeExpr = parseExpr(); 1976 if (failed(resultTypeExpr)) 1977 return failure(); 1978 resultTypes.push_back(*resultTypeExpr); 1979 } while (consumeIf(Token::comma)); 1980 1981 if (failed(parseToken(Token::r_paren, 1982 "expected `)` after operation result type list"))) 1983 return failure(); 1984 } 1985 } else if (parserContext != ParserContext::Rewrite) { 1986 // If the result list isn't specified and we are in a match context, define 1987 // an inplace unconstrained result range corresponding to all of the results 1988 // of the operation. This avoids treating zero results the same way as 1989 // "unconstrained results". 1990 resultTypes.push_back(createImplicitRangeVar( 1991 ast::TypeRangeConstraintDecl::create(ctx, loc), typeRangeTy)); 1992 } 1993 1994 return createOperationExpr(loc, *opNameDecl, operands, attributes, 1995 resultTypes); 1996 } 1997 1998 FailureOr<ast::Expr *> Parser::parseTupleExpr() { 1999 SMRange loc = curToken.getLoc(); 2000 consumeToken(Token::l_paren); 2001 2002 DenseMap<StringRef, SMRange> usedNames; 2003 SmallVector<StringRef> elementNames; 2004 SmallVector<ast::Expr *> elements; 2005 if (curToken.isNot(Token::r_paren)) { 2006 do { 2007 // Check for the optional element name assignment before the value. 2008 StringRef elementName; 2009 if (curToken.is(Token::identifier) || curToken.isDependentKeyword()) { 2010 Token elementNameTok = curToken; 2011 consumeToken(); 2012 2013 // The element name is only present if followed by an `=`. 2014 if (consumeIf(Token::equal)) { 2015 elementName = elementNameTok.getSpelling(); 2016 2017 // Check to see if this name is already used. 2018 auto elementNameIt = 2019 usedNames.try_emplace(elementName, elementNameTok.getLoc()); 2020 if (!elementNameIt.second) { 2021 return emitErrorAndNote( 2022 elementNameTok.getLoc(), 2023 llvm::formatv("duplicate tuple element label `{0}`", 2024 elementName), 2025 elementNameIt.first->getSecond(), 2026 "see previous label use here"); 2027 } 2028 } else { 2029 // Otherwise, we treat this as part of an expression so reset the 2030 // lexer. 2031 resetToken(elementNameTok.getLoc()); 2032 } 2033 } 2034 elementNames.push_back(elementName); 2035 2036 // Parse the tuple element value. 2037 FailureOr<ast::Expr *> element = parseExpr(); 2038 if (failed(element)) 2039 return failure(); 2040 elements.push_back(*element); 2041 } while (consumeIf(Token::comma)); 2042 } 2043 loc.End = curToken.getEndLoc(); 2044 if (failed( 2045 parseToken(Token::r_paren, "expected `)` after tuple element list"))) 2046 return failure(); 2047 return createTupleExpr(loc, elements, elementNames); 2048 } 2049 2050 FailureOr<ast::Expr *> Parser::parseTypeExpr() { 2051 SMRange loc = curToken.getLoc(); 2052 consumeToken(Token::kw_type); 2053 2054 // If we aren't followed by a `<`, the `type` keyword is treated as a normal 2055 // identifier. 2056 if (!consumeIf(Token::less)) { 2057 resetToken(loc); 2058 return parseIdentifierExpr(); 2059 } 2060 2061 if (!curToken.isString()) 2062 return emitError("expected string literal containing MLIR type"); 2063 std::string attrExpr = curToken.getStringValue(); 2064 consumeToken(); 2065 2066 if (failed(parseToken(Token::greater, "expected `>` after type literal"))) 2067 return failure(); 2068 return ast::TypeExpr::create(ctx, loc, attrExpr); 2069 } 2070 2071 FailureOr<ast::Expr *> Parser::parseUnderscoreExpr() { 2072 StringRef name = curToken.getSpelling(); 2073 SMRange nameLoc = curToken.getLoc(); 2074 consumeToken(Token::underscore); 2075 2076 // Underscore expressions require a constraint list. 2077 if (failed(parseToken(Token::colon, "expected `:` after `_` variable"))) 2078 return failure(); 2079 2080 // Parse the constraints for the expression. 2081 SmallVector<ast::ConstraintRef> constraints; 2082 if (failed(parseVariableDeclConstraintList(constraints))) 2083 return failure(); 2084 2085 ast::Type type; 2086 if (failed(validateVariableConstraints(constraints, type))) 2087 return failure(); 2088 return createInlineVariableExpr(type, name, nameLoc, constraints); 2089 } 2090 2091 //===----------------------------------------------------------------------===// 2092 // Stmts 2093 2094 FailureOr<ast::Stmt *> Parser::parseStmt(bool expectTerminalSemicolon) { 2095 FailureOr<ast::Stmt *> stmt; 2096 switch (curToken.getKind()) { 2097 case Token::kw_erase: 2098 stmt = parseEraseStmt(); 2099 break; 2100 case Token::kw_let: 2101 stmt = parseLetStmt(); 2102 break; 2103 case Token::kw_replace: 2104 stmt = parseReplaceStmt(); 2105 break; 2106 case Token::kw_return: 2107 stmt = parseReturnStmt(); 2108 break; 2109 case Token::kw_rewrite: 2110 stmt = parseRewriteStmt(); 2111 break; 2112 default: 2113 stmt = parseExpr(); 2114 break; 2115 } 2116 if (failed(stmt) || 2117 (expectTerminalSemicolon && 2118 failed(parseToken(Token::semicolon, "expected `;` after statement")))) 2119 return failure(); 2120 return stmt; 2121 } 2122 2123 FailureOr<ast::CompoundStmt *> Parser::parseCompoundStmt() { 2124 SMLoc startLoc = curToken.getStartLoc(); 2125 consumeToken(Token::l_brace); 2126 2127 // Push a new block scope and parse any nested statements. 2128 pushDeclScope(); 2129 SmallVector<ast::Stmt *> statements; 2130 while (curToken.isNot(Token::r_brace)) { 2131 FailureOr<ast::Stmt *> statement = parseStmt(); 2132 if (failed(statement)) 2133 return popDeclScope(), failure(); 2134 statements.push_back(*statement); 2135 } 2136 popDeclScope(); 2137 2138 // Consume the end brace. 2139 SMRange location(startLoc, curToken.getEndLoc()); 2140 consumeToken(Token::r_brace); 2141 2142 return ast::CompoundStmt::create(ctx, location, statements); 2143 } 2144 2145 FailureOr<ast::EraseStmt *> Parser::parseEraseStmt() { 2146 if (parserContext == ParserContext::Constraint) 2147 return emitError("`erase` cannot be used within a Constraint"); 2148 SMRange loc = curToken.getLoc(); 2149 consumeToken(Token::kw_erase); 2150 2151 // Parse the root operation expression. 2152 FailureOr<ast::Expr *> rootOp = parseExpr(); 2153 if (failed(rootOp)) 2154 return failure(); 2155 2156 return createEraseStmt(loc, *rootOp); 2157 } 2158 2159 FailureOr<ast::LetStmt *> Parser::parseLetStmt() { 2160 SMRange loc = curToken.getLoc(); 2161 consumeToken(Token::kw_let); 2162 2163 // Parse the name of the new variable. 2164 SMRange varLoc = curToken.getLoc(); 2165 if (curToken.isNot(Token::identifier) && !curToken.isDependentKeyword()) { 2166 // `_` is a reserved variable name. 2167 if (curToken.is(Token::underscore)) { 2168 return emitError(varLoc, 2169 "`_` may only be used to define \"inline\" variables"); 2170 } 2171 return emitError(varLoc, 2172 "expected identifier after `let` to name a new variable"); 2173 } 2174 StringRef varName = curToken.getSpelling(); 2175 consumeToken(); 2176 2177 // Parse the optional set of constraints. 2178 SmallVector<ast::ConstraintRef> constraints; 2179 if (consumeIf(Token::colon) && 2180 failed(parseVariableDeclConstraintList(constraints))) 2181 return failure(); 2182 2183 // Parse the optional initializer expression. 2184 ast::Expr *initializer = nullptr; 2185 if (consumeIf(Token::equal)) { 2186 FailureOr<ast::Expr *> initOrFailure = parseExpr(); 2187 if (failed(initOrFailure)) 2188 return failure(); 2189 initializer = *initOrFailure; 2190 2191 // Check that the constraints are compatible with having an initializer, 2192 // e.g. type constraints cannot be used with initializers. 2193 for (ast::ConstraintRef constraint : constraints) { 2194 LogicalResult result = 2195 TypeSwitch<const ast::Node *, LogicalResult>(constraint.constraint) 2196 .Case<ast::AttrConstraintDecl, ast::ValueConstraintDecl, 2197 ast::ValueRangeConstraintDecl>([&](const auto *cst) { 2198 if (auto *typeConstraintExpr = cst->getTypeExpr()) { 2199 return this->emitError( 2200 constraint.referenceLoc, 2201 "type constraints are not permitted on variables with " 2202 "initializers"); 2203 } 2204 return success(); 2205 }) 2206 .Default(success()); 2207 if (failed(result)) 2208 return failure(); 2209 } 2210 } 2211 2212 FailureOr<ast::VariableDecl *> varDecl = 2213 createVariableDecl(varName, varLoc, initializer, constraints); 2214 if (failed(varDecl)) 2215 return failure(); 2216 return ast::LetStmt::create(ctx, loc, *varDecl); 2217 } 2218 2219 FailureOr<ast::ReplaceStmt *> Parser::parseReplaceStmt() { 2220 if (parserContext == ParserContext::Constraint) 2221 return emitError("`replace` cannot be used within a Constraint"); 2222 SMRange loc = curToken.getLoc(); 2223 consumeToken(Token::kw_replace); 2224 2225 // Parse the root operation expression. 2226 FailureOr<ast::Expr *> rootOp = parseExpr(); 2227 if (failed(rootOp)) 2228 return failure(); 2229 2230 if (failed( 2231 parseToken(Token::kw_with, "expected `with` after root operation"))) 2232 return failure(); 2233 2234 // The replacement portion of this statement is within a rewrite context. 2235 llvm::SaveAndRestore<ParserContext> saveCtx(parserContext, 2236 ParserContext::Rewrite); 2237 2238 // Parse the replacement values. 2239 SmallVector<ast::Expr *> replValues; 2240 if (consumeIf(Token::l_paren)) { 2241 if (consumeIf(Token::r_paren)) { 2242 return emitError( 2243 loc, "expected at least one replacement value, consider using " 2244 "`erase` if no replacement values are desired"); 2245 } 2246 2247 do { 2248 FailureOr<ast::Expr *> replExpr = parseExpr(); 2249 if (failed(replExpr)) 2250 return failure(); 2251 replValues.emplace_back(*replExpr); 2252 } while (consumeIf(Token::comma)); 2253 2254 if (failed(parseToken(Token::r_paren, 2255 "expected `)` after replacement values"))) 2256 return failure(); 2257 } else { 2258 FailureOr<ast::Expr *> replExpr = parseExpr(); 2259 if (failed(replExpr)) 2260 return failure(); 2261 replValues.emplace_back(*replExpr); 2262 } 2263 2264 return createReplaceStmt(loc, *rootOp, replValues); 2265 } 2266 2267 FailureOr<ast::ReturnStmt *> Parser::parseReturnStmt() { 2268 SMRange loc = curToken.getLoc(); 2269 consumeToken(Token::kw_return); 2270 2271 // Parse the result value. 2272 FailureOr<ast::Expr *> resultExpr = parseExpr(); 2273 if (failed(resultExpr)) 2274 return failure(); 2275 2276 return ast::ReturnStmt::create(ctx, loc, *resultExpr); 2277 } 2278 2279 FailureOr<ast::RewriteStmt *> Parser::parseRewriteStmt() { 2280 if (parserContext == ParserContext::Constraint) 2281 return emitError("`rewrite` cannot be used within a Constraint"); 2282 SMRange loc = curToken.getLoc(); 2283 consumeToken(Token::kw_rewrite); 2284 2285 // Parse the root operation. 2286 FailureOr<ast::Expr *> rootOp = parseExpr(); 2287 if (failed(rootOp)) 2288 return failure(); 2289 2290 if (failed(parseToken(Token::kw_with, "expected `with` before rewrite body"))) 2291 return failure(); 2292 2293 if (curToken.isNot(Token::l_brace)) 2294 return emitError("expected `{` to start rewrite body"); 2295 2296 // The rewrite body of this statement is within a rewrite context. 2297 llvm::SaveAndRestore<ParserContext> saveCtx(parserContext, 2298 ParserContext::Rewrite); 2299 2300 FailureOr<ast::CompoundStmt *> rewriteBody = parseCompoundStmt(); 2301 if (failed(rewriteBody)) 2302 return failure(); 2303 2304 // Verify the rewrite body. 2305 for (const ast::Stmt *stmt : (*rewriteBody)->getChildren()) { 2306 if (isa<ast::ReturnStmt>(stmt)) { 2307 return emitError(stmt->getLoc(), 2308 "`return` statements are only permitted within a " 2309 "`Constraint` or `Rewrite` body"); 2310 } 2311 } 2312 2313 return createRewriteStmt(loc, *rootOp, *rewriteBody); 2314 } 2315 2316 //===----------------------------------------------------------------------===// 2317 // Creation+Analysis 2318 //===----------------------------------------------------------------------===// 2319 2320 //===----------------------------------------------------------------------===// 2321 // Decls 2322 2323 ast::CallableDecl *Parser::tryExtractCallableDecl(ast::Node *node) { 2324 // Unwrap reference expressions. 2325 if (auto *init = dyn_cast<ast::DeclRefExpr>(node)) 2326 node = init->getDecl(); 2327 return dyn_cast<ast::CallableDecl>(node); 2328 } 2329 2330 FailureOr<ast::PatternDecl *> 2331 Parser::createPatternDecl(SMRange loc, const ast::Name *name, 2332 const ParsedPatternMetadata &metadata, 2333 ast::CompoundStmt *body) { 2334 return ast::PatternDecl::create(ctx, loc, name, metadata.benefit, 2335 metadata.hasBoundedRecursion, body); 2336 } 2337 2338 ast::Type Parser::createUserConstraintRewriteResultType( 2339 ArrayRef<ast::VariableDecl *> results) { 2340 // Single result decls use the type of the single result. 2341 if (results.size() == 1) 2342 return results[0]->getType(); 2343 2344 // Multiple results use a tuple type, with the types and names grabbed from 2345 // the result variable decls. 2346 auto resultTypes = llvm::map_range( 2347 results, [&](const auto *result) { return result->getType(); }); 2348 auto resultNames = llvm::map_range( 2349 results, [&](const auto *result) { return result->getName().getName(); }); 2350 return ast::TupleType::get(ctx, llvm::to_vector(resultTypes), 2351 llvm::to_vector(resultNames)); 2352 } 2353 2354 template <typename T> 2355 FailureOr<T *> Parser::createUserPDLLConstraintOrRewriteDecl( 2356 const ast::Name &name, ArrayRef<ast::VariableDecl *> arguments, 2357 ArrayRef<ast::VariableDecl *> results, ast::Type resultType, 2358 ast::CompoundStmt *body) { 2359 if (!body->getChildren().empty()) { 2360 if (auto *retStmt = dyn_cast<ast::ReturnStmt>(body->getChildren().back())) { 2361 ast::Expr *resultExpr = retStmt->getResultExpr(); 2362 2363 // Process the result of the decl. If no explicit signature results 2364 // were provided, check for return type inference. Otherwise, check that 2365 // the return expression can be converted to the expected type. 2366 if (results.empty()) 2367 resultType = resultExpr->getType(); 2368 else if (failed(convertExpressionTo(resultExpr, resultType))) 2369 return failure(); 2370 else 2371 retStmt->setResultExpr(resultExpr); 2372 } 2373 } 2374 return T::createPDLL(ctx, name, arguments, results, body, resultType); 2375 } 2376 2377 FailureOr<ast::VariableDecl *> 2378 Parser::createVariableDecl(StringRef name, SMRange loc, ast::Expr *initializer, 2379 ArrayRef<ast::ConstraintRef> constraints) { 2380 // The type of the variable, which is expected to be inferred by either a 2381 // constraint or an initializer expression. 2382 ast::Type type; 2383 if (failed(validateVariableConstraints(constraints, type))) 2384 return failure(); 2385 2386 if (initializer) { 2387 // Update the variable type based on the initializer, or try to convert the 2388 // initializer to the existing type. 2389 if (!type) 2390 type = initializer->getType(); 2391 else if (ast::Type mergedType = type.refineWith(initializer->getType())) 2392 type = mergedType; 2393 else if (failed(convertExpressionTo(initializer, type))) 2394 return failure(); 2395 2396 // Otherwise, if there is no initializer check that the type has already 2397 // been resolved from the constraint list. 2398 } else if (!type) { 2399 return emitErrorAndNote( 2400 loc, "unable to infer type for variable `" + name + "`", loc, 2401 "the type of a variable must be inferable from the constraint " 2402 "list or the initializer"); 2403 } 2404 2405 // Constraint types cannot be used when defining variables. 2406 if (type.isa<ast::ConstraintType, ast::RewriteType>()) { 2407 return emitError( 2408 loc, llvm::formatv("unable to define variable of `{0}` type", type)); 2409 } 2410 2411 // Try to define a variable with the given name. 2412 FailureOr<ast::VariableDecl *> varDecl = 2413 defineVariableDecl(name, loc, type, initializer, constraints); 2414 if (failed(varDecl)) 2415 return failure(); 2416 2417 return *varDecl; 2418 } 2419 2420 FailureOr<ast::VariableDecl *> 2421 Parser::createArgOrResultVariableDecl(StringRef name, SMRange loc, 2422 const ast::ConstraintRef &constraint) { 2423 // Constraint arguments may apply more complex constraints via the arguments. 2424 bool allowNonCoreConstraints = parserContext == ParserContext::Constraint; 2425 ast::Type argType; 2426 if (failed(validateVariableConstraint(constraint, argType, 2427 allowNonCoreConstraints))) 2428 return failure(); 2429 return defineVariableDecl(name, loc, argType, constraint); 2430 } 2431 2432 LogicalResult 2433 Parser::validateVariableConstraints(ArrayRef<ast::ConstraintRef> constraints, 2434 ast::Type &inferredType, 2435 bool allowNonCoreConstraints) { 2436 for (const ast::ConstraintRef &ref : constraints) 2437 if (failed(validateVariableConstraint(ref, inferredType, 2438 allowNonCoreConstraints))) 2439 return failure(); 2440 return success(); 2441 } 2442 2443 LogicalResult Parser::validateVariableConstraint(const ast::ConstraintRef &ref, 2444 ast::Type &inferredType, 2445 bool allowNonCoreConstraints) { 2446 ast::Type constraintType; 2447 if (const auto *cst = dyn_cast<ast::AttrConstraintDecl>(ref.constraint)) { 2448 if (const ast::Expr *typeExpr = cst->getTypeExpr()) { 2449 if (failed(validateTypeConstraintExpr(typeExpr))) 2450 return failure(); 2451 } 2452 constraintType = ast::AttributeType::get(ctx); 2453 } else if (const auto *cst = 2454 dyn_cast<ast::OpConstraintDecl>(ref.constraint)) { 2455 constraintType = ast::OperationType::get(ctx, cst->getName()); 2456 } else if (isa<ast::TypeConstraintDecl>(ref.constraint)) { 2457 constraintType = typeTy; 2458 } else if (isa<ast::TypeRangeConstraintDecl>(ref.constraint)) { 2459 constraintType = typeRangeTy; 2460 } else if (const auto *cst = 2461 dyn_cast<ast::ValueConstraintDecl>(ref.constraint)) { 2462 if (const ast::Expr *typeExpr = cst->getTypeExpr()) { 2463 if (failed(validateTypeConstraintExpr(typeExpr))) 2464 return failure(); 2465 } 2466 constraintType = valueTy; 2467 } else if (const auto *cst = 2468 dyn_cast<ast::ValueRangeConstraintDecl>(ref.constraint)) { 2469 if (const ast::Expr *typeExpr = cst->getTypeExpr()) { 2470 if (failed(validateTypeRangeConstraintExpr(typeExpr))) 2471 return failure(); 2472 } 2473 constraintType = valueRangeTy; 2474 } else if (const auto *cst = 2475 dyn_cast<ast::UserConstraintDecl>(ref.constraint)) { 2476 if (!allowNonCoreConstraints) { 2477 return emitError(ref.referenceLoc, 2478 "`Rewrite` arguments and results are only permitted to " 2479 "use core constraints, such as `Attr`, `Op`, `Type`, " 2480 "`TypeRange`, `Value`, `ValueRange`"); 2481 } 2482 2483 ArrayRef<ast::VariableDecl *> inputs = cst->getInputs(); 2484 if (inputs.size() != 1) { 2485 return emitErrorAndNote(ref.referenceLoc, 2486 "`Constraint`s applied via a variable constraint " 2487 "list must take a single input, but got " + 2488 Twine(inputs.size()), 2489 cst->getLoc(), 2490 "see definition of constraint here"); 2491 } 2492 constraintType = inputs.front()->getType(); 2493 } else { 2494 llvm_unreachable("unknown constraint type"); 2495 } 2496 2497 // Check that the constraint type is compatible with the current inferred 2498 // type. 2499 if (!inferredType) { 2500 inferredType = constraintType; 2501 } else if (ast::Type mergedTy = inferredType.refineWith(constraintType)) { 2502 inferredType = mergedTy; 2503 } else { 2504 return emitError(ref.referenceLoc, 2505 llvm::formatv("constraint type `{0}` is incompatible " 2506 "with the previously inferred type `{1}`", 2507 constraintType, inferredType)); 2508 } 2509 return success(); 2510 } 2511 2512 LogicalResult Parser::validateTypeConstraintExpr(const ast::Expr *typeExpr) { 2513 ast::Type typeExprType = typeExpr->getType(); 2514 if (typeExprType != typeTy) { 2515 return emitError(typeExpr->getLoc(), 2516 "expected expression of `Type` in type constraint"); 2517 } 2518 return success(); 2519 } 2520 2521 LogicalResult 2522 Parser::validateTypeRangeConstraintExpr(const ast::Expr *typeExpr) { 2523 ast::Type typeExprType = typeExpr->getType(); 2524 if (typeExprType != typeRangeTy) { 2525 return emitError(typeExpr->getLoc(), 2526 "expected expression of `TypeRange` in type constraint"); 2527 } 2528 return success(); 2529 } 2530 2531 //===----------------------------------------------------------------------===// 2532 // Exprs 2533 2534 FailureOr<ast::CallExpr *> 2535 Parser::createCallExpr(SMRange loc, ast::Expr *parentExpr, 2536 MutableArrayRef<ast::Expr *> arguments) { 2537 ast::Type parentType = parentExpr->getType(); 2538 2539 ast::CallableDecl *callableDecl = tryExtractCallableDecl(parentExpr); 2540 if (!callableDecl) { 2541 return emitError(loc, 2542 llvm::formatv("expected a reference to a callable " 2543 "`Constraint` or `Rewrite`, but got: `{0}`", 2544 parentType)); 2545 } 2546 if (parserContext == ParserContext::Rewrite) { 2547 if (isa<ast::UserConstraintDecl>(callableDecl)) 2548 return emitError( 2549 loc, "unable to invoke `Constraint` within a rewrite section"); 2550 } else if (isa<ast::UserRewriteDecl>(callableDecl)) { 2551 return emitError(loc, "unable to invoke `Rewrite` within a match section"); 2552 } 2553 2554 // Verify the arguments of the call. 2555 /// Handle size mismatch. 2556 ArrayRef<ast::VariableDecl *> callArgs = callableDecl->getInputs(); 2557 if (callArgs.size() != arguments.size()) { 2558 return emitErrorAndNote( 2559 loc, 2560 llvm::formatv("invalid number of arguments for {0} call; expected " 2561 "{1}, but got {2}", 2562 callableDecl->getCallableType(), callArgs.size(), 2563 arguments.size()), 2564 callableDecl->getLoc(), 2565 llvm::formatv("see the definition of {0} here", 2566 callableDecl->getName()->getName())); 2567 } 2568 2569 /// Handle argument type mismatch. 2570 auto attachDiagFn = [&](ast::Diagnostic &diag) { 2571 diag.attachNote(llvm::formatv("see the definition of `{0}` here", 2572 callableDecl->getName()->getName()), 2573 callableDecl->getLoc()); 2574 }; 2575 for (auto it : llvm::zip(callArgs, arguments)) { 2576 if (failed(convertExpressionTo(std::get<1>(it), std::get<0>(it)->getType(), 2577 attachDiagFn))) 2578 return failure(); 2579 } 2580 2581 return ast::CallExpr::create(ctx, loc, parentExpr, arguments, 2582 callableDecl->getResultType()); 2583 } 2584 2585 FailureOr<ast::DeclRefExpr *> Parser::createDeclRefExpr(SMRange loc, 2586 ast::Decl *decl) { 2587 // Check the type of decl being referenced. 2588 ast::Type declType; 2589 if (isa<ast::ConstraintDecl>(decl)) 2590 declType = ast::ConstraintType::get(ctx); 2591 else if (isa<ast::UserRewriteDecl>(decl)) 2592 declType = ast::RewriteType::get(ctx); 2593 else if (auto *varDecl = dyn_cast<ast::VariableDecl>(decl)) 2594 declType = varDecl->getType(); 2595 else 2596 return emitError(loc, "invalid reference to `" + 2597 decl->getName()->getName() + "`"); 2598 2599 return ast::DeclRefExpr::create(ctx, loc, decl, declType); 2600 } 2601 2602 FailureOr<ast::DeclRefExpr *> 2603 Parser::createInlineVariableExpr(ast::Type type, StringRef name, SMRange loc, 2604 ArrayRef<ast::ConstraintRef> constraints) { 2605 FailureOr<ast::VariableDecl *> decl = 2606 defineVariableDecl(name, loc, type, constraints); 2607 if (failed(decl)) 2608 return failure(); 2609 return ast::DeclRefExpr::create(ctx, loc, *decl, type); 2610 } 2611 2612 FailureOr<ast::MemberAccessExpr *> 2613 Parser::createMemberAccessExpr(ast::Expr *parentExpr, StringRef name, 2614 SMRange loc) { 2615 // Validate the member name for the given parent expression. 2616 FailureOr<ast::Type> memberType = validateMemberAccess(parentExpr, name, loc); 2617 if (failed(memberType)) 2618 return failure(); 2619 2620 return ast::MemberAccessExpr::create(ctx, loc, parentExpr, name, *memberType); 2621 } 2622 2623 FailureOr<ast::Type> Parser::validateMemberAccess(ast::Expr *parentExpr, 2624 StringRef name, SMRange loc) { 2625 ast::Type parentType = parentExpr->getType(); 2626 if (ast::OperationType opType = parentType.dyn_cast<ast::OperationType>()) { 2627 if (name == ast::AllResultsMemberAccessExpr::getMemberName()) 2628 return valueRangeTy; 2629 2630 // Verify member access based on the operation type. 2631 if (const ods::Operation *odsOp = lookupODSOperation(opType.getName())) { 2632 auto results = odsOp->getResults(); 2633 2634 // Handle indexed results. 2635 unsigned index = 0; 2636 if (llvm::isDigit(name[0]) && !name.getAsInteger(/*Radix=*/10, index) && 2637 index < results.size()) { 2638 return results[index].isVariadic() ? valueRangeTy : valueTy; 2639 } 2640 2641 // Handle named results. 2642 const auto *it = llvm::find_if(results, [&](const auto &result) { 2643 return result.getName() == name; 2644 }); 2645 if (it != results.end()) 2646 return it->isVariadic() ? valueRangeTy : valueTy; 2647 } 2648 2649 } else if (auto tupleType = parentType.dyn_cast<ast::TupleType>()) { 2650 // Handle indexed results. 2651 unsigned index = 0; 2652 if (llvm::isDigit(name[0]) && !name.getAsInteger(/*Radix=*/10, index) && 2653 index < tupleType.size()) { 2654 return tupleType.getElementTypes()[index]; 2655 } 2656 2657 // Handle named results. 2658 auto elementNames = tupleType.getElementNames(); 2659 const auto *it = llvm::find(elementNames, name); 2660 if (it != elementNames.end()) 2661 return tupleType.getElementTypes()[it - elementNames.begin()]; 2662 } 2663 return emitError( 2664 loc, 2665 llvm::formatv("invalid member access `{0}` on expression of type `{1}`", 2666 name, parentType)); 2667 } 2668 2669 FailureOr<ast::OperationExpr *> Parser::createOperationExpr( 2670 SMRange loc, const ast::OpNameDecl *name, 2671 MutableArrayRef<ast::Expr *> operands, 2672 MutableArrayRef<ast::NamedAttributeDecl *> attributes, 2673 MutableArrayRef<ast::Expr *> results) { 2674 Optional<StringRef> opNameRef = name->getName(); 2675 const ods::Operation *odsOp = lookupODSOperation(opNameRef); 2676 2677 // Verify the inputs operands. 2678 if (failed(validateOperationOperands(loc, opNameRef, odsOp, operands))) 2679 return failure(); 2680 2681 // Verify the attribute list. 2682 for (ast::NamedAttributeDecl *attr : attributes) { 2683 // Check for an attribute type, or a type awaiting resolution. 2684 ast::Type attrType = attr->getValue()->getType(); 2685 if (!attrType.isa<ast::AttributeType>()) { 2686 return emitError( 2687 attr->getValue()->getLoc(), 2688 llvm::formatv("expected `Attr` expression, but got `{0}`", attrType)); 2689 } 2690 } 2691 2692 // Verify the result types. 2693 if (failed(validateOperationResults(loc, opNameRef, odsOp, results))) 2694 return failure(); 2695 2696 return ast::OperationExpr::create(ctx, loc, name, operands, results, 2697 attributes); 2698 } 2699 2700 LogicalResult 2701 Parser::validateOperationOperands(SMRange loc, Optional<StringRef> name, 2702 const ods::Operation *odsOp, 2703 MutableArrayRef<ast::Expr *> operands) { 2704 return validateOperationOperandsOrResults( 2705 "operand", loc, odsOp ? odsOp->getLoc() : Optional<SMRange>(), name, 2706 operands, odsOp ? odsOp->getOperands() : llvm::None, valueTy, 2707 valueRangeTy); 2708 } 2709 2710 LogicalResult 2711 Parser::validateOperationResults(SMRange loc, Optional<StringRef> name, 2712 const ods::Operation *odsOp, 2713 MutableArrayRef<ast::Expr *> results) { 2714 return validateOperationOperandsOrResults( 2715 "result", loc, odsOp ? odsOp->getLoc() : Optional<SMRange>(), name, 2716 results, odsOp ? odsOp->getResults() : llvm::None, typeTy, typeRangeTy); 2717 } 2718 2719 LogicalResult Parser::validateOperationOperandsOrResults( 2720 StringRef groupName, SMRange loc, Optional<SMRange> odsOpLoc, 2721 Optional<StringRef> name, MutableArrayRef<ast::Expr *> values, 2722 ArrayRef<ods::OperandOrResult> odsValues, ast::Type singleTy, 2723 ast::Type rangeTy) { 2724 // All operation types accept a single range parameter. 2725 if (values.size() == 1) { 2726 if (failed(convertExpressionTo(values[0], rangeTy))) 2727 return failure(); 2728 return success(); 2729 } 2730 2731 /// If the operation has ODS information, we can more accurately verify the 2732 /// values. 2733 if (odsOpLoc) { 2734 if (odsValues.size() != values.size()) { 2735 return emitErrorAndNote( 2736 loc, 2737 llvm::formatv("invalid number of {0} groups for `{1}`; expected " 2738 "{2}, but got {3}", 2739 groupName, *name, odsValues.size(), values.size()), 2740 *odsOpLoc, llvm::formatv("see the definition of `{0}` here", *name)); 2741 } 2742 auto diagFn = [&](ast::Diagnostic &diag) { 2743 diag.attachNote(llvm::formatv("see the definition of `{0}` here", *name), 2744 *odsOpLoc); 2745 }; 2746 for (unsigned i = 0, e = values.size(); i < e; ++i) { 2747 ast::Type expectedType = odsValues[i].isVariadic() ? rangeTy : singleTy; 2748 if (failed(convertExpressionTo(values[i], expectedType, diagFn))) 2749 return failure(); 2750 } 2751 return success(); 2752 } 2753 2754 // Otherwise, accept the value groups as they have been defined and just 2755 // ensure they are one of the expected types. 2756 for (ast::Expr *&valueExpr : values) { 2757 ast::Type valueExprType = valueExpr->getType(); 2758 2759 // Check if this is one of the expected types. 2760 if (valueExprType == rangeTy || valueExprType == singleTy) 2761 continue; 2762 2763 // If the operand is an Operation, allow converting to a Value or 2764 // ValueRange. This situations arises quite often with nested operation 2765 // expressions: `op<my_dialect.foo>(op<my_dialect.bar>)` 2766 if (singleTy == valueTy) { 2767 if (valueExprType.isa<ast::OperationType>()) { 2768 valueExpr = convertOpToValue(valueExpr); 2769 continue; 2770 } 2771 } 2772 2773 return emitError( 2774 valueExpr->getLoc(), 2775 llvm::formatv( 2776 "expected `{0}` or `{1}` convertible expression, but got `{2}`", 2777 singleTy, rangeTy, valueExprType)); 2778 } 2779 return success(); 2780 } 2781 2782 FailureOr<ast::TupleExpr *> 2783 Parser::createTupleExpr(SMRange loc, ArrayRef<ast::Expr *> elements, 2784 ArrayRef<StringRef> elementNames) { 2785 for (const ast::Expr *element : elements) { 2786 ast::Type eleTy = element->getType(); 2787 if (eleTy.isa<ast::ConstraintType, ast::RewriteType, ast::TupleType>()) { 2788 return emitError( 2789 element->getLoc(), 2790 llvm::formatv("unable to build a tuple with `{0}` element", eleTy)); 2791 } 2792 } 2793 return ast::TupleExpr::create(ctx, loc, elements, elementNames); 2794 } 2795 2796 //===----------------------------------------------------------------------===// 2797 // Stmts 2798 2799 FailureOr<ast::EraseStmt *> Parser::createEraseStmt(SMRange loc, 2800 ast::Expr *rootOp) { 2801 // Check that root is an Operation. 2802 ast::Type rootType = rootOp->getType(); 2803 if (!rootType.isa<ast::OperationType>()) 2804 return emitError(rootOp->getLoc(), "expected `Op` expression"); 2805 2806 return ast::EraseStmt::create(ctx, loc, rootOp); 2807 } 2808 2809 FailureOr<ast::ReplaceStmt *> 2810 Parser::createReplaceStmt(SMRange loc, ast::Expr *rootOp, 2811 MutableArrayRef<ast::Expr *> replValues) { 2812 // Check that root is an Operation. 2813 ast::Type rootType = rootOp->getType(); 2814 if (!rootType.isa<ast::OperationType>()) { 2815 return emitError( 2816 rootOp->getLoc(), 2817 llvm::formatv("expected `Op` expression, but got `{0}`", rootType)); 2818 } 2819 2820 // If there are multiple replacement values, we implicitly convert any Op 2821 // expressions to the value form. 2822 bool shouldConvertOpToValues = replValues.size() > 1; 2823 for (ast::Expr *&replExpr : replValues) { 2824 ast::Type replType = replExpr->getType(); 2825 2826 // Check that replExpr is an Operation, Value, or ValueRange. 2827 if (replType.isa<ast::OperationType>()) { 2828 if (shouldConvertOpToValues) 2829 replExpr = convertOpToValue(replExpr); 2830 continue; 2831 } 2832 2833 if (replType != valueTy && replType != valueRangeTy) { 2834 return emitError(replExpr->getLoc(), 2835 llvm::formatv("expected `Op`, `Value` or `ValueRange` " 2836 "expression, but got `{0}`", 2837 replType)); 2838 } 2839 } 2840 2841 return ast::ReplaceStmt::create(ctx, loc, rootOp, replValues); 2842 } 2843 2844 FailureOr<ast::RewriteStmt *> 2845 Parser::createRewriteStmt(SMRange loc, ast::Expr *rootOp, 2846 ast::CompoundStmt *rewriteBody) { 2847 // Check that root is an Operation. 2848 ast::Type rootType = rootOp->getType(); 2849 if (!rootType.isa<ast::OperationType>()) { 2850 return emitError( 2851 rootOp->getLoc(), 2852 llvm::formatv("expected `Op` expression, but got `{0}`", rootType)); 2853 } 2854 2855 return ast::RewriteStmt::create(ctx, loc, rootOp, rewriteBody); 2856 } 2857 2858 //===----------------------------------------------------------------------===// 2859 // Code Completion 2860 //===----------------------------------------------------------------------===// 2861 2862 LogicalResult Parser::codeCompleteMemberAccess(ast::Expr *parentExpr) { 2863 ast::Type parentType = parentExpr->getType(); 2864 if (ast::OperationType opType = parentType.dyn_cast<ast::OperationType>()) 2865 codeCompleteContext->codeCompleteOperationMemberAccess(opType); 2866 else if (ast::TupleType tupleType = parentType.dyn_cast<ast::TupleType>()) 2867 codeCompleteContext->codeCompleteTupleMemberAccess(tupleType); 2868 return failure(); 2869 } 2870 2871 LogicalResult Parser::codeCompleteAttributeName(Optional<StringRef> opName) { 2872 if (opName) 2873 codeCompleteContext->codeCompleteOperationAttributeName(*opName); 2874 return failure(); 2875 } 2876 2877 LogicalResult 2878 Parser::codeCompleteConstraintName(ast::Type inferredType, 2879 bool allowNonCoreConstraints, 2880 bool allowInlineTypeConstraints) { 2881 codeCompleteContext->codeCompleteConstraintName( 2882 inferredType, allowNonCoreConstraints, allowInlineTypeConstraints, 2883 curDeclScope); 2884 return failure(); 2885 } 2886 2887 LogicalResult Parser::codeCompleteDialectName() { 2888 codeCompleteContext->codeCompleteDialectName(); 2889 return failure(); 2890 } 2891 2892 LogicalResult Parser::codeCompleteOperationName(StringRef dialectName) { 2893 codeCompleteContext->codeCompleteOperationName(dialectName); 2894 return failure(); 2895 } 2896 2897 LogicalResult Parser::codeCompletePatternMetadata() { 2898 codeCompleteContext->codeCompletePatternMetadata(); 2899 return failure(); 2900 } 2901 2902 //===----------------------------------------------------------------------===// 2903 // Parser 2904 //===----------------------------------------------------------------------===// 2905 2906 FailureOr<ast::Module *> 2907 mlir::pdll::parsePDLAST(ast::Context &ctx, llvm::SourceMgr &sourceMgr, 2908 CodeCompleteContext *codeCompleteContext) { 2909 Parser parser(ctx, sourceMgr, codeCompleteContext); 2910 return parser.parseModule(); 2911 } 2912