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; 1520741773SRiver Riddle 1620741773SRiver Riddle //===----------------------------------------------------------------------===// 1720741773SRiver Riddle // Builder::Parameter 1820741773SRiver Riddle //===----------------------------------------------------------------------===// 1920741773SRiver Riddle 2020741773SRiver Riddle /// Return a string containing the C++ type of this parameter. getCppType() const2120741773SRiver RiddleStringRef Builder::Parameter::getCppType() const { 2220741773SRiver Riddle if (const auto *stringInit = dyn_cast<llvm::StringInit>(def)) 2320741773SRiver Riddle return stringInit->getValue(); 2420741773SRiver Riddle const llvm::Record *record = cast<llvm::DefInit>(def)->getDef(); 25*46394861Swren romano // Inlining the first part of `Record::getValueAsString` to give better 26*46394861Swren romano // error messages. 27*46394861Swren romano const llvm::RecordVal *type = record->getValue("type"); 28*46394861Swren romano if (!type || !type->getValue()) { 29*46394861Swren romano llvm::PrintFatalError("Builder DAG arguments must be either strings or " 30*46394861Swren romano "defs which inherit from CArg"); 31*46394861Swren romano } 3220741773SRiver Riddle return record->getValueAsString("type"); 3320741773SRiver Riddle } 3420741773SRiver Riddle 3520741773SRiver Riddle /// Return an optional string containing the default value to use for this 3620741773SRiver Riddle /// parameter. getDefaultValue() const3720741773SRiver RiddleOptional<StringRef> Builder::Parameter::getDefaultValue() const { 3820741773SRiver Riddle if (isa<llvm::StringInit>(def)) 3920741773SRiver Riddle return llvm::None; 4020741773SRiver Riddle const llvm::Record *record = cast<llvm::DefInit>(def)->getDef(); 4120741773SRiver Riddle Optional<StringRef> value = record->getValueAsOptionalString("defaultValue"); 4220741773SRiver Riddle return value && !value->empty() ? value : llvm::None; 4320741773SRiver Riddle } 4420741773SRiver Riddle 4520741773SRiver Riddle //===----------------------------------------------------------------------===// 4620741773SRiver Riddle // Builder 4720741773SRiver Riddle //===----------------------------------------------------------------------===// 4820741773SRiver Riddle Builder(const llvm::Record * record,ArrayRef<SMLoc> loc)496842ec42SRiver RiddleBuilder::Builder(const llvm::Record *record, ArrayRef<SMLoc> loc) 5020741773SRiver Riddle : def(record) { 5120741773SRiver Riddle // Initialize the parameters of the builder. 5220741773SRiver Riddle const llvm::DagInit *dag = def->getValueAsDag("dagParams"); 5320741773SRiver Riddle auto *defInit = dyn_cast<llvm::DefInit>(dag->getOperator()); 5420741773SRiver Riddle if (!defInit || !defInit->getDef()->getName().equals("ins")) 5520741773SRiver Riddle PrintFatalError(def->getLoc(), "expected 'ins' in builders"); 5620741773SRiver Riddle 5720741773SRiver Riddle bool seenDefaultValue = false; 5820741773SRiver Riddle for (unsigned i = 0, e = dag->getNumArgs(); i < e; ++i) { 5920741773SRiver Riddle const llvm::StringInit *paramName = dag->getArgName(i); 6020741773SRiver Riddle const llvm::Init *paramValue = dag->getArg(i); 6120741773SRiver Riddle Parameter param(paramName ? paramName->getValue() : Optional<StringRef>(), 6220741773SRiver Riddle paramValue); 6320741773SRiver Riddle 6420741773SRiver Riddle // Similarly to C++, once an argument with a default value is detected, the 6520741773SRiver Riddle // following arguments must have default values as well. 6620741773SRiver Riddle if (param.getDefaultValue()) { 6720741773SRiver Riddle seenDefaultValue = true; 6820741773SRiver Riddle } else if (seenDefaultValue) { 6920741773SRiver Riddle PrintFatalError(loc, 7020741773SRiver Riddle "expected an argument with default value after other " 7120741773SRiver Riddle "arguments with default values"); 7220741773SRiver Riddle } 7320741773SRiver Riddle parameters.emplace_back(param); 7420741773SRiver Riddle } 7520741773SRiver Riddle } 7620741773SRiver Riddle 7720741773SRiver Riddle /// Return an optional string containing the body of the builder. getBody() const7820741773SRiver RiddleOptional<StringRef> Builder::getBody() const { 7920741773SRiver Riddle Optional<StringRef> body = def->getValueAsOptionalString("body"); 8020741773SRiver Riddle return body && !body->empty() ? body : llvm::None; 8120741773SRiver Riddle } 82