1 | //===- Type.cpp - Type class ----------------------------------------------===// |
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 | // Type wrapper to simplify using TableGen Record defining a MLIR Type. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "mlir/TableGen/Type.h" |
14 | #include "mlir/TableGen/Dialect.h" |
15 | #include "llvm/ADT/Twine.h" |
16 | #include "llvm/ADT/TypeSwitch.h" |
17 | #include "llvm/TableGen/Record.h" |
18 | |
19 | using namespace mlir; |
20 | using namespace mlir::tblgen; |
21 | using llvm::Record; |
22 | |
23 | TypeConstraint::TypeConstraint(const llvm::DefInit *init) |
24 | : TypeConstraint(init->getDef()) {} |
25 | |
26 | bool TypeConstraint::isOptional() const { |
27 | return def->isSubClassOf(Name: "Optional" ); |
28 | } |
29 | |
30 | bool TypeConstraint::isVariadic() const { |
31 | return def->isSubClassOf(Name: "Variadic" ); |
32 | } |
33 | |
34 | bool TypeConstraint::isVariadicOfVariadic() const { |
35 | return def->isSubClassOf(Name: "VariadicOfVariadic" ); |
36 | } |
37 | |
38 | StringRef TypeConstraint::getVariadicOfVariadicSegmentSizeAttr() const { |
39 | assert(isVariadicOfVariadic()); |
40 | return def->getValueAsString(FieldName: "segmentAttrName" ); |
41 | } |
42 | |
43 | // Returns the builder call for this constraint if this is a buildable type, |
44 | // returns std::nullopt otherwise. |
45 | std::optional<StringRef> TypeConstraint::getBuilderCall() const { |
46 | const Record *baseType = def; |
47 | if (isVariableLength()) |
48 | baseType = baseType->getValueAsDef(FieldName: "baseType" ); |
49 | |
50 | // Check to see if this type constraint has a builder call. |
51 | const llvm::RecordVal *builderCall = baseType->getValue(Name: "builderCall" ); |
52 | if (!builderCall || !builderCall->getValue()) |
53 | return std::nullopt; |
54 | return TypeSwitch<const llvm::Init *, std::optional<StringRef>>( |
55 | builderCall->getValue()) |
56 | .Case<llvm::StringInit>(caseFn: [&](auto *init) { |
57 | StringRef value = init->getValue(); |
58 | return value.empty() ? std::optional<StringRef>() : value; |
59 | }) |
60 | .Default(defaultFn: [](auto *) { return std::nullopt; }); |
61 | } |
62 | |
63 | // Return the C++ type for this type (which may just be ::mlir::Type). |
64 | StringRef TypeConstraint::getCppType() const { |
65 | return def->getValueAsString(FieldName: "cppType" ); |
66 | } |
67 | |
68 | Type::Type(const Record *record) : TypeConstraint(record) {} |
69 | |
70 | Dialect Type::getDialect() const { |
71 | return Dialect(def->getValueAsDef(FieldName: "dialect" )); |
72 | } |
73 | |