1 //===- OpFormatGen.cpp - MLIR operation asm format generator --------------===//
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 "OpFormatGen.h"
10 #include "mlir/ADT/TypeSwitch.h"
11 #include "mlir/Support/LogicalResult.h"
12 #include "mlir/Support/STLExtras.h"
13 #include "mlir/TableGen/Format.h"
14 #include "mlir/TableGen/GenInfo.h"
15 #include "mlir/TableGen/OpClass.h"
16 #include "mlir/TableGen/OpInterfaces.h"
17 #include "mlir/TableGen/OpTrait.h"
18 #include "mlir/TableGen/Operator.h"
19 #include "llvm/ADT/MapVector.h"
20 #include "llvm/ADT/Sequence.h"
21 #include "llvm/ADT/SmallBitVector.h"
22 #include "llvm/ADT/StringExtras.h"
23 #include "llvm/Support/CommandLine.h"
24 #include "llvm/Support/Signals.h"
25 #include "llvm/TableGen/Error.h"
26 #include "llvm/TableGen/Record.h"
27 
28 #define DEBUG_TYPE "mlir-tblgen-opformatgen"
29 
30 using namespace mlir;
31 using namespace mlir::tblgen;
32 
33 static llvm::cl::opt<bool> formatErrorIsFatal(
34     "asmformat-error-is-fatal",
35     llvm::cl::desc("Emit a fatal error if format parsing fails"),
36     llvm::cl::init(true));
37 
38 //===----------------------------------------------------------------------===//
39 // Element
40 //===----------------------------------------------------------------------===//
41 
42 namespace {
43 /// This class represents a single format element.
44 class Element {
45 public:
46   enum class Kind {
47     /// This element is a directive.
48     AttrDictDirective,
49     FunctionalTypeDirective,
50     OperandsDirective,
51     ResultsDirective,
52     SuccessorsDirective,
53     TypeDirective,
54 
55     /// This element is a literal.
56     Literal,
57 
58     /// This element is an variable value.
59     AttributeVariable,
60     OperandVariable,
61     ResultVariable,
62     SuccessorVariable,
63 
64     /// This element is an optional element.
65     Optional,
66   };
67   Element(Kind kind) : kind(kind) {}
68   virtual ~Element() = default;
69 
70   /// Return the kind of this element.
71   Kind getKind() const { return kind; }
72 
73 private:
74   /// The kind of this element.
75   Kind kind;
76 };
77 } // namespace
78 
79 //===----------------------------------------------------------------------===//
80 // VariableElement
81 
82 namespace {
83 /// This class represents an instance of an variable element. A variable refers
84 /// to something registered on the operation itself, e.g. an argument, result,
85 /// etc.
86 template <typename VarT, Element::Kind kindVal>
87 class VariableElement : public Element {
88 public:
89   VariableElement(const VarT *var) : Element(kindVal), var(var) {}
90   static bool classof(const Element *element) {
91     return element->getKind() == kindVal;
92   }
93   const VarT *getVar() { return var; }
94 
95 protected:
96   const VarT *var;
97 };
98 
99 /// This class represents a variable that refers to an attribute argument.
100 struct AttributeVariable
101     : public VariableElement<NamedAttribute, Element::Kind::AttributeVariable> {
102   using VariableElement<NamedAttribute,
103                         Element::Kind::AttributeVariable>::VariableElement;
104 
105   /// Return the constant builder call for the type of this attribute, or None
106   /// if it doesn't have one.
107   Optional<StringRef> getTypeBuilder() const {
108     Optional<Type> attrType = var->attr.getValueType();
109     return attrType ? attrType->getBuilderCall() : llvm::None;
110   }
111 };
112 
113 /// This class represents a variable that refers to an operand argument.
114 using OperandVariable =
115     VariableElement<NamedTypeConstraint, Element::Kind::OperandVariable>;
116 
117 /// This class represents a variable that refers to a result.
118 using ResultVariable =
119     VariableElement<NamedTypeConstraint, Element::Kind::ResultVariable>;
120 
121 /// This class represents a variable that refers to a successor.
122 using SuccessorVariable =
123     VariableElement<NamedSuccessor, Element::Kind::SuccessorVariable>;
124 } // end anonymous namespace
125 
126 //===----------------------------------------------------------------------===//
127 // DirectiveElement
128 
129 namespace {
130 /// This class implements single kind directives.
131 template <Element::Kind type>
132 class DirectiveElement : public Element {
133 public:
134   DirectiveElement() : Element(type){};
135   static bool classof(const Element *ele) { return ele->getKind() == type; }
136 };
137 /// This class represents the `operands` directive. This directive represents
138 /// all of the operands of an operation.
139 using OperandsDirective = DirectiveElement<Element::Kind::OperandsDirective>;
140 
141 /// This class represents the `results` directive. This directive represents
142 /// all of the results of an operation.
143 using ResultsDirective = DirectiveElement<Element::Kind::ResultsDirective>;
144 
145 /// This class represents the `successors` directive. This directive represents
146 /// all of the successors of an operation.
147 using SuccessorsDirective =
148     DirectiveElement<Element::Kind::SuccessorsDirective>;
149 
150 /// This class represents the `attr-dict` directive. This directive represents
151 /// the attribute dictionary of the operation.
152 class AttrDictDirective
153     : public DirectiveElement<Element::Kind::AttrDictDirective> {
154 public:
155   explicit AttrDictDirective(bool withKeyword) : withKeyword(withKeyword) {}
156   bool isWithKeyword() const { return withKeyword; }
157 
158 private:
159   /// If the dictionary should be printed with the 'attributes' keyword.
160   bool withKeyword;
161 };
162 
163 /// This class represents the `functional-type` directive. This directive takes
164 /// two arguments and formats them, respectively, as the inputs and results of a
165 /// FunctionType.
166 class FunctionalTypeDirective
167     : public DirectiveElement<Element::Kind::FunctionalTypeDirective> {
168 public:
169   FunctionalTypeDirective(std::unique_ptr<Element> inputs,
170                           std::unique_ptr<Element> results)
171       : inputs(std::move(inputs)), results(std::move(results)) {}
172   Element *getInputs() const { return inputs.get(); }
173   Element *getResults() const { return results.get(); }
174 
175 private:
176   /// The input and result arguments.
177   std::unique_ptr<Element> inputs, results;
178 };
179 
180 /// This class represents the `type` directive.
181 class TypeDirective : public DirectiveElement<Element::Kind::TypeDirective> {
182 public:
183   TypeDirective(std::unique_ptr<Element> arg) : operand(std::move(arg)) {}
184   Element *getOperand() const { return operand.get(); }
185 
186 private:
187   /// The operand that is used to format the directive.
188   std::unique_ptr<Element> operand;
189 };
190 } // end anonymous namespace
191 
192 //===----------------------------------------------------------------------===//
193 // LiteralElement
194 
195 namespace {
196 /// This class represents an instance of a literal element.
197 class LiteralElement : public Element {
198 public:
199   LiteralElement(StringRef literal)
200       : Element{Kind::Literal}, literal(literal) {}
201   static bool classof(const Element *element) {
202     return element->getKind() == Kind::Literal;
203   }
204 
205   /// Return the literal for this element.
206   StringRef getLiteral() const { return literal; }
207 
208   /// Returns true if the given string is a valid literal.
209   static bool isValidLiteral(StringRef value);
210 
211 private:
212   /// The spelling of the literal for this element.
213   StringRef literal;
214 };
215 } // end anonymous namespace
216 
217 bool LiteralElement::isValidLiteral(StringRef value) {
218   if (value.empty())
219     return false;
220   char front = value.front();
221 
222   // If there is only one character, this must either be punctuation or a
223   // single character bare identifier.
224   if (value.size() == 1)
225     return isalpha(front) || StringRef("_:,=<>()[]").contains(front);
226 
227   // Check the punctuation that are larger than a single character.
228   if (value == "->")
229     return true;
230 
231   // Otherwise, this must be an identifier.
232   if (!isalpha(front) && front != '_')
233     return false;
234   return llvm::all_of(value.drop_front(), [](char c) {
235     return isalnum(c) || c == '_' || c == '$' || c == '.';
236   });
237 }
238 
239 //===----------------------------------------------------------------------===//
240 // OptionalElement
241 
242 namespace {
243 /// This class represents a group of elements that are optionally emitted based
244 /// upon an optional variable of the operation.
245 class OptionalElement : public Element {
246 public:
247   OptionalElement(std::vector<std::unique_ptr<Element>> &&elements,
248                   unsigned anchor)
249       : Element{Kind::Optional}, elements(std::move(elements)), anchor(anchor) {
250   }
251   static bool classof(const Element *element) {
252     return element->getKind() == Kind::Optional;
253   }
254 
255   /// Return the nested elements of this grouping.
256   auto getElements() const { return llvm::make_pointee_range(elements); }
257 
258   /// Return the anchor of this optional group.
259   Element *getAnchor() const { return elements[anchor].get(); }
260 
261 private:
262   /// The child elements of this optional.
263   std::vector<std::unique_ptr<Element>> elements;
264   /// The index of the element that acts as the anchor for the optional group.
265   unsigned anchor;
266 };
267 } // end anonymous namespace
268 
269 //===----------------------------------------------------------------------===//
270 // OperationFormat
271 //===----------------------------------------------------------------------===//
272 
273 namespace {
274 struct OperationFormat {
275   /// This class represents a specific resolver for an operand or result type.
276   class TypeResolution {
277   public:
278     TypeResolution() = default;
279 
280     /// Get the index into the buildable types for this type, or None.
281     Optional<int> getBuilderIdx() const { return builderIdx; }
282     void setBuilderIdx(int idx) { builderIdx = idx; }
283 
284     /// Get the variable this type is resolved to, or None.
285     const NamedTypeConstraint *getVariable() const { return variable; }
286     Optional<StringRef> getVarTransformer() const {
287       return variableTransformer;
288     }
289     void setVariable(const NamedTypeConstraint *var,
290                      Optional<StringRef> transformer) {
291       variable = var;
292       variableTransformer = transformer;
293     }
294 
295   private:
296     /// If the type is resolved with a buildable type, this is the index into
297     /// 'buildableTypes' in the parent format.
298     Optional<int> builderIdx;
299     /// If the type is resolved based upon another operand or result, this is
300     /// the variable that this type is resolved to.
301     const NamedTypeConstraint *variable;
302     /// If the type is resolved based upon another operand or result, this is
303     /// a transformer to apply to the variable when resolving.
304     Optional<StringRef> variableTransformer;
305   };
306 
307   OperationFormat(const Operator &op)
308       : allOperands(false), allOperandTypes(false), allResultTypes(false) {
309     operandTypes.resize(op.getNumOperands(), TypeResolution());
310     resultTypes.resize(op.getNumResults(), TypeResolution());
311   }
312 
313   /// Generate the operation parser from this format.
314   void genParser(Operator &op, OpClass &opClass);
315   /// Generate the c++ to resolve the types of operands and results during
316   /// parsing.
317   void genParserTypeResolution(Operator &op, OpMethodBody &body);
318   /// Generate the c++ to resolve successors during parsing.
319   void genParserSuccessorResolution(Operator &op, OpMethodBody &body);
320   /// Generate the c++ to handling variadic segment size traits.
321   void genParserVariadicSegmentResolution(Operator &op, OpMethodBody &body);
322 
323   /// Generate the operation printer from this format.
324   void genPrinter(Operator &op, OpClass &opClass);
325 
326   /// The various elements in this format.
327   std::vector<std::unique_ptr<Element>> elements;
328 
329   /// A flag indicating if all operand/result types were seen. If the format
330   /// contains these, it can not contain individual type resolvers.
331   bool allOperands, allOperandTypes, allResultTypes;
332 
333   /// A map of buildable types to indices.
334   llvm::MapVector<StringRef, int, llvm::StringMap<int>> buildableTypes;
335 
336   /// The index of the buildable type, if valid, for every operand and result.
337   std::vector<TypeResolution> operandTypes, resultTypes;
338 };
339 } // end anonymous namespace
340 
341 //===----------------------------------------------------------------------===//
342 // Parser Gen
343 
344 /// Returns if we can format the given attribute as an EnumAttr in the parser
345 /// format.
346 static bool canFormatEnumAttr(const NamedAttribute *attr) {
347   const EnumAttr *enumAttr = dyn_cast<EnumAttr>(&attr->attr);
348   if (!enumAttr)
349     return false;
350 
351   // The attribute must have a valid underlying type and a constant builder.
352   return !enumAttr->getUnderlyingType().empty() &&
353          !enumAttr->getConstBuilderTemplate().empty();
354 }
355 
356 /// The code snippet used to generate a parser call for an attribute.
357 ///
358 /// {0}: The storage type of the attribute.
359 /// {1}: The name of the attribute.
360 /// {2}: The type for the attribute.
361 const char *const attrParserCode = R"(
362   {0} {1}Attr;
363   if (parser.parseAttribute({1}Attr{2}, "{1}", result.attributes))
364     return failure();
365 )";
366 
367 /// The code snippet used to generate a parser call for an enum attribute.
368 ///
369 /// {0}: The name of the attribute.
370 /// {1}: The c++ namespace for the enum symbolize functions.
371 /// {2}: The function to symbolize a string of the enum.
372 /// {3}: The constant builder call to create an attribute of the enum type.
373 const char *const enumAttrParserCode = R"(
374   {
375     StringAttr attrVal;
376     SmallVector<NamedAttribute, 1> attrStorage;
377     auto loc = parser.getCurrentLocation();
378     if (parser.parseAttribute(attrVal, parser.getBuilder().getNoneType(),
379                               "{0}", attrStorage))
380       return failure();
381 
382     auto attrOptional = {1}::{2}(attrVal.getValue());
383     if (!attrOptional)
384       return parser.emitError(loc, "invalid ")
385              << "{0} attribute specification: " << attrVal;
386 
387     result.addAttribute("{0}", {3});
388   }
389 )";
390 
391 /// The code snippet used to generate a parser call for an operand.
392 ///
393 /// {0}: The name of the operand.
394 const char *const variadicOperandParserCode = R"(
395   if (parser.parseOperandList({0}Operands))
396     return failure();
397 )";
398 const char *const operandParserCode = R"(
399   if (parser.parseOperand({0}RawOperands[0]))
400     return failure();
401 )";
402 
403 /// The code snippet used to generate a parser call for a type list.
404 ///
405 /// {0}: The name for the type list.
406 const char *const variadicTypeParserCode = R"(
407   if (parser.parseTypeList({0}Types))
408     return failure();
409 )";
410 const char *const typeParserCode = R"(
411   if (parser.parseType({0}RawTypes[0]))
412     return failure();
413 )";
414 
415 /// The code snippet used to generate a parser call for a functional type.
416 ///
417 /// {0}: The name for the input type list.
418 /// {1}: The name for the result type list.
419 const char *const functionalTypeParserCode = R"(
420   FunctionType {0}__{1}_functionType;
421   if (parser.parseType({0}__{1}_functionType))
422     return failure();
423   {0}Types = {0}__{1}_functionType.getInputs();
424   {1}Types = {0}__{1}_functionType.getResults();
425 )";
426 
427 /// The code snippet used to generate a parser call for a successor list.
428 ///
429 /// {0}: The name for the successor list.
430 const char *successorListParserCode = R"(
431   SmallVector<Block *, 2> {0}Successors;
432   {
433     Block *succ;
434     auto firstSucc = parser.parseOptionalSuccessor(succ);
435     if (firstSucc.hasValue()) {
436       if (failed(*firstSucc))
437         return failure();
438       {0}Successors.emplace_back(succ);
439 
440       // Parse any trailing successors.
441       while (succeeded(parser.parseOptionalComma())) {
442         if (parser.parseSuccessor(succ))
443           return failure();
444         {0}Successors.emplace_back(succ);
445       }
446     }
447   }
448 )";
449 
450 /// The code snippet used to generate a parser call for a successor.
451 ///
452 /// {0}: The name of the successor.
453 const char *successorParserCode = R"(
454   Block *{0}Successor = nullptr;
455   if (parser.parseSuccessor({0}Successor))
456     return failure();
457 )";
458 
459 /// Get the name used for the type list for the given type directive operand.
460 /// 'isVariadic' is set to true if the operand has variadic types.
461 static StringRef getTypeListName(Element *arg, bool &isVariadic) {
462   if (auto *operand = dyn_cast<OperandVariable>(arg)) {
463     isVariadic = operand->getVar()->isVariadic();
464     return operand->getVar()->name;
465   }
466   if (auto *result = dyn_cast<ResultVariable>(arg)) {
467     isVariadic = result->getVar()->isVariadic();
468     return result->getVar()->name;
469   }
470   isVariadic = true;
471   if (isa<OperandsDirective>(arg))
472     return "allOperand";
473   if (isa<ResultsDirective>(arg))
474     return "allResult";
475   llvm_unreachable("unknown 'type' directive argument");
476 }
477 
478 /// Generate the parser for a literal value.
479 static void genLiteralParser(StringRef value, OpMethodBody &body) {
480   // Handle the case of a keyword/identifier.
481   if (value.front() == '_' || isalpha(value.front())) {
482     body << "Keyword(\"" << value << "\")";
483     return;
484   }
485   body << (StringRef)llvm::StringSwitch<StringRef>(value)
486               .Case("->", "Arrow()")
487               .Case(":", "Colon()")
488               .Case(",", "Comma()")
489               .Case("=", "Equal()")
490               .Case("<", "Less()")
491               .Case(">", "Greater()")
492               .Case("(", "LParen()")
493               .Case(")", "RParen()")
494               .Case("[", "LSquare()")
495               .Case("]", "RSquare()");
496 }
497 
498 /// Generate the storage code required for parsing the given element.
499 static void genElementParserStorage(Element *element, OpMethodBody &body) {
500   if (auto *optional = dyn_cast<OptionalElement>(element)) {
501     for (auto &childElement : optional->getElements())
502       genElementParserStorage(&childElement, body);
503   } else if (auto *operand = dyn_cast<OperandVariable>(element)) {
504     StringRef name = operand->getVar()->name;
505     if (operand->getVar()->isVariadic()) {
506       body << "  SmallVector<OpAsmParser::OperandType, 4> " << name
507            << "Operands;\n";
508     } else {
509       body << "  OpAsmParser::OperandType " << name << "RawOperands[1];\n"
510            << "  ArrayRef<OpAsmParser::OperandType> " << name << "Operands("
511            << name << "RawOperands);";
512     }
513     body << llvm::formatv(
514         "  llvm::SMLoc {0}OperandsLoc = parser.getCurrentLocation();\n"
515         "  (void){0}OperandsLoc;\n",
516         name);
517   } else if (auto *dir = dyn_cast<TypeDirective>(element)) {
518     bool variadic = false;
519     StringRef name = getTypeListName(dir->getOperand(), variadic);
520     if (variadic)
521       body << "  SmallVector<Type, 1> " << name << "Types;\n";
522     else
523       body << llvm::formatv("  Type {0}RawTypes[1];\n", name)
524            << llvm::formatv("  ArrayRef<Type> {0}Types({0}RawTypes);\n", name);
525   } else if (auto *dir = dyn_cast<FunctionalTypeDirective>(element)) {
526     bool ignored = false;
527     body << "  ArrayRef<Type> " << getTypeListName(dir->getInputs(), ignored)
528          << "Types;\n";
529     body << "  ArrayRef<Type> " << getTypeListName(dir->getResults(), ignored)
530          << "Types;\n";
531   }
532 }
533 
534 /// Generate the parser for a single format element.
535 static void genElementParser(Element *element, OpMethodBody &body,
536                              FmtContext &attrTypeCtx) {
537   /// Optional Group.
538   if (auto *optional = dyn_cast<OptionalElement>(element)) {
539     auto elements = optional->getElements();
540 
541     // Generate a special optional parser for the first element to gate the
542     // parsing of the rest of the elements.
543     if (auto *literal = dyn_cast<LiteralElement>(&*elements.begin())) {
544       body << "  if (succeeded(parser.parseOptional";
545       genLiteralParser(literal->getLiteral(), body);
546       body << ")) {\n";
547     } else if (auto *opVar = dyn_cast<OperandVariable>(&*elements.begin())) {
548       genElementParser(opVar, body, attrTypeCtx);
549       body << "  if (!" << opVar->getVar()->name << "Operands.empty()) {\n";
550     }
551 
552     // Generate the rest of the elements normally.
553     for (auto &childElement : llvm::drop_begin(elements, 1))
554       genElementParser(&childElement, body, attrTypeCtx);
555     body << "  }\n";
556 
557     /// Literals.
558   } else if (LiteralElement *literal = dyn_cast<LiteralElement>(element)) {
559     body << "  if (parser.parse";
560     genLiteralParser(literal->getLiteral(), body);
561     body << ")\n    return failure();\n";
562 
563     /// Arguments.
564   } else if (auto *attr = dyn_cast<AttributeVariable>(element)) {
565     const NamedAttribute *var = attr->getVar();
566 
567     // Check to see if we can parse this as an enum attribute.
568     if (canFormatEnumAttr(var)) {
569       const EnumAttr &enumAttr = cast<EnumAttr>(var->attr);
570 
571       // Generate the code for building an attribute for this enum.
572       std::string attrBuilderStr;
573       {
574         llvm::raw_string_ostream os(attrBuilderStr);
575         os << tgfmt(enumAttr.getConstBuilderTemplate(), &attrTypeCtx,
576                     "attrOptional.getValue()");
577       }
578 
579       body << formatv(enumAttrParserCode, var->name, enumAttr.getCppNamespace(),
580                       enumAttr.getStringToSymbolFnName(), attrBuilderStr);
581       return;
582     }
583 
584     // If this attribute has a buildable type, use that when parsing the
585     // attribute.
586     std::string attrTypeStr;
587     if (Optional<StringRef> typeBuilder = attr->getTypeBuilder()) {
588       llvm::raw_string_ostream os(attrTypeStr);
589       os << ", " << tgfmt(*typeBuilder, &attrTypeCtx);
590     }
591 
592     body << formatv(attrParserCode, var->attr.getStorageType(), var->name,
593                     attrTypeStr);
594   } else if (auto *operand = dyn_cast<OperandVariable>(element)) {
595     bool isVariadic = operand->getVar()->isVariadic();
596     body << formatv(isVariadic ? variadicOperandParserCode : operandParserCode,
597                     operand->getVar()->name);
598   } else if (auto *successor = dyn_cast<SuccessorVariable>(element)) {
599     bool isVariadic = successor->getVar()->isVariadic();
600     body << formatv(isVariadic ? successorListParserCode : successorParserCode,
601                     successor->getVar()->name);
602 
603     /// Directives.
604   } else if (auto *attrDict = dyn_cast<AttrDictDirective>(element)) {
605     body << "  if (parser.parseOptionalAttrDict"
606          << (attrDict->isWithKeyword() ? "WithKeyword" : "")
607          << "(result.attributes))\n"
608          << "    return failure();\n";
609   } else if (isa<OperandsDirective>(element)) {
610     body << "  llvm::SMLoc allOperandLoc = parser.getCurrentLocation();\n"
611          << "  SmallVector<OpAsmParser::OperandType, 4> allOperands;\n"
612          << "  if (parser.parseOperandList(allOperands))\n"
613          << "    return failure();\n";
614   } else if (isa<SuccessorsDirective>(element)) {
615     body << llvm::formatv(successorListParserCode, "full");
616   } else if (auto *dir = dyn_cast<TypeDirective>(element)) {
617     bool isVariadic = false;
618     StringRef listName = getTypeListName(dir->getOperand(), isVariadic);
619     body << formatv(isVariadic ? variadicTypeParserCode : typeParserCode,
620                     listName);
621   } else if (auto *dir = dyn_cast<FunctionalTypeDirective>(element)) {
622     bool ignored = false;
623     body << formatv(functionalTypeParserCode,
624                     getTypeListName(dir->getInputs(), ignored),
625                     getTypeListName(dir->getResults(), ignored));
626   } else {
627     llvm_unreachable("unknown format element");
628   }
629 }
630 
631 void OperationFormat::genParser(Operator &op, OpClass &opClass) {
632   auto &method = opClass.newMethod(
633       "ParseResult", "parse", "OpAsmParser &parser, OperationState &result",
634       OpMethod::MP_Static);
635   auto &body = method.body();
636 
637   // Generate variables to store the operands and type within the format. This
638   // allows for referencing these variables in the presence of optional
639   // groupings.
640   for (auto &element : elements)
641     genElementParserStorage(&*element, body);
642 
643   // A format context used when parsing attributes with buildable types.
644   FmtContext attrTypeCtx;
645   attrTypeCtx.withBuilder("parser.getBuilder()");
646 
647   // Generate parsers for each of the elements.
648   for (auto &element : elements)
649     genElementParser(element.get(), body, attrTypeCtx);
650 
651   // Generate the code to resolve the operand/result types and successors now
652   // that they have been parsed.
653   genParserTypeResolution(op, body);
654   genParserSuccessorResolution(op, body);
655   genParserVariadicSegmentResolution(op, body);
656 
657   body << "  return success();\n";
658 }
659 
660 void OperationFormat::genParserTypeResolution(Operator &op,
661                                               OpMethodBody &body) {
662   // If any of type resolutions use transformed variables, make sure that the
663   // types of those variables are resolved.
664   SmallPtrSet<const NamedTypeConstraint *, 8> verifiedVariables;
665   FmtContext verifierFCtx;
666   for (TypeResolution &resolver :
667        llvm::concat<TypeResolution>(resultTypes, operandTypes)) {
668     Optional<StringRef> transformer = resolver.getVarTransformer();
669     if (!transformer)
670       continue;
671     // Ensure that we don't verify the same variables twice.
672     const NamedTypeConstraint *variable = resolver.getVariable();
673     if (!verifiedVariables.insert(variable).second)
674       continue;
675 
676     auto constraint = variable->constraint;
677     body << "  for (Type type : " << variable->name << "Types) {\n"
678          << "    (void)type;\n"
679          << "    if (!("
680          << tgfmt(constraint.getConditionTemplate(),
681                   &verifierFCtx.withSelf("type"))
682          << ")) {\n"
683          << formatv("      return parser.emitError(parser.getNameLoc()) << "
684                     "\"'{0}' must be {1}, but got \" << type;\n",
685                     variable->name, constraint.getDescription())
686          << "    }\n"
687          << "  }\n";
688   }
689 
690   // Initialize the set of buildable types.
691   if (!buildableTypes.empty()) {
692     body << "  Builder &builder = parser.getBuilder();\n";
693 
694     FmtContext typeBuilderCtx;
695     typeBuilderCtx.withBuilder("builder");
696     for (auto &it : buildableTypes)
697       body << "  Type odsBuildableType" << it.second << " = "
698            << tgfmt(it.first, &typeBuilderCtx) << ";\n";
699   }
700 
701   // Emit the code necessary for a type resolver.
702   auto emitTypeResolver = [&](TypeResolution &resolver, StringRef curVar) {
703     if (Optional<int> val = resolver.getBuilderIdx()) {
704       body << "odsBuildableType" << *val;
705     } else if (const NamedTypeConstraint *var = resolver.getVariable()) {
706       if (Optional<StringRef> tform = resolver.getVarTransformer())
707         body << tgfmt(*tform, &FmtContext().withSelf(var->name + "Types[0]"));
708       else
709         body << var->name << "Types";
710     } else {
711       body << curVar << "Types";
712     }
713   };
714 
715   // Resolve each of the result types.
716   if (allResultTypes) {
717     body << "  result.addTypes(allResultTypes);\n";
718   } else {
719     for (unsigned i = 0, e = op.getNumResults(); i != e; ++i) {
720       body << "  result.addTypes(";
721       emitTypeResolver(resultTypes[i], op.getResultName(i));
722       body << ");\n";
723     }
724   }
725 
726   // Early exit if there are no operands.
727   if (op.getNumOperands() == 0)
728     return;
729 
730   // Handle the case where all operand types are in one group.
731   if (allOperandTypes) {
732     // If we have all operands together, use the full operand list directly.
733     if (allOperands) {
734       body << "  if (parser.resolveOperands(allOperands, allOperandTypes, "
735               "allOperandLoc, result.operands))\n"
736               "    return failure();\n";
737       return;
738     }
739 
740     // Otherwise, use llvm::concat to merge the disjoint operand lists together.
741     // llvm::concat does not allow the case of a single range, so guard it here.
742     body << "  if (parser.resolveOperands(";
743     if (op.getNumOperands() > 1) {
744       body << "llvm::concat<const OpAsmParser::OperandType>(";
745       interleaveComma(op.getOperands(), body, [&](auto &operand) {
746         body << operand.name << "Operands";
747       });
748       body << ")";
749     } else {
750       body << op.operand_begin()->name << "Operands";
751     }
752     body << ", allOperandTypes, parser.getNameLoc(), result.operands))\n"
753          << "    return failure();\n";
754     return;
755   }
756   // Handle the case where all of the operands were grouped together.
757   if (allOperands) {
758     body << "  if (parser.resolveOperands(allOperands, ";
759 
760     // Group all of the operand types together to perform the resolution all at
761     // once. Use llvm::concat to perform the merge. llvm::concat does not allow
762     // the case of a single range, so guard it here.
763     if (op.getNumOperands() > 1) {
764       body << "llvm::concat<const Type>(";
765       interleaveComma(llvm::seq<int>(0, op.getNumOperands()), body, [&](int i) {
766         body << "ArrayRef<Type>(";
767         emitTypeResolver(operandTypes[i], op.getOperand(i).name);
768         body << ")";
769       });
770       body << ")";
771     } else {
772       emitTypeResolver(operandTypes.front(), op.getOperand(0).name);
773     }
774 
775     body << ", allOperandLoc, result.operands))\n"
776          << "    return failure();\n";
777     return;
778   }
779 
780   // The final case is the one where each of the operands types are resolved
781   // separately.
782   for (unsigned i = 0, e = op.getNumOperands(); i != e; ++i) {
783     NamedTypeConstraint &operand = op.getOperand(i);
784     body << "  if (parser.resolveOperands(" << operand.name << "Operands, ";
785     emitTypeResolver(operandTypes[i], operand.name);
786 
787     // If this isn't a buildable type, verify the sizes match by adding the loc.
788     if (!operandTypes[i].getBuilderIdx())
789       body << ", " << operand.name << "OperandsLoc";
790     body << ", result.operands))\n    return failure();\n";
791   }
792 }
793 
794 void OperationFormat::genParserSuccessorResolution(Operator &op,
795                                                    OpMethodBody &body) {
796   // Check for the case where all successors were parsed.
797   bool hasAllSuccessors = llvm::any_of(
798       elements, [](auto &elt) { return isa<SuccessorsDirective>(elt.get()); });
799   if (hasAllSuccessors) {
800     body << "  result.addSuccessors(fullSuccessors);\n";
801     return;
802   }
803 
804   // Otherwise, handle each successor individually.
805   for (const NamedSuccessor &successor : op.getSuccessors()) {
806     if (successor.isVariadic())
807       body << "  result.addSuccessors(" << successor.name << "Successors);\n";
808     else
809       body << "  result.addSuccessors(" << successor.name << "Successor);\n";
810   }
811 }
812 
813 void OperationFormat::genParserVariadicSegmentResolution(Operator &op,
814                                                          OpMethodBody &body) {
815   if (!allOperands && op.getTrait("OpTrait::AttrSizedOperandSegments")) {
816     body << "  result.addAttribute(\"operand_segment_sizes\", "
817          << "builder.getI32VectorAttr({";
818     auto interleaveFn = [&](const NamedTypeConstraint &operand) {
819       // If the operand is variadic emit the parsed size.
820       if (operand.isVariadic())
821         body << "static_cast<int32_t>(" << operand.name << "Operands.size())";
822       else
823         body << "1";
824     };
825     interleaveComma(op.getOperands(), body, interleaveFn);
826     body << "}));\n";
827   }
828 }
829 
830 //===----------------------------------------------------------------------===//
831 // PrinterGen
832 
833 /// Generate the printer for the 'attr-dict' directive.
834 static void genAttrDictPrinter(OperationFormat &fmt, Operator &op,
835                                OpMethodBody &body, bool withKeyword) {
836   // Collect all of the attributes used in the format, these will be elided.
837   SmallVector<const NamedAttribute *, 1> usedAttributes;
838   for (auto &it : fmt.elements)
839     if (auto *attr = dyn_cast<AttributeVariable>(it.get()))
840       usedAttributes.push_back(attr->getVar());
841 
842   body << "  p.printOptionalAttrDict" << (withKeyword ? "WithKeyword" : "")
843        << "(getAttrs(), /*elidedAttrs=*/{";
844   // Elide the variadic segment size attributes if necessary.
845   if (!fmt.allOperands && op.getTrait("OpTrait::AttrSizedOperandSegments"))
846     body << "\"operand_segment_sizes\", ";
847   interleaveComma(usedAttributes, body, [&](const NamedAttribute *attr) {
848     body << "\"" << attr->name << "\"";
849   });
850   body << "});\n";
851 }
852 
853 /// Generate the printer for a literal value. `shouldEmitSpace` is true if a
854 /// space should be emitted before this element. `lastWasPunctuation` is true if
855 /// the previous element was a punctuation literal.
856 static void genLiteralPrinter(StringRef value, OpMethodBody &body,
857                               bool &shouldEmitSpace, bool &lastWasPunctuation) {
858   body << "  p";
859 
860   // Don't insert a space for certain punctuation.
861   auto shouldPrintSpaceBeforeLiteral = [&] {
862     if (value.size() != 1 && value != "->")
863       return true;
864     if (lastWasPunctuation)
865       return !StringRef(">)}],").contains(value.front());
866     return !StringRef("<>(){}[],").contains(value.front());
867   };
868   if (shouldEmitSpace && shouldPrintSpaceBeforeLiteral())
869     body << " << \" \"";
870   body << " << \"" << value << "\";\n";
871 
872   // Insert a space after certain literals.
873   shouldEmitSpace =
874       value.size() != 1 || !StringRef("<({[").contains(value.front());
875   lastWasPunctuation = !(value.front() == '_' || isalpha(value.front()));
876 }
877 
878 /// Generate the C++ for an operand to a (*-)type directive.
879 static OpMethodBody &genTypeOperandPrinter(Element *arg, OpMethodBody &body) {
880   if (isa<OperandsDirective>(arg))
881     return body << "getOperation()->getOperandTypes()";
882   if (isa<ResultsDirective>(arg))
883     return body << "getOperation()->getResultTypes()";
884   auto *operand = dyn_cast<OperandVariable>(arg);
885   auto *var = operand ? operand->getVar() : cast<ResultVariable>(arg)->getVar();
886   if (var->isVariadic())
887     return body << var->name << "().getTypes()";
888   return body << "ArrayRef<Type>(" << var->name << "().getType())";
889 }
890 
891 /// Generate the code for printing the given element.
892 static void genElementPrinter(Element *element, OpMethodBody &body,
893                               OperationFormat &fmt, Operator &op,
894                               bool &shouldEmitSpace, bool &lastWasPunctuation) {
895   if (LiteralElement *literal = dyn_cast<LiteralElement>(element))
896     return genLiteralPrinter(literal->getLiteral(), body, shouldEmitSpace,
897                              lastWasPunctuation);
898 
899   // Emit an optional group.
900   if (OptionalElement *optional = dyn_cast<OptionalElement>(element)) {
901     // Emit the check for the presence of the anchor element.
902     Element *anchor = optional->getAnchor();
903     if (AttributeVariable *attrVar = dyn_cast<AttributeVariable>(anchor))
904       body << "  if (getAttr(\"" << attrVar->getVar()->name << "\")) {\n";
905     else
906       body << "  if (!" << cast<OperandVariable>(anchor)->getVar()->name
907            << "().empty()) {\n";
908 
909     // Emit each of the elements.
910     for (Element &childElement : optional->getElements())
911       genElementPrinter(&childElement, body, fmt, op, shouldEmitSpace,
912                         lastWasPunctuation);
913     body << "  }\n";
914     return;
915   }
916 
917   // Emit the attribute dictionary.
918   if (auto *attrDict = dyn_cast<AttrDictDirective>(element)) {
919     genAttrDictPrinter(fmt, op, body, attrDict->isWithKeyword());
920     lastWasPunctuation = false;
921     return;
922   }
923 
924   // Optionally insert a space before the next element. The AttrDict printer
925   // already adds a space as necessary.
926   if (shouldEmitSpace || !lastWasPunctuation)
927     body << "  p << \" \";\n";
928   lastWasPunctuation = false;
929   shouldEmitSpace = true;
930 
931   if (auto *attr = dyn_cast<AttributeVariable>(element)) {
932     const NamedAttribute *var = attr->getVar();
933 
934     // If we are formatting as an enum, symbolize the attribute as a string.
935     if (canFormatEnumAttr(var)) {
936       const EnumAttr &enumAttr = cast<EnumAttr>(var->attr);
937       body << "  p << \"\\\"\" << " << enumAttr.getSymbolToStringFnName() << "("
938            << var->name << "()) << \"\\\"\";\n";
939       return;
940     }
941 
942     // Elide the attribute type if it is buildable.
943     if (attr->getTypeBuilder())
944       body << "  p.printAttributeWithoutType(" << var->name << "Attr());\n";
945     else
946       body << "  p.printAttribute(" << var->name << "Attr());\n";
947   } else if (auto *operand = dyn_cast<OperandVariable>(element)) {
948     body << "  p << " << operand->getVar()->name << "();\n";
949   } else if (auto *successor = dyn_cast<SuccessorVariable>(element)) {
950     const NamedSuccessor *var = successor->getVar();
951     if (var->isVariadic())
952       body << "  interleaveComma(" << var->name << "(), p);\n";
953     else
954       body << "  p << " << var->name << "();\n";
955   } else if (isa<OperandsDirective>(element)) {
956     body << "  p << getOperation()->getOperands();\n";
957   } else if (isa<SuccessorsDirective>(element)) {
958     body << "  interleaveComma(getOperation()->getSuccessors(), p);\n";
959   } else if (auto *dir = dyn_cast<TypeDirective>(element)) {
960     body << "  p << ";
961     genTypeOperandPrinter(dir->getOperand(), body) << ";\n";
962   } else if (auto *dir = dyn_cast<FunctionalTypeDirective>(element)) {
963     body << "  p.printFunctionalType(";
964     genTypeOperandPrinter(dir->getInputs(), body) << ", ";
965     genTypeOperandPrinter(dir->getResults(), body) << ");\n";
966   } else {
967     llvm_unreachable("unknown format element");
968   }
969 }
970 
971 void OperationFormat::genPrinter(Operator &op, OpClass &opClass) {
972   auto &method = opClass.newMethod("void", "print", "OpAsmPrinter &p");
973   auto &body = method.body();
974 
975   // Emit the operation name, trimming the prefix if this is the standard
976   // dialect.
977   body << "  p << \"";
978   std::string opName = op.getOperationName();
979   if (op.getDialectName() == "std")
980     body << StringRef(opName).drop_front(4);
981   else
982     body << opName;
983   body << "\";\n";
984 
985   // Flags for if we should emit a space, and if the last element was
986   // punctuation.
987   bool shouldEmitSpace = true, lastWasPunctuation = false;
988   for (auto &element : elements)
989     genElementPrinter(element.get(), body, *this, op, shouldEmitSpace,
990                       lastWasPunctuation);
991 }
992 
993 //===----------------------------------------------------------------------===//
994 // FormatLexer
995 //===----------------------------------------------------------------------===//
996 
997 namespace {
998 /// This class represents a specific token in the input format.
999 class Token {
1000 public:
1001   enum Kind {
1002     // Markers.
1003     eof,
1004     error,
1005 
1006     // Tokens with no info.
1007     l_paren,
1008     r_paren,
1009     caret,
1010     comma,
1011     equal,
1012     question,
1013 
1014     // Keywords.
1015     keyword_start,
1016     kw_attr_dict,
1017     kw_attr_dict_w_keyword,
1018     kw_functional_type,
1019     kw_operands,
1020     kw_results,
1021     kw_successors,
1022     kw_type,
1023     keyword_end,
1024 
1025     // String valued tokens.
1026     identifier,
1027     literal,
1028     variable,
1029   };
1030   Token(Kind kind, StringRef spelling) : kind(kind), spelling(spelling) {}
1031 
1032   /// Return the bytes that make up this token.
1033   StringRef getSpelling() const { return spelling; }
1034 
1035   /// Return the kind of this token.
1036   Kind getKind() const { return kind; }
1037 
1038   /// Return a location for this token.
1039   llvm::SMLoc getLoc() const {
1040     return llvm::SMLoc::getFromPointer(spelling.data());
1041   }
1042 
1043   /// Return if this token is a keyword.
1044   bool isKeyword() const { return kind > keyword_start && kind < keyword_end; }
1045 
1046 private:
1047   /// Discriminator that indicates the kind of token this is.
1048   Kind kind;
1049 
1050   /// A reference to the entire token contents; this is always a pointer into
1051   /// a memory buffer owned by the source manager.
1052   StringRef spelling;
1053 };
1054 
1055 /// This class implements a simple lexer for operation assembly format strings.
1056 class FormatLexer {
1057 public:
1058   FormatLexer(llvm::SourceMgr &mgr);
1059 
1060   /// Lex the next token and return it.
1061   Token lexToken();
1062 
1063   /// Emit an error to the lexer with the given location and message.
1064   Token emitError(llvm::SMLoc loc, const Twine &msg);
1065   Token emitError(const char *loc, const Twine &msg);
1066 
1067 private:
1068   Token formToken(Token::Kind kind, const char *tokStart) {
1069     return Token(kind, StringRef(tokStart, curPtr - tokStart));
1070   }
1071 
1072   /// Return the next character in the stream.
1073   int getNextChar();
1074 
1075   /// Lex an identifier, literal, or variable.
1076   Token lexIdentifier(const char *tokStart);
1077   Token lexLiteral(const char *tokStart);
1078   Token lexVariable(const char *tokStart);
1079 
1080   llvm::SourceMgr &srcMgr;
1081   StringRef curBuffer;
1082   const char *curPtr;
1083 };
1084 } // end anonymous namespace
1085 
1086 FormatLexer::FormatLexer(llvm::SourceMgr &mgr) : srcMgr(mgr) {
1087   curBuffer = srcMgr.getMemoryBuffer(mgr.getMainFileID())->getBuffer();
1088   curPtr = curBuffer.begin();
1089 }
1090 
1091 Token FormatLexer::emitError(llvm::SMLoc loc, const Twine &msg) {
1092   srcMgr.PrintMessage(loc, llvm::SourceMgr::DK_Error, msg);
1093   return formToken(Token::error, loc.getPointer());
1094 }
1095 Token FormatLexer::emitError(const char *loc, const Twine &msg) {
1096   return emitError(llvm::SMLoc::getFromPointer(loc), msg);
1097 }
1098 
1099 int FormatLexer::getNextChar() {
1100   char curChar = *curPtr++;
1101   switch (curChar) {
1102   default:
1103     return (unsigned char)curChar;
1104   case 0: {
1105     // A nul character in the stream is either the end of the current buffer or
1106     // a random nul in the file. Disambiguate that here.
1107     if (curPtr - 1 != curBuffer.end())
1108       return 0;
1109 
1110     // Otherwise, return end of file.
1111     --curPtr;
1112     return EOF;
1113   }
1114   case '\n':
1115   case '\r':
1116     // Handle the newline character by ignoring it and incrementing the line
1117     // count. However, be careful about 'dos style' files with \n\r in them.
1118     // Only treat a \n\r or \r\n as a single line.
1119     if ((*curPtr == '\n' || (*curPtr == '\r')) && *curPtr != curChar)
1120       ++curPtr;
1121     return '\n';
1122   }
1123 }
1124 
1125 Token FormatLexer::lexToken() {
1126   const char *tokStart = curPtr;
1127 
1128   // This always consumes at least one character.
1129   int curChar = getNextChar();
1130   switch (curChar) {
1131   default:
1132     // Handle identifiers: [a-zA-Z_]
1133     if (isalpha(curChar) || curChar == '_')
1134       return lexIdentifier(tokStart);
1135 
1136     // Unknown character, emit an error.
1137     return emitError(tokStart, "unexpected character");
1138   case EOF:
1139     // Return EOF denoting the end of lexing.
1140     return formToken(Token::eof, tokStart);
1141 
1142   // Lex punctuation.
1143   case '^':
1144     return formToken(Token::caret, tokStart);
1145   case ',':
1146     return formToken(Token::comma, tokStart);
1147   case '=':
1148     return formToken(Token::equal, tokStart);
1149   case '?':
1150     return formToken(Token::question, tokStart);
1151   case '(':
1152     return formToken(Token::l_paren, tokStart);
1153   case ')':
1154     return formToken(Token::r_paren, tokStart);
1155 
1156   // Ignore whitespace characters.
1157   case 0:
1158   case ' ':
1159   case '\t':
1160   case '\n':
1161     return lexToken();
1162 
1163   case '`':
1164     return lexLiteral(tokStart);
1165   case '$':
1166     return lexVariable(tokStart);
1167   }
1168 }
1169 
1170 Token FormatLexer::lexLiteral(const char *tokStart) {
1171   assert(curPtr[-1] == '`');
1172 
1173   // Lex a literal surrounded by ``.
1174   while (const char curChar = *curPtr++) {
1175     if (curChar == '`')
1176       return formToken(Token::literal, tokStart);
1177   }
1178   return emitError(curPtr - 1, "unexpected end of file in literal");
1179 }
1180 
1181 Token FormatLexer::lexVariable(const char *tokStart) {
1182   if (!isalpha(curPtr[0]) && curPtr[0] != '_')
1183     return emitError(curPtr - 1, "expected variable name");
1184 
1185   // Otherwise, consume the rest of the characters.
1186   while (isalnum(*curPtr) || *curPtr == '_')
1187     ++curPtr;
1188   return formToken(Token::variable, tokStart);
1189 }
1190 
1191 Token FormatLexer::lexIdentifier(const char *tokStart) {
1192   // Match the rest of the identifier regex: [0-9a-zA-Z_\-]*
1193   while (isalnum(*curPtr) || *curPtr == '_' || *curPtr == '-')
1194     ++curPtr;
1195 
1196   // Check to see if this identifier is a keyword.
1197   StringRef str(tokStart, curPtr - tokStart);
1198   Token::Kind kind =
1199       llvm::StringSwitch<Token::Kind>(str)
1200           .Case("attr-dict", Token::kw_attr_dict)
1201           .Case("attr-dict-with-keyword", Token::kw_attr_dict_w_keyword)
1202           .Case("functional-type", Token::kw_functional_type)
1203           .Case("operands", Token::kw_operands)
1204           .Case("results", Token::kw_results)
1205           .Case("successors", Token::kw_successors)
1206           .Case("type", Token::kw_type)
1207           .Default(Token::identifier);
1208   return Token(kind, str);
1209 }
1210 
1211 //===----------------------------------------------------------------------===//
1212 // FormatParser
1213 //===----------------------------------------------------------------------===//
1214 
1215 /// Function to find an element within the given range that has the same name as
1216 /// 'name'.
1217 template <typename RangeT> static auto findArg(RangeT &&range, StringRef name) {
1218   auto it = llvm::find_if(range, [=](auto &arg) { return arg.name == name; });
1219   return it != range.end() ? &*it : nullptr;
1220 }
1221 
1222 namespace {
1223 /// This class implements a parser for an instance of an operation assembly
1224 /// format.
1225 class FormatParser {
1226 public:
1227   FormatParser(llvm::SourceMgr &mgr, OperationFormat &format, Operator &op)
1228       : lexer(mgr), curToken(lexer.lexToken()), fmt(format), op(op),
1229         seenOperandTypes(op.getNumOperands()),
1230         seenResultTypes(op.getNumResults()) {}
1231 
1232   /// Parse the operation assembly format.
1233   LogicalResult parse();
1234 
1235 private:
1236   /// This struct represents a type resolution instance. It includes a specific
1237   /// type as well as an optional transformer to apply to that type in order to
1238   /// properly resolve the type of a variable.
1239   struct TypeResolutionInstance {
1240     const NamedTypeConstraint *type;
1241     Optional<StringRef> transformer;
1242   };
1243 
1244   /// Verify the state of operation attributes within the format.
1245   LogicalResult verifyAttributes(llvm::SMLoc loc);
1246 
1247   /// Verify the state of operation operands within the format.
1248   LogicalResult
1249   verifyOperands(llvm::SMLoc loc,
1250                  llvm::StringMap<TypeResolutionInstance> &variableTyResolver);
1251 
1252   /// Verify the state of operation results within the format.
1253   LogicalResult
1254   verifyResults(llvm::SMLoc loc,
1255                 llvm::StringMap<TypeResolutionInstance> &variableTyResolver);
1256 
1257   /// Verify the state of operation successors within the format.
1258   LogicalResult verifySuccessors(llvm::SMLoc loc);
1259 
1260   /// Given the values of an `AllTypesMatch` trait, check for inferable type
1261   /// resolution.
1262   void handleAllTypesMatchConstraint(
1263       ArrayRef<StringRef> values,
1264       llvm::StringMap<TypeResolutionInstance> &variableTyResolver);
1265   /// Check for inferable type resolution given all operands, and or results,
1266   /// have the same type. If 'includeResults' is true, the results also have the
1267   /// same type as all of the operands.
1268   void handleSameTypesConstraint(
1269       llvm::StringMap<TypeResolutionInstance> &variableTyResolver,
1270       bool includeResults);
1271 
1272   /// Returns an argument with the given name that has been seen within the
1273   /// format.
1274   const NamedTypeConstraint *findSeenArg(StringRef name);
1275 
1276   /// Parse a specific element.
1277   LogicalResult parseElement(std::unique_ptr<Element> &element,
1278                              bool isTopLevel);
1279   LogicalResult parseVariable(std::unique_ptr<Element> &element,
1280                               bool isTopLevel);
1281   LogicalResult parseDirective(std::unique_ptr<Element> &element,
1282                                bool isTopLevel);
1283   LogicalResult parseLiteral(std::unique_ptr<Element> &element);
1284   LogicalResult parseOptional(std::unique_ptr<Element> &element,
1285                               bool isTopLevel);
1286   LogicalResult parseOptionalChildElement(
1287       std::vector<std::unique_ptr<Element>> &childElements,
1288       SmallPtrSetImpl<const NamedTypeConstraint *> &seenVariables,
1289       Optional<unsigned> &anchorIdx);
1290 
1291   /// Parse the various different directives.
1292   LogicalResult parseAttrDictDirective(std::unique_ptr<Element> &element,
1293                                        llvm::SMLoc loc, bool isTopLevel,
1294                                        bool withKeyword);
1295   LogicalResult parseFunctionalTypeDirective(std::unique_ptr<Element> &element,
1296                                              Token tok, bool isTopLevel);
1297   LogicalResult parseOperandsDirective(std::unique_ptr<Element> &element,
1298                                        llvm::SMLoc loc, bool isTopLevel);
1299   LogicalResult parseResultsDirective(std::unique_ptr<Element> &element,
1300                                       llvm::SMLoc loc, bool isTopLevel);
1301   LogicalResult parseSuccessorsDirective(std::unique_ptr<Element> &element,
1302                                          llvm::SMLoc loc, bool isTopLevel);
1303   LogicalResult parseTypeDirective(std::unique_ptr<Element> &element, Token tok,
1304                                    bool isTopLevel);
1305   LogicalResult parseTypeDirectiveOperand(std::unique_ptr<Element> &element);
1306 
1307   //===--------------------------------------------------------------------===//
1308   // Lexer Utilities
1309   //===--------------------------------------------------------------------===//
1310 
1311   /// Advance the current lexer onto the next token.
1312   void consumeToken() {
1313     assert(curToken.getKind() != Token::eof &&
1314            curToken.getKind() != Token::error &&
1315            "shouldn't advance past EOF or errors");
1316     curToken = lexer.lexToken();
1317   }
1318   LogicalResult parseToken(Token::Kind kind, const Twine &msg) {
1319     if (curToken.getKind() != kind)
1320       return emitError(curToken.getLoc(), msg);
1321     consumeToken();
1322     return success();
1323   }
1324   LogicalResult emitError(llvm::SMLoc loc, const Twine &msg) {
1325     lexer.emitError(loc, msg);
1326     return failure();
1327   }
1328 
1329   //===--------------------------------------------------------------------===//
1330   // Fields
1331   //===--------------------------------------------------------------------===//
1332 
1333   FormatLexer lexer;
1334   Token curToken;
1335   OperationFormat &fmt;
1336   Operator &op;
1337 
1338   // The following are various bits of format state used for verification
1339   // during parsing.
1340   bool hasAllOperands = false, hasAttrDict = false;
1341   bool hasAllSuccessors = false;
1342   llvm::SmallBitVector seenOperandTypes, seenResultTypes;
1343   llvm::DenseSet<const NamedTypeConstraint *> seenOperands;
1344   llvm::DenseSet<const NamedAttribute *> seenAttrs;
1345   llvm::DenseSet<const NamedSuccessor *> seenSuccessors;
1346   llvm::DenseSet<const NamedTypeConstraint *> optionalVariables;
1347 };
1348 } // end anonymous namespace
1349 
1350 LogicalResult FormatParser::parse() {
1351   llvm::SMLoc loc = curToken.getLoc();
1352 
1353   // Parse each of the format elements into the main format.
1354   while (curToken.getKind() != Token::eof) {
1355     std::unique_ptr<Element> element;
1356     if (failed(parseElement(element, /*isTopLevel=*/true)))
1357       return failure();
1358     fmt.elements.push_back(std::move(element));
1359   }
1360 
1361   // Check that the attribute dictionary is in the format.
1362   if (!hasAttrDict)
1363     return emitError(loc, "format missing 'attr-dict' directive");
1364 
1365   // Check for any type traits that we can use for inferring types.
1366   llvm::StringMap<TypeResolutionInstance> variableTyResolver;
1367   for (const OpTrait &trait : op.getTraits()) {
1368     const llvm::Record &def = trait.getDef();
1369     if (def.isSubClassOf("AllTypesMatch")) {
1370       handleAllTypesMatchConstraint(def.getValueAsListOfStrings("values"),
1371                                     variableTyResolver);
1372     } else if (def.getName() == "SameTypeOperands") {
1373       handleSameTypesConstraint(variableTyResolver, /*includeResults=*/false);
1374     } else if (def.getName() == "SameOperandsAndResultType") {
1375       handleSameTypesConstraint(variableTyResolver, /*includeResults=*/true);
1376     } else if (def.isSubClassOf("TypesMatchWith")) {
1377       if (const auto *lhsArg = findSeenArg(def.getValueAsString("lhs")))
1378         variableTyResolver[def.getValueAsString("rhs")] = {
1379             lhsArg, def.getValueAsString("transformer")};
1380     }
1381   }
1382 
1383   // Verify the state of the various operation components.
1384   if (failed(verifyAttributes(loc)) ||
1385       failed(verifyResults(loc, variableTyResolver)) ||
1386       failed(verifyOperands(loc, variableTyResolver)) ||
1387       failed(verifySuccessors(loc)))
1388     return failure();
1389 
1390   // Check to see if we are formatting all of the operands.
1391   fmt.allOperands = llvm::any_of(fmt.elements, [](auto &elt) {
1392     return isa<OperandsDirective>(elt.get());
1393   });
1394   return success();
1395 }
1396 
1397 LogicalResult FormatParser::verifyAttributes(llvm::SMLoc loc) {
1398   // Check that there are no `:` literals after an attribute without a constant
1399   // type. The attribute grammar contains an optional trailing colon type, which
1400   // can lead to unexpected and generally unintended behavior. Given that, it is
1401   // better to just error out here instead.
1402   using ElementsIterT = llvm::pointee_iterator<
1403       std::vector<std::unique_ptr<Element>>::const_iterator>;
1404   SmallVector<std::pair<ElementsIterT, ElementsIterT>, 1> iteratorStack;
1405   iteratorStack.emplace_back(fmt.elements.begin(), fmt.elements.end());
1406   while (!iteratorStack.empty()) {
1407     auto &stackIt = iteratorStack.back();
1408     ElementsIterT &it = stackIt.first, e = stackIt.second;
1409     while (it != e) {
1410       Element *element = &*(it++);
1411 
1412       // Traverse into optional groups.
1413       if (auto *optional = dyn_cast<OptionalElement>(element)) {
1414         auto elements = optional->getElements();
1415         iteratorStack.emplace_back(elements.begin(), elements.end());
1416         break;
1417       }
1418 
1419       // We are checking for an attribute element followed by a `:`, so there is
1420       // no need to check the end.
1421       if (it == e && iteratorStack.size() == 1)
1422         break;
1423 
1424       // Check for an attribute with a constant type builder, followed by a `:`.
1425       auto *prevAttr = dyn_cast<AttributeVariable>(element);
1426       if (!prevAttr || prevAttr->getTypeBuilder())
1427         continue;
1428 
1429       // Check the next iterator within the stack for literal elements.
1430       for (auto &nextItPair : iteratorStack) {
1431         ElementsIterT nextIt = nextItPair.first, nextE = nextItPair.second;
1432         for (; nextIt != nextE; ++nextIt) {
1433           // Skip any trailing optional groups or attribute dictionaries.
1434           if (isa<AttrDictDirective>(*nextIt) || isa<OptionalElement>(*nextIt))
1435             continue;
1436 
1437           // We are only interested in `:` literals.
1438           auto *literal = dyn_cast<LiteralElement>(&*nextIt);
1439           if (!literal || literal->getLiteral() != ":")
1440             break;
1441 
1442           // TODO: Use the location of the literal element itself.
1443           return emitError(
1444               loc, llvm::formatv("format ambiguity caused by `:` literal found "
1445                                  "after attribute `{0}` which does not have "
1446                                  "a buildable type",
1447                                  prevAttr->getVar()->name));
1448         }
1449       }
1450     }
1451     if (it == e)
1452       iteratorStack.pop_back();
1453   }
1454   return success();
1455 }
1456 
1457 LogicalResult FormatParser::verifyOperands(
1458     llvm::SMLoc loc,
1459     llvm::StringMap<TypeResolutionInstance> &variableTyResolver) {
1460   // Check that all of the operands are within the format, and their types can
1461   // be inferred.
1462   auto &buildableTypes = fmt.buildableTypes;
1463   for (unsigned i = 0, e = op.getNumOperands(); i != e; ++i) {
1464     NamedTypeConstraint &operand = op.getOperand(i);
1465 
1466     // Check that the operand itself is in the format.
1467     if (!hasAllOperands && !seenOperands.count(&operand)) {
1468       return emitError(loc, "format missing instance of operand #" + Twine(i) +
1469                                 "('" + operand.name + "')");
1470     }
1471 
1472     // Check that the operand type is in the format, or that it can be inferred.
1473     if (fmt.allOperandTypes || seenOperandTypes.test(i))
1474       continue;
1475 
1476     // Check to see if we can infer this type from another variable.
1477     auto varResolverIt = variableTyResolver.find(op.getOperand(i).name);
1478     if (varResolverIt != variableTyResolver.end()) {
1479       fmt.operandTypes[i].setVariable(varResolverIt->second.type,
1480                                       varResolverIt->second.transformer);
1481       continue;
1482     }
1483 
1484     // Similarly to results, allow a custom builder for resolving the type if
1485     // we aren't using the 'operands' directive.
1486     Optional<StringRef> builder = operand.constraint.getBuilderCall();
1487     if (!builder || (hasAllOperands && operand.isVariadic())) {
1488       return emitError(loc, "format missing instance of operand #" + Twine(i) +
1489                                 "('" + operand.name + "') type");
1490     }
1491     auto it = buildableTypes.insert({*builder, buildableTypes.size()});
1492     fmt.operandTypes[i].setBuilderIdx(it.first->second);
1493   }
1494   return success();
1495 }
1496 
1497 LogicalResult FormatParser::verifyResults(
1498     llvm::SMLoc loc,
1499     llvm::StringMap<TypeResolutionInstance> &variableTyResolver) {
1500   // If we format all of the types together, there is nothing to check.
1501   if (fmt.allResultTypes)
1502     return success();
1503 
1504   // Check that all of the result types can be inferred.
1505   auto &buildableTypes = fmt.buildableTypes;
1506   for (unsigned i = 0, e = op.getNumResults(); i != e; ++i) {
1507     if (seenResultTypes.test(i))
1508       continue;
1509 
1510     // Check to see if we can infer this type from another variable.
1511     auto varResolverIt = variableTyResolver.find(op.getResultName(i));
1512     if (varResolverIt != variableTyResolver.end()) {
1513       fmt.resultTypes[i].setVariable(varResolverIt->second.type,
1514                                      varResolverIt->second.transformer);
1515       continue;
1516     }
1517 
1518     // If the result is not variadic, allow for the case where the type has a
1519     // builder that we can use.
1520     NamedTypeConstraint &result = op.getResult(i);
1521     Optional<StringRef> builder = result.constraint.getBuilderCall();
1522     if (!builder || result.constraint.isVariadic()) {
1523       return emitError(loc, "format missing instance of result #" + Twine(i) +
1524                                 "('" + result.name + "') type");
1525     }
1526     // Note in the format that this result uses the custom builder.
1527     auto it = buildableTypes.insert({*builder, buildableTypes.size()});
1528     fmt.resultTypes[i].setBuilderIdx(it.first->second);
1529   }
1530   return success();
1531 }
1532 
1533 LogicalResult FormatParser::verifySuccessors(llvm::SMLoc loc) {
1534   // Check that all of the successors are within the format.
1535   if (hasAllSuccessors)
1536     return success();
1537 
1538   for (unsigned i = 0, e = op.getNumSuccessors(); i != e; ++i) {
1539     const NamedSuccessor &successor = op.getSuccessor(i);
1540     if (!seenSuccessors.count(&successor)) {
1541       return emitError(loc, "format missing instance of successor #" +
1542                                 Twine(i) + "('" + successor.name + "')");
1543     }
1544   }
1545   return success();
1546 }
1547 
1548 void FormatParser::handleAllTypesMatchConstraint(
1549     ArrayRef<StringRef> values,
1550     llvm::StringMap<TypeResolutionInstance> &variableTyResolver) {
1551   for (unsigned i = 0, e = values.size(); i != e; ++i) {
1552     // Check to see if this value matches a resolved operand or result type.
1553     const NamedTypeConstraint *arg = findSeenArg(values[i]);
1554     if (!arg)
1555       continue;
1556 
1557     // Mark this value as the type resolver for the other variables.
1558     for (unsigned j = 0; j != i; ++j)
1559       variableTyResolver[values[j]] = {arg, llvm::None};
1560     for (unsigned j = i + 1; j != e; ++j)
1561       variableTyResolver[values[j]] = {arg, llvm::None};
1562   }
1563 }
1564 
1565 void FormatParser::handleSameTypesConstraint(
1566     llvm::StringMap<TypeResolutionInstance> &variableTyResolver,
1567     bool includeResults) {
1568   const NamedTypeConstraint *resolver = nullptr;
1569   int resolvedIt = -1;
1570 
1571   // Check to see if there is an operand or result to use for the resolution.
1572   if ((resolvedIt = seenOperandTypes.find_first()) != -1)
1573     resolver = &op.getOperand(resolvedIt);
1574   else if (includeResults && (resolvedIt = seenResultTypes.find_first()) != -1)
1575     resolver = &op.getResult(resolvedIt);
1576   else
1577     return;
1578 
1579   // Set the resolvers for each operand and result.
1580   for (unsigned i = 0, e = op.getNumOperands(); i != e; ++i)
1581     if (!seenOperandTypes.test(i) && !op.getOperand(i).name.empty())
1582       variableTyResolver[op.getOperand(i).name] = {resolver, llvm::None};
1583   if (includeResults) {
1584     for (unsigned i = 0, e = op.getNumResults(); i != e; ++i)
1585       if (!seenResultTypes.test(i) && !op.getResultName(i).empty())
1586         variableTyResolver[op.getResultName(i)] = {resolver, llvm::None};
1587   }
1588 }
1589 
1590 const NamedTypeConstraint *FormatParser::findSeenArg(StringRef name) {
1591   if (auto *arg = findArg(op.getOperands(), name))
1592     return seenOperandTypes.test(arg - op.operand_begin()) ? arg : nullptr;
1593   if (auto *arg = findArg(op.getResults(), name))
1594     return seenResultTypes.test(arg - op.result_begin()) ? arg : nullptr;
1595   return nullptr;
1596 }
1597 
1598 LogicalResult FormatParser::parseElement(std::unique_ptr<Element> &element,
1599                                          bool isTopLevel) {
1600   // Directives.
1601   if (curToken.isKeyword())
1602     return parseDirective(element, isTopLevel);
1603   // Literals.
1604   if (curToken.getKind() == Token::literal)
1605     return parseLiteral(element);
1606   // Optionals.
1607   if (curToken.getKind() == Token::l_paren)
1608     return parseOptional(element, isTopLevel);
1609   // Variables.
1610   if (curToken.getKind() == Token::variable)
1611     return parseVariable(element, isTopLevel);
1612   return emitError(curToken.getLoc(),
1613                    "expected directive, literal, variable, or optional group");
1614 }
1615 
1616 LogicalResult FormatParser::parseVariable(std::unique_ptr<Element> &element,
1617                                           bool isTopLevel) {
1618   Token varTok = curToken;
1619   consumeToken();
1620 
1621   StringRef name = varTok.getSpelling().drop_front();
1622   llvm::SMLoc loc = varTok.getLoc();
1623 
1624   // Check that the parsed argument is something actually registered on the
1625   // op.
1626   /// Attributes
1627   if (const NamedAttribute *attr = findArg(op.getAttributes(), name)) {
1628     if (isTopLevel && !seenAttrs.insert(attr).second)
1629       return emitError(loc, "attribute '" + name + "' is already bound");
1630     element = std::make_unique<AttributeVariable>(attr);
1631     return success();
1632   }
1633   /// Operands
1634   if (const NamedTypeConstraint *operand = findArg(op.getOperands(), name)) {
1635     if (isTopLevel) {
1636       if (hasAllOperands || !seenOperands.insert(operand).second)
1637         return emitError(loc, "operand '" + name + "' is already bound");
1638     }
1639     element = std::make_unique<OperandVariable>(operand);
1640     return success();
1641   }
1642   /// Results.
1643   if (const auto *result = findArg(op.getResults(), name)) {
1644     if (isTopLevel)
1645       return emitError(loc, "results can not be used at the top level");
1646     element = std::make_unique<ResultVariable>(result);
1647     return success();
1648   }
1649   /// Successors.
1650   if (const auto *successor = findArg(op.getSuccessors(), name)) {
1651     if (!isTopLevel)
1652       return emitError(loc, "successors can only be used at the top level");
1653     if (hasAllSuccessors || !seenSuccessors.insert(successor).second)
1654       return emitError(loc, "successor '" + name + "' is already bound");
1655     element = std::make_unique<SuccessorVariable>(successor);
1656     return success();
1657   }
1658   return emitError(
1659       loc, "expected variable to refer to an argument, result, or successor");
1660 }
1661 
1662 LogicalResult FormatParser::parseDirective(std::unique_ptr<Element> &element,
1663                                            bool isTopLevel) {
1664   Token dirTok = curToken;
1665   consumeToken();
1666 
1667   switch (dirTok.getKind()) {
1668   case Token::kw_attr_dict:
1669     return parseAttrDictDirective(element, dirTok.getLoc(), isTopLevel,
1670                                   /*withKeyword=*/false);
1671   case Token::kw_attr_dict_w_keyword:
1672     return parseAttrDictDirective(element, dirTok.getLoc(), isTopLevel,
1673                                   /*withKeyword=*/true);
1674   case Token::kw_functional_type:
1675     return parseFunctionalTypeDirective(element, dirTok, isTopLevel);
1676   case Token::kw_operands:
1677     return parseOperandsDirective(element, dirTok.getLoc(), isTopLevel);
1678   case Token::kw_results:
1679     return parseResultsDirective(element, dirTok.getLoc(), isTopLevel);
1680   case Token::kw_successors:
1681     return parseSuccessorsDirective(element, dirTok.getLoc(), isTopLevel);
1682   case Token::kw_type:
1683     return parseTypeDirective(element, dirTok, isTopLevel);
1684 
1685   default:
1686     llvm_unreachable("unknown directive token");
1687   }
1688 }
1689 
1690 LogicalResult FormatParser::parseLiteral(std::unique_ptr<Element> &element) {
1691   Token literalTok = curToken;
1692   consumeToken();
1693 
1694   // Check that the parsed literal is valid.
1695   StringRef value = literalTok.getSpelling().drop_front().drop_back();
1696   if (!LiteralElement::isValidLiteral(value))
1697     return emitError(literalTok.getLoc(), "expected valid literal");
1698 
1699   element = std::make_unique<LiteralElement>(value);
1700   return success();
1701 }
1702 
1703 LogicalResult FormatParser::parseOptional(std::unique_ptr<Element> &element,
1704                                           bool isTopLevel) {
1705   llvm::SMLoc curLoc = curToken.getLoc();
1706   if (!isTopLevel)
1707     return emitError(curLoc, "optional groups can only be used as top-level "
1708                              "elements");
1709   consumeToken();
1710 
1711   // Parse the child elements for this optional group.
1712   std::vector<std::unique_ptr<Element>> elements;
1713   SmallPtrSet<const NamedTypeConstraint *, 8> seenVariables;
1714   Optional<unsigned> anchorIdx;
1715   do {
1716     if (failed(parseOptionalChildElement(elements, seenVariables, anchorIdx)))
1717       return failure();
1718   } while (curToken.getKind() != Token::r_paren);
1719   consumeToken();
1720   if (failed(parseToken(Token::question, "expected '?' after optional group")))
1721     return failure();
1722 
1723   // The optional group is required to have an anchor.
1724   if (!anchorIdx)
1725     return emitError(curLoc, "optional group specified no anchor element");
1726 
1727   // The first element of the group must be one that can be parsed/printed in an
1728   // optional fashion.
1729   if (!isa<LiteralElement>(&*elements.front()) &&
1730       !isa<OperandVariable>(&*elements.front()))
1731     return emitError(curLoc, "first element of an operand group must be a "
1732                              "literal or operand");
1733 
1734   // After parsing all of the elements, ensure that all type directives refer
1735   // only to elements within the group.
1736   auto checkTypeOperand = [&](Element *typeEle) {
1737     auto *opVar = dyn_cast<OperandVariable>(typeEle);
1738     const NamedTypeConstraint *var = opVar ? opVar->getVar() : nullptr;
1739     if (!seenVariables.count(var))
1740       return emitError(curLoc, "type directive can only refer to variables "
1741                                "within the optional group");
1742     return success();
1743   };
1744   for (auto &ele : elements) {
1745     if (auto *typeEle = dyn_cast<TypeDirective>(ele.get())) {
1746       if (failed(checkTypeOperand(typeEle->getOperand())))
1747         return failure();
1748     } else if (auto *typeEle = dyn_cast<FunctionalTypeDirective>(ele.get())) {
1749       if (failed(checkTypeOperand(typeEle->getInputs())) ||
1750           failed(checkTypeOperand(typeEle->getResults())))
1751         return failure();
1752     }
1753   }
1754 
1755   optionalVariables.insert(seenVariables.begin(), seenVariables.end());
1756   element = std::make_unique<OptionalElement>(std::move(elements), *anchorIdx);
1757   return success();
1758 }
1759 
1760 LogicalResult FormatParser::parseOptionalChildElement(
1761     std::vector<std::unique_ptr<Element>> &childElements,
1762     SmallPtrSetImpl<const NamedTypeConstraint *> &seenVariables,
1763     Optional<unsigned> &anchorIdx) {
1764   llvm::SMLoc childLoc = curToken.getLoc();
1765   childElements.push_back({});
1766   if (failed(parseElement(childElements.back(), /*isTopLevel=*/true)))
1767     return failure();
1768 
1769   // Check to see if this element is the anchor of the optional group.
1770   bool isAnchor = curToken.getKind() == Token::caret;
1771   if (isAnchor) {
1772     if (anchorIdx)
1773       return emitError(childLoc, "only one element can be marked as the anchor "
1774                                  "of an optional group");
1775     anchorIdx = childElements.size() - 1;
1776     consumeToken();
1777   }
1778 
1779   return TypeSwitch<Element *, LogicalResult>(childElements.back().get())
1780       // All attributes can be within the optional group, but only optional
1781       // attributes can be the anchor.
1782       .Case([&](AttributeVariable *attrEle) {
1783         if (isAnchor && !attrEle->getVar()->attr.isOptional())
1784           return emitError(childLoc, "only optional attributes can be used to "
1785                                      "anchor an optional group");
1786         return success();
1787       })
1788       // Only optional-like(i.e. variadic) operands can be within an optional
1789       // group.
1790       .Case<OperandVariable>([&](OperandVariable *ele) {
1791         if (!ele->getVar()->isVariadic())
1792           return emitError(childLoc, "only variadic operands can be used within"
1793                                      " an optional group");
1794         seenVariables.insert(ele->getVar());
1795         return success();
1796       })
1797       // Literals and type directives may be used, but they can't anchor the
1798       // group.
1799       .Case<LiteralElement, TypeDirective, FunctionalTypeDirective>(
1800           [&](Element *) {
1801             if (isAnchor)
1802               return emitError(childLoc, "only variables can be used to anchor "
1803                                          "an optional group");
1804             return success();
1805           })
1806       .Default([&](Element *) {
1807         return emitError(childLoc, "only literals, types, and variables can be "
1808                                    "used within an optional group");
1809       });
1810 }
1811 
1812 LogicalResult
1813 FormatParser::parseAttrDictDirective(std::unique_ptr<Element> &element,
1814                                      llvm::SMLoc loc, bool isTopLevel,
1815                                      bool withKeyword) {
1816   if (!isTopLevel)
1817     return emitError(loc, "'attr-dict' directive can only be used as a "
1818                           "top-level directive");
1819   if (hasAttrDict)
1820     return emitError(loc, "'attr-dict' directive has already been seen");
1821 
1822   hasAttrDict = true;
1823   element = std::make_unique<AttrDictDirective>(withKeyword);
1824   return success();
1825 }
1826 
1827 LogicalResult
1828 FormatParser::parseFunctionalTypeDirective(std::unique_ptr<Element> &element,
1829                                            Token tok, bool isTopLevel) {
1830   llvm::SMLoc loc = tok.getLoc();
1831   if (!isTopLevel)
1832     return emitError(
1833         loc, "'functional-type' is only valid as a top-level directive");
1834 
1835   // Parse the main operand.
1836   std::unique_ptr<Element> inputs, results;
1837   if (failed(parseToken(Token::l_paren, "expected '(' before argument list")) ||
1838       failed(parseTypeDirectiveOperand(inputs)) ||
1839       failed(parseToken(Token::comma, "expected ',' after inputs argument")) ||
1840       failed(parseTypeDirectiveOperand(results)) ||
1841       failed(parseToken(Token::r_paren, "expected ')' after argument list")))
1842     return failure();
1843   element = std::make_unique<FunctionalTypeDirective>(std::move(inputs),
1844                                                       std::move(results));
1845   return success();
1846 }
1847 
1848 LogicalResult
1849 FormatParser::parseOperandsDirective(std::unique_ptr<Element> &element,
1850                                      llvm::SMLoc loc, bool isTopLevel) {
1851   if (isTopLevel && (hasAllOperands || !seenOperands.empty()))
1852     return emitError(loc, "'operands' directive creates overlap in format");
1853   hasAllOperands = true;
1854   element = std::make_unique<OperandsDirective>();
1855   return success();
1856 }
1857 
1858 LogicalResult
1859 FormatParser::parseResultsDirective(std::unique_ptr<Element> &element,
1860                                     llvm::SMLoc loc, bool isTopLevel) {
1861   if (isTopLevel)
1862     return emitError(loc, "'results' directive can not be used as a "
1863                           "top-level directive");
1864   element = std::make_unique<ResultsDirective>();
1865   return success();
1866 }
1867 
1868 LogicalResult
1869 FormatParser::parseSuccessorsDirective(std::unique_ptr<Element> &element,
1870                                        llvm::SMLoc loc, bool isTopLevel) {
1871   if (!isTopLevel)
1872     return emitError(loc,
1873                      "'successors' is only valid as a top-level directive");
1874   if (hasAllSuccessors || !seenSuccessors.empty())
1875     return emitError(loc, "'successors' directive creates overlap in format");
1876   hasAllSuccessors = true;
1877   element = std::make_unique<SuccessorsDirective>();
1878   return success();
1879 }
1880 
1881 LogicalResult
1882 FormatParser::parseTypeDirective(std::unique_ptr<Element> &element, Token tok,
1883                                  bool isTopLevel) {
1884   llvm::SMLoc loc = tok.getLoc();
1885   if (!isTopLevel)
1886     return emitError(loc, "'type' is only valid as a top-level directive");
1887 
1888   std::unique_ptr<Element> operand;
1889   if (failed(parseToken(Token::l_paren, "expected '(' before argument list")) ||
1890       failed(parseTypeDirectiveOperand(operand)) ||
1891       failed(parseToken(Token::r_paren, "expected ')' after argument list")))
1892     return failure();
1893   element = std::make_unique<TypeDirective>(std::move(operand));
1894   return success();
1895 }
1896 
1897 LogicalResult
1898 FormatParser::parseTypeDirectiveOperand(std::unique_ptr<Element> &element) {
1899   llvm::SMLoc loc = curToken.getLoc();
1900   if (failed(parseElement(element, /*isTopLevel=*/false)))
1901     return failure();
1902   if (isa<LiteralElement>(element.get()))
1903     return emitError(
1904         loc, "'type' directive operand expects variable or directive operand");
1905 
1906   if (auto *var = dyn_cast<OperandVariable>(element.get())) {
1907     unsigned opIdx = var->getVar() - op.operand_begin();
1908     if (fmt.allOperandTypes || seenOperandTypes.test(opIdx))
1909       return emitError(loc, "'type' of '" + var->getVar()->name +
1910                                 "' is already bound");
1911     seenOperandTypes.set(opIdx);
1912   } else if (auto *var = dyn_cast<ResultVariable>(element.get())) {
1913     unsigned resIdx = var->getVar() - op.result_begin();
1914     if (fmt.allResultTypes || seenResultTypes.test(resIdx))
1915       return emitError(loc, "'type' of '" + var->getVar()->name +
1916                                 "' is already bound");
1917     seenResultTypes.set(resIdx);
1918   } else if (isa<OperandsDirective>(&*element)) {
1919     if (fmt.allOperandTypes || seenOperandTypes.any())
1920       return emitError(loc, "'operands' 'type' is already bound");
1921     fmt.allOperandTypes = true;
1922   } else if (isa<ResultsDirective>(&*element)) {
1923     if (fmt.allResultTypes || seenResultTypes.any())
1924       return emitError(loc, "'results' 'type' is already bound");
1925     fmt.allResultTypes = true;
1926   } else {
1927     return emitError(loc, "invalid argument to 'type' directive");
1928   }
1929   return success();
1930 }
1931 
1932 //===----------------------------------------------------------------------===//
1933 // Interface
1934 //===----------------------------------------------------------------------===//
1935 
1936 void mlir::tblgen::generateOpFormat(const Operator &constOp, OpClass &opClass) {
1937   // TODO(riverriddle) Operator doesn't expose all necessary functionality via
1938   // the const interface.
1939   Operator &op = const_cast<Operator &>(constOp);
1940   if (!op.hasAssemblyFormat())
1941     return;
1942 
1943   // Parse the format description.
1944   llvm::SourceMgr mgr;
1945   mgr.AddNewSourceBuffer(
1946       llvm::MemoryBuffer::getMemBuffer(op.getAssemblyFormat()), llvm::SMLoc());
1947   OperationFormat format(op);
1948   if (failed(FormatParser(mgr, format, op).parse())) {
1949     // Exit the process if format errors are treated as fatal.
1950     if (formatErrorIsFatal) {
1951       // Invoke the interrupt handlers to run the file cleanup handlers.
1952       llvm::sys::RunInterruptHandlers();
1953       std::exit(1);
1954     }
1955     return;
1956   }
1957 
1958   // Generate the printer and parser based on the parsed format.
1959   format.genParser(op, opClass);
1960   format.genPrinter(op, opClass);
1961 }
1962