120741773SRiver Riddle //===- Builder.cpp - Builder definitions ----------------------------------===// 220741773SRiver Riddle // 320741773SRiver Riddle // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 420741773SRiver Riddle // See https://llvm.org/LICENSE.txt for license information. 520741773SRiver Riddle // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 620741773SRiver Riddle // 720741773SRiver Riddle //===----------------------------------------------------------------------===// 820741773SRiver Riddle 920741773SRiver Riddle #include "mlir/TableGen/Builder.h" 1020741773SRiver Riddle #include "llvm/TableGen/Error.h" 1120741773SRiver Riddle #include "llvm/TableGen/Record.h" 1220741773SRiver Riddle 1320741773SRiver Riddle using namespace mlir; 1420741773SRiver Riddle using namespace mlir::tblgen; 15*659192b1SRahul Joshi using llvm::DagInit; 16*659192b1SRahul Joshi using llvm::DefInit; 17*659192b1SRahul Joshi using llvm::Init; 18*659192b1SRahul Joshi using llvm::Record; 19*659192b1SRahul Joshi using llvm::StringInit; 2020741773SRiver Riddle 2120741773SRiver Riddle //===----------------------------------------------------------------------===// 2220741773SRiver Riddle // Builder::Parameter 2320741773SRiver Riddle //===----------------------------------------------------------------------===// 2420741773SRiver Riddle 2520741773SRiver Riddle /// Return a string containing the C++ type of this parameter. 2620741773SRiver Riddle StringRef Builder::Parameter::getCppType() const { 27*659192b1SRahul Joshi if (const auto *stringInit = dyn_cast<StringInit>(def)) 2820741773SRiver Riddle return stringInit->getValue(); 29*659192b1SRahul Joshi const Record *record = cast<DefInit>(def)->getDef(); 3046394861Swren romano // Inlining the first part of `Record::getValueAsString` to give better 3146394861Swren romano // error messages. 3246394861Swren romano const llvm::RecordVal *type = record->getValue("type"); 3346394861Swren romano if (!type || !type->getValue()) { 3446394861Swren romano llvm::PrintFatalError("Builder DAG arguments must be either strings or " 3546394861Swren romano "defs which inherit from CArg"); 3646394861Swren romano } 3720741773SRiver Riddle return record->getValueAsString("type"); 3820741773SRiver Riddle } 3920741773SRiver Riddle 4020741773SRiver Riddle /// Return an optional string containing the default value to use for this 4120741773SRiver Riddle /// parameter. 423cfe412eSFangrui Song std::optional<StringRef> Builder::Parameter::getDefaultValue() const { 43*659192b1SRahul Joshi if (isa<StringInit>(def)) 441a36588eSKazu Hirata return std::nullopt; 45*659192b1SRahul Joshi const Record *record = cast<DefInit>(def)->getDef(); 463cfe412eSFangrui Song std::optional<StringRef> value = 473cfe412eSFangrui Song record->getValueAsOptionalString("defaultValue"); 481a36588eSKazu Hirata return value && !value->empty() ? value : std::nullopt; 4920741773SRiver Riddle } 5020741773SRiver Riddle 5120741773SRiver Riddle //===----------------------------------------------------------------------===// 5220741773SRiver Riddle // Builder 5320741773SRiver Riddle //===----------------------------------------------------------------------===// 5420741773SRiver Riddle 55*659192b1SRahul Joshi Builder::Builder(const Record *record, ArrayRef<SMLoc> loc) : def(record) { 5620741773SRiver Riddle // Initialize the parameters of the builder. 57*659192b1SRahul Joshi const DagInit *dag = def->getValueAsDag("dagParams"); 58*659192b1SRahul Joshi auto *defInit = dyn_cast<DefInit>(dag->getOperator()); 59dec8055aSKazu Hirata if (!defInit || defInit->getDef()->getName() != "ins") 6020741773SRiver Riddle PrintFatalError(def->getLoc(), "expected 'ins' in builders"); 6120741773SRiver Riddle 6220741773SRiver Riddle bool seenDefaultValue = false; 6320741773SRiver Riddle for (unsigned i = 0, e = dag->getNumArgs(); i < e; ++i) { 64*659192b1SRahul Joshi const StringInit *paramName = dag->getArgName(i); 65*659192b1SRahul Joshi const Init *paramValue = dag->getArg(i); 663cfe412eSFangrui Song Parameter param(paramName ? paramName->getValue() 673cfe412eSFangrui Song : std::optional<StringRef>(), 6820741773SRiver Riddle paramValue); 6920741773SRiver Riddle 7020741773SRiver Riddle // Similarly to C++, once an argument with a default value is detected, the 7120741773SRiver Riddle // following arguments must have default values as well. 7220741773SRiver Riddle if (param.getDefaultValue()) { 7320741773SRiver Riddle seenDefaultValue = true; 7420741773SRiver Riddle } else if (seenDefaultValue) { 7520741773SRiver Riddle PrintFatalError(loc, 7620741773SRiver Riddle "expected an argument with default value after other " 7720741773SRiver Riddle "arguments with default values"); 7820741773SRiver Riddle } 7920741773SRiver Riddle parameters.emplace_back(param); 8020741773SRiver Riddle } 8120741773SRiver Riddle } 8220741773SRiver Riddle 8320741773SRiver Riddle /// Return an optional string containing the body of the builder. 843cfe412eSFangrui Song std::optional<StringRef> Builder::getBody() const { 853cfe412eSFangrui Song std::optional<StringRef> body = def->getValueAsOptionalString("body"); 861a36588eSKazu Hirata return body && !body->empty() ? body : std::nullopt; 8720741773SRiver Riddle } 880f827ee0SMarkus Böck 890f827ee0SMarkus Böck std::optional<StringRef> Builder::getDeprecatedMessage() const { 900f827ee0SMarkus Böck std::optional<StringRef> message = 910f827ee0SMarkus Böck def->getValueAsOptionalString("odsCppDeprecated"); 920f827ee0SMarkus Böck return message && !message->empty() ? message : std::nullopt; 930f827ee0SMarkus Böck } 94