19#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
20#include "mlir/IR/BuiltinAttributes.h"
21#include "mlir/IR/Value.h"
74 llvm::StringRef fieldName,
75 unsigned fieldIndex) {
80 bool addressedByFieldIndex =
84 if (!addressedByFieldIndex)
100 auto fieldPtr = cir::PointerType::get(fieldType, addrSpace);
101 bool needsBitcast =
false;
105 fieldPtr = cir::PointerType::get(memberType, addrSpace);
112 mlir::Value addr = builder.createGetMember(loc, fieldPtr, base.
getPointer(),
113 fieldName, fieldIndex);
119 addr = builder.createPtrBitcast(addr, fieldType);
131 assert(
expr->getType()->isPointerType() ||
132 expr->getType()->isObjCObjectPointerType());
136 if (
auto const *ce = dyn_cast<CastExpr>(
expr)) {
137 if (
const auto *ece = dyn_cast<ExplicitCastExpr>(ce))
138 cgm.emitExplicitCastExprType(ece);
140 switch (ce->getCastKind()) {
144 case CK_AddressSpaceConversion: {
145 if (
const auto *ptrTy =
146 ce->getSubExpr()->getType()->getAs<
PointerType>()) {
147 if (ptrTy->getPointeeType()->isVoidType())
155 *baseInfo = innerBaseInfo;
175 const mlir::Type eltTy =
179 if (ce->getCastKind() == CK_AddressSpaceConversion)
189 case CK_ArrayToPointerDecay:
192 case CK_UncheckedDerivedToBase:
193 case CK_DerivedToBase: {
198 ce->getSubExpr()->getType()->getPointeeCXXRecordDecl();
204 case CK_AnyPointerToBlockPointerCast:
205 case CK_BaseToDerived:
206 case CK_BaseToDerivedMemberPointer:
207 case CK_BlockPointerToObjCPointerCast:
208 case CK_BuiltinFnToFnPtr:
209 case CK_CPointerToObjCPointerCast:
210 case CK_DerivedToBaseMemberPointer:
212 case CK_FunctionToPointerDecay:
213 case CK_IntegralToPointer:
214 case CK_LValueToRValue:
215 case CK_LValueToRValueBitCast:
216 case CK_NullToMemberPointer:
217 case CK_NullToPointer:
218 case CK_ReinterpretMemberPointer:
219 case CK_UserDefinedConversion:
225 case CK_ARCConsumeObject:
226 case CK_ARCExtendBlockObject:
227 case CK_ARCProduceObject:
228 case CK_ARCReclaimReturnedObject:
229 case CK_AtomicToNonAtomic:
230 case CK_BooleanToSignedIntegral:
231 case CK_ConstructorConversion:
232 case CK_CopyAndAutoreleaseBlockObject:
234 case CK_FixedPointCast:
235 case CK_FixedPointToBoolean:
236 case CK_FixedPointToFloating:
237 case CK_FixedPointToIntegral:
238 case CK_FloatingCast:
239 case CK_FloatingComplexCast:
240 case CK_FloatingComplexToBoolean:
241 case CK_FloatingComplexToIntegralComplex:
242 case CK_FloatingComplexToReal:
243 case CK_FloatingRealToComplex:
244 case CK_FloatingToBoolean:
245 case CK_FloatingToFixedPoint:
246 case CK_FloatingToIntegral:
247 case CK_HLSLAggregateSplatCast:
248 case CK_HLSLArrayRValue:
249 case CK_HLSLElementwiseCast:
250 case CK_HLSLVectorTruncation:
251 case CK_HLSLMatrixTruncation:
252 case CK_IntToOCLSampler:
253 case CK_IntegralCast:
254 case CK_IntegralComplexCast:
255 case CK_IntegralComplexToBoolean:
256 case CK_IntegralComplexToFloatingComplex:
257 case CK_IntegralComplexToReal:
258 case CK_IntegralRealToComplex:
259 case CK_IntegralToBoolean:
260 case CK_IntegralToFixedPoint:
261 case CK_IntegralToFloating:
262 case CK_LValueBitCast:
264 case CK_MemberPointerToBoolean:
265 case CK_NonAtomicToAtomic:
266 case CK_ObjCObjectLValueCast:
267 case CK_PointerToBoolean:
268 case CK_PointerToIntegral:
272 case CK_ZeroToOCLOpaqueType:
277 cgm.errorNYI(ce->getSourceRange(),
278 "unexpected cast for emitPointerWithAlignment: ",
279 ce->getCastKindName());
287 if (uo->getOpcode() == UO_AddrOf) {
297 if (
auto const *call = dyn_cast<CallExpr>(
expr)) {
298 switch (call->getBuiltinCallee()) {
301 case Builtin::BIaddressof:
302 case Builtin::BI__addressof:
303 case Builtin::BI__builtin_addressof: {
321 auto getScalarSizeInBits = [&](mlir::Type ty) ->
unsigned {
322 mlir::Type scalarTy = mlir::isa<cir::VectorType>(ty)
323 ? mlir::cast<cir::VectorType>(ty).getElementType()
329 mlir::Value srcVal = src.
getValue();
332 getScalarSizeInBits(srcVal.getType())) {
335 "emitStoreThroughExtVectorComponentLValue: dstTySize > srcTysize");
341 "emitStoreThroughExtVectorComponentLValue: HLSL");
351 mlir::Value vec = builder.createLoad(loc, dstAddr, dst.
isVolatile());
353 unsigned numSrcElts = vecTy->getNumElements();
355 if (numDstElts == numSrcElts) {
360 for (
unsigned i = 0; i != numDstElts; ++i)
363 vec = builder.createVecShuffle(loc, srcVal, mask);
364 }
else if (numDstElts > numSrcElts) {
370 std::iota(extMask.begin(), extMask.begin() + numSrcElts, 0);
372 mlir::Value extSrcVal = builder.createVecShuffle(loc, srcVal, extMask);
376 std::iota(mask.begin(), mask.begin() + numDstElts, 0);
385 for (
unsigned i = 0; i != numSrcElts; ++i)
388 vec = builder.createVecShuffle(loc, vec, extSrcVal, mask);
391 llvm_unreachable(
"unexpected shorten vector length");
397 cir::ConstantOp elt = builder.getSInt64(inIdx, loc);
398 vec = cir::VecInsertOp::create(builder, loc, vec, srcVal, elt);
411 const mlir::Value vector =
413 const mlir::Value newVector = cir::VecInsertOp::create(
424 const mlir::Location loc = dst.
getPointer().getLoc();
429 const mlir::Value matrix =
431 const mlir::Value newMatrix = builder.createMatrixInsert(
440 cgm.errorNYI(
"emitStoreThroughLValue: !dst.isSimple() && isMatrixRow");
444 assert(dst.
isBitField() &&
"Unknown LValue type");
452 assert(src.
isScalar() &&
"Can't emit an aggregate store with this method");
459 std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> res =
460 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(vd);
464 if (*res == OMPDeclareTargetDeclAttr::MT_Local)
467 if ((*res == OMPDeclareTargetDeclAttr::MT_To ||
468 *res == OMPDeclareTargetDeclAttr::MT_Enter) &&
472 "emitDeclTargetVarDeclLValue: indirect access");
495 cir::PointerType realPtrTy = cir::PointerType::get(
496 realVarTy, mlir::cast<cir::PointerType>(v.getType()).getAddrSpace());
497 if (realPtrTy != v.getType())
501 Address addr(v, realVarTy, alignment);
515 bool isNontemporal) {
521 if (clangVecTy->getNumElements() == 3 && !
getLangOpts().PreserveVec3Type)
523 "emitStoreOfScalar Vec3 & PreserveVec3Type disabled");
537 assert(addr.
getPointer() &&
"expected pointer to exist");
539 if (currVarDecl && srcAlloca) {
540 const VarDecl *vd = currVarDecl;
541 assert(vd &&
"VarDecl expected");
546 assert(
currSrcLoc &&
"must pass in source location");
564 assert(
currSrcLoc &&
"must pass in source location");
590 mlir::Type fieldType,
593 cir::PointerType fieldPtr =
600 rec.getElementOffset(
cgm.getDataLayout().layout,
index));
608 cgm.getTypes().getCIRGenRecordLayout(field->
getParent());
618 addr = builder.createElementBitCast(loc, addr, info.storageType);
641 if (
auto *classDecl = dyn_cast<CXXRecordDecl>(rec)) {
642 if (
cgm.getCodeGenOpts().StrictVTablePointers &&
643 classDecl->isDynamicClass()) {
645 "emitLValueForField: strict vtable for dynamic class");
651 llvm::StringRef fieldName = field->
getName();
653 if (
cgm.lambdaFieldToName.count(field))
654 fieldName =
cgm.lambdaFieldToName[field];
661 cgm.getTypes().getCIRGenRecordLayout(field->
getParent());
691 if (field->
hasAttr<AnnotateAttr>()) {
702 "emitLValueForField: __weak attribute");
718 cgm.getTypes().getCIRGenRecordLayout(field->
getParent());
744 ty = atomicTy->getValueType();
747 cgm.errorNYI(
"emitToMemory: ConstantMatrixBoolType");
758 ty = atomicTy->getValueType();
761 cgm.errorNYI(
"emitFromMemory: PackedVectorBoolType");
777 bool isNontemporal) {
784 if (clangVecTy->getNumElements() == 3 && !
getLangOpts().PreserveVec3Type)
786 "emitLoadOfScalar Vec3 & PreserveVec3Type disabled");
794 if (mlir::isa<cir::VoidType>(eltTy))
795 cgm.errorNYI(loc,
"emitLoadOfScalar: void type");
800 builder.createLoad(
getLoc(loc), addr, isVolatile, isNontemporal);
823 loc,
"emitLoadOfMatrixLValue: HLSL & hlsl_constant address space");
847 const mlir::Value load =
859 const mlir::Location mlirLoc =
getLoc(loc);
860 const mlir::Value matrix =
866 cgm.errorNYI(loc,
"emitLoadOfLValue");
871 const mlir::ArrayAttr elts) {
872 auto elt = mlir::cast<mlir::IntegerAttr>(elts[idx]);
885 !mlir::isa<cir::VectorType, cir::MatrixType>(vec.getType())) {
886 auto dstTy = cir::VectorType::get(
887 vec.getType(), llvm::ElementCount::get(1,
false));
888 cir::ConstantOp poison =
889 builder.getConstant(loc, cir::PoisonAttr::get(dstTy));
890 vec = builder.createInsertElement(loc, poison, vec, 0);
893 assert((mlir::isa<cir::VectorType, cir::MatrixType>(vec.getType())) &&
894 "ExtVecElement with non vector or matrix type on non-HLSL mode");
903 cir::ConstantOp
index =
904 builder.getConstInt(loc, builder.getSInt64Ty(), indexValue);
905 if (mlir::isa<cir::VectorType>(vec.getType()))
908 cir::ConstantOp columnIdx =
909 builder.getConstInt(loc, builder.getSInt64Ty(), 0);
910 mlir::Value element =
911 cir::MatrixExtractOp::create(builder, loc, vec,
index, columnIdx);
917 for (
auto i : llvm::seq<unsigned>(0, exprVecTy->getNumElements()))
920 cir::VecShuffleOp resultVec = builder.createVecShuffle(loc, vec, mask);
922 cgm.errorNYI(loc,
"emitLoadOfExtVectorElementLValue: ExtVectorBoolType");
932 "unexpected binary operator opcode");
947 memberPtrTy, &baseInfo);
949 return makeAddrLValue(memberAddr, memberPtrTy->getPointeeType(), baseInfo);
954 mlir::Location loc) {
957 mlir::Type vectorElementTy =
cgm.getTypes().convertType(elementTy);
963 mlir::Value idxValue =
964 builder.getConstInt(loc, mlir::cast<cir::IntType>(
ptrDiffTy), idx);
966 mlir::Value elementValue = builder.getArrayElement(
967 loc, loc, castToPointerElement.
getPointer(), vectorElementTy, idxValue,
973 return Address(elementValue, vectorElementTy, alignment);
982 mlir::Value thisValue) {
990 mlir::Value thisValue) {
991 bool hasExplicitObjectParameter =
false;
992 const auto *md = dyn_cast_if_present<CXXMethodDecl>(
curCodeDecl);
995 hasExplicitObjectParameter = md->isExplicitObjectMemberFunction();
996 assert(md->getParent()->isLambda());
997 assert(md->getParent() == field->
getParent());
1000 if (hasExplicitObjectParameter) {
1003 assert(it !=
localDeclMap.end() &&
"explicit parameter not loaded?");
1004 Address addrOfExplicitObject = it->second;
1016 if (thisTy != lambdaTy) {
1020 llvm::make_range(basePathArray.begin(), basePathArray.end()),
1046 mlir::Type fnTy = funcOp.getFunctionType();
1047 mlir::Type ptrTy = cir::PointerType::get(fnTy);
1055 fd->
hasAttr<CUDAGlobalAttr>()) {
1056 auto handle = mlir::cast<cir::GlobalOp>(
1058 cir::PointerType handlePtrTy = cir::PointerType::get(handle.getSymType());
1059 mlir::Value handleAddr = cir::GetGlobalOp::create(
1060 cgf.
getBuilder(), loc, handlePtrTy, handle.getSymName());
1061 addr = cir::CastOp::create(cgf.
getBuilder(), loc, ptrTy,
1062 cir::CastKind::bitcast, handleAddr);
1066 addr = cir::GetGlobalOp::create(cgf.
getBuilder(), loc, ptrTy,
1067 funcOp.getSymName());
1071 ptrTy = cir::PointerType::get(fnTy);
1073 addr = cir::CastOp::create(cgf.
getBuilder(), addr.getLoc(), ptrTy,
1074 cir::CastKind::bitcast, addr);
1121 case cir::GlobalLinkageKind::ExternalLinkage:
1122 case cir::GlobalLinkageKind::LinkOnceODRLinkage:
1123 case cir::GlobalLinkageKind::WeakODRLinkage:
1124 case cir::GlobalLinkageKind::InternalLinkage:
1125 case cir::GlobalLinkageKind::PrivateLinkage:
1137 "should not emit an unevaluated operand");
1139 if (
const auto *vd = dyn_cast<VarDecl>(nd)) {
1141 if (vd->getStorageClass() ==
SC_Register && vd->hasAttr<AsmLabelAttr>() &&
1142 !vd->isLocalVarDecl()) {
1144 "emitDeclRefLValue: Global Named registers access");
1149 (vd->getType()->isReferenceType() ||
1151 vd->getAnyInitializer(vd);
1153 e->
getLocation(), *vd->evaluateValue(), vd->getType());
1154 assert(val &&
"failed to emit constant expression");
1157 if (!vd->getType()->isReferenceType()) {
1159 addr =
cgm.createUnnamedGlobalFrom(*vd, val,
1162 auto ptrTy = mlir::cast<cir::PointerType>(addr.
getPointer().getType());
1163 if (ptrTy.getPointee() != varTy) {
1182 vd = vd->getCanonicalDecl();
1195 "Should not use decl without marking it used!");
1197 if (nd->
hasAttr<WeakRefAttr>())
1200 if (
const auto *vd = dyn_cast<VarDecl>(nd)) {
1210 if (vd->hasLinkage() || vd->isStaticDataMember())
1218 addr = iter->second;
1220 }
else if (vd->isStaticLocal()) {
1224 cgm.getOrCreateStaticVarDecl(*vd,
cgm.getCIRLinkageVarDefinition(vd));
1225 mlir::Value getGlobVal = builder.createGetGlobal(var);
1226 auto getGlob = getGlobVal.getDefiningOp<cir::GetGlobalOp>();
1227 getGlob.setStaticLocal(var.getDynamicInitGuard().has_value());
1229 addr =
Address(
cgm.castGlobalToDeclAddrSpace(getGlob, *vd),
1233 llvm_unreachable(
"DeclRefExpr for Decl not entered in localDeclMap?");
1245 assert((vd->isStaticLocal() ||
symbolTable.count(vd)) &&
1246 "non-static locals should be already mapped");
1251 if (
const auto *bd = dyn_cast<BindingDecl>(nd)) {
1259 if (
const auto *fd = dyn_cast<FunctionDecl>(nd)) {
1263 if (
getContext().getTargetInfo().allowDebugInfoForExternalRef())
1270 "emitDeclRefLValue: unhandled MS Guid Decl");
1272 if (
const auto *tpo = dyn_cast<TemplateParamObjectDecl>(nd)) {
1273 CharUnits alignment =
cgm.getNaturalTypeAlignment(tpo->getType());
1274 cir::GetGlobalOp atpo =
1275 builder.createGetGlobal(
cgm.getAddrOfTemplateParamObject(tpo));
1277 "Do an address space conversion if necessary");
1284 llvm_unreachable(
"Unhandled DeclRefExpr");
1294 "evaluateExprAsBool: member pointer type");
1310 if (op == UO_Extension)
1316 assert(!t.
isNull() &&
"CodeGenFunction::EmitUnaryOpLValue: Illegal type");
1336 assert(lv.
isSimple() &&
"real/imag on non-ordinary l-value");
1351 ? builder.createComplexRealPtr(loc, lv.
getAddress())
1352 : builder.createComplexImagPtr(loc, lv.
getAddress());
1362 assert(e->
isPrefix() &&
"Prefix operator in unexpected state!");
1372 llvm_unreachable(
"UnaryOperator extension should be handled above!");
1381 llvm_unreachable(
"UnaryOperator of non-lvalue kind!");
1383 llvm_unreachable(
"Unknown unary operator kind!");
1391 const auto *
castExpr = dyn_cast<CastExpr>(e);
1405 if (
auto constantOp = idx.getDefiningOp<cir::ConstantOp>())
1406 return constantOp.getValueAttr<cir::IntAttr>();
1415 const CharUnits offset = constantIdx.getValue().getZExtValue() * eltSize;
1423 mlir::Location beginLoc,
1424 mlir::Location endLoc, mlir::Value ptr,
1425 mlir::Type eltTy, mlir::Value idx,
1436 mlir::Location beginLoc,
1437 mlir::Location endLoc,
Address addr,
1439 mlir::Location loc,
bool shouldDecay) {
1454 const mlir::Value eltPtr =
1458 return Address(eltPtr, elementType, eltAlign);
1474 auto emitIdxAfterBase = [&, idxPre](
bool promote) -> mlir::Value {
1475 mlir::Value idx = idxPre;
1477 assert(e->
getRHS() == e->
getIdx() &&
"index was neither LHS nor RHS");
1487 mlir::Type desiredIdxTy =
1492 if (idx.getType() != desiredIdxTy) {
1493 cir::CastKind
kind = mlir::isa<cir::BoolType>(idx.getType())
1494 ? cir::CastKind::bool_to_int
1495 : cir::CastKind::integral;
1496 idx = builder.createOrFold<cir::CastOp>(idx.getLoc(), desiredIdxTy,
1505 idxPre = mlir::Value();
1512 const mlir::Value idx = emitIdxAfterBase(
false);
1527 const mlir::Value idx = emitIdxAfterBase(
true);
1545 mlir::Value idx = emitIdxAfterBase(
true);
1549 idx = builder.createIntCast(idx, numElements.getType());
1558 idx = builder.createMul(
cgm.getLoc(e->
getExprLoc()), idx, numElements,
1571 if (
const auto *ase = dyn_cast<ArraySubscriptExpr>(array))
1575 mlir::Value idx = emitIdxAfterBase(
true);
1579 *
this,
cgm.getLoc(array->getBeginLoc()),
cgm.getLoc(array->getEndLoc()),
1594 "The base must be a pointer");
1598 const mlir::Value idx = emitIdxAfterBase(
true);
1616 "incomplete matrix subscript expressions should be rejected in Sema");
1623 "emitMatrixSubscriptExpr: row-major matrix");
1639 const auto *clangPtrTy =
1641 base =
makeAddrLValue(ptr, clangPtrTy->getPointeeType(), baseInfo);
1642 base.getQuals().removeObjCGCAttr();
1651 "Result must be a vector");
1659 "emitExtVectorElementExpr: ExtVectorBoolType & !HLSL");
1662 builder.createStore(vec.getLoc(), vec, vecMem);
1675 mlir::ArrayAttr elts = builder.getI64ArrayAttr(attrElts);
1685 assert(base.
isExtVectorElt() &&
"Can only subscript lvalue vec elts here!");
1688 for (
unsigned idx : indices)
1690 mlir::ArrayAttr cv = builder.getI64ArrayAttr(elts);
1717 const auto *matrixTy =
1720 for (uint32_t &idx : indices) {
1722 unsigned row = idx / numCols;
1723 unsigned column = idx % numCols;
1725 idx = matrixTy->getColumnMajorFlattenedIndex(row, column);
1735 "emitMatrixElementExpr simple & HLSL address space hlsl_constant");
1740 mlir::ArrayAttr elts = builder.getI64ArrayAttr(attrElts);
1750 llvm::StringRef name) {
1751 cir::GlobalOp globalOp =
cgm.getGlobalForStringLiteral(e, name);
1752 assert(globalOp.getAlignment() &&
"expected alignment for string literal");
1753 unsigned align = *(globalOp.getAlignment());
1756 mlir::ptr::MemorySpaceAttrInterface destAS =
1757 cgm.getTypes().getPointerAddressSpace(e->
getType());
1758 if (mlir::cast<cir::PointerType>(addr.getType()).getAddrSpace() != destAS)
1760 addr, builder.getPointerTo(globalOp.getSymType(), destAS));
1776 case CK_LValueToRValueBitCast:
1777 case CK_ArrayToPointerDecay:
1778 case CK_FunctionToPointerDecay:
1779 case CK_NullToMemberPointer:
1780 case CK_NullToPointer:
1781 case CK_IntegralToPointer:
1782 case CK_PointerToIntegral:
1783 case CK_PointerToBoolean:
1784 case CK_IntegralCast:
1785 case CK_BooleanToSignedIntegral:
1786 case CK_IntegralToBoolean:
1787 case CK_IntegralToFloating:
1788 case CK_FloatingToIntegral:
1789 case CK_FloatingToBoolean:
1790 case CK_FloatingCast:
1791 case CK_FloatingRealToComplex:
1792 case CK_FloatingComplexToReal:
1793 case CK_FloatingComplexToBoolean:
1794 case CK_FloatingComplexCast:
1795 case CK_FloatingComplexToIntegralComplex:
1796 case CK_IntegralRealToComplex:
1797 case CK_IntegralComplexToReal:
1798 case CK_IntegralComplexToBoolean:
1799 case CK_IntegralComplexCast:
1800 case CK_IntegralComplexToFloatingComplex:
1801 case CK_DerivedToBaseMemberPointer:
1802 case CK_BaseToDerivedMemberPointer:
1803 case CK_MemberPointerToBoolean:
1804 case CK_ReinterpretMemberPointer:
1805 case CK_AnyPointerToBlockPointerCast:
1806 case CK_ARCProduceObject:
1807 case CK_ARCConsumeObject:
1808 case CK_ARCReclaimReturnedObject:
1809 case CK_ARCExtendBlockObject:
1810 case CK_CopyAndAutoreleaseBlockObject:
1811 case CK_IntToOCLSampler:
1812 case CK_FloatingToFixedPoint:
1813 case CK_FixedPointToFloating:
1814 case CK_FixedPointCast:
1815 case CK_FixedPointToBoolean:
1816 case CK_FixedPointToIntegral:
1817 case CK_IntegralToFixedPoint:
1819 case CK_HLSLVectorTruncation:
1820 case CK_HLSLMatrixTruncation:
1821 case CK_HLSLArrayRValue:
1822 case CK_HLSLElementwiseCast:
1823 case CK_HLSLAggregateSplatCast:
1824 llvm_unreachable(
"unexpected cast lvalue");
1827 llvm_unreachable(
"dependent cast kind in IR gen!");
1829 case CK_BuiltinFnToFnPtr:
1830 llvm_unreachable(
"builtin functions are handled elsewhere");
1843 case CK_ConstructorConversion:
1844 case CK_UserDefinedConversion:
1845 case CK_CPointerToObjCPointerCast:
1846 case CK_BlockPointerToObjCPointerCast:
1847 case CK_LValueToRValue:
1850 case CK_NonAtomicToAtomic:
1851 case CK_AtomicToNonAtomic:
1852 case CK_ObjCObjectLValueCast:
1853 case CK_VectorSplat: {
1857 case CK_AddressSpaceConversion: {
1868 case CK_LValueBitCast: {
1872 cgm.emitExplicitCastExprType(ce,
this);
1896 auto toTy = dyn_cast<cir::ArrayType>(ty);
1897 if (!fromTy || !toTy ||
1898 fromTy.getElementType() != toTy.getElementType() ||
1899 toTy.getSize() != 0)
1901 "emitCastLValue NoOp not array-shrink case");
1911 case CK_UncheckedDerivedToBase:
1912 case CK_DerivedToBase: {
1930 case CK_BaseToDerived: {
1946 case CK_ZeroToOCLOpaqueType:
1947 llvm_unreachable(
"NULL to OpenCL opaque type lvalue cast is not valid");
1950 llvm_unreachable(
"Invalid cast kind");
1987 if (
auto *field = dyn_cast<FieldDecl>(nd)) {
2001 if (
const auto *fd = dyn_cast<FunctionDecl>(nd))
2004 llvm_unreachable(
"Unhandled member declaration!");
2034 llvm_unreachable(
"bad evaluation kind");
2039 const Expr *inner) {
2050 cir::AllocaOp extDeclAlloca;
2054 extDeclAlloca = extDeclAddrIter->second.getUnderlyingAllocaOp();
2056 mlir::OpBuilder::InsertPoint ip;
2057 if (extDeclAlloca) {
2058 ip = {extDeclAlloca->getBlock(), extDeclAlloca->getIterator()};
2076 assert(addr.getAlignment().has_value() &&
2077 "This should always have an alignment");
2083 llvm_unreachable(
"temporary can't have dynamic storage duration");
2085 llvm_unreachable(
"unknown storage duration");
2109 if (
const auto *classDecl =
2113 referenceTemporaryDtor = classDecl->getDestructor();
2115 if (!referenceTemporaryDtor)
2124 auto registerOp = cir::RegisterExitDtorOp::create(
2125 builder, loc, globalOp.getSymNameAttr().getValue());
2126 mlir::OpBuilder::InsertionGuard guard(builder);
2127 builder.setInsertionPointToStart(
2128 builder.createBlock(®isterOp.getBody()));
2139 builder.
createCallOp(loc, dtorFn, mlir::ValueRange{tempAddr},
2141 dtorFn.getCallingConv());
2143 cir::YieldOp::create(builder, loc);
2160 llvm_unreachable(
"temporary cannot have dynamic storage duration");
2170 "Reference should never be pseudo-strong!");
2178 "emitMaterializeTemporaryExpr: ObjCLifetime");
2186 for (
const Expr *ignored : commaLHSs)
2191 "emitMaterializeTemporaryExpr: OpaqueValueExpr");
2197 cir::GlobalOp var =
nullptr;
2198 if (
auto getGlobalOp =
object.getPointer().getDefiningOp<cir::GetGlobalOp>())
2199 var = mlir::dyn_cast_or_null<cir::GlobalOp>(
2200 cgm.getGlobalValue(getGlobalOp.getName()));
2203 if (!var.getInitialValue().has_value()) {
2204 var.setInitialValueAttr(builder.getZeroInitAttr(var.getSymType()));
2218 switch (adjustment.Kind) {
2222 adjustment.DerivedToBase.BasePath->path(),
2229 "materialized temporary field is not a simple lvalue");
2236 e,
object, ptr, adjustment.Ptr.MPT,
nullptr);
2253 assert(e->
isUnique() &&
"LValue for a nonunique OVE hasn't been emitted");
2265 assert(e->
isUnique() &&
"RValue for a nonunique OVE hasn't been emitted");
2279 ".compoundliteral");
2290 "emitCompoundLiteralLValue: non C++ DestructedType");
2305 "Can't have a scalar return unless the return type is a "
2323 "binding l-value to type which needs a temporary");
2339 assert(e->
getOpcode() == BO_Assign &&
"unexpected binary l-value");
2375 llvm_unreachable(
"bad evaluation kind");
2381 bool ignoreResult) {
2388 if (!ignoreResult && aggSlot.
isIgnored())
2395 llvm_unreachable(
"bad evaluation kind");
2401 auto noBuiltins = fn->getAttrOfType<mlir::ArrayAttr>(
2402 cir::CIRDialect::getNoBuiltinsAttrName());
2405 return noBuiltins.empty() ||
2406 llvm::is_contained(noBuiltins,
2407 mlir::StringAttr::get(fn.getContext(), name));
2410CIRGenCallee CIRGenFunction::emitDirectCallee(
const GlobalDecl &gd) {
2413 if (
unsigned builtinID = fd->getBuiltinID()) {
2414 StringRef ident =
cgm.getMangledName(gd);
2415 std::string fdInlineName = (ident +
".inline").str();
2417 bool isPredefinedLibFunction =
2418 cgm.getASTContext().BuiltinInfo.isPredefinedLibFunction(builtinID);
2419 auto fn = dyn_cast<cir::FuncOp>(
curFn);
2424 if ((!fn || fn.getName() != fdInlineName) &&
2427 mlir::cast_or_null<cir::FuncOp>(
cgm.getGlobalValue(fdInlineName));
2433 mlir::OpBuilder::InsertionGuard guard(builder);
2434 builder.setInsertionPointToStart(
cgm.getModule().getBody());
2436 clone = cir::FuncOp::create(builder, calleeFunc.getLoc(), fdInlineName,
2437 calleeFunc.getFunctionType());
2438 cgm.insertGlobalSymbol(clone);
2439 clone.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
2440 &
cgm.getMLIRContext(), cir::GlobalLinkageKind::InternalLinkage));
2441 clone.setSymVisibility(
"private");
2442 clone.setInlineKind(cir::InlineKind::AlwaysInline);
2453 else if (!isPredefinedLibFunction || !hasAttributeNoBuiltin)
2459 if ((
cgm.getLangOpts().CUDA ||
cgm.getLangOpts().HIP) &&
2460 !
cgm.getLangOpts().CUDAIsDevice && fd->hasAttr<CUDAGlobalAttr>()) {
2461 mlir::Operation *handle =
cgm.getCUDARuntime().getKernelHandle(callee, gd);
2463 mlir::cast<cir::FuncOp>(*
cgm.getCUDARuntime().getKernelStub(handle));
2471 return builder.getConstant(loc, cir::UndefAttr::get(cirTy));
2478 mlir::Location loc = builder.getUnknownLoc();
2485 mlir::Value v = builder.createComplexCreate(loc, undefElem, undefElem);
2500 llvm_unreachable(
"bad evaluation kind");
2510 "Callee must have function pointer type!");
2533 if (
const auto *oce = dyn_cast<CXXOperatorCallExpr>(e)) {
2534 if (
const auto *md =
2535 dyn_cast_if_present<CXXMethodDecl>(oce->getCalleeDecl());
2536 md && md->isStatic()) {
2538 arguments = llvm::drop_begin(arguments, 1);
2542 emitCallArgs(args, dyn_cast<FunctionProtoType>(fnType), arguments,
2546 cgm.getTypes().arrangeFreeFunctionCall(args, fnType);
2568 calleeTy = cir::FuncType::get(calleeTy.getInputs(),
2569 calleeTy.getReturnType(),
false);
2570 auto calleePtrTy = cir::PointerType::get(calleeTy);
2574 if (
auto funcOp = mlir::dyn_cast<cir::FuncOp>(fn)) {
2575 addr = cir::GetGlobalOp::create(
2577 cir::PointerType::get(funcOp.getFunctionType()), funcOp.getSymName());
2579 addr = fn->getResult(0);
2582 fn = builder.createBitcast(addr, calleePtrTy).getDefiningOp();
2598 auto handlePtrTy = mlir::cast<cir::PointerType>(handleAddr.getType());
2599 mlir::Value handleAddrAddr =
2600 builder.createBitcast(handleAddr, cir::PointerType::get(handlePtrTy));
2601 cir::LoadOp stub = builder.createLoad(
2606 cir::CIRCallOpInterface callOp;
2619 if (
const auto *implicitCast = dyn_cast<ImplicitCastExpr>(e)) {
2620 if (implicitCast->getCastKind() == CK_FunctionToPointerDecay ||
2621 implicitCast->getCastKind() == CK_BuiltinFnToFnPtr) {
2622 return emitCallee(implicitCast->getSubExpr());
2630 }
else if (
const auto *declRef = dyn_cast<DeclRefExpr>(e)) {
2632 if (
const auto *funcDecl = dyn_cast<FunctionDecl>(declRef->getDecl()))
2633 return emitDirectCallee(funcDecl);
2634 }
else if (
auto me = dyn_cast<MemberExpr>(e)) {
2635 if (
const auto *fd = dyn_cast<FunctionDecl>(me->getMemberDecl())) {
2637 return emitDirectCallee(fd);
2640 }
else if (
auto *pde = dyn_cast<CXXPseudoDestructorExpr>(e)) {
2645 mlir::Value calleePtr;
2657 if (
const auto *vd =
2662 CIRGenCallee callee(calleeInfo, calleePtr.getDefiningOp());
2670 if (
const auto *ce = dyn_cast<CXXMemberCallExpr>(e))
2681 if (
const auto *operatorCall = dyn_cast<CXXOperatorCallExpr>(e)) {
2682 if (
const auto *md =
2683 dyn_cast_if_present<CXXMethodDecl>(operatorCall->getCalleeDecl());
2684 md && md->isImplicitObjectMemberFunction())
2715 "Array to pointer decay must have array source type!");
2727 assert(mlir::isa<cir::ArrayType>(arrayTy) &&
"expected array");
2738 mlir::Value ptr = builder.maybeBuildArrayDecay(
2756 llvm_unreachable(
"bad evaluation kind");
2763 const Stmt *elseS) {
2765 std::optional<mlir::Location> elseLoc;
2769 mlir::LogicalResult resThen = mlir::success(), resElse = mlir::success();
2772 [&](mlir::OpBuilder &, mlir::Location) {
2773 LexicalScope lexScope{*
this, thenLoc, builder.getInsertionBlock()};
2778 [&](mlir::OpBuilder &, mlir::Location) {
2779 assert(elseLoc &&
"Invalid location for elseS.");
2780 LexicalScope lexScope{*
this, *elseLoc, builder.getInsertionBlock()};
2785 return mlir::LogicalResult::success(resThen.succeeded() &&
2786 resElse.succeeded());
2794 std::optional<mlir::Location> elseLoc) {
2800 ifLocs.push_back(*elseLoc);
2801 mlir::Location loc = mlir::FusedLoc::get(&
getMLIRContext(), ifLocs);
2812 std::optional<mlir::Location> elseLoc) {
2813 cir::IfOp ifOp = cir::IfOp::create(builder, loc, condV, elseLoc.has_value(),
2817 assert((elseLoc.has_value() || ifOp.getElseRegion().empty()) &&
2818 "else region created with no else location");
2819 if (elseLoc.has_value())
2838 Expr *trueExpr = condOp->getTrueExpr();
2839 Expr *falseExpr = condOp->getFalseExpr();
2842 mlir::Value ternaryOpRes =
2843 cir::TernaryOp::create(
2844 builder, loc, condV,
2845 [
this, trueExpr](mlir::OpBuilder &b, mlir::Location loc) {
2847 cir::YieldOp::create(b, loc, lhs);
2850 [
this, falseExpr](mlir::OpBuilder &b, mlir::Location loc) {
2852 cir::YieldOp::create(b, loc, rhs);
2861 cgm.errorNYI(
"NYI");
2875 mlir::Location loc,
CharUnits alignment,
2876 bool insertIntoFnEntryBlock,
2877 mlir::Value arraySize) {
2878 mlir::Block *entryBlock = insertIntoFnEntryBlock
2887 llvm::dyn_cast_if_present<cir::TryOp>(entryBlock->getParentOp())) {
2888 if (auto scopeOp = llvm::dyn_cast<cir::ScopeOp>(tryOp->getParentOp()))
2889 entryBlock = &scopeOp.getScopeRegion().front();
2897 mlir::Location loc,
CharUnits alignment,
2898 mlir::OpBuilder::InsertPoint ip,
2899 mlir::Value arraySize) {
2903 cir::PointerType localVarPtrTy =
2905 mlir::IntegerAttr alignIntAttr =
cgm.
getSize(alignment);
2909 mlir::OpBuilder::InsertionGuard guard(builder);
2910 builder.restoreInsertionPoint(ip);
2912 alignIntAttr, arraySize);
2930 if (md->isStatic()) {
2935 bool hasQualifier = me->hasQualifier();
2937 bool isArrow = me->isArrow();
2938 const Expr *base = me->getBase();
2941 ce, md,
returnValue, hasQualifier, qualifier, isArrow, base);
2958 cgm.errorNYI(loc,
"load of volatile reference");
2984 cir::TrapOp::create(builder, loc);
2986 builder.createBlock(builder.getBlock()->getParent());
2990 bool createNewBlock) {
2992 cir::UnreachableOp::create(builder,
getLoc(loc));
2994 builder.createBlock(builder.getBlock()->getParent());
3001 return builder.createDummyValue(loc, t, alignment);
3010 const Twine &name) {
3016 const Twine &name,
Address *alloca,
3017 mlir::OpBuilder::InsertPoint ip) {
3024 mlir::Location loc,
const Twine &name,
3026 mlir::OpBuilder::InsertPoint ip) {
3029 name,
nullptr, alloca, ip);
3032 cgm.errorNYI(loc,
"createMemTemp constant matrix type");
3042 mlir::Type ty,
CharUnits align, mlir::Location loc,
const Twine &name,
3043 mlir::Value arraySize, mlir::OpBuilder::InsertPoint ip) {
3044 cir::AllocaOp alloca = ip.isSet()
3047 alloca.setAlignmentAttr(
cgm.getSize(align));
3048 return Address(alloca, ty, align);
3052 mlir::Location loc,
const Twine &name,
3053 mlir::Value arraySize,
3055 mlir::OpBuilder::InsertPoint ip) {
3061 Address alloca, mlir::ptr::MemorySpaceAttrInterface destAddrSpace,
3062 mlir::Value arraySize) {
3081 if (srcAddrSpace == destAddrSpace)
3084 mlir::OpBuilder::InsertionGuard guard(builder);
3086 builder.setInsertionPointAfter(allocaOp);
3087 }
else if (!arraySize) {
3089 builder.restoreInsertionPoint(builder.getBestAllocaInsertPoint(entryBlock));
3092 mlir::Type destPtrTy =
3102 mlir::Type ty, mlir::ptr::MemorySpaceAttrInterface destAddrSpace,
3103 CharUnits align, mlir::Location loc,
const Twine &name,
3104 mlir::Value arraySize,
Address *allocaAddr,
3105 mlir::OpBuilder::InsertPoint ip) {
3109 *allocaAddr = alloca;
3119 mlir::Value arraySize,
3120 bool insertIntoFnEntryBlock) {
3122 insertIntoFnEntryBlock, arraySize)
3130 mlir::OpBuilder::InsertPoint ip,
3131 mlir::Value arraySize) {
3132 assert(ip.isSet() &&
"Insertion point is not set");
3133 return mlir::cast<cir::AllocaOp>(
3144 const Twine &name) {
3164 else if (
const auto *var = dyn_cast<VarDecl>(value))
3174 bool resultIsReference;
3180 resultIsReference =
false;
3184 resultIsReference =
true;
3185 resultType = value->
getType();
3203 auto *md = dyn_cast_or_null<CXXMethodDecl>(
curCodeDecl);
3204 if (
isLambdaMethod(md) && md->getOverloadedOperator() == OO_Call) {
3207 if (
const auto *vd = dyn_cast<const VarDecl>(d)) {
3208 if (!vd->hasAttr<CUDADeviceAttr>())
3220 mlir::TypedAttr cstToEmit = mlir::dyn_cast_if_present<mlir::TypedAttr>(c);
3228 if (resultIsReference)
3243 assert(constant &&
"not a constant");
3253 assert(sl !=
nullptr &&
"No StringLiteral name in PredefinedExpr");
3255 StringRef fnName = fn.getName();
3256 fnName.consume_front(
"\01");
3257 std::array<StringRef, 2> nameItems = {
3259 std::string gvName = llvm::join(nameItems,
".");
3274std::optional<LValue> handleConditionalOperatorLValueSimpleCase(
3277 llvm::APSInt condExprVal;
3279 return std::nullopt;
3282 if (!condExprVal.getBoolValue())
3283 std::swap(live, dead);
3286 return std::nullopt;
3293 if (
auto *throwExpr = dyn_cast<CXXThrowExpr>(live->
IgnoreParens())) {
3297 mlir::Type elemTy = cgf.
convertType(dead->getType());
3298 mlir::Value undefPtr =
3300 cgf.
getLoc(throwExpr->getSourceRange()));
3310static std::optional<LValue> emitLValueOrThrowExpression(
CIRGenFunction &cgf,
3311 const Expr *operand) {
3312 if (
auto *throwExpr = dyn_cast<CXXThrowExpr>(operand->
IgnoreParens())) {
3314 return std::nullopt;
3323template <
typename FuncTy>
3326 const FuncTy &branchGenFunc) {
3335 auto emitBranch = [&](mlir::OpBuilder &b, mlir::Location loc,
3336 const Expr *
expr, std::optional<LValue> &resultLV) {
3340 mlir::Value resultPtr;
3347 resultLV = branchGenFunc(*
this,
expr);
3348 resultPtr = resultLV ? resultLV->getPointer() : mlir::Value();
3356 cir::YieldOp::create(b, loc, resultPtr);
3359 cir::TernaryOp ternary = cir::TernaryOp::create(
3360 builder, loc, condV,
3362 [&](mlir::OpBuilder &b, mlir::Location loc) {
3366 [&](mlir::OpBuilder &b, mlir::Location loc) {
3375 info.result = ternary.getResult();
3381 if (!
expr->isGLValue()) {
3384 "Unexpected conditional operator!");
3389 if (std::optional<LValue> res =
3390 handleConditionalOperatorLValueSimpleCase(*
this,
expr))
3395 return emitLValueOrThrowExpression(cgf, e);
3398 if ((info.lhs && !info.lhs->isSimple()) ||
3399 (info.rhs && !info.rhs->isSimple())) {
3400 cgm.errorNYI(
expr->getSourceRange(),
3401 "unsupported conditional operator with non-simple lvalue");
3405 if (info.lhs && info.rhs) {
3406 Address lhsAddr = info.lhs->getAddress();
3407 Address rhsAddr = info.rhs->getAddress();
3411 std::max(info.lhs->getBaseInfo().getAlignmentSource(),
3412 info.rhs->getBaseInfo().getAlignmentSource());
3417 assert((info.lhs || info.rhs) &&
3418 "both operands of glvalue conditional are throw-expressions?");
3422 const LValue &survivingLV = info.lhs ? *info.lhs : *info.rhs;
3434 if (!
cgm.getLangOpts().MSVolatile)
3437 cgm.errorNYI(
"LValueSuitableForInlineAtomic LangOpts MSVolatile");
This file provides some common utility functions for processing Lambda related AST Constructs.
Provides definitions for the various language-specific address spaces.
llvm::function_ref< void(mlir::OpBuilder &, mlir::Location)> BuilderCallbackRef
static std::optional< LValue > emitDeclTargetVarDeclLValue(CIRGenFunction &cgf, const Expr *e, const VarDecl *vd)
static Address createReferenceTemporary(CIRGenFunction &cgf, const MaterializeTemporaryExpr *m, const Expr *inner)
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 RValue emitLoadOfMatrixLValue(LValue lv, SourceLocation loc, CIRGenFunction &cgf)
static cir::IntAttr getConstantIndexOrNull(mlir::Value idx)
static bool hasNoBuiltinAttr(cir::FuncOp fn, StringRef name)
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 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 Address emitAddrOfZeroSizeField(CIRGenFunction &cgf, Address base, const FieldDecl *field)
Get the address of a zero-sized field within a record.
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines AST-level helper utilities for matrix types.
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
cir::ConstantOp getConstant(mlir::Location loc, mlir::TypedAttr attr)
cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base, mlir::Value stride)
static OpBuilder::InsertPoint getBestAllocaInsertPoint(mlir::Block *block)
cir::PointerType getPointerTo(mlir::Type ty)
cir::CallOp createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee, mlir::Type returnType, mlir::ValueRange operands, llvm::ArrayRef< mlir::NamedAttribute > attrs={}, llvm::ArrayRef< mlir::NamedAttrList > argAttrs={}, llvm::ArrayRef< mlir::NamedAttribute > resAttrs={}, cir::CallingConv callingConv=cir::CallingConv::C)
cir::ConstantOp getNullPtr(mlir::Type ty, mlir::Location loc)
mlir::Value createPtrBitcast(mlir::Value src, mlir::Type newPointeeTy)
cir::GetGlobalOp createGetGlobal(mlir::Location loc, cir::GlobalOp global, bool threadLocal=false)
mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType, llvm::StringRef name, mlir::IntegerAttr alignment, mlir::Value dynAllocSize)
mlir::Value createBitcast(mlir::Value src, mlir::Type newTy)
llvm::TypeSize getTypeSizeInBits(mlir::Type ty) const
llvm::ArrayRef< mlir::Type > getMembers() const
uint64_t getElementOffset(const mlir::DataLayout &dataLayout, unsigned idx) const
const LValueBase getLValueBase() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
uint64_t getFieldOffset(const ValueDecl *FD) const
Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
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.
llvm::DenseMap< const CXXMethodDecl *, CXXCastPath > LambdaCastPaths
For capturing lambdas with an explicit object parameter whose type is derived from the lambda 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
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
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".
Address withPointer(mlir::Value newPtr) const
Return address with different pointer, but same element type and alignment.
mlir::ptr::MemorySpaceAttrInterface getAddressSpace() const
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
cir::AllocaOp getUnderlyingAllocaOp() const
Return the underlying alloca for this address, if any.
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)
Address getAddress() const
void setExternallyDestructed(bool destructed=true)
static AggValueSlot ignored()
Returns an aggregate value slot indicating that the aggregate value is being ignored.
cir::IntType getUInt8Ty()
cir::ConstantOp getUInt64(uint64_t c, mlir::Location loc)
Address createGetMember(mlir::Location loc, Address base, llvm::StringRef name, unsigned index, const cir::CIRDataLayout &layout)
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.
virtual mlir::Operation * getKernelHandle(cir::FuncOp fn, GlobalDecl gd)=0
Abstract information about a function or function prototype.
clang::GlobalDecl getCalleeDecl() const
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
CIRGenCalleeInfo getAbstractInfo() 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 forReference(mlir::TypedAttr c)
static ConstantEmission forValue(mlir::TypedAttr c)
LValue getReferenceLValue(CIRGenFunction &cgf, const Expr *refExpr) const
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)
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
void forceCleanup(ArrayRef< mlir::Value * > valuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
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,...
mlir::Type convertType(clang::QualType t)
LValue emitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *e)
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)
bool isInConditionalBranch() const
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,...
cir::IfOp emitIfOnBoolValue(mlir::Value condV, mlir::Location loc, BuilderCallbackRef thenBuilder, mlir::Location thenLoc, BuilderCallbackRef elseBuilder, std::optional< mlir::Location > elseLoc={})
Build the cir.if for an already-emitted condition value.
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).
void emitStoreThroughExtVectorComponentLValue(RValue src, LValue dst)
CodeGenUtils::EvaluationOrder EvaluationOrder
void emitCallArgs(CallArgList &args, PrototypeWrapper prototype, llvm::iterator_range< clang::CallExpr::const_arg_iterator > argRange, AbstractCallee callee=AbstractCallee(), unsigned paramsToSkip=0, EvaluationOrder order=EvaluationOrder::Default)
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)
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)
Address maybeCastStackAddressSpace(Address alloca, mlir::ptr::MemorySpaceAttrInterface destAddrSpace, mlir::Value arraySize=nullptr)
RValue emitAtomicLoad(LValue lvalue, SourceLocation loc, AggValueSlot slot=AggValueSlot::ignored())
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)
mlir::Value emitComplexPrePostIncDec(const UnaryOperator *e, LValue lv)
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)
void emitCXXConstructExpr(const clang::CXXConstructExpr *e, AggValueSlot dest)
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)
const CallExpr * mustTailCall
std::string getCounterAggTmpAsString()
LValue emitUnaryOpLValue(const clang::UnaryOperator *e)
LValue emitMatrixSubscriptExpr(const MatrixSubscriptExpr *e)
RValue emitLoadOfBitfieldLValue(LValue lv, SourceLocation 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)
void emitCXXTemporary(const CXXTemporary *temporary, QualType tempType, Address ptr)
Emits all the code to cause the given temporary to be cleaned up.
LValue emitStringLiteralLValue(const StringLiteral *e, llvm::StringRef name=".str")
mlir::Value getUndefConstant(mlir::Location loc, mlir::Type cirTy)
Return a CIR constant for an undefined value of cirTy.
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.
void pushLifetimeExtendedDestroy(CleanupKind kind, Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray, const clang::ValueDecl *extendingDecl)
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)
void emitDestroy(Address addr, QualType type, Destroyer *destroyer)
Immediately perform the destruction of the given object.
CIRGenModule & getCIRGenModule()
mlir::MLIRContext & getMLIRContext()
std::optional< SourceRange > currSrcLoc
Use to track source locations across nested visitor traversals.
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...
mlir::Value emitScalarPrePostIncDec(const UnaryOperator *e, LValue lv)
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.
RValue emitCall(const CIRGenFunctionInfo &funcInfo, const CIRGenCallee &callee, ReturnValueSlot returnValue, const CallArgList &args, cir::CIRCallOpInterface *callOp, bool isMustTail, SourceRange clangLoc)
void emitCXXThrowExpr(const CXXThrowExpr *e)
LValue makeAddrLValue(Address addr, QualType ty, AlignmentSource source=AlignmentSource::Type)
LValue emitMatrixElementExpr(const MatrixElementExpr *e)
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)
void terminateStructuredRegionBody(mlir::Region &r, mlir::Location loc)
Address createMemTempWithoutCast(QualType t, mlir::Location loc, const Twine &name="tmp")
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...
LValue emitCXXConstructLValue(const CXXConstructExpr *e)
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)
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.
cir::GlobalLinkageKind getCIRLinkageVarDefinition(const VarDecl *vd)
CIRGenCUDARuntime & getCUDARuntime()
mlir::IntegerAttr getSize(CharUnits size)
CIRGenBuilderTy & getBuilder()
std::pair< cir::FuncType, cir::FuncOp > getAddrAndTypeOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
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.
const clang::LangOptions & getLangOpts() const
mlir::Location getLoc(clang::SourceLocation cLoc)
Helpers to convert the presumed location of Clang's SourceLocation to an MLIR Location.
CIRGenOpenMPRuntime & getOpenMPRuntime()
bool hasRequiresUnifiedSharedMemory() const
Return whether unified shared memory is required.
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.
bool hasCIRField(const clang::FieldDecl *fd) const
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
mlir::Value getVectorPointer() 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
Address getMatrixAddress() const
void setNontemporal(bool v)
bool isVolatileQualified() const
Address getVectorAddress() const
clang::CharUnits getAlignment() const
LValueBaseInfo getBaseInfo() const
mlir::Value getMatrixColumnIdx() const
bool isNontemporal() const
static LValue makeMatrixElt(Address matAddress, mlir::Value rowIdx, mlir::Value colIdx, clang::QualType t, LValueBaseInfo baseInfo)
const CIRGenBitFieldInfo & getBitFieldInfo() const
Address getBitFieldAddress() const
Address getExtVectorAddress() const
mlir::Value getMatrixRowIdx() const
This trivial value class is used to represent the result of an expression that is evaluated.
Address getAggregateAddress() const
Return the value of the address of the aggregate.
static RValue get(mlir::Value v)
static RValue getAggregate(Address addr, bool isVolatile=false)
Convert an Address to an RValue.
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 binding an expression to a temporary.
CXXTemporary * getTemporary()
const Expr * getSubExpr() const
Represents a call to a C++ constructor.
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 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]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
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.
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?
bool isZero() const
Test whether the quantity equals zero.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits 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)
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 ?
Represents a concrete matrix type with constant number of rows and columns.
unsigned getNumColumns() const
Returns the number of columns in the matrix.
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
Decl - This represents one declaration (or definition), e.g.
SourceLocation getLocation() const
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
DeclContext * getDeclContext()
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
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 EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...
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 isPotentiallyOverlapping() const
Determine if this field is of potentially-overlapping class type, that is, subobject with the [[no_un...
Represents a function declaration or definition.
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.
void getEncodedElementAccess(SmallVectorImpl< uint32_t > &Elts) const
getEncodedElementAccess - Encode the elements accessed into an llvm aggregate Constant of ConstantInt...
MatrixSubscriptExpr - Matrix subscript expression for the MatrixType extension.
bool isIncomplete() const
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 getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
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.
bool isValid() const
Return true if this is a valid SourceLocation object.
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.
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
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 isConstantMatrixBoolType() 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>'.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
Expr * getSubExpr() const
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.
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_None
Not a TLS variable.
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.
mlir::ptr::MemorySpaceAttrInterface normalizeDefaultAddressSpace(mlir::ptr::MemorySpaceAttrInterface addrSpace)
Normalize LangAddressSpace::Default to null (empty attribute).
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...
bool isAAPCS(const TargetInfo &TargetInfo)
Helper method to check if the underlying ABI is AAPCS.
QualType getFixedSizeElementType(const ASTContext &Ctx, const VariableArrayType *VLA)
Strip off the variably-modified array types wrapping VLA and return the first element type that has a...
bool onlyHasInlineBuiltinDeclaration(const FunctionDecl *FD)
Detect the unusual situation where an inline version of a builtin is shadowed by a non-inline version...
EvaluationOrder getCallArgEvaluationOrder(const CallExpr *E)
Returns the argument evaluation order the language requires for the given call.
ConstantEmissionKind checkVarTypeForConstantEmission(QualType Type)
Can we constant-emit a load of a reference to a variable of the given type?
bool isEmptyFieldForLayout(const ASTContext &Ctx, const FieldDecl *FD)
Return true iff the field is "empty", that is, either a zero-width bit-field or an isEmptyRecordForLa...
ConstantEmissionKind
How a reference to a variable can be emitted as a constant.
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.
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
QualType pointeeType(QualType T)
bool isMatrixRowMajor(const LangOptions &LangOpts, QualType T)
Returns true if matrices of T should be laid out in row-major order.
@ 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.
@ Dtor_Complete
Complete object dtor.
SmallVector< CXXBaseSpecifier *, 4 > CXXCastPath
A simple array of base specifiers.
U cast(CodeGen::Address addr)
bool isLambdaMethod(const DeclContext *DC)
@ 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 openMPNontemporalDecl()
static bool setObjCGCLValueClass()
static bool cirgenABIInfo()
static bool opLoadStoreObjC()
static bool pointerAuthentication()
static bool insertBuiltinUnpredictable()
static bool matrixTypeIndexAssumption()
static bool shouldReverseUnaryCondOnBoolExpr()
static bool addressIsKnownNonNull()
static bool openMPLastprivateConditional()
static bool astVarDeclInterface()
static bool cgCapturedStmtInfo()
static bool opAllocaEscapeByReference()
static bool opCallFnInfoOpts()
static bool generateDebugInfo()
static bool incrementProfileCounter()
Record with information about how a bitfield should be accessed.
Represents a scope, including function bodies, compound statements, and the substatements of if/while...
clang::CharUnits getPointerAlign() const
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.
An adjustment to be made to the temporary created when emitting a reference binding,...
@ DerivedToBaseAdjustment
@ MemberPointerAdjustment