1*20741773SRiver Riddle //===- Builder.cpp - Builder definitions ----------------------------------===// 2*20741773SRiver Riddle // 3*20741773SRiver Riddle // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*20741773SRiver Riddle // See https://llvm.org/LICENSE.txt for license information. 5*20741773SRiver Riddle // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*20741773SRiver Riddle // 7*20741773SRiver Riddle //===----------------------------------------------------------------------===// 8*20741773SRiver Riddle 9*20741773SRiver Riddle #include "mlir/TableGen/Builder.h" 10*20741773SRiver Riddle #include "llvm/TableGen/Error.h" 11*20741773SRiver Riddle #include "llvm/TableGen/Record.h" 12*20741773SRiver Riddle 13*20741773SRiver Riddle using namespace mlir; 14*20741773SRiver Riddle using namespace mlir::tblgen; 15*20741773SRiver Riddle 16*20741773SRiver Riddle //===----------------------------------------------------------------------===// 17*20741773SRiver Riddle // Builder::Parameter 18*20741773SRiver Riddle //===----------------------------------------------------------------------===// 19*20741773SRiver Riddle 20*20741773SRiver Riddle /// Return a string containing the C++ type of this parameter. 21*20741773SRiver Riddle StringRef Builder::Parameter::getCppType() const { 22*20741773SRiver Riddle if (const auto *stringInit = dyn_cast<llvm::StringInit>(def)) 23*20741773SRiver Riddle return stringInit->getValue(); 24*20741773SRiver Riddle const llvm::Record *record = cast<llvm::DefInit>(def)->getDef(); 25*20741773SRiver Riddle return record->getValueAsString("type"); 26*20741773SRiver Riddle } 27*20741773SRiver Riddle 28*20741773SRiver Riddle /// Return an optional string containing the default value to use for this 29*20741773SRiver Riddle /// parameter. 30*20741773SRiver Riddle Optional<StringRef> Builder::Parameter::getDefaultValue() const { 31*20741773SRiver Riddle if (isa<llvm::StringInit>(def)) 32*20741773SRiver Riddle return llvm::None; 33*20741773SRiver Riddle const llvm::Record *record = cast<llvm::DefInit>(def)->getDef(); 34*20741773SRiver Riddle Optional<StringRef> value = record->getValueAsOptionalString("defaultValue"); 35*20741773SRiver Riddle return value && !value->empty() ? value : llvm::None; 36*20741773SRiver Riddle } 37*20741773SRiver Riddle 38*20741773SRiver Riddle //===----------------------------------------------------------------------===// 39*20741773SRiver Riddle // Builder 40*20741773SRiver Riddle //===----------------------------------------------------------------------===// 41*20741773SRiver Riddle 42*20741773SRiver Riddle Builder::Builder(const llvm::Record *record, ArrayRef<llvm::SMLoc> loc) 43*20741773SRiver Riddle : def(record) { 44*20741773SRiver Riddle // Initialize the parameters of the builder. 45*20741773SRiver Riddle const llvm::DagInit *dag = def->getValueAsDag("dagParams"); 46*20741773SRiver Riddle auto *defInit = dyn_cast<llvm::DefInit>(dag->getOperator()); 47*20741773SRiver Riddle if (!defInit || !defInit->getDef()->getName().equals("ins")) 48*20741773SRiver Riddle PrintFatalError(def->getLoc(), "expected 'ins' in builders"); 49*20741773SRiver Riddle 50*20741773SRiver Riddle bool seenDefaultValue = false; 51*20741773SRiver Riddle for (unsigned i = 0, e = dag->getNumArgs(); i < e; ++i) { 52*20741773SRiver Riddle const llvm::StringInit *paramName = dag->getArgName(i); 53*20741773SRiver Riddle const llvm::Init *paramValue = dag->getArg(i); 54*20741773SRiver Riddle Parameter param(paramName ? paramName->getValue() : Optional<StringRef>(), 55*20741773SRiver Riddle paramValue); 56*20741773SRiver Riddle 57*20741773SRiver Riddle // Similarly to C++, once an argument with a default value is detected, the 58*20741773SRiver Riddle // following arguments must have default values as well. 59*20741773SRiver Riddle if (param.getDefaultValue()) { 60*20741773SRiver Riddle seenDefaultValue = true; 61*20741773SRiver Riddle } else if (seenDefaultValue) { 62*20741773SRiver Riddle PrintFatalError(loc, 63*20741773SRiver Riddle "expected an argument with default value after other " 64*20741773SRiver Riddle "arguments with default values"); 65*20741773SRiver Riddle } 66*20741773SRiver Riddle parameters.emplace_back(param); 67*20741773SRiver Riddle } 68*20741773SRiver Riddle } 69*20741773SRiver Riddle 70*20741773SRiver Riddle /// Return an optional string containing the body of the builder. 71*20741773SRiver Riddle Optional<StringRef> Builder::getBody() const { 72*20741773SRiver Riddle Optional<StringRef> body = def->getValueAsOptionalString("body"); 73*20741773SRiver Riddle return body && !body->empty() ? body : llvm::None; 74*20741773SRiver Riddle } 75