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