26 #include "llvm/ADT/StringExtras.h" 27 #include "llvm/ADT/TypeSwitch.h" 28 #include "llvm/Support/FormatVariadic.h" 29 #include "llvm/Support/ManagedStatic.h" 30 #include "llvm/Support/SaveAndRestore.h" 31 #include "llvm/Support/ScopedPrinter.h" 32 #include "llvm/TableGen/Error.h" 33 #include "llvm/TableGen/Parser.h" 48 : ctx(ctx), lexer(sourceMgr, ctx.
getDiagEngine(), codeCompleteContext),
49 curToken(lexer.lexToken()), enableDocumentation(enableDocumentation),
55 codeCompleteContext(codeCompleteContext) {}
66 enum class ParserContext {
83 enum class OpResultTypeContext {
102 return (curDeclScope = newScope);
104 void pushDeclScope(
ast::DeclScope *scope) { curDeclScope = scope; }
107 void popDeclScope() { curDeclScope = curDeclScope->
getParentScope(); }
132 StringRef processDoc(StringRef doc) {
133 return enableDocumentation ? doc : StringRef();
138 std::string processAndFormatDoc(
const Twine &doc) {
139 if (!enableDocumentation)
143 llvm::raw_string_ostream docOS(docStr);
144 std::string tmpDocStr = doc.str();
146 StringRef(tmpDocStr).rtrim(
" \t"));
156 LogicalResult parseTdInclude(StringRef filename, SMRange fileLoc,
160 void processTdIncludeRecords(llvm::RecordKeeper &tdRecords,
165 template <
typename Constra
intT>
167 createODSNativePDLLConstraintDecl(StringRef name, StringRef codeBlock,
169 StringRef nativeType, StringRef docString);
170 template <
typename Constra
intT>
174 StringRef nativeType);
180 struct ParsedPatternMetadata {
182 bool hasBoundedRecursion =
false;
200 parseUserConstraintDecl(
bool isInline =
false);
231 template <
typename T,
typename ParseUserPDLLDeclFnT>
233 ParseUserPDLLDeclFnT &&parseUserPDLLFn, ParserContext declContext,
234 StringRef anonymousNamePrefix,
bool isInline);
238 template <
typename T>
261 bool expectTerminalSemicolon =
true);
264 LogicalResult parsePatternDeclMetadata(ParsedPatternMetadata &metadata);
273 defineVariableDecl(StringRef name, SMRange nameLoc,
ast::Type type,
277 defineVariableDecl(StringRef name, SMRange nameLoc,
ast::Type type,
298 bool allowInlineTypeConstraints,
299 bool allowNonCoreConstraints);
322 parseOperationExpr(OpResultTypeContext inputResultTypeContext =
323 OpResultTypeContext::Explicit);
353 createPatternDecl(SMRange loc,
const ast::Name *name,
354 const ParsedPatternMetadata &metadata,
363 template <
typename T>
372 createVariableDecl(StringRef name, SMRange loc,
ast::Expr *initializer,
378 createArgOrResultVariableDecl(StringRef name, SMRange loc,
390 bool allowNonCoreConstraints =
true);
398 bool allowNonCoreConstraints =
true);
406 createCallExpr(SMRange loc,
ast::Expr *parentExpr,
410 createInlineVariableExpr(
ast::Type type, StringRef name, SMRange loc,
413 createMemberAccessExpr(
ast::Expr *parentExpr, StringRef name, SMRange loc);
418 StringRef name, SMRange loc);
421 OpResultTypeContext resultTypeContext,
432 void checkOperationResultTypeInferrence(SMRange loc, StringRef name,
448 createReplaceStmt(SMRange loc,
ast::Expr *rootOp,
451 createRewriteStmt(SMRange loc,
ast::Expr *rootOp,
465 bool allowNonCoreConstraints,
466 bool allowInlineTypeConstraints);
468 LogicalResult codeCompleteOperationName(StringRef dialectName);
470 LogicalResult codeCompleteIncludeFilename(StringRef curPath);
472 void codeCompleteCallSignature(
ast::Node *parent,
unsigned currentNumArgs);
474 unsigned currentNumOperands);
476 unsigned currentNumResults);
485 if (curToken.isNot(kind))
492 void consumeToken() {
494 "shouldn't advance past EOF or errors");
495 curToken = lexer.lexToken();
502 assert(curToken.is(kind) &&
"consumed an unexpected token");
507 void resetToken(SMRange tokLoc) {
508 lexer.resetPointer(tokLoc.Start.getPointer());
509 curToken = lexer.lexToken();
515 if (curToken.getKind() != kind)
516 return emitError(curToken.getLoc(), msg);
521 lexer.emitError(loc, msg);
525 return emitError(curToken.getLoc(), msg);
527 LogicalResult emitErrorAndNote(SMRange loc,
const Twine &msg, SMRange noteLoc,
529 lexer.emitErrorAndNote(loc, msg, noteLoc, note);
548 bool enableDocumentation;
552 llvm::SpecificBumpPtrAllocator<ast::DeclScope> scopeAllocator;
555 ParserContext parserContext = ParserContext::Global;
563 unsigned anonymousDeclNameCounter = 0;
571 SMLoc moduleLoc = curToken.getStartLoc();
576 if (
failed(parseModuleBody(decls)))
577 return popDeclScope(),
failure();
586 if (
failed(parseDirective(decls)))
594 decls.push_back(*decl);
608 if (exprType == type)
613 expr->
getLoc(), llvm::formatv(
"unable to convert expression of type " 614 "`{0}` to the expected type of " 626 if (opType.getName())
627 return emitConvertError();
632 if (type == valueRangeTy) {
639 if (type == valueTy) {
643 if (odsOp->getResults().empty()) {
644 return emitConvertError()->attachNote(
645 llvm::formatv(
"see the definition of `{0}`, which was defined " 651 unsigned numSingleResults = llvm::count_if(
653 return result.getVariableLengthKind() ==
656 if (numSingleResults > 1) {
657 return emitConvertError()->attachNote(
658 llvm::formatv(
"see the definition of `{0}`, which was defined " 659 "with at least {1} results",
660 odsOp->getName(), numSingleResults),
669 return emitConvertError();
676 if ((exprType == valueTy || exprType == valueRangeTy) &&
677 (type == valueTy || type == valueRangeTy))
679 if ((exprType == typeTy || exprType == typeRangeTy) &&
680 (type == typeTy || type == typeRangeTy))
686 if (!tupleType || tupleType.size() != exprTupleType.size())
687 return emitConvertError();
692 for (
unsigned i = 0, e = exprTupleType.size(); i < e; ++i) {
694 ctx, expr->
getLoc(), expr, llvm::to_string(i),
695 exprTupleType.getElementTypes()[i]));
698 diag.attachNote(llvm::formatv(
"when converting element #{0} of `{1}`",
703 if (
failed(convertExpressionTo(newExprs.back(),
704 tupleType.getElementTypes()[i], diagFn)))
708 tupleType.getElementNames());
712 return emitConvertError();
719 StringRef directive = curToken.getSpelling();
720 if (directive ==
"#include")
721 return parseInclude(decls);
723 return emitError(
"unknown directive `" + directive +
"`");
727 SMRange loc = curToken.getLoc();
732 return codeCompleteIncludeFilename(curToken.getStringValue());
735 if (!curToken.isString())
737 "expected string file name after `include` directive");
738 SMRange fileLoc = curToken.getLoc();
739 std::string filenameStr = curToken.getStringValue();
740 StringRef filename = filenameStr;
745 if (filename.endswith(
".pdll")) {
746 if (
failed(lexer.pushInclude(filename, fileLoc)))
748 "unable to open include file `" + filename +
"`");
753 curToken = lexer.lexToken();
755 curToken = lexer.lexToken();
760 if (filename.endswith(
".td"))
761 return parseTdInclude(filename, fileLoc, decls);
764 "expected include filename to end with `.pdll` or `.td`");
767 LogicalResult Parser::parseTdInclude(StringRef filename, llvm::SMRange fileLoc,
769 llvm::SourceMgr &parserSrcMgr = lexer.getSourceMgr();
772 std::string includedFile;
773 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> includeBuffer =
774 parserSrcMgr.OpenIncludeFile(filename.str(), includedFile);
776 return emitError(fileLoc,
"unable to open include file `" + filename +
"`");
779 llvm::SourceMgr tdSrcMgr;
780 tdSrcMgr.AddNewSourceBuffer(std::move(*includeBuffer), SMLoc());
781 tdSrcMgr.setIncludeDirs(parserSrcMgr.getIncludeDirs());
785 struct DiagHandlerContext {
789 } handlerContext{*
this, filename, fileLoc};
792 tdSrcMgr.setDiagHandler(
793 [](
const llvm::SMDiagnostic &diag,
void *rawHandlerContext) {
794 auto *ctx =
reinterpret_cast<DiagHandlerContext *
>(rawHandlerContext);
795 (
void)ctx->parser.emitError(
797 llvm::formatv(
"error while processing include file `{0}`: {1}",
798 ctx->filename, diag.getMessage()));
803 llvm::RecordKeeper tdRecords;
804 if (llvm::TableGenParseFile(tdSrcMgr, tdRecords))
808 processTdIncludeRecords(tdRecords, decls);
813 parserSrcMgr.takeSourceBuffersFrom(tdSrcMgr, fileLoc.End);
817 void Parser::processTdIncludeRecords(llvm::RecordKeeper &tdRecords,
820 auto getLengthKind = [](
const auto &
value) {
821 if (
value.isOptional())
832 cst.constraint.getUniqueDefName(),
833 processDoc(cst.constraint.getSummary()),
834 cst.constraint.getCPPClassName());
836 auto convertLocToRange = [&](llvm::SMLoc loc) -> llvm::SMRange {
837 return {loc, llvm::SMLoc::getFromPointer(loc.getPointer() + 1)};
842 for (llvm::Record *def : tdRecords.getAllDerivedDefinitions(
"Op")) {
846 bool supportsResultTypeInferrence =
847 op.getTrait(
"::mlir::InferTypeOpInterface::Trait");
849 bool inserted =
false;
852 op.getOperationName(), processDoc(op.getSummary()),
853 processAndFormatDoc(op.getDescription()), op.getQualCppClassName(),
854 supportsResultTypeInferrence, op.getLoc().front());
863 attr.attr.getUniqueDefName(),
864 processDoc(attr.attr.getSummary()),
865 attr.attr.getStorageType()));
869 addTypeConstraint(operand));
873 addTypeConstraint(result));
877 auto shouldBeSkipped = [
this](llvm::Record *def) {
878 return def->isAnonymous() || curDeclScope->lookup(def->getName()) ||
879 def->isSubClassOf(
"DeclareInterfaceMethods");
883 for (llvm::Record *def : tdRecords.getAllDerivedDefinitions(
"Attr")) {
884 if (shouldBeSkipped(def))
888 decls.push_back(createODSNativePDLLConstraintDecl<ast::AttrConstraintDecl>(
889 constraint, convertLocToRange(def->getLoc().front()), attrTy,
890 constraint.getStorageType()));
893 for (llvm::Record *def : tdRecords.getAllDerivedDefinitions(
"Type")) {
894 if (shouldBeSkipped(def))
898 decls.push_back(createODSNativePDLLConstraintDecl<ast::TypeConstraintDecl>(
899 constraint, convertLocToRange(def->getLoc().front()), typeTy,
900 constraint.getCPPClassName()));
904 for (llvm::Record *def : tdRecords.getAllDerivedDefinitions(
"OpInterface")) {
905 if (shouldBeSkipped(def))
908 SMRange loc = convertLocToRange(def->getLoc().front());
910 std::string cppClassName =
911 llvm::formatv(
"{0}::{1}", def->getValueAsString(
"cppNamespace"),
912 def->getValueAsString(
"cppInterfaceName"))
914 std::string codeBlock =
915 llvm::formatv(
"return ::mlir::success(llvm::isa<{0}>(self));",
920 processAndFormatDoc(def->getValueAsString(
"description"));
921 decls.push_back(createODSNativePDLLConstraintDecl<ast::OpConstraintDecl>(
922 def->getName(), codeBlock, loc, opTy, cppClassName, desc));
926 template <
typename Constra
intT>
927 ast::Decl *Parser::createODSNativePDLLConstraintDecl(
928 StringRef name, StringRef codeBlock, SMRange loc,
ast::Type type,
929 StringRef nativeType, StringRef docString) {
935 argScope->
add(paramVar);
942 constraintDecl->setDocComment(ctx, docString);
943 curDeclScope->add(constraintDecl);
944 return constraintDecl;
947 template <
typename Constra
intT>
951 StringRef nativeType) {
962 std::string docString;
963 if (enableDocumentation) {
965 docString = processAndFormatDoc(
970 return createODSNativePDLLConstraintDecl<ConstraintT>(
980 switch (curToken.getKind()) {
982 decl = parseUserConstraintDecl();
985 decl = parsePatternDecl();
988 decl = parseUserRewriteDecl();
991 return emitError(
"expected top-level declaration, such as a `Pattern`");
998 if (
failed(checkDefineNamedDecl(*name)))
1000 curDeclScope->add(*decl);
1009 return codeCompleteAttributeName(parentOpName);
1011 std::string attrNameStr;
1012 if (curToken.isString())
1013 attrNameStr = curToken.getStringValue();
1015 attrNameStr = curToken.getSpelling().str();
1017 return emitError(
"expected identifier or string attribute name");
1027 attrValue = *attrExpr;
1039 bool expectTerminalSemicolon) {
1043 SMLoc bodyStartLoc = curToken.getStartLoc();
1046 bool failedToParse =
1047 failed(singleStatement) ||
failed(processStatementFn(*singleStatement));
1052 SMRange bodyLoc(bodyStartLoc, curToken.getStartLoc());
1059 return emitError(
"expected identifier argument name");
1062 StringRef name = curToken.getSpelling();
1063 SMRange nameLoc = curToken.getLoc();
1067 parseToken(
Token::colon,
"expected `:` before argument constraint")))
1074 return createArgOrResultVariableDecl(name, nameLoc, *cst);
1081 ast::Decl *existingDecl = curDeclScope->lookup(curToken.getSpelling());
1082 if (isa_and_nonnull<ast::ConstraintDecl>(existingDecl)) {
1085 if (parserContext == ParserContext::Rewrite) {
1087 "`Rewrite` results are only permitted to use core constraints, " 1088 "such as `Attr`, `Op`, `Type`, `TypeRange`, `Value`, `ValueRange`");
1096 StringRef name = curToken.getSpelling();
1097 SMRange nameLoc = curToken.getLoc();
1101 "expected `:` before result constraint")))
1108 return createArgOrResultVariableDecl(name, nameLoc, *cst);
1118 return createArgOrResultVariableDecl(
"", cst->referenceLoc, *cst);
1122 Parser::parseUserConstraintDecl(
bool isInline) {
1125 return parseUserConstraintOrRewriteDecl<ast::UserConstraintDecl>(
1126 [&](
auto &&...args) {
1127 return this->parseUserPDLLConstraintDecl(args...);
1129 ParserContext::Constraint,
"constraint", isInline);
1134 parseUserConstraintDecl(
true);
1135 if (
failed(decl) ||
failed(checkDefineNamedDecl((*decl)->getName())))
1138 curDeclScope->add(*decl);
1148 pushDeclScope(argumentScope);
1159 "expected `Constraint` lambda body to contain a " 1160 "single expression");
1176 auto bodyIt = body->
begin(), bodyE = body->
end();
1177 for (; bodyIt != bodyE; ++bodyIt)
1178 if (isa<ast::ReturnStmt>(*bodyIt))
1180 if (
failed(validateUserConstraintOrRewriteReturn(
1181 "Constraint", body, bodyIt, bodyE, results, resultType)))
1186 return createUserPDLLConstraintOrRewriteDecl<ast::UserConstraintDecl>(
1187 name, arguments, results, resultType, body);
1193 return parseUserConstraintOrRewriteDecl<ast::UserRewriteDecl>(
1194 [&](
auto &&...args) {
return this->parseUserPDLLRewriteDecl(args...); },
1195 ParserContext::Rewrite,
"rewrite", isInline);
1200 parseUserRewriteDecl(
true);
1201 if (
failed(decl) ||
failed(checkDefineNamedDecl((*decl)->getName())))
1204 curDeclScope->add(*decl);
1214 curDeclScope = argumentScope;
1219 if (isa<ast::OpRewriteStmt>(statement))
1223 if (!statementExpr) {
1226 "expected `Rewrite` lambda body to contain a single expression " 1227 "or an operation rewrite statement; such as `erase`, " 1228 "`replace`, or `rewrite`");
1247 auto bodyIt = body->
begin(), bodyE = body->
end();
1248 for (; bodyIt != bodyE; ++bodyIt)
1249 if (isa<ast::ReturnStmt>(*bodyIt))
1251 if (
failed(validateUserConstraintOrRewriteReturn(
"Rewrite", body, bodyIt,
1252 bodyE, results, resultType)))
1254 return createUserPDLLConstraintOrRewriteDecl<ast::UserRewriteDecl>(
1255 name, arguments, results, resultType, body);
1258 template <
typename T,
typename ParseUserPDLLDeclFnT>
1260 ParseUserPDLLDeclFnT &&parseUserPDLLFn, ParserContext declContext,
1261 StringRef anonymousNamePrefix,
bool isInline) {
1262 SMRange loc = curToken.getLoc();
1264 llvm::SaveAndRestore<ParserContext> saveCtx(parserContext, declContext);
1272 return emitError(
"expected identifier name");
1276 std::string anonName =
1277 llvm::formatv(
"<anonymous_{0}_{1}>", anonymousNamePrefix,
1278 anonymousDeclNameCounter++)
1291 if (
failed(parseUserConstraintOrRewriteSignature(arguments, results,
1292 argumentScope, resultType)))
1298 return parseUserPDLLFn(*name, isInline, arguments, argumentScope, results,
1302 return parseUserNativeConstraintOrRewriteDecl<T>(*name, isInline, arguments,
1303 results, resultType);
1306 template <
typename T>
1312 std::string codeStrStorage;
1314 if (curToken.isString()) {
1315 codeStrStorage = curToken.getStringValue();
1316 optCodeStr = codeStrStorage;
1318 }
else if (isInline) {
1320 "external declarations must be declared in global scope");
1325 "expected `;` after native declaration")))
1331 "native Constraints currently do not support returning results");
1333 return T::createNative(ctx, name, arguments, results, optCodeStr, resultType);
1336 LogicalResult Parser::parseUserConstraintOrRewriteSignature(
1344 argumentScope = pushDeclScope();
1350 arguments.emplace_back(*argument);
1364 results.emplace_back(*result);
1371 if (
failed(parseResultFn()))
1378 }
else if (
failed(parseResultFn())) {
1385 resultType = createUserConstraintRewriteResultType(results);
1388 if (results.size() == 1 && !results.front()->getName().getName().empty()) {
1390 results.front()->getLoc(),
1391 "cannot create a single-element tuple with an element label");
1396 LogicalResult Parser::validateUserConstraintOrRewriteReturn(
1402 if (bodyIt != bodyE) {
1404 if (std::next(bodyIt) != bodyE) {
1406 (*std::next(bodyIt))->getLoc(),
1407 llvm::formatv(
"`return` terminated the `{0}` body, but found " 1408 "trailing statements afterwards",
1414 }
else if (!results.empty()) {
1417 llvm::formatv(
"missing return in a `{0}` expected to return `{1}`",
1418 declType, resultType));
1425 if (isa<ast::OpRewriteStmt>(statement))
1429 "expected Pattern lambda body to contain a single operation " 1430 "rewrite statement, such as `erase`, `replace`, or `rewrite`");
1435 SMRange loc = curToken.getLoc();
1437 llvm::SaveAndRestore<ParserContext> saveCtx(parserContext,
1438 ParserContext::PatternMatch);
1448 ParsedPatternMetadata metadata;
1463 return emitError(
"expected `{` or `=>` to start pattern body");
1470 auto bodyIt = body->
begin(), bodyE = body->
end();
1471 for (; bodyIt != bodyE; ++bodyIt) {
1472 if (isa<ast::ReturnStmt>(*bodyIt)) {
1474 "`return` statements are only permitted within a " 1475 "`Constraint` or `Rewrite` body");
1478 if (isa<ast::OpRewriteStmt>(*bodyIt))
1481 if (bodyIt == bodyE) {
1483 "expected Pattern body to terminate with an operation " 1484 "rewrite statement, such as `erase`");
1486 if (std::next(bodyIt) != bodyE) {
1487 return emitError((*std::next(bodyIt))->getLoc(),
1488 "Pattern body was terminated by an operation " 1489 "rewrite statement, but found trailing statements");
1493 return createPatternDecl(loc, name, metadata, body);
1497 Parser::parsePatternDeclMetadata(ParsedPatternMetadata &metadata) {
1504 return codeCompletePatternMetadata();
1507 return emitError(
"expected pattern metadata identifier");
1508 StringRef metadataStr = curToken.getSpelling();
1509 SMRange metadataLoc = curToken.getLoc();
1513 if (metadataStr ==
"benefit") {
1515 return emitErrorAndNote(metadataLoc,
1516 "pattern benefit has already been specified",
1517 *benefitLoc,
"see previous definition here");
1520 "expected `(` before pattern benefit")))
1523 uint16_t benefitValue = 0;
1525 return emitError(
"expected integral pattern benefit");
1526 if (curToken.getSpelling().getAsInteger(10, benefitValue))
1528 "expected pattern benefit to fit within a 16-bit integer");
1531 metadata.benefit = benefitValue;
1532 benefitLoc = metadataLoc;
1535 parseToken(
Token::r_paren,
"expected `)` after pattern benefit")))
1541 if (metadataStr ==
"recursion") {
1542 if (hasBoundedRecursionLoc) {
1543 return emitErrorAndNote(
1545 "pattern recursion metadata has already been specified",
1546 *hasBoundedRecursionLoc,
"see previous definition here");
1548 metadata.hasBoundedRecursion =
true;
1549 hasBoundedRecursionLoc = metadataLoc;
1553 return emitError(metadataLoc,
"unknown pattern metadata");
1565 "expected `>` after variable type constraint")))
1571 assert(curDeclScope &&
"defining decl outside of a decl scope");
1573 return emitErrorAndNote(
1574 name.
getLoc(),
"`" + name.
getName() +
"` has already been defined",
1575 lastDecl->getName()->getLoc(),
"see previous definition here");
1581 Parser::defineVariableDecl(StringRef name, SMRange nameLoc,
ast::Type type,
1584 assert(curDeclScope &&
"defining variable outside of decl scope");
1589 if (name.empty() || name ==
"_") {
1593 if (
failed(checkDefineNamedDecl(nameDecl)))
1598 curDeclScope->add(varDecl);
1603 Parser::defineVariableDecl(StringRef name, SMRange nameLoc,
ast::Type type,
1605 return defineVariableDecl(name, nameLoc, type,
nullptr,
1612 auto parseSingleConstraint = [&] {
1614 typeConstraint, constraints,
true,
1618 constraints.push_back(*constraint);
1624 return parseSingleConstraint();
1627 if (
failed(parseSingleConstraint()))
1630 return parseToken(
Token::r_square,
"expected `]` after constraint list");
1636 bool allowInlineTypeConstraints,
1637 bool allowNonCoreConstraints) {
1639 if (!allowInlineTypeConstraints) {
1642 "inline `Attr`, `Value`, and `ValueRange` type constraints are not " 1643 "permitted on arguments or results");
1646 return emitErrorAndNote(
1648 "the type of this variable has already been constrained",
1649 *typeConstraint,
"see previous constraint location here");
1651 if (
failed(constraintExpr))
1653 typeExpr = *constraintExpr;
1654 typeConstraint = typeExpr->getLoc();
1658 SMRange loc = curToken.getLoc();
1659 switch (curToken.getKind()) {
1676 parseWrappedOperationName(
true);
1721 StringRef constraintName = curToken.getSpelling();
1727 return emitError(loc,
"unknown reference to constraint `" +
1728 constraintName +
"`");
1732 if (
auto *cst = dyn_cast<ast::ConstraintDecl>(cstDecl))
1735 return emitErrorAndNote(
1736 loc,
"invalid reference to non-constraint", cstDecl->
getLoc(),
1737 "see the definition of `" + constraintName +
"` here");
1743 if (
failed(validateVariableConstraints(existingConstraints, inferredType,
1744 allowNonCoreConstraints)))
1747 return codeCompleteConstraintName(inferredType, allowNonCoreConstraints,
1748 allowInlineTypeConstraints);
1753 return emitError(loc,
"expected identifier constraint");
1758 bool allowNonCoreConstraints = parserContext == ParserContext::Constraint;
1761 return parseConstraint(typeConstraint, llvm::None,
1763 allowNonCoreConstraints);
1771 return parseUnderscoreExpr();
1775 switch (curToken.getKind()) {
1777 lhsExpr = parseAttributeExpr();
1780 lhsExpr = parseInlineConstraintLambdaExpr();
1783 lhsExpr = parseIdentifierExpr();
1786 lhsExpr = parseOperationExpr();
1789 lhsExpr = parseInlineRewriteLambdaExpr();
1792 lhsExpr = parseTypeExpr();
1795 lhsExpr = parseTupleExpr();
1798 return emitError(
"expected expression");
1805 switch (curToken.getKind()) {
1807 lhsExpr = parseMemberAccessExpr(*lhsExpr);
1810 lhsExpr = parseCallExpr(*lhsExpr);
1821 SMRange loc = curToken.getLoc();
1828 return parseIdentifierExpr();
1831 if (!curToken.isString())
1832 return emitError(
"expected string literal containing MLIR attribute");
1833 std::string attrExpr = curToken.getStringValue();
1836 loc.End = curToken.getEndLoc();
1838 parseToken(
Token::greater,
"expected `>` after attribute literal")))
1852 codeCompleteCallSignature(parentExpr, arguments.size());
1859 arguments.push_back(*argument);
1863 SMRange loc(parentExpr->
getLoc().Start, curToken.getEndLoc());
1867 return createCallExpr(loc, parentExpr, arguments);
1871 ast::Decl *decl = curDeclScope->lookup(name);
1873 return emitError(loc,
"undefined reference to `" + name +
"`");
1875 return createDeclRefExpr(loc, decl);
1879 StringRef name = curToken.getSpelling();
1880 SMRange nameLoc = curToken.getLoc();
1887 if (
failed(parseVariableDeclConstraintList(constraints)))
1890 if (
failed(validateVariableConstraints(constraints, type)))
1892 return createInlineVariableExpr(type, name, nameLoc, constraints);
1895 return parseDeclRefExpr(name, nameLoc);
1917 SMRange dotLoc = curToken.getLoc();
1922 return codeCompleteMemberAccess(parentExpr);
1925 Token memberNameTok = curToken;
1928 return emitError(dotLoc,
"expected identifier or numeric member name");
1929 StringRef memberName = memberNameTok.
getSpelling();
1930 SMRange loc(parentExpr->
getLoc().Start, curToken.getEndLoc());
1933 return createMemberAccessExpr(parentExpr, memberName, loc);
1937 SMRange loc = curToken.getLoc();
1941 return codeCompleteDialectName();
1947 return emitError(
"expected dialect namespace");
1949 StringRef name = curToken.getSpelling();
1953 if (
failed(parseToken(
Token::dot,
"expected `.` after dialect namespace")))
1958 return codeCompleteOperationName(name);
1961 return emitError(
"expected operation name after dialect namespace");
1963 name = StringRef(name.data(), name.size() + 1);
1965 name = StringRef(name.data(), name.size() + curToken.getSpelling().size());
1966 loc.End = curToken.getEndLoc();
1969 curToken.isKeyword());
1974 Parser::parseWrappedOperationName(
bool allowEmptyName) {
1988 Parser::parseOperationExpr(OpResultTypeContext inputResultTypeContext) {
1989 SMRange loc = curToken.getLoc();
1996 return parseIdentifierExpr();
2002 bool allowEmptyName = parserContext != ParserContext::Rewrite;
2004 parseWrappedOperationName(allowEmptyName);
2014 assert(
succeeded(rangeVar) &&
"expected range variable to be valid");
2025 if (parserContext != ParserContext::Rewrite) {
2026 operands.push_back(createImplicitRangeVar(
2034 codeCompleteOperationOperandsSignature(opName, operands.size());
2041 operands.push_back(*operand);
2045 "expected `)` after operation operand list")))
2054 parseNamedAttributeDecl(opName);
2057 attributes.emplace_back(*decl);
2061 "expected `}` after operation attribute list")))
2067 OpResultTypeContext resultTypeContext = inputResultTypeContext;
2072 "expected `(` before operation result type list")))
2080 resultTypeContext = OpResultTypeContext::Explicit;
2087 codeCompleteOperationResultsSignature(opName, resultTypes.size());
2092 if (
failed(resultTypeExpr))
2094 resultTypes.push_back(*resultTypeExpr);
2098 "expected `)` after operation result type list")))
2101 }
else if (parserContext != ParserContext::Rewrite) {
2106 resultTypes.push_back(createImplicitRangeVar(
2108 }
else if (resultTypeContext == OpResultTypeContext::Explicit) {
2111 resultTypeContext = OpResultTypeContext::Interface;
2114 return createOperationExpr(loc, *opNameDecl, resultTypeContext, operands,
2115 attributes, resultTypes);
2119 SMRange loc = curToken.getLoc();
2128 StringRef elementName;
2130 Token elementNameTok = curToken;
2138 auto elementNameIt =
2139 usedNames.try_emplace(elementName, elementNameTok.
getLoc());
2140 if (!elementNameIt.second) {
2141 return emitErrorAndNote(
2143 llvm::formatv(
"duplicate tuple element label `{0}`",
2145 elementNameIt.first->getSecond(),
2146 "see previous label use here");
2151 resetToken(elementNameTok.
getLoc());
2154 elementNames.push_back(elementName);
2160 elements.push_back(*element);
2163 loc.End = curToken.getEndLoc();
2165 parseToken(
Token::r_paren,
"expected `)` after tuple element list")))
2167 return createTupleExpr(loc, elements, elementNames);
2171 SMRange loc = curToken.getLoc();
2178 return parseIdentifierExpr();
2181 if (!curToken.isString())
2182 return emitError(
"expected string literal containing MLIR type");
2183 std::string attrExpr = curToken.getStringValue();
2186 loc.End = curToken.getEndLoc();
2193 StringRef name = curToken.getSpelling();
2194 SMRange nameLoc = curToken.getLoc();
2203 if (
failed(parseVariableDeclConstraintList(constraints)))
2207 if (
failed(validateVariableConstraints(constraints, type)))
2209 return createInlineVariableExpr(type, name, nameLoc, constraints);
2217 switch (curToken.getKind()) {
2219 stmt = parseEraseStmt();
2222 stmt = parseLetStmt();
2225 stmt = parseReplaceStmt();
2228 stmt = parseReturnStmt();
2231 stmt = parseRewriteStmt();
2238 (expectTerminalSemicolon &&
2245 SMLoc startLoc = curToken.getStartLoc();
2254 return popDeclScope(),
failure();
2255 statements.push_back(*statement);
2260 SMRange location(startLoc, curToken.getEndLoc());
2267 if (parserContext == ParserContext::Constraint)
2268 return emitError(
"`erase` cannot be used within a Constraint");
2269 SMRange loc = curToken.getLoc();
2277 return createEraseStmt(loc, *rootOp);
2281 SMRange loc = curToken.getLoc();
2285 SMRange varLoc = curToken.getLoc();
2290 "`_` may only be used to define \"inline\" variables");
2293 "expected identifier after `let` to name a new variable");
2295 StringRef varName = curToken.getSpelling();
2301 failed(parseVariableDeclConstraintList(constraints)))
2308 if (
failed(initOrFailure))
2310 initializer = *initOrFailure;
2319 if (
auto *typeConstraintExpr = cst->getTypeExpr()) {
2321 constraint.referenceLoc,
2322 "type constraints are not permitted on variables with " 2334 createVariableDecl(varName, varLoc, initializer, constraints);
2341 if (parserContext == ParserContext::Constraint)
2342 return emitError(
"`replace` cannot be used within a Constraint");
2343 SMRange loc = curToken.getLoc();
2352 parseToken(
Token::kw_with,
"expected `with` after root operation")))
2356 llvm::SaveAndRestore<ParserContext> saveCtx(parserContext,
2357 ParserContext::Rewrite);
2364 loc,
"expected at least one replacement value, consider using " 2365 "`erase` if no replacement values are desired");
2372 replValues.emplace_back(*replExpr);
2376 "expected `)` after replacement values")))
2383 replExpr = parseOperationExpr(OpResultTypeContext::Replacement);
2385 replExpr = parseExpr();
2388 replValues.emplace_back(*replExpr);
2391 return createReplaceStmt(loc, *rootOp, replValues);
2395 SMRange loc = curToken.getLoc();
2407 if (parserContext == ParserContext::Constraint)
2408 return emitError(
"`rewrite` cannot be used within a Constraint");
2409 SMRange loc = curToken.getLoc();
2421 return emitError(
"expected `{` to start rewrite body");
2424 llvm::SaveAndRestore<ParserContext> saveCtx(parserContext,
2425 ParserContext::Rewrite);
2432 for (
const ast::Stmt *stmt : (*rewriteBody)->getChildren()) {
2433 if (isa<ast::ReturnStmt>(stmt)) {
2435 "`return` statements are only permitted within a " 2436 "`Constraint` or `Rewrite` body");
2440 return createRewriteStmt(loc, *rootOp, *rewriteBody);
2452 if (
auto *init = dyn_cast<ast::DeclRefExpr>(node))
2453 node = init->getDecl();
2458 Parser::createPatternDecl(SMRange loc,
const ast::Name *name,
2459 const ParsedPatternMetadata &metadata,
2462 metadata.hasBoundedRecursion, body);
2465 ast::Type Parser::createUserConstraintRewriteResultType(
2468 if (results.size() == 1)
2469 return results[0]->getType();
2473 auto resultTypes = llvm::map_range(
2474 results, [&](
const auto *result) {
return result->getType(); });
2475 auto resultNames = llvm::map_range(
2476 results, [&](
const auto *result) {
return result->getName().getName(); });
2478 llvm::to_vector(resultNames));
2481 template <
typename T>
2487 if (
auto *retStmt = dyn_cast<ast::ReturnStmt>(body->
getChildren().back())) {
2488 ast::Expr *resultExpr = retStmt->getResultExpr();
2493 if (results.empty())
2494 resultType = resultExpr->
getType();
2495 else if (
failed(convertExpressionTo(resultExpr, resultType)))
2498 retStmt->setResultExpr(resultExpr);
2501 return T::createPDLL(ctx, name, arguments, results, body, resultType);
2505 Parser::createVariableDecl(StringRef name, SMRange loc,
ast::Expr *initializer,
2510 if (
failed(validateVariableConstraints(constraints, type)))
2517 type = initializer->
getType();
2520 else if (
failed(convertExpressionTo(initializer, type)))
2526 return emitErrorAndNote(
2527 loc,
"unable to infer type for variable `" + name +
"`", loc,
2528 "the type of a variable must be inferable from the constraint " 2529 "list or the initializer");
2535 loc, llvm::formatv(
"unable to define variable of `{0}` type", type));
2540 defineVariableDecl(name, loc, type, initializer, constraints);
2548 Parser::createArgOrResultVariableDecl(StringRef name, SMRange loc,
2551 bool allowNonCoreConstraints = parserContext == ParserContext::Constraint;
2553 if (
failed(validateVariableConstraint(constraint, argType,
2554 allowNonCoreConstraints)))
2556 return defineVariableDecl(name, loc, argType, constraint);
2562 bool allowNonCoreConstraints) {
2564 if (
failed(validateVariableConstraint(ref, inferredType,
2565 allowNonCoreConstraints)))
2572 bool allowNonCoreConstraints) {
2574 if (
const auto *cst = dyn_cast<ast::AttrConstraintDecl>(ref.
constraint)) {
2575 if (
const ast::Expr *typeExpr = cst->getTypeExpr()) {
2576 if (
failed(validateTypeConstraintExpr(typeExpr)))
2580 }
else if (
const auto *cst =
2581 dyn_cast<ast::OpConstraintDecl>(ref.
constraint)) {
2584 }
else if (isa<ast::TypeConstraintDecl>(ref.
constraint)) {
2585 constraintType = typeTy;
2586 }
else if (isa<ast::TypeRangeConstraintDecl>(ref.
constraint)) {
2587 constraintType = typeRangeTy;
2588 }
else if (
const auto *cst =
2589 dyn_cast<ast::ValueConstraintDecl>(ref.
constraint)) {
2590 if (
const ast::Expr *typeExpr = cst->getTypeExpr()) {
2591 if (
failed(validateTypeConstraintExpr(typeExpr)))
2594 constraintType = valueTy;
2595 }
else if (
const auto *cst =
2596 dyn_cast<ast::ValueRangeConstraintDecl>(ref.
constraint)) {
2597 if (
const ast::Expr *typeExpr = cst->getTypeExpr()) {
2598 if (
failed(validateTypeRangeConstraintExpr(typeExpr)))
2601 constraintType = valueRangeTy;
2602 }
else if (
const auto *cst =
2603 dyn_cast<ast::UserConstraintDecl>(ref.
constraint)) {
2604 if (!allowNonCoreConstraints) {
2606 "`Rewrite` arguments and results are only permitted to " 2607 "use core constraints, such as `Attr`, `Op`, `Type`, " 2608 "`TypeRange`, `Value`, `ValueRange`");
2612 if (inputs.size() != 1) {
2614 "`Constraint`s applied via a variable constraint " 2615 "list must take a single input, but got " +
2616 Twine(inputs.size()),
2618 "see definition of constraint here");
2620 constraintType = inputs.front()->getType();
2622 llvm_unreachable(
"unknown constraint type");
2627 if (!inferredType) {
2628 inferredType = constraintType;
2630 inferredType = mergedTy;
2633 llvm::formatv(
"constraint type `{0}` is incompatible " 2634 "with the previously inferred type `{1}`",
2635 constraintType, inferredType));
2642 if (typeExprType != typeTy) {
2644 "expected expression of `Type` in type constraint");
2650 Parser::validateTypeRangeConstraintExpr(
const ast::Expr *typeExpr) {
2652 if (typeExprType != typeRangeTy) {
2654 "expected expression of `TypeRange` in type constraint");
2663 Parser::createCallExpr(SMRange loc,
ast::Expr *parentExpr,
2668 if (!callableDecl) {
2670 llvm::formatv(
"expected a reference to a callable " 2671 "`Constraint` or `Rewrite`, but got: `{0}`",
2674 if (parserContext == ParserContext::Rewrite) {
2675 if (isa<ast::UserConstraintDecl>(callableDecl))
2677 loc,
"unable to invoke `Constraint` within a rewrite section");
2678 }
else if (isa<ast::UserRewriteDecl>(callableDecl)) {
2679 return emitError(loc,
"unable to invoke `Rewrite` within a match section");
2685 if (callArgs.size() != arguments.size()) {
2686 return emitErrorAndNote(
2688 llvm::formatv(
"invalid number of arguments for {0} call; expected " 2693 llvm::formatv(
"see the definition of {0} here",
2699 diag.attachNote(llvm::formatv(
"see the definition of `{0}` here",
2703 for (
auto it : llvm::zip(callArgs, arguments)) {
2704 if (
failed(convertExpressionTo(std::get<1>(it), std::get<0>(it)->getType(),
2717 if (isa<ast::ConstraintDecl>(decl))
2719 else if (isa<ast::UserRewriteDecl>(decl))
2721 else if (
auto *varDecl = dyn_cast<ast::VariableDecl>(decl))
2722 declType = varDecl->getType();
2724 return emitError(loc,
"invalid reference to `" +
2731 Parser::createInlineVariableExpr(
ast::Type type, StringRef name, SMRange loc,
2734 defineVariableDecl(name, loc, type, constraints);
2741 Parser::createMemberAccessExpr(
ast::Expr *parentExpr, StringRef name,
2752 StringRef name, SMRange loc) {
2756 return valueRangeTy;
2764 if (llvm::isDigit(name[0]) && !name.getAsInteger(10, index) &&
2765 index < results.size()) {
2766 return results[index].isVariadic() ? valueRangeTy : valueTy;
2770 const auto *it = llvm::find_if(results, [&](
const auto &result) {
2771 return result.getName() == name;
2773 if (it != results.end())
2774 return it->isVariadic() ? valueRangeTy : valueTy;
2775 }
else if (llvm::isDigit(name[0])) {
2783 if (llvm::isDigit(name[0]) && !name.getAsInteger(10, index) &&
2784 index < tupleType.size()) {
2785 return tupleType.getElementTypes()[index];
2789 auto elementNames = tupleType.getElementNames();
2790 const auto *it = llvm::find(elementNames, name);
2791 if (it != elementNames.end())
2792 return tupleType.getElementTypes()[it - elementNames.begin()];
2796 llvm::formatv(
"invalid member access `{0}` on expression of type `{1}`",
2802 OpResultTypeContext resultTypeContext,
2810 if (
failed(validateOperationOperands(loc, opNameRef, odsOp, operands)))
2816 ast::Type attrType = attr->getValue()->getType();
2819 attr->getValue()->getLoc(),
2820 llvm::formatv(
"expected `Attr` expression, but got `{0}`", attrType));
2825 (resultTypeContext == OpResultTypeContext::Explicit || results.empty()) &&
2826 "unexpected inferrence when results were explicitly specified");
2830 if (resultTypeContext == OpResultTypeContext::Explicit) {
2831 if (
failed(validateOperationResults(loc, opNameRef, odsOp, results)))
2835 }
else if (resultTypeContext == OpResultTypeContext::Interface) {
2837 "expected valid operation name when inferring operation results");
2838 checkOperationResultTypeInferrence(loc, *opNameRef, odsOp);
2849 return validateOperationOperandsOrResults(
2851 operands, odsOp ? odsOp->
getOperands() : llvm::None, valueTy,
2859 return validateOperationOperandsOrResults(
2861 results, odsOp ? odsOp->
getResults() : llvm::None, typeTy, typeRangeTy);
2864 void Parser::checkOperationResultTypeInferrence(SMRange loc, StringRef opName,
2875 "operation result types are marked to be inferred, but " 2876 "`{0}` is unknown. Ensure that `{0}` supports zero " 2877 "results or implements `InferTypeOpInterface`. Include " 2878 "the ODS definition of this operation to remove this warning.",
2887 bool requiresInferrence =
2889 return !result.isVariableLength();
2894 llvm::formatv(
"operation result types are marked to be inferred, but " 2895 "`{0}` does not provide an implementation of " 2896 "`InferTypeOpInterface`. Ensure that `{0}` attaches " 2897 "`InferTypeOpInterface` at runtime, or add support to " 2898 "the ODS definition to remove this warning.",
2900 diag->
attachNote(llvm::formatv(
"see the definition of `{0}` here", opName),
2912 if (values.size() == 1) {
2913 if (
failed(convertExpressionTo(values[0], rangeTy)))
2921 if (odsValues.size() != values.size()) {
2922 return emitErrorAndNote(
2924 llvm::formatv(
"invalid number of {0} groups for `{1}`; expected " 2926 groupName, *name, odsValues.size(), values.size()),
2927 *odsOpLoc, llvm::formatv(
"see the definition of `{0}` here", *name));
2930 diag.attachNote(llvm::formatv(
"see the definition of `{0}` here", *name),
2933 for (
unsigned i = 0, e = values.size(); i < e; ++i) {
2934 ast::Type expectedType = odsValues[i].isVariadic() ? rangeTy : singleTy;
2935 if (
failed(convertExpressionTo(values[i], expectedType, diagFn)))
2944 ast::Type valueExprType = valueExpr->getType();
2947 if (valueExprType == rangeTy || valueExprType == singleTy)
2953 if (singleTy == valueTy) {
2955 valueExpr = convertOpToValue(valueExpr);
2961 valueExpr->getLoc(),
2963 "expected `{0}` or `{1}` convertible expression, but got `{2}`",
2964 singleTy, rangeTy, valueExprType));
2972 for (
const ast::Expr *element : elements) {
2977 llvm::formatv(
"unable to build a tuple with `{0}` element", eleTy));
2997 Parser::createReplaceStmt(SMRange loc,
ast::Expr *rootOp,
3004 llvm::formatv(
"expected `Op` expression, but got `{0}`", rootType));
3009 bool shouldConvertOpToValues = replValues.size() > 1;
3010 for (
ast::Expr *&replExpr : replValues) {
3011 ast::Type replType = replExpr->getType();
3015 if (shouldConvertOpToValues)
3016 replExpr = convertOpToValue(replExpr);
3020 if (replType != valueTy && replType != valueRangeTy) {
3022 llvm::formatv(
"expected `Op`, `Value` or `ValueRange` " 3023 "expression, but got `{0}`",
3032 Parser::createRewriteStmt(SMRange loc,
ast::Expr *rootOp,
3039 llvm::formatv(
"expected `Op` expression, but got `{0}`", rootType));
3065 Parser::codeCompleteConstraintName(
ast::Type inferredType,
3066 bool allowNonCoreConstraints,
3067 bool allowInlineTypeConstraints) {
3069 inferredType, allowNonCoreConstraints, allowInlineTypeConstraints,
3079 LogicalResult Parser::codeCompleteOperationName(StringRef dialectName) {
3089 LogicalResult Parser::codeCompleteIncludeFilename(StringRef curPath) {
3094 void Parser::codeCompleteCallSignature(
ast::Node *parent,
3095 unsigned currentNumArgs) {
3103 void Parser::codeCompleteOperationOperandsSignature(
3106 opName, currentNumOperands);
3110 unsigned currentNumResults) {
3121 bool enableDocumentation,
3123 Parser
parser(ctx, sourceMgr, enableDocumentation, codeCompleteContext);
3124 return parser.parseModule();
static EraseStmt * create(Context &ctx, SMRange loc, Expr *rootOp)
Include the generated interface declarations.
ArrayRef< OperandOrResult > getOperands() const
Returns the operands of this operation.
static ConstraintType get(Context &context)
Return an instance of the Constraint type.
virtual void codeCompletePatternMetadata()
Signal code completion for Pattern metadata.
static std::string diag(llvm::Value &v)
std::string getConditionTemplate() const
virtual void codeCompleteOperationName(StringRef dialectName)
Signal code completion for an operation name in the given dialect.
InFlightDiagnostic emitError(SMRange loc, const Twine &msg)
Emit an error to the diagnostic engine.
ods::Context & getODSContext()
Return the ODS context used by the AST.
static OperationExpr * create(Context &ctx, SMRange loc, const ods::Operation *odsOp, const OpNameDecl *nameDecl, ArrayRef< Expr *> operands, ArrayRef< Expr *> resultTypes, ArrayRef< NamedAttributeDecl *> attributes)
This class represents the main context of the PDLL AST.
This class represents the base of all AST Constraint decls.
StringRef getCallableType() const
Return the callable type of this decl.
static NamedAttributeDecl * create(Context &ctx, const Name &name, Expr *value)
static OperationType get(Context &context, Optional< StringRef > name=llvm::None, const ods::Operation *odsOp=nullptr)
Return an instance of the Operation type with an optional operation name.
bool hasResultTypeInferrence() const
Return if the operation is known to support result type inferrence.
FailureOr< ast::Module * > parsePDLLAST(ast::Context &ctx, llvm::SourceMgr &sourceMgr, bool enableDocumentation=false, CodeCompleteContext *codeCompleteContext=nullptr)
Parse an AST module from the main file of the given source manager.
Token signifying a code completion location.
void appendAttribute(StringRef name, bool optional, const AttributeConstraint &constraint)
Append an attribute to this operation.
static UserConstraintDecl * createNative(Context &ctx, const Name &name, ArrayRef< VariableDecl *> inputs, ArrayRef< VariableDecl *> results, Optional< StringRef > codeBlock, Type resultType, ArrayRef< StringRef > nativeInputTypes={})
Create a native constraint with the given optional code block.
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value...
Token signifying a code completion location within a string.
This class represents a PDLL tuple type, i.e.
This class represents a generic ODS Type constraint.
std::string getUniqueDefName() const
Returns a unique name for the TablGen def of this constraint.
static ReplaceStmt * create(Context &ctx, SMRange loc, Expr *rootOp, ArrayRef< Expr *> replExprs)
static StringRef getMemberName()
Return the member name used for the "all-results" access.
bool isKeyword() const
Return true if this is one of the keyword token kinds (e.g. kw_if).
bool isa() const
Provide type casting support.
ArrayRef< Stmt * >::iterator begin() const
bool succeeded(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a success value...
static ValueType get(Context &context)
Return an instance of the Value type.
static Module * create(Context &ctx, SMLoc loc, ArrayRef< Decl *> children)
StringRef getDescription() const
SMRange getLoc() const
Return the source location of this operation.
static LetStmt * create(Context &ctx, SMRange loc, VariableDecl *varDecl)
This class contains all of the registered ODS operation classes.
SMRange getLoc() const
Return the location of this node.
static const Name & create(Context &ctx, StringRef name, SMRange location)
static constexpr const bool value
This class represents the base Decl node.
The class represents an Attribute constraint, and constrains a variable to be an Attribute.
Format context containing substitutions for special placeholders.
static AttrConstraintDecl * create(Context &ctx, SMRange loc, Expr *typeExpr=nullptr)
virtual void codeCompleteDialectName()
Signal code completion for a dialect name.
This class represents a scope for named AST decls.
static VariableDecl * create(Context &ctx, const Name &name, Type type, Expr *initExpr, ArrayRef< ConstraintRef > constraints)
StringRef getName() const
Return the raw string name.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
static TupleType get(Context &context, ArrayRef< Type > elementTypes, ArrayRef< StringRef > elementNames)
Return an instance of the Tuple type.
Type getType() const
Return the type of this expression.
This class represents an efficient way to signal success or failure.
const ConstraintDecl * constraint
virtual void codeCompleteIncludeFilename(StringRef curPath)
Signal code completion for an include filename.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
This class provides support for representing a failure result, or a valid value of type T...
Type refineWith(Type other) const
Try to refine this type with the one provided.
The class represents a ValueRange constraint, and constrains a variable to be a ValueRange.
static RewriteType get(Context &context)
Return an instance of the Rewrite type.
FmtContext & withSelf(Twine subst)
const Name * getName() const
Return the name of the decl, or nullptr if it doesn't have one.
This class represents a base AST Statement node.
static ReturnStmt * create(Context &ctx, SMRange loc, Expr *resultExpr)
std::pair< Operation *, bool > insertOperation(StringRef name, StringRef summary, StringRef desc, StringRef nativeClassName, bool supportsResultTypeInferrence, SMLoc loc)
Insert a new operation with the context.
const Operation * lookupOperation(StringRef name) const
Lookup an operation registered with the given name, or null if no operation with that name is registe...
static CompoundStmt * create(Context &ctx, SMRange location, ArrayRef< Stmt *> children)
This class represents a PDLL type that corresponds to an mlir::Attribute.
void appendResult(StringRef name, VariableLengthKind variableLengthKind, const TypeConstraint &constraint)
Append a result to this operation.
ArrayRef< OperandOrResult > getResults() const
Returns the results of this operation.
This class represents a reference to a constraint, and contains a constraint and the location of the ...
This class provides a simple implementation of a PDLL diagnostic.
static TypeRangeConstraintDecl * create(Context &ctx, SMRange loc)
static TypeExpr * create(Context &ctx, SMRange loc, StringRef value)
void appendOperand(StringRef name, VariableLengthKind variableLengthKind, const TypeConstraint &constraint)
Append an operand to this operation.
virtual void codeCompleteOperationOperandsSignature(Optional< StringRef > opName, unsigned currentNumOperands)
Signal code completion for the signature of an operation's operands.
const AttributeConstraint & insertAttributeConstraint(StringRef name, StringRef summary, StringRef cppClass)
Insert a new attribute constraint with the context.
ArrayRef< VariableDecl * > getInputs() const
Return the inputs of this decl.
static TypeType get(Context &context)
Return an instance of the Type type.
This class represents a PDLL type that corresponds to a constraint.
This class represents a base AST node.
void add(Decl *decl)
Add a new decl to the scope.
The class represents a Value constraint, and constrains a variable to be a Value. ...
This decl represents a shared interface for all callable decls.
virtual void codeCompleteOperationAttributeName(StringRef opName)
Signal code completion for a member access into the given operation type.
raw_indented_ostream & printReindented(StringRef str)
Prints a string re-indented to the current indent.
This class represents a diagnostic that is inflight and set to be reported.
virtual void codeCompleteOperationMemberAccess(ast::OperationType opType)
Signal code completion for a member access into the given operation type.
This class provides an abstract interface into the parser for hooking in code completion events...
virtual void codeCompleteConstraintName(ast::Type currentType, bool allowNonCoreConstraints, bool allowInlineTypeConstraints, const ast::DeclScope *scope)
Signal code completion for a constraint name with an optional decl scope.
This class represents a PDLL type that corresponds to a rewrite reference.
StringRef getSpelling() const
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
Diagnostic & attachNote(const Twine &msg, Optional< SMRange > noteLoc=llvm::None)
Attach a note to this diagnostic.
This Decl represents a NamedAttribute, and contains a string name and attribute value.
This class provides an ODS representation of a specific operation.
static ValueRangeType get(Context &context)
Return an instance of the ValueRange type.
static MemberAccessExpr * create(Context &ctx, SMRange loc, const Expr *parentExpr, StringRef memberName, Type type)
This class provides a convenient API for interacting with source names.
virtual void codeCompleteTupleMemberAccess(ast::TupleType tupleType)
Signal code completion for a member access into the given tuple type.
Optional< StringRef > getName() const
Return the name of this operation, or none if the name is unknown.
static ValueConstraintDecl * create(Context &ctx, SMRange loc, Expr *typeExpr)
virtual void codeCompleteCallSignature(const ast::CallableDecl *callable, unsigned currentNumArgs)
Signal code completion for the signature of a callable.
DeclScope * getParentScope()
Return the parent scope of this scope, or nullptr if there is no parent.
static TupleExpr * create(Context &ctx, SMRange loc, ArrayRef< Expr *> elements, ArrayRef< StringRef > elementNames)
static TypeConstraintDecl * create(Context &ctx, SMRange loc)
auto tgfmt(StringRef fmt, const FmtContext *ctx, Ts &&...vals) -> FmtObject< decltype(std::make_tuple(llvm::detail::build_format_adapter(std::forward< Ts >(vals))...))>
Formats text by substituting placeholders in format string with replacement parameters.
This class provides an ODS representation of a specific operation operand or result.
virtual void codeCompleteOperationResultsSignature(Optional< StringRef > opName, unsigned currentNumResults)
Signal code completion for the signature of an operation's results.
MutableArrayRef< Stmt * > getChildren()
Return the children of this compound statement.
static OpConstraintDecl * create(Context &ctx, SMRange loc, const OpNameDecl *nameDecl=nullptr)
StringRef getSummary() const
Type getResultType() const
Return the result type of this decl.
static PatternDecl * create(Context &ctx, SMRange location, const Name *name, Optional< uint16_t > benefit, bool hasBoundedRecursion, const CompoundStmt *body)
DiagnosticEngine & getDiagEngine()
Return the diagnostic engine of this context.
const TypeConstraint & insertTypeConstraint(StringRef name, StringRef summary, StringRef cppClass)
Insert a new type constraint with the context.
This Decl represents an OperationName.
static OpNameDecl * create(Context &ctx, const Name &name)
static CallExpr * create(Context &ctx, SMRange loc, Expr *callable, ArrayRef< Expr *> arguments, Type resultType)
static AttributeType get(Context &context)
Return an instance of the Attribute type.
static AttributeExpr * create(Context &ctx, SMRange loc, StringRef value)
static DeclRefExpr * create(Context &ctx, SMRange loc, Decl *decl, Type type)
static RewriteStmt * create(Context &ctx, SMRange loc, Expr *rootOp, CompoundStmt *rewriteBody)
raw_ostream subclass that simplifies indention a sequence of code.
This statement represents a compound statement, which contains a collection of other statements...
SMRange getLoc() const
Get the location of this name.
static ValueRangeConstraintDecl * create(Context &ctx, SMRange loc, Expr *typeExpr=nullptr)
This class represents a base AST Expression node.
static TypeRangeType get(Context &context)
Return an instance of the TypeRange type.
InFlightDiagnostic emitWarning(SMRange loc, const Twine &msg)
ArrayRef< Stmt * >::iterator end() const
This class represents a PDLL type that corresponds to an mlir::Operation.
static AllResultsMemberAccessExpr * create(Context &ctx, SMRange loc, const Expr *parentExpr, Type type)
This class breaks up the current file into a token stream.
This represents a token in the MLIR syntax.