1//===-- TestTypeDefs.td - Test dialect type definitions ----*- tablegen -*-===// 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// TableGen data type definitions for Test dialect. 10// 11//===----------------------------------------------------------------------===// 12 13#ifndef TEST_TYPEDEFS 14#define TEST_TYPEDEFS 15 16// To get the test dialect def. 17include "TestOps.td" 18include "mlir/IR/BuiltinTypes.td" 19include "mlir/Interfaces/DataLayoutInterfaces.td" 20 21// All of the types will extend this class. 22class Test_Type<string name, list<Trait> traits = []> 23 : TypeDef<Test_Dialect, name, traits>; 24 25def SimpleTypeA : Test_Type<"SimpleA"> { 26 let mnemonic = "smpla"; 27} 28 29// A more complex parameterized type. 30def CompoundTypeA : Test_Type<"CompoundA"> { 31 let mnemonic = "cmpnd_a"; 32 33 // List of type parameters. 34 let parameters = ( 35 ins 36 "int":$widthOfSomething, 37 "::mlir::Type":$oneType, 38 // This is special syntax since ArrayRefs require allocation in the 39 // constructor. 40 ArrayRefParameter< 41 "int", // The parameter C++ type. 42 "An example of an array of ints" // Parameter description. 43 >: $arrayOfInts 44 ); 45 46 let extraClassDeclaration = [{ 47 struct SomeCppStruct {}; 48 }]; 49} 50 51// An example of how one could implement a standard integer. 52def IntegerType : Test_Type<"TestInteger"> { 53 let mnemonic = "int"; 54 let genVerifyDecl = 1; 55 let parameters = ( 56 ins 57 "unsigned":$width, 58 // SignednessSemantics is defined below. 59 "::mlir::test::TestIntegerType::SignednessSemantics":$signedness 60 ); 61 62 // We define the printer inline. 63 let printer = [{ 64 $_printer << "int<"; 65 printSignedness($_printer, getImpl()->signedness); 66 $_printer << ", " << getImpl()->width << ">"; 67 }]; 68 69 // Define custom builder methods. 70 let builders = [ 71 TypeBuilder<(ins "unsigned":$width, 72 CArg<"SignednessSemantics", "Signless">:$signedness), [{ 73 return $_get($_ctxt, width, signedness); 74 }]> 75 ]; 76 let skipDefaultBuilders = 1; 77 78 // The parser is defined here also. 79 let parser = [{ 80 if (parser.parseLess()) return Type(); 81 SignednessSemantics signedness; 82 if (parseSignedness($_parser, signedness)) return mlir::Type(); 83 if ($_parser.parseComma()) return Type(); 84 int width; 85 if ($_parser.parseInteger(width)) return Type(); 86 if ($_parser.parseGreater()) return Type(); 87 Location loc = $_parser.getEncodedSourceLoc($_parser.getNameLoc()); 88 return getChecked(loc, loc.getContext(), width, signedness); 89 }]; 90 91 // Any extra code one wants in the type's class declaration. 92 let extraClassDeclaration = [{ 93 /// Signedness semantics. 94 enum SignednessSemantics { 95 Signless, /// No signedness semantics 96 Signed, /// Signed integer 97 Unsigned, /// Unsigned integer 98 }; 99 100 /// Return true if this is a signless integer type. 101 bool isSignless() const { return getSignedness() == Signless; } 102 /// Return true if this is a signed integer type. 103 bool isSigned() const { return getSignedness() == Signed; } 104 /// Return true if this is an unsigned integer type. 105 bool isUnsigned() const { return getSignedness() == Unsigned; } 106 }]; 107} 108 109// A parent type for any type which is just a list of fields (e.g. structs, 110// unions). 111class FieldInfo_Type<string name> : Test_Type<name> { 112 let parameters = ( 113 ins 114 // An ArrayRef of something which requires allocation in the storage 115 // constructor. 116 ArrayRefOfSelfAllocationParameter< 117 "::mlir::test::FieldInfo", // FieldInfo is defined/declared in TestTypes.h. 118 "Models struct fields">: $fields 119 ); 120 121 // Prints the type in this format: 122 // struct<[{field1Name, field1Type}, {field2Name, field2Type}] 123 let printer = [{ 124 $_printer << "struct" << "<"; 125 for (size_t i=0, e = getImpl()->fields.size(); i < e; i++) { 126 const auto& field = getImpl()->fields[i]; 127 $_printer << "{" << field.name << "," << field.type << "}"; 128 if (i < getImpl()->fields.size() - 1) 129 $_printer << ","; 130 } 131 $_printer << ">"; 132 }]; 133 134 // Parses the above format 135 let parser = [{ 136 llvm::SmallVector<FieldInfo, 4> parameters; 137 if ($_parser.parseLess()) return Type(); 138 while (mlir::succeeded($_parser.parseOptionalLBrace())) { 139 StringRef name; 140 if ($_parser.parseKeyword(&name)) return Type(); 141 if ($_parser.parseComma()) return Type(); 142 Type type; 143 if ($_parser.parseType(type)) return Type(); 144 if ($_parser.parseRBrace()) return Type(); 145 parameters.push_back(FieldInfo {name, type}); 146 if ($_parser.parseOptionalComma()) break; 147 } 148 if ($_parser.parseGreater()) return Type(); 149 return get($_ctxt, parameters); 150 }]; 151} 152 153def StructType : FieldInfo_Type<"Struct"> { 154 let mnemonic = "struct"; 155} 156 157def TestType : Test_Type<"Test", [ 158 DeclareTypeInterfaceMethods<TestTypeInterface> 159]> { 160 let mnemonic = "test_type"; 161} 162 163def TestTypeWithLayoutType : Test_Type<"TestTypeWithLayout", [ 164 DeclareTypeInterfaceMethods<DataLayoutTypeInterface, ["areCompatible"]> 165]> { 166 let mnemonic = "test_type_with_layout"; 167 let parameters = (ins "unsigned":$key); 168 let extraClassDeclaration = [{ 169 LogicalResult verifyEntries(DataLayoutEntryListRef params, 170 Location loc) const; 171 172 private: 173 unsigned extractKind(DataLayoutEntryListRef params, 174 StringRef expectedKind) const; 175 176 public: 177 }]; 178} 179 180def TestMemRefElementType : Test_Type<"TestMemRefElementType", 181 [MemRefElementTypeInterface]> { 182 let mnemonic = "memref_element"; 183} 184 185#endif // TEST_TYPEDEFS 186