18#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
19#include "mlir/IR/BuiltinAttributes.h"
20#include "mlir/IR/Value.h"
42 llvm::StringRef fieldName,
43 unsigned fieldIndex) {
46 "emitAddrOfFieldStorage: zero-sized field");
53 auto fieldPtr = cir::PointerType::get(fieldType);
57 cir::GetMemberOp memberAddr = builder.createGetMember(
58 loc, fieldPtr, base.
getPointer(), fieldName, fieldIndex);
66 layout.
getCIRType().getElementOffset(
cgm.getDataLayout().layout, idx));
75 assert(
expr->getType()->isPointerType() ||
76 expr->getType()->isObjCObjectPointerType());
80 if (
auto const *ce = dyn_cast<CastExpr>(
expr)) {
81 if (
const auto *ece = dyn_cast<ExplicitCastExpr>(ce))
82 cgm.emitExplicitCastExprType(ece);
84 switch (ce->getCastKind()) {
88 case CK_AddressSpaceConversion: {
89 if (
const auto *ptrTy =
90 ce->getSubExpr()->getType()->getAs<
PointerType>()) {
91 if (ptrTy->getPointeeType()->isVoidType())
99 *baseInfo = innerBaseInfo;
104 const QualType pointeeType =
expr->getType()->getPointeeType();
106 cgm.getNaturalTypeAlignment(pointeeType, &targetTypeBaseInfo);
119 const mlir::Type eltTy =
131 case CK_ArrayToPointerDecay:
134 case CK_UncheckedDerivedToBase:
135 case CK_DerivedToBase: {
140 ce->getSubExpr()->getType()->getPointeeCXXRecordDecl();
146 case CK_AnyPointerToBlockPointerCast:
147 case CK_BaseToDerived:
148 case CK_BaseToDerivedMemberPointer:
149 case CK_BlockPointerToObjCPointerCast:
150 case CK_BuiltinFnToFnPtr:
151 case CK_CPointerToObjCPointerCast:
152 case CK_DerivedToBaseMemberPointer:
154 case CK_FunctionToPointerDecay:
155 case CK_IntegralToPointer:
156 case CK_LValueToRValue:
157 case CK_LValueToRValueBitCast:
158 case CK_NullToMemberPointer:
159 case CK_NullToPointer:
160 case CK_ReinterpretMemberPointer:
166 case CK_ARCConsumeObject:
167 case CK_ARCExtendBlockObject:
168 case CK_ARCProduceObject:
169 case CK_ARCReclaimReturnedObject:
170 case CK_AtomicToNonAtomic:
171 case CK_BooleanToSignedIntegral:
172 case CK_ConstructorConversion:
173 case CK_CopyAndAutoreleaseBlockObject:
175 case CK_FixedPointCast:
176 case CK_FixedPointToBoolean:
177 case CK_FixedPointToFloating:
178 case CK_FixedPointToIntegral:
179 case CK_FloatingCast:
180 case CK_FloatingComplexCast:
181 case CK_FloatingComplexToBoolean:
182 case CK_FloatingComplexToIntegralComplex:
183 case CK_FloatingComplexToReal:
184 case CK_FloatingRealToComplex:
185 case CK_FloatingToBoolean:
186 case CK_FloatingToFixedPoint:
187 case CK_FloatingToIntegral:
188 case CK_HLSLAggregateSplatCast:
189 case CK_HLSLArrayRValue:
190 case CK_HLSLElementwiseCast:
191 case CK_HLSLVectorTruncation:
192 case CK_HLSLMatrixTruncation:
193 case CK_IntToOCLSampler:
194 case CK_IntegralCast:
195 case CK_IntegralComplexCast:
196 case CK_IntegralComplexToBoolean:
197 case CK_IntegralComplexToFloatingComplex:
198 case CK_IntegralComplexToReal:
199 case CK_IntegralRealToComplex:
200 case CK_IntegralToBoolean:
201 case CK_IntegralToFixedPoint:
202 case CK_IntegralToFloating:
203 case CK_LValueBitCast:
205 case CK_MemberPointerToBoolean:
206 case CK_NonAtomicToAtomic:
207 case CK_ObjCObjectLValueCast:
208 case CK_PointerToBoolean:
209 case CK_PointerToIntegral:
212 case CK_UserDefinedConversion:
214 case CK_ZeroToOCLOpaqueType:
215 llvm_unreachable(
"unexpected cast for emitPointerWithAlignment");
222 if (uo->getOpcode() == UO_AddrOf) {
232 if (
auto const *call = dyn_cast<CallExpr>(
expr)) {
233 switch (call->getBuiltinCallee()) {
236 case Builtin::BIaddressof:
237 case Builtin::BI__addressof:
238 case Builtin::BI__builtin_addressof: {
239 cgm.errorNYI(
expr->getSourceRange(),
240 "emitPointerWithAlignment: builtin addressof");
254 if (!dst.isSimple()) {
255 if (dst.isVectorElt()) {
257 const mlir::Location loc = dst.getVectorPointer().getLoc();
258 const mlir::Value vector =
259 builder.createLoad(loc, dst.getVectorAddress());
260 const mlir::Value newVector = cir::VecInsertOp::create(
261 builder, loc, vector, src.
getValue(), dst.getVectorIdx());
262 builder.createStore(loc, newVector, dst.getVectorAddress());
266 assert(dst.isBitField() &&
"Unknown LValue type");
270 cgm.errorNYI(dst.getPointer().getLoc(),
271 "emitStoreThroughLValue: non-simple lvalue");
277 assert(src.
isScalar() &&
"Can't emit an aggregate store with this method");
288 "emitGlobalVarDeclLValue: thread_local variable");
302 if (realPtrTy != v.getType())
306 Address addr(v, realVarTy, alignment);
320 bool isNontemporal) {
324 if (clangVecTy->isExtVectorBoolType())
326 "emitStoreOfScalar ExtVectorBoolType");
334 if (vecTy.getSize() == 3 && !
getLangOpts().PreserveVec3Type)
336 "emitStoreOfScalar Vec3 & PreserveVec3Type disabled");
350 assert(addr.
getPointer() &&
"expected pointer to exist");
352 if (currVarDecl && srcAlloca) {
353 const VarDecl *vd = currVarDecl;
354 assert(vd &&
"VarDecl expected");
359 assert(
currSrcLoc &&
"must pass in source location");
360 builder.createStore(*
currSrcLoc, value, addr, isVolatile);
363 cgm.errorNYI(addr.
getPointer().getLoc(),
"emitStoreOfScalar nontemporal");
373 return targetInfo.
getABI().starts_with(
"aapcs");
381 Address ptr = dst.getBitFieldAddress();
383 bool useVoaltile =
cgm.getCodeGenOpts().AAPCSBitfieldWidth &&
384 dst.isVolatileQualified() &&
387 assert(
currSrcLoc &&
"must pass in source location");
389 return builder.createSetBitfield(*
currSrcLoc, resLTy, ptr,
391 dst.isVolatileQualified(), useVoaltile);
413 mlir::Type fieldType,
416 cir::PointerType fieldPtr = cir::PointerType::get(fieldType);
422 rec.getElementOffset(
cgm.getDataLayout().layout,
index));
430 cgm.getTypes().getCIRGenRecordLayout(field->
getParent());
440 addr = builder.createElementBitCast(loc, addr, info.
storageType);
463 if (
auto *classDecl = dyn_cast<CXXRecordDecl>(rec)) {
464 if (
cgm.getCodeGenOpts().StrictVTablePointers &&
465 classDecl->isDynamicClass()) {
467 "emitLValueForField: strict vtable for dynamic class");
473 llvm::StringRef fieldName = field->
getName();
475 if (
cgm.lambdaFieldToName.count(field))
476 fieldName =
cgm.lambdaFieldToName[field];
482 cgm.getTypes().getCIRGenRecordLayout(field->
getParent());
503 if (field->
hasAttr<AnnotateAttr>()) {
514 "emitLValueForField: __weak attribute");
529 cgm.getTypes().getCIRGenRecordLayout(field->
getParent());
553 ty = atomicTy->getValueType();
556 cgm.errorNYI(
"emitToMemory: extVectorBoolType");
567 ty = atomicTy->getValueType();
570 cgm.errorNYI(
"emitFromMemory: PackedVectorBoolType");
579 assert(0 &&
"NYI: emitStoreOfScalar constant matrix type");
596 if (clangVecTy->isExtVectorBoolType()) {
597 cgm.errorNYI(loc,
"emitLoadOfScalar: ExtVectorBoolType");
605 if (vecTy.getSize() == 3 && !
getLangOpts().PreserveVec3Type)
607 "emitLoadOfScalar Vec3 & PreserveVec3Type disabled");
613 cgm.errorNYI(
"emitLoadOfScalar: load atomic");
615 if (mlir::isa<cir::VoidType>(eltTy))
616 cgm.errorNYI(loc,
"emitLoadOfScalar: void type");
620 mlir::Value loadOp = builder.createLoad(
getLoc(loc), addr, isVolatile);
622 cgm.errorNYI(
"emitLoadOfScalar: boolean type with boolean representation");
649 const mlir::Value load =
658 cgm.errorNYI(loc,
"emitLoadOfLValue");
663 const mlir::ArrayAttr elts) {
664 auto elt = mlir::cast<mlir::IntegerAttr>(elts[idx]);
676 if (
getLangOpts().
HLSL && !mlir::isa<cir::VectorType>(vec.getType())) {
677 cgm.errorNYI(loc,
"emitLoadOfExtVectorElementLValue: HLSL");
688 cir::ConstantOp
index =
689 builder.getConstInt(loc, builder.getSInt64Ty(), indexValue);
695 for (
auto i : llvm::seq<unsigned>(0, exprVecTy->getNumElements()))
698 cir::VecShuffleOp resultVec = builder.createVecShuffle(loc, vec, mask);
700 cgm.errorNYI(loc,
"emitLoadOfExtVectorElementLValue: ExtVectorBoolType");
710 "unexpected binary operator opcode");
725 memberPtrTy, &baseInfo);
727 return makeAddrLValue(memberAddr, memberPtrTy->getPointeeType(), baseInfo);
732 mlir::Location loc) {
735 mlir::Type vectorElementTy =
cgm.getTypes().convertType(elementTy);
741 mlir::Value idxValue =
742 builder.getConstInt(loc, mlir::cast<cir::IntType>(
ptrDiffTy), idx);
744 mlir::Value elementValue = builder.getArrayElement(
745 loc, loc, castToPointerElement.
getPointer(), vectorElementTy, idxValue,
751 return Address(elementValue, vectorElementTy, alignment);
760 mlir::Value thisValue) {
768 mlir::Value thisValue) {
769 bool hasExplicitObjectParameter =
false;
770 const auto *methD = dyn_cast_if_present<CXXMethodDecl>(
curCodeDecl);
773 hasExplicitObjectParameter = methD->isExplicitObjectMemberFunction();
774 assert(methD->getParent()->isLambda());
775 assert(methD->getParent() == field->
getParent());
777 if (hasExplicitObjectParameter) {
800 mlir::Type fnTy = funcOp.getFunctionType();
801 mlir::Type ptrTy = cir::PointerType::get(fnTy);
802 mlir::Value addr = cir::GetGlobalOp::create(cgf.
getBuilder(), loc, ptrTy,
803 funcOp.getSymName());
807 ptrTy = cir::PointerType::get(fnTy);
809 addr = cir::CastOp::create(cgf.
getBuilder(), addr.getLoc(), ptrTy,
810 cir::CastKind::bitcast, addr);
857 case cir::GlobalLinkageKind::ExternalLinkage:
858 case cir::GlobalLinkageKind::LinkOnceODRLinkage:
859 case cir::GlobalLinkageKind::WeakODRLinkage:
860 case cir::GlobalLinkageKind::InternalLinkage:
861 case cir::GlobalLinkageKind::PrivateLinkage:
873 "should not emit an unevaluated operand");
875 if (
const auto *vd = dyn_cast<VarDecl>(nd)) {
877 if (vd->getStorageClass() ==
SC_Register && vd->hasAttr<AsmLabelAttr>() &&
878 !vd->isLocalVarDecl()) {
880 "emitDeclRefLValue: Global Named registers access");
885 (vd->getType()->isReferenceType() ||
887 vd->getAnyInitializer(vd);
889 e->
getLocation(), *vd->evaluateValue(), vd->getType());
890 assert(val &&
"failed to emit constant expression");
893 if (!vd->getType()->isReferenceType()) {
895 addr =
cgm.createUnnamedGlobalFrom(*vd, val,
898 auto ptrTy = mlir::cast<cir::PointerType>(addr.
getPointer().getType());
899 if (ptrTy.getPointee() != varTy) {
904 "emitDeclRefLValue: non-odr reference type");
911 vd = vd->getCanonicalDecl();
919 if (
const auto *vd = dyn_cast<VarDecl>(nd)) {
929 if (vd->hasLinkage() || vd->isStaticDataMember())
953 assert((vd->isStaticLocal() ||
symbolTable.count(vd)) &&
954 "non-static locals should be already mapped");
959 if (
const auto *bd = dyn_cast<BindingDecl>(nd)) {
968 if (
const auto *fd = dyn_cast<FunctionDecl>(nd)) {
972 if (
getContext().getTargetInfo().allowDebugInfoForExternalRef())
989 "evaluateExprAsBool: member pointer type");
1005 if (op == UO_Extension)
1011 assert(!t.
isNull() &&
"CodeGenFunction::EmitUnaryOpLValue: Illegal type");
1031 assert(lv.
isSimple() &&
"real/imag on non-ordinary l-value");
1046 ? builder.createComplexRealPtr(loc, lv.
getAddress())
1047 : builder.createComplexImagPtr(loc, lv.
getAddress());
1055 cir::UnaryOpKind
kind =
1056 e->
isIncrementOp() ? cir::UnaryOpKind::Inc : cir::UnaryOpKind::Dec;
1059 assert(e->
isPrefix() &&
"Prefix operator in unexpected state!");
1070 llvm_unreachable(
"UnaryOperator extension should be handled above!");
1079 llvm_unreachable(
"UnaryOperator of non-lvalue kind!");
1081 llvm_unreachable(
"Unknown unary operator kind!");
1089 const auto *
castExpr = dyn_cast<CastExpr>(e);
1103 if (
auto constantOp = idx.getDefiningOp<cir::ConstantOp>())
1104 return constantOp.getValueAttr<cir::IntAttr>();
1113 const CharUnits offset = constantIdx.getValue().getZExtValue() * eltSize;
1130 mlir::Location beginLoc,
1131 mlir::Location endLoc, mlir::Value ptr,
1132 mlir::Type eltTy, mlir::Value idx,
1143 mlir::Location beginLoc,
1144 mlir::Location endLoc,
Address addr,
1146 mlir::Location loc,
bool shouldDecay) {
1161 const mlir::Value eltPtr =
1165 return Address(eltPtr, elementType, eltAlign);
1178 "index was neither LHS nor RHS");
1180 auto emitIdxAfterBase = [&](
bool promote) -> mlir::Value {
1184 auto ptrTy = mlir::dyn_cast<cir::PointerType>(idx.getType());
1185 if (promote && ptrTy && ptrTy.isPtrTo<cir::IntType>())
1187 "emitArraySubscriptExpr: index type cast");
1195 const mlir::Value idx = emitIdxAfterBase(
false);
1208 mlir::Value idx = emitIdxAfterBase(
true);
1233 idx = builder.createIntCast(idx, numElements.getType());
1242 idx = builder.createMul(
cgm.getLoc(e->
getExprLoc()), idx, numElements,
1255 if (
const auto *ase = dyn_cast<ArraySubscriptExpr>(array))
1262 *
this,
cgm.getLoc(array->getBeginLoc()),
cgm.getLoc(array->getEndLoc()),
1277 "The base must be a pointer");
1306 const auto *clangPtrTy =
1308 base =
makeAddrLValue(ptr, clangPtrTy->getPointeeType(), baseInfo);
1309 base.getQuals().removeObjCGCAttr();
1318 "Result must be a vector");
1326 "emitExtVectorElementExpr: ExtVectorBoolType & !HLSL");
1329 builder.createStore(vec.getLoc(), vec, vecMem);
1342 mlir::ArrayAttr elts = builder.getI64ArrayAttr(attrElts);
1348 "emitExtVectorElementExpr: isSimple is false");
1353 llvm::StringRef name) {
1354 cir::GlobalOp globalOp =
cgm.getGlobalForStringLiteral(e, name);
1355 assert(globalOp.getAlignment() &&
"expected alignment for string literal");
1356 unsigned align = *(globalOp.getAlignment());
1374 case CK_LValueToRValueBitCast:
1375 case CK_ArrayToPointerDecay:
1376 case CK_FunctionToPointerDecay:
1377 case CK_NullToMemberPointer:
1378 case CK_NullToPointer:
1379 case CK_IntegralToPointer:
1380 case CK_PointerToIntegral:
1381 case CK_PointerToBoolean:
1382 case CK_IntegralCast:
1383 case CK_BooleanToSignedIntegral:
1384 case CK_IntegralToBoolean:
1385 case CK_IntegralToFloating:
1386 case CK_FloatingToIntegral:
1387 case CK_FloatingToBoolean:
1388 case CK_FloatingCast:
1389 case CK_FloatingRealToComplex:
1390 case CK_FloatingComplexToReal:
1391 case CK_FloatingComplexToBoolean:
1392 case CK_FloatingComplexCast:
1393 case CK_FloatingComplexToIntegralComplex:
1394 case CK_IntegralRealToComplex:
1395 case CK_IntegralComplexToReal:
1396 case CK_IntegralComplexToBoolean:
1397 case CK_IntegralComplexCast:
1398 case CK_IntegralComplexToFloatingComplex:
1399 case CK_DerivedToBaseMemberPointer:
1400 case CK_BaseToDerivedMemberPointer:
1401 case CK_MemberPointerToBoolean:
1402 case CK_ReinterpretMemberPointer:
1403 case CK_AnyPointerToBlockPointerCast:
1404 case CK_ARCProduceObject:
1405 case CK_ARCConsumeObject:
1406 case CK_ARCReclaimReturnedObject:
1407 case CK_ARCExtendBlockObject:
1408 case CK_CopyAndAutoreleaseBlockObject:
1409 case CK_IntToOCLSampler:
1410 case CK_FloatingToFixedPoint:
1411 case CK_FixedPointToFloating:
1412 case CK_FixedPointCast:
1413 case CK_FixedPointToBoolean:
1414 case CK_FixedPointToIntegral:
1415 case CK_IntegralToFixedPoint:
1417 case CK_HLSLVectorTruncation:
1418 case CK_HLSLMatrixTruncation:
1419 case CK_HLSLArrayRValue:
1420 case CK_HLSLElementwiseCast:
1421 case CK_HLSLAggregateSplatCast:
1422 llvm_unreachable(
"unexpected cast lvalue");
1425 llvm_unreachable(
"dependent cast kind in IR gen!");
1427 case CK_BuiltinFnToFnPtr:
1428 llvm_unreachable(
"builtin functions are handled elsewhere");
1438 case CK_NonAtomicToAtomic:
1439 case CK_AtomicToNonAtomic:
1441 case CK_ObjCObjectLValueCast:
1442 case CK_VectorSplat:
1443 case CK_ConstructorConversion:
1444 case CK_UserDefinedConversion:
1445 case CK_CPointerToObjCPointerCast:
1446 case CK_BlockPointerToObjCPointerCast:
1447 case CK_LValueToRValue: {
1449 std::string(
"emitCastLValue for unhandled cast kind: ") +
1454 case CK_AddressSpaceConversion: {
1459 mlir::ptr::MemorySpaceAttrInterface srcAS;
1465 "emitCastLValue: address space conversion from unknown address "
1475 case CK_LValueBitCast: {
1479 cgm.emitExplicitCastExprType(ce,
this);
1500 "emitCastLValue: NoOp needs bitcast");
1506 case CK_UncheckedDerivedToBase:
1507 case CK_DerivedToBase: {
1525 case CK_BaseToDerived: {
1541 case CK_ZeroToOCLOpaqueType:
1542 llvm_unreachable(
"NULL to OpenCL opaque type lvalue cast is not valid");
1545 llvm_unreachable(
"Invalid cast kind");
1582 if (
auto *field = dyn_cast<FieldDecl>(nd)) {
1599 llvm_unreachable(
"Unhandled member declaration!");
1629 llvm_unreachable(
"bad evaluation kind");
1634 const Expr *inner) {
1645 cir::AllocaOp extDeclAlloca;
1649 extDeclAlloca = extDeclAddrIter->second.getDefiningOp<cir::AllocaOp>();
1651 mlir::OpBuilder::InsertPoint ip;
1653 ip = {extDeclAlloca->getBlock(), extDeclAlloca->getIterator()};
1663 assert(addr.getAlignment().has_value() &&
1664 "This should always have an alignment");
1670 llvm_unreachable(
"temporary can't have dynamic storage duration");
1672 llvm_unreachable(
"unknown storage duration");
1696 if (
const auto *classDecl =
1700 referenceTemporaryDtor = classDecl->getDestructor();
1702 if (!referenceTemporaryDtor)
1706 "storage duration with destructors");
1717 "pushTemporaryCleanup: automatic storage duration");
1721 llvm_unreachable(
"temporary cannot have dynamic storage duration");
1731 "Reference should never be pseudo-strong!");
1739 "emitMaterializeTemporaryExpr: ObjCLifetime");
1747 for (
const Expr *ignored : commaLHSs)
1752 "emitMaterializeTemporaryExpr: OpaqueValueExpr");
1759 if (
auto var =
object.getPointer().getDefiningOp<cir::GlobalOp>()) {
1772 if (!adjustments.empty()) {
1774 "emitMaterializeTemporaryExpr: Adjustments");
1789 assert(e->
isUnique() &&
"LValue for a nonunique OVE hasn't been emitted");
1801 assert(e->
isUnique() &&
"RValue for a nonunique OVE hasn't been emitted");
1815 ".compoundliteral");
1826 "emitCompoundLiteralLValue: non C++ DestructedType");
1842 "Can't have a scalar return unless the return type is a "
1858 assert(e->
getOpcode() == BO_Assign &&
"unexpected binary l-value");
1897 llvm_unreachable(
"bad evaluation kind");
1903 bool ignoreResult) {
1910 if (!ignoreResult && aggSlot.
isIgnored())
1917 llvm_unreachable(
"bad evaluation kind");
1925 if (!pd->isInlineBuiltinDeclaration())
1930CIRGenCallee CIRGenFunction::emitDirectCallee(
const GlobalDecl &gd) {
1933 if (
unsigned builtinID = fd->getBuiltinID()) {
1934 StringRef ident =
cgm.getMangledName(gd);
1935 std::string fdInlineName = (ident +
".inline").str();
1937 bool isPredefinedLibFunction =
1938 cgm.getASTContext().BuiltinInfo.isPredefinedLibFunction(builtinID);
1944 bool hasAttributeNoBuiltin =
false;
1952 mlir::cast_or_null<cir::FuncOp>(
cgm.getGlobalValue(fdInlineName));
1958 mlir::OpBuilder::InsertionGuard guard(builder);
1959 builder.setInsertionPointToStart(
cgm.getModule().getBody());
1961 clone = cir::FuncOp::create(builder, calleeFunc.getLoc(), fdInlineName,
1962 calleeFunc.getFunctionType());
1963 clone.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
1964 &
cgm.getMLIRContext(), cir::GlobalLinkageKind::InternalLinkage));
1965 clone.setSymVisibility(
"private");
1966 clone.setInlineKind(cir::InlineKind::AlwaysInline);
1977 else if (!isPredefinedLibFunction || !hasAttributeNoBuiltin)
1983 if ((
cgm.getLangOpts().CUDA ||
cgm.getLangOpts().HIP) &&
1984 !
cgm.getLangOpts().CUDAIsDevice && fd->hasAttr<CUDAGlobalAttr>()) {
1985 mlir::Operation *handle =
cgm.getCUDARuntime().getKernelHandle(callee, gd);
1987 mlir::cast<cir::FuncOp>(*
cgm.getCUDARuntime().getKernelStub(handle));
1997 cgm.errorNYI(
"unsupported type for undef rvalue");
2008 "Callee must have function pointer type!");
2029 cgm.getTypes().arrangeFreeFunctionCall(args, fnType);
2051 calleeTy = cir::FuncType::get(calleeTy.getInputs(),
2052 calleeTy.getReturnType(),
false);
2053 auto calleePtrTy = cir::PointerType::get(calleeTy);
2057 if (
auto funcOp = mlir::dyn_cast<cir::FuncOp>(fn)) {
2058 addr = cir::GetGlobalOp::create(
2060 cir::PointerType::get(funcOp.getFunctionType()), funcOp.getSymName());
2062 addr = fn->getResult(0);
2065 fn = builder.createBitcast(addr, calleePtrTy).getDefiningOp();
2073 cir::CIRCallOpInterface callOp;
2086 if (
const auto *implicitCast = dyn_cast<ImplicitCastExpr>(e)) {
2087 if (implicitCast->getCastKind() == CK_FunctionToPointerDecay ||
2088 implicitCast->getCastKind() == CK_BuiltinFnToFnPtr) {
2089 return emitCallee(implicitCast->getSubExpr());
2094 assert(implicitCast->getCastKind() == CK_LValueToRValue &&
2095 "unexpected implicit cast on function pointers");
2096 }
else if (
const auto *declRef = dyn_cast<DeclRefExpr>(e)) {
2099 return emitDirectCallee(funcDecl);
2100 }
else if (
auto me = dyn_cast<MemberExpr>(e)) {
2101 if (
const auto *fd = dyn_cast<FunctionDecl>(me->getMemberDecl())) {
2103 return emitDirectCallee(fd);
2106 }
else if (
auto *pde = dyn_cast<CXXPseudoDestructorExpr>(e)) {
2111 mlir::Value calleePtr;
2123 if (
const auto *vd =
2128 CIRGenCallee callee(calleeInfo, calleePtr.getDefiningOp());
2136 if (
const auto *ce = dyn_cast<CXXMemberCallExpr>(e))
2142 if (
const auto *operatorCall = dyn_cast<CXXOperatorCallExpr>(e)) {
2146 dyn_cast_or_null<CXXMethodDecl>(operatorCall->getCalleeDecl()))
2180 "Array to pointer decay must have array source type!");
2188 auto lvalueAddrTy = mlir::cast<cir::PointerType>(addr.
getPointer().getType());
2193 [[maybe_unused]]
auto pointeeTy =
2194 mlir::cast<cir::ArrayType>(lvalueAddrTy.getPointee());
2197 assert(mlir::isa<cir::ArrayType>(arrayTy) &&
"expected array");
2198 assert(pointeeTy == arrayTy);
2208 mlir::Value ptr = builder.maybeBuildArrayDecay(
2226 llvm_unreachable(
"bad evaluation kind");
2233 const Stmt *elseS) {
2235 std::optional<mlir::Location> elseLoc;
2239 mlir::LogicalResult resThen = mlir::success(), resElse = mlir::success();
2242 [&](mlir::OpBuilder &, mlir::Location) {
2243 LexicalScope lexScope{*
this, thenLoc, builder.getInsertionBlock()};
2248 [&](mlir::OpBuilder &, mlir::Location) {
2249 assert(elseLoc &&
"Invalid location for elseS.");
2250 LexicalScope lexScope{*
this, *elseLoc, builder.getInsertionBlock()};
2255 return mlir::LogicalResult::success(resThen.succeeded() &&
2256 resElse.succeeded());
2264 std::optional<mlir::Location> elseLoc) {
2270 ifLocs.push_back(*elseLoc);
2271 mlir::Location loc = mlir::FusedLoc::get(&
getMLIRContext(), ifLocs);
2275 return cir::IfOp::create(builder, loc, condV, elseLoc.has_value(),
2294 Expr *trueExpr = condOp->getTrueExpr();
2295 Expr *falseExpr = condOp->getFalseExpr();
2298 mlir::Value ternaryOpRes =
2299 cir::TernaryOp::create(
2300 builder, loc, condV,
2301 [
this, trueExpr](mlir::OpBuilder &
b, mlir::Location loc) {
2303 cir::YieldOp::create(
b, loc, lhs);
2306 [
this, falseExpr](mlir::OpBuilder &
b, mlir::Location loc) {
2308 cir::YieldOp::create(
b, loc, rhs);
2317 cgm.errorNYI(
"NYI");
2331 mlir::Location loc,
CharUnits alignment,
2332 bool insertIntoFnEntryBlock,
2333 mlir::Value arraySize) {
2334 mlir::Block *entryBlock = insertIntoFnEntryBlock
2343 llvm::dyn_cast_if_present<cir::TryOp>(entryBlock->getParentOp())) {
2344 if (auto scopeOp = llvm::dyn_cast<cir::ScopeOp>(tryOp->getParentOp()))
2345 entryBlock = &scopeOp.getScopeRegion().front();
2353 mlir::Location loc,
CharUnits alignment,
2354 mlir::OpBuilder::InsertPoint ip,
2355 mlir::Value arraySize) {
2359 cir::PointerType localVarPtrTy =
2361 mlir::IntegerAttr alignIntAttr =
cgm.
getSize(alignment);
2365 mlir::OpBuilder::InsertionGuard guard(builder);
2366 builder.restoreInsertionPoint(ip);
2368 ty, name, alignIntAttr, arraySize);
2386 if (md->isStatic()) {
2391 bool hasQualifier = me->hasQualifier();
2393 bool isArrow = me->isArrow();
2394 const Expr *base = me->getBase();
2397 ce, md,
returnValue, hasQualifier, qualifier, isArrow, base);
2414 cgm.errorNYI(loc,
"load of volatile reference");
2423 CharUnits align =
cgm.getNaturalTypeAlignment(pointeeType, pointeeBaseInfo);
2440 cir::TrapOp::create(builder, loc);
2442 builder.createBlock(builder.getBlock()->getParent());
2446 bool createNewBlock) {
2448 cir::UnreachableOp::create(builder,
getLoc(loc));
2450 builder.createBlock(builder.getBlock()->getParent());
2457 return builder.createDummyValue(loc, t, alignment);
2465 const Twine &name,
Address *alloca,
2466 mlir::OpBuilder::InsertPoint ip) {
2473 mlir::Location loc,
const Twine &name,
2475 mlir::OpBuilder::InsertPoint ip) {
2477 nullptr, alloca, ip);
2480 cgm.errorNYI(loc,
"temporary matrix value");
2488 mlir::Type ty,
CharUnits align, mlir::Location loc,
const Twine &name,
2489 mlir::Value arraySize, mlir::OpBuilder::InsertPoint ip) {
2490 cir::AllocaOp alloca = ip.isSet()
2493 alloca.setAlignmentAttr(
cgm.getSize(align));
2494 return Address(alloca, ty, align);
2502 mlir::Location loc,
const Twine &name,
2503 mlir::Value arraySize,
2505 mlir::OpBuilder::InsertPoint ip) {
2509 *allocaAddr = alloca;
2516 cir::PointerType dstTy;
2532 mlir::Value arraySize,
2533 bool insertIntoFnEntryBlock) {
2535 insertIntoFnEntryBlock, arraySize)
2543 mlir::OpBuilder::InsertPoint ip,
2544 mlir::Value arraySize) {
2545 assert(ip.isSet() &&
"Insertion point is not set");
2546 return mlir::cast<cir::AllocaOp>(
2557 const Twine &name) {
2599 mlir::TypedAttr cstToEmit = mlir::dyn_cast_if_present<mlir::TypedAttr>(
c);
2600 assert(cstToEmit &&
"expected a typed attribute");
2616 assert(constant &&
"not a constant");
2626 assert(sl !=
nullptr &&
"No StringLiteral name in PredefinedExpr");
2628 StringRef fnName = fn.getName();
2629 fnName.consume_front(
"\01");
2630 std::array<StringRef, 2> nameItems = {
2632 std::string gvName = llvm::join(nameItems,
".");
2647std::optional<LValue> handleConditionalOperatorLValueSimpleCase(
2650 llvm::APSInt condExprVal;
2652 return std::nullopt;
2655 if (!condExprVal.getBoolValue())
2656 std::swap(live, dead);
2659 return std::nullopt;
2666 if (
auto *throwExpr = dyn_cast<CXXThrowExpr>(live->
IgnoreParens())) {
2670 mlir::Type elemTy = cgf.
convertType(dead->getType());
2671 mlir::Value undefPtr =
2673 cgf.
getLoc(throwExpr->getSourceRange()));
2683static std::optional<LValue> emitLValueOrThrowExpression(
CIRGenFunction &cgf,
2684 const Expr *operand) {
2685 if (
auto *throwExpr = dyn_cast<CXXThrowExpr>(operand->
IgnoreParens())) {
2687 return std::nullopt;
2696template <
typename FuncTy>
2699 const FuncTy &branchGenFunc) {
2707 mlir::Type yieldTy{};
2709 auto emitBranch = [&](mlir::OpBuilder &
b, mlir::Location loc,
2710 const Expr *
expr, std::optional<LValue> &resultLV) {
2716 resultLV = branchGenFunc(*
this,
expr);
2717 mlir::Value resultPtr = resultLV ? resultLV->getPointer() : mlir::Value();
2721 yieldTy = resultPtr.getType();
2722 cir::YieldOp::create(
b, loc, resultPtr);
2728 if (builder.getInsertionBlock()->mightHaveTerminator()) {
2729 mlir::Operation *terminator =
2730 builder.getInsertionBlock()->getTerminator();
2731 if (isa_and_nonnull<cir::UnreachableOp>(terminator))
2732 insertPoints.push_back(
b.saveInsertionPoint());
2737 info.
result = cir::TernaryOp::create(
2738 builder, loc, condV,
2740 [&](mlir::OpBuilder &
b, mlir::Location loc) {
2744 [&](mlir::OpBuilder &
b, mlir::Location loc) {
2754 for (mlir::OpBuilder::InsertPoint &toInsert : insertPoints) {
2755 mlir::OpBuilder::InsertionGuard guard(builder);
2756 builder.restoreInsertionPoint(toInsert);
2760 cir::YieldOp::create(builder, loc);
2762 mlir::Value op0 = builder.getNullValue(yieldTy, loc);
2763 cir::YieldOp::create(builder, loc, op0);
2772 if (!
expr->isGLValue()) {
2775 "Unexpected conditional operator!");
2780 if (std::optional<LValue> res =
2781 handleConditionalOperatorLValueSimpleCase(*
this,
expr))
2786 return emitLValueOrThrowExpression(cgf, e);
2789 if ((info.
lhs && !info.
lhs->isSimple()) ||
2790 (info.
rhs && !info.
rhs->isSimple())) {
2791 cgm.errorNYI(
expr->getSourceRange(),
2792 "unsupported conditional operator with non-simple lvalue");
2796 if (info.
lhs && info.
rhs) {
2802 std::max(info.
lhs->getBaseInfo().getAlignmentSource(),
2803 info.
rhs->getBaseInfo().getAlignmentSource());
2808 assert((info.
lhs || info.
rhs) &&
2809 "both operands of glvalue conditional are throw-expressions?");
2810 return info.
lhs ? *info.
lhs : *info.
rhs;
2817 if (!
cgm.getLangOpts().MSVolatile)
2820 cgm.errorNYI(
"LValueSuitableForInlineAtomic LangOpts MSVolatile");
Provides definitions for the various language-specific address spaces.
llvm::function_ref< void(mlir::OpBuilder &, mlir::Location)> BuilderCallbackRef
static Address createReferenceTemporary(CIRGenFunction &cgf, const MaterializeTemporaryExpr *m, const Expr *inner)
static bool isAAPCS(const TargetInfo &targetInfo)
Helper method to check if the underlying ABI is AAPCS.
static LValue emitFunctionDeclLValue(CIRGenFunction &cgf, const Expr *e, GlobalDecl gd)
static CharUnits getArrayElementAlign(CharUnits arrayAlign, mlir::Value idx, CharUnits eltSize)
static void pushTemporaryCleanup(CIRGenFunction &cgf, const MaterializeTemporaryExpr *m, const Expr *e, Address referenceTemporary)
static cir::IntAttr getConstantIndexOrNull(mlir::Value idx)
static const Expr * getSimpleArrayDecayOperand(const Expr *e)
If the specified expr is a simple decay from an array to pointer, return the array subexpression.
static QualType getFixedSizeElementType(const ASTContext &astContext, const VariableArrayType *vla)
static bool canEmitSpuriousReferenceToVariable(CIRGenFunction &cgf, const DeclRefExpr *e, const VarDecl *vd)
Determine whether we can emit a reference to vd from the current context, despite not necessarily hav...
static DeclRefExpr * tryToConvertMemberExprToDeclRefExpr(CIRGenFunction &cgf, const MemberExpr *me)
static cir::FuncOp emitFunctionDeclPointer(CIRGenModule &cgm, GlobalDecl gd)
static LValue emitGlobalVarDeclLValue(CIRGenFunction &cgf, const Expr *e, const VarDecl *vd)
static mlir::Value emitArraySubscriptPtr(CIRGenFunction &cgf, mlir::Location beginLoc, mlir::Location endLoc, mlir::Value ptr, mlir::Type eltTy, mlir::Value idx, bool shouldDecay)
static LValue emitCapturedFieldLValue(CIRGenFunction &cgf, const FieldDecl *fd, mlir::Value thisValue)
static bool onlyHasInlineBuiltinDeclaration(const FunctionDecl *fd)
Defines the clang::Expr interface and subclasses for C++ expressions.
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
__device__ __2f16 float c
static OpBuilder::InsertPoint getBestAllocaInsertPoint(mlir::Block *block)
cir::GetMemberOp createGetMember(mlir::Location loc, mlir::Type resultTy, mlir::Value base, llvm::StringRef name, unsigned index)
cir::PointerType getPointerTo(mlir::Type ty)
cir::ConstantOp getNullPtr(mlir::Type ty, mlir::Location loc)
mlir::Value createBitcast(mlir::Value src, mlir::Type newTy)
mlir::Value createGetGlobal(mlir::Location loc, cir::GlobalOp global, bool threadLocal=false)
mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType, mlir::Type type, llvm::StringRef name, mlir::IntegerAttr alignment, mlir::Value dynAllocSize)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
const VariableArrayType * getAsVariableArrayType(QualType T) const
CanQualType getCanonicalTagType(const TagDecl *TD) const
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
SourceLocation getExprLoc() const LLVM_READONLY
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
SourceLocation getBeginLoc() const LLVM_READONLY
SourceLocation getEndLoc() const
QualType getElementType() const
A builtin binary operation expression such as "x + y" or "x <= y".
mlir::Value getPointer() const
mlir::Type getElementType() const
Address withElementType(CIRGenBuilderTy &builder, mlir::Type ElemTy) const
Return address with different element type, a bitcast pointer, and the same alignment.
clang::CharUnits getAlignment() const
mlir::Type getType() const
mlir::Operation * getDefiningOp() const
Get the operation which defines this address.
IsDestructed_t
This is set to true if the slot might be aliased and it's not undefined behavior to access it through...
static AggValueSlot forAddr(Address addr, clang::Qualifiers quals, IsDestructed_t isDestructed, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed)
static AggValueSlot ignored()
Returns an aggregate value slot indicating that the aggregate value is being ignored.
Address createElementBitCast(mlir::Location loc, Address addr, mlir::Type destType)
Cast the element type of the given address to a different type, preserving information like the align...
mlir::Value getArrayElement(mlir::Location arrayLocBegin, mlir::Location arrayLocEnd, mlir::Value arrayPtr, mlir::Type eltTy, mlir::Value idx, bool shouldDecay)
Create a cir.ptr_stride operation to get access to an array element.
Abstract information about a function or function prototype.
bool isPseudoDestructor() const
void setFunctionPointer(mlir::Operation *functionPtr)
const clang::FunctionDecl * getBuiltinDecl() const
const CXXPseudoDestructorExpr * getPseudoDestructorExpr() const
static CIRGenCallee forDirect(mlir::Operation *funcPtr, const CIRGenCalleeInfo &abstractInfo=CIRGenCalleeInfo())
unsigned getBuiltinID() const
static CIRGenCallee forBuiltin(unsigned builtinID, const clang::FunctionDecl *builtinDecl)
mlir::Operation * getFunctionPointer() const
static CIRGenCallee forPseudoDestructor(const clang::CXXPseudoDestructorExpr *expr)
An object to manage conditionally-evaluated expressions.
static ConstantEmission forValue(mlir::TypedAttr c)
mlir::TypedAttr getValue() const
static bool shouldBindAsLValue(const Expr *expr)
An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
static bool shouldBindAsLValue(const Expr *expr)
mlir::Value emitComplexToScalarConversion(mlir::Value src, QualType srcTy, QualType dstTy, SourceLocation loc)
Emit a conversion from the specified complex type to the specified destination type,...
void emitCallArgs(CallArgList &args, PrototypeWrapper prototype, llvm::iterator_range< clang::CallExpr::const_arg_iterator > argRange, AbstractCallee callee=AbstractCallee(), unsigned paramsToSkip=0)
mlir::Type convertType(clang::QualType t)
LValue emitOpaqueValueLValue(const OpaqueValueExpr *e)
static cir::TypeEvaluationKind getEvaluationKind(clang::QualType type)
Return the cir::TypeEvaluationKind of QualType type.
RValue convertTempToRValue(Address addr, clang::QualType type, clang::SourceLocation loc)
Given the address of a temporary variable, produce an r-value of its type.
Address emitCXXMemberDataPointerAddress(const Expr *e, Address base, mlir::Value memberPtr, const MemberPointerType *memberPtrType, LValueBaseInfo *baseInfo)
CIRGenTypes & getTypes() const
Address emitPointerWithAlignment(const clang::Expr *expr, LValueBaseInfo *baseInfo=nullptr)
Given an expression with a pointer type, emit the value and compute our best estimate of the alignmen...
void emitVariablyModifiedType(QualType ty)
RValue emitLoadOfLValue(LValue lv, SourceLocation loc)
Given an expression that represents a value lvalue, this method emits the address of the lvalue,...
const clang::LangOptions & getLangOpts() const
cir::AllocaOp createTempAlloca(mlir::Type ty, mlir::Location loc, const Twine &name="tmp", mlir::Value arraySize=nullptr, bool insertIntoFnEntryBlock=false)
This creates an alloca and inserts it into the entry block if ArraySize is nullptr,...
void emitTrap(mlir::Location loc, bool createNewBlock)
Emit a trap instruction, which is used to abort the program in an abnormal way, usually for debugging...
mlir::Block * getCurFunctionEntryBlock()
RValue emitCXXMemberCallExpr(const clang::CXXMemberCallExpr *e, ReturnValueSlot returnValue)
RValue emitCXXMemberPointerCallExpr(const CXXMemberCallExpr *ce, ReturnValueSlot returnValue)
LValue emitLValueForBitField(LValue base, const FieldDecl *field)
mlir::LogicalResult emitIfOnBoolExpr(const clang::Expr *cond, const clang::Stmt *thenS, const clang::Stmt *elseS)
Emit an if on a boolean condition to the specified blocks.
VlaSizePair getVLASize(const VariableArrayType *type)
Returns an MLIR::Value+QualType pair that corresponds to the size, in non-variably-sized elements,...
mlir::Value emitComplexExpr(const Expr *e)
Emit the computation of the specified expression of complex type, returning the result.
LValue makeNaturalAlignPointeeAddrLValue(mlir::Value v, clang::QualType t)
Given a value of type T* that may not be to a complete object, construct an l-vlaue withi the natural...
RValue emitCallExpr(const clang::CallExpr *e, ReturnValueSlot returnValue=ReturnValueSlot())
LValue emitMemberExpr(const MemberExpr *e)
LValue emitConditionalOperatorLValue(const AbstractConditionalOperator *expr)
LValue emitLValue(const clang::Expr *e)
Emit code to compute a designator that specifies the location of the expression.
Address makeNaturalAddressForPointer(mlir::Value ptr, QualType t, CharUnits alignment, bool forPointeeType=false, LValueBaseInfo *baseInfo=nullptr)
Construct an address with the natural alignment of T.
LValue emitLValueForLambdaField(const FieldDecl *field)
mlir::Value evaluateExprAsBool(const clang::Expr *e)
Perform the usual unary conversions on the specified expression and compare the result against zero,...
std::string getCounterRefTmpAsString()
LValue makeNaturalAlignAddrLValue(mlir::Value val, QualType ty)
bool constantFoldsToSimpleInteger(const clang::Expr *cond, llvm::APSInt &resultInt, bool allowLabels=false)
If the specified expression does not fold to a constant, or if it does fold but contains a label,...
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
mlir::Value emitOpOnBoolExpr(mlir::Location loc, const clang::Expr *cond)
TODO(cir): see EmitBranchOnBoolExpr for extra ideas).
Address getAddressOfBaseClass(Address value, const CXXRecordDecl *derived, llvm::iterator_range< CastExpr::path_const_iterator > path, bool nullCheckValue, SourceLocation loc)
LValue emitLoadOfReferenceLValue(Address refAddr, mlir::Location loc, QualType refTy, AlignmentSource source)
mlir::Value emitScalarPrePostIncDec(const UnaryOperator *e, LValue lv, cir::UnaryOpKind kind, bool isPre)
void emitAnyExprToMem(const Expr *e, Address location, Qualifiers quals, bool isInitializer)
Emits the code necessary to evaluate an arbitrary expression into the given memory location.
LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its LValue mapping if it exists, otherwise create one.
mlir::Value performAddrSpaceCast(mlir::Value v, mlir::Type destTy) const
RValue emitReferenceBindingToExpr(const Expr *e)
Emits a reference binding to the passed in expression.
LValue emitArraySubscriptExpr(const clang::ArraySubscriptExpr *e)
RValue emitCUDAKernelCallExpr(const CUDAKernelCallExpr *expr, ReturnValueSlot returnValue)
mlir::Operation * curFn
The current function or global initializer that is generated code for.
Address emitExtVectorElementLValue(LValue lv, mlir::Location loc)
Generates lvalue for partial ext_vector access.
mlir::Value emitScalarConversion(mlir::Value src, clang::QualType srcType, clang::QualType dstType, clang::SourceLocation loc)
Emit a conversion from the specified type to the specified destination type, both of which are CIR sc...
Address getAddressOfDerivedClass(mlir::Location loc, Address baseAddr, const CXXRecordDecl *derived, llvm::iterator_range< CastExpr::path_const_iterator > path, bool nullCheckValue)
AggValueSlot createAggTemp(QualType ty, mlir::Location loc, const Twine &name="tmp", Address *alloca=nullptr)
Create a temporary memory object for the given aggregate type.
RValue emitLoadOfExtVectorElementLValue(LValue lv)
mlir::Value emitCXXTypeidExpr(const CXXTypeidExpr *e)
mlir::Type convertTypeForMem(QualType t)
mlir::Value emitAlloca(llvm::StringRef name, mlir::Type ty, mlir::Location loc, clang::CharUnits alignment, bool insertIntoFnEntryBlock, mlir::Value arraySize=nullptr)
void emitUnreachable(clang::SourceLocation loc, bool createNewBlock)
Emit a reached-unreachable diagnostic if loc is valid and runtime checking is enabled.
mlir::Value createDummyValue(mlir::Location loc, clang::QualType qt)
mlir::Value emitLoadOfComplex(LValue src, SourceLocation loc)
Load a complex number from the specified l-value.
LValue emitAggExprToLValue(const Expr *e)
void emitStoreOfScalar(mlir::Value value, Address addr, bool isVolatile, clang::QualType ty, LValueBaseInfo baseInfo, bool isInit=false, bool isNontemporal=false)
void pushDestroy(QualType::DestructionKind dtorKind, Address addr, QualType type)
Push the standard destructor for the given type as at least a normal cleanup.
static Destroyer destroyCXXObject
RValue getUndefRValue(clang::QualType ty)
Get an appropriate 'undef' rvalue for the given type.
Address returnValue
The temporary alloca to hold the return value.
static bool hasAggregateEvaluationKind(clang::QualType type)
LValue emitPointerToDataMemberBinaryExpr(const BinaryOperator *e)
mlir::Value emitComplexPrePostIncDec(const UnaryOperator *e, LValue lv, cir::UnaryOpKind op, bool isPre)
std::string getCounterAggTmpAsString()
LValue emitUnaryOpLValue(const clang::UnaryOperator *e)
RValue emitLoadOfBitfieldLValue(LValue lv, SourceLocation loc)
RValue emitCall(const CIRGenFunctionInfo &funcInfo, const CIRGenCallee &callee, ReturnValueSlot returnValue, const CallArgList &args, cir::CIRCallOpInterface *callOp, mlir::Location loc)
LValue emitComplexAssignmentLValue(const BinaryOperator *e)
const clang::Decl * curCodeDecl
This is the inner-most code context, which includes blocks.
LValue emitLValueForFieldInitialization(LValue base, const clang::FieldDecl *field, llvm::StringRef fieldName)
Like emitLValueForField, excpet that if the Field is a reference, this will return the address of the...
LValue emitCallExprLValue(const clang::CallExpr *e)
LValue emitStringLiteralLValue(const StringLiteral *e, llvm::StringRef name=".str")
mlir::Value emitToMemory(mlir::Value value, clang::QualType ty)
Given a value and its clang type, returns the value casted to its memory representation.
LValue emitLValueForField(LValue base, const clang::FieldDecl *field)
mlir::Value emitScalarExpr(const clang::Expr *e, bool ignoreResultAssign=false)
Emit the computation of the specified expression of scalar type.
Address emitLoadOfReference(LValue refLVal, mlir::Location loc, LValueBaseInfo *pointeeBaseInfo)
bool shouldNullCheckClassCastValue(const CastExpr *ce)
CIRGenBuilderTy & getBuilder()
LValue emitBinaryOperatorLValue(const BinaryOperator *e)
Address getAddrOfBitFieldStorage(LValue base, const clang::FieldDecl *field, mlir::Type fieldType, unsigned index)
CIRGenModule & getCIRGenModule()
mlir::MLIRContext & getMLIRContext()
LValue emitCastLValue(const CastExpr *e)
Casts are never lvalues unless that cast is to a reference type.
LValue emitCXXTypeidLValue(const CXXTypeidExpr *e)
mlir::Value emitLoadOfScalar(LValue lvalue, SourceLocation loc)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
bool containsLabel(const clang::Stmt *s, bool ignoreCaseStmts=false)
Return true if the statement contains a label in it.
DeclMapTy localDeclMap
This keeps track of the CIR allocas or globals for local C declarations.
LValue emitDeclRefLValue(const clang::DeclRefExpr *e)
void emitComplexExprIntoLValue(const Expr *e, LValue dest, bool isInit)
llvm::DenseMap< const clang::ValueDecl *, clang::FieldDecl * > lambdaCaptureFields
ConstantEmission tryEmitAsConstant(const DeclRefExpr *refExpr)
Try to emit a reference to the given value without producing it as an l-value.
void emitCXXThrowExpr(const CXXThrowExpr *e)
LValue makeAddrLValue(Address addr, QualType ty, AlignmentSource source=AlignmentSource::Type)
int64_t getAccessedFieldNo(unsigned idx, mlir::ArrayAttr elts)
LValue emitPredefinedLValue(const PredefinedExpr *e)
RValue emitAnyExpr(const clang::Expr *e, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
Emit code to compute the specified expression which can have any type.
llvm::DenseMap< const OpaqueValueExpr *, RValue > opaqueRValues
Address emitArrayToPointerDecay(const Expr *e, LValueBaseInfo *baseInfo=nullptr)
LexicalScope * curLexScope
void emitAtomicStore(RValue rvalue, LValue dest, bool isInit)
mlir::Value emitStoreThroughBitfieldLValue(RValue src, LValue dstresult)
llvm::DenseMap< const OpaqueValueExpr *, LValue > opaqueLValues
Keeps track of the current set of opaque value expressions.
CIRGenFunction(CIRGenModule &cgm, CIRGenBuilderTy &builder, bool suppressNewContext=false)
std::optional< mlir::Location > currSrcLoc
Use to track source locations across nested visitor traversals.
LValue emitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *e)
LValue emitExtVectorElementExpr(const ExtVectorElementExpr *e)
clang::ASTContext & getContext() const
RValue emitCXXMemberOrOperatorMemberCallExpr(const clang::CallExpr *ce, const clang::CXXMethodDecl *md, ReturnValueSlot returnValue, bool hasQualifier, clang::NestedNameSpecifier qualifier, bool isArrow, const clang::Expr *base)
mlir::Value emitScalarConstant(const ConstantEmission &constant, Expr *e)
RValue emitBuiltinExpr(const clang::GlobalDecl &gd, unsigned builtinID, const clang::CallExpr *e, ReturnValueSlot returnValue)
RValue emitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *e, const CXXMethodDecl *md, ReturnValueSlot returnValue)
void emitStoreThroughLValue(RValue src, LValue dst, bool isInit=false)
Store the specified rvalue into the specified lvalue, where both are guaranteed to the have the same ...
mlir::Value cxxabiThisValue
bool isLValueSuitableForInlineAtomic(LValue lv)
An LValue is a candidate for having its loads and stores be made atomic if we are operating under /vo...
mlir::LogicalResult emitStmt(const clang::Stmt *s, bool useCurrentScope, llvm::ArrayRef< const Attr * > attrs={})
RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its RValue mapping if it exists, otherwise create one.
Address createTempAllocaWithoutCast(mlir::Type ty, CharUnits align, mlir::Location loc, const Twine &name="tmp", mlir::Value arraySize=nullptr, mlir::OpBuilder::InsertPoint ip={})
This creates a alloca and inserts it into the entry block of the current region.
mlir::Value emitFromMemory(mlir::Value value, clang::QualType ty)
EmitFromMemory - Change a scalar value from its memory representation to its value representation.
void emitIgnoredExpr(const clang::Expr *e)
Emit code to compute the specified expression, ignoring the result.
Address createMemTemp(QualType t, mlir::Location loc, const Twine &name="tmp", Address *alloca=nullptr, mlir::OpBuilder::InsertPoint ip={})
Create a temporary memory object of the given type, with appropriate alignmen and cast it to the defa...
mlir::Value emitDynamicCast(Address thisAddr, const CXXDynamicCastExpr *dce)
void emitAggExpr(const clang::Expr *e, AggValueSlot slot)
ConditionalInfo emitConditionalBlocks(const AbstractConditionalOperator *e, const FuncTy &branchGenFunc)
Address createDefaultAlignTempAlloca(mlir::Type ty, mlir::Location loc, const Twine &name)
CreateDefaultAlignTempAlloca - This creates an alloca with the default alignment of the corresponding...
RValue emitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *expr)
LValue emitCompoundLiteralLValue(const CompoundLiteralExpr *e)
CIRGenCallee emitCallee(const clang::Expr *e)
Address emitAddrOfFieldStorage(Address base, const FieldDecl *field, llvm::StringRef fieldName, unsigned fieldIndex)
Get the address of a zero-sized field within a record.
This class organizes the cross-function state that is used while generating CIR code.
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
mlir::IntegerAttr getSize(CharUnits size)
CIRGenBuilderTy & getBuilder()
cir::FuncOp getAddrOfFunction(clang::GlobalDecl gd, mlir::Type funcType=nullptr, bool forVTable=false, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
Return the address of the given function.
mlir::Operation * getAddrOfGlobalTemporary(const MaterializeTemporaryExpr *mte, const Expr *init)
Returns a pointer to a global variable representing a temporary with static or thread storage duratio...
mlir::Value getAddrOfGlobalVar(const VarDecl *d, mlir::Type ty={}, ForDefinition_t isForDefinition=NotForDefinition)
Return the mlir::Value for the address of the given global variable.
cir::GlobalLinkageKind getCIRLinkageVarDefinition(const VarDecl *vd, bool isConstant)
This class handles record and union layout info while lowering AST types to CIR types.
cir::RecordType getCIRType() const
Return the "complete object" LLVM type associated with this record.
const CIRGenBitFieldInfo & getBitFieldInfo(const clang::FieldDecl *fd) const
Return the BitFieldInfo that corresponds to the field FD.
unsigned getCIRFieldNo(const clang::FieldDecl *fd) const
Return cir::RecordType element number that corresponds to the field FD.
cir::FuncType getFunctionType(const CIRGenFunctionInfo &info)
Get the CIR function type for.
mlir::Type convertTypeForMem(clang::QualType, bool forBitField=false)
Convert type T into an mlir::Type.
mlir::Attribute emitAbstract(const Expr *e, QualType destType)
Emit the result of the given expression as an abstract constant, asserting that it succeeded.
AlignmentSource getAlignmentSource() const
void mergeForCast(const LValueBaseInfo &info)
bool isExtVectorElt() const
const clang::Qualifiers & getQuals() const
mlir::Value getExtVectorPointer() const
static LValue makeExtVectorElt(Address vecAddress, mlir::ArrayAttr elts, clang::QualType type, LValueBaseInfo baseInfo)
mlir::Value getVectorIdx() const
Address getAddress() const
static LValue makeAddr(Address address, clang::QualType t, LValueBaseInfo baseInfo)
mlir::ArrayAttr getExtVectorElts() const
static LValue makeVectorElt(Address vecAddress, mlir::Value index, clang::QualType t, LValueBaseInfo baseInfo)
RValue asAggregateRValue() const
unsigned getVRQualifiers() const
clang::QualType getType() const
static LValue makeBitfield(Address addr, const CIRGenBitFieldInfo &info, clang::QualType type, LValueBaseInfo baseInfo)
Create a new object to represent a bit-field access.
mlir::Value getPointer() const
bool isVolatileQualified() const
Address getVectorAddress() const
clang::CharUnits getAlignment() const
LValueBaseInfo getBaseInfo() const
const CIRGenBitFieldInfo & getBitFieldInfo() const
Address getBitFieldAddress() const
Address getExtVectorAddress() const
This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(mlir::Value v)
static RValue getComplex(mlir::Value v)
mlir::Value getValue() const
Return the value of this scalar value.
Contains the address where the return value of a function can be stored, and whether the address is v...
Represents a C++ destructor within a class.
Represents a call to a member function that may be written either with member call syntax (e....
Represents a static or instance method of a struct/union/class.
Represents a C++ struct/union/class.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CastKind getCastKind() const
llvm::iterator_range< path_iterator > path()
Path through the class hierarchy taken by casts between base and derived classes (see implementation ...
bool changesVolatileQualification() const
Return.
static const char * getCastKindName(CastKind CK)
CharUnits - This is an opaque type for sizes expressed in character units.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
static CharUnits One()
One - Construct a CharUnits quantity of one.
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Complex values, per C99 6.2.5p11.
CompoundLiteralExpr - [C99 6.5.2.5].
const Expr * getInitializer() const
ConditionalOperator - The ?
A reference to a declared variable, function, enum, etc.
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
NonOdrUseReason isNonOdrUse() const
Is this expression a non-odr-use reference, and if so, why?
SourceLocation getLocation() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
const Expr * getBase() const
This represents one expression.
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Decl * getReferencedDeclOfCallee()
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
bool isArrow() const
isArrow - Return true if the base expression is a pointer to vector, return false if the base express...
void getEncodedElementAccess(SmallVectorImpl< uint32_t > &Elts) const
getEncodedElementAccess - Encode the elements accessed into an llvm aggregate Constant of ConstantInt...
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
bool isZeroSize(const ASTContext &Ctx) const
Determine if this field is a subobject of zero size, that is, either a zero-length bit-field or a fie...
Represents a function declaration or definition.
FunctionDecl * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
Represents a prototype with parameter type info, e.g.
GlobalDecl - represents a global declaration.
const Decl * getDecl() const
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
ValueDecl * getExtendingDecl()
Get the declaration which triggered the lifetime-extension of this temporary, if any.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
NonOdrUseReason isNonOdrUse() const
Is this expression a non-odr-use reference, and if so, why?
SourceLocation getExprLoc() const LLVM_READONLY
A pointer to member type per C++ 8.3.3 - Pointers to members.
This represents a decl that may have a name.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
A C++ nested-name-specifier augmented with source location information.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
PointerType - C99 6.7.5.1 - Pointer Declarators.
[C99 6.4.2.2] - A predefined identifier such as func.
StringRef getIdentKindName() const
PredefinedIdentKind getIdentKind() const
StringLiteral * getFunctionName()
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType withCVRQualifiers(unsigned CVR) const
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
The collection of all-type qualifiers we support.
unsigned getCVRQualifiers() const
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
void addCVRQualifiers(unsigned mask)
void addQualifiers(Qualifiers Q)
Add the qualifiers from the given set to this set.
Represents a struct/union/class.
Encodes a location in the source.
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
StringLiteral - This represents a string literal expression, e.g.
Exposes information about the current target.
virtual StringRef getABI() const
Get the ABI currently in use.
bool isBooleanType() const
bool isPackedVectorBoolType(const ASTContext &ctx) const
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isFunctionPointerType() const
CXXRecordDecl * castAsCXXRecordDecl() const
bool isArithmeticType() const
bool isConstantMatrixType() const
bool isPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isVariableArrayType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isExtVectorBoolType() const
bool isAnyComplexType() const
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isAtomicType() const
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isFunctionType() const
bool isVectorType() const
bool isSubscriptableVectorType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool hasBooleanRepresentation() const
Determine whether this type has a boolean representation – i.e., it is a boolean type,...
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
Expr * getSubExpr() const
static bool isIncrementOp(Opcode Op)
static bool isPrefix(Opcode Op)
isPrefix - Return true if this is a prefix operation, like –x.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
TLSKind getTLSKind() const
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
@ TLS_Dynamic
TLS with a dynamic initializer.
Represents a C array with a specified size that is not an integer-constant-expression.
Represents a GCC generic vector type.
Defines the clang::TargetInfo interface.
mlir::ptr::MemorySpaceAttrInterface toCIRAddressSpaceAttr(mlir::MLIRContext &ctx, clang::LangAS langAS)
Convert an AST LangAS to the appropriate CIR address space attribute interface.
AlignmentSource
The source of the alignment of an l-value; an expression of confidence in the alignment actually matc...
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
static AlignmentSource getFieldAlignmentSource(AlignmentSource source)
Given that the base address has the given alignment source, what's our confidence in the alignment of...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< FunctionType > functionType
const internal::VariadicDynCastAllOfMatcher< Stmt, CUDAKernelCallExpr > cudaKernelCallExpr
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr
Matches any cast nodes of Clang's AST.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
bool isTargetAddressSpace(LangAS AS)
@ SD_Thread
Thread storage duration.
@ SD_Static
Static storage duration.
@ SD_FullExpression
Full-expression storage duration (for temporaries).
@ SD_Automatic
Automatic storage duration (most local variables).
@ SD_Dynamic
Dynamic storage duration.
LangAS
Defines the address space values used by the address space qualifier of QualType.
U cast(CodeGen::Address addr)
@ NOUR_Unevaluated
This name appears in an unevaluated operand.
@ NOUR_Constant
This name appears as a potential result of an lvalue-to-rvalue conversion that is a constant expressi...
static bool weakRefReference()
static bool objCLifetime()
static bool emitLifetimeMarkers()
static bool opLoadEmitScalarRangeCheck()
static bool addressSpace()
static bool opAllocaNonGC()
static bool opAllocaOpenMPThreadPrivate()
static bool preservedAccessIndexRegion()
static bool mergeAllConstants()
static bool opLoadStoreTbaa()
static bool opCallChain()
static bool opAllocaImpreciseLifetime()
static bool opAllocaStaticLocal()
static bool opAllocaTLS()
static bool emitCheckedInBoundsGEP()
static bool attributeNoBuiltin()
static bool setObjCGCLValueClass()
static bool cirgenABIInfo()
static bool opLoadStoreObjC()
static bool opCallArgEvaluationOrder()
static bool lambdaCaptures()
static bool insertBuiltinUnpredictable()
static bool opCallMustTail()
static bool shouldReverseUnaryCondOnBoolExpr()
static bool tryEmitAsConstant()
static bool addressIsKnownNonNull()
static bool astVarDeclInterface()
static bool cgCapturedStmtInfo()
static bool opAllocaEscapeByReference()
static bool opLoadStoreNontemporal()
static bool opCallFnInfoOpts()
static bool generateDebugInfo()
static bool incrementProfileCounter()
Record with information about how a bitfield should be accessed.
unsigned volatileStorageSize
The storage size in bits which should be used when accessing this bitfield.
unsigned volatileOffset
The offset within a contiguous run of bitfields that are represented as a single "field" within the c...
std::optional< LValue > rhs
std::optional< LValue > lhs
Represents a scope, including function bodies, compound statements, and the substatements of if/while...
mlir::ptr::MemorySpaceAttrInterface getCIRAllocaAddressSpace() const
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
bool HasSideEffects
Whether the evaluated expression has side effects.