1 //===- DialectImplementation.h ----------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains utilities classes for implementing dialect attributes and 10 // types. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef MLIR_IR_DIALECTIMPLEMENTATION_H 15 #define MLIR_IR_DIALECTIMPLEMENTATION_H 16 17 #include "mlir/IR/OpImplementation.h" 18 19 namespace mlir { 20 21 //===----------------------------------------------------------------------===// 22 // DialectAsmPrinter 23 //===----------------------------------------------------------------------===// 24 25 /// This is a pure-virtual base class that exposes the asmprinter hooks 26 /// necessary to implement a custom printAttribute/printType() method on a 27 /// dialect. 28 class DialectAsmPrinter : public AsmPrinter { 29 public: 30 using AsmPrinter::AsmPrinter; 31 ~DialectAsmPrinter() override; 32 }; 33 34 //===----------------------------------------------------------------------===// 35 // DialectAsmParser 36 //===----------------------------------------------------------------------===// 37 38 /// The DialectAsmParser has methods for interacting with the asm parser when 39 /// parsing attributes and types. 40 class DialectAsmParser : public AsmParser { 41 public: 42 using AsmParser::AsmParser; 43 ~DialectAsmParser() override; 44 45 /// Returns the full specification of the symbol being parsed. This allows for 46 /// using a separate parser if necessary. 47 virtual StringRef getFullSymbolSpec() const = 0; 48 }; 49 50 //===----------------------------------------------------------------------===// 51 // Parse Fields 52 //===----------------------------------------------------------------------===// 53 54 /// Provide a template class that can be specialized by users to dispatch to 55 /// parsers. Auto-generated parsers generate calls to `FieldParser<T>::parse`, 56 /// where `T` is the parameter storage type, to parse custom types. 57 template <typename T, typename = T> 58 struct FieldParser; 59 60 /// Parse an attribute. 61 template <typename AttributeT> 62 struct FieldParser< 63 AttributeT, std::enable_if_t<std::is_base_of<Attribute, AttributeT>::value, 64 AttributeT>> { 65 static FailureOr<AttributeT> parse(AsmParser &parser) { 66 AttributeT value; 67 if (parser.parseCustomAttributeWithFallback(value)) 68 return failure(); 69 return value; 70 } 71 }; 72 73 /// Parse an attribute. 74 template <typename TypeT> 75 struct FieldParser< 76 TypeT, std::enable_if_t<std::is_base_of<Type, TypeT>::value, TypeT>> { 77 static FailureOr<TypeT> parse(AsmParser &parser) { 78 TypeT value; 79 if (parser.parseCustomTypeWithFallback(value)) 80 return failure(); 81 return value; 82 } 83 }; 84 85 /// Parse any integer. 86 template <typename IntT> 87 struct FieldParser<IntT, 88 std::enable_if_t<std::is_integral<IntT>::value, IntT>> { 89 static FailureOr<IntT> parse(AsmParser &parser) { 90 IntT value; 91 if (parser.parseInteger(value)) 92 return failure(); 93 return value; 94 } 95 }; 96 97 /// Parse a string. 98 template <> 99 struct FieldParser<std::string> { 100 static FailureOr<std::string> parse(AsmParser &parser) { 101 std::string value; 102 if (parser.parseString(&value)) 103 return failure(); 104 return value; 105 } 106 }; 107 108 /// Parse any container that supports back insertion as a list. 109 template <typename ContainerT> 110 struct FieldParser< 111 ContainerT, std::enable_if_t<std::is_member_function_pointer< 112 decltype(&ContainerT::push_back)>::value, 113 ContainerT>> { 114 using ElementT = typename ContainerT::value_type; 115 static FailureOr<ContainerT> parse(AsmParser &parser) { 116 ContainerT elements; 117 auto elementParser = [&]() { 118 auto element = FieldParser<ElementT>::parse(parser); 119 if (failed(element)) 120 return failure(); 121 elements.push_back(*element); 122 return success(); 123 }; 124 if (parser.parseCommaSeparatedList(elementParser)) 125 return failure(); 126 return elements; 127 } 128 }; 129 130 /// Parse an affine map. 131 template <> 132 struct FieldParser<AffineMap> { 133 static FailureOr<AffineMap> parse(AsmParser &parser) { 134 AffineMap map; 135 if (failed(parser.parseAffineMap(map))) 136 return failure(); 137 return map; 138 } 139 }; 140 141 } // namespace mlir 142 143 #endif // MLIR_IR_DIALECTIMPLEMENTATION_H 144