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