18f5fa566SLei Zhang //===- Type.cpp - Type class ----------------------------------------------===// 2b2cc2c34SLei Zhang // 330857107SMehdi Amini // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 456222a06SMehdi Amini // See https://llvm.org/LICENSE.txt for license information. 556222a06SMehdi Amini // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6b2cc2c34SLei Zhang // 756222a06SMehdi Amini //===----------------------------------------------------------------------===// 8b2cc2c34SLei Zhang // 9b2cc2c34SLei Zhang // Type wrapper to simplify using TableGen Record defining a MLIR Type. 10b2cc2c34SLei Zhang // 11b2cc2c34SLei Zhang //===----------------------------------------------------------------------===// 12b2cc2c34SLei Zhang 13b2cc2c34SLei Zhang #include "mlir/TableGen/Type.h" 14c42cee0cSRiver Riddle #include "mlir/TableGen/Dialect.h" 15c42cee0cSRiver Riddle #include "llvm/ADT/Twine.h" 16ebf190fcSRiver Riddle #include "llvm/ADT/TypeSwitch.h" 17b2cc2c34SLei Zhang #include "llvm/TableGen/Record.h" 18b2cc2c34SLei Zhang 19b2cc2c34SLei Zhang using namespace mlir; 2027e8efedSJacques Pienaar using namespace mlir::tblgen; 21b2cc2c34SLei Zhang TypeConstraint(const llvm::DefInit * init)2227e8efedSJacques PienaarTypeConstraint::TypeConstraint(const llvm::DefInit *init) 238f5fa566SLei Zhang : TypeConstraint(init->getDef()) {} 2444e9869fSAlex Zinenko isOptional() const25aba1acc8SRiver Riddlebool TypeConstraint::isOptional() const { 26aba1acc8SRiver Riddle return def->isSubClassOf("Optional"); 27aba1acc8SRiver Riddle } 28aba1acc8SRiver Riddle isVariadic() const2927e8efedSJacques Pienaarbool TypeConstraint::isVariadic() const { 30509cd739SJacques Pienaar return def->isSubClassOf("Variadic"); 31509cd739SJacques Pienaar } 3227e8efedSJacques Pienaar isVariadicOfVariadic() const33*4e103a12SRiver Riddlebool TypeConstraint::isVariadicOfVariadic() const { 34*4e103a12SRiver Riddle return def->isSubClassOf("VariadicOfVariadic"); 35*4e103a12SRiver Riddle } 36*4e103a12SRiver Riddle getVariadicOfVariadicSegmentSizeAttr() const37*4e103a12SRiver RiddleStringRef TypeConstraint::getVariadicOfVariadicSegmentSizeAttr() const { 38*4e103a12SRiver Riddle assert(isVariadicOfVariadic()); 39*4e103a12SRiver Riddle return def->getValueAsString("segmentAttrName"); 40*4e103a12SRiver Riddle } 41*4e103a12SRiver Riddle 42b3a1d09cSRiver Riddle // Returns the builder call for this constraint if this is a buildable type, 43b3a1d09cSRiver Riddle // returns None otherwise. getBuilderCall() const44b3a1d09cSRiver RiddleOptional<StringRef> TypeConstraint::getBuilderCall() const { 45b3a1d09cSRiver Riddle const llvm::Record *baseType = def; 46aba1acc8SRiver Riddle if (isVariableLength()) 47b3a1d09cSRiver Riddle baseType = baseType->getValueAsDef("baseType"); 48b3a1d09cSRiver Riddle 49fbba6395SRiver Riddle // Check to see if this type constraint has a builder call. 50fbba6395SRiver Riddle const llvm::RecordVal *builderCall = baseType->getValue("builderCall"); 51fbba6395SRiver Riddle if (!builderCall || !builderCall->getValue()) 52fbba6395SRiver Riddle return llvm::None; 53fbba6395SRiver Riddle return TypeSwitch<llvm::Init *, Optional<StringRef>>(builderCall->getValue()) 54415fab6fSPaul C. Anagnostopoulos .Case<llvm::StringInit>([&](auto *init) { 55fbba6395SRiver Riddle StringRef value = init->getValue(); 56fbba6395SRiver Riddle return value.empty() ? Optional<StringRef>() : value; 57fbba6395SRiver Riddle }) 58fbba6395SRiver Riddle .Default([](auto *) { return llvm::None; }); 59b3a1d09cSRiver Riddle } 60b3a1d09cSRiver Riddle 619eb3e564SChris Lattner // Return the C++ class name for this type (which may just be ::mlir::Type). getCPPClassName() const62c42cee0cSRiver Riddlestd::string TypeConstraint::getCPPClassName() const { 63c42cee0cSRiver Riddle StringRef className = def->getValueAsString("cppClassName"); 64c42cee0cSRiver Riddle 65c42cee0cSRiver Riddle // If the class name is already namespace resolved, use it. 66c42cee0cSRiver Riddle if (className.contains("::")) 67c42cee0cSRiver Riddle return className.str(); 68c42cee0cSRiver Riddle 69c42cee0cSRiver Riddle // Otherwise, check to see if there is a namespace from a dialect to prepend. 70c42cee0cSRiver Riddle if (const llvm::RecordVal *value = def->getValue("dialect")) { 71c42cee0cSRiver Riddle Dialect dialect(cast<const llvm::DefInit>(value->getValue())->getDef()); 72c42cee0cSRiver Riddle return (dialect.getCppNamespace() + "::" + className).str(); 73c42cee0cSRiver Riddle } 74c42cee0cSRiver Riddle return className.str(); 759eb3e564SChris Lattner } 769eb3e564SChris Lattner Type(const llvm::Record * record)7727e8efedSJacques PienaarType::Type(const llvm::Record *record) : TypeConstraint(record) {} 7827e8efedSJacques Pienaar getDialect() const7927e8efedSJacques PienaarDialect Type::getDialect() const { 8027e8efedSJacques Pienaar return Dialect(def->getValueAsDef("dialect")); 8127e8efedSJacques Pienaar } 82