brintos

brintos / llvm-project-archived public Read only

0
0
Text · 103.5 KiB · 4065124 Raw
2727 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 Expr nodes as CIR code.10//11//===----------------------------------------------------------------------===//12 13#include "Address.h"14#include "CIRGenConstantEmitter.h"15#include "CIRGenFunction.h"16#include "CIRGenModule.h"17#include "CIRGenValue.h"18#include "mlir/IR/BuiltinAttributes.h"19#include "mlir/IR/Value.h"20#include "clang/AST/Attr.h"21#include "clang/AST/CharUnits.h"22#include "clang/AST/Decl.h"23#include "clang/AST/Expr.h"24#include "clang/AST/ExprCXX.h"25#include "clang/Basic/AddressSpaces.h"26#include "clang/Basic/TargetInfo.h"27#include "clang/CIR/Dialect/IR/CIRAttrs.h"28#include "clang/CIR/Dialect/IR/CIRDialect.h"29#include "clang/CIR/Dialect/IR/CIRTypes.h"30#include "clang/CIR/MissingFeatures.h"31#include <optional>32 33using namespace clang;34using namespace clang::CIRGen;35using namespace cir;36 37/// Get the address of a zero-sized field within a record. The resulting address38/// doesn't necessarily have the right type.39Address CIRGenFunction::emitAddrOfFieldStorage(Address base,40                                               const FieldDecl *field,41                                               llvm::StringRef fieldName,42                                               unsigned fieldIndex) {43  if (field->isZeroSize(getContext())) {44    cgm.errorNYI(field->getSourceRange(),45                 "emitAddrOfFieldStorage: zero-sized field");46    return Address::invalid();47  }48 49  mlir::Location loc = getLoc(field->getLocation());50 51  mlir::Type fieldType = convertType(field->getType());52  auto fieldPtr = cir::PointerType::get(fieldType);53  // For most cases fieldName is the same as field->getName() but for lambdas,54  // which do not currently carry the name, so it can be passed down from the55  // CaptureStmt.56  cir::GetMemberOp memberAddr = builder.createGetMember(57      loc, fieldPtr, base.getPointer(), fieldName, fieldIndex);58 59  // Retrieve layout information, compute alignment and return the final60  // address.61  const RecordDecl *rec = field->getParent();62  const CIRGenRecordLayout &layout = cgm.getTypes().getCIRGenRecordLayout(rec);63  unsigned idx = layout.getCIRFieldNo(field);64  CharUnits offset = CharUnits::fromQuantity(65      layout.getCIRType().getElementOffset(cgm.getDataLayout().layout, idx));66  return Address(memberAddr, base.getAlignment().alignmentAtOffset(offset));67}68 69/// Given an expression of pointer type, try to70/// derive a more accurate bound on the alignment of the pointer.71Address CIRGenFunction::emitPointerWithAlignment(const Expr *expr,72                                                 LValueBaseInfo *baseInfo) {73  // We allow this with ObjC object pointers because of fragile ABIs.74  assert(expr->getType()->isPointerType() ||75         expr->getType()->isObjCObjectPointerType());76  expr = expr->IgnoreParens();77 78  // Casts:79  if (auto const *ce = dyn_cast<CastExpr>(expr)) {80    if (const auto *ece = dyn_cast<ExplicitCastExpr>(ce))81      cgm.emitExplicitCastExprType(ece);82 83    switch (ce->getCastKind()) {84    // Non-converting casts (but not C's implicit conversion from void*).85    case CK_BitCast:86    case CK_NoOp:87    case CK_AddressSpaceConversion: {88      if (const auto *ptrTy =89              ce->getSubExpr()->getType()->getAs<PointerType>()) {90        if (ptrTy->getPointeeType()->isVoidType())91          break;92 93        LValueBaseInfo innerBaseInfo;94        assert(!cir::MissingFeatures::opTBAA());95        Address addr =96            emitPointerWithAlignment(ce->getSubExpr(), &innerBaseInfo);97        if (baseInfo)98          *baseInfo = innerBaseInfo;99 100        if (isa<ExplicitCastExpr>(ce)) {101          LValueBaseInfo targetTypeBaseInfo;102 103          const QualType pointeeType = expr->getType()->getPointeeType();104          const CharUnits align =105              cgm.getNaturalTypeAlignment(pointeeType, &targetTypeBaseInfo);106 107          // If the source l-value is opaque, honor the alignment of the108          // casted-to type.109          if (innerBaseInfo.getAlignmentSource() != AlignmentSource::Decl) {110            if (baseInfo)111              baseInfo->mergeForCast(targetTypeBaseInfo);112            addr = Address(addr.getPointer(), addr.getElementType(), align);113          }114        }115 116        assert(!cir::MissingFeatures::sanitizers());117 118        const mlir::Type eltTy =119            convertTypeForMem(expr->getType()->getPointeeType());120        addr = getBuilder().createElementBitCast(getLoc(expr->getSourceRange()),121                                                 addr, eltTy);122        assert(!cir::MissingFeatures::addressSpace());123 124        return addr;125      }126      break;127    }128 129    // Array-to-pointer decay. TODO(cir): BaseInfo and TBAAInfo.130    case CK_ArrayToPointerDecay:131      return emitArrayToPointerDecay(ce->getSubExpr(), baseInfo);132 133    case CK_UncheckedDerivedToBase:134    case CK_DerivedToBase: {135      assert(!cir::MissingFeatures::opTBAA());136      assert(!cir::MissingFeatures::addressIsKnownNonNull());137      Address addr = emitPointerWithAlignment(ce->getSubExpr(), baseInfo);138      const CXXRecordDecl *derived =139          ce->getSubExpr()->getType()->getPointeeCXXRecordDecl();140      return getAddressOfBaseClass(addr, derived, ce->path(),141                                   shouldNullCheckClassCastValue(ce),142                                   ce->getExprLoc());143    }144 145    case CK_AnyPointerToBlockPointerCast:146    case CK_BaseToDerived:147    case CK_BaseToDerivedMemberPointer:148    case CK_BlockPointerToObjCPointerCast:149    case CK_BuiltinFnToFnPtr:150    case CK_CPointerToObjCPointerCast:151    case CK_DerivedToBaseMemberPointer:152    case CK_Dynamic:153    case CK_FunctionToPointerDecay:154    case CK_IntegralToPointer:155    case CK_LValueToRValue:156    case CK_LValueToRValueBitCast:157    case CK_NullToMemberPointer:158    case CK_NullToPointer:159    case CK_ReinterpretMemberPointer:160      // Common pointer conversions, nothing to do here.161      // TODO: Is there any reason to treat base-to-derived conversions162      // specially?163      break;164 165    case CK_ARCConsumeObject:166    case CK_ARCExtendBlockObject:167    case CK_ARCProduceObject:168    case CK_ARCReclaimReturnedObject:169    case CK_AtomicToNonAtomic:170    case CK_BooleanToSignedIntegral:171    case CK_ConstructorConversion:172    case CK_CopyAndAutoreleaseBlockObject:173    case CK_Dependent:174    case CK_FixedPointCast:175    case CK_FixedPointToBoolean:176    case CK_FixedPointToFloating:177    case CK_FixedPointToIntegral:178    case CK_FloatingCast:179    case CK_FloatingComplexCast:180    case CK_FloatingComplexToBoolean:181    case CK_FloatingComplexToIntegralComplex:182    case CK_FloatingComplexToReal:183    case CK_FloatingRealToComplex:184    case CK_FloatingToBoolean:185    case CK_FloatingToFixedPoint:186    case CK_FloatingToIntegral:187    case CK_HLSLAggregateSplatCast:188    case CK_HLSLArrayRValue:189    case CK_HLSLElementwiseCast:190    case CK_HLSLVectorTruncation:191    case CK_IntToOCLSampler:192    case CK_IntegralCast:193    case CK_IntegralComplexCast:194    case CK_IntegralComplexToBoolean:195    case CK_IntegralComplexToFloatingComplex:196    case CK_IntegralComplexToReal:197    case CK_IntegralRealToComplex:198    case CK_IntegralToBoolean:199    case CK_IntegralToFixedPoint:200    case CK_IntegralToFloating:201    case CK_LValueBitCast:202    case CK_MatrixCast:203    case CK_MemberPointerToBoolean:204    case CK_NonAtomicToAtomic:205    case CK_ObjCObjectLValueCast:206    case CK_PointerToBoolean:207    case CK_PointerToIntegral:208    case CK_ToUnion:209    case CK_ToVoid:210    case CK_UserDefinedConversion:211    case CK_VectorSplat:212    case CK_ZeroToOCLOpaqueType:213      llvm_unreachable("unexpected cast for emitPointerWithAlignment");214    }215  }216 217  // Unary &218  if (const UnaryOperator *uo = dyn_cast<UnaryOperator>(expr)) {219    // TODO(cir): maybe we should use cir.unary for pointers here instead.220    if (uo->getOpcode() == UO_AddrOf) {221      LValue lv = emitLValue(uo->getSubExpr());222      if (baseInfo)223        *baseInfo = lv.getBaseInfo();224      assert(!cir::MissingFeatures::opTBAA());225      return lv.getAddress();226    }227  }228 229  // std::addressof and variants.230  if (auto const *call = dyn_cast<CallExpr>(expr)) {231    switch (call->getBuiltinCallee()) {232    default:233      break;234    case Builtin::BIaddressof:235    case Builtin::BI__addressof:236    case Builtin::BI__builtin_addressof: {237      cgm.errorNYI(expr->getSourceRange(),238                   "emitPointerWithAlignment: builtin addressof");239      return Address::invalid();240    }241    }242  }243 244  // Otherwise, use the alignment of the type.245  return makeNaturalAddressForPointer(246      emitScalarExpr(expr), expr->getType()->getPointeeType(), CharUnits(),247      /*forPointeeType=*/true, baseInfo);248}249 250void CIRGenFunction::emitStoreThroughLValue(RValue src, LValue dst,251                                            bool isInit) {252  if (!dst.isSimple()) {253    if (dst.isVectorElt()) {254      // Read/modify/write the vector, inserting the new element255      const mlir::Location loc = dst.getVectorPointer().getLoc();256      const mlir::Value vector =257          builder.createLoad(loc, dst.getVectorAddress());258      const mlir::Value newVector = cir::VecInsertOp::create(259          builder, loc, vector, src.getValue(), dst.getVectorIdx());260      builder.createStore(loc, newVector, dst.getVectorAddress());261      return;262    }263 264    assert(dst.isBitField() && "Unknown LValue type");265    emitStoreThroughBitfieldLValue(src, dst);266    return;267 268    cgm.errorNYI(dst.getPointer().getLoc(),269                 "emitStoreThroughLValue: non-simple lvalue");270    return;271  }272 273  assert(!cir::MissingFeatures::opLoadStoreObjC());274 275  assert(src.isScalar() && "Can't emit an aggregate store with this method");276  emitStoreOfScalar(src.getValue(), dst, isInit);277}278 279static LValue emitGlobalVarDeclLValue(CIRGenFunction &cgf, const Expr *e,280                                      const VarDecl *vd) {281  QualType t = e->getType();282 283  // If it's thread_local, emit a call to its wrapper function instead.284  assert(!cir::MissingFeatures::opGlobalThreadLocal());285  if (vd->getTLSKind() == VarDecl::TLS_Dynamic)286    cgf.cgm.errorNYI(e->getSourceRange(),287                     "emitGlobalVarDeclLValue: thread_local variable");288 289  // Check if the variable is marked as declare target with link clause in290  // device codegen.291  if (cgf.getLangOpts().OpenMP)292    cgf.cgm.errorNYI(e->getSourceRange(), "emitGlobalVarDeclLValue: OpenMP");293 294  // Traditional LLVM codegen handles thread local separately, CIR handles295  // as part of getAddrOfGlobalVar.296  mlir::Value v = cgf.cgm.getAddrOfGlobalVar(vd);297 298  assert(!cir::MissingFeatures::addressSpace());299  mlir::Type realVarTy = cgf.convertTypeForMem(vd->getType());300  cir::PointerType realPtrTy = cgf.getBuilder().getPointerTo(realVarTy);301  if (realPtrTy != v.getType())302    v = cgf.getBuilder().createBitcast(v.getLoc(), v, realPtrTy);303 304  CharUnits alignment = cgf.getContext().getDeclAlign(vd);305  Address addr(v, realVarTy, alignment);306  LValue lv;307  if (vd->getType()->isReferenceType())308    cgf.cgm.errorNYI(e->getSourceRange(),309                     "emitGlobalVarDeclLValue: reference type");310  else311    lv = cgf.makeAddrLValue(addr, t, AlignmentSource::Decl);312  assert(!cir::MissingFeatures::setObjCGCLValueClass());313  return lv;314}315 316void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr,317                                       bool isVolatile, QualType ty,318                                       LValueBaseInfo baseInfo, bool isInit,319                                       bool isNontemporal) {320  assert(!cir::MissingFeatures::opLoadStoreThreadLocal());321 322  if (const auto *clangVecTy = ty->getAs<clang::VectorType>()) {323    // Boolean vectors use `iN` as storage type.324    if (clangVecTy->isExtVectorBoolType())325      cgm.errorNYI(addr.getPointer().getLoc(),326                   "emitStoreOfScalar ExtVectorBoolType");327 328    // Handle vectors of size 3 like size 4 for better performance.329    const mlir::Type elementType = addr.getElementType();330    const auto vecTy = cast<cir::VectorType>(elementType);331 332    // TODO(CIR): Use `ABIInfo::getOptimalVectorMemoryType` once it upstreamed333    assert(!cir::MissingFeatures::cirgenABIInfo());334    if (vecTy.getSize() == 3 && !getLangOpts().PreserveVec3Type)335      cgm.errorNYI(addr.getPointer().getLoc(),336                   "emitStoreOfScalar Vec3 & PreserveVec3Type disabled");337  }338 339  value = emitToMemory(value, ty);340 341  assert(!cir::MissingFeatures::opLoadStoreTbaa());342  LValue atomicLValue = LValue::makeAddr(addr, ty, baseInfo);343  if (ty->isAtomicType() ||344      (!isInit && isLValueSuitableForInlineAtomic(atomicLValue))) {345    emitAtomicStore(RValue::get(value), atomicLValue, isInit);346    return;347  }348 349  // Update the alloca with more info on initialization.350  assert(addr.getPointer() && "expected pointer to exist");351  auto srcAlloca = addr.getDefiningOp<cir::AllocaOp>();352  if (currVarDecl && srcAlloca) {353    const VarDecl *vd = currVarDecl;354    assert(vd && "VarDecl expected");355    if (vd->hasInit())356      srcAlloca.setInitAttr(mlir::UnitAttr::get(&getMLIRContext()));357  }358 359  assert(currSrcLoc && "must pass in source location");360  builder.createStore(*currSrcLoc, value, addr, isVolatile);361 362  if (isNontemporal) {363    cgm.errorNYI(addr.getPointer().getLoc(), "emitStoreOfScalar nontemporal");364    return;365  }366 367  assert(!cir::MissingFeatures::opTBAA());368}369 370// TODO: Replace this with a proper TargetInfo function call.371/// Helper method to check if the underlying ABI is AAPCS372static bool isAAPCS(const TargetInfo &targetInfo) {373  return targetInfo.getABI().starts_with("aapcs");374}375 376mlir::Value CIRGenFunction::emitStoreThroughBitfieldLValue(RValue src,377                                                           LValue dst) {378 379  const CIRGenBitFieldInfo &info = dst.getBitFieldInfo();380  mlir::Type resLTy = convertTypeForMem(dst.getType());381  Address ptr = dst.getBitFieldAddress();382 383  bool useVoaltile = cgm.getCodeGenOpts().AAPCSBitfieldWidth &&384                     dst.isVolatileQualified() &&385                     info.volatileStorageSize != 0 && isAAPCS(cgm.getTarget());386 387  mlir::Value dstAddr = dst.getAddress().getPointer();388 389  return builder.createSetBitfield(dstAddr.getLoc(), resLTy, ptr,390                                   ptr.getElementType(), src.getValue(), info,391                                   dst.isVolatileQualified(), useVoaltile);392}393 394RValue CIRGenFunction::emitLoadOfBitfieldLValue(LValue lv, SourceLocation loc) {395  const CIRGenBitFieldInfo &info = lv.getBitFieldInfo();396 397  // Get the output type.398  mlir::Type resLTy = convertType(lv.getType());399  Address ptr = lv.getBitFieldAddress();400 401  bool useVoaltile = lv.isVolatileQualified() && info.volatileOffset != 0 &&402                     isAAPCS(cgm.getTarget());403 404  mlir::Value field =405      builder.createGetBitfield(getLoc(loc), resLTy, ptr, ptr.getElementType(),406                                info, lv.isVolatile(), useVoaltile);407  assert(!cir::MissingFeatures::opLoadEmitScalarRangeCheck() && "NYI");408  return RValue::get(field);409}410 411Address CIRGenFunction::getAddrOfBitFieldStorage(LValue base,412                                                 const FieldDecl *field,413                                                 mlir::Type fieldType,414                                                 unsigned index) {415  mlir::Location loc = getLoc(field->getLocation());416  cir::PointerType fieldPtr = cir::PointerType::get(fieldType);417  auto rec = cast<cir::RecordType>(base.getAddress().getElementType());418  cir::GetMemberOp sea = getBuilder().createGetMember(419      loc, fieldPtr, base.getPointer(), field->getName(),420      rec.isUnion() ? field->getFieldIndex() : index);421  CharUnits offset = CharUnits::fromQuantity(422      rec.getElementOffset(cgm.getDataLayout().layout, index));423  return Address(sea, base.getAlignment().alignmentAtOffset(offset));424}425 426LValue CIRGenFunction::emitLValueForBitField(LValue base,427                                             const FieldDecl *field) {428  LValueBaseInfo baseInfo = base.getBaseInfo();429  const CIRGenRecordLayout &layout =430      cgm.getTypes().getCIRGenRecordLayout(field->getParent());431  const CIRGenBitFieldInfo &info = layout.getBitFieldInfo(field);432 433  assert(!cir::MissingFeatures::preservedAccessIndexRegion());434 435  unsigned idx = layout.getCIRFieldNo(field);436  Address addr = getAddrOfBitFieldStorage(base, field, info.storageType, idx);437 438  mlir::Location loc = getLoc(field->getLocation());439  if (addr.getElementType() != info.storageType)440    addr = builder.createElementBitCast(loc, addr, info.storageType);441 442  QualType fieldType =443      field->getType().withCVRQualifiers(base.getVRQualifiers());444  // TODO(cir): Support TBAA for bit fields.445  assert(!cir::MissingFeatures::opTBAA());446  LValueBaseInfo fieldBaseInfo(baseInfo.getAlignmentSource());447  return LValue::makeBitfield(addr, info, fieldType, fieldBaseInfo);448}449 450LValue CIRGenFunction::emitLValueForField(LValue base, const FieldDecl *field) {451  LValueBaseInfo baseInfo = base.getBaseInfo();452 453  if (field->isBitField())454    return emitLValueForBitField(base, field);455 456  QualType fieldType = field->getType();457  const RecordDecl *rec = field->getParent();458  AlignmentSource baseAlignSource = baseInfo.getAlignmentSource();459  LValueBaseInfo fieldBaseInfo(getFieldAlignmentSource(baseAlignSource));460  assert(!cir::MissingFeatures::opTBAA());461 462  Address addr = base.getAddress();463  if (auto *classDecl = dyn_cast<CXXRecordDecl>(rec)) {464    if (cgm.getCodeGenOpts().StrictVTablePointers &&465        classDecl->isDynamicClass()) {466      cgm.errorNYI(field->getSourceRange(),467                   "emitLValueForField: strict vtable for dynamic class");468    }469  }470 471  unsigned recordCVR = base.getVRQualifiers();472 473  llvm::StringRef fieldName = field->getName();474  unsigned fieldIndex;475  if (cgm.lambdaFieldToName.count(field))476    fieldName = cgm.lambdaFieldToName[field];477 478  if (rec->isUnion())479    fieldIndex = field->getFieldIndex();480  else {481    const CIRGenRecordLayout &layout =482        cgm.getTypes().getCIRGenRecordLayout(field->getParent());483    fieldIndex = layout.getCIRFieldNo(field);484  }485 486  addr = emitAddrOfFieldStorage(addr, field, fieldName, fieldIndex);487  assert(!cir::MissingFeatures::preservedAccessIndexRegion());488 489  // If this is a reference field, load the reference right now.490  if (fieldType->isReferenceType()) {491    assert(!cir::MissingFeatures::opTBAA());492    LValue refLVal = makeAddrLValue(addr, fieldType, fieldBaseInfo);493    if (recordCVR & Qualifiers::Volatile)494      refLVal.getQuals().addVolatile();495    addr = emitLoadOfReference(refLVal, getLoc(field->getSourceRange()),496                               &fieldBaseInfo);497 498    // Qualifiers on the struct don't apply to the referencee.499    recordCVR = 0;500    fieldType = fieldType->getPointeeType();501  }502 503  if (field->hasAttr<AnnotateAttr>()) {504    cgm.errorNYI(field->getSourceRange(), "emitLValueForField: AnnotateAttr");505    return LValue();506  }507 508  LValue lv = makeAddrLValue(addr, fieldType, fieldBaseInfo);509  lv.getQuals().addCVRQualifiers(recordCVR);510 511  // __weak attribute on a field is ignored.512  if (lv.getQuals().getObjCGCAttr() == Qualifiers::Weak) {513    cgm.errorNYI(field->getSourceRange(),514                 "emitLValueForField: __weak attribute");515    return LValue();516  }517 518  return lv;519}520 521LValue CIRGenFunction::emitLValueForFieldInitialization(522    LValue base, const clang::FieldDecl *field, llvm::StringRef fieldName) {523  QualType fieldType = field->getType();524 525  if (!fieldType->isReferenceType())526    return emitLValueForField(base, field);527 528  const CIRGenRecordLayout &layout =529      cgm.getTypes().getCIRGenRecordLayout(field->getParent());530  unsigned fieldIndex = layout.getCIRFieldNo(field);531 532  Address v =533      emitAddrOfFieldStorage(base.getAddress(), field, fieldName, fieldIndex);534 535  // Make sure that the address is pointing to the right type.536  mlir::Type memTy = convertTypeForMem(fieldType);537  v = builder.createElementBitCast(getLoc(field->getSourceRange()), v, memTy);538 539  // TODO: Generate TBAA information that describes this access as a structure540  // member access and not just an access to an object of the field's type. This541  // should be similar to what we do in EmitLValueForField().542  LValueBaseInfo baseInfo = base.getBaseInfo();543  AlignmentSource fieldAlignSource = baseInfo.getAlignmentSource();544  LValueBaseInfo fieldBaseInfo(getFieldAlignmentSource(fieldAlignSource));545  assert(!cir::MissingFeatures::opTBAA());546  return makeAddrLValue(v, fieldType, fieldBaseInfo);547}548 549mlir::Value CIRGenFunction::emitToMemory(mlir::Value value, QualType ty) {550  // Bool has a different representation in memory than in registers,551  // but in ClangIR, it is simply represented as a cir.bool value.552  // This function is here as a placeholder for possible future changes.553  return value;554}555 556void CIRGenFunction::emitStoreOfScalar(mlir::Value value, LValue lvalue,557                                       bool isInit) {558  if (lvalue.getType()->isConstantMatrixType()) {559    assert(0 && "NYI: emitStoreOfScalar constant matrix type");560    return;561  }562 563  emitStoreOfScalar(value, lvalue.getAddress(), lvalue.isVolatile(),564                    lvalue.getType(), lvalue.getBaseInfo(), isInit,565                    /*isNontemporal=*/false);566}567 568mlir::Value CIRGenFunction::emitLoadOfScalar(Address addr, bool isVolatile,569                                             QualType ty, SourceLocation loc,570                                             LValueBaseInfo baseInfo) {571  assert(!cir::MissingFeatures::opLoadStoreThreadLocal());572  mlir::Type eltTy = addr.getElementType();573 574  if (const auto *clangVecTy = ty->getAs<clang::VectorType>()) {575    if (clangVecTy->isExtVectorBoolType()) {576      cgm.errorNYI(loc, "emitLoadOfScalar: ExtVectorBoolType");577      return nullptr;578    }579 580    const auto vecTy = cast<cir::VectorType>(eltTy);581 582    // Handle vectors of size 3 like size 4 for better performance.583    assert(!cir::MissingFeatures::cirgenABIInfo());584    if (vecTy.getSize() == 3 && !getLangOpts().PreserveVec3Type)585      cgm.errorNYI(addr.getPointer().getLoc(),586                   "emitLoadOfScalar Vec3 & PreserveVec3Type disabled");587  }588 589  assert(!cir::MissingFeatures::opLoadStoreTbaa());590  LValue atomicLValue = LValue::makeAddr(addr, ty, baseInfo);591  if (ty->isAtomicType() || isLValueSuitableForInlineAtomic(atomicLValue))592    cgm.errorNYI("emitLoadOfScalar: load atomic");593 594  if (mlir::isa<cir::VoidType>(eltTy))595    cgm.errorNYI(loc, "emitLoadOfScalar: void type");596 597  assert(!cir::MissingFeatures::opLoadEmitScalarRangeCheck());598 599  mlir::Value loadOp = builder.createLoad(getLoc(loc), addr, isVolatile);600  if (!ty->isBooleanType() && ty->hasBooleanRepresentation())601    cgm.errorNYI("emitLoadOfScalar: boolean type with boolean representation");602 603  return loadOp;604}605 606mlir::Value CIRGenFunction::emitLoadOfScalar(LValue lvalue,607                                             SourceLocation loc) {608  assert(!cir::MissingFeatures::opLoadStoreNontemporal());609  assert(!cir::MissingFeatures::opLoadStoreTbaa());610  return emitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatile(),611                          lvalue.getType(), loc, lvalue.getBaseInfo());612}613 614/// Given an expression that represents a value lvalue, this615/// method emits the address of the lvalue, then loads the result as an rvalue,616/// returning the rvalue.617RValue CIRGenFunction::emitLoadOfLValue(LValue lv, SourceLocation loc) {618  assert(!lv.getType()->isFunctionType());619  assert(!(lv.getType()->isConstantMatrixType()) && "not implemented");620 621  if (lv.isBitField())622    return emitLoadOfBitfieldLValue(lv, loc);623 624  if (lv.isSimple())625    return RValue::get(emitLoadOfScalar(lv, loc));626 627  if (lv.isVectorElt()) {628    const mlir::Value load =629        builder.createLoad(getLoc(loc), lv.getVectorAddress());630    return RValue::get(cir::VecExtractOp::create(builder, getLoc(loc), load,631                                                 lv.getVectorIdx()));632  }633 634  if (lv.isExtVectorElt())635    return emitLoadOfExtVectorElementLValue(lv);636 637  cgm.errorNYI(loc, "emitLoadOfLValue");638  return RValue::get(nullptr);639}640 641int64_t CIRGenFunction::getAccessedFieldNo(unsigned int idx,642                                           const mlir::ArrayAttr elts) {643  auto elt = mlir::cast<mlir::IntegerAttr>(elts[idx]);644  return elt.getInt();645}646 647// If this is a reference to a subset of the elements of a vector, create an648// appropriate shufflevector.649RValue CIRGenFunction::emitLoadOfExtVectorElementLValue(LValue lv) {650  mlir::Location loc = lv.getExtVectorPointer().getLoc();651  mlir::Value vec = builder.createLoad(loc, lv.getExtVectorAddress());652 653  // HLSL allows treating scalars as one-element vectors. Converting the scalar654  // IR value to a vector here allows the rest of codegen to behave as normal.655  if (getLangOpts().HLSL && !mlir::isa<cir::VectorType>(vec.getType())) {656    cgm.errorNYI(loc, "emitLoadOfExtVectorElementLValue: HLSL");657    return {};658  }659 660  const mlir::ArrayAttr elts = lv.getExtVectorElts();661 662  // If the result of the expression is a non-vector type, we must be extracting663  // a single element. Just codegen as an extractelement.664  const auto *exprVecTy = lv.getType()->getAs<clang::VectorType>();665  if (!exprVecTy) {666    int64_t indexValue = getAccessedFieldNo(0, elts);667    cir::ConstantOp index =668        builder.getConstInt(loc, builder.getSInt64Ty(), indexValue);669    return RValue::get(cir::VecExtractOp::create(builder, loc, vec, index));670  }671 672  // Always use shuffle vector to try to retain the original program structure673  SmallVector<int64_t> mask;674  for (auto i : llvm::seq<unsigned>(0, exprVecTy->getNumElements()))675    mask.push_back(getAccessedFieldNo(i, elts));676 677  cir::VecShuffleOp resultVec = builder.createVecShuffle(loc, vec, mask);678  if (lv.getType()->isExtVectorBoolType()) {679    cgm.errorNYI(loc, "emitLoadOfExtVectorElementLValue: ExtVectorBoolType");680    return {};681  }682 683  return RValue::get(resultVec);684}685 686/// Generates lvalue for partial ext_vector access.687Address CIRGenFunction::emitExtVectorElementLValue(LValue lv,688                                                   mlir::Location loc) {689  Address vectorAddress = lv.getExtVectorAddress();690  QualType elementTy = lv.getType()->castAs<VectorType>()->getElementType();691  mlir::Type vectorElementTy = cgm.getTypes().convertType(elementTy);692  Address castToPointerElement =693      vectorAddress.withElementType(builder, vectorElementTy);694 695  mlir::ArrayAttr extVecElts = lv.getExtVectorElts();696  unsigned idx = getAccessedFieldNo(0, extVecElts);697  mlir::Value idxValue =698      builder.getConstInt(loc, mlir::cast<cir::IntType>(ptrDiffTy), idx);699 700  mlir::Value elementValue = builder.getArrayElement(701      loc, loc, castToPointerElement.getPointer(), vectorElementTy, idxValue,702      /*shouldDecay=*/false);703 704  const CharUnits eltSize = getContext().getTypeSizeInChars(elementTy);705  const CharUnits alignment =706      castToPointerElement.getAlignment().alignmentAtOffset(idx * eltSize);707  return Address(elementValue, vectorElementTy, alignment);708}709 710static cir::FuncOp emitFunctionDeclPointer(CIRGenModule &cgm, GlobalDecl gd) {711  assert(!cir::MissingFeatures::weakRefReference());712  return cgm.getAddrOfFunction(gd);713}714 715static LValue emitCapturedFieldLValue(CIRGenFunction &cgf, const FieldDecl *fd,716                                      mlir::Value thisValue) {717  return cgf.emitLValueForLambdaField(fd, thisValue);718}719 720/// Given that we are currently emitting a lambda, emit an l-value for721/// one of its members.722///723LValue CIRGenFunction::emitLValueForLambdaField(const FieldDecl *field,724                                                mlir::Value thisValue) {725  bool hasExplicitObjectParameter = false;726  const auto *methD = dyn_cast_if_present<CXXMethodDecl>(curCodeDecl);727  LValue lambdaLV;728  if (methD) {729    hasExplicitObjectParameter = methD->isExplicitObjectMemberFunction();730    assert(methD->getParent()->isLambda());731    assert(methD->getParent() == field->getParent());732  }733  if (hasExplicitObjectParameter) {734    cgm.errorNYI(field->getSourceRange(), "ExplicitObjectMemberFunction");735  } else {736    QualType lambdaTagType =737        getContext().getCanonicalTagType(field->getParent());738    lambdaLV = makeNaturalAlignAddrLValue(thisValue, lambdaTagType);739  }740  return emitLValueForField(lambdaLV, field);741}742 743LValue CIRGenFunction::emitLValueForLambdaField(const FieldDecl *field) {744  return emitLValueForLambdaField(field, cxxabiThisValue);745}746 747static LValue emitFunctionDeclLValue(CIRGenFunction &cgf, const Expr *e,748                                     GlobalDecl gd) {749  const FunctionDecl *fd = cast<FunctionDecl>(gd.getDecl());750  cir::FuncOp funcOp = emitFunctionDeclPointer(cgf.cgm, gd);751  mlir::Location loc = cgf.getLoc(e->getSourceRange());752  CharUnits align = cgf.getContext().getDeclAlign(fd);753 754  assert(!cir::MissingFeatures::sanitizers());755 756  mlir::Type fnTy = funcOp.getFunctionType();757  mlir::Type ptrTy = cir::PointerType::get(fnTy);758  mlir::Value addr = cir::GetGlobalOp::create(cgf.getBuilder(), loc, ptrTy,759                                              funcOp.getSymName());760 761  if (funcOp.getFunctionType() != cgf.convertType(fd->getType())) {762    fnTy = cgf.convertType(fd->getType());763    ptrTy = cir::PointerType::get(fnTy);764 765    addr = cir::CastOp::create(cgf.getBuilder(), addr.getLoc(), ptrTy,766                               cir::CastKind::bitcast, addr);767  }768 769  return cgf.makeAddrLValue(Address(addr, fnTy, align), e->getType(),770                            AlignmentSource::Decl);771}772 773/// Determine whether we can emit a reference to \p vd from the current774/// context, despite not necessarily having seen an odr-use of the variable in775/// this context.776/// TODO(cir): This could be shared with classic codegen.777static bool canEmitSpuriousReferenceToVariable(CIRGenFunction &cgf,778                                               const DeclRefExpr *e,779                                               const VarDecl *vd) {780  // For a variable declared in an enclosing scope, do not emit a spurious781  // reference even if we have a capture, as that will emit an unwarranted782  // reference to our capture state, and will likely generate worse code than783  // emitting a local copy.784  if (e->refersToEnclosingVariableOrCapture())785    return false;786 787  // For a local declaration declared in this function, we can always reference788  // it even if we don't have an odr-use.789  if (vd->hasLocalStorage()) {790    return vd->getDeclContext() ==791           dyn_cast_or_null<DeclContext>(cgf.curCodeDecl);792  }793 794  // For a global declaration, we can emit a reference to it if we know795  // for sure that we are able to emit a definition of it.796  vd = vd->getDefinition(cgf.getContext());797  if (!vd)798    return false;799 800  // Don't emit a spurious reference if it might be to a variable that only801  // exists on a different device / target.802  // FIXME: This is unnecessarily broad. Check whether this would actually be a803  // cross-target reference.804  if (cgf.getLangOpts().OpenMP || cgf.getLangOpts().CUDA ||805      cgf.getLangOpts().OpenCL) {806    return false;807  }808 809  // We can emit a spurious reference only if the linkage implies that we'll810  // be emitting a non-interposable symbol that will be retained until link811  // time.812  switch (cgf.cgm.getCIRLinkageVarDefinition(vd, /*IsConstant=*/false)) {813  case cir::GlobalLinkageKind::ExternalLinkage:814  case cir::GlobalLinkageKind::LinkOnceODRLinkage:815  case cir::GlobalLinkageKind::WeakODRLinkage:816  case cir::GlobalLinkageKind::InternalLinkage:817  case cir::GlobalLinkageKind::PrivateLinkage:818    return true;819  default:820    return false;821  }822}823 824LValue CIRGenFunction::emitDeclRefLValue(const DeclRefExpr *e) {825  const NamedDecl *nd = e->getDecl();826  QualType ty = e->getType();827 828  assert(e->isNonOdrUse() != NOUR_Unevaluated &&829         "should not emit an unevaluated operand");830 831  if (const auto *vd = dyn_cast<VarDecl>(nd)) {832    // Global Named registers access via intrinsics only833    if (vd->getStorageClass() == SC_Register && vd->hasAttr<AsmLabelAttr>() &&834        !vd->isLocalVarDecl()) {835      cgm.errorNYI(e->getSourceRange(),836                   "emitDeclRefLValue: Global Named registers access");837      return LValue();838    }839 840    if (e->isNonOdrUse() == NOUR_Constant &&841        (vd->getType()->isReferenceType() ||842         !canEmitSpuriousReferenceToVariable(*this, e, vd))) {843      cgm.errorNYI(e->getSourceRange(), "emitDeclRefLValue: NonOdrUse");844      return LValue();845    }846 847    // Check for captured variables.848    if (e->refersToEnclosingVariableOrCapture()) {849      vd = vd->getCanonicalDecl();850      if (FieldDecl *fd = lambdaCaptureFields.lookup(vd))851        return emitCapturedFieldLValue(*this, fd, cxxabiThisValue);852      assert(!cir::MissingFeatures::cgCapturedStmtInfo());853      assert(!cir::MissingFeatures::openMP());854    }855  }856 857  if (const auto *vd = dyn_cast<VarDecl>(nd)) {858    // Checks for omitted feature handling859    assert(!cir::MissingFeatures::opAllocaStaticLocal());860    assert(!cir::MissingFeatures::opAllocaNonGC());861    assert(!cir::MissingFeatures::opAllocaImpreciseLifetime());862    assert(!cir::MissingFeatures::opAllocaTLS());863    assert(!cir::MissingFeatures::opAllocaOpenMPThreadPrivate());864    assert(!cir::MissingFeatures::opAllocaEscapeByReference());865 866    // Check if this is a global variable867    if (vd->hasLinkage() || vd->isStaticDataMember())868      return emitGlobalVarDeclLValue(*this, e, vd);869 870    Address addr = Address::invalid();871 872    // The variable should generally be present in the local decl map.873    auto iter = localDeclMap.find(vd);874    if (iter != localDeclMap.end()) {875      addr = iter->second;876    } else {877      // Otherwise, it might be static local we haven't emitted yet for some878      // reason; most likely, because it's in an outer function.879      cgm.errorNYI(e->getSourceRange(), "emitDeclRefLValue: static local");880    }881 882    // Drill into reference types.883    LValue lv =884        vd->getType()->isReferenceType()885            ? emitLoadOfReferenceLValue(addr, getLoc(e->getSourceRange()),886                                        vd->getType(), AlignmentSource::Decl)887            : makeAddrLValue(addr, ty, AlignmentSource::Decl);888 889    // Statics are defined as globals, so they are not include in the function's890    // symbol table.891    assert((vd->isStaticLocal() || symbolTable.count(vd)) &&892           "non-static locals should be already mapped");893 894    return lv;895  }896 897  if (const auto *bd = dyn_cast<BindingDecl>(nd)) {898    if (e->refersToEnclosingVariableOrCapture()) {899      assert(!cir::MissingFeatures::lambdaCaptures());900      cgm.errorNYI(e->getSourceRange(), "emitDeclRefLValue: lambda captures");901      return LValue();902    }903    return emitLValue(bd->getBinding());904  }905 906  if (const auto *fd = dyn_cast<FunctionDecl>(nd)) {907    LValue lv = emitFunctionDeclLValue(*this, e, fd);908 909    // Emit debuginfo for the function declaration if the target wants to.910    if (getContext().getTargetInfo().allowDebugInfoForExternalRef())911      assert(!cir::MissingFeatures::generateDebugInfo());912 913    return lv;914  }915 916  cgm.errorNYI(e->getSourceRange(), "emitDeclRefLValue: unhandled decl type");917  return LValue();918}919 920mlir::Value CIRGenFunction::evaluateExprAsBool(const Expr *e) {921  QualType boolTy = getContext().BoolTy;922  SourceLocation loc = e->getExprLoc();923 924  assert(!cir::MissingFeatures::pgoUse());925  if (e->getType()->getAs<MemberPointerType>()) {926    cgm.errorNYI(e->getSourceRange(),927                 "evaluateExprAsBool: member pointer type");928    return createDummyValue(getLoc(loc), boolTy);929  }930 931  assert(!cir::MissingFeatures::cgFPOptionsRAII());932  if (!e->getType()->isAnyComplexType())933    return emitScalarConversion(emitScalarExpr(e), e->getType(), boolTy, loc);934 935  return emitComplexToScalarConversion(emitComplexExpr(e), e->getType(), boolTy,936                                       loc);937}938 939LValue CIRGenFunction::emitUnaryOpLValue(const UnaryOperator *e) {940  UnaryOperatorKind op = e->getOpcode();941 942  // __extension__ doesn't affect lvalue-ness.943  if (op == UO_Extension)944    return emitLValue(e->getSubExpr());945 946  switch (op) {947  case UO_Deref: {948    QualType t = e->getSubExpr()->getType()->getPointeeType();949    assert(!t.isNull() && "CodeGenFunction::EmitUnaryOpLValue: Illegal type");950 951    assert(!cir::MissingFeatures::opTBAA());952    LValueBaseInfo baseInfo;953    Address addr = emitPointerWithAlignment(e->getSubExpr(), &baseInfo);954 955    // Tag 'load' with deref attribute.956    // FIXME: This misses some derefence cases and has problematic interactions957    // with other operators.958    if (auto loadOp = addr.getDefiningOp<cir::LoadOp>())959      loadOp.setIsDerefAttr(mlir::UnitAttr::get(&getMLIRContext()));960 961    LValue lv = makeAddrLValue(addr, t, baseInfo);962    assert(!cir::MissingFeatures::addressSpace());963    assert(!cir::MissingFeatures::setNonGC());964    return lv;965  }966  case UO_Real:967  case UO_Imag: {968    LValue lv = emitLValue(e->getSubExpr());969    assert(lv.isSimple() && "real/imag on non-ordinary l-value");970 971    // __real is valid on scalars. This is a faster way of testing that.972    // __imag can only produce an rvalue on scalars.973    if (e->getOpcode() == UO_Real &&974        !mlir::isa<cir::ComplexType>(lv.getAddress().getElementType())) {975      assert(e->getSubExpr()->getType()->isArithmeticType());976      return lv;977    }978 979    QualType exprTy = getContext().getCanonicalType(e->getSubExpr()->getType());980    QualType elemTy = exprTy->castAs<clang::ComplexType>()->getElementType();981    mlir::Location loc = getLoc(e->getExprLoc());982    Address component =983        e->getOpcode() == UO_Real984            ? builder.createComplexRealPtr(loc, lv.getAddress())985            : builder.createComplexImagPtr(loc, lv.getAddress());986    assert(!cir::MissingFeatures::opTBAA());987    LValue elemLV = makeAddrLValue(component, elemTy);988    elemLV.getQuals().addQualifiers(lv.getQuals());989    return elemLV;990  }991  case UO_PreInc:992  case UO_PreDec: {993    cir::UnaryOpKind kind =994        e->isIncrementOp() ? cir::UnaryOpKind::Inc : cir::UnaryOpKind::Dec;995    LValue lv = emitLValue(e->getSubExpr());996 997    assert(e->isPrefix() && "Prefix operator in unexpected state!");998 999    if (e->getType()->isAnyComplexType()) {1000      emitComplexPrePostIncDec(e, lv, kind, /*isPre=*/true);1001    } else {1002      emitScalarPrePostIncDec(e, lv, kind, /*isPre=*/true);1003    }1004 1005    return lv;1006  }1007  case UO_Extension:1008    llvm_unreachable("UnaryOperator extension should be handled above!");1009  case UO_Plus:1010  case UO_Minus:1011  case UO_Not:1012  case UO_LNot:1013  case UO_AddrOf:1014  case UO_PostInc:1015  case UO_PostDec:1016  case UO_Coawait:1017    llvm_unreachable("UnaryOperator of non-lvalue kind!");1018  }1019  llvm_unreachable("Unknown unary operator kind!");1020}1021 1022/// If the specified expr is a simple decay from an array to pointer,1023/// return the array subexpression.1024/// FIXME: this could be abstracted into a common AST helper.1025static const Expr *getSimpleArrayDecayOperand(const Expr *e) {1026  // If this isn't just an array->pointer decay, bail out.1027  const auto *castExpr = dyn_cast<CastExpr>(e);1028  if (!castExpr || castExpr->getCastKind() != CK_ArrayToPointerDecay)1029    return nullptr;1030 1031  // If this is a decay from variable width array, bail out.1032  const Expr *subExpr = castExpr->getSubExpr();1033  if (subExpr->getType()->isVariableArrayType())1034    return nullptr;1035 1036  return subExpr;1037}1038 1039static cir::IntAttr getConstantIndexOrNull(mlir::Value idx) {1040  // TODO(cir): should we consider using MLIRs IndexType instead of IntegerAttr?1041  if (auto constantOp = idx.getDefiningOp<cir::ConstantOp>())1042    return constantOp.getValueAttr<cir::IntAttr>();1043  return {};1044}1045 1046static CharUnits getArrayElementAlign(CharUnits arrayAlign, mlir::Value idx,1047                                      CharUnits eltSize) {1048  // If we have a constant index, we can use the exact offset of the1049  // element we're accessing.1050  if (const cir::IntAttr constantIdx = getConstantIndexOrNull(idx)) {1051    const CharUnits offset = constantIdx.getValue().getZExtValue() * eltSize;1052    return arrayAlign.alignmentAtOffset(offset);1053  }1054  // Otherwise, use the worst-case alignment for any element.1055  return arrayAlign.alignmentOfArrayElement(eltSize);1056}1057 1058static QualType getFixedSizeElementType(const ASTContext &astContext,1059                                        const VariableArrayType *vla) {1060  QualType eltType;1061  do {1062    eltType = vla->getElementType();1063  } while ((vla = astContext.getAsVariableArrayType(eltType)));1064  return eltType;1065}1066 1067static mlir::Value emitArraySubscriptPtr(CIRGenFunction &cgf,1068                                         mlir::Location beginLoc,1069                                         mlir::Location endLoc, mlir::Value ptr,1070                                         mlir::Type eltTy, mlir::Value idx,1071                                         bool shouldDecay) {1072  CIRGenModule &cgm = cgf.getCIRGenModule();1073  // TODO(cir): LLVM codegen emits in bound gep check here, is there anything1074  // that would enhance tracking this later in CIR?1075  assert(!cir::MissingFeatures::emitCheckedInBoundsGEP());1076  return cgm.getBuilder().getArrayElement(beginLoc, endLoc, ptr, eltTy, idx,1077                                          shouldDecay);1078}1079 1080static Address emitArraySubscriptPtr(CIRGenFunction &cgf,1081                                     mlir::Location beginLoc,1082                                     mlir::Location endLoc, Address addr,1083                                     QualType eltType, mlir::Value idx,1084                                     mlir::Location loc, bool shouldDecay) {1085 1086  // Determine the element size of the statically-sized base.  This is1087  // the thing that the indices are expressed in terms of.1088  if (const VariableArrayType *vla =1089          cgf.getContext().getAsVariableArrayType(eltType)) {1090    eltType = getFixedSizeElementType(cgf.getContext(), vla);1091  }1092 1093  // We can use that to compute the best alignment of the element.1094  const CharUnits eltSize = cgf.getContext().getTypeSizeInChars(eltType);1095  const CharUnits eltAlign =1096      getArrayElementAlign(addr.getAlignment(), idx, eltSize);1097 1098  assert(!cir::MissingFeatures::preservedAccessIndexRegion());1099  const mlir::Value eltPtr =1100      emitArraySubscriptPtr(cgf, beginLoc, endLoc, addr.getPointer(),1101                            addr.getElementType(), idx, shouldDecay);1102  const mlir::Type elementType = cgf.convertTypeForMem(eltType);1103  return Address(eltPtr, elementType, eltAlign);1104}1105 1106LValue1107CIRGenFunction::emitArraySubscriptExpr(const clang::ArraySubscriptExpr *e) {1108  if (getContext().getAsVariableArrayType(e->getType())) {1109    cgm.errorNYI(e->getSourceRange(),1110                 "emitArraySubscriptExpr: VariableArrayType");1111    return LValue::makeAddr(Address::invalid(), e->getType(), LValueBaseInfo());1112  }1113 1114  if (e->getType()->getAs<ObjCObjectType>()) {1115    cgm.errorNYI(e->getSourceRange(), "emitArraySubscriptExpr: ObjCObjectType");1116    return LValue::makeAddr(Address::invalid(), e->getType(), LValueBaseInfo());1117  }1118 1119  // The index must always be an integer, which is not an aggregate.  Emit it1120  // in lexical order (this complexity is, sadly, required by C++17).1121  assert((e->getIdx() == e->getLHS() || e->getIdx() == e->getRHS()) &&1122         "index was neither LHS nor RHS");1123 1124  auto emitIdxAfterBase = [&](bool promote) -> mlir::Value {1125    const mlir::Value idx = emitScalarExpr(e->getIdx());1126 1127    // Extend or truncate the index type to 32 or 64-bits.1128    auto ptrTy = mlir::dyn_cast<cir::PointerType>(idx.getType());1129    if (promote && ptrTy && ptrTy.isPtrTo<cir::IntType>())1130      cgm.errorNYI(e->getSourceRange(),1131                   "emitArraySubscriptExpr: index type cast");1132    return idx;1133  };1134 1135  // If the base is a vector type, then we are forming a vector element1136  // with this subscript.1137  if (e->getBase()->getType()->isSubscriptableVectorType() &&1138      !isa<ExtVectorElementExpr>(e->getBase())) {1139    const mlir::Value idx = emitIdxAfterBase(/*promote=*/false);1140    const LValue lv = emitLValue(e->getBase());1141    return LValue::makeVectorElt(lv.getAddress(), idx, e->getBase()->getType(),1142                                 lv.getBaseInfo());1143  }1144 1145  const mlir::Value idx = emitIdxAfterBase(/*promote=*/true);1146 1147  // Handle the extvector case we ignored above.1148  if (isa<ExtVectorElementExpr>(e->getBase())) {1149    const LValue lv = emitLValue(e->getBase());1150    Address addr = emitExtVectorElementLValue(lv, cgm.getLoc(e->getExprLoc()));1151 1152    QualType elementType = lv.getType()->castAs<VectorType>()->getElementType();1153    addr = emitArraySubscriptPtr(*this, cgm.getLoc(e->getBeginLoc()),1154                                 cgm.getLoc(e->getEndLoc()), addr, e->getType(),1155                                 idx, cgm.getLoc(e->getExprLoc()),1156                                 /*shouldDecay=*/false);1157 1158    return makeAddrLValue(addr, elementType, lv.getBaseInfo());1159  }1160 1161  if (const Expr *array = getSimpleArrayDecayOperand(e->getBase())) {1162    LValue arrayLV;1163    if (const auto *ase = dyn_cast<ArraySubscriptExpr>(array))1164      arrayLV = emitArraySubscriptExpr(ase);1165    else1166      arrayLV = emitLValue(array);1167 1168    // Propagate the alignment from the array itself to the result.1169    const Address addr = emitArraySubscriptPtr(1170        *this, cgm.getLoc(array->getBeginLoc()), cgm.getLoc(array->getEndLoc()),1171        arrayLV.getAddress(), e->getType(), idx, cgm.getLoc(e->getExprLoc()),1172        /*shouldDecay=*/true);1173 1174    const LValue lv = LValue::makeAddr(addr, e->getType(), LValueBaseInfo());1175 1176    if (getLangOpts().ObjC && getLangOpts().getGC() != LangOptions::NonGC) {1177      cgm.errorNYI(e->getSourceRange(), "emitArraySubscriptExpr: ObjC with GC");1178    }1179 1180    return lv;1181  }1182 1183  // The base must be a pointer; emit it with an estimate of its alignment.1184  assert(e->getBase()->getType()->isPointerType() &&1185         "The base must be a pointer");1186 1187  LValueBaseInfo eltBaseInfo;1188  const Address ptrAddr = emitPointerWithAlignment(e->getBase(), &eltBaseInfo);1189  // Propagate the alignment from the array itself to the result.1190  const Address addxr = emitArraySubscriptPtr(1191      *this, cgm.getLoc(e->getBeginLoc()), cgm.getLoc(e->getEndLoc()), ptrAddr,1192      e->getType(), idx, cgm.getLoc(e->getExprLoc()),1193      /*shouldDecay=*/false);1194 1195  const LValue lv = LValue::makeAddr(addxr, e->getType(), eltBaseInfo);1196 1197  if (getLangOpts().ObjC && getLangOpts().getGC() != LangOptions::NonGC) {1198    cgm.errorNYI(e->getSourceRange(), "emitArraySubscriptExpr: ObjC with GC");1199  }1200 1201  return lv;1202}1203 1204LValue CIRGenFunction::emitExtVectorElementExpr(const ExtVectorElementExpr *e) {1205  // Emit the base vector as an l-value.1206  LValue base;1207 1208  // ExtVectorElementExpr's base can either be a vector or pointer to vector.1209  if (e->isArrow()) {1210    // If it is a pointer to a vector, emit the address and form an lvalue with1211    // it.1212    LValueBaseInfo baseInfo;1213    Address ptr = emitPointerWithAlignment(e->getBase(), &baseInfo);1214    const auto *clangPtrTy =1215        e->getBase()->getType()->castAs<clang::PointerType>();1216    base = makeAddrLValue(ptr, clangPtrTy->getPointeeType(), baseInfo);1217    base.getQuals().removeObjCGCAttr();1218  } else if (e->getBase()->isGLValue()) {1219    // Otherwise, if the base is an lvalue ( as in the case of foo.x.x),1220    // emit the base as an lvalue.1221    assert(e->getBase()->getType()->isVectorType());1222    base = emitLValue(e->getBase());1223  } else {1224    // Otherwise, the base is a normal rvalue (as in (V+V).x), emit it as such.1225    assert(e->getBase()->getType()->isVectorType() &&1226           "Result must be a vector");1227    mlir::Value vec = emitScalarExpr(e->getBase());1228 1229    // Store the vector to memory (because LValue wants an address).1230    QualType baseTy = e->getBase()->getType();1231    Address vecMem = createMemTemp(baseTy, vec.getLoc(), "tmp");1232    if (!getLangOpts().HLSL && baseTy->isExtVectorBoolType()) {1233      cgm.errorNYI(e->getSourceRange(),1234                   "emitExtVectorElementExpr: ExtVectorBoolType & !HLSL");1235      return {};1236    }1237    builder.createStore(vec.getLoc(), vec, vecMem);1238    base = makeAddrLValue(vecMem, baseTy, AlignmentSource::Decl);1239  }1240 1241  QualType type =1242      e->getType().withCVRQualifiers(base.getQuals().getCVRQualifiers());1243 1244  // Encode the element access list into a vector of unsigned indices.1245  SmallVector<uint32_t, 4> indices;1246  e->getEncodedElementAccess(indices);1247 1248  if (base.isSimple()) {1249    SmallVector<int64_t> attrElts(indices.begin(), indices.end());1250    mlir::ArrayAttr elts = builder.getI64ArrayAttr(attrElts);1251    return LValue::makeExtVectorElt(base.getAddress(), elts, type,1252                                    base.getBaseInfo());1253  }1254 1255  cgm.errorNYI(e->getSourceRange(),1256               "emitExtVectorElementExpr: isSimple is false");1257  return {};1258}1259 1260LValue CIRGenFunction::emitStringLiteralLValue(const StringLiteral *e,1261                                               llvm::StringRef name) {1262  cir::GlobalOp globalOp = cgm.getGlobalForStringLiteral(e, name);1263  assert(globalOp.getAlignment() && "expected alignment for string literal");1264  unsigned align = *(globalOp.getAlignment());1265  mlir::Value addr =1266      builder.createGetGlobal(getLoc(e->getSourceRange()), globalOp);1267  return makeAddrLValue(1268      Address(addr, globalOp.getSymType(), CharUnits::fromQuantity(align)),1269      e->getType(), AlignmentSource::Decl);1270}1271 1272/// Casts are never lvalues unless that cast is to a reference type. If the cast1273/// is to a reference, we can have the usual lvalue result, otherwise if a cast1274/// is needed by the code generator in an lvalue context, then it must mean that1275/// we need the address of an aggregate in order to access one of its members.1276/// This can happen for all the reasons that casts are permitted with aggregate1277/// result, including noop aggregate casts, and cast from scalar to union.1278LValue CIRGenFunction::emitCastLValue(const CastExpr *e) {1279  switch (e->getCastKind()) {1280  case CK_ToVoid:1281  case CK_BitCast:1282  case CK_LValueToRValueBitCast:1283  case CK_ArrayToPointerDecay:1284  case CK_FunctionToPointerDecay:1285  case CK_NullToMemberPointer:1286  case CK_NullToPointer:1287  case CK_IntegralToPointer:1288  case CK_PointerToIntegral:1289  case CK_PointerToBoolean:1290  case CK_IntegralCast:1291  case CK_BooleanToSignedIntegral:1292  case CK_IntegralToBoolean:1293  case CK_IntegralToFloating:1294  case CK_FloatingToIntegral:1295  case CK_FloatingToBoolean:1296  case CK_FloatingCast:1297  case CK_FloatingRealToComplex:1298  case CK_FloatingComplexToReal:1299  case CK_FloatingComplexToBoolean:1300  case CK_FloatingComplexCast:1301  case CK_FloatingComplexToIntegralComplex:1302  case CK_IntegralRealToComplex:1303  case CK_IntegralComplexToReal:1304  case CK_IntegralComplexToBoolean:1305  case CK_IntegralComplexCast:1306  case CK_IntegralComplexToFloatingComplex:1307  case CK_DerivedToBaseMemberPointer:1308  case CK_BaseToDerivedMemberPointer:1309  case CK_MemberPointerToBoolean:1310  case CK_ReinterpretMemberPointer:1311  case CK_AnyPointerToBlockPointerCast:1312  case CK_ARCProduceObject:1313  case CK_ARCConsumeObject:1314  case CK_ARCReclaimReturnedObject:1315  case CK_ARCExtendBlockObject:1316  case CK_CopyAndAutoreleaseBlockObject:1317  case CK_IntToOCLSampler:1318  case CK_FloatingToFixedPoint:1319  case CK_FixedPointToFloating:1320  case CK_FixedPointCast:1321  case CK_FixedPointToBoolean:1322  case CK_FixedPointToIntegral:1323  case CK_IntegralToFixedPoint:1324  case CK_MatrixCast:1325  case CK_HLSLVectorTruncation:1326  case CK_HLSLArrayRValue:1327  case CK_HLSLElementwiseCast:1328  case CK_HLSLAggregateSplatCast:1329    llvm_unreachable("unexpected cast lvalue");1330 1331  case CK_Dependent:1332    llvm_unreachable("dependent cast kind in IR gen!");1333 1334  case CK_BuiltinFnToFnPtr:1335    llvm_unreachable("builtin functions are handled elsewhere");1336 1337  case CK_Dynamic: {1338    LValue lv = emitLValue(e->getSubExpr());1339    Address v = lv.getAddress();1340    const auto *dce = cast<CXXDynamicCastExpr>(e);1341    return makeNaturalAlignAddrLValue(emitDynamicCast(v, dce), e->getType());1342  }1343 1344  // These are never l-values; just use the aggregate emission code.1345  case CK_NonAtomicToAtomic:1346  case CK_AtomicToNonAtomic:1347  case CK_ToUnion:1348  case CK_ObjCObjectLValueCast:1349  case CK_VectorSplat:1350  case CK_ConstructorConversion:1351  case CK_UserDefinedConversion:1352  case CK_CPointerToObjCPointerCast:1353  case CK_BlockPointerToObjCPointerCast:1354  case CK_LValueToRValue: {1355    cgm.errorNYI(e->getSourceRange(),1356                 std::string("emitCastLValue for unhandled cast kind: ") +1357                     e->getCastKindName());1358 1359    return {};1360  }1361  case CK_AddressSpaceConversion: {1362    LValue lv = emitLValue(e->getSubExpr());1363    QualType destTy = getContext().getPointerType(e->getType());1364 1365    clang::LangAS srcLangAS = e->getSubExpr()->getType().getAddressSpace();1366    cir::TargetAddressSpaceAttr srcAS;1367    if (clang::isTargetAddressSpace(srcLangAS))1368      srcAS = cir::toCIRTargetAddressSpace(getMLIRContext(), srcLangAS);1369    else1370      cgm.errorNYI(1371          e->getSourceRange(),1372          "emitCastLValue: address space conversion from unknown address "1373          "space");1374 1375    mlir::Value v = getTargetHooks().performAddrSpaceCast(1376        *this, lv.getPointer(), srcAS, convertType(destTy));1377 1378    return makeAddrLValue(Address(v, convertTypeForMem(e->getType()),1379                                  lv.getAddress().getAlignment()),1380                          e->getType(), lv.getBaseInfo());1381  }1382 1383  case CK_LValueBitCast: {1384    // This must be a reinterpret_cast (or c-style equivalent).1385    const auto *ce = cast<ExplicitCastExpr>(e);1386 1387    cgm.emitExplicitCastExprType(ce, this);1388    LValue LV = emitLValue(e->getSubExpr());1389    Address V = LV.getAddress().withElementType(1390        builder, convertTypeForMem(ce->getTypeAsWritten()->getPointeeType()));1391 1392    return makeAddrLValue(V, e->getType(), LV.getBaseInfo());1393  }1394 1395  case CK_NoOp: {1396    // CK_NoOp can model a qualification conversion, which can remove an array1397    // bound and change the IR type.1398    LValue lv = emitLValue(e->getSubExpr());1399    // Propagate the volatile qualifier to LValue, if exists in e.1400    if (e->changesVolatileQualification())1401      cgm.errorNYI(e->getSourceRange(),1402                   "emitCastLValue: NoOp changes volatile qual");1403    if (lv.isSimple()) {1404      Address v = lv.getAddress();1405      if (v.isValid()) {1406        mlir::Type ty = convertTypeForMem(e->getType());1407        if (v.getElementType() != ty)1408          cgm.errorNYI(e->getSourceRange(),1409                       "emitCastLValue: NoOp needs bitcast");1410      }1411    }1412    return lv;1413  }1414 1415  case CK_UncheckedDerivedToBase:1416  case CK_DerivedToBase: {1417    auto *derivedClassDecl = e->getSubExpr()->getType()->castAsCXXRecordDecl();1418 1419    LValue lv = emitLValue(e->getSubExpr());1420    Address thisAddr = lv.getAddress();1421 1422    // Perform the derived-to-base conversion1423    Address baseAddr =1424        getAddressOfBaseClass(thisAddr, derivedClassDecl, e->path(),1425                              /*NullCheckValue=*/false, e->getExprLoc());1426 1427    // TODO: Support accesses to members of base classes in TBAA. For now, we1428    // conservatively pretend that the complete object is of the base class1429    // type.1430    assert(!cir::MissingFeatures::opTBAA());1431    return makeAddrLValue(baseAddr, e->getType(), lv.getBaseInfo());1432  }1433 1434  case CK_BaseToDerived: {1435    const auto *derivedClassDecl = e->getType()->castAsCXXRecordDecl();1436    LValue lv = emitLValue(e->getSubExpr());1437 1438    // Perform the base-to-derived conversion1439    Address derived = getAddressOfDerivedClass(1440        getLoc(e->getSourceRange()), lv.getAddress(), derivedClassDecl,1441        e->path(), /*NullCheckValue=*/false);1442    // C++11 [expr.static.cast]p2: Behavior is undefined if a downcast is1443    // performed and the object is not of the derived type.1444    assert(!cir::MissingFeatures::sanitizers());1445 1446    assert(!cir::MissingFeatures::opTBAA());1447    return makeAddrLValue(derived, e->getType(), lv.getBaseInfo());1448  }1449 1450  case CK_ZeroToOCLOpaqueType:1451    llvm_unreachable("NULL to OpenCL opaque type lvalue cast is not valid");1452  }1453 1454  llvm_unreachable("Invalid cast kind");1455}1456 1457static DeclRefExpr *tryToConvertMemberExprToDeclRefExpr(CIRGenFunction &cgf,1458                                                        const MemberExpr *me) {1459  if (auto *vd = dyn_cast<VarDecl>(me->getMemberDecl())) {1460    // Try to emit static variable member expressions as DREs.1461    return DeclRefExpr::Create(1462        cgf.getContext(), NestedNameSpecifierLoc(), SourceLocation(), vd,1463        /*RefersToEnclosingVariableOrCapture=*/false, me->getExprLoc(),1464        me->getType(), me->getValueKind(), nullptr, nullptr, me->isNonOdrUse());1465  }1466  return nullptr;1467}1468 1469LValue CIRGenFunction::emitMemberExpr(const MemberExpr *e) {1470  if (DeclRefExpr *dre = tryToConvertMemberExprToDeclRefExpr(*this, e)) {1471    emitIgnoredExpr(e->getBase());1472    return emitDeclRefLValue(dre);1473  }1474 1475  Expr *baseExpr = e->getBase();1476  // If this is s.x, emit s as an lvalue.  If it is s->x, emit s as a scalar.1477  LValue baseLV;1478  if (e->isArrow()) {1479    LValueBaseInfo baseInfo;1480    assert(!cir::MissingFeatures::opTBAA());1481    Address addr = emitPointerWithAlignment(baseExpr, &baseInfo);1482    QualType ptrTy = baseExpr->getType()->getPointeeType();1483    assert(!cir::MissingFeatures::typeChecks());1484    baseLV = makeAddrLValue(addr, ptrTy, baseInfo);1485  } else {1486    assert(!cir::MissingFeatures::typeChecks());1487    baseLV = emitLValue(baseExpr);1488  }1489 1490  const NamedDecl *nd = e->getMemberDecl();1491  if (auto *field = dyn_cast<FieldDecl>(nd)) {1492    LValue lv = emitLValueForField(baseLV, field);1493    assert(!cir::MissingFeatures::setObjCGCLValueClass());1494    if (getLangOpts().OpenMP) {1495      // If the member was explicitly marked as nontemporal, mark it as1496      // nontemporal. If the base lvalue is marked as nontemporal, mark access1497      // to children as nontemporal too.1498      cgm.errorNYI(e->getSourceRange(), "emitMemberExpr: OpenMP");1499    }1500    return lv;1501  }1502 1503  if (isa<FunctionDecl>(nd)) {1504    cgm.errorNYI(e->getSourceRange(), "emitMemberExpr: FunctionDecl");1505    return LValue();1506  }1507 1508  llvm_unreachable("Unhandled member declaration!");1509}1510 1511/// Evaluate an expression into a given memory location.1512void CIRGenFunction::emitAnyExprToMem(const Expr *e, Address location,1513                                      Qualifiers quals, bool isInit) {1514  // FIXME: This function should take an LValue as an argument.1515  switch (getEvaluationKind(e->getType())) {1516  case cir::TEK_Complex: {1517    LValue lv = makeAddrLValue(location, e->getType());1518    emitComplexExprIntoLValue(e, lv, isInit);1519    return;1520  }1521 1522  case cir::TEK_Aggregate: {1523    emitAggExpr(e, AggValueSlot::forAddr(location, quals,1524                                         AggValueSlot::IsDestructed_t(isInit),1525                                         AggValueSlot::IsAliased_t(!isInit),1526                                         AggValueSlot::MayOverlap));1527    return;1528  }1529 1530  case cir::TEK_Scalar: {1531    RValue rv = RValue::get(emitScalarExpr(e));1532    LValue lv = makeAddrLValue(location, e->getType());1533    emitStoreThroughLValue(rv, lv);1534    return;1535  }1536  }1537 1538  llvm_unreachable("bad evaluation kind");1539}1540 1541static Address createReferenceTemporary(CIRGenFunction &cgf,1542                                        const MaterializeTemporaryExpr *m,1543                                        const Expr *inner) {1544  // TODO(cir): cgf.getTargetHooks();1545  switch (m->getStorageDuration()) {1546  case SD_FullExpression:1547  case SD_Automatic: {1548    QualType ty = inner->getType();1549 1550    assert(!cir::MissingFeatures::mergeAllConstants());1551 1552    // The temporary memory should be created in the same scope as the extending1553    // declaration of the temporary materialization expression.1554    cir::AllocaOp extDeclAlloca;1555    if (const ValueDecl *extDecl = m->getExtendingDecl()) {1556      auto extDeclAddrIter = cgf.localDeclMap.find(extDecl);1557      if (extDeclAddrIter != cgf.localDeclMap.end())1558        extDeclAlloca = extDeclAddrIter->second.getDefiningOp<cir::AllocaOp>();1559    }1560    mlir::OpBuilder::InsertPoint ip;1561    if (extDeclAlloca)1562      ip = {extDeclAlloca->getBlock(), extDeclAlloca->getIterator()};1563    return cgf.createMemTemp(ty, cgf.getLoc(m->getSourceRange()),1564                             cgf.getCounterRefTmpAsString(), /*alloca=*/nullptr,1565                             ip);1566  }1567  case SD_Thread:1568  case SD_Static: {1569    cgf.cgm.errorNYI(1570        m->getSourceRange(),1571        "createReferenceTemporary: static/thread storage duration");1572    return Address::invalid();1573  }1574 1575  case SD_Dynamic:1576    llvm_unreachable("temporary can't have dynamic storage duration");1577  }1578  llvm_unreachable("unknown storage duration");1579}1580 1581static void pushTemporaryCleanup(CIRGenFunction &cgf,1582                                 const MaterializeTemporaryExpr *m,1583                                 const Expr *e, Address referenceTemporary) {1584  // Objective-C++ ARC:1585  //   If we are binding a reference to a temporary that has ownership, we1586  //   need to perform retain/release operations on the temporary.1587  //1588  // FIXME(ogcg): This should be looking at e, not m.1589  if (m->getType().getObjCLifetime()) {1590    cgf.cgm.errorNYI(e->getSourceRange(), "pushTemporaryCleanup: ObjCLifetime");1591    return;1592  }1593 1594  const QualType::DestructionKind dk = e->getType().isDestructedType();1595  if (dk == QualType::DK_none)1596    return;1597 1598  switch (m->getStorageDuration()) {1599  case SD_Static:1600  case SD_Thread: {1601    CXXDestructorDecl *referenceTemporaryDtor = nullptr;1602    if (const auto *classDecl =1603            e->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();1604        classDecl && !classDecl->hasTrivialDestructor())1605      // Get the destructor for the reference temporary.1606      referenceTemporaryDtor = classDecl->getDestructor();1607 1608    if (!referenceTemporaryDtor)1609      return;1610 1611    cgf.cgm.errorNYI(e->getSourceRange(), "pushTemporaryCleanup: static/thread "1612                                          "storage duration with destructors");1613    break;1614  }1615 1616  case SD_FullExpression:1617    cgf.pushDestroy(NormalAndEHCleanup, referenceTemporary, e->getType(),1618                    CIRGenFunction::destroyCXXObject);1619    break;1620 1621  case SD_Automatic:1622    cgf.cgm.errorNYI(e->getSourceRange(),1623                     "pushTemporaryCleanup: automatic storage duration");1624    break;1625 1626  case SD_Dynamic:1627    llvm_unreachable("temporary cannot have dynamic storage duration");1628  }1629}1630 1631LValue CIRGenFunction::emitMaterializeTemporaryExpr(1632    const MaterializeTemporaryExpr *m) {1633  const Expr *e = m->getSubExpr();1634 1635  assert((!m->getExtendingDecl() || !isa<VarDecl>(m->getExtendingDecl()) ||1636          !cast<VarDecl>(m->getExtendingDecl())->isARCPseudoStrong()) &&1637         "Reference should never be pseudo-strong!");1638 1639  // FIXME: ideally this would use emitAnyExprToMem, however, we cannot do so1640  // as that will cause the lifetime adjustment to be lost for ARC1641  auto ownership = m->getType().getObjCLifetime();1642  if (ownership != Qualifiers::OCL_None &&1643      ownership != Qualifiers::OCL_ExplicitNone) {1644    cgm.errorNYI(e->getSourceRange(),1645                 "emitMaterializeTemporaryExpr: ObjCLifetime");1646    return {};1647  }1648 1649  SmallVector<const Expr *, 2> commaLHSs;1650  SmallVector<SubobjectAdjustment, 2> adjustments;1651  e = e->skipRValueSubobjectAdjustments(commaLHSs, adjustments);1652 1653  for (const Expr *ignored : commaLHSs)1654    emitIgnoredExpr(ignored);1655 1656  if (isa<OpaqueValueExpr>(e)) {1657    cgm.errorNYI(e->getSourceRange(),1658                 "emitMaterializeTemporaryExpr: OpaqueValueExpr");1659    return {};1660  }1661 1662  // Create and initialize the reference temporary.1663  Address object = createReferenceTemporary(*this, m, e);1664 1665  if (auto var = object.getPointer().getDefiningOp<cir::GlobalOp>()) {1666    // TODO(cir): add something akin to stripPointerCasts() to ptr above1667    cgm.errorNYI(e->getSourceRange(), "emitMaterializeTemporaryExpr: GlobalOp");1668    return {};1669  } else {1670    assert(!cir::MissingFeatures::emitLifetimeMarkers());1671    emitAnyExprToMem(e, object, Qualifiers(), /*isInitializer=*/true);1672  }1673  pushTemporaryCleanup(*this, m, e, object);1674 1675  // Perform derived-to-base casts and/or field accesses, to get from the1676  // temporary object we created (and, potentially, for which we extended1677  // the lifetime) to the subobject we're binding the reference to.1678  if (!adjustments.empty()) {1679    cgm.errorNYI(e->getSourceRange(),1680                 "emitMaterializeTemporaryExpr: Adjustments");1681    return {};1682  }1683 1684  return makeAddrLValue(object, m->getType(), AlignmentSource::Decl);1685}1686 1687LValue1688CIRGenFunction::getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e) {1689  assert(OpaqueValueMapping::shouldBindAsLValue(e));1690 1691  auto it = opaqueLValues.find(e);1692  if (it != opaqueLValues.end())1693    return it->second;1694 1695  assert(e->isUnique() && "LValue for a nonunique OVE hasn't been emitted");1696  return emitLValue(e->getSourceExpr());1697}1698 1699RValue1700CIRGenFunction::getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e) {1701  assert(!OpaqueValueMapping::shouldBindAsLValue(e));1702 1703  auto it = opaqueRValues.find(e);1704  if (it != opaqueRValues.end())1705    return it->second;1706 1707  assert(e->isUnique() && "RValue for a nonunique OVE hasn't been emitted");1708  return emitAnyExpr(e->getSourceExpr());1709}1710 1711LValue CIRGenFunction::emitCompoundLiteralLValue(const CompoundLiteralExpr *e) {1712  if (e->isFileScope()) {1713    cgm.errorNYI(e->getSourceRange(), "emitCompoundLiteralLValue: FileScope");1714    return {};1715  }1716 1717  if (e->getType()->isVariablyModifiedType()) {1718    cgm.errorNYI(e->getSourceRange(),1719                 "emitCompoundLiteralLValue: VariablyModifiedType");1720    return {};1721  }1722 1723  Address declPtr = createMemTemp(e->getType(), getLoc(e->getSourceRange()),1724                                  ".compoundliteral");1725  const Expr *initExpr = e->getInitializer();1726  LValue result = makeAddrLValue(declPtr, e->getType(), AlignmentSource::Decl);1727 1728  emitAnyExprToMem(initExpr, declPtr, e->getType().getQualifiers(),1729                   /*Init*/ true);1730 1731  // Block-scope compound literals are destroyed at the end of the enclosing1732  // scope in C.1733  if (!getLangOpts().CPlusPlus && e->getType().isDestructedType()) {1734    cgm.errorNYI(e->getSourceRange(),1735                 "emitCompoundLiteralLValue: non C++ DestructedType");1736    return {};1737  }1738 1739  return result;1740}1741 1742LValue CIRGenFunction::emitCallExprLValue(const CallExpr *e) {1743  RValue rv = emitCallExpr(e);1744 1745  if (!rv.isScalar()) {1746    cgm.errorNYI(e->getSourceRange(), "emitCallExprLValue: non-scalar return");1747    return {};1748  }1749 1750  assert(e->getCallReturnType(getContext())->isReferenceType() &&1751         "Can't have a scalar return unless the return type is a "1752         "reference type!");1753 1754  return makeNaturalAlignPointeeAddrLValue(rv.getValue(), e->getType());1755}1756 1757LValue CIRGenFunction::emitBinaryOperatorLValue(const BinaryOperator *e) {1758  // Comma expressions just emit their LHS then their RHS as an l-value.1759  if (e->getOpcode() == BO_Comma) {1760    emitIgnoredExpr(e->getLHS());1761    return emitLValue(e->getRHS());1762  }1763 1764  if (e->getOpcode() == BO_PtrMemD || e->getOpcode() == BO_PtrMemI) {1765    cgm.errorNYI(e->getSourceRange(), "member pointers");1766    return {};1767  }1768 1769  assert(e->getOpcode() == BO_Assign && "unexpected binary l-value");1770 1771  // Note that in all of these cases, __block variables need the RHS1772  // evaluated first just in case the variable gets moved by the RHS.1773 1774  switch (CIRGenFunction::getEvaluationKind(e->getType())) {1775  case cir::TEK_Scalar: {1776    assert(!cir::MissingFeatures::objCLifetime());1777    if (e->getLHS()->getType().getObjCLifetime() !=1778        clang::Qualifiers::ObjCLifetime::OCL_None) {1779      cgm.errorNYI(e->getSourceRange(), "objc lifetimes");1780      return {};1781    }1782 1783    RValue rv = emitAnyExpr(e->getRHS());1784    LValue lv = emitLValue(e->getLHS());1785 1786    SourceLocRAIIObject loc{*this, getLoc(e->getSourceRange())};1787    if (lv.isBitField())1788      emitStoreThroughBitfieldLValue(rv, lv);1789    else1790      emitStoreThroughLValue(rv, lv);1791 1792    if (getLangOpts().OpenMP) {1793      cgm.errorNYI(e->getSourceRange(), "openmp");1794      return {};1795    }1796 1797    return lv;1798  }1799 1800  case cir::TEK_Complex: {1801    return emitComplexAssignmentLValue(e);1802  }1803 1804  case cir::TEK_Aggregate:1805    cgm.errorNYI(e->getSourceRange(), "aggregate lvalues");1806    return {};1807  }1808  llvm_unreachable("bad evaluation kind");1809}1810 1811/// Emit code to compute the specified expression which1812/// can have any type.  The result is returned as an RValue struct.1813RValue CIRGenFunction::emitAnyExpr(const Expr *e, AggValueSlot aggSlot,1814                                   bool ignoreResult) {1815  switch (CIRGenFunction::getEvaluationKind(e->getType())) {1816  case cir::TEK_Scalar:1817    return RValue::get(emitScalarExpr(e, ignoreResult));1818  case cir::TEK_Complex:1819    return RValue::getComplex(emitComplexExpr(e));1820  case cir::TEK_Aggregate: {1821    if (!ignoreResult && aggSlot.isIgnored())1822      aggSlot = createAggTemp(e->getType(), getLoc(e->getSourceRange()),1823                              getCounterAggTmpAsString());1824    emitAggExpr(e, aggSlot);1825    return aggSlot.asRValue();1826  }1827  }1828  llvm_unreachable("bad evaluation kind");1829}1830 1831// Detect the unusual situation where an inline version is shadowed by a1832// non-inline version. In that case we should pick the external one1833// everywhere. That's GCC behavior too.1834static bool onlyHasInlineBuiltinDeclaration(const FunctionDecl *fd) {1835  for (const FunctionDecl *pd = fd; pd; pd = pd->getPreviousDecl())1836    if (!pd->isInlineBuiltinDeclaration())1837      return false;1838  return true;1839}1840 1841CIRGenCallee CIRGenFunction::emitDirectCallee(const GlobalDecl &gd) {1842  const auto *fd = cast<FunctionDecl>(gd.getDecl());1843 1844  if (unsigned builtinID = fd->getBuiltinID()) {1845    StringRef ident = cgm.getMangledName(gd);1846    std::string fdInlineName = (ident + ".inline").str();1847 1848    bool isPredefinedLibFunction =1849        cgm.getASTContext().BuiltinInfo.isPredefinedLibFunction(builtinID);1850    // Assume nobuiltins everywhere until we actually read the attributes.1851    bool hasAttributeNoBuiltin = true;1852    assert(!cir::MissingFeatures::attributeNoBuiltin());1853 1854    // When directing calling an inline builtin, call it through it's mangled1855    // name to make it clear it's not the actual builtin.1856    auto fn = cast<cir::FuncOp>(curFn);1857    if (fn.getName() != fdInlineName && onlyHasInlineBuiltinDeclaration(fd)) {1858      cir::FuncOp clone =1859          mlir::cast_or_null<cir::FuncOp>(cgm.getGlobalValue(fdInlineName));1860 1861      if (!clone) {1862        // Create a forward declaration - the body will be generated in1863        // generateCode when the function definition is processed1864        cir::FuncOp calleeFunc = emitFunctionDeclPointer(cgm, gd);1865        mlir::OpBuilder::InsertionGuard guard(builder);1866        builder.setInsertionPointToStart(cgm.getModule().getBody());1867 1868        clone = cir::FuncOp::create(builder, calleeFunc.getLoc(), fdInlineName,1869                                    calleeFunc.getFunctionType());1870        clone.setLinkageAttr(cir::GlobalLinkageKindAttr::get(1871            &cgm.getMLIRContext(), cir::GlobalLinkageKind::InternalLinkage));1872        clone.setSymVisibility("private");1873        clone.setInlineKindAttr(cir::InlineAttr::get(1874            &cgm.getMLIRContext(), cir::InlineKind::AlwaysInline));1875      }1876      return CIRGenCallee::forDirect(clone, gd);1877    }1878 1879    // Replaceable builtins provide their own implementation of a builtin. If we1880    // are in an inline builtin implementation, avoid trivial infinite1881    // recursion. Honor __attribute__((no_builtin("foo"))) or1882    // __attribute__((no_builtin)) on the current function unless foo is1883    // not a predefined library function which means we must generate the1884    // builtin no matter what.1885    else if (!isPredefinedLibFunction || !hasAttributeNoBuiltin)1886      return CIRGenCallee::forBuiltin(builtinID, fd);1887  }1888 1889  cir::FuncOp callee = emitFunctionDeclPointer(cgm, gd);1890 1891  assert(!cir::MissingFeatures::hip());1892 1893  return CIRGenCallee::forDirect(callee, gd);1894}1895 1896RValue CIRGenFunction::getUndefRValue(QualType ty) {1897  if (ty->isVoidType())1898    return RValue::get(nullptr);1899 1900  cgm.errorNYI("unsupported type for undef rvalue");1901  return RValue::get(nullptr);1902}1903 1904RValue CIRGenFunction::emitCall(clang::QualType calleeTy,1905                                const CIRGenCallee &origCallee,1906                                const clang::CallExpr *e,1907                                ReturnValueSlot returnValue) {1908  // Get the actual function type. The callee type will always be a pointer to1909  // function type or a block pointer type.1910  assert(calleeTy->isFunctionPointerType() &&1911         "Callee must have function pointer type!");1912 1913  calleeTy = getContext().getCanonicalType(calleeTy);1914  auto pointeeTy = cast<PointerType>(calleeTy)->getPointeeType();1915 1916  CIRGenCallee callee = origCallee;1917 1918  if (getLangOpts().CPlusPlus)1919    assert(!cir::MissingFeatures::sanitizers());1920 1921  const auto *fnType = cast<FunctionType>(pointeeTy);1922 1923  assert(!cir::MissingFeatures::sanitizers());1924 1925  CallArgList args;1926  assert(!cir::MissingFeatures::opCallArgEvaluationOrder());1927 1928  emitCallArgs(args, dyn_cast<FunctionProtoType>(fnType), e->arguments(),1929               e->getDirectCallee());1930 1931  const CIRGenFunctionInfo &funcInfo =1932      cgm.getTypes().arrangeFreeFunctionCall(args, fnType);1933 1934  // C99 6.5.2.2p6:1935  //   If the expression that denotes the called function has a type that does1936  //   not include a prototype, [the default argument promotions are performed].1937  //   If the number of arguments does not equal the number of parameters, the1938  //   behavior is undefined. If the function is defined with a type that1939  //   includes a prototype, and either the prototype ends with an ellipsis (,1940  //   ...) or the types of the arguments after promotion are not compatible1941  //   with the types of the parameters, the behavior is undefined. If the1942  //   function is defined with a type that does not include a prototype, and1943  //   the types of the arguments after promotion are not compatible with those1944  //   of the parameters after promotion, the behavior is undefined [except in1945  //   some trivial cases].1946  // That is, in the general case, we should assume that a call through an1947  // unprototyped function type works like a *non-variadic* call. The way we1948  // make this work is to cast to the exxact type fo the promoted arguments.1949  if (isa<FunctionNoProtoType>(fnType)) {1950    assert(!cir::MissingFeatures::opCallChain());1951    assert(!cir::MissingFeatures::addressSpace());1952    cir::FuncType calleeTy = getTypes().getFunctionType(funcInfo);1953    // get non-variadic function type1954    calleeTy = cir::FuncType::get(calleeTy.getInputs(),1955                                  calleeTy.getReturnType(), false);1956    auto calleePtrTy = cir::PointerType::get(calleeTy);1957 1958    mlir::Operation *fn = callee.getFunctionPointer();1959    mlir::Value addr;1960    if (auto funcOp = mlir::dyn_cast<cir::FuncOp>(fn)) {1961      addr = cir::GetGlobalOp::create(1962          builder, getLoc(e->getSourceRange()),1963          cir::PointerType::get(funcOp.getFunctionType()), funcOp.getSymName());1964    } else {1965      addr = fn->getResult(0);1966    }1967 1968    fn = builder.createBitcast(addr, calleePtrTy).getDefiningOp();1969    callee.setFunctionPointer(fn);1970  }1971 1972  assert(!cir::MissingFeatures::opCallFnInfoOpts());1973  assert(!cir::MissingFeatures::hip());1974  assert(!cir::MissingFeatures::opCallMustTail());1975 1976  cir::CIRCallOpInterface callOp;1977  RValue callResult = emitCall(funcInfo, callee, returnValue, args, &callOp,1978                               getLoc(e->getExprLoc()));1979 1980  assert(!cir::MissingFeatures::generateDebugInfo());1981 1982  return callResult;1983}1984 1985CIRGenCallee CIRGenFunction::emitCallee(const clang::Expr *e) {1986  e = e->IgnoreParens();1987 1988  // Look through function-to-pointer decay.1989  if (const auto *implicitCast = dyn_cast<ImplicitCastExpr>(e)) {1990    if (implicitCast->getCastKind() == CK_FunctionToPointerDecay ||1991        implicitCast->getCastKind() == CK_BuiltinFnToFnPtr) {1992      return emitCallee(implicitCast->getSubExpr());1993    }1994    // When performing an indirect call through a function pointer lvalue, the1995    // function pointer lvalue is implicitly converted to an rvalue through an1996    // lvalue-to-rvalue conversion.1997    assert(implicitCast->getCastKind() == CK_LValueToRValue &&1998           "unexpected implicit cast on function pointers");1999  } else if (const auto *declRef = dyn_cast<DeclRefExpr>(e)) {2000    // Resolve direct calls.2001    const auto *funcDecl = cast<FunctionDecl>(declRef->getDecl());2002    return emitDirectCallee(funcDecl);2003  } else if (auto me = dyn_cast<MemberExpr>(e)) {2004    if (const auto *fd = dyn_cast<FunctionDecl>(me->getMemberDecl())) {2005      emitIgnoredExpr(me->getBase());2006      return emitDirectCallee(fd);2007    }2008    // Else fall through to the indirect reference handling below.2009  } else if (auto *pde = dyn_cast<CXXPseudoDestructorExpr>(e)) {2010    return CIRGenCallee::forPseudoDestructor(pde);2011  }2012 2013  // Otherwise, we have an indirect reference.2014  mlir::Value calleePtr;2015  QualType functionType;2016  if (const auto *ptrType = e->getType()->getAs<clang::PointerType>()) {2017    calleePtr = emitScalarExpr(e);2018    functionType = ptrType->getPointeeType();2019  } else {2020    functionType = e->getType();2021    calleePtr = emitLValue(e).getPointer();2022  }2023  assert(functionType->isFunctionType());2024 2025  GlobalDecl gd;2026  if (const auto *vd =2027          dyn_cast_or_null<VarDecl>(e->getReferencedDeclOfCallee()))2028    gd = GlobalDecl(vd);2029 2030  CIRGenCalleeInfo calleeInfo(functionType->getAs<FunctionProtoType>(), gd);2031  CIRGenCallee callee(calleeInfo, calleePtr.getDefiningOp());2032  return callee;2033}2034 2035RValue CIRGenFunction::emitCallExpr(const clang::CallExpr *e,2036                                    ReturnValueSlot returnValue) {2037  assert(!cir::MissingFeatures::objCBlocks());2038 2039  if (const auto *ce = dyn_cast<CXXMemberCallExpr>(e))2040    return emitCXXMemberCallExpr(ce, returnValue);2041 2042  if (isa<CUDAKernelCallExpr>(e)) {2043    cgm.errorNYI(e->getSourceRange(), "call to CUDA kernel");2044    return RValue::get(nullptr);2045  }2046 2047  if (const auto *operatorCall = dyn_cast<CXXOperatorCallExpr>(e)) {2048    // If the callee decl is a CXXMethodDecl, we need to emit this as a C++2049    // operator member call.2050    if (const CXXMethodDecl *md =2051            dyn_cast_or_null<CXXMethodDecl>(operatorCall->getCalleeDecl()))2052      return emitCXXOperatorMemberCallExpr(operatorCall, md, returnValue);2053    // A CXXOperatorCallExpr is created even for explicit object methods, but2054    // these should be treated like static function calls. Fall through to do2055    // that.2056  }2057 2058  CIRGenCallee callee = emitCallee(e->getCallee());2059 2060  if (callee.isBuiltin())2061    return emitBuiltinExpr(callee.getBuiltinDecl(), callee.getBuiltinID(), e,2062                           returnValue);2063 2064  if (callee.isPseudoDestructor())2065    return emitCXXPseudoDestructorExpr(callee.getPseudoDestructorExpr());2066 2067  return emitCall(e->getCallee()->getType(), callee, e, returnValue);2068}2069 2070/// Emit code to compute the specified expression, ignoring the result.2071void CIRGenFunction::emitIgnoredExpr(const Expr *e) {2072  if (e->isPRValue()) {2073    emitAnyExpr(e, AggValueSlot::ignored(), /*ignoreResult=*/true);2074    return;2075  }2076 2077  // Just emit it as an l-value and drop the result.2078  emitLValue(e);2079}2080 2081Address CIRGenFunction::emitArrayToPointerDecay(const Expr *e,2082                                                LValueBaseInfo *baseInfo) {2083  assert(!cir::MissingFeatures::opTBAA());2084  assert(e->getType()->isArrayType() &&2085         "Array to pointer decay must have array source type!");2086 2087  // Expressions of array type can't be bitfields or vector elements.2088  LValue lv = emitLValue(e);2089  Address addr = lv.getAddress();2090 2091  // If the array type was an incomplete type, we need to make sure2092  // the decay ends up being the right type.2093  auto lvalueAddrTy = mlir::cast<cir::PointerType>(addr.getPointer().getType());2094 2095  if (e->getType()->isVariableArrayType())2096    return addr;2097 2098  [[maybe_unused]] auto pointeeTy =2099      mlir::cast<cir::ArrayType>(lvalueAddrTy.getPointee());2100 2101  [[maybe_unused]] mlir::Type arrayTy = convertType(e->getType());2102  assert(mlir::isa<cir::ArrayType>(arrayTy) && "expected array");2103  assert(pointeeTy == arrayTy);2104 2105  // The result of this decay conversion points to an array element within the2106  // base lvalue. However, since TBAA currently does not support representing2107  // accesses to elements of member arrays, we conservatively represent accesses2108  // to the pointee object as if it had no any base lvalue specified.2109  // TODO: Support TBAA for member arrays.2110  QualType eltType = e->getType()->castAsArrayTypeUnsafe()->getElementType();2111  assert(!cir::MissingFeatures::opTBAA());2112 2113  mlir::Value ptr = builder.maybeBuildArrayDecay(2114      cgm.getLoc(e->getSourceRange()), addr.getPointer(),2115      convertTypeForMem(eltType));2116  return Address(ptr, addr.getAlignment());2117}2118 2119/// Given the address of a temporary variable, produce an r-value of its type.2120RValue CIRGenFunction::convertTempToRValue(Address addr, clang::QualType type,2121                                           clang::SourceLocation loc) {2122  LValue lvalue = makeAddrLValue(addr, type, AlignmentSource::Decl);2123  switch (getEvaluationKind(type)) {2124  case cir::TEK_Complex:2125    return RValue::getComplex(emitLoadOfComplex(lvalue, loc));2126  case cir::TEK_Aggregate:2127    cgm.errorNYI(loc, "convertTempToRValue: aggregate type");2128    return RValue::get(nullptr);2129  case cir::TEK_Scalar:2130    return RValue::get(emitLoadOfScalar(lvalue, loc));2131  }2132  llvm_unreachable("bad evaluation kind");2133}2134 2135/// Emit an `if` on a boolean condition, filling `then` and `else` into2136/// appropriated regions.2137mlir::LogicalResult CIRGenFunction::emitIfOnBoolExpr(const Expr *cond,2138                                                     const Stmt *thenS,2139                                                     const Stmt *elseS) {2140  mlir::Location thenLoc = getLoc(thenS->getSourceRange());2141  std::optional<mlir::Location> elseLoc;2142  if (elseS)2143    elseLoc = getLoc(elseS->getSourceRange());2144 2145  mlir::LogicalResult resThen = mlir::success(), resElse = mlir::success();2146  emitIfOnBoolExpr(2147      cond, /*thenBuilder=*/2148      [&](mlir::OpBuilder &, mlir::Location) {2149        LexicalScope lexScope{*this, thenLoc, builder.getInsertionBlock()};2150        resThen = emitStmt(thenS, /*useCurrentScope=*/true);2151      },2152      thenLoc,2153      /*elseBuilder=*/2154      [&](mlir::OpBuilder &, mlir::Location) {2155        assert(elseLoc && "Invalid location for elseS.");2156        LexicalScope lexScope{*this, *elseLoc, builder.getInsertionBlock()};2157        resElse = emitStmt(elseS, /*useCurrentScope=*/true);2158      },2159      elseLoc);2160 2161  return mlir::LogicalResult::success(resThen.succeeded() &&2162                                      resElse.succeeded());2163}2164 2165/// Emit an `if` on a boolean condition, filling `then` and `else` into2166/// appropriated regions.2167cir::IfOp CIRGenFunction::emitIfOnBoolExpr(2168    const clang::Expr *cond, BuilderCallbackRef thenBuilder,2169    mlir::Location thenLoc, BuilderCallbackRef elseBuilder,2170    std::optional<mlir::Location> elseLoc) {2171  // Attempt to be as accurate as possible with IfOp location, generate2172  // one fused location that has either 2 or 4 total locations, depending2173  // on else's availability.2174  SmallVector<mlir::Location, 2> ifLocs{thenLoc};2175  if (elseLoc)2176    ifLocs.push_back(*elseLoc);2177  mlir::Location loc = mlir::FusedLoc::get(&getMLIRContext(), ifLocs);2178 2179  // Emit the code with the fully general case.2180  mlir::Value condV = emitOpOnBoolExpr(loc, cond);2181  return cir::IfOp::create(builder, loc, condV, elseLoc.has_value(),2182                           /*thenBuilder=*/thenBuilder,2183                           /*elseBuilder=*/elseBuilder);2184}2185 2186/// TODO(cir): see EmitBranchOnBoolExpr for extra ideas).2187mlir::Value CIRGenFunction::emitOpOnBoolExpr(mlir::Location loc,2188                                             const Expr *cond) {2189  assert(!cir::MissingFeatures::pgoUse());2190  assert(!cir::MissingFeatures::generateDebugInfo());2191  cond = cond->IgnoreParens();2192 2193  // In LLVM the condition is reversed here for efficient codegen.2194  // This should be done in CIR prior to LLVM lowering, if we do now2195  // we can make CIR based diagnostics misleading.2196  //  cir.ternary(!x, t, f) -> cir.ternary(x, f, t)2197  assert(!cir::MissingFeatures::shouldReverseUnaryCondOnBoolExpr());2198 2199  if (const ConditionalOperator *condOp = dyn_cast<ConditionalOperator>(cond)) {2200    Expr *trueExpr = condOp->getTrueExpr();2201    Expr *falseExpr = condOp->getFalseExpr();2202    mlir::Value condV = emitOpOnBoolExpr(loc, condOp->getCond());2203 2204    mlir::Value ternaryOpRes =2205        cir::TernaryOp::create(2206            builder, loc, condV, /*thenBuilder=*/2207            [this, trueExpr](mlir::OpBuilder &b, mlir::Location loc) {2208              mlir::Value lhs = emitScalarExpr(trueExpr);2209              cir::YieldOp::create(b, loc, lhs);2210            },2211            /*elseBuilder=*/2212            [this, falseExpr](mlir::OpBuilder &b, mlir::Location loc) {2213              mlir::Value rhs = emitScalarExpr(falseExpr);2214              cir::YieldOp::create(b, loc, rhs);2215            })2216            .getResult();2217 2218    return emitScalarConversion(ternaryOpRes, condOp->getType(),2219                                getContext().BoolTy, condOp->getExprLoc());2220  }2221 2222  if (isa<CXXThrowExpr>(cond)) {2223    cgm.errorNYI("NYI");2224    return createDummyValue(loc, cond->getType());2225  }2226 2227  // If the branch has a condition wrapped by __builtin_unpredictable,2228  // create metadata that specifies that the branch is unpredictable.2229  // Don't bother if not optimizing because that metadata would not be used.2230  assert(!cir::MissingFeatures::insertBuiltinUnpredictable());2231 2232  // Emit the code with the fully general case.2233  return evaluateExprAsBool(cond);2234}2235 2236mlir::Value CIRGenFunction::emitAlloca(StringRef name, mlir::Type ty,2237                                       mlir::Location loc, CharUnits alignment,2238                                       bool insertIntoFnEntryBlock,2239                                       mlir::Value arraySize) {2240  mlir::Block *entryBlock = insertIntoFnEntryBlock2241                                ? getCurFunctionEntryBlock()2242                                : curLexScope->getEntryBlock();2243 2244  // If this is an alloca in the entry basic block of a cir.try and there's2245  // a surrounding cir.scope, make sure the alloca ends up in the surrounding2246  // scope instead. This is necessary in order to guarantee all SSA values are2247  // reachable during cleanups.2248  if (auto tryOp =2249          llvm::dyn_cast_if_present<cir::TryOp>(entryBlock->getParentOp())) {2250    if (auto scopeOp = llvm::dyn_cast<cir::ScopeOp>(tryOp->getParentOp()))2251      entryBlock = &scopeOp.getScopeRegion().front();2252  }2253 2254  return emitAlloca(name, ty, loc, alignment,2255                    builder.getBestAllocaInsertPoint(entryBlock), arraySize);2256}2257 2258mlir::Value CIRGenFunction::emitAlloca(StringRef name, mlir::Type ty,2259                                       mlir::Location loc, CharUnits alignment,2260                                       mlir::OpBuilder::InsertPoint ip,2261                                       mlir::Value arraySize) {2262  // CIR uses its own alloca address space rather than follow the target data2263  // layout like original CodeGen. The data layout awareness should be done in2264  // the lowering pass instead.2265  cir::PointerType localVarPtrTy =2266      builder.getPointerTo(ty, getCIRAllocaAddressSpace());2267  mlir::IntegerAttr alignIntAttr = cgm.getSize(alignment);2268 2269  mlir::Value addr;2270  {2271    mlir::OpBuilder::InsertionGuard guard(builder);2272    builder.restoreInsertionPoint(ip);2273    addr = builder.createAlloca(loc, /*addr type*/ localVarPtrTy,2274                                /*var type*/ ty, name, alignIntAttr, arraySize);2275    assert(!cir::MissingFeatures::astVarDeclInterface());2276  }2277  return addr;2278}2279 2280// Note: this function also emit constructor calls to support a MSVC extensions2281// allowing explicit constructor function call.2282RValue CIRGenFunction::emitCXXMemberCallExpr(const CXXMemberCallExpr *ce,2283                                             ReturnValueSlot returnValue) {2284  const Expr *callee = ce->getCallee()->IgnoreParens();2285 2286  if (isa<BinaryOperator>(callee)) {2287    cgm.errorNYI(ce->getSourceRange(),2288                 "emitCXXMemberCallExpr: C++ binary operator");2289    return RValue::get(nullptr);2290  }2291 2292  const auto *me = cast<MemberExpr>(callee);2293  const auto *md = cast<CXXMethodDecl>(me->getMemberDecl());2294 2295  if (md->isStatic()) {2296    cgm.errorNYI(ce->getSourceRange(), "emitCXXMemberCallExpr: static method");2297    return RValue::get(nullptr);2298  }2299 2300  bool hasQualifier = me->hasQualifier();2301  NestedNameSpecifier qualifier = me->getQualifier();2302  bool isArrow = me->isArrow();2303  const Expr *base = me->getBase();2304 2305  return emitCXXMemberOrOperatorMemberCallExpr(2306      ce, md, returnValue, hasQualifier, qualifier, isArrow, base);2307}2308 2309RValue CIRGenFunction::emitReferenceBindingToExpr(const Expr *e) {2310  // Emit the expression as an lvalue.2311  LValue lv = emitLValue(e);2312  assert(lv.isSimple());2313  mlir::Value value = lv.getPointer();2314 2315  assert(!cir::MissingFeatures::sanitizers());2316 2317  return RValue::get(value);2318}2319 2320Address CIRGenFunction::emitLoadOfReference(LValue refLVal, mlir::Location loc,2321                                            LValueBaseInfo *pointeeBaseInfo) {2322  if (refLVal.isVolatile())2323    cgm.errorNYI(loc, "load of volatile reference");2324 2325  cir::LoadOp load =2326      cir::LoadOp::create(builder, loc, refLVal.getAddress().getElementType(),2327                          refLVal.getAddress().getPointer());2328 2329  assert(!cir::MissingFeatures::opTBAA());2330 2331  QualType pointeeType = refLVal.getType()->getPointeeType();2332  CharUnits align = cgm.getNaturalTypeAlignment(pointeeType, pointeeBaseInfo);2333  return Address(load, convertTypeForMem(pointeeType), align);2334}2335 2336LValue CIRGenFunction::emitLoadOfReferenceLValue(Address refAddr,2337                                                 mlir::Location loc,2338                                                 QualType refTy,2339                                                 AlignmentSource source) {2340  LValue refLVal = makeAddrLValue(refAddr, refTy, LValueBaseInfo(source));2341  LValueBaseInfo pointeeBaseInfo;2342  assert(!cir::MissingFeatures::opTBAA());2343  Address pointeeAddr = emitLoadOfReference(refLVal, loc, &pointeeBaseInfo);2344  return makeAddrLValue(pointeeAddr, refLVal.getType()->getPointeeType(),2345                        pointeeBaseInfo);2346}2347 2348void CIRGenFunction::emitTrap(mlir::Location loc, bool createNewBlock) {2349  cir::TrapOp::create(builder, loc);2350  if (createNewBlock)2351    builder.createBlock(builder.getBlock()->getParent());2352}2353 2354void CIRGenFunction::emitUnreachable(clang::SourceLocation loc,2355                                     bool createNewBlock) {2356  assert(!cir::MissingFeatures::sanitizers());2357  cir::UnreachableOp::create(builder, getLoc(loc));2358  if (createNewBlock)2359    builder.createBlock(builder.getBlock()->getParent());2360}2361 2362mlir::Value CIRGenFunction::createDummyValue(mlir::Location loc,2363                                             clang::QualType qt) {2364  mlir::Type t = convertType(qt);2365  CharUnits alignment = getContext().getTypeAlignInChars(qt);2366  return builder.createDummyValue(loc, t, alignment);2367}2368 2369//===----------------------------------------------------------------------===//2370// CIR builder helpers2371//===----------------------------------------------------------------------===//2372 2373Address CIRGenFunction::createMemTemp(QualType ty, mlir::Location loc,2374                                      const Twine &name, Address *alloca,2375                                      mlir::OpBuilder::InsertPoint ip) {2376  // FIXME: Should we prefer the preferred type alignment here?2377  return createMemTemp(ty, getContext().getTypeAlignInChars(ty), loc, name,2378                       alloca, ip);2379}2380 2381Address CIRGenFunction::createMemTemp(QualType ty, CharUnits align,2382                                      mlir::Location loc, const Twine &name,2383                                      Address *alloca,2384                                      mlir::OpBuilder::InsertPoint ip) {2385  Address result = createTempAlloca(convertTypeForMem(ty), align, loc, name,2386                                    /*ArraySize=*/nullptr, alloca, ip);2387  if (ty->isConstantMatrixType()) {2388    assert(!cir::MissingFeatures::matrixType());2389    cgm.errorNYI(loc, "temporary matrix value");2390  }2391  return result;2392}2393 2394/// This creates a alloca and inserts it into the entry block of the2395/// current region.2396Address CIRGenFunction::createTempAllocaWithoutCast(2397    mlir::Type ty, CharUnits align, mlir::Location loc, const Twine &name,2398    mlir::Value arraySize, mlir::OpBuilder::InsertPoint ip) {2399  cir::AllocaOp alloca = ip.isSet()2400                             ? createTempAlloca(ty, loc, name, ip, arraySize)2401                             : createTempAlloca(ty, loc, name, arraySize);2402  alloca.setAlignmentAttr(cgm.getSize(align));2403  return Address(alloca, ty, align);2404}2405 2406/// This creates a alloca and inserts it into the entry block. The alloca is2407/// casted to default address space if necessary.2408// TODO(cir): Implement address space casting to match classic codegen's2409// CreateTempAlloca behavior with DestLangAS parameter2410Address CIRGenFunction::createTempAlloca(mlir::Type ty, CharUnits align,2411                                         mlir::Location loc, const Twine &name,2412                                         mlir::Value arraySize,2413                                         Address *allocaAddr,2414                                         mlir::OpBuilder::InsertPoint ip) {2415  Address alloca =2416      createTempAllocaWithoutCast(ty, align, loc, name, arraySize, ip);2417  if (allocaAddr)2418    *allocaAddr = alloca;2419  mlir::Value v = alloca.getPointer();2420  // Alloca always returns a pointer in alloca address space, which may2421  // be different from the type defined by the language. For example,2422  // in C++ the auto variables are in the default address space. Therefore2423  // cast alloca to the default address space when necessary.2424 2425  LangAS allocaAS = alloca.getAddressSpace()2426                        ? clang::getLangASFromTargetAS(2427                              alloca.getAddressSpace().getValue().getUInt())2428                        : clang::LangAS::Default;2429  LangAS dstTyAS = clang::LangAS::Default;2430  if (getCIRAllocaAddressSpace()) {2431    dstTyAS = clang::getLangASFromTargetAS(2432        getCIRAllocaAddressSpace().getValue().getUInt());2433  }2434 2435  if (dstTyAS != allocaAS) {2436    getTargetHooks().performAddrSpaceCast(*this, v, getCIRAllocaAddressSpace(),2437                                          builder.getPointerTo(ty, dstTyAS));2438  }2439  return Address(v, ty, align);2440}2441 2442/// This creates an alloca and inserts it into the entry block if \p ArraySize2443/// is nullptr, otherwise inserts it at the current insertion point of the2444/// builder.2445cir::AllocaOp CIRGenFunction::createTempAlloca(mlir::Type ty,2446                                               mlir::Location loc,2447                                               const Twine &name,2448                                               mlir::Value arraySize,2449                                               bool insertIntoFnEntryBlock) {2450  return mlir::cast<cir::AllocaOp>(emitAlloca(name.str(), ty, loc, CharUnits(),2451                                              insertIntoFnEntryBlock, arraySize)2452                                       .getDefiningOp());2453}2454 2455/// This creates an alloca and inserts it into the provided insertion point2456cir::AllocaOp CIRGenFunction::createTempAlloca(mlir::Type ty,2457                                               mlir::Location loc,2458                                               const Twine &name,2459                                               mlir::OpBuilder::InsertPoint ip,2460                                               mlir::Value arraySize) {2461  assert(ip.isSet() && "Insertion point is not set");2462  return mlir::cast<cir::AllocaOp>(2463      emitAlloca(name.str(), ty, loc, CharUnits(), ip, arraySize)2464          .getDefiningOp());2465}2466 2467/// Try to emit a reference to the given value without producing it as2468/// an l-value.  For many cases, this is just an optimization, but it avoids2469/// us needing to emit global copies of variables if they're named without2470/// triggering a formal use in a context where we can't emit a direct2471/// reference to them, for instance if a block or lambda or a member of a2472/// local class uses a const int variable or constexpr variable from an2473/// enclosing function.2474///2475/// For named members of enums, this is the only way they are emitted.2476CIRGenFunction::ConstantEmission2477CIRGenFunction::tryEmitAsConstant(const DeclRefExpr *refExpr) {2478  const ValueDecl *value = refExpr->getDecl();2479 2480  // There is a lot more to do here, but for now only EnumConstantDecl is2481  // supported.2482  assert(!cir::MissingFeatures::tryEmitAsConstant());2483 2484  // The value needs to be an enum constant or a constant variable.2485  if (!isa<EnumConstantDecl>(value))2486    return ConstantEmission();2487 2488  Expr::EvalResult result;2489  if (!refExpr->EvaluateAsRValue(result, getContext()))2490    return ConstantEmission();2491 2492  QualType resultType = refExpr->getType();2493 2494  // As long as we're only handling EnumConstantDecl, there should be no2495  // side-effects.2496  assert(!result.HasSideEffects);2497 2498  // Emit as a constant.2499  // FIXME(cir): have emitAbstract build a TypedAttr instead (this requires2500  // somewhat heavy refactoring...)2501  mlir::Attribute c = ConstantEmitter(*this).emitAbstract(2502      refExpr->getLocation(), result.Val, resultType);2503  mlir::TypedAttr cstToEmit = mlir::dyn_cast_if_present<mlir::TypedAttr>(c);2504  assert(cstToEmit && "expected a typed attribute");2505 2506  assert(!cir::MissingFeatures::generateDebugInfo());2507 2508  return ConstantEmission::forValue(cstToEmit);2509}2510 2511CIRGenFunction::ConstantEmission2512CIRGenFunction::tryEmitAsConstant(const MemberExpr *me) {2513  if (DeclRefExpr *dre = tryToConvertMemberExprToDeclRefExpr(*this, me))2514    return tryEmitAsConstant(dre);2515  return ConstantEmission();2516}2517 2518mlir::Value CIRGenFunction::emitScalarConstant(2519    const CIRGenFunction::ConstantEmission &constant, Expr *e) {2520  assert(constant && "not a constant");2521  if (constant.isReference()) {2522    cgm.errorNYI(e->getSourceRange(), "emitScalarConstant: reference");2523    return {};2524  }2525  return builder.getConstant(getLoc(e->getSourceRange()), constant.getValue());2526}2527 2528LValue CIRGenFunction::emitPredefinedLValue(const PredefinedExpr *e) {2529  const StringLiteral *sl = e->getFunctionName();2530  assert(sl != nullptr && "No StringLiteral name in PredefinedExpr");2531  auto fn = cast<cir::FuncOp>(curFn);2532  StringRef fnName = fn.getName();2533  fnName.consume_front("\01");2534  std::array<StringRef, 2> nameItems = {2535      PredefinedExpr::getIdentKindName(e->getIdentKind()), fnName};2536  std::string gvName = llvm::join(nameItems, ".");2537  if (isa_and_nonnull<BlockDecl>(curCodeDecl))2538    cgm.errorNYI(e->getSourceRange(), "predefined lvalue in block");2539 2540  return emitStringLiteralLValue(sl, gvName);2541}2542 2543LValue CIRGenFunction::emitOpaqueValueLValue(const OpaqueValueExpr *e) {2544  assert(OpaqueValueMappingData::shouldBindAsLValue(e));2545  return getOrCreateOpaqueLValueMapping(e);2546}2547 2548namespace {2549// Handle the case where the condition is a constant evaluatable simple integer,2550// which means we don't have to separately handle the true/false blocks.2551std::optional<LValue> handleConditionalOperatorLValueSimpleCase(2552    CIRGenFunction &cgf, const AbstractConditionalOperator *e) {2553  const Expr *condExpr = e->getCond();2554  llvm::APSInt condExprVal;2555  if (!cgf.constantFoldsToSimpleInteger(condExpr, condExprVal))2556    return std::nullopt;2557 2558  const Expr *live = e->getTrueExpr(), *dead = e->getFalseExpr();2559  if (!condExprVal.getBoolValue())2560    std::swap(live, dead);2561 2562  if (cgf.containsLabel(dead))2563    return std::nullopt;2564 2565  // If the true case is live, we need to track its region.2566  assert(!cir::MissingFeatures::incrementProfileCounter());2567  assert(!cir::MissingFeatures::pgoUse());2568  // If a throw expression we emit it and return an undefined lvalue2569  // because it can't be used.2570  if (auto *throwExpr = dyn_cast<CXXThrowExpr>(live->IgnoreParens())) {2571    cgf.emitCXXThrowExpr(throwExpr);2572    // Return an undefined lvalue - the throw terminates execution2573    // so this value will never actually be used2574    mlir::Type elemTy = cgf.convertType(dead->getType());2575    mlir::Value undefPtr =2576        cgf.getBuilder().getNullPtr(cgf.getBuilder().getPointerTo(elemTy),2577                                    cgf.getLoc(throwExpr->getSourceRange()));2578    return cgf.makeAddrLValue(Address(undefPtr, elemTy, CharUnits::One()),2579                              dead->getType());2580  }2581  return cgf.emitLValue(live);2582}2583 2584/// Emit the operand of a glvalue conditional operator. This is either a glvalue2585/// or a (possibly-parenthesized) throw-expression. If this is a throw, no2586/// LValue is returned and the current block has been terminated.2587static std::optional<LValue> emitLValueOrThrowExpression(CIRGenFunction &cgf,2588                                                         const Expr *operand) {2589  if (auto *throwExpr = dyn_cast<CXXThrowExpr>(operand->IgnoreParens())) {2590    cgf.emitCXXThrowExpr(throwExpr);2591    return std::nullopt;2592  }2593 2594  return cgf.emitLValue(operand);2595}2596} // namespace2597 2598// Create and generate the 3 blocks for a conditional operator.2599// Leaves the 'current block' in the continuation basic block.2600template <typename FuncTy>2601CIRGenFunction::ConditionalInfo2602CIRGenFunction::emitConditionalBlocks(const AbstractConditionalOperator *e,2603                                      const FuncTy &branchGenFunc) {2604  ConditionalInfo info;2605  ConditionalEvaluation eval(*this);2606  mlir::Location loc = getLoc(e->getSourceRange());2607  CIRGenBuilderTy &builder = getBuilder();2608 2609  mlir::Value condV = emitOpOnBoolExpr(loc, e->getCond());2610  SmallVector<mlir::OpBuilder::InsertPoint, 2> insertPoints{};2611  mlir::Type yieldTy{};2612 2613  auto emitBranch = [&](mlir::OpBuilder &b, mlir::Location loc,2614                        const Expr *expr, std::optional<LValue> &resultLV) {2615    CIRGenFunction::LexicalScope lexScope{*this, loc, b.getInsertionBlock()};2616    curLexScope->setAsTernary();2617 2618    assert(!cir::MissingFeatures::incrementProfileCounter());2619    eval.beginEvaluation();2620    resultLV = branchGenFunc(*this, expr);2621    mlir::Value resultPtr = resultLV ? resultLV->getPointer() : mlir::Value();2622    eval.endEvaluation();2623 2624    if (resultPtr) {2625      yieldTy = resultPtr.getType();2626      cir::YieldOp::create(b, loc, resultPtr);2627    } else {2628      // If LHS or RHS is a void expression we need2629      // to patch arms as to properly match yield types.2630      // If the current block's terminator is an UnreachableOp (from a throw),2631      // we don't need a yield2632      if (builder.getInsertionBlock()->mightHaveTerminator()) {2633        mlir::Operation *terminator =2634            builder.getInsertionBlock()->getTerminator();2635        if (isa_and_nonnull<cir::UnreachableOp>(terminator))2636          insertPoints.push_back(b.saveInsertionPoint());2637      }2638    }2639  };2640 2641  info.result = cir::TernaryOp::create(2642                    builder, loc, condV,2643                    /*trueBuilder=*/2644                    [&](mlir::OpBuilder &b, mlir::Location loc) {2645                      emitBranch(b, loc, e->getTrueExpr(), info.lhs);2646                    },2647                    /*falseBuilder=*/2648                    [&](mlir::OpBuilder &b, mlir::Location loc) {2649                      emitBranch(b, loc, e->getFalseExpr(), info.rhs);2650                    })2651                    .getResult();2652 2653  // If both arms are void, so be it.2654  if (!yieldTy)2655    yieldTy = voidTy;2656 2657  // Insert required yields.2658  for (mlir::OpBuilder::InsertPoint &toInsert : insertPoints) {2659    mlir::OpBuilder::InsertionGuard guard(builder);2660    builder.restoreInsertionPoint(toInsert);2661 2662    // Block does not return: build empty yield.2663    if (!yieldTy) {2664      cir::YieldOp::create(builder, loc);2665    } else { // Block returns: set null yield value.2666      mlir::Value op0 = builder.getNullValue(yieldTy, loc);2667      cir::YieldOp::create(builder, loc, op0);2668    }2669  }2670 2671  return info;2672}2673 2674LValue CIRGenFunction::emitConditionalOperatorLValue(2675    const AbstractConditionalOperator *expr) {2676  if (!expr->isGLValue()) {2677    // ?: here should be an aggregate.2678    assert(hasAggregateEvaluationKind(expr->getType()) &&2679           "Unexpected conditional operator!");2680    return emitAggExprToLValue(expr);2681  }2682 2683  OpaqueValueMapping binding(*this, expr);2684  if (std::optional<LValue> res =2685          handleConditionalOperatorLValueSimpleCase(*this, expr))2686    return *res;2687 2688  ConditionalInfo info =2689      emitConditionalBlocks(expr, [](CIRGenFunction &cgf, const Expr *e) {2690        return emitLValueOrThrowExpression(cgf, e);2691      });2692 2693  if ((info.lhs && !info.lhs->isSimple()) ||2694      (info.rhs && !info.rhs->isSimple())) {2695    cgm.errorNYI(expr->getSourceRange(),2696                 "unsupported conditional operator with non-simple lvalue");2697    return LValue();2698  }2699 2700  if (info.lhs && info.rhs) {2701    Address lhsAddr = info.lhs->getAddress();2702    Address rhsAddr = info.rhs->getAddress();2703    Address result(info.result, lhsAddr.getElementType(),2704                   std::min(lhsAddr.getAlignment(), rhsAddr.getAlignment()));2705    AlignmentSource alignSource =2706        std::max(info.lhs->getBaseInfo().getAlignmentSource(),2707                 info.rhs->getBaseInfo().getAlignmentSource());2708    assert(!cir::MissingFeatures::opTBAA());2709    return makeAddrLValue(result, expr->getType(), LValueBaseInfo(alignSource));2710  }2711 2712  assert((info.lhs || info.rhs) &&2713         "both operands of glvalue conditional are throw-expressions?");2714  return info.lhs ? *info.lhs : *info.rhs;2715}2716 2717/// An LValue is a candidate for having its loads and stores be made atomic if2718/// we are operating under /volatile:ms *and* the LValue itself is volatile and2719/// performing such an operation can be performed without a libcall.2720bool CIRGenFunction::isLValueSuitableForInlineAtomic(LValue lv) {2721  if (!cgm.getLangOpts().MSVolatile)2722    return false;2723 2724  cgm.errorNYI("LValueSuitableForInlineAtomic LangOpts MSVolatile");2725  return false;2726}2727