15#include "mlir/IR/DialectImplementation.h" 
   20#include "llvm/ADT/TypeSwitch.h" 
   26  if (
auto sizedTy = mlir::dyn_cast<cir::SizedTypeInterface>(ty))
 
   27    return sizedTy.isSized();
 
 
   36static mlir::ParseResult
 
   40                                mlir::ArrayRef<mlir::Type> params,
 
   46static mlir::ParseResult
 
   51                                mlir::ArrayRef<mlir::Type> params,
 
   59                                          cir::TargetAddressSpaceAttr &attr);
 
   62                             cir::TargetAddressSpaceAttr attr);
 
   70#include "clang/CIR/Dialect/IR/CIRTypeConstraints.cpp.inc" 
   74#define GET_TYPEDEF_CLASSES 
   75#include "clang/CIR/Dialect/IR/CIROpsTypes.cpp.inc" 
   84Type CIRDialect::parseType(DialectAsmParser &parser)
 const {
 
   85  llvm::SMLoc typeLoc = parser.getCurrentLocation();
 
   86  llvm::StringRef mnemonic;
 
   90  OptionalParseResult parseResult =
 
   91      generatedTypeParser(parser, &mnemonic, genType);
 
   92  if (parseResult.has_value())
 
   96  return StringSwitch<function_ref<Type()>>(mnemonic)
 
   97      .Case(
"record", [&] { 
return RecordType::parse(parser); })
 
   99        parser.emitError(typeLoc) << 
"unknown CIR type: " << mnemonic;
 
  104void CIRDialect::printType(Type type, DialectAsmPrinter &os)
 const {
 
  106  if (generatedTypePrinter(type, os).succeeded())
 
  110  llvm::report_fatal_error(
"printer is missing a handler for this type");
 
  117Type RecordType::parse(mlir::AsmParser &parser) {
 
  118  FailureOr<AsmParser::CyclicParseReset> cyclicParseGuard;
 
  119  const llvm::SMLoc loc = parser.getCurrentLocation();
 
  120  const mlir::Location eLoc = parser.getEncodedSourceLoc(loc);
 
  124  mlir::MLIRContext *context = parser.getContext();
 
  126  if (parser.parseLess())
 
  131  if (parser.parseOptionalKeyword(
"struct").succeeded())
 
  132    kind = RecordKind::Struct;
 
  133  else if (parser.parseOptionalKeyword(
"union").succeeded())
 
  134    kind = RecordKind::Union;
 
  135  else if (parser.parseOptionalKeyword(
"class").succeeded())
 
  136    kind = RecordKind::Class;
 
  138    parser.emitError(loc, 
"unknown record type");
 
  142  mlir::StringAttr 
name;
 
  143  parser.parseOptionalAttribute(name);
 
  146  if (name && parser.parseOptionalGreater().succeeded()) {
 
  147    RecordType 
type = getChecked(eLoc, context, name, kind);
 
  148    if (succeeded(parser.tryStartCyclicParse(type))) {
 
  149      parser.emitError(loc, 
"invalid self-reference within record");
 
  157    RecordType 
type = getChecked(eLoc, context, name, kind);
 
  158    cyclicParseGuard = parser.tryStartCyclicParse(type);
 
  159    if (failed(cyclicParseGuard)) {
 
  160      parser.emitError(loc, 
"record already defined");
 
  165  if (parser.parseOptionalKeyword(
"packed").succeeded())
 
  168  if (parser.parseOptionalKeyword(
"padded").succeeded())
 
  172  bool incomplete = 
true;
 
  173  llvm::SmallVector<mlir::Type> members;
 
  174  if (parser.parseOptionalKeyword(
"incomplete").failed()) {
 
  176    const auto delimiter = AsmParser::Delimiter::Braces;
 
  177    const auto parseElementFn = [&parser, &members]() {
 
  178      return parser.parseType(members.emplace_back());
 
  180    if (parser.parseCommaSeparatedList(delimiter, parseElementFn).failed())
 
  184  if (parser.parseGreater())
 
  188  ArrayRef<mlir::Type> membersRef(members); 
 
  189  mlir::Type 
type = {};
 
  190  if (name && incomplete) { 
 
  191    type = getChecked(eLoc, context, name, kind);
 
  192  } 
else if (!name && !incomplete) { 
 
  193    type = getChecked(eLoc, context, membersRef, packed, padded, kind);
 
  194  } 
else if (!incomplete) { 
 
  195    type = getChecked(eLoc, context, membersRef, name, packed, padded, kind);
 
  198    if (mlir::cast<RecordType>(type).isIncomplete())
 
  199      mlir::cast<RecordType>(type).complete(membersRef, packed, padded);
 
  202    parser.emitError(loc, 
"anonymous records must be complete");
 
  209void RecordType::print(mlir::AsmPrinter &printer)
 const {
 
  210  FailureOr<AsmPrinter::CyclicPrintReset> cyclicPrintGuard;
 
  214  case RecordKind::Struct:
 
  215    printer << 
"struct ";
 
  217  case RecordKind::Union:
 
  220  case RecordKind::Class:
 
  229  cyclicPrintGuard = printer.tryStartCyclicPrint(*
this);
 
  230  if (failed(cyclicPrintGuard)) {
 
  239    printer << 
"packed ";
 
  242    printer << 
"padded ";
 
  244  if (isIncomplete()) {
 
  245    printer << 
"incomplete";
 
  248    llvm::interleaveComma(getMembers(), printer);
 
  256RecordType::verify(function_ref<mlir::InFlightDiagnostic()> emitError,
 
  257                   llvm::ArrayRef<mlir::Type> members, mlir::StringAttr name,
 
  258                   bool incomplete, 
bool packed, 
bool padded,
 
  259                   RecordType::RecordKind kind) {
 
  260  if (name && 
name.getValue().empty())
 
  261    return emitError() << 
"identified records cannot have an empty name";
 
  262  return mlir::success();
 
  265::llvm::ArrayRef<mlir::Type> RecordType::getMembers()
 const {
 
  269bool RecordType::isIncomplete()
 const { 
return getImpl()->incomplete; }
 
  271mlir::StringAttr RecordType::getName()
 const { 
return getImpl()->name; }
 
  273bool RecordType::getIncomplete()
 const { 
return getImpl()->incomplete; }
 
  275bool RecordType::getPacked()
 const { 
return getImpl()->packed; }
 
  277bool RecordType::getPadded()
 const { 
return getImpl()->padded; }
 
  279cir::RecordType::RecordKind RecordType::getKind()
 const {
 
  283void RecordType::complete(ArrayRef<Type> members, 
bool packed, 
bool padded) {
 
  285  if (mutate(members, packed, padded).failed())
 
  286    llvm_unreachable(
"failed to complete record");
 
  292Type RecordType::getLargestMember(const ::mlir::DataLayout &dataLayout)
 const {
 
  293  assert(isUnion() && 
"Only call getLargestMember on unions");
 
  294  llvm::ArrayRef<Type> members = getMembers();
 
  297  return *std::max_element(
 
  298      members.begin(), getPadded() ? members.end() - 1 : members.end(),
 
  299      [&](Type lhs, Type rhs) {
 
  300        return dataLayout.getTypeABIAlignment(lhs) <
 
  301                   dataLayout.getTypeABIAlignment(rhs) ||
 
  302               (dataLayout.getTypeABIAlignment(lhs) ==
 
  303                    dataLayout.getTypeABIAlignment(rhs) &&
 
  304                dataLayout.getTypeSize(lhs) < dataLayout.getTypeSize(rhs));
 
  308bool RecordType::isLayoutIdentical(
const RecordType &other) {
 
  309  if (
getImpl() == other.getImpl())
 
  312  if (getPacked() != other.getPacked())
 
  315  return getMembers() == other.getMembers();
 
  323PointerType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
 
  324                               ::mlir::DataLayoutEntryListRef params)
 const {
 
  327  return llvm::TypeSize::getFixed(64);
 
  331PointerType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
 
  332                             ::mlir::DataLayoutEntryListRef params)
 const {
 
  339RecordType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
 
  340                              mlir::DataLayoutEntryListRef params)
 const {
 
  342    return dataLayout.getTypeSize(getLargestMember(dataLayout));
 
  344  unsigned recordSize = computeStructSize(dataLayout);
 
  345  return llvm::TypeSize::getFixed(recordSize * 8);
 
  349RecordType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
 
  350                            ::mlir::DataLayoutEntryListRef params)
 const {
 
  352    return dataLayout.getTypeABIAlignment(getLargestMember(dataLayout));
 
  357  return computeStructAlignment(dataLayout);
 
  361RecordType::computeStructSize(
const mlir::DataLayout &dataLayout)
 const {
 
  362  assert(isComplete() && 
"Cannot get layout of incomplete records");
 
  365  unsigned recordSize = 0;
 
  368  for (mlir::Type ty : getMembers()) {
 
  372        (getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
 
  376    recordSize = llvm::alignTo(recordSize, tyAlign);
 
  377    recordSize += dataLayout.getTypeSize(ty);
 
  381    recordAlignment = std::max(tyAlign, recordAlignment);
 
  386  recordSize = llvm::alignTo(recordSize, recordAlignment);
 
  395RecordType::computeStructAlignment(
const mlir::DataLayout &dataLayout)
 const {
 
  396  assert(isComplete() && 
"Cannot get layout of incomplete records");
 
  400  for (mlir::Type ty : getMembers())
 
  402        std::max(dataLayout.getTypeABIAlignment(ty), recordAlignment);
 
  404  return recordAlignment;
 
  407uint64_t RecordType::getElementOffset(const ::mlir::DataLayout &dataLayout,
 
  408                                      unsigned idx)
 const {
 
  409  assert(idx < getMembers().size() && 
"access not valid");
 
  412  if (isUnion() || idx == 0)
 
  415  assert(isComplete() && 
"Cannot get layout of incomplete records");
 
  416  assert(idx < getNumElements());
 
  417  llvm::ArrayRef<mlir::Type> members = getMembers();
 
  422       llvm::make_range(members.begin(), std::next(members.begin(), idx))) {
 
  424    const llvm::Align tyAlign =
 
  425        llvm::Align(getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
 
  428    offset = llvm::alignTo(offset, tyAlign);
 
  431    offset += dataLayout.getTypeSize(ty);
 
  436  const llvm::Align tyAlign = llvm::Align(
 
  437      getPacked() ? 1 : dataLayout.getTypeABIAlignment(members[idx]));
 
  438  offset = llvm::alignTo(offset, tyAlign);
 
  447Type IntType::parse(mlir::AsmParser &parser) {
 
  448  mlir::MLIRContext *context = parser.getBuilder().getContext();
 
  449  llvm::SMLoc loc = parser.getCurrentLocation();
 
  453  if (parser.parseLess())
 
  457  llvm::StringRef 
sign;
 
  458  if (parser.parseKeyword(&
sign))
 
  462  else if (
sign == 
"u")
 
  465    parser.emitError(loc, 
"expected 's' or 'u'");
 
  469  if (parser.parseComma())
 
  473  if (parser.parseInteger(width))
 
  475  if (width < IntType::minBitwidth() || width > IntType::maxBitwidth()) {
 
  476    parser.emitError(loc, 
"expected integer width to be from ")
 
  477        << IntType::minBitwidth() << 
" up to " << IntType::maxBitwidth();
 
  481  if (parser.parseGreater())
 
  484  return IntType::get(context, width, isSigned);
 
  487void IntType::print(mlir::AsmPrinter &printer)
 const {
 
  488  char sign = isSigned() ? 
's' : 
'u';
 
  489  printer << 
'<' << 
sign << 
", " << getWidth() << 
'>';
 
  493IntType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
 
  494                           mlir::DataLayoutEntryListRef params)
 const {
 
  495  return llvm::TypeSize::getFixed(getWidth());
 
  498uint64_t IntType::getABIAlignment(
const mlir::DataLayout &dataLayout,
 
  499                                  mlir::DataLayoutEntryListRef params)
 const {
 
  500  return (uint64_t)(getWidth() / 8);
 
  504IntType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
 
  505                unsigned width, 
bool isSigned) {
 
  506  if (width < IntType::minBitwidth() || width > IntType::maxBitwidth())
 
  507    return emitError() << 
"IntType only supports widths from " 
  508                       << IntType::minBitwidth() << 
" up to " 
  509                       << IntType::maxBitwidth();
 
  510  return mlir::success();
 
  514  return width == 8 || width == 16 || width == 32 || width == 64;
 
 
  521const llvm::fltSemantics &SingleType::getFloatSemantics()
 const {
 
  522  return llvm::APFloat::IEEEsingle();
 
  526SingleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
 
  527                              mlir::DataLayoutEntryListRef params)
 const {
 
  528  return llvm::TypeSize::getFixed(getWidth());
 
  532SingleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
 
  533                            mlir::DataLayoutEntryListRef params)
 const {
 
  534  return (uint64_t)(getWidth() / 8);
 
  537const llvm::fltSemantics &DoubleType::getFloatSemantics()
 const {
 
  538  return llvm::APFloat::IEEEdouble();
 
  542DoubleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
 
  543                              mlir::DataLayoutEntryListRef params)
 const {
 
  544  return llvm::TypeSize::getFixed(getWidth());
 
  548DoubleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
 
  549                            mlir::DataLayoutEntryListRef params)
 const {
 
  550  return (uint64_t)(getWidth() / 8);
 
  553const llvm::fltSemantics &FP16Type::getFloatSemantics()
 const {
 
  554  return llvm::APFloat::IEEEhalf();
 
  558FP16Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
 
  559                            mlir::DataLayoutEntryListRef params)
 const {
 
  560  return llvm::TypeSize::getFixed(getWidth());
 
  563uint64_t FP16Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
 
  564                                   mlir::DataLayoutEntryListRef params)
 const {
 
  565  return (uint64_t)(getWidth() / 8);
 
  568const llvm::fltSemantics &BF16Type::getFloatSemantics()
 const {
 
  569  return llvm::APFloat::BFloat();
 
  573BF16Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
 
  574                            mlir::DataLayoutEntryListRef params)
 const {
 
  575  return llvm::TypeSize::getFixed(getWidth());
 
  578uint64_t BF16Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
 
  579                                   mlir::DataLayoutEntryListRef params)
 const {
 
  580  return (uint64_t)(getWidth() / 8);
 
  583const llvm::fltSemantics &FP80Type::getFloatSemantics()
 const {
 
  584  return llvm::APFloat::x87DoubleExtended();
 
  588FP80Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
 
  589                            mlir::DataLayoutEntryListRef params)
 const {
 
  591  return llvm::TypeSize::getFixed(128);
 
  594uint64_t FP80Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
 
  595                                   mlir::DataLayoutEntryListRef params)
 const {
 
  599const llvm::fltSemantics &FP128Type::getFloatSemantics()
 const {
 
  600  return llvm::APFloat::IEEEquad();
 
  604FP128Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
 
  605                             mlir::DataLayoutEntryListRef params)
 const {
 
  606  return llvm::TypeSize::getFixed(getWidth());
 
  609uint64_t FP128Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
 
  610                                    mlir::DataLayoutEntryListRef params)
 const {
 
  614const llvm::fltSemantics &LongDoubleType::getFloatSemantics()
 const {
 
  615  return mlir::cast<cir::FPTypeInterface>(getUnderlying()).getFloatSemantics();
 
  619LongDoubleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
 
  620                                  mlir::DataLayoutEntryListRef params)
 const {
 
  621  return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
 
  622      .getTypeSizeInBits(dataLayout, params);
 
  626LongDoubleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
 
  627                                mlir::DataLayoutEntryListRef params)
 const {
 
  628  return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
 
  629      .getABIAlignment(dataLayout, params);
 
  637cir::ComplexType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
 
  638                                    mlir::DataLayoutEntryListRef params)
 const {
 
  644  return dataLayout.getTypeSizeInBits(getElementType()) * 2;
 
  648cir::ComplexType::getABIAlignment(
const mlir::DataLayout &dataLayout,
 
  649                                  mlir::DataLayoutEntryListRef params)
 const {
 
  655  return dataLayout.getTypeABIAlignment(getElementType());
 
  658FuncType FuncType::clone(TypeRange inputs, TypeRange results)
 const {
 
  659  assert(results.size() == 1 && 
"expected exactly one result type");
 
  660  return get(llvm::to_vector(inputs), results[0], isVarArg());
 
  664static mlir::ParseResult
 
  668  return p.parseCommaSeparatedList(
 
  669      AsmParser::Delimiter::Paren, [&]() -> mlir::ParseResult {
 
  671          return p.emitError(p.getCurrentLocation(),
 
  672                             "variadic `...` must be the last parameter");
 
  673        if (succeeded(p.parseOptionalEllipsis())) {
 
  678        if (failed(p.parseType(type)))
 
  680        params.push_back(type);
 
 
  686                                mlir::ArrayRef<mlir::Type> params,
 
  689  llvm::interleaveComma(params, p,
 
  690                        [&p](mlir::Type type) { p.printType(type); });
 
 
  701mlir::Type FuncType::getReturnType()
 const {
 
  703    return cir::VoidType::get(getContext());
 
  704  return getOptionalReturnType();
 
  710llvm::ArrayRef<mlir::Type> FuncType::getReturnTypes()
 const {
 
  716  return getImpl()->optionalReturnType;
 
  720bool FuncType::hasVoidReturn()
 const { 
return !getOptionalReturnType(); }
 
  723FuncType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
 
  724                 llvm::ArrayRef<mlir::Type> argTypes, mlir::Type returnType,
 
  726  if (mlir::isa_and_nonnull<cir::VoidType>(returnType))
 
  728           << 
"!cir.func cannot have an explicit 'void' return type";
 
  729  return mlir::success();
 
  737BoolType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
 
  738                            ::mlir::DataLayoutEntryListRef params)
 const {
 
  739  return llvm::TypeSize::getFixed(8);
 
  743BoolType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
 
  744                          ::mlir::DataLayoutEntryListRef params)
 const {
 
  753VPtrType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
 
  754                            mlir::DataLayoutEntryListRef params)
 const {
 
  756  return llvm::TypeSize::getFixed(64);
 
  759uint64_t VPtrType::getABIAlignment(
const mlir::DataLayout &dataLayout,
 
  760                                   mlir::DataLayoutEntryListRef params)
 const {
 
  770ArrayType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
 
  771                             ::mlir::DataLayoutEntryListRef params)
 const {
 
  772  return getSize() * dataLayout.getTypeSizeInBits(getElementType());
 
  776ArrayType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
 
  777                           ::mlir::DataLayoutEntryListRef params)
 const {
 
  778  return dataLayout.getTypeABIAlignment(getElementType());
 
  785llvm::TypeSize cir::VectorType::getTypeSizeInBits(
 
  786    const ::mlir::DataLayout &dataLayout,
 
  787    ::mlir::DataLayoutEntryListRef params)
 const {
 
  788  return llvm::TypeSize::getFixed(
 
  789      getSize() * dataLayout.getTypeSizeInBits(getElementType()));
 
  793cir::VectorType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
 
  794                                 ::mlir::DataLayoutEntryListRef params)
 const {
 
  795  return llvm::NextPowerOf2(dataLayout.getTypeSizeInBits(*
this));
 
  798mlir::LogicalResult cir::VectorType::verify(
 
  799    llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
 
  800    mlir::Type elementType, uint64_t size) {
 
  802    return emitError() << 
"the number of vector elements must be non-zero";
 
  811                                          cir::TargetAddressSpaceAttr &attr) {
 
  812  if (failed(p.parseKeyword(
"target_address_space")))
 
  813    return mlir::failure();
 
  815  if (failed(p.parseLParen()))
 
  816    return mlir::failure();
 
  819  if (failed(p.parseInteger(targetValue)))
 
  820    return p.emitError(p.getCurrentLocation(),
 
  821                       "expected integer address space value");
 
  823  if (failed(p.parseRParen()))
 
  824    return p.emitError(p.getCurrentLocation(),
 
  825                       "expected ')' after address space value");
 
  827  mlir::MLIRContext *context = p.getBuilder().getContext();
 
  828  attr = cir::TargetAddressSpaceAttr::get(
 
  829      context, p.getBuilder().getUI32IntegerAttr(targetValue));
 
  830  return mlir::success();
 
 
  836                             cir::TargetAddressSpaceAttr attr) {
 
  837  p << 
"target_address_space(" << attr.getValue().getUInt() << 
")";
 
 
  844void CIRDialect::registerTypes() {
 
  847#define GET_TYPEDEF_LIST 
  848#include "clang/CIR/Dialect/IR/CIROpsTypes.cpp.inc" 
mlir::ParseResult parseTargetAddressSpace(mlir::AsmParser &p, cir::TargetAddressSpaceAttr &attr)
 
void printTargetAddressSpace(mlir::AsmPrinter &p, cir::TargetAddressSpaceAttr attr)
 
mlir::ParseResult parseTargetAddressSpace(mlir::AsmParser &p, cir::TargetAddressSpaceAttr &attr)
 
static mlir::ParseResult parseFuncTypeParams(mlir::AsmParser &p, llvm::SmallVector< mlir::Type > ¶ms, bool &isVarArg)
 
static void printFuncTypeParams(mlir::AsmPrinter &p, mlir::ArrayRef< mlir::Type > params, bool isVarArg)
 
void printTargetAddressSpace(mlir::AsmPrinter &p, cir::TargetAddressSpaceAttr attr)
 
static Decl::Kind getKind(const Decl *D)
 
static LiveVariablesImpl & getImpl(void *x)
 
bool isValidFundamentalIntWidth(unsigned width)
 
bool isSized(mlir::Type ty)
Returns true if the type is a CIR sized type.
 
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
 
unsigned kind
All of the diagnostics that can be emitted by the frontend.
 
StringRef getName(const HeaderType T)
 
float __ovld __cnfn sign(float)
Returns 1.0 if x > 0, -0.0 if x = -0.0, +0.0 if x = +0.0, or -1.0 if x < 0.
 
static bool unsizedTypes()
 
static bool dataLayoutPtrHandlingBasedOnLangAS()
 
static bool astRecordDeclAttr()