19#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
20#include "mlir/IR/BuiltinAttributes.h"
21#include "mlir/IR/Value.h"
69 llvm::StringRef fieldName,
70 unsigned fieldIndex) {
89 auto fieldPtr = cir::PointerType::get(fieldType);
90 bool needsBitcast =
false;
94 fieldPtr = cir::PointerType::get(memberType);
101 mlir::Value addr = builder.createGetMember(loc, fieldPtr, base.
getPointer(),
102 fieldName, fieldIndex);
108 addr = builder.createPtrBitcast(addr, fieldType);
120 assert(
expr->getType()->isPointerType() ||
121 expr->getType()->isObjCObjectPointerType());
125 if (
auto const *ce = dyn_cast<CastExpr>(
expr)) {
126 if (
const auto *ece = dyn_cast<ExplicitCastExpr>(ce))
127 cgm.emitExplicitCastExprType(ece);
129 switch (ce->getCastKind()) {
133 case CK_AddressSpaceConversion: {
134 if (
const auto *ptrTy =
135 ce->getSubExpr()->getType()->getAs<
PointerType>()) {
136 if (ptrTy->getPointeeType()->isVoidType())
144 *baseInfo = innerBaseInfo;
149 const QualType pointeeType =
expr->getType()->getPointeeType();
151 cgm.getNaturalTypeAlignment(pointeeType, &targetTypeBaseInfo);
164 const mlir::Type eltTy =
176 case CK_ArrayToPointerDecay:
179 case CK_UncheckedDerivedToBase:
180 case CK_DerivedToBase: {
185 ce->getSubExpr()->getType()->getPointeeCXXRecordDecl();
191 case CK_AnyPointerToBlockPointerCast:
192 case CK_BaseToDerived:
193 case CK_BaseToDerivedMemberPointer:
194 case CK_BlockPointerToObjCPointerCast:
195 case CK_BuiltinFnToFnPtr:
196 case CK_CPointerToObjCPointerCast:
197 case CK_DerivedToBaseMemberPointer:
199 case CK_FunctionToPointerDecay:
200 case CK_IntegralToPointer:
201 case CK_LValueToRValue:
202 case CK_LValueToRValueBitCast:
203 case CK_NullToMemberPointer:
204 case CK_NullToPointer:
205 case CK_ReinterpretMemberPointer:
206 case CK_UserDefinedConversion:
212 case CK_ARCConsumeObject:
213 case CK_ARCExtendBlockObject:
214 case CK_ARCProduceObject:
215 case CK_ARCReclaimReturnedObject:
216 case CK_AtomicToNonAtomic:
217 case CK_BooleanToSignedIntegral:
218 case CK_ConstructorConversion:
219 case CK_CopyAndAutoreleaseBlockObject:
221 case CK_FixedPointCast:
222 case CK_FixedPointToBoolean:
223 case CK_FixedPointToFloating:
224 case CK_FixedPointToIntegral:
225 case CK_FloatingCast:
226 case CK_FloatingComplexCast:
227 case CK_FloatingComplexToBoolean:
228 case CK_FloatingComplexToIntegralComplex:
229 case CK_FloatingComplexToReal:
230 case CK_FloatingRealToComplex:
231 case CK_FloatingToBoolean:
232 case CK_FloatingToFixedPoint:
233 case CK_FloatingToIntegral:
234 case CK_HLSLAggregateSplatCast:
235 case CK_HLSLArrayRValue:
236 case CK_HLSLElementwiseCast:
237 case CK_HLSLVectorTruncation:
238 case CK_HLSLMatrixTruncation:
239 case CK_IntToOCLSampler:
240 case CK_IntegralCast:
241 case CK_IntegralComplexCast:
242 case CK_IntegralComplexToBoolean:
243 case CK_IntegralComplexToFloatingComplex:
244 case CK_IntegralComplexToReal:
245 case CK_IntegralRealToComplex:
246 case CK_IntegralToBoolean:
247 case CK_IntegralToFixedPoint:
248 case CK_IntegralToFloating:
249 case CK_LValueBitCast:
251 case CK_MemberPointerToBoolean:
252 case CK_NonAtomicToAtomic:
253 case CK_ObjCObjectLValueCast:
254 case CK_PointerToBoolean:
255 case CK_PointerToIntegral:
259 case CK_ZeroToOCLOpaqueType:
264 cgm.errorNYI(ce->getSourceRange(),
265 "unexpected cast for emitPointerWithAlignment: ",
266 ce->getCastKindName());
274 if (uo->getOpcode() == UO_AddrOf) {
284 if (
auto const *call = dyn_cast<CallExpr>(
expr)) {
285 switch (call->getBuiltinCallee()) {
288 case Builtin::BIaddressof:
289 case Builtin::BI__addressof:
290 case Builtin::BI__builtin_addressof: {
308 auto getScalarSizeInBits = [&](mlir::Type ty) ->
unsigned {
309 mlir::Type scalarTy = mlir::isa<cir::VectorType>(ty)
310 ? mlir::cast<cir::VectorType>(ty).getElementType()
316 mlir::Value srcVal = src.
getValue();
319 getScalarSizeInBits(srcVal.getType())) {
322 "emitStoreThroughExtVectorComponentLValue: dstTySize > srcTysize");
328 "emitStoreThroughExtVectorComponentLValue: HLSL");
338 mlir::Value vec = builder.createLoad(loc, dstAddr, dst.
isVolatile());
340 unsigned numSrcElts = vecTy->getNumElements();
342 if (numDstElts == numSrcElts) {
347 for (
unsigned i = 0; i != numDstElts; ++i)
350 vec = builder.createVecShuffle(loc, srcVal, mask);
351 }
else if (numDstElts > numSrcElts) {
357 std::iota(extMask.begin(), extMask.begin() + numSrcElts, 0);
359 mlir::Value extSrcVal = builder.createVecShuffle(loc, srcVal, extMask);
363 std::iota(mask.begin(), mask.begin() + numDstElts, 0);
372 for (
unsigned i = 0; i != numSrcElts; ++i)
375 vec = builder.createVecShuffle(loc, vec, extSrcVal, mask);
378 llvm_unreachable(
"unexpected shorten vector length");
384 cir::ConstantOp elt = builder.getSInt64(inIdx, loc);
385 vec = cir::VecInsertOp::create(builder, loc, vec, srcVal, elt);
398 const mlir::Value vector =
400 const mlir::Value newVector = cir::VecInsertOp::create(
410 cgm.errorNYI(
"emitStoreThroughLValue: !dst.isSimple() && isMatrixElt");
415 cgm.errorNYI(
"emitStoreThroughLValue: !dst.isSimple() && isMatrixRow");
419 assert(dst.
isBitField() &&
"Unknown LValue type");
427 assert(src.
isScalar() &&
"Can't emit an aggregate store with this method");
449 cir::PointerType realPtrTy = cir::PointerType::get(
450 realVarTy, mlir::cast<cir::PointerType>(v.getType()).getAddrSpace());
451 if (realPtrTy != v.getType())
455 Address addr(v, realVarTy, alignment);
469 bool isNontemporal) {
473 if (clangVecTy->isExtVectorBoolType())
475 "emitStoreOfScalar ExtVectorBoolType");
483 if (vecTy.getSize() == 3 && !
getLangOpts().PreserveVec3Type)
485 "emitStoreOfScalar Vec3 & PreserveVec3Type disabled");
499 assert(addr.
getPointer() &&
"expected pointer to exist");
501 if (currVarDecl && srcAlloca) {
502 const VarDecl *vd = currVarDecl;
503 assert(vd &&
"VarDecl expected");
508 assert(
currSrcLoc &&
"must pass in source location");
509 builder.createStore(*
currSrcLoc, value, addr, isVolatile, isNontemporal);
517 return targetInfo.
getABI().starts_with(
"aapcs");
527 bool useVoaltile =
cgm.getCodeGenOpts().AAPCSBitfieldWidth &&
531 assert(
currSrcLoc &&
"must pass in source location");
533 return builder.createSetBitfield(*
currSrcLoc, resLTy, ptr,
557 mlir::Type fieldType,
560 cir::PointerType fieldPtr = cir::PointerType::get(fieldType);
566 rec.getElementOffset(
cgm.getDataLayout().layout,
index));
574 cgm.getTypes().getCIRGenRecordLayout(field->
getParent());
584 addr = builder.createElementBitCast(loc, addr, info.
storageType);
607 if (
auto *classDecl = dyn_cast<CXXRecordDecl>(rec)) {
608 if (
cgm.getCodeGenOpts().StrictVTablePointers &&
609 classDecl->isDynamicClass()) {
611 "emitLValueForField: strict vtable for dynamic class");
617 llvm::StringRef fieldName = field->
getName();
619 if (
cgm.lambdaFieldToName.count(field))
620 fieldName =
cgm.lambdaFieldToName[field];
635 cgm.getTypes().getCIRGenRecordLayout(field->
getParent());
656 if (field->
hasAttr<AnnotateAttr>()) {
667 "emitLValueForField: __weak attribute");
686 cgm.getTypes().getCIRGenRecordLayout(field->
getParent());
709 ty = atomicTy->getValueType();
712 cgm.errorNYI(
"emitToMemory: extVectorBoolType");
723 ty = atomicTy->getValueType();
726 cgm.errorNYI(
"emitFromMemory: PackedVectorBoolType");
735 assert(0 &&
"NYI: emitStoreOfScalar constant matrix type");
747 bool isNontemporal) {
753 if (clangVecTy->isExtVectorBoolType()) {
754 cgm.errorNYI(loc,
"emitLoadOfScalar: ExtVectorBoolType");
762 if (vecTy.getSize() == 3 && !
getLangOpts().PreserveVec3Type)
764 "emitLoadOfScalar Vec3 & PreserveVec3Type disabled");
772 if (mlir::isa<cir::VoidType>(eltTy))
773 cgm.errorNYI(loc,
"emitLoadOfScalar: void type");
778 builder.createLoad(
getLoc(loc), addr, isVolatile, isNontemporal);
810 const mlir::Value load =
819 cgm.errorNYI(loc,
"emitLoadOfLValue");
824 const mlir::ArrayAttr elts) {
825 auto elt = mlir::cast<mlir::IntegerAttr>(elts[idx]);
837 if (
getLangOpts().
HLSL && !mlir::isa<cir::VectorType>(vec.getType())) {
838 cgm.errorNYI(loc,
"emitLoadOfExtVectorElementLValue: HLSL");
849 cir::ConstantOp
index =
850 builder.getConstInt(loc, builder.getSInt64Ty(), indexValue);
856 for (
auto i : llvm::seq<unsigned>(0, exprVecTy->getNumElements()))
859 cir::VecShuffleOp resultVec = builder.createVecShuffle(loc, vec, mask);
861 cgm.errorNYI(loc,
"emitLoadOfExtVectorElementLValue: ExtVectorBoolType");
871 "unexpected binary operator opcode");
886 memberPtrTy, &baseInfo);
888 return makeAddrLValue(memberAddr, memberPtrTy->getPointeeType(), baseInfo);
893 mlir::Location loc) {
896 mlir::Type vectorElementTy =
cgm.getTypes().convertType(elementTy);
902 mlir::Value idxValue =
903 builder.getConstInt(loc, mlir::cast<cir::IntType>(
ptrDiffTy), idx);
905 mlir::Value elementValue = builder.getArrayElement(
906 loc, loc, castToPointerElement.
getPointer(), vectorElementTy, idxValue,
912 return Address(elementValue, vectorElementTy, alignment);
921 mlir::Value thisValue) {
929 mlir::Value thisValue) {
930 bool hasExplicitObjectParameter =
false;
931 const auto *methD = dyn_cast_if_present<CXXMethodDecl>(
curCodeDecl);
934 hasExplicitObjectParameter = methD->isExplicitObjectMemberFunction();
935 assert(methD->getParent()->isLambda());
936 assert(methD->getParent() == field->
getParent());
938 if (hasExplicitObjectParameter) {
961 mlir::Type fnTy = funcOp.getFunctionType();
962 mlir::Type ptrTy = cir::PointerType::get(fnTy);
963 mlir::Value addr = cir::GetGlobalOp::create(cgf.
getBuilder(), loc, ptrTy,
964 funcOp.getSymName());
968 ptrTy = cir::PointerType::get(fnTy);
970 addr = cir::CastOp::create(cgf.
getBuilder(), addr.getLoc(), ptrTy,
971 cir::CastKind::bitcast, addr);
1018 case cir::GlobalLinkageKind::ExternalLinkage:
1019 case cir::GlobalLinkageKind::LinkOnceODRLinkage:
1020 case cir::GlobalLinkageKind::WeakODRLinkage:
1021 case cir::GlobalLinkageKind::InternalLinkage:
1022 case cir::GlobalLinkageKind::PrivateLinkage:
1034 "should not emit an unevaluated operand");
1036 if (
const auto *vd = dyn_cast<VarDecl>(nd)) {
1038 if (vd->getStorageClass() ==
SC_Register && vd->hasAttr<AsmLabelAttr>() &&
1039 !vd->isLocalVarDecl()) {
1041 "emitDeclRefLValue: Global Named registers access");
1046 (vd->getType()->isReferenceType() ||
1048 vd->getAnyInitializer(vd);
1050 e->
getLocation(), *vd->evaluateValue(), vd->getType());
1051 assert(val &&
"failed to emit constant expression");
1054 if (!vd->getType()->isReferenceType()) {
1056 addr =
cgm.createUnnamedGlobalFrom(*vd, val,
1059 auto ptrTy = mlir::cast<cir::PointerType>(addr.
getPointer().getType());
1060 if (ptrTy.getPointee() != varTy) {
1079 vd = vd->getCanonicalDecl();
1092 "Should not use decl without marking it used!");
1094 if (nd->
hasAttr<WeakRefAttr>())
1097 if (
const auto *vd = dyn_cast<VarDecl>(nd)) {
1107 if (vd->hasLinkage() || vd->isStaticDataMember())
1115 addr = iter->second;
1117 }
else if (vd->isStaticLocal()) {
1121 cgm.getOrCreateStaticVarDecl(*vd,
cgm.getCIRLinkageVarDefinition(vd));
1122 mlir::Value getGlobVal = builder.createGetGlobal(var);
1123 auto getGlob = getGlobVal.getDefiningOp<cir::GetGlobalOp>();
1124 getGlob.setStaticLocal(var.getStaticLocalGuard().has_value());
1129 llvm_unreachable(
"DeclRefExpr for Decl not entered in localDeclMap?");
1141 assert((vd->isStaticLocal() ||
symbolTable.count(vd)) &&
1142 "non-static locals should be already mapped");
1147 if (
const auto *bd = dyn_cast<BindingDecl>(nd)) {
1155 if (
const auto *fd = dyn_cast<FunctionDecl>(nd)) {
1159 if (
getContext().getTargetInfo().allowDebugInfoForExternalRef())
1166 "emitDeclRefLValue: unhandled MS Guid Decl");
1168 if (
const auto *tpo = dyn_cast<TemplateParamObjectDecl>(nd)) {
1169 CharUnits alignment =
cgm.getNaturalTypeAlignment(tpo->getType());
1170 cir::GetGlobalOp atpo =
1171 builder.createGetGlobal(
cgm.getAddrOfTemplateParamObject(tpo));
1173 "Do an address space conversion if necessary");
1180 llvm_unreachable(
"Unhandled DeclRefExpr");
1190 "evaluateExprAsBool: member pointer type");
1206 if (op == UO_Extension)
1212 assert(!t.
isNull() &&
"CodeGenFunction::EmitUnaryOpLValue: Illegal type");
1232 assert(lv.
isSimple() &&
"real/imag on non-ordinary l-value");
1247 ? builder.createComplexRealPtr(loc, lv.
getAddress())
1248 : builder.createComplexImagPtr(loc, lv.
getAddress());
1258 assert(e->
isPrefix() &&
"Prefix operator in unexpected state!");
1268 llvm_unreachable(
"UnaryOperator extension should be handled above!");
1277 llvm_unreachable(
"UnaryOperator of non-lvalue kind!");
1279 llvm_unreachable(
"Unknown unary operator kind!");
1287 const auto *
castExpr = dyn_cast<CastExpr>(e);
1301 if (
auto constantOp = idx.getDefiningOp<cir::ConstantOp>())
1302 return constantOp.getValueAttr<cir::IntAttr>();
1311 const CharUnits offset = constantIdx.getValue().getZExtValue() * eltSize;
1328 mlir::Location beginLoc,
1329 mlir::Location endLoc, mlir::Value ptr,
1330 mlir::Type eltTy, mlir::Value idx,
1341 mlir::Location beginLoc,
1342 mlir::Location endLoc,
Address addr,
1344 mlir::Location loc,
bool shouldDecay) {
1359 const mlir::Value eltPtr =
1363 return Address(eltPtr, elementType, eltAlign);
1376 "index was neither LHS nor RHS");
1378 auto emitIdxAfterBase = [&](
bool promote) -> mlir::Value {
1387 mlir::Type desiredIdxTy =
1392 if (idx.getType() != desiredIdxTy) {
1393 cir::CastKind
kind = mlir::isa<cir::BoolType>(idx.getType())
1394 ? cir::CastKind::bool_to_int
1395 : cir::CastKind::integral;
1396 idx = builder.createOrFold<cir::CastOp>(idx.getLoc(), desiredIdxTy,
1408 const mlir::Value idx = emitIdxAfterBase(
false);
1421 mlir::Value idx = emitIdxAfterBase(
true);
1446 idx = builder.createIntCast(idx, numElements.getType());
1455 idx = builder.createMul(
cgm.getLoc(e->
getExprLoc()), idx, numElements,
1468 if (
const auto *ase = dyn_cast<ArraySubscriptExpr>(array))
1475 *
this,
cgm.getLoc(array->getBeginLoc()),
cgm.getLoc(array->getEndLoc()),
1490 "The base must be a pointer");
1519 const auto *clangPtrTy =
1521 base =
makeAddrLValue(ptr, clangPtrTy->getPointeeType(), baseInfo);
1522 base.getQuals().removeObjCGCAttr();
1531 "Result must be a vector");
1539 "emitExtVectorElementExpr: ExtVectorBoolType & !HLSL");
1542 builder.createStore(vec.getLoc(), vec, vecMem);
1555 mlir::ArrayAttr elts = builder.getI64ArrayAttr(attrElts);
1565 assert(base.
isExtVectorElt() &&
"Can only subscript lvalue vec elts here!");
1568 for (
unsigned idx : indices)
1570 mlir::ArrayAttr cv = builder.getI64ArrayAttr(elts);
1576 llvm::StringRef name) {
1577 cir::GlobalOp globalOp =
cgm.getGlobalForStringLiteral(e, name);
1578 assert(globalOp.getAlignment() &&
"expected alignment for string literal");
1579 unsigned align = *(globalOp.getAlignment());
1597 case CK_LValueToRValueBitCast:
1598 case CK_ArrayToPointerDecay:
1599 case CK_FunctionToPointerDecay:
1600 case CK_NullToMemberPointer:
1601 case CK_NullToPointer:
1602 case CK_IntegralToPointer:
1603 case CK_PointerToIntegral:
1604 case CK_PointerToBoolean:
1605 case CK_IntegralCast:
1606 case CK_BooleanToSignedIntegral:
1607 case CK_IntegralToBoolean:
1608 case CK_IntegralToFloating:
1609 case CK_FloatingToIntegral:
1610 case CK_FloatingToBoolean:
1611 case CK_FloatingCast:
1612 case CK_FloatingRealToComplex:
1613 case CK_FloatingComplexToReal:
1614 case CK_FloatingComplexToBoolean:
1615 case CK_FloatingComplexCast:
1616 case CK_FloatingComplexToIntegralComplex:
1617 case CK_IntegralRealToComplex:
1618 case CK_IntegralComplexToReal:
1619 case CK_IntegralComplexToBoolean:
1620 case CK_IntegralComplexCast:
1621 case CK_IntegralComplexToFloatingComplex:
1622 case CK_DerivedToBaseMemberPointer:
1623 case CK_BaseToDerivedMemberPointer:
1624 case CK_MemberPointerToBoolean:
1625 case CK_ReinterpretMemberPointer:
1626 case CK_AnyPointerToBlockPointerCast:
1627 case CK_ARCProduceObject:
1628 case CK_ARCConsumeObject:
1629 case CK_ARCReclaimReturnedObject:
1630 case CK_ARCExtendBlockObject:
1631 case CK_CopyAndAutoreleaseBlockObject:
1632 case CK_IntToOCLSampler:
1633 case CK_FloatingToFixedPoint:
1634 case CK_FixedPointToFloating:
1635 case CK_FixedPointCast:
1636 case CK_FixedPointToBoolean:
1637 case CK_FixedPointToIntegral:
1638 case CK_IntegralToFixedPoint:
1640 case CK_HLSLVectorTruncation:
1641 case CK_HLSLMatrixTruncation:
1642 case CK_HLSLArrayRValue:
1643 case CK_HLSLElementwiseCast:
1644 case CK_HLSLAggregateSplatCast:
1645 llvm_unreachable(
"unexpected cast lvalue");
1648 llvm_unreachable(
"dependent cast kind in IR gen!");
1650 case CK_BuiltinFnToFnPtr:
1651 llvm_unreachable(
"builtin functions are handled elsewhere");
1664 case CK_ConstructorConversion:
1665 case CK_UserDefinedConversion:
1666 case CK_CPointerToObjCPointerCast:
1667 case CK_BlockPointerToObjCPointerCast:
1668 case CK_LValueToRValue:
1671 case CK_NonAtomicToAtomic:
1672 case CK_AtomicToNonAtomic:
1673 case CK_ObjCObjectLValueCast:
1674 case CK_VectorSplat: {
1676 std::string(
"emitCastLValue for unhandled cast kind: ") +
1682 case CK_AddressSpaceConversion: {
1693 case CK_LValueBitCast: {
1697 cgm.emitExplicitCastExprType(ce,
this);
1721 auto toTy = dyn_cast<cir::ArrayType>(ty);
1722 if (!fromTy || !toTy ||
1723 fromTy.getElementType() != toTy.getElementType() ||
1724 toTy.getSize() != 0)
1726 "emitCastLValue NoOp not array-shrink case");
1736 case CK_UncheckedDerivedToBase:
1737 case CK_DerivedToBase: {
1755 case CK_BaseToDerived: {
1771 case CK_ZeroToOCLOpaqueType:
1772 llvm_unreachable(
"NULL to OpenCL opaque type lvalue cast is not valid");
1775 llvm_unreachable(
"Invalid cast kind");
1812 if (
auto *field = dyn_cast<FieldDecl>(nd)) {
1824 if (
const auto *fd = dyn_cast<FunctionDecl>(nd))
1827 llvm_unreachable(
"Unhandled member declaration!");
1857 llvm_unreachable(
"bad evaluation kind");
1862 const Expr *inner) {
1873 cir::AllocaOp extDeclAlloca;
1877 extDeclAlloca = extDeclAddrIter->second.getUnderlyingAllocaOp();
1879 mlir::OpBuilder::InsertPoint ip;
1880 if (extDeclAlloca) {
1881 ip = {extDeclAlloca->getBlock(), extDeclAlloca->getIterator()};
1899 assert(addr.getAlignment().has_value() &&
1900 "This should always have an alignment");
1906 llvm_unreachable(
"temporary can't have dynamic storage duration");
1908 llvm_unreachable(
"unknown storage duration");
1932 if (
const auto *classDecl =
1936 referenceTemporaryDtor = classDecl->getDestructor();
1938 if (!referenceTemporaryDtor)
1955 mlir::OpBuilder::InsertionGuard guard(builder);
1956 assert(extendingGlobalOp.getDtorRegion().empty() &&
1957 "extending global already has a dtor region");
1958 mlir::Block *block =
1959 builder.createBlock(&extendingGlobalOp.getDtorRegion());
1960 builder.setInsertionPointToStart(block);
1975 builder.
createCallOp(loc, dtorFn, mlir::ValueRange{tempAddr});
1978 cir::YieldOp::create(builder, loc);
1994 llvm_unreachable(
"temporary cannot have dynamic storage duration");
2004 "Reference should never be pseudo-strong!");
2012 "emitMaterializeTemporaryExpr: ObjCLifetime");
2020 for (
const Expr *ignored : commaLHSs)
2025 "emitMaterializeTemporaryExpr: OpaqueValueExpr");
2031 cir::GlobalOp var =
nullptr;
2032 if (
auto getGlobalOp =
object.getPointer().getDefiningOp<cir::GetGlobalOp>())
2033 var = mlir::dyn_cast_or_null<cir::GlobalOp>(
2034 cgm.getGlobalValue(getGlobalOp.getName()));
2037 if (!var.getInitialValue().has_value()) {
2038 var.setInitialValueAttr(cir::ZeroAttr::get(var.getSymType()));
2052 switch (adjustment.Kind) {
2056 adjustment.DerivedToBase.BasePath->path(),
2063 "materialized temporary field is not a simple lvalue");
2070 e,
object, ptr, adjustment.Ptr.MPT,
nullptr);
2087 assert(e->
isUnique() &&
"LValue for a nonunique OVE hasn't been emitted");
2099 assert(e->
isUnique() &&
"RValue for a nonunique OVE hasn't been emitted");
2113 ".compoundliteral");
2124 "emitCompoundLiteralLValue: non C++ DestructedType");
2139 "Can't have a scalar return unless the return type is a "
2157 "binding l-value to type which needs a temporary");
2173 assert(e->
getOpcode() == BO_Assign &&
"unexpected binary l-value");
2212 llvm_unreachable(
"bad evaluation kind");
2218 bool ignoreResult) {
2225 if (!ignoreResult && aggSlot.
isIgnored())
2232 llvm_unreachable(
"bad evaluation kind");
2240 if (!pd->isInlineBuiltinDeclaration())
2245CIRGenCallee CIRGenFunction::emitDirectCallee(
const GlobalDecl &gd) {
2248 if (
unsigned builtinID = fd->getBuiltinID()) {
2249 StringRef ident =
cgm.getMangledName(gd);
2250 std::string fdInlineName = (ident +
".inline").str();
2252 bool isPredefinedLibFunction =
2253 cgm.getASTContext().BuiltinInfo.isPredefinedLibFunction(builtinID);
2259 bool hasAttributeNoBuiltin =
false;
2264 if (
auto fn = dyn_cast<cir::FuncOp>(
curFn);
2265 (!fn || fn.getName() != fdInlineName) &&
2268 mlir::cast_or_null<cir::FuncOp>(
cgm.getGlobalValue(fdInlineName));
2274 mlir::OpBuilder::InsertionGuard guard(builder);
2275 builder.setInsertionPointToStart(
cgm.getModule().getBody());
2277 clone = cir::FuncOp::create(builder, calleeFunc.getLoc(), fdInlineName,
2278 calleeFunc.getFunctionType());
2279 cgm.insertGlobalSymbol(clone);
2280 clone.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
2281 &
cgm.getMLIRContext(), cir::GlobalLinkageKind::InternalLinkage));
2282 clone.setSymVisibility(
"private");
2283 clone.setInlineKind(cir::InlineKind::AlwaysInline);
2294 else if (!isPredefinedLibFunction || !hasAttributeNoBuiltin)
2300 if ((
cgm.getLangOpts().CUDA ||
cgm.getLangOpts().HIP) &&
2301 !
cgm.getLangOpts().CUDAIsDevice && fd->hasAttr<CUDAGlobalAttr>()) {
2302 mlir::Operation *handle =
cgm.getCUDARuntime().getKernelHandle(callee, gd);
2304 mlir::cast<cir::FuncOp>(*
cgm.getCUDARuntime().getKernelStub(handle));
2312 return builder.getConstant(loc, cir::UndefAttr::get(cirTy));
2319 mlir::Location loc = builder.getUnknownLoc();
2326 mlir::Value v = builder.createComplexCreate(loc, undefElem, undefElem);
2341 llvm_unreachable(
"bad evaluation kind");
2351 "Callee must have function pointer type!");
2374 if (
const auto *oce = dyn_cast<CXXOperatorCallExpr>(e)) {
2375 if (
const auto *md =
2376 dyn_cast_if_present<CXXMethodDecl>(oce->getCalleeDecl());
2377 md && md->isStatic()) {
2379 arguments = llvm::drop_begin(arguments, 1);
2383 emitCallArgs(args, dyn_cast<FunctionProtoType>(fnType), arguments,
2387 cgm.getTypes().arrangeFreeFunctionCall(args, fnType);
2409 calleeTy = cir::FuncType::get(calleeTy.getInputs(),
2410 calleeTy.getReturnType(),
false);
2411 auto calleePtrTy = cir::PointerType::get(calleeTy);
2415 if (
auto funcOp = mlir::dyn_cast<cir::FuncOp>(fn)) {
2416 addr = cir::GetGlobalOp::create(
2418 cir::PointerType::get(funcOp.getFunctionType()), funcOp.getSymName());
2420 addr = fn->getResult(0);
2423 fn = builder.createBitcast(addr, calleePtrTy).getDefiningOp();
2431 cir::CIRCallOpInterface callOp;
2444 if (
const auto *implicitCast = dyn_cast<ImplicitCastExpr>(e)) {
2445 if (implicitCast->getCastKind() == CK_FunctionToPointerDecay ||
2446 implicitCast->getCastKind() == CK_BuiltinFnToFnPtr) {
2447 return emitCallee(implicitCast->getSubExpr());
2455 }
else if (
const auto *declRef = dyn_cast<DeclRefExpr>(e)) {
2457 if (
const auto *funcDecl = dyn_cast<FunctionDecl>(declRef->getDecl()))
2458 return emitDirectCallee(funcDecl);
2459 }
else if (
auto me = dyn_cast<MemberExpr>(e)) {
2460 if (
const auto *fd = dyn_cast<FunctionDecl>(me->getMemberDecl())) {
2462 return emitDirectCallee(fd);
2465 }
else if (
auto *pde = dyn_cast<CXXPseudoDestructorExpr>(e)) {
2470 mlir::Value calleePtr;
2482 if (
const auto *vd =
2487 CIRGenCallee callee(calleeInfo, calleePtr.getDefiningOp());
2495 if (
const auto *ce = dyn_cast<CXXMemberCallExpr>(e))
2506 if (
const auto *operatorCall = dyn_cast<CXXOperatorCallExpr>(e)) {
2507 if (
const auto *md =
2508 dyn_cast_if_present<CXXMethodDecl>(operatorCall->getCalleeDecl());
2509 md && md->isImplicitObjectMemberFunction())
2540 "Array to pointer decay must have array source type!");
2548 auto lvalueAddrTy = mlir::cast<cir::PointerType>(addr.
getPointer().getType());
2553 [[maybe_unused]]
auto pointeeTy =
2554 mlir::cast<cir::ArrayType>(lvalueAddrTy.getPointee());
2557 assert(mlir::isa<cir::ArrayType>(arrayTy) &&
"expected array");
2558 assert(pointeeTy == arrayTy);
2568 mlir::Value ptr = builder.maybeBuildArrayDecay(
2586 llvm_unreachable(
"bad evaluation kind");
2593 const Stmt *elseS) {
2595 std::optional<mlir::Location> elseLoc;
2599 mlir::LogicalResult resThen = mlir::success(), resElse = mlir::success();
2602 [&](mlir::OpBuilder &, mlir::Location) {
2603 LexicalScope lexScope{*
this, thenLoc, builder.getInsertionBlock()};
2608 [&](mlir::OpBuilder &, mlir::Location) {
2609 assert(elseLoc &&
"Invalid location for elseS.");
2610 LexicalScope lexScope{*
this, *elseLoc, builder.getInsertionBlock()};
2615 return mlir::LogicalResult::success(resThen.succeeded() &&
2616 resElse.succeeded());
2624 std::optional<mlir::Location> elseLoc) {
2630 ifLocs.push_back(*elseLoc);
2631 mlir::Location loc = mlir::FusedLoc::get(&
getMLIRContext(), ifLocs);
2635 cir::IfOp ifOp = cir::IfOp::create(builder, loc, condV, elseLoc.has_value(),
2639 assert((elseLoc.has_value() || ifOp.getElseRegion().empty()) &&
2640 "else region created with no else location");
2641 if (elseLoc.has_value())
2660 Expr *trueExpr = condOp->getTrueExpr();
2661 Expr *falseExpr = condOp->getFalseExpr();
2664 mlir::Value ternaryOpRes =
2665 cir::TernaryOp::create(
2666 builder, loc, condV,
2667 [
this, trueExpr](mlir::OpBuilder &b, mlir::Location loc) {
2669 cir::YieldOp::create(b, loc, lhs);
2672 [
this, falseExpr](mlir::OpBuilder &b, mlir::Location loc) {
2674 cir::YieldOp::create(b, loc, rhs);
2683 cgm.errorNYI(
"NYI");
2697 mlir::Location loc,
CharUnits alignment,
2698 bool insertIntoFnEntryBlock,
2699 mlir::Value arraySize) {
2700 mlir::Block *entryBlock = insertIntoFnEntryBlock
2709 llvm::dyn_cast_if_present<cir::TryOp>(entryBlock->getParentOp())) {
2710 if (auto scopeOp = llvm::dyn_cast<cir::ScopeOp>(tryOp->getParentOp()))
2711 entryBlock = &scopeOp.getScopeRegion().front();
2719 mlir::Location loc,
CharUnits alignment,
2720 mlir::OpBuilder::InsertPoint ip,
2721 mlir::Value arraySize) {
2725 cir::PointerType localVarPtrTy =
2727 mlir::IntegerAttr alignIntAttr =
cgm.
getSize(alignment);
2731 mlir::OpBuilder::InsertionGuard guard(builder);
2732 builder.restoreInsertionPoint(ip);
2734 alignIntAttr, arraySize);
2752 if (md->isStatic()) {
2757 bool hasQualifier = me->hasQualifier();
2759 bool isArrow = me->isArrow();
2760 const Expr *base = me->getBase();
2763 ce, md,
returnValue, hasQualifier, qualifier, isArrow, base);
2780 cgm.errorNYI(loc,
"load of volatile reference");
2789 CharUnits align =
cgm.getNaturalTypeAlignment(pointeeType, pointeeBaseInfo);
2806 cir::TrapOp::create(builder, loc);
2808 builder.createBlock(builder.getBlock()->getParent());
2812 bool createNewBlock) {
2814 cir::UnreachableOp::create(builder,
getLoc(loc));
2816 builder.createBlock(builder.getBlock()->getParent());
2823 return builder.createDummyValue(loc, t, alignment);
2832 const Twine &name) {
2838 const Twine &name,
Address *alloca,
2839 mlir::OpBuilder::InsertPoint ip) {
2846 mlir::Location loc,
const Twine &name,
2848 mlir::OpBuilder::InsertPoint ip) {
2851 name,
nullptr, alloca, ip);
2854 cgm.errorNYI(loc,
"temporary matrix value");
2862 mlir::Type ty,
CharUnits align, mlir::Location loc,
const Twine &name,
2863 mlir::Value arraySize, mlir::OpBuilder::InsertPoint ip) {
2864 cir::AllocaOp alloca = ip.isSet()
2867 alloca.setAlignmentAttr(
cgm.getSize(align));
2868 return Address(alloca, ty, align);
2872 mlir::Location loc,
const Twine &name,
2873 mlir::Value arraySize,
2875 mlir::OpBuilder::InsertPoint ip) {
2881 Address alloca, mlir::ptr::MemorySpaceAttrInterface destAddrSpace,
2882 mlir::Value arraySize) {
2892 if (srcAddrSpace == destAddrSpace)
2895 mlir::OpBuilder::InsertionGuard guard(builder);
2897 builder.setInsertionPointAfter(allocaOp);
2898 }
else if (!arraySize) {
2900 builder.restoreInsertionPoint(builder.getBestAllocaInsertPoint(entryBlock));
2903 mlir::Type destPtrTy =
2913 mlir::Type ty, mlir::ptr::MemorySpaceAttrInterface destAddrSpace,
2914 CharUnits align, mlir::Location loc,
const Twine &name,
2915 mlir::Value arraySize,
Address *allocaAddr,
2916 mlir::OpBuilder::InsertPoint ip) {
2920 *allocaAddr = alloca;
2930 mlir::Value arraySize,
2931 bool insertIntoFnEntryBlock) {
2933 insertIntoFnEntryBlock, arraySize)
2941 mlir::OpBuilder::InsertPoint ip,
2942 mlir::Value arraySize) {
2943 assert(ip.isSet() &&
"Insertion point is not set");
2944 return mlir::cast<cir::AllocaOp>(
2955 const Twine &name) {
2997 mlir::TypedAttr cstToEmit = mlir::dyn_cast_if_present<mlir::TypedAttr>(c);
2998 assert(cstToEmit &&
"expected a typed attribute");
3014 assert(constant &&
"not a constant");
3024 assert(sl !=
nullptr &&
"No StringLiteral name in PredefinedExpr");
3026 StringRef fnName = fn.getName();
3027 fnName.consume_front(
"\01");
3028 std::array<StringRef, 2> nameItems = {
3030 std::string gvName = llvm::join(nameItems,
".");
3045std::optional<LValue> handleConditionalOperatorLValueSimpleCase(
3048 llvm::APSInt condExprVal;
3050 return std::nullopt;
3053 if (!condExprVal.getBoolValue())
3054 std::swap(live, dead);
3057 return std::nullopt;
3064 if (
auto *throwExpr = dyn_cast<CXXThrowExpr>(live->
IgnoreParens())) {
3068 mlir::Type elemTy = cgf.
convertType(dead->getType());
3069 mlir::Value undefPtr =
3071 cgf.
getLoc(throwExpr->getSourceRange()));
3081static std::optional<LValue> emitLValueOrThrowExpression(
CIRGenFunction &cgf,
3082 const Expr *operand) {
3083 if (
auto *throwExpr = dyn_cast<CXXThrowExpr>(operand->
IgnoreParens())) {
3085 return std::nullopt;
3094template <
typename FuncTy>
3097 const FuncTy &branchGenFunc) {
3105 auto emitBranch = [&](mlir::OpBuilder &b, mlir::Location loc,
3106 const Expr *
expr, std::optional<LValue> &resultLV) {
3110 mlir::Value resultPtr;
3117 resultLV = branchGenFunc(*
this,
expr);
3118 resultPtr = resultLV ? resultLV->getPointer() : mlir::Value();
3126 cir::YieldOp::create(b, loc, resultPtr);
3129 cir::TernaryOp ternary = cir::TernaryOp::create(
3130 builder, loc, condV,
3132 [&](mlir::OpBuilder &b, mlir::Location loc) {
3136 [&](mlir::OpBuilder &b, mlir::Location loc) {
3145 info.
result = ternary.getResult();
3151 if (!
expr->isGLValue()) {
3154 "Unexpected conditional operator!");
3159 if (std::optional<LValue> res =
3160 handleConditionalOperatorLValueSimpleCase(*
this,
expr))
3165 return emitLValueOrThrowExpression(cgf, e);
3168 if ((info.
lhs && !info.
lhs->isSimple()) ||
3169 (info.
rhs && !info.
rhs->isSimple())) {
3170 cgm.errorNYI(
expr->getSourceRange(),
3171 "unsupported conditional operator with non-simple lvalue");
3175 if (info.
lhs && info.
rhs) {
3181 std::max(info.
lhs->getBaseInfo().getAlignmentSource(),
3182 info.
rhs->getBaseInfo().getAlignmentSource());
3187 assert((info.
lhs || info.
rhs) &&
3188 "both operands of glvalue conditional are throw-expressions?");
3204 if (!
cgm.getLangOpts().MSVolatile)
3207 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)
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.
*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::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)
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={})
llvm::TypeSize getTypeSizeInBits(mlir::Type ty) const
llvm::ArrayRef< mlir::Type > getMembers() const
uint64_t getElementOffset(const mlir::DataLayout &dataLayout, unsigned idx) const
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.
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.
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".
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)
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)
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,...
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 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)
Address maybeCastStackAddressSpace(Address alloca, mlir::ptr::MemorySpaceAttrInterface destAddrSpace, mlir::Value arraySize)
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,...
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)
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)
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)
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)
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.
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()
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.
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.
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={})
void pushLifetimeExtendedDestroy(CleanupKind kind, Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)
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)
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::GlobalOp getOrCreateCIRGlobal(llvm::StringRef mangledName, mlir::Type ty, LangAS langAS, const VarDecl *d, ForDefinition_t isForDefinition)
If the specified mangled name is not in the module, create and return an mlir::GlobalOp value.
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.
mlir::Location getLoc(clang::SourceLocation cLoc)
Helpers to convert the presumed location of Clang's SourceLocation to an MLIR Location.
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
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
bool isVolatileQualified() const
Address getVectorAddress() const
clang::CharUnits getAlignment() const
LValueBaseInfo getBaseInfo() const
bool isNontemporal() 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.
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.
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?
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
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
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 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.
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.
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.
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.
Exposes information about the current target.
virtual StringRef getABI() const
Get the ABI currently in use.
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 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.
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 ...
bool isEmptyFieldForLayout(const ASTContext &context, const FieldDecl *fd)
isEmptyFieldForLayout - Return true if the field is "empty", that is, either a zero-width bit-field o...
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)
@ 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.
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 pointerAuthentication()
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 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.
An adjustment to be made to the temporary created when emitting a reference binding,...
@ DerivedToBaseAdjustment
@ MemberPointerAdjustment