1 | //===- Builder.cpp - Builder definitions ----------------------------------===// |
---|---|
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 "mlir/TableGen/Builder.h" |
10 | #include "llvm/TableGen/Error.h" |
11 | #include "llvm/TableGen/Record.h" |
12 | |
13 | using namespace mlir; |
14 | using namespace mlir::tblgen; |
15 | |
16 | //===----------------------------------------------------------------------===// |
17 | // Builder::Parameter |
18 | //===----------------------------------------------------------------------===// |
19 | |
20 | /// Return a string containing the C++ type of this parameter. |
21 | StringRef Builder::Parameter::getCppType() const { |
22 | if (const auto *stringInit = dyn_cast<llvm::StringInit>(Val: def)) |
23 | return stringInit->getValue(); |
24 | const llvm::Record *record = cast<llvm::DefInit>(Val: def)->getDef(); |
25 | // Inlining the first part of `Record::getValueAsString` to give better |
26 | // error messages. |
27 | const llvm::RecordVal *type = record->getValue(Name: "type"); |
28 | if (!type || !type->getValue()) { |
29 | llvm::PrintFatalError(Msg: "Builder DAG arguments must be either strings or " |
30 | "defs which inherit from CArg"); |
31 | } |
32 | return record->getValueAsString(FieldName: "type"); |
33 | } |
34 | |
35 | /// Return an optional string containing the default value to use for this |
36 | /// parameter. |
37 | std::optional<StringRef> Builder::Parameter::getDefaultValue() const { |
38 | if (isa<llvm::StringInit>(Val: def)) |
39 | return std::nullopt; |
40 | const llvm::Record *record = cast<llvm::DefInit>(Val: def)->getDef(); |
41 | std::optional<StringRef> value = |
42 | record->getValueAsOptionalString(FieldName: "defaultValue"); |
43 | return value && !value->empty() ? value : std::nullopt; |
44 | } |
45 | |
46 | //===----------------------------------------------------------------------===// |
47 | // Builder |
48 | //===----------------------------------------------------------------------===// |
49 | |
50 | Builder::Builder(const llvm::Record *record, ArrayRef<SMLoc> loc) |
51 | : def(record) { |
52 | // Initialize the parameters of the builder. |
53 | const llvm::DagInit *dag = def->getValueAsDag(FieldName: "dagParams"); |
54 | auto *defInit = dyn_cast<llvm::DefInit>(Val: dag->getOperator()); |
55 | if (!defInit || !defInit->getDef()->getName().equals(RHS: "ins")) |
56 | PrintFatalError(ErrorLoc: def->getLoc(), Msg: "expected 'ins' in builders"); |
57 | |
58 | bool seenDefaultValue = false; |
59 | for (unsigned i = 0, e = dag->getNumArgs(); i < e; ++i) { |
60 | const llvm::StringInit *paramName = dag->getArgName(Num: i); |
61 | const llvm::Init *paramValue = dag->getArg(Num: i); |
62 | Parameter param(paramName ? paramName->getValue() |
63 | : std::optional<StringRef>(), |
64 | paramValue); |
65 | |
66 | // Similarly to C++, once an argument with a default value is detected, the |
67 | // following arguments must have default values as well. |
68 | if (param.getDefaultValue()) { |
69 | seenDefaultValue = true; |
70 | } else if (seenDefaultValue) { |
71 | PrintFatalError(ErrorLoc: loc, |
72 | Msg: "expected an argument with default value after other " |
73 | "arguments with default values"); |
74 | } |
75 | parameters.emplace_back(Args&: param); |
76 | } |
77 | } |
78 | |
79 | /// Return an optional string containing the body of the builder. |
80 | std::optional<StringRef> Builder::getBody() const { |
81 | std::optional<StringRef> body = def->getValueAsOptionalString(FieldName: "body"); |
82 | return body && !body->empty() ? body : std::nullopt; |
83 | } |
84 | |
85 | std::optional<StringRef> Builder::getDeprecatedMessage() const { |
86 | std::optional<StringRef> message = |
87 | def->getValueAsOptionalString(FieldName: "odsCppDeprecated"); |
88 | return message && !message->empty() ? message : std::nullopt; |
89 | } |
90 |