brintos

brintos / llvm-project-archived public Read only

0
0
Text · 71.2 KiB · 66f8ef9 Raw
1947 lines · cpp
1//===----------------------------------------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8//9// This contains code to emit Constant Expr nodes as LLVM code.10//11//===----------------------------------------------------------------------===//12 13#include "Address.h"14#include "CIRGenCXXABI.h"15#include "CIRGenConstantEmitter.h"16#include "CIRGenModule.h"17#include "CIRGenRecordLayout.h"18#include "mlir/IR/Attributes.h"19#include "mlir/IR/BuiltinAttributeInterfaces.h"20#include "mlir/IR/BuiltinAttributes.h"21#include "clang/AST/APValue.h"22#include "clang/AST/ASTContext.h"23#include "clang/AST/Attr.h"24#include "clang/AST/CharUnits.h"25#include "clang/AST/OperationKinds.h"26#include "clang/AST/RecordLayout.h"27#include "clang/AST/StmtVisitor.h"28#include "clang/Basic/Builtins.h"29#include "clang/CIR/Dialect/IR/CIRAttrs.h"30#include "clang/CIR/Dialect/IR/CIRTypes.h"31#include "clang/CIR/MissingFeatures.h"32#include "llvm/ADT/ArrayRef.h"33#include "llvm/ADT/STLExtras.h"34#include "llvm/Support/ErrorHandling.h"35#include <functional>36#include <iterator>37 38using namespace clang;39using namespace clang::CIRGen;40 41//===----------------------------------------------------------------------===//42//                            ConstantAggregateBuilder43//===----------------------------------------------------------------------===//44 45namespace {46class ConstExprEmitter;47 48static mlir::TypedAttr computePadding(CIRGenModule &cgm, CharUnits size) {49  mlir::Type eltTy = cgm.uCharTy;50  clang::CharUnits::QuantityType arSize = size.getQuantity();51  CIRGenBuilderTy &bld = cgm.getBuilder();52  if (size > CharUnits::One()) {53    SmallVector<mlir::Attribute> elts(arSize, cir::ZeroAttr::get(eltTy));54    return bld.getConstArray(mlir::ArrayAttr::get(bld.getContext(), elts),55                             cir::ArrayType::get(eltTy, arSize));56  }57 58  return cir::ZeroAttr::get(eltTy);59}60 61static mlir::Attribute62emitArrayConstant(CIRGenModule &cgm, mlir::Type desiredType,63                  mlir::Type commonElementType, unsigned arrayBound,64                  SmallVectorImpl<mlir::TypedAttr> &elements,65                  mlir::TypedAttr filler);66 67struct ConstantAggregateBuilderUtils {68  CIRGenModule &cgm;69  cir::CIRDataLayout dataLayout;70 71  ConstantAggregateBuilderUtils(CIRGenModule &cgm)72      : cgm(cgm), dataLayout{cgm.getModule()} {}73 74  CharUnits getAlignment(const mlir::TypedAttr c) const {75    return CharUnits::fromQuantity(76        dataLayout.getAlignment(c.getType(), /*useABIAlign=*/true));77  }78 79  CharUnits getSize(mlir::Type ty) const {80    return CharUnits::fromQuantity(dataLayout.getTypeAllocSize(ty));81  }82 83  CharUnits getSize(const mlir::TypedAttr c) const {84    return getSize(c.getType());85  }86 87  mlir::TypedAttr getPadding(CharUnits size) const {88    return computePadding(cgm, size);89  }90};91 92/// Incremental builder for an mlir::TypedAttr holding a record or array93/// constant.94class ConstantAggregateBuilder : private ConstantAggregateBuilderUtils {95  struct Element {96    Element(mlir::TypedAttr element, CharUnits offset)97        : element(element), offset(offset) {}98 99    mlir::TypedAttr element;100    /// Describes the offset of `element` within the constant.101    CharUnits offset;102  };103  /// The elements of the constant. The elements are kept in increasing offset104  /// order, and we ensure that there is no overlap:105  /// elements.offset[i+1] >= elements.offset[i] + getSize(elements.element[i])106  ///107  /// This may contain explicit padding elements (in order to create a108  /// natural layout), but need not. Gaps between elements are implicitly109  /// considered to be filled with undef.110  llvm::SmallVector<Element, 32> elements;111 112  /// The size of the constant (the maximum end offset of any added element).113  /// May be larger than the end of elems.back() if we split the last element114  /// and removed some trailing undefs.115  CharUnits size = CharUnits::Zero();116 117  /// This is true only if laying out elems in order as the elements of a118  /// non-packed LLVM struct will give the correct layout.119  bool naturalLayout = true;120 121  bool split(size_t index, CharUnits hint);122  std::optional<size_t> splitAt(CharUnits pos);123 124  static mlir::Attribute buildFrom(CIRGenModule &cgm, ArrayRef<Element> elems,125                                   CharUnits startOffset, CharUnits size,126                                   bool naturalLayout, mlir::Type desiredTy,127                                   bool allowOversized);128 129public:130  ConstantAggregateBuilder(CIRGenModule &cgm)131      : ConstantAggregateBuilderUtils(cgm) {}132 133  /// Update or overwrite the value starting at \p offset with \c c.134  ///135  /// \param allowOverwrite If \c true, this constant might overwrite (part of)136  ///        a constant that has already been added. This flag is only used to137  ///        detect bugs.138  bool add(mlir::TypedAttr typedAttr, CharUnits offset, bool allowOverwrite);139 140  /// Update or overwrite the bits starting at \p offsetInBits with \p bits.141  bool addBits(llvm::APInt bits, uint64_t offsetInBits, bool allowOverwrite);142 143  /// Attempt to condense the value starting at \p offset to a constant of type144  /// \p desiredTy.145  void condense(CharUnits offset, mlir::Type desiredTy);146 147  /// Produce a constant representing the entire accumulated value, ideally of148  /// the specified type. If \p allowOversized, the constant might be larger149  /// than implied by \p desiredTy (eg, if there is a flexible array member).150  /// Otherwise, the constant will be of exactly the same size as \p desiredTy151  /// even if we can't represent it as that type.152  mlir::Attribute build(mlir::Type desiredTy, bool allowOversized) const {153    return buildFrom(cgm, elements, CharUnits::Zero(), size, naturalLayout,154                     desiredTy, allowOversized);155  }156};157 158template <typename Container, typename Range = std::initializer_list<159                                  typename Container::value_type>>160static void replace(Container &c, size_t beginOff, size_t endOff, Range vals) {161  assert(beginOff <= endOff && "invalid replacement range");162  llvm::replace(c, c.begin() + beginOff, c.begin() + endOff, vals);163}164 165bool ConstantAggregateBuilder::add(mlir::TypedAttr typedAttr, CharUnits offset,166                                   bool allowOverwrite) {167  // Common case: appending to a layout.168  if (offset >= size) {169    CharUnits align = getAlignment(typedAttr);170    CharUnits alignedSize = size.alignTo(align);171    if (alignedSize > offset || offset.alignTo(align) != offset) {172      naturalLayout = false;173    } else if (alignedSize < offset) {174      elements.emplace_back(getPadding(offset - size), size);175    }176    elements.emplace_back(typedAttr, offset);177    size = offset + getSize(typedAttr);178    return true;179  }180 181  // Uncommon case: constant overlaps what we've already created.182  std::optional<size_t> firstElemToReplace = splitAt(offset);183  if (!firstElemToReplace)184    return false;185 186  CharUnits cSize = getSize(typedAttr);187  std::optional<size_t> lastElemToReplace = splitAt(offset + cSize);188  if (!lastElemToReplace)189    return false;190 191  assert((firstElemToReplace == lastElemToReplace || allowOverwrite) &&192         "unexpectedly overwriting field");193 194  Element newElt(typedAttr, offset);195  replace(elements, *firstElemToReplace, *lastElemToReplace, {newElt});196  size = std::max(size, offset + cSize);197  naturalLayout = false;198  return true;199}200 201bool ConstantAggregateBuilder::addBits(llvm::APInt bits, uint64_t offsetInBits,202                                       bool allowOverwrite) {203  const ASTContext &astContext = cgm.getASTContext();204  const uint64_t charWidth = astContext.getCharWidth();205  mlir::Type charTy = cgm.getBuilder().getUIntNTy(charWidth);206 207  // Offset of where we want the first bit to go within the bits of the208  // current char.209  unsigned offsetWithinChar = offsetInBits % charWidth;210 211  // We split bit-fields up into individual bytes. Walk over the bytes and212  // update them.213  for (CharUnits offsetInChars =214           astContext.toCharUnitsFromBits(offsetInBits - offsetWithinChar);215       /**/; ++offsetInChars) {216    // Number of bits we want to fill in this char.217    unsigned wantedBits =218        std::min((uint64_t)bits.getBitWidth(), charWidth - offsetWithinChar);219 220    // Get a char containing the bits we want in the right places. The other221    // bits have unspecified values.222    llvm::APInt bitsThisChar = bits;223    if (bitsThisChar.getBitWidth() < charWidth)224      bitsThisChar = bitsThisChar.zext(charWidth);225    if (cgm.getDataLayout().isBigEndian()) {226      // Figure out how much to shift by. We may need to left-shift if we have227      // less than one byte of Bits left.228      int shift = bits.getBitWidth() - charWidth + offsetWithinChar;229      if (shift > 0)230        bitsThisChar.lshrInPlace(shift);231      else if (shift < 0)232        bitsThisChar = bitsThisChar.shl(-shift);233    } else {234      bitsThisChar = bitsThisChar.shl(offsetWithinChar);235    }236    if (bitsThisChar.getBitWidth() > charWidth)237      bitsThisChar = bitsThisChar.trunc(charWidth);238 239    if (wantedBits == charWidth) {240      // Got a full byte: just add it directly.241      add(cir::IntAttr::get(charTy, bitsThisChar), offsetInChars,242          allowOverwrite);243    } else {244      // Partial byte: update the existing integer if there is one. If we245      // can't split out a 1-CharUnit range to update, then we can't add246      // these bits and fail the entire constant emission.247      std::optional<size_t> firstElemToUpdate = splitAt(offsetInChars);248      if (!firstElemToUpdate)249        return false;250      std::optional<size_t> lastElemToUpdate =251          splitAt(offsetInChars + CharUnits::One());252      if (!lastElemToUpdate)253        return false;254      assert(*lastElemToUpdate - *firstElemToUpdate < 2 &&255             "should have at most one element covering one byte");256 257      // Figure out which bits we want and discard the rest.258      llvm::APInt updateMask(charWidth, 0);259      if (cgm.getDataLayout().isBigEndian())260        updateMask.setBits(charWidth - offsetWithinChar - wantedBits,261                           charWidth - offsetWithinChar);262      else263        updateMask.setBits(offsetWithinChar, offsetWithinChar + wantedBits);264      bitsThisChar &= updateMask;265      bool isNull = false;266      if (*firstElemToUpdate < elements.size()) {267        auto firstEltToUpdate =268            mlir::dyn_cast<cir::IntAttr>(elements[*firstElemToUpdate].element);269        isNull = firstEltToUpdate && firstEltToUpdate.isNullValue();270      }271 272      if (*firstElemToUpdate == *lastElemToUpdate || isNull) {273        // All existing bits are either zero or undef.274        add(cir::IntAttr::get(charTy, bitsThisChar), offsetInChars,275            /*allowOverwrite*/ true);276      } else {277        cir::IntAttr ci =278            mlir::dyn_cast<cir::IntAttr>(elements[*firstElemToUpdate].element);279        // In order to perform a partial update, we need the existing bitwise280        // value, which we can only extract for a constant int.281        if (!ci)282          return false;283        // Because this is a 1-CharUnit range, the constant occupying it must284        // be exactly one CharUnit wide.285        assert(ci.getBitWidth() == charWidth && "splitAt failed");286        assert((!(ci.getValue() & updateMask) || allowOverwrite) &&287               "unexpectedly overwriting bitfield");288        bitsThisChar |= (ci.getValue() & ~updateMask);289        elements[*firstElemToUpdate].element =290            cir::IntAttr::get(charTy, bitsThisChar);291      }292    }293 294    // Stop if we've added all the bits.295    if (wantedBits == bits.getBitWidth())296      break;297 298    // Remove the consumed bits from Bits.299    if (!cgm.getDataLayout().isBigEndian())300      bits.lshrInPlace(wantedBits);301    bits = bits.trunc(bits.getBitWidth() - wantedBits);302 303    // The remaining bits go at the start of the following bytes.304    offsetWithinChar = 0;305  }306 307  return true;308}309 310/// Returns a position within elements such that all elements311/// before the returned index end before pos and all elements at or after312/// the returned index begin at or after pos. Splits elements as necessary313/// to ensure this. Returns std::nullopt if we find something we can't split.314std::optional<size_t> ConstantAggregateBuilder::splitAt(CharUnits pos) {315  if (pos >= size)316    return elements.size();317 318  while (true) {319    // Find the first element that starts after pos.320    Element *iter =321        llvm::upper_bound(elements, pos, [](CharUnits pos, const Element &elt) {322          return pos < elt.offset;323        });324 325    if (iter == elements.begin())326      return 0;327 328    size_t index = iter - elements.begin() - 1;329    const Element &elt = elements[index];330 331    // If we already have an element starting at pos, we're done.332    if (elt.offset == pos)333      return index;334 335    // Check for overlap with the element that starts before pos.336    CharUnits eltEnd = elt.offset + getSize(elt.element);337    if (eltEnd <= pos)338      return index + 1;339 340    // Try to decompose it into smaller constants.341    if (!split(index, pos))342      return std::nullopt;343  }344}345 346/// Split the constant at index, if possible. Return true if we did.347/// Hint indicates the location at which we'd like to split, but may be348/// ignored.349bool ConstantAggregateBuilder::split(size_t index, CharUnits hint) {350  cgm.errorNYI("split constant at index");351  return false;352}353 354void ConstantAggregateBuilder::condense(CharUnits offset,355                                        mlir::Type desiredTy) {356  CharUnits desiredSize = getSize(desiredTy);357 358  std::optional<size_t> firstElemToReplace = splitAt(offset);359  if (!firstElemToReplace)360    return;361  size_t first = *firstElemToReplace;362 363  std::optional<size_t> lastElemToReplace = splitAt(offset + desiredSize);364  if (!lastElemToReplace)365    return;366  size_t last = *lastElemToReplace;367 368  size_t length = last - first;369  if (length == 0)370    return;371 372  if (length == 1 && elements[first].offset == offset &&373      getSize(elements[first].element) == desiredSize) {374    cgm.errorNYI("re-wrapping single element records");375    return;376  }377 378  // Build a new constant from the elements in the range.379  SmallVector<Element> subElems(elements.begin() + first,380                                elements.begin() + last);381  mlir::Attribute replacement =382      buildFrom(cgm, subElems, offset, desiredSize,383                /*naturalLayout=*/false, desiredTy, false);384 385  // Replace the range with the condensed constant.386  Element newElt(mlir::cast<mlir::TypedAttr>(replacement), offset);387  replace(elements, first, last, {newElt});388}389 390mlir::Attribute391ConstantAggregateBuilder::buildFrom(CIRGenModule &cgm, ArrayRef<Element> elems,392                                    CharUnits startOffset, CharUnits size,393                                    bool naturalLayout, mlir::Type desiredTy,394                                    bool allowOversized) {395  ConstantAggregateBuilderUtils utils(cgm);396 397  if (elems.empty())398    return cir::UndefAttr::get(desiredTy);399 400  // If we want an array type, see if all the elements are the same type and401  // appropriately spaced.402  if (mlir::isa<cir::ArrayType>(desiredTy)) {403    cgm.errorNYI("array aggregate constants");404    return {};405  }406 407  // The size of the constant we plan to generate. This is usually just the size408  // of the initialized type, but in AllowOversized mode (i.e. flexible array409  // init), it can be larger.410  CharUnits desiredSize = utils.getSize(desiredTy);411  if (size > desiredSize) {412    assert(allowOversized && "elems are oversized");413    desiredSize = size;414  }415 416  // The natural alignment of an unpacked CIR record with the given elements.417  CharUnits align = CharUnits::One();418  for (auto [e, offset] : elems)419    align = std::max(align, utils.getAlignment(e));420 421  // The natural size of an unpacked LLVM struct with the given elements.422  CharUnits alignedSize = size.alignTo(align);423 424  bool packed = false;425  bool padded = false;426 427  llvm::SmallVector<mlir::Attribute, 32> unpackedElems;428  if (desiredSize < alignedSize || desiredSize.alignTo(align) != desiredSize) {429    naturalLayout = false;430    packed = true;431  } else {432    // The natural layout would be too small. Add padding to fix it. (This433    // is ignored if we choose a packed layout.)434    unpackedElems.reserve(elems.size() + 1);435    llvm::transform(elems, std::back_inserter(unpackedElems),436                    std::mem_fn(&Element::element));437    if (desiredSize > alignedSize)438      unpackedElems.push_back(utils.getPadding(desiredSize - size));439  }440 441  // If we don't have a natural layout, insert padding as necessary.442  // As we go, double-check to see if we can actually just emit Elems443  // as a non-packed record and do so opportunistically if possible.444  llvm::SmallVector<mlir::Attribute, 32> packedElems;445  packedElems.reserve(elems.size());446  if (!naturalLayout) {447    CharUnits sizeSoFar = CharUnits::Zero();448    for (auto [element, offset] : elems) {449      CharUnits align = utils.getAlignment(element);450      CharUnits naturalOffset = sizeSoFar.alignTo(align);451      CharUnits desiredOffset = offset - startOffset;452      assert(desiredOffset >= sizeSoFar && "elements out of order");453 454      if (desiredOffset != naturalOffset)455        packed = true;456      if (desiredOffset != sizeSoFar)457        packedElems.push_back(utils.getPadding(desiredOffset - sizeSoFar));458      packedElems.push_back(element);459      sizeSoFar = desiredOffset + utils.getSize(element);460    }461    // If we're using the packed layout, pad it out to the desired size if462    // necessary.463    if (packed) {464      assert(sizeSoFar <= desiredSize &&465             "requested size is too small for contents");466 467      if (sizeSoFar < desiredSize)468        packedElems.push_back(utils.getPadding(desiredSize - sizeSoFar));469    }470  }471 472  CIRGenBuilderTy &builder = cgm.getBuilder();473  auto arrAttr = mlir::ArrayAttr::get(builder.getContext(),474                                      packed ? packedElems : unpackedElems);475 476  cir::RecordType recordType = builder.getCompleteRecordType(arrAttr, packed);477  if (auto desired = mlir::dyn_cast<cir::RecordType>(desiredTy))478    if (desired.isLayoutIdentical(recordType))479      recordType = desired;480 481  return builder.getConstRecordOrZeroAttr(arrAttr, packed, padded, recordType);482}483 484//===----------------------------------------------------------------------===//485//                            ConstRecordBuilder486//===----------------------------------------------------------------------===//487 488class ConstRecordBuilder {489  CIRGenModule &cgm;490  ConstantEmitter &emitter;491  ConstantAggregateBuilder &builder;492  CharUnits startOffset;493 494public:495  static mlir::Attribute buildRecord(ConstantEmitter &emitter,496                                     InitListExpr *ile, QualType valTy);497  static mlir::Attribute buildRecord(ConstantEmitter &emitter,498                                     const APValue &value, QualType valTy);499  static bool updateRecord(ConstantEmitter &emitter,500                           ConstantAggregateBuilder &constant, CharUnits offset,501                           InitListExpr *updater);502 503private:504  ConstRecordBuilder(ConstantEmitter &emitter,505                     ConstantAggregateBuilder &builder, CharUnits startOffset)506      : cgm(emitter.cgm), emitter(emitter), builder(builder),507        startOffset(startOffset) {}508 509  bool appendField(const FieldDecl *field, uint64_t fieldOffset,510                   mlir::TypedAttr initCst, bool allowOverwrite = false);511 512  bool appendBytes(CharUnits fieldOffsetInChars, mlir::TypedAttr initCst,513                   bool allowOverwrite = false);514 515  bool appendBitField(const FieldDecl *field, uint64_t fieldOffset,516                      cir::IntAttr ci, bool allowOverwrite = false);517 518  /// Applies zero-initialization to padding bytes before and within a field.519  /// \param layout The record layout containing field offset information.520  /// \param fieldNo The field index in the record.521  /// \param field The field declaration.522  /// \param allowOverwrite Whether to allow overwriting existing values.523  /// \param sizeSoFar The current size processed, updated by this function.524  /// \param zeroFieldSize Set to true if the field has zero size.525  /// \returns true on success, false if padding could not be applied.526  bool applyZeroInitPadding(const ASTRecordLayout &layout, unsigned fieldNo,527                            const FieldDecl &field, bool allowOverwrite,528                            CharUnits &sizeSoFar, bool &zeroFieldSize);529 530  /// Applies zero-initialization to trailing padding bytes in a record.531  /// \param layout The record layout containing size information.532  /// \param allowOverwrite Whether to allow overwriting existing values.533  /// \param sizeSoFar The current size processed.534  /// \returns true on success, false if padding could not be applied.535  bool applyZeroInitPadding(const ASTRecordLayout &layout, bool allowOverwrite,536                            CharUnits &sizeSoFar);537 538  bool build(InitListExpr *ile, bool allowOverwrite);539  bool build(const APValue &val, const RecordDecl *rd, bool isPrimaryBase,540             const CXXRecordDecl *vTableClass, CharUnits baseOffset);541 542  mlir::Attribute finalize(QualType ty);543};544 545bool ConstRecordBuilder::appendField(const FieldDecl *field,546                                     uint64_t fieldOffset,547                                     mlir::TypedAttr initCst,548                                     bool allowOverwrite) {549  const ASTContext &astContext = cgm.getASTContext();550 551  CharUnits fieldOffsetInChars = astContext.toCharUnitsFromBits(fieldOffset);552 553  return appendBytes(fieldOffsetInChars, initCst, allowOverwrite);554}555 556bool ConstRecordBuilder::appendBytes(CharUnits fieldOffsetInChars,557                                     mlir::TypedAttr initCst,558                                     bool allowOverwrite) {559  return builder.add(initCst, startOffset + fieldOffsetInChars, allowOverwrite);560}561 562bool ConstRecordBuilder::appendBitField(const FieldDecl *field,563                                        uint64_t fieldOffset, cir::IntAttr ci,564                                        bool allowOverwrite) {565  const CIRGenRecordLayout &rl =566      cgm.getTypes().getCIRGenRecordLayout(field->getParent());567  const CIRGenBitFieldInfo &info = rl.getBitFieldInfo(field);568  llvm::APInt fieldValue = ci.getValue();569 570  // Promote the size of FieldValue if necessary571  // FIXME: This should never occur, but currently it can because initializer572  // constants are cast to bool, and because clang is not enforcing bitfield573  // width limits.574  if (info.size > fieldValue.getBitWidth())575    fieldValue = fieldValue.zext(info.size);576 577  // Truncate the size of FieldValue to the bit field size.578  if (info.size < fieldValue.getBitWidth())579    fieldValue = fieldValue.trunc(info.size);580 581  return builder.addBits(fieldValue,582                         cgm.getASTContext().toBits(startOffset) + fieldOffset,583                         allowOverwrite);584}585 586bool ConstRecordBuilder::applyZeroInitPadding(587    const ASTRecordLayout &layout, unsigned fieldNo, const FieldDecl &field,588    bool allowOverwrite, CharUnits &sizeSoFar, bool &zeroFieldSize) {589  uint64_t startBitOffset = layout.getFieldOffset(fieldNo);590  CharUnits startOffset =591      cgm.getASTContext().toCharUnitsFromBits(startBitOffset);592  if (sizeSoFar < startOffset) {593    if (!appendBytes(sizeSoFar, computePadding(cgm, startOffset - sizeSoFar),594                     allowOverwrite))595      return false;596  }597 598  if (!field.isBitField()) {599    CharUnits fieldSize =600        cgm.getASTContext().getTypeSizeInChars(field.getType());601    sizeSoFar = startOffset + fieldSize;602    zeroFieldSize = fieldSize.isZero();603  } else {604    const CIRGenRecordLayout &rl =605        cgm.getTypes().getCIRGenRecordLayout(field.getParent());606    const CIRGenBitFieldInfo &info = rl.getBitFieldInfo(&field);607    uint64_t endBitOffset = startBitOffset + info.size;608    sizeSoFar = cgm.getASTContext().toCharUnitsFromBits(endBitOffset);609    if (endBitOffset % cgm.getASTContext().getCharWidth() != 0)610      sizeSoFar++;611    zeroFieldSize = info.size == 0;612  }613  return true;614}615 616bool ConstRecordBuilder::applyZeroInitPadding(const ASTRecordLayout &layout,617                                              bool allowOverwrite,618                                              CharUnits &sizeSoFar) {619  CharUnits totalSize = layout.getSize();620  if (sizeSoFar < totalSize) {621    if (!appendBytes(sizeSoFar, computePadding(cgm, totalSize - sizeSoFar),622                     allowOverwrite))623      return false;624  }625  sizeSoFar = totalSize;626  return true;627}628 629bool ConstRecordBuilder::build(InitListExpr *ile, bool allowOverwrite) {630  RecordDecl *rd = ile->getType()->castAsRecordDecl();631  const ASTRecordLayout &layout = cgm.getASTContext().getASTRecordLayout(rd);632 633  // Bail out if we have base classes. We could support these, but they only634  // arise in C++1z where we will have already constant folded most interesting635  // cases. FIXME: There are still a few more cases we can handle this way.636  if (auto *cxxrd = dyn_cast<CXXRecordDecl>(rd))637    if (cxxrd->getNumBases())638      return false;639 640  const bool zeroInitPadding = cgm.shouldZeroInitPadding();641  bool zeroFieldSize = false;642  CharUnits sizeSoFar = CharUnits::Zero();643 644  unsigned elementNo = 0;645  for (auto [index, field] : llvm::enumerate(rd->fields())) {646 647    // If this is a union, skip all the fields that aren't being initialized.648    if (rd->isUnion() &&649        !declaresSameEntity(ile->getInitializedFieldInUnion(), field))650      continue;651 652    // Don't emit anonymous bitfields.653    if (field->isUnnamedBitField())654      continue;655 656    // Get the initializer.  A record can include fields without initializers,657    // we just use explicit null values for them.658    Expr *init = nullptr;659    if (elementNo < ile->getNumInits())660      init = ile->getInit(elementNo++);661    if (isa_and_nonnull<NoInitExpr>(init))662      continue;663 664    // Zero-sized fields are not emitted, but their initializers may still665    // prevent emission of this record as a constant.666    if (field->isZeroSize(cgm.getASTContext())) {667      if (init->HasSideEffects(cgm.getASTContext()))668        return false;669      continue;670    }671 672    if (zeroInitPadding &&673        !applyZeroInitPadding(layout, index, *field, allowOverwrite, sizeSoFar,674                              zeroFieldSize))675      return false;676 677    // When emitting a DesignatedInitUpdateExpr, a nested InitListExpr678    // represents additional overwriting of our current constant value, and not679    // a new constant to emit independently.680    if (allowOverwrite &&681        (field->getType()->isArrayType() || field->getType()->isRecordType())) {682      cgm.errorNYI(field->getSourceRange(), "designated init lists");683      return false;684    }685 686    mlir::Attribute eltInitAttr =687        init ? emitter.tryEmitPrivateForMemory(init, field->getType())688             : emitter.emitNullForMemory(cgm.getLoc(ile->getSourceRange()),689                                         field->getType());690    if (!eltInitAttr)691      return false;692 693    mlir::TypedAttr eltInit = mlir::cast<mlir::TypedAttr>(eltInitAttr);694    if (!field->isBitField()) {695      // Handle non-bitfield members.696      if (!appendField(field, layout.getFieldOffset(index), eltInit,697                       allowOverwrite))698        return false;699      // After emitting a non-empty field with [[no_unique_address]], we may700      // need to overwrite its tail padding.701      if (field->hasAttr<NoUniqueAddressAttr>())702        allowOverwrite = true;703    } else {704      // Otherwise we have a bitfield.705      if (auto constInt = dyn_cast<cir::IntAttr>(eltInit)) {706        if (!appendBitField(field, layout.getFieldOffset(index), constInt,707                            allowOverwrite))708          return false;709      } else {710        // We are trying to initialize a bitfield with a non-trivial constant,711        // this must require run-time code.712        return false;713      }714    }715  }716 717  return !zeroInitPadding ||718         applyZeroInitPadding(layout, allowOverwrite, sizeSoFar);719}720 721namespace {722struct BaseInfo {723  BaseInfo(const CXXRecordDecl *decl, CharUnits offset, unsigned index)724      : decl(decl), offset(offset), index(index) {}725 726  const CXXRecordDecl *decl;727  CharUnits offset;728  unsigned index;729 730  bool operator<(const BaseInfo &o) const { return offset < o.offset; }731};732} // namespace733 734bool ConstRecordBuilder::build(const APValue &val, const RecordDecl *rd,735                               bool isPrimaryBase,736                               const CXXRecordDecl *vTableClass,737                               CharUnits offset) {738  const ASTRecordLayout &layout = cgm.getASTContext().getASTRecordLayout(rd);739  if (const CXXRecordDecl *cd = dyn_cast<CXXRecordDecl>(rd)) {740    // Add a vtable pointer, if we need one and it hasn't already been added.741    if (layout.hasOwnVFPtr()) {742      CIRGenBuilderTy &builder = cgm.getBuilder();743      cir::GlobalOp vtable =744          cgm.getCXXABI().getAddrOfVTable(vTableClass, CharUnits());745      clang::VTableLayout::AddressPointLocation addressPoint =746          cgm.getItaniumVTableContext()747              .getVTableLayout(vTableClass)748              .getAddressPoint(BaseSubobject(cd, offset));749      assert(!cir::MissingFeatures::addressPointerAuthInfo());750      mlir::ArrayAttr indices = builder.getArrayAttr({751          builder.getI32IntegerAttr(addressPoint.VTableIndex),752          builder.getI32IntegerAttr(addressPoint.AddressPointIndex),753      });754      cir::GlobalViewAttr vtableInit =755          cgm.getBuilder().getGlobalViewAttr(vtable, indices);756      if (!appendBytes(offset, vtableInit))757        return false;758    }759 760    // Accumulate and sort bases, in order to visit them in address order, which761    // may not be the same as declaration order.762    SmallVector<BaseInfo> bases;763    bases.reserve(cd->getNumBases());764    for (auto [index, base] : llvm::enumerate(cd->bases())) {765      assert(!base.isVirtual() && "should not have virtual bases here");766      const CXXRecordDecl *bd = base.getType()->getAsCXXRecordDecl();767      CharUnits baseOffset = layout.getBaseClassOffset(bd);768      bases.push_back(BaseInfo(bd, baseOffset, index));769    }770#ifdef EXPENSIVE_CHECKS771    assert(llvm::is_sorted(bases) && "bases not sorted by offset");772#endif773 774    for (BaseInfo &base : bases) {775      bool isPrimaryBase = layout.getPrimaryBase() == base.decl;776      build(val.getStructBase(base.index), base.decl, isPrimaryBase,777            vTableClass, offset + base.offset);778    }779  }780 781  uint64_t offsetBits = cgm.getASTContext().toBits(offset);782 783  bool allowOverwrite = false;784  for (auto [index, field] : llvm::enumerate(rd->fields())) {785    // If this is a union, skip all the fields that aren't being initialized.786    if (rd->isUnion() && !declaresSameEntity(val.getUnionField(), field))787      continue;788 789    // Don't emit anonymous bitfields or zero-sized fields.790    if (field->isUnnamedBitField() || field->isZeroSize(cgm.getASTContext()))791      continue;792 793    // Emit the value of the initializer.794    const APValue &fieldValue =795        rd->isUnion() ? val.getUnionValue() : val.getStructField(index);796    mlir::TypedAttr eltInit = mlir::cast<mlir::TypedAttr>(797        emitter.tryEmitPrivateForMemory(fieldValue, field->getType()));798    if (!eltInit)799      return false;800 801    if (!field->isBitField()) {802      // Handle non-bitfield members.803      if (!appendField(field, layout.getFieldOffset(index) + offsetBits,804                       eltInit, allowOverwrite))805        return false;806      // After emitting a non-empty field with [[no_unique_address]], we may807      // need to overwrite its tail padding.808      if (field->hasAttr<NoUniqueAddressAttr>())809        allowOverwrite = true;810    } else {811      // Otherwise we have a bitfield.812      if (auto constInt = dyn_cast<cir::IntAttr>(eltInit)) {813        if (!appendBitField(field, layout.getFieldOffset(index) + offsetBits,814                            constInt, allowOverwrite))815          return false;816      } else {817        // We are trying to initialize a bitfield with a non-trivial constant,818        // this must require run-time code.819        return false;820      }821    }822  }823 824  return true;825}826 827mlir::Attribute ConstRecordBuilder::finalize(QualType type) {828  type = type.getNonReferenceType();829  RecordDecl *rd =830      type->castAs<clang::RecordType>()->getDecl()->getDefinitionOrSelf();831  mlir::Type valTy = cgm.convertType(type);832  return builder.build(valTy, rd->hasFlexibleArrayMember());833}834 835mlir::Attribute ConstRecordBuilder::buildRecord(ConstantEmitter &emitter,836                                                InitListExpr *ile,837                                                QualType valTy) {838  ConstantAggregateBuilder constant(emitter.cgm);839  ConstRecordBuilder builder(emitter, constant, CharUnits::Zero());840 841  if (!builder.build(ile, /*allowOverwrite*/ false))842    return nullptr;843 844  return builder.finalize(valTy);845}846 847mlir::Attribute ConstRecordBuilder::buildRecord(ConstantEmitter &emitter,848                                                const APValue &val,849                                                QualType valTy) {850  ConstantAggregateBuilder constant(emitter.cgm);851  ConstRecordBuilder builder(emitter, constant, CharUnits::Zero());852 853  const RecordDecl *rd =854      valTy->castAs<clang::RecordType>()->getDecl()->getDefinitionOrSelf();855  const CXXRecordDecl *cd = dyn_cast<CXXRecordDecl>(rd);856  if (!builder.build(val, rd, false, cd, CharUnits::Zero()))857    return nullptr;858 859  return builder.finalize(valTy);860}861 862bool ConstRecordBuilder::updateRecord(ConstantEmitter &emitter,863                                      ConstantAggregateBuilder &constant,864                                      CharUnits offset, InitListExpr *updater) {865  return ConstRecordBuilder(emitter, constant, offset)866      .build(updater, /*allowOverwrite*/ true);867}868 869//===----------------------------------------------------------------------===//870//                             ConstExprEmitter871//===----------------------------------------------------------------------===//872 873// This class only needs to handle arrays, structs and unions.874//875// In LLVM codegen, when outside C++11 mode, those types are not constant876// folded, while all other types are handled by constant folding.877//878// In CIR codegen, instead of folding things here, we should defer that work879// to MLIR: do not attempt to do much here.880class ConstExprEmitter881    : public StmtVisitor<ConstExprEmitter, mlir::Attribute, QualType> {882  CIRGenModule &cgm;883  [[maybe_unused]] ConstantEmitter &emitter;884 885public:886  ConstExprEmitter(ConstantEmitter &emitter)887      : cgm(emitter.cgm), emitter(emitter) {}888 889  //===--------------------------------------------------------------------===//890  //                            Visitor Methods891  //===--------------------------------------------------------------------===//892 893  mlir::Attribute VisitStmt(Stmt *s, QualType t) { return {}; }894 895  mlir::Attribute VisitConstantExpr(ConstantExpr *ce, QualType t) {896    if (mlir::Attribute result = emitter.tryEmitConstantExpr(ce))897      return result;898    return Visit(ce->getSubExpr(), t);899  }900 901  mlir::Attribute VisitParenExpr(ParenExpr *pe, QualType t) {902    return Visit(pe->getSubExpr(), t);903  }904 905  mlir::Attribute906  VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *pe,907                                    QualType t) {908    return Visit(pe->getReplacement(), t);909  }910 911  mlir::Attribute VisitGenericSelectionExpr(GenericSelectionExpr *ge,912                                            QualType t) {913    return Visit(ge->getResultExpr(), t);914  }915 916  mlir::Attribute VisitChooseExpr(ChooseExpr *ce, QualType t) {917    return Visit(ce->getChosenSubExpr(), t);918  }919 920  mlir::Attribute VisitCompoundLiteralExpr(CompoundLiteralExpr *e, QualType t) {921    return Visit(e->getInitializer(), t);922  }923 924  mlir::Attribute VisitCastExpr(CastExpr *e, QualType destType) {925    if (const auto *ece = dyn_cast<ExplicitCastExpr>(e))926      cgm.emitExplicitCastExprType(ece,927                                   const_cast<CIRGenFunction *>(emitter.cgf));928 929    Expr *subExpr = e->getSubExpr();930 931    switch (e->getCastKind()) {932    case CK_ToUnion:933    case CK_AddressSpaceConversion:934    case CK_ReinterpretMemberPointer:935    case CK_DerivedToBaseMemberPointer:936    case CK_BaseToDerivedMemberPointer:937      cgm.errorNYI(e->getBeginLoc(), "ConstExprEmitter::VisitCastExpr");938      return {};939 940    case CK_LValueToRValue:941    case CK_AtomicToNonAtomic:942    case CK_NonAtomicToAtomic:943    case CK_NoOp:944    case CK_ConstructorConversion:945      return Visit(subExpr, destType);946 947    case CK_IntToOCLSampler:948      llvm_unreachable("global sampler variables are not generated");949 950    case CK_Dependent:951      llvm_unreachable("saw dependent cast!");952 953    case CK_BuiltinFnToFnPtr:954      llvm_unreachable("builtin functions are handled elsewhere");955 956    // These will never be supported.957    case CK_ObjCObjectLValueCast:958    case CK_ARCProduceObject:959    case CK_ARCConsumeObject:960    case CK_ARCReclaimReturnedObject:961    case CK_ARCExtendBlockObject:962    case CK_CopyAndAutoreleaseBlockObject:963      return {};964 965    // These don't need to be handled here because Evaluate knows how to966    // evaluate them in the cases where they can be folded.967    case CK_BitCast:968    case CK_ToVoid:969    case CK_Dynamic:970    case CK_LValueBitCast:971    case CK_LValueToRValueBitCast:972    case CK_NullToMemberPointer:973    case CK_UserDefinedConversion:974    case CK_CPointerToObjCPointerCast:975    case CK_BlockPointerToObjCPointerCast:976    case CK_AnyPointerToBlockPointerCast:977    case CK_ArrayToPointerDecay:978    case CK_FunctionToPointerDecay:979    case CK_BaseToDerived:980    case CK_DerivedToBase:981    case CK_UncheckedDerivedToBase:982    case CK_MemberPointerToBoolean:983    case CK_VectorSplat:984    case CK_FloatingRealToComplex:985    case CK_FloatingComplexToReal:986    case CK_FloatingComplexToBoolean:987    case CK_FloatingComplexCast:988    case CK_FloatingComplexToIntegralComplex:989    case CK_IntegralRealToComplex:990    case CK_IntegralComplexToReal:991    case CK_IntegralComplexToBoolean:992    case CK_IntegralComplexCast:993    case CK_IntegralComplexToFloatingComplex:994    case CK_PointerToIntegral:995    case CK_PointerToBoolean:996    case CK_NullToPointer:997    case CK_IntegralCast:998    case CK_BooleanToSignedIntegral:999    case CK_IntegralToPointer:1000    case CK_IntegralToBoolean:1001    case CK_IntegralToFloating:1002    case CK_FloatingToIntegral:1003    case CK_FloatingToBoolean:1004    case CK_FloatingCast:1005    case CK_FloatingToFixedPoint:1006    case CK_FixedPointToFloating:1007    case CK_FixedPointCast:1008    case CK_FixedPointToBoolean:1009    case CK_FixedPointToIntegral:1010    case CK_IntegralToFixedPoint:1011    case CK_ZeroToOCLOpaqueType:1012    case CK_MatrixCast:1013    case CK_HLSLArrayRValue:1014    case CK_HLSLVectorTruncation:1015    case CK_HLSLElementwiseCast:1016    case CK_HLSLAggregateSplatCast:1017      return {};1018    }1019    llvm_unreachable("Invalid CastKind");1020  }1021 1022  mlir::Attribute VisitCXXDefaultInitExpr(CXXDefaultInitExpr *die, QualType t) {1023    // No need for a DefaultInitExprScope: we don't handle 'this' in a1024    // constant expression.1025    return Visit(die->getExpr(), t);1026  }1027 1028  mlir::Attribute VisitExprWithCleanups(ExprWithCleanups *e, QualType t) {1029    // Since this about constant emission no need to wrap this under a scope.1030    return Visit(e->getSubExpr(), t);1031  }1032 1033  mlir::Attribute VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *e,1034                                                QualType t) {1035    return Visit(e->getSubExpr(), t);1036  }1037 1038  mlir::Attribute VisitImplicitValueInitExpr(ImplicitValueInitExpr *e,1039                                             QualType t) {1040    return cgm.getBuilder().getZeroInitAttr(cgm.convertType(t));1041  }1042 1043  mlir::Attribute VisitInitListExpr(InitListExpr *ile, QualType t) {1044    if (ile->isTransparent())1045      return Visit(ile->getInit(0), t);1046 1047    if (ile->getType()->isArrayType()) {1048      // If we return null here, the non-constant initializer will take care of1049      // it, but we would prefer to handle it here.1050      assert(!cir::MissingFeatures::constEmitterArrayILE());1051      return {};1052    }1053 1054    if (ile->getType()->isRecordType()) {1055      return ConstRecordBuilder::buildRecord(emitter, ile, t);1056    }1057 1058    if (ile->getType()->isVectorType()) {1059      // If we return null here, the non-constant initializer will take care of1060      // it, but we would prefer to handle it here.1061      assert(!cir::MissingFeatures::constEmitterVectorILE());1062      return {};1063    }1064 1065    return {};1066  }1067 1068  mlir::Attribute VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *e,1069                                                QualType destType) {1070    mlir::Attribute c = Visit(e->getBase(), destType);1071    if (!c)1072      return {};1073 1074    cgm.errorNYI(e->getBeginLoc(),1075                 "ConstExprEmitter::VisitDesignatedInitUpdateExpr");1076    return {};1077  }1078 1079  mlir::Attribute VisitCXXConstructExpr(CXXConstructExpr *e, QualType ty) {1080    if (!e->getConstructor()->isTrivial())1081      return {};1082 1083    // Only default and copy/move constructors can be trivial.1084    if (e->getNumArgs()) {1085      assert(e->getNumArgs() == 1 && "trivial ctor with > 1 argument");1086      assert(e->getConstructor()->isCopyOrMoveConstructor() &&1087             "trivial ctor has argument but isn't a copy/move ctor");1088 1089      Expr *arg = e->getArg(0);1090      assert(cgm.getASTContext().hasSameUnqualifiedType(ty, arg->getType()) &&1091             "argument to copy ctor is of wrong type");1092 1093      // Look through the temporary; it's just converting the value to an lvalue1094      // to pass it to the constructor.1095      if (auto const *mte = dyn_cast<MaterializeTemporaryExpr>(arg))1096        return Visit(mte->getSubExpr(), ty);1097 1098      // TODO: Investigate whether there are cases that can fall through to here1099      //       that need to be handled. This is missing in classic codegen also.1100      assert(!cir::MissingFeatures::ctorConstLvalueToRvalueConversion());1101 1102      // Don't try to support arbitrary lvalue-to-rvalue conversions for now.1103      return {};1104    }1105 1106    return cgm.getBuilder().getZeroInitAttr(cgm.convertType(ty));1107  }1108 1109  mlir::Attribute VisitStringLiteral(StringLiteral *e, QualType t) {1110    // This is a string literal initializing an array in an initializer.1111    return cgm.getConstantArrayFromStringLiteral(e);1112  }1113 1114  mlir::Attribute VisitObjCEncodeExpr(ObjCEncodeExpr *e, QualType t) {1115    cgm.errorNYI(e->getBeginLoc(), "ConstExprEmitter::VisitObjCEncodeExpr");1116    return {};1117  }1118 1119  mlir::Attribute VisitUnaryExtension(const UnaryOperator *e, QualType t) {1120    return Visit(e->getSubExpr(), t);1121  }1122 1123  // Utility methods1124  mlir::Type convertType(QualType t) { return cgm.convertType(t); }1125};1126 1127// TODO(cir): this can be shared with LLVM's codegen1128static QualType getNonMemoryType(CIRGenModule &cgm, QualType type) {1129  if (const auto *at = type->getAs<AtomicType>()) {1130    return cgm.getASTContext().getQualifiedType(at->getValueType(),1131                                                type.getQualifiers());1132  }1133  return type;1134}1135 1136static mlir::Attribute1137emitArrayConstant(CIRGenModule &cgm, mlir::Type desiredType,1138                  mlir::Type commonElementType, unsigned arrayBound,1139                  SmallVectorImpl<mlir::TypedAttr> &elements,1140                  mlir::TypedAttr filler) {1141  CIRGenBuilderTy &builder = cgm.getBuilder();1142 1143  unsigned nonzeroLength = arrayBound;1144  if (elements.size() < nonzeroLength && builder.isNullValue(filler))1145    nonzeroLength = elements.size();1146 1147  if (nonzeroLength == elements.size()) {1148    while (nonzeroLength > 0 &&1149           builder.isNullValue(elements[nonzeroLength - 1]))1150      --nonzeroLength;1151  }1152 1153  if (nonzeroLength == 0)1154    return cir::ZeroAttr::get(desiredType);1155 1156  const unsigned trailingZeroes = arrayBound - nonzeroLength;1157 1158  // Add a zeroinitializer array filler if we have lots of trailing zeroes.1159  if (trailingZeroes >= 8) {1160    assert(elements.size() >= nonzeroLength &&1161           "missing initializer for non-zero element");1162 1163    if (commonElementType && nonzeroLength >= 8) {1164      // If all the elements had the same type up to the trailing zeroes and1165      // there are eight or more nonzero elements, emit a struct of two arrays1166      // (the nonzero data and the zeroinitializer).1167      SmallVector<mlir::Attribute> eles;1168      eles.reserve(nonzeroLength);1169      for (const auto &element : elements)1170        eles.push_back(element);1171      auto initial = cir::ConstArrayAttr::get(1172          cir::ArrayType::get(commonElementType, nonzeroLength),1173          mlir::ArrayAttr::get(builder.getContext(), eles));1174      elements.resize(2);1175      elements[0] = initial;1176    } else {1177      // Otherwise, emit a struct with individual elements for each nonzero1178      // initializer, followed by a zeroinitializer array filler.1179      elements.resize(nonzeroLength + 1);1180    }1181 1182    mlir::Type fillerType =1183        commonElementType1184            ? commonElementType1185            : mlir::cast<cir::ArrayType>(desiredType).getElementType();1186    fillerType = cir::ArrayType::get(fillerType, trailingZeroes);1187    elements.back() = cir::ZeroAttr::get(fillerType);1188    commonElementType = nullptr;1189  } else if (elements.size() != arrayBound) {1190    elements.resize(arrayBound, filler);1191 1192    if (filler.getType() != commonElementType)1193      commonElementType = {};1194  }1195 1196  if (commonElementType) {1197    SmallVector<mlir::Attribute> eles;1198    eles.reserve(elements.size());1199 1200    for (const auto &element : elements)1201      eles.push_back(element);1202 1203    return cir::ConstArrayAttr::get(1204        cir::ArrayType::get(commonElementType, arrayBound),1205        mlir::ArrayAttr::get(builder.getContext(), eles));1206  }1207 1208  SmallVector<mlir::Attribute> eles;1209  eles.reserve(elements.size());1210  for (auto const &element : elements)1211    eles.push_back(element);1212 1213  auto arrAttr = mlir::ArrayAttr::get(builder.getContext(), eles);1214  return builder.getAnonConstRecord(arrAttr, /*packed=*/true);1215}1216 1217} // namespace1218 1219//===----------------------------------------------------------------------===//1220//                          ConstantLValueEmitter1221//===----------------------------------------------------------------------===//1222 1223namespace {1224/// A struct which can be used to peephole certain kinds of finalization1225/// that normally happen during l-value emission.1226struct ConstantLValue {1227  llvm::PointerUnion<mlir::Value, mlir::Attribute> value;1228  bool hasOffsetApplied;1229 1230  /*implicit*/ ConstantLValue(std::nullptr_t)1231      : value(nullptr), hasOffsetApplied(false) {}1232  /*implicit*/ ConstantLValue(cir::GlobalViewAttr address)1233      : value(address), hasOffsetApplied(false) {}1234 1235  ConstantLValue() : value(nullptr), hasOffsetApplied(false) {}1236};1237 1238/// A helper class for emitting constant l-values.1239class ConstantLValueEmitter1240    : public ConstStmtVisitor<ConstantLValueEmitter, ConstantLValue> {1241  CIRGenModule &cgm;1242  ConstantEmitter &emitter;1243  const APValue &value;1244  QualType destType;1245 1246  // Befriend StmtVisitorBase so that we don't have to expose Visit*.1247  friend StmtVisitorBase;1248 1249public:1250  ConstantLValueEmitter(ConstantEmitter &emitter, const APValue &value,1251                        QualType destType)1252      : cgm(emitter.cgm), emitter(emitter), value(value), destType(destType) {}1253 1254  mlir::Attribute tryEmit();1255 1256private:1257  mlir::Attribute tryEmitAbsolute(mlir::Type destTy);1258  ConstantLValue tryEmitBase(const APValue::LValueBase &base);1259 1260  ConstantLValue VisitStmt(const Stmt *s) { return nullptr; }1261  ConstantLValue VisitConstantExpr(const ConstantExpr *e);1262  ConstantLValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *e);1263  ConstantLValue VisitStringLiteral(const StringLiteral *e);1264  ConstantLValue VisitObjCBoxedExpr(const ObjCBoxedExpr *e);1265  ConstantLValue VisitObjCEncodeExpr(const ObjCEncodeExpr *e);1266  ConstantLValue VisitObjCStringLiteral(const ObjCStringLiteral *e);1267  ConstantLValue VisitPredefinedExpr(const PredefinedExpr *e);1268  ConstantLValue VisitAddrLabelExpr(const AddrLabelExpr *e);1269  ConstantLValue VisitCallExpr(const CallExpr *e);1270  ConstantLValue VisitBlockExpr(const BlockExpr *e);1271  ConstantLValue VisitCXXTypeidExpr(const CXXTypeidExpr *e);1272  ConstantLValue1273  VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *e);1274 1275  /// Return GEP-like value offset1276  mlir::ArrayAttr getOffset(mlir::Type ty) {1277    int64_t offset = value.getLValueOffset().getQuantity();1278    cir::CIRDataLayout layout(cgm.getModule());1279    SmallVector<int64_t, 3> idxVec;1280    cgm.getBuilder().computeGlobalViewIndicesFromFlatOffset(offset, ty, layout,1281                                                            idxVec);1282 1283    llvm::SmallVector<mlir::Attribute, 3> indices;1284    for (int64_t i : idxVec) {1285      mlir::IntegerAttr intAttr = cgm.getBuilder().getI32IntegerAttr(i);1286      indices.push_back(intAttr);1287    }1288 1289    if (indices.empty())1290      return {};1291    return cgm.getBuilder().getArrayAttr(indices);1292  }1293 1294  /// Apply the value offset to the given constant.1295  ConstantLValue applyOffset(ConstantLValue &c) {1296    // Handle attribute constant LValues.1297    if (auto attr = mlir::dyn_cast<mlir::Attribute>(c.value)) {1298      if (auto gv = mlir::dyn_cast<cir::GlobalViewAttr>(attr)) {1299        auto baseTy = mlir::cast<cir::PointerType>(gv.getType()).getPointee();1300        mlir::Type destTy = cgm.getTypes().convertTypeForMem(destType);1301        assert(!gv.getIndices() && "Global view is already indexed");1302        return cir::GlobalViewAttr::get(destTy, gv.getSymbol(),1303                                        getOffset(baseTy));1304      }1305      llvm_unreachable("Unsupported attribute type to offset");1306    }1307 1308    cgm.errorNYI("ConstantLValue: non-attribute offset");1309    return {};1310  }1311};1312 1313} // namespace1314 1315mlir::Attribute ConstantLValueEmitter::tryEmit() {1316  const APValue::LValueBase &base = value.getLValueBase();1317 1318  // The destination type should be a pointer or reference1319  // type, but it might also be a cast thereof.1320  //1321  // FIXME: the chain of casts required should be reflected in the APValue.1322  // We need this in order to correctly handle things like a ptrtoint of a1323  // non-zero null pointer and addrspace casts that aren't trivially1324  // represented in LLVM IR.1325  mlir::Type destTy = cgm.getTypes().convertTypeForMem(destType);1326  assert(mlir::isa<cir::PointerType>(destTy));1327 1328  // If there's no base at all, this is a null or absolute pointer,1329  // possibly cast back to an integer type.1330  if (!base)1331    return tryEmitAbsolute(destTy);1332 1333  // Otherwise, try to emit the base.1334  ConstantLValue result = tryEmitBase(base);1335 1336  // If that failed, we're done.1337  llvm::PointerUnion<mlir::Value, mlir::Attribute> &value = result.value;1338  if (!value)1339    return {};1340 1341  // Apply the offset if necessary and not already done.1342  if (!result.hasOffsetApplied)1343    value = applyOffset(result).value;1344 1345  // Convert to the appropriate type; this could be an lvalue for1346  // an integer. FIXME: performAddrSpaceCast1347  if (mlir::isa<cir::PointerType>(destTy)) {1348    if (auto attr = mlir::dyn_cast<mlir::Attribute>(value))1349      return attr;1350    cgm.errorNYI("ConstantLValueEmitter: non-attribute pointer");1351    return {};1352  }1353 1354  cgm.errorNYI("ConstantLValueEmitter: other?");1355  return {};1356}1357 1358/// Try to emit an absolute l-value, such as a null pointer or an integer1359/// bitcast to pointer type.1360mlir::Attribute ConstantLValueEmitter::tryEmitAbsolute(mlir::Type destTy) {1361  // If we're producing a pointer, this is easy.1362  auto destPtrTy = mlir::cast<cir::PointerType>(destTy);1363  return cgm.getBuilder().getConstPtrAttr(1364      destPtrTy, value.getLValueOffset().getQuantity());1365}1366 1367ConstantLValue1368ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) {1369  // Handle values.1370  if (const ValueDecl *d = base.dyn_cast<const ValueDecl *>()) {1371    // The constant always points to the canonical declaration. We want to look1372    // at properties of the most recent declaration at the point of emission.1373    d = cast<ValueDecl>(d->getMostRecentDecl());1374 1375    if (d->hasAttr<WeakRefAttr>()) {1376      cgm.errorNYI(d->getSourceRange(),1377                   "ConstantLValueEmitter: emit pointer base for weakref");1378      return {};1379    }1380 1381    if (auto *fd = dyn_cast<FunctionDecl>(d)) {1382      cir::FuncOp fop = cgm.getAddrOfFunction(fd);1383      CIRGenBuilderTy &builder = cgm.getBuilder();1384      mlir::MLIRContext *mlirContext = builder.getContext();1385      return cir::GlobalViewAttr::get(1386          builder.getPointerTo(fop.getFunctionType()),1387          mlir::FlatSymbolRefAttr::get(mlirContext, fop.getSymNameAttr()));1388    }1389 1390    if (auto *vd = dyn_cast<VarDecl>(d)) {1391      // We can never refer to a variable with local storage.1392      if (!vd->hasLocalStorage()) {1393        if (vd->isFileVarDecl() || vd->hasExternalStorage())1394          return cgm.getAddrOfGlobalVarAttr(vd);1395 1396        if (vd->isLocalVarDecl()) {1397          cgm.errorNYI(vd->getSourceRange(),1398                       "ConstantLValueEmitter: local var decl");1399          return {};1400        }1401      }1402    }1403 1404    // Classic codegen handles MSGuidDecl,UnnamedGlobalConstantDecl, and1405    // TemplateParamObjectDecl, but it can also fall through from VarDecl,1406    // in which case it silently returns nullptr. For now, let's emit an1407    // error to see what cases we need to handle.1408    cgm.errorNYI(d->getSourceRange(),1409                 "ConstantLValueEmitter: unhandled value decl");1410    return {};1411  }1412 1413  // Handle typeid(T).1414  if (base.dyn_cast<TypeInfoLValue>()) {1415    cgm.errorNYI("ConstantLValueEmitter: typeid");1416    return {};1417  }1418 1419  // Otherwise, it must be an expression.1420  return Visit(base.get<const Expr *>());1421}1422 1423ConstantLValue ConstantLValueEmitter::VisitConstantExpr(const ConstantExpr *e) {1424  cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: constant expr");1425  return {};1426}1427 1428ConstantLValue1429ConstantLValueEmitter::VisitCompoundLiteralExpr(const CompoundLiteralExpr *e) {1430  cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: compound literal");1431  return {};1432}1433 1434ConstantLValue1435ConstantLValueEmitter::VisitStringLiteral(const StringLiteral *e) {1436  return cgm.getAddrOfConstantStringFromLiteral(e);1437}1438 1439ConstantLValue1440ConstantLValueEmitter::VisitObjCEncodeExpr(const ObjCEncodeExpr *e) {1441  cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: objc encode expr");1442  return {};1443}1444 1445ConstantLValue1446ConstantLValueEmitter::VisitObjCStringLiteral(const ObjCStringLiteral *e) {1447  cgm.errorNYI(e->getSourceRange(),1448               "ConstantLValueEmitter: objc string literal");1449  return {};1450}1451 1452ConstantLValue1453ConstantLValueEmitter::VisitObjCBoxedExpr(const ObjCBoxedExpr *e) {1454  cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: objc boxed expr");1455  return {};1456}1457 1458ConstantLValue1459ConstantLValueEmitter::VisitPredefinedExpr(const PredefinedExpr *e) {1460  cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: predefined expr");1461  return {};1462}1463 1464ConstantLValue1465ConstantLValueEmitter::VisitAddrLabelExpr(const AddrLabelExpr *e) {1466  cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: addr label expr");1467  return {};1468}1469 1470ConstantLValue ConstantLValueEmitter::VisitCallExpr(const CallExpr *e) {1471  cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: call expr");1472  return {};1473}1474 1475ConstantLValue ConstantLValueEmitter::VisitBlockExpr(const BlockExpr *e) {1476  cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: block expr");1477  return {};1478}1479 1480ConstantLValue1481ConstantLValueEmitter::VisitCXXTypeidExpr(const CXXTypeidExpr *e) {1482  cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: cxx typeid expr");1483  return {};1484}1485 1486ConstantLValue ConstantLValueEmitter::VisitMaterializeTemporaryExpr(1487    const MaterializeTemporaryExpr *e) {1488  cgm.errorNYI(e->getSourceRange(),1489               "ConstantLValueEmitter: materialize temporary expr");1490  return {};1491}1492 1493//===----------------------------------------------------------------------===//1494//                             ConstantEmitter1495//===----------------------------------------------------------------------===//1496 1497mlir::Attribute ConstantEmitter::tryEmitForInitializer(const VarDecl &d) {1498  initializeNonAbstract();1499  return markIfFailed(tryEmitPrivateForVarInit(d));1500}1501 1502void ConstantEmitter::finalize(cir::GlobalOp gv) {1503  assert(initializedNonAbstract &&1504         "finalizing emitter that was used for abstract emission?");1505  assert(!finalized && "finalizing emitter multiple times");1506  assert(!gv.isDeclaration());1507#ifndef NDEBUG1508  // Note that we might also be Failed.1509  finalized = true;1510#endif // NDEBUG1511}1512 1513mlir::Attribute1514ConstantEmitter::tryEmitAbstractForInitializer(const VarDecl &d) {1515  AbstractStateRAII state(*this, true);1516  return tryEmitPrivateForVarInit(d);1517}1518 1519ConstantEmitter::~ConstantEmitter() {1520  assert((!initializedNonAbstract || finalized || failed) &&1521         "not finalized after being initialized for non-abstract emission");1522}1523 1524static mlir::TypedAttr emitNullConstantForBase(CIRGenModule &cgm,1525                                               mlir::Type baseType,1526                                               const CXXRecordDecl *baseDecl);1527 1528static mlir::TypedAttr emitNullConstant(CIRGenModule &cgm, const RecordDecl *rd,1529                                        bool asCompleteObject) {1530  const CIRGenRecordLayout &layout = cgm.getTypes().getCIRGenRecordLayout(rd);1531  mlir::Type ty = (asCompleteObject ? layout.getCIRType()1532                                    : layout.getBaseSubobjectCIRType());1533  auto recordTy = mlir::cast<cir::RecordType>(ty);1534 1535  unsigned numElements = recordTy.getNumElements();1536  SmallVector<mlir::Attribute> elements(numElements);1537 1538  auto *cxxrd = dyn_cast<CXXRecordDecl>(rd);1539  // Fill in all the bases.1540  if (cxxrd) {1541    for (const CXXBaseSpecifier &base : cxxrd->bases()) {1542      if (base.isVirtual()) {1543        // Ignore virtual bases; if we're laying out for a complete1544        // object, we'll lay these out later.1545        continue;1546      }1547 1548      const auto *baseDecl = base.getType()->castAsCXXRecordDecl();1549      // Ignore empty bases.1550      if (isEmptyRecordForLayout(cgm.getASTContext(), base.getType()) ||1551          cgm.getASTContext()1552              .getASTRecordLayout(baseDecl)1553              .getNonVirtualSize()1554              .isZero())1555        continue;1556 1557      unsigned fieldIndex = layout.getNonVirtualBaseCIRFieldNo(baseDecl);1558      mlir::Type baseType = recordTy.getElementType(fieldIndex);1559      elements[fieldIndex] = emitNullConstantForBase(cgm, baseType, baseDecl);1560    }1561  }1562 1563  // Fill in all the fields.1564  for (const FieldDecl *field : rd->fields()) {1565    // Fill in non-bitfields. (Bitfields always use a zero pattern, which we1566    // will fill in later.)1567    if (!field->isBitField() &&1568        !isEmptyFieldForLayout(cgm.getASTContext(), field)) {1569      unsigned fieldIndex = layout.getCIRFieldNo(field);1570      elements[fieldIndex] = cgm.emitNullConstantAttr(field->getType());1571    }1572 1573    // For unions, stop after the first named field.1574    if (rd->isUnion()) {1575      if (field->getIdentifier())1576        break;1577      if (const auto *fieldRD = field->getType()->getAsRecordDecl())1578        if (fieldRD->findFirstNamedDataMember())1579          break;1580    }1581  }1582 1583  // Fill in the virtual bases, if we're working with the complete object.1584  if (cxxrd && asCompleteObject) {1585    for ([[maybe_unused]] const CXXBaseSpecifier &vbase : cxxrd->vbases()) {1586      cgm.errorNYI(vbase.getSourceRange(), "emitNullConstant: virtual base");1587      return {};1588    }1589  }1590 1591  // Now go through all other fields and zero them out.1592  for (unsigned i = 0; i != numElements; ++i) {1593    if (!elements[i]) {1594      cgm.errorNYI(rd->getSourceRange(), "emitNullConstant: field not zeroed");1595      return {};1596    }1597  }1598 1599  mlir::MLIRContext *mlirContext = recordTy.getContext();1600  return cir::ConstRecordAttr::get(recordTy,1601                                   mlir::ArrayAttr::get(mlirContext, elements));1602}1603 1604/// Emit the null constant for a base subobject.1605static mlir::TypedAttr emitNullConstantForBase(CIRGenModule &cgm,1606                                               mlir::Type baseType,1607                                               const CXXRecordDecl *baseDecl) {1608  const CIRGenRecordLayout &baseLayout =1609      cgm.getTypes().getCIRGenRecordLayout(baseDecl);1610 1611  // Just zero out bases that don't have any pointer to data members.1612  if (baseLayout.isZeroInitializableAsBase())1613    return cgm.getBuilder().getZeroInitAttr(baseType);1614 1615  // Otherwise, we can just use its null constant.1616  return emitNullConstant(cgm, baseDecl, /*asCompleteObject=*/false);1617}1618 1619mlir::Attribute ConstantEmitter::tryEmitPrivateForVarInit(const VarDecl &d) {1620  // Make a quick check if variable can be default NULL initialized1621  // and avoid going through rest of code which may do, for c++11,1622  // initialization of memory to all NULLs.1623  if (!d.hasLocalStorage()) {1624    QualType ty = cgm.getASTContext().getBaseElementType(d.getType());1625    if (ty->isRecordType()) {1626      if (const auto *e = dyn_cast_or_null<CXXConstructExpr>(d.getInit())) {1627        const CXXConstructorDecl *cd = e->getConstructor();1628        // FIXME: we should probably model this more closely to C++ than1629        // just emitting a global with zero init (mimic what we do for trivial1630        // assignments and whatnots). Since this is for globals shouldn't1631        // be a problem for the near future.1632        if (cd->isTrivial() && cd->isDefaultConstructor()) {1633          const auto *cxxrd = ty->castAsCXXRecordDecl();1634          if (cxxrd->getNumBases() != 0) {1635            // There may not be anything additional to do here, but this will1636            // force us to pause and test this path when it is supported.1637            cgm.errorNYI("tryEmitPrivateForVarInit: cxx record with bases");1638            return {};1639          }1640          if (!cgm.getTypes().isZeroInitializable(cxxrd)) {1641            // To handle this case, we really need to go through1642            // emitNullConstant, but we need an attribute, not a value1643            cgm.errorNYI(1644                "tryEmitPrivateForVarInit: non-zero-initializable cxx record");1645            return {};1646          }1647          return cir::ZeroAttr::get(cgm.convertType(d.getType()));1648        }1649      }1650    }1651  }1652  inConstantContext = d.hasConstantInitialization();1653 1654  const Expr *e = d.getInit();1655  assert(e && "No initializer to emit");1656 1657  QualType destType = d.getType();1658 1659  if (!destType->isReferenceType()) {1660    QualType nonMemoryDestType = getNonMemoryType(cgm, destType);1661    if (mlir::Attribute c = ConstExprEmitter(*this).Visit(const_cast<Expr *>(e),1662                                                          nonMemoryDestType))1663      return emitForMemory(c, destType);1664  }1665 1666  // Try to emit the initializer.  Note that this can allow some things that1667  // are not allowed by tryEmitPrivateForMemory alone.1668  if (APValue *value = d.evaluateValue())1669    return tryEmitPrivateForMemory(*value, destType);1670 1671  return {};1672}1673 1674mlir::Attribute ConstantEmitter::tryEmitConstantExpr(const ConstantExpr *ce) {1675  if (!ce->hasAPValueResult())1676    return {};1677 1678  QualType retType = ce->getType();1679  if (ce->isGLValue())1680    retType = cgm.getASTContext().getLValueReferenceType(retType);1681 1682  return emitAbstract(ce->getBeginLoc(), ce->getAPValueResult(), retType);1683}1684 1685mlir::Attribute ConstantEmitter::tryEmitPrivateForMemory(const Expr *e,1686                                                         QualType destType) {1687  QualType nonMemoryDestType = getNonMemoryType(cgm, destType);1688  mlir::TypedAttr c = tryEmitPrivate(e, nonMemoryDestType);1689  if (c) {1690    mlir::Attribute attr = emitForMemory(c, destType);1691    return mlir::cast<mlir::TypedAttr>(attr);1692  }1693  return nullptr;1694}1695 1696mlir::Attribute ConstantEmitter::tryEmitPrivateForMemory(const APValue &value,1697                                                         QualType destType) {1698  QualType nonMemoryDestType = getNonMemoryType(cgm, destType);1699  mlir::Attribute c = tryEmitPrivate(value, nonMemoryDestType);1700  return (c ? emitForMemory(c, destType) : nullptr);1701}1702 1703mlir::Attribute ConstantEmitter::emitAbstract(const Expr *e,1704                                              QualType destType) {1705  AbstractStateRAII state{*this, true};1706  mlir::Attribute c = mlir::cast<mlir::Attribute>(tryEmitPrivate(e, destType));1707  if (!c)1708    cgm.errorNYI(e->getSourceRange(),1709                 "emitAbstract failed, emit null constaant");1710  return c;1711}1712 1713mlir::Attribute ConstantEmitter::emitAbstract(SourceLocation loc,1714                                              const APValue &value,1715                                              QualType destType) {1716  AbstractStateRAII state(*this, true);1717  mlir::Attribute c = tryEmitPrivate(value, destType);1718  if (!c)1719    cgm.errorNYI(loc, "emitAbstract failed, emit null constaant");1720  return c;1721}1722 1723mlir::Attribute ConstantEmitter::emitNullForMemory(mlir::Location loc,1724                                                   CIRGenModule &cgm,1725                                                   QualType t) {1726  cir::ConstantOp cstOp =1727      cgm.emitNullConstant(t, loc).getDefiningOp<cir::ConstantOp>();1728  assert(cstOp && "expected cir.const op");1729  return emitForMemory(cgm, cstOp.getValue(), t);1730}1731 1732mlir::Attribute ConstantEmitter::emitForMemory(mlir::Attribute c,1733                                               QualType destType) {1734  // For an _Atomic-qualified constant, we may need to add tail padding.1735  if (destType->getAs<AtomicType>()) {1736    cgm.errorNYI("emitForMemory: atomic type");1737    return {};1738  }1739 1740  return c;1741}1742 1743mlir::Attribute ConstantEmitter::emitForMemory(CIRGenModule &cgm,1744                                               mlir::Attribute c,1745                                               QualType destType) {1746  // For an _Atomic-qualified constant, we may need to add tail padding.1747  if (destType->getAs<AtomicType>()) {1748    cgm.errorNYI("atomic constants");1749  }1750 1751  return c;1752}1753 1754mlir::TypedAttr ConstantEmitter::tryEmitPrivate(const Expr *e,1755                                                QualType destType) {1756  assert(!destType->isVoidType() && "can't emit a void constant");1757 1758  if (mlir::Attribute c =1759          ConstExprEmitter(*this).Visit(const_cast<Expr *>(e), destType))1760    return llvm::dyn_cast<mlir::TypedAttr>(c);1761 1762  Expr::EvalResult result;1763 1764  bool success = false;1765 1766  if (destType->isReferenceType())1767    success = e->EvaluateAsLValue(result, cgm.getASTContext());1768  else1769    success =1770        e->EvaluateAsRValue(result, cgm.getASTContext(), inConstantContext);1771 1772  if (success && !result.hasSideEffects()) {1773    mlir::Attribute c = tryEmitPrivate(result.Val, destType);1774    return llvm::dyn_cast<mlir::TypedAttr>(c);1775  }1776 1777  return nullptr;1778}1779 1780mlir::Attribute ConstantEmitter::tryEmitPrivate(const APValue &value,1781                                                QualType destType) {1782  auto &builder = cgm.getBuilder();1783  switch (value.getKind()) {1784  case APValue::None:1785  case APValue::Indeterminate:1786    cgm.errorNYI("ConstExprEmitter::tryEmitPrivate none or indeterminate");1787    return {};1788  case APValue::Int: {1789    mlir::Type ty = cgm.convertType(destType);1790    if (mlir::isa<cir::BoolType>(ty))1791      return builder.getCIRBoolAttr(value.getInt().getZExtValue());1792    assert(mlir::isa<cir::IntType>(ty) && "expected integral type");1793    return cir::IntAttr::get(ty, value.getInt());1794  }1795  case APValue::Float: {1796    const llvm::APFloat &init = value.getFloat();1797    if (&init.getSemantics() == &llvm::APFloat::IEEEhalf() &&1798        !cgm.getASTContext().getLangOpts().NativeHalfType &&1799        cgm.getASTContext().getTargetInfo().useFP16ConversionIntrinsics()) {1800      cgm.errorNYI("ConstExprEmitter::tryEmitPrivate half");1801      return {};1802    }1803 1804    mlir::Type ty = cgm.convertType(destType);1805    assert(mlir::isa<cir::FPTypeInterface>(ty) &&1806           "expected floating-point type");1807    return cir::FPAttr::get(ty, init);1808  }1809  case APValue::Array: {1810    const ArrayType *arrayTy = cgm.getASTContext().getAsArrayType(destType);1811    const QualType arrayElementTy = arrayTy->getElementType();1812    const unsigned numElements = value.getArraySize();1813    const unsigned numInitElts = value.getArrayInitializedElts();1814 1815    mlir::Attribute filler;1816    if (value.hasArrayFiller()) {1817      filler = tryEmitPrivate(value.getArrayFiller(), arrayElementTy);1818      if (!filler)1819        return {};1820    }1821 1822    SmallVector<mlir::TypedAttr, 16> elements;1823    if (filler && builder.isNullValue(filler))1824      elements.reserve(numInitElts + 1);1825    else1826      elements.reserve(numInitElts);1827 1828    mlir::Type commonElementType;1829    for (unsigned i = 0; i < numInitElts; ++i) {1830      const APValue &arrayElement = value.getArrayInitializedElt(i);1831      const mlir::Attribute element =1832          tryEmitPrivateForMemory(arrayElement, arrayElementTy);1833      if (!element)1834        return {};1835 1836      const mlir::TypedAttr elementTyped = mlir::cast<mlir::TypedAttr>(element);1837      if (i == 0)1838        commonElementType = elementTyped.getType();1839      else if (elementTyped.getType() != commonElementType) {1840        commonElementType = {};1841      }1842 1843      elements.push_back(elementTyped);1844    }1845 1846    mlir::TypedAttr typedFiller = llvm::cast_or_null<mlir::TypedAttr>(filler);1847    if (filler && !typedFiller)1848      cgm.errorNYI("array filler should always be typed");1849 1850    mlir::Type desiredType = cgm.convertType(destType);1851    return emitArrayConstant(cgm, desiredType, commonElementType, numElements,1852                             elements, typedFiller);1853  }1854  case APValue::Vector: {1855    const QualType elementType =1856        destType->castAs<VectorType>()->getElementType();1857    const unsigned numElements = value.getVectorLength();1858 1859    SmallVector<mlir::Attribute, 16> elements;1860    elements.reserve(numElements);1861 1862    for (unsigned i = 0; i < numElements; ++i) {1863      const mlir::Attribute element =1864          tryEmitPrivateForMemory(value.getVectorElt(i), elementType);1865      if (!element)1866        return {};1867      elements.push_back(element);1868    }1869 1870    const auto desiredVecTy =1871        mlir::cast<cir::VectorType>(cgm.convertType(destType));1872 1873    return cir::ConstVectorAttr::get(1874        desiredVecTy,1875        mlir::ArrayAttr::get(cgm.getBuilder().getContext(), elements));1876  }1877  case APValue::MemberPointer: {1878    cgm.errorNYI("ConstExprEmitter::tryEmitPrivate member pointer");1879    return {};1880  }1881  case APValue::LValue:1882    return ConstantLValueEmitter(*this, value, destType).tryEmit();1883  case APValue::Struct:1884  case APValue::Union:1885    return ConstRecordBuilder::buildRecord(*this, value, destType);1886  case APValue::ComplexInt:1887  case APValue::ComplexFloat: {1888    mlir::Type desiredType = cgm.convertType(destType);1889    auto complexType = mlir::dyn_cast<cir::ComplexType>(desiredType);1890 1891    mlir::Type complexElemTy = complexType.getElementType();1892    if (isa<cir::IntType>(complexElemTy)) {1893      const llvm::APSInt &real = value.getComplexIntReal();1894      const llvm::APSInt &imag = value.getComplexIntImag();1895      return cir::ConstComplexAttr::get(builder.getContext(), complexType,1896                                        cir::IntAttr::get(complexElemTy, real),1897                                        cir::IntAttr::get(complexElemTy, imag));1898    }1899 1900    assert(isa<cir::FPTypeInterface>(complexElemTy) &&1901           "expected floating-point type");1902    const llvm::APFloat &real = value.getComplexFloatReal();1903    const llvm::APFloat &imag = value.getComplexFloatImag();1904    return cir::ConstComplexAttr::get(builder.getContext(), complexType,1905                                      cir::FPAttr::get(complexElemTy, real),1906                                      cir::FPAttr::get(complexElemTy, imag));1907  }1908  case APValue::FixedPoint:1909  case APValue::AddrLabelDiff:1910    cgm.errorNYI(1911        "ConstExprEmitter::tryEmitPrivate fixed point, addr label diff");1912    return {};1913  }1914  llvm_unreachable("Unknown APValue kind");1915}1916 1917mlir::Value CIRGenModule::emitNullConstant(QualType t, mlir::Location loc) {1918  return builder.getConstant(loc, emitNullConstantAttr(t));1919}1920 1921mlir::TypedAttr CIRGenModule::emitNullConstantAttr(QualType t) {1922  if (t->getAs<PointerType>())1923    return builder.getConstNullPtrAttr(getTypes().convertTypeForMem(t));1924 1925  if (getTypes().isZeroInitializable(t))1926    return builder.getZeroInitAttr(getTypes().convertTypeForMem(t));1927 1928  if (getASTContext().getAsConstantArrayType(t)) {1929    errorNYI("CIRGenModule::emitNullConstantAttr ConstantArrayType");1930    return {};1931  }1932 1933  if (const RecordType *rt = t->getAs<RecordType>())1934    return ::emitNullConstant(*this, rt->getDecl(), /*asCompleteObject=*/true);1935 1936  assert(t->isMemberDataPointerType() &&1937         "Should only see pointers to data members here!");1938 1939  errorNYI("CIRGenModule::emitNullConstantAttr unsupported type");1940  return {};1941}1942 1943mlir::TypedAttr1944CIRGenModule::emitNullConstantForBase(const CXXRecordDecl *record) {1945  return ::emitNullConstant(*this, record, false);1946}1947