summaryrefslogtreecommitdiff
path: root/mlir/lib/Dialect/PDL/IR/PDLTypes.cpp
blob: 6f6c9d337066d06e65a76fab7ef645ddf506a65b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//===- PDLTypes.cpp - Pattern Descriptor Language Types -------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "mlir/Dialect/PDL/IR/PDLTypes.h"
#include "mlir/Dialect/PDL/IR/PDL.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/DialectImplementation.h"
#include "llvm/ADT/TypeSwitch.h"

using namespace mlir;
using namespace mlir::pdl;

//===----------------------------------------------------------------------===//
// TableGen'd type method definitions
//===----------------------------------------------------------------------===//

#define GET_TYPEDEF_CLASSES
#include "mlir/Dialect/PDL/IR/PDLOpsTypes.cpp.inc"

//===----------------------------------------------------------------------===//
// PDLDialect
//===----------------------------------------------------------------------===//

void PDLDialect::registerTypes() {
  addTypes<
#define GET_TYPEDEF_LIST
#include "mlir/Dialect/PDL/IR/PDLOpsTypes.cpp.inc"
      >();
}

static Type parsePDLType(AsmParser &parser) {
  StringRef typeTag;
  {
    Type genType;
    auto parseResult = generatedTypeParser(parser, &typeTag, genType);
    if (parseResult.has_value())
      return genType;
  }

  // FIXME: This ends up with a double error being emitted if `RangeType` also
  // emits an error. We should rework the `generatedTypeParser` to better
  // support when the keyword is valid but the individual type parser itself
  // emits an error.
  parser.emitError(parser.getNameLoc(), "invalid 'pdl' type: `")
      << typeTag << "'";
  return Type();
}

//===----------------------------------------------------------------------===//
// PDL Types
//===----------------------------------------------------------------------===//

bool PDLType::classof(Type type) {
  return llvm::isa<PDLDialect>(type.getDialect());
}

Type pdl::getRangeElementTypeOrSelf(Type type) {
  if (auto rangeType = llvm::dyn_cast<RangeType>(type))
    return rangeType.getElementType();
  return type;
}

//===----------------------------------------------------------------------===//
// RangeType
//===----------------------------------------------------------------------===//

Type RangeType::parse(AsmParser &parser) {
  if (parser.parseLess())
    return Type();

  SMLoc elementLoc = parser.getCurrentLocation();
  Type elementType = parsePDLType(parser);
  if (!elementType || parser.parseGreater())
    return Type();

  if (llvm::isa<RangeType>(elementType)) {
    parser.emitError(elementLoc)
        << "element of pdl.range cannot be another range, but got"
        << elementType;
    return Type();
  }
  return RangeType::get(elementType);
}

void RangeType::print(AsmPrinter &printer) const {
  printer << "<";
  (void)generatedTypePrinter(getElementType(), printer);
  printer << ">";
}

LogicalResult RangeType::verify(function_ref<InFlightDiagnostic()> emitError,
                                Type elementType) {
  if (!llvm::isa<PDLType>(elementType) || llvm::isa<RangeType>(elementType)) {
    return emitError()
           << "expected element of pdl.range to be one of [!pdl.attribute, "
              "!pdl.operation, !pdl.type, !pdl.value], but got "
           << elementType;
  }
  return success();
}