18#include "mlir/IR/Attributes.h"
19#include "mlir/IR/BuiltinAttributeInterfaces.h"
20#include "mlir/IR/BuiltinAttributes.h"
33#include "llvm/ADT/ArrayRef.h"
34#include "llvm/ADT/STLExtras.h"
35#include "llvm/Support/ErrorHandling.h"
52 for (
auto [idx, memberTy] : llvm::enumerate(recordTy.
getMembers())) {
55 mlir::Attribute elt = elements[idx];
61 stored.push_back(elt);
74class RecordBuilderInitList {
77 std::variant<APValue, const InitListExpr *> value;
79 bool holdsExpr()
const {
80 return std::holds_alternative<const InitListExpr *>(value);
83 bool holdsAPValue()
const {
return std::holds_alternative<APValue>(value); }
85 const Expr *getExpr() {
87 return std::get<const InitListExpr *>(value)->getInit(initIdx);
92 return cgm.
getLoc(std::get<const InitListExpr *>(value)->getBeginLoc());
96 assert(holdsAPValue());
98 return std::get<APValue>(value).getUnionValue();
99 return std::get<APValue>(value).getStructField(initIdx);
104 : isUnion(rd->
isUnion()), value(val) {}
106 : isUnion(rd->
isUnion()), value(ile) {
111 if (
auto *
const *ile = std::get_if<const InitListExpr *>(&value))
112 return initIdx >= (*ile)->getNumInits();
117 return !std::get<APValue>(value).isUnion();
119 return initIdx >= std::get<APValue>(value).getStructNumFields();
122 const FieldDecl *getActiveUnionField()
const {
124 return std::get<const InitListExpr *>(value)
125 ->getInitializedFieldInUnion();
126 return std::get<APValue>(value).getUnionField();
135 if (holdsExpr() && isa_and_nonnull<NoInitExpr>(getExpr()))
157 APValue getBase(
unsigned idx) {
162 assert(holdsAPValue());
164 return std::get<APValue>(value).getStructBase(idx);
168 if (holdsExpr() && getExpr()->HasSideEffects(ctx))
176 const Expr *e = getExpr();
184llvm::APInt bitfieldStorageToAPInt(mlir::Attribute
attr,
unsigned storageSize,
188 return llvm::APInt(storageSize, 0);
190 if (
auto intAttr = mlir::dyn_cast<cir::IntAttr>(
attr))
191 return intAttr.getValue();
195 llvm::APInt result(storageSize, 0);
196 auto elts = mlir::cast<mlir::ArrayAttr>(
197 mlir::cast<cir::ConstArrayAttr>(
attr).getElts());
199 unsigned numBytes = elts.size();
200 for (
unsigned i = 0; i != numBytes; ++i) {
201 unsigned byteIdx = isBigEndian ? numBytes - 1 - i : i;
203 mlir::cast<cir::IntAttr>(elts[i]).getValue().zextOrTrunc(8);
204 result.insertBits(
byte, byteIdx * 8);
209mlir::Attribute apIntToBitfieldStorage(
CIRGenModule &cgm,
210 mlir::Type storageType,
211 const llvm::APInt &value,
214 if (mlir::isa<cir::IntTypeInterface>(storageType))
215 return cir::IntAttr::get(storageType, value);
219 auto arrayTy = mlir::cast<cir::ArrayType>(storageType);
221 unsigned numBytes = arrayTy.getSize();
225 for (
unsigned i = 0; i != numBytes; ++i) {
226 unsigned byteIdx = isBigEndian ? numBytes - 1 - i : i;
227 bytes[i] = cir::IntAttr::get(byteTy, value.extractBits(8, byteIdx * 8));
229 return cir::ConstArrayAttr::get(
230 arrayTy, mlir::ArrayAttr::get(builder.getContext(),
bytes));
240 mlir::Attribute existingVal,
241 cir::IntAttr newVal,
bool isSigned,
245 bitfieldStorageToAPInt(existingVal, bfInfo.
storageSize, isBigEndian);
247 llvm::APInt curValue = newVal.getValue();
252 curValue = curValue.sextOrTrunc(bfInfo.
size);
254 curValue = curValue.zextOrTrunc(bfInfo.
size);
261 curValue = curValue.shl(bfInfo.
offset);
268 return apIntToBitfieldStorage(cgm, bfInfo.
storageType, result, isBigEndian);
274 mlir::Attribute existingVal, mlir::Attribute newVal) {
276 auto intAttr = mlir::dyn_cast<cir::IntAttr>(newVal);
280 auto boolAttr = mlir::cast<cir::BoolAttr>(newVal);
281 intAttr = cir::IntAttr::get(
282 builder.
getUIntNTy(1), llvm::APInt(1, boolAttr.getValue()));
285 return updateBitfieldInit(
286 cgm, existingVal, intAttr,
293 auto typedAttr = mlir::cast<mlir::TypedAttr>(
attr);
294 if (typedAttr.getType() == baseSubobjTy)
297 if (mlir::isa<cir::ZeroAttr>(
attr))
300 auto recordAttr = mlir::cast<cir::ConstRecordAttr>(
attr);
301 mlir::ArrayAttr members = recordAttr.getMembers();
303 members.begin(), members.begin() + baseSubobjTy.
getNumElements());
315 llvm::zip_equal(baseMembers,
316 llvm::map_range(llvm::make_filter_range(
320 [](
const auto &pair) {
321 auto &[member, baseTy] = pair;
322 return mlir::cast<mlir::TypedAttr>(member).getType() == baseTy;
324 "base-subobject member type does not match complete-object member "
325 "type at the same index");
327 return cir::ConstRecordAttr::get(baseSubobjTy,
328 builder.getArrayAttr(baseMembers));
334 RecordBuilderInitList
inits,
bool handleBases,
353 mlir::Attribute eltAttr =
inits.emit(emitter, activeField->
getType());
358 eltAttr = setBitfieldInit(cgm, cirLayout, builder, activeField,
361 return cir::ConstRecordAttr::get(recordTy, builder.getArrayAttr({eltAttr}));
366 if (
auto *cxxrd = dyn_cast<CXXRecordDecl>(rd)) {
374 auto apOp = addrPtr.getDefiningOp<cir::VTableAddrPointOp>();
375 mlir::ArrayAttr indices = builder.getArrayAttr(
376 {builder.getI32IntegerAttr(apOp.getAddressPoint().getIndex()),
377 builder.getI32IntegerAttr(apOp.getAddressPoint().getOffset())});
378 elements[0] = cir::GlobalViewAttr::get(
379 cir::VPtrType::get(builder.getContext()), apOp.getNameAttr(), indices,
391 if (base.isVirtual())
394 const auto *baseDecl = base.getType()->castAsCXXRecordDecl();
396 unsigned curBaseNo = baseNo++;
409 elements[baseFieldIdx] = buildRecordHelper(
410 emitter, baseDecl, vtableBaseTy, RecordBuilderInitList(rd, baseValue),
411 handleBases, baseOff,
true);
414 if (cxxrd->getNumVBases()) {
415 cgm.
errorNYI(cxxrd->getSourceRange(),
416 "buildRecordHelper: virtual base classes");
429 if (
inits.shouldSkip(field)) {
430 inits.advanceSkip(field);
448 mlir::Attribute eltAttr =
inits.emit(emitter, field->
getType());
455 elements[fieldIdx] = setBitfieldInit(cgm, cirLayout, builder, field,
456 elements[fieldIdx], eltAttr);
459 if (
auto expectedTy = mlir::dyn_cast<cir::RecordType>(
461 eltAttr = asBaseSubobject(builder, eltAttr, expectedTy);
463 elements[fieldIdx] = eltAttr;
485 const bool handleBases =
false;
487 return buildRecordHelper(emitter, rd, rd, RecordBuilderInitList(rd, ile),
495 valTy->
castAs<clang::RecordType>()->getDecl()->getDefinitionOrSelf();
496 return buildRecordHelper(emitter, rd, rd, RecordBuilderInitList(rd, val),
513class ConstExprEmitter
514 :
public StmtVisitor<ConstExprEmitter, mlir::Attribute, QualType> {
520 : cgm(emitter.cgm), emitter(emitter) {}
526 mlir::Attribute VisitStmt(Stmt *s, QualType t) {
return {}; }
528 mlir::Attribute VisitConstantExpr(ConstantExpr *ce, QualType t) {
529 if (mlir::Attribute result = emitter.tryEmitConstantExpr(ce))
534 mlir::Attribute VisitParenExpr(ParenExpr *pe, QualType t) {
539 VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *pe,
544 mlir::Attribute VisitGenericSelectionExpr(GenericSelectionExpr *ge,
549 mlir::Attribute VisitChooseExpr(ChooseExpr *ce, QualType t) {
553 mlir::Attribute VisitCompoundLiteralExpr(CompoundLiteralExpr *e, QualType t) {
557 mlir::Attribute VisitCastExpr(
CastExpr *e, QualType destType) {
558 if (
const auto *ece = dyn_cast<ExplicitCastExpr>(e))
559 cgm.emitExplicitCastExprType(ece,
560 const_cast<CIRGenFunction *
>(emitter.cgf));
566 case CK_AddressSpaceConversion:
567 case CK_ReinterpretMemberPointer:
568 cgm.errorNYI(e->
getBeginLoc(),
"ConstExprEmitter::VisitCastExpr");
571 case CK_DerivedToBaseMemberPointer:
572 case CK_BaseToDerivedMemberPointer:
578 case CK_LValueToRValue:
579 case CK_AtomicToNonAtomic:
580 case CK_NonAtomicToAtomic:
582 case CK_ConstructorConversion:
583 return Visit(subExpr, destType);
585 case CK_IntToOCLSampler:
586 llvm_unreachable(
"global sampler variables are not generated");
589 llvm_unreachable(
"saw dependent cast!");
591 case CK_BuiltinFnToFnPtr:
592 llvm_unreachable(
"builtin functions are handled elsewhere");
595 case CK_ObjCObjectLValueCast:
596 case CK_ARCProduceObject:
597 case CK_ARCConsumeObject:
598 case CK_ARCReclaimReturnedObject:
599 case CK_ARCExtendBlockObject:
600 case CK_CopyAndAutoreleaseBlockObject:
608 case CK_LValueBitCast:
609 case CK_LValueToRValueBitCast:
610 case CK_NullToMemberPointer:
611 case CK_UserDefinedConversion:
612 case CK_CPointerToObjCPointerCast:
613 case CK_BlockPointerToObjCPointerCast:
614 case CK_AnyPointerToBlockPointerCast:
615 case CK_ArrayToPointerDecay:
616 case CK_FunctionToPointerDecay:
617 case CK_BaseToDerived:
618 case CK_DerivedToBase:
619 case CK_UncheckedDerivedToBase:
620 case CK_MemberPointerToBoolean:
622 case CK_FloatingRealToComplex:
623 case CK_FloatingComplexToReal:
624 case CK_FloatingComplexToBoolean:
625 case CK_FloatingComplexCast:
626 case CK_FloatingComplexToIntegralComplex:
627 case CK_IntegralRealToComplex:
628 case CK_IntegralComplexToReal:
629 case CK_IntegralComplexToBoolean:
630 case CK_IntegralComplexCast:
631 case CK_IntegralComplexToFloatingComplex:
632 case CK_PointerToIntegral:
633 case CK_PointerToBoolean:
634 case CK_NullToPointer:
635 case CK_IntegralCast:
636 case CK_BooleanToSignedIntegral:
637 case CK_IntegralToPointer:
638 case CK_IntegralToBoolean:
639 case CK_IntegralToFloating:
640 case CK_FloatingToIntegral:
641 case CK_FloatingToBoolean:
642 case CK_FloatingCast:
643 case CK_FloatingToFixedPoint:
644 case CK_FixedPointToFloating:
645 case CK_FixedPointCast:
646 case CK_FixedPointToBoolean:
647 case CK_FixedPointToIntegral:
648 case CK_IntegralToFixedPoint:
649 case CK_ZeroToOCLOpaqueType:
651 case CK_HLSLArrayRValue:
652 case CK_HLSLVectorTruncation:
653 case CK_HLSLMatrixTruncation:
654 case CK_HLSLElementwiseCast:
655 case CK_HLSLAggregateSplatCast:
658 llvm_unreachable(
"Invalid CastKind");
661 mlir::Attribute VisitCXXDefaultInitExpr(CXXDefaultInitExpr *die, QualType t) {
664 return Visit(die->
getExpr(), t);
667 mlir::Attribute VisitExprWithCleanups(ExprWithCleanups *e, QualType t) {
672 mlir::Attribute VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *e,
677 mlir::Attribute VisitImplicitValueInitExpr(ImplicitValueInitExpr *e,
679 return cgm.emitNullConstantAttr(t);
682 mlir::Attribute VisitInitListExpr(InitListExpr *ile, QualType t) {
684 return Visit(ile->
getInit(0), t);
694 return ConstRecordBuilder::buildRecord(emitter, ile, t);
707 mlir::Attribute VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *e,
709 mlir::Attribute c = Visit(e->
getBase(), destType);
714 "ConstExprEmitter::VisitDesignatedInitUpdateExpr");
718 mlir::Attribute VisitCXXConstructExpr(CXXConstructExpr *e, QualType ty) {
724 assert(e->
getNumArgs() == 1 &&
"trivial ctor with > 1 argument");
726 "trivial ctor has argument but isn't a copy/move ctor");
729 assert(cgm.getASTContext().hasSameUnqualifiedType(ty,
arg->getType()) &&
730 "argument to copy ctor is of wrong type");
734 if (
auto const *mte = dyn_cast<MaterializeTemporaryExpr>(arg))
735 return Visit(mte->getSubExpr(), ty);
745 return cgm.getBuilder().getZeroInitAttr(cgm.convertType(ty));
748 mlir::Attribute VisitStringLiteral(StringLiteral *e, QualType t) {
750 return cgm.getConstantArrayFromStringLiteral(e);
753 mlir::Attribute VisitObjCEncodeExpr(ObjCEncodeExpr *e, QualType t) {
754 cgm.errorNYI(e->
getBeginLoc(),
"ConstExprEmitter::VisitObjCEncodeExpr");
758 mlir::Attribute VisitUnaryExtension(
const UnaryOperator *e, QualType t) {
763 mlir::Type convertType(QualType t) {
return cgm.convertType(t); }
770 type.getQualifiers());
783struct ConstantLValue {
784 llvm::PointerUnion<mlir::Value, mlir::Attribute> value;
785 bool hasOffsetApplied;
787 ConstantLValue(std::nullptr_t)
789 ConstantLValue(cir::GlobalViewAttr address)
790 : value(address), hasOffsetApplied(
false) {}
791 ConstantLValue(cir::GlobalOffsetAttr address)
792 : value(address), hasOffsetApplied(
true) {}
793 ConstantLValue(cir::BlockAddrInfoAttr address)
794 : value(address), hasOffsetApplied(
true) {}
796 ConstantLValue() : value(
nullptr), hasOffsetApplied(
false) {}
800class ConstantLValueEmitter
803 ConstantEmitter &emitter;
808 friend StmtVisitorBase;
811 ConstantLValueEmitter(ConstantEmitter &emitter,
const APValue &value,
813 : cgm(emitter.cgm), emitter(emitter), value(value), destType(destType) {}
815 mlir::Attribute tryEmit();
818 mlir::Attribute tryEmitAbsolute(mlir::Type destTy);
819 ConstantLValue tryEmitBase(
const APValue::LValueBase &base);
821 ConstantLValue VisitStmt(
const Stmt *s) {
return nullptr; }
822 ConstantLValue VisitConstantExpr(
const ConstantExpr *e);
823 ConstantLValue VisitCompoundLiteralExpr(
const CompoundLiteralExpr *e);
824 ConstantLValue VisitStringLiteral(
const StringLiteral *e);
825 ConstantLValue VisitObjCBoxedExpr(
const ObjCBoxedExpr *e);
826 ConstantLValue VisitObjCEncodeExpr(
const ObjCEncodeExpr *e);
827 ConstantLValue VisitObjCStringLiteral(
const ObjCStringLiteral *e);
828 ConstantLValue VisitPredefinedExpr(
const PredefinedExpr *e);
829 ConstantLValue VisitAddrLabelExpr(
const AddrLabelExpr *e);
830 ConstantLValue VisitCallExpr(
const CallExpr *e);
831 ConstantLValue VisitBlockExpr(
const BlockExpr *e);
832 ConstantLValue VisitCXXTypeidExpr(
const CXXTypeidExpr *e);
834 VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *e);
839 std::optional<mlir::ArrayAttr> getOffsetIndices(mlir::Type ty) {
840 int64_t offset = value.getLValueOffset().getQuantity();
841 cir::CIRDataLayout layout(cgm.getModule());
842 SmallVector<int64_t, 3> idxVec;
843 if (!cgm.getBuilder().computeGlobalViewIndicesFromFlatOffset(
844 offset, ty, layout, idxVec))
847 llvm::SmallVector<mlir::Attribute, 3> indices;
848 for (int64_t i : idxVec) {
849 mlir::IntegerAttr intAttr = cgm.getBuilder().getI32IntegerAttr(i);
850 indices.push_back(intAttr);
854 return mlir::ArrayAttr{};
855 return cgm.getBuilder().getArrayAttr(indices);
859 ConstantLValue applyOffset(ConstantLValue &c) {
861 if (
auto attr = mlir::dyn_cast<mlir::Attribute>(c.value)) {
862 if (
auto gv = mlir::dyn_cast<cir::GlobalViewAttr>(attr)) {
863 auto baseTy = mlir::cast<cir::PointerType>(gv.getType()).getPointee();
864 mlir::Type destTy = cgm.getTypes().convertTypeForMem(destType);
865 assert(!gv.getIndices() &&
"Global view is already indexed");
866 std::optional<mlir::ArrayAttr> indices = getOffsetIndices(baseTy);
868 return cir::GlobalOffsetAttr::get(
869 destTy, gv.getSymbol(), value.getLValueOffset().getQuantity());
870 return cir::GlobalViewAttr::get(destTy, gv.getSymbol(), *indices);
872 llvm_unreachable(
"Unsupported attribute type to offset");
875 cgm.errorNYI(
"ConstantLValue: non-attribute offset");
882mlir::Attribute ConstantLValueEmitter::tryEmit() {
893 assert((mlir::isa<cir::PointerType>(destTy) ||
894 mlir::isa<cir::IntType>(destTy)) &&
895 "constant lvalue destination must be pointer or integer");
900 return tryEmitAbsolute(destTy);
903 ConstantLValue result = tryEmitBase(base);
906 llvm::PointerUnion<mlir::Value, mlir::Attribute> &value = result.value;
911 if (!result.hasOffsetApplied)
912 value = applyOffset(result).value;
917 if (PointerAuthQualifier pointerAuth = destType.
getPointerAuth()) {
918 cgm.
errorNYI(
"ConstantLValueEmitter: pointer authentication");
924 if (
auto attr = mlir::dyn_cast<mlir::Attribute>(value)) {
925 if (
auto gv = mlir::dyn_cast<cir::GlobalViewAttr>(attr))
926 return cir::GlobalViewAttr::get(destTy, gv.getSymbol(), gv.getIndices());
928 if (mlir::isa<cir::PointerType>(destTy))
932 cgm.
errorNYI(
"ConstantLValueEmitter: non-attribute pointer or integer");
938mlir::Attribute ConstantLValueEmitter::tryEmitAbsolute(mlir::Type destTy) {
940 auto destPtrTy = mlir::cast<cir::PointerType>(destTy);
942 destPtrTy, value.getLValueOffset().getQuantity());
946ConstantLValueEmitter::tryEmitBase(
const APValue::LValueBase &base) {
948 if (
const ValueDecl *d = base.
dyn_cast<
const ValueDecl *>()) {
953 if (d->hasAttr<WeakRefAttr>()) {
955 "ConstantLValueEmitter: emit pointer base for weakref");
959 if (
auto *fd = dyn_cast<FunctionDecl>(d)) {
962 mlir::MLIRContext *mlirContext = builder.getContext();
968 cir::PointerType ptrTy =
969 mlir::isa<cir::PointerType>(destTy)
970 ? mlir::cast<cir::PointerType>(destTy)
971 : cir::PointerType::get(fop.getFunctionType());
972 mlir::StringAttr symName = fop.getSymNameAttr();
977 fd->hasAttr<CUDAGlobalAttr>())
978 symName = mlir::cast<cir::GlobalOp>(
981 return cir::GlobalViewAttr::get(
982 ptrTy, mlir::FlatSymbolRefAttr::get(mlirContext, symName));
985 if (
auto *vd = dyn_cast<VarDecl>(d)) {
987 if (!vd->hasLocalStorage()) {
988 if (vd->isFileVarDecl() || vd->hasExternalStorage())
991 if (vd->isLocalVarDecl()) {
1000 cgm.
errorNYI(d->getSourceRange(),
"ConstantLValueEmitter: MSGuidDecl");
1002 if (
const auto *gcd = dyn_cast<UnnamedGlobalConstantDecl>(d))
1006 if (
const auto *tpo = dyn_cast<TemplateParamObjectDecl>(d))
1014 if (TypeInfoLValue typeInfo = base.
dyn_cast<TypeInfoLValue>())
1016 cgm.
getBuilder().getUnknownLoc(), QualType(typeInfo.getType(), 0)));
1019 return Visit(base.
get<
const Expr *>());
1022ConstantLValue ConstantLValueEmitter::VisitConstantExpr(
const ConstantExpr *e) {
1027static cir::GlobalViewAttr
1042 "file-scope compound literal did not have constant initializer!");
1046 auto typedInit = mlir::cast<mlir::TypedAttr>(c);
1055 gv.setLinkage(cir::GlobalLinkageKind::InternalLinkage);
1056 gv.setAlignment(align.getAsAlign().value());
1065ConstantLValueEmitter::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *e) {
1066 ConstantEmitter compoundLiteralEmitter(cgm, emitter.
cgf);
1072ConstantLValueEmitter::VisitStringLiteral(
const StringLiteral *e) {
1077ConstantLValueEmitter::VisitObjCEncodeExpr(
const ObjCEncodeExpr *e) {
1083ConstantLValueEmitter::VisitObjCStringLiteral(
const ObjCStringLiteral *e) {
1085 "ConstantLValueEmitter: objc string literal");
1090ConstantLValueEmitter::VisitObjCBoxedExpr(
const ObjCBoxedExpr *e) {
1096ConstantLValueEmitter::VisitPredefinedExpr(
const PredefinedExpr *e) {
1101ConstantLValueEmitter::VisitAddrLabelExpr(
const AddrLabelExpr *e) {
1107 assert(emitter.
cgf &&
"label address in a constant requires a function");
1108 CIRGenFunction &cgf = *
const_cast<CIRGenFunction *
>(emitter.
cgf);
1110 return cir::BlockAddrInfoAttr::get(&cgf.
getMLIRContext(), func.getSymName(),
1114ConstantLValue ConstantLValueEmitter::VisitCallExpr(
const CallExpr *e) {
1119ConstantLValue ConstantLValueEmitter::VisitBlockExpr(
const BlockExpr *e) {
1125ConstantLValueEmitter::VisitCXXTypeidExpr(
const CXXTypeidExpr *e) {
1134ConstantLValue ConstantLValueEmitter::VisitMaterializeTemporaryExpr(
1135 const MaterializeTemporaryExpr *e) {
1139 return ConstantLValue(
1148 initializeNonAbstract();
1154 initializeNonAbstract();
1160 initializeNonAbstract();
1162 assert(c &&
"couldn't emit constant value non-abstractly?");
1167 assert(initializedNonAbstract &&
1168 "finalizing emitter that was used for abstract emission?");
1169 assert(!finalized &&
"finalizing emitter multiple times");
1170 assert(!gv.isDeclaration());
1179 AbstractStateRAII state(*
this,
true);
1184 assert((!initializedNonAbstract || finalized || failed) &&
1185 "not finalized after being initialized for non-abstract emission");
1189 mlir::Type baseType,
1193 bool asCompleteObject) {
1195 mlir::Type ty = (asCompleteObject ? layout.
getCIRType()
1197 auto recordTy = mlir::cast<cir::RecordType>(ty);
1199 unsigned numElements = rd->
isUnion() ? 1 : recordTy.getNumElements();
1202 auto *cxxrd = dyn_cast<CXXRecordDecl>(rd);
1206 if (base.isVirtual()) {
1223 mlir::Type baseType = recordTy.getElementType(fieldIndex);
1232 if (!field->isBitField() &&
1240 if (field->getIdentifier())
1242 if (
const auto *fieldRD = field->getType()->getAsRecordDecl())
1243 if (fieldRD->findFirstNamedDataMember())
1249 if (cxxrd && asCompleteObject) {
1251 cgm.
errorNYI(vbase.getSourceRange(),
"emitNullConstant: virtual base");
1256 mlir::MLIRContext *mlirContext = recordTy.getContext();
1264 return cir::ConstRecordAttr::get(
1265 recordTy, mlir::ArrayAttr::get(mlirContext, elements));
1274 return cir::ConstRecordAttr::get(
1275 recordTy, mlir::ArrayAttr::get(mlirContext, storedElements));
1280 mlir::Type baseType,
1300 if (
const auto *e = dyn_cast_or_null<CXXConstructExpr>(d.
getInit())) {
1303 return cgm.emitNullConstantAttr(d.
getType());
1310 assert(e &&
"No initializer to emit");
1316 if (mlir::Attribute c = ConstExprEmitter(*this).Visit(
const_cast<Expr *
>(e),
1331 AbstractStateRAII state{*
this,
true};
1341 retType =
cgm.getASTContext().getLValueReferenceType(retType);
1352 return mlir::cast<mlir::TypedAttr>(
attr);
1366 AbstractStateRAII state{*
this,
true};
1367 mlir::Attribute c = mlir::cast<mlir::Attribute>(
tryEmitPrivate(e, destType));
1370 "emitAbstract failed, emit null constaant");
1377 AbstractStateRAII state(*
this,
true);
1380 cgm.errorNYI(loc,
"emitAbstract failed, emit null constaant");
1387 cir::ConstantOp cstOp =
1388 cgm.emitNullConstant(t, loc).getDefiningOp<cir::ConstantOp>();
1389 assert(cstOp &&
"expected cir.const op");
1403 QualType destValueType = at->getValueType();
1406 uint64_t innerSize =
cgm.getASTContext().getTypeSize(destValueType);
1407 uint64_t outerSize =
cgm.getASTContext().getTypeSize(destType);
1408 if (innerSize == outerSize)
1411 assert(innerSize < outerSize &&
"emitted over-large constant for atomic");
1412 cgm.errorNYI(
"emitForMemory: tail padding in atomic initializer");
1418 cgm.errorNYI(
"emitForMemory: zero-extend HLSL bool vectors");
1431 assert(!destType->
isVoidType() &&
"can't emit a void constant");
1433 if (mlir::Attribute c =
1434 ConstExprEmitter(*this).Visit(
const_cast<Expr *
>(e), destType))
1435 return llvm::dyn_cast<mlir::TypedAttr>(c);
1439 bool success =
false;
1449 return llvm::dyn_cast<mlir::TypedAttr>(c);
1457 auto &builder =
cgm.getBuilder();
1461 cgm.errorNYI(
"ConstExprEmitter::tryEmitPrivate none or indeterminate");
1464 mlir::Type ty =
cgm.convertType(destType);
1465 if (mlir::isa<cir::BoolType>(ty))
1467 assert(mlir::isa<cir::IntType>(ty) &&
"expected integral type");
1468 return cir::IntAttr::get(ty, value.
getInt());
1471 mlir::Type ty =
cgm.convertType(destType);
1472 assert(mlir::isa<cir::FPTypeInterface>(ty) &&
1473 "expected floating-point type");
1474 return cir::FPAttr::get(ty, value.
getFloat());
1477 const ArrayType *arrayTy =
cgm.getASTContext().getAsArrayType(destType);
1482 mlir::TypedAttr filler;
1484 mlir::Attribute fillerTemp =
1488 filler = dyn_cast<mlir::TypedAttr>(fillerTemp);
1490 cgm.errorNYI(
"ConstExprEmitter::tryEmitPrivate array filler should "
1497 cir::ArrayType desiredType =
1502 elts.reserve(numInitElts);
1504 elts.reserve(numElements);
1507 for (
unsigned i = 0; i < numInitElts; ++i) {
1509 const mlir::Attribute element =
1514 elts.push_back(element);
1519 elts.insert(elts.end(), numElements - elts.size(), filler);
1522 while (!elts.empty() && builder.
isNullValue(elts.back()))
1527 if (desiredType.getSize() == 0 && numElements > 0) {
1529 cir::ArrayType::get(desiredType.getElementType(), numElements);
1533 return cir::ZeroAttr::get(desiredType);
1535 return cir::ConstArrayAttr::get(
1536 desiredType, mlir::ArrayAttr::get(builder.getContext(), elts));
1544 elements.reserve(numElements);
1546 for (
unsigned i = 0; i < numElements; ++i) {
1547 const mlir::Attribute element =
1551 elements.push_back(element);
1554 const auto desiredVecTy =
1555 mlir::cast<cir::VectorType>(
cgm.convertType(destType));
1557 return cir::ConstVectorAttr::get(
1559 mlir::ArrayAttr::get(
cgm.getBuilder().getContext(), elements));
1568 if (
auto const *cxxDecl = dyn_cast<CXXMethodDecl>(memberDecl)) {
1569 auto ty = mlir::cast<cir::MethodType>(
cgm.convertType(destType));
1570 if (cxxDecl->isVirtual())
1571 return cgm.getCXXABI().buildVirtualMethodAttr(ty, cxxDecl);
1573 cir::FuncOp methodFuncOp =
1574 cgm.getAddrOfFunction(cxxDecl, ty.getMemberFuncTy());
1575 return cgm.getBuilder().getMethodAttr(ty, methodFuncOp);
1578 auto cirTy = mlir::cast<cir::DataMemberType>(
cgm.convertType(destType));
1584 if (
const auto *
fieldDecl = dyn_cast<FieldDecl>(memberDecl);
1590 return cir::DataMemberOffsetAttr::get(cirTy, offset.
getQuantity());
1593 std::optional<llvm::SmallVector<int32_t>> path =
1594 cgm.buildMemberPath(destClass, memberDecl);
1600 return ConstantLValueEmitter(*
this, value, destType).tryEmit();
1603 return ConstRecordBuilder::buildRecord(*
this, value, destType);
1606 mlir::Type desiredType =
cgm.convertType(destType);
1607 auto complexType = mlir::dyn_cast<cir::ComplexType>(desiredType);
1609 mlir::Type complexElemTy =
complexType.getElementType();
1613 return cir::ConstComplexAttr::get(builder.getContext(),
complexType,
1614 cir::IntAttr::get(complexElemTy, real),
1615 cir::IntAttr::get(complexElemTy, imag));
1619 "expected floating-point type");
1622 return cir::ConstComplexAttr::get(builder.getContext(),
complexType,
1623 cir::FPAttr::get(complexElemTy, real),
1624 cir::FPAttr::get(complexElemTy, imag));
1627 mlir::Type ty =
cgm.convertType(destType);
1628 return cir::IntAttr::get(ty, value.
getFixedPoint().getValue());
1638 mlir::Type resultType =
cgm.getTypes().convertType(destType);
1639 auto intResultType = mlir::cast<cir::IntType>(resultType);
1641 return cir::BlockAddrDiffAttr::get(
1642 builder.getContext(), intResultType, func.getSymName(),
1647 cgm.errorNYI(
"ConstExprEmitter::tryEmitPrivate matrix");
1651 llvm_unreachable(
"std::meta::info is consteval-only type");
1653 llvm_unreachable(
"Unknown APValue kind");
1661 mlir::Location loc) {
1667 return builder.getConstNullPtrAttr(
getTypes().convertTypeForMem(t));
1669 if (
getTypes().isZeroInitializable(t))
1670 return builder.getZeroInitAttr(
getTypes().convertTypeForMem(t));
1674 QualType elementTy = cat->getElementType();
1679 auto arrayTy = mlir::cast<cir::ArrayType>(
getTypes().convertTypeForMem(t));
1681 if (builder.isNullValue(elementAttr))
1682 return cir::ZeroAttr::get(arrayTy);
1686 return cir::ConstArrayAttr::get(
1687 arrayTy, mlir::ArrayAttr::get(builder.getContext(), elements));
1690 if (
const RecordType *rt = t->
getAs<RecordType>())
1691 return ::emitNullConstant(*
this, rt->getDecl(),
true);
1694 "Should only see pointers to data members here!");
1701 return ::emitNullConstant(*
this, record,
false);
Defines the clang::ASTContext interface.
static StringRef bytes(const std::vector< T, Allocator > &v)
Defines enum values for all the target-independent builtin functions.
static void emit(Program &P, llvm::SmallVectorImpl< std::byte > &Code, const T &Val, bool &Success)
Helper to write bytecode and bail out if 32-bit offsets become invalid.
static QualType getNonMemoryType(CodeGenModule &CGM, QualType type)
static mlir::TypedAttr emitNullConstant(CIRGenModule &cgm, const RecordDecl *rd, bool asCompleteObject)
static mlir::TypedAttr emitNullConstantForBase(CIRGenModule &cgm, mlir::Type baseType, const CXXRecordDecl *baseDecl)
Emit the null constant for a base subobject.
static bool collectStoredInitializers(CIRGenBuilderTy &builder, cir::RecordType recordTy, llvm::ArrayRef< mlir::Attribute > elements, llvm::SmallVectorImpl< mlir::Attribute > &stored)
Collects the initializer elements for the members of recordTy that are stored, in order,...
static cir::GlobalViewAttr tryEmitGlobalCompoundLiteral(ConstantEmitter &emitter, const CompoundLiteralExpr *e)
static ParseState advance(ParseState S, size_t N)
cir::GlobalViewAttr getGlobalViewAttr(cir::GlobalOp globalOp, mlir::ArrayAttr indices={})
Get constant address of a global variable as an MLIR attribute.
cir::BoolAttr getCIRBoolAttr(bool state)
mlir::TypedAttr getZeroInitAttr(mlir::Type ty)
mlir::TypedAttr getConstPtrAttr(mlir::Type type, int64_t value)
C++ view class that accepts both !cir.struct and !cir.union types.
llvm::ArrayRef< mlir::Type > getMembers() const
size_t getNumElements() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool hasArrayFiller() const
const LValueBase getLValueBase() const
APValue & getArrayInitializedElt(unsigned I)
APSInt & getComplexIntImag()
ValueKind getKind() const
unsigned getArrayInitializedElts() const
APFixedPoint & getFixedPoint()
const ValueDecl * getMemberPointerDecl() const
const AddrLabelExpr * getAddrLabelDiffRHS() const
APValue & getVectorElt(unsigned I)
APValue & getArrayFiller()
unsigned getVectorLength() const
unsigned getArraySize() const
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
@ None
There is no such object (it's outside its lifetime).
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
const AddrLabelExpr * getAddrLabelDiffLHS() 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.
CharUnits getMemberPointerPathAdjustment(const APValue &MP) const
Find the 'this' offset for the member path in a pointer-to-member APValue.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
bool hasOwnVFPtr() const
hasOwnVFPtr - Does this class provide its own virtual-function table pointer, rather than inheriting ...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getNonVirtualSize() const
getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...
AddrLabelExpr - The GNU address of label extension, representing &&label.
LabelDecl * getLabel() const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
cir::IntType getUInt8Ty()
cir::DataMemberAttr getDataMemberAttr(cir::DataMemberType ty, llvm::ArrayRef< int32_t > path)
mlir::Attribute getConstRecordOrZeroAttr(mlir::ArrayAttr arrayAttr, cir::RecordType recordTy)
bool isNullValue(mlir::Attribute attr) const
cir::IntType getUIntNTy(int n)
virtual mlir::Operation * getKernelHandle(cir::FuncOp fn, GlobalDecl gd)=0
virtual mlir::Value getVTableAddressPoint(BaseSubobject base, const CXXRecordDecl *vtableClass)=0
Get the address point of the vtable for the given base subobject.
mlir::Operation * curFn
The current function or global initializer that is generated code for.
mlir::MLIRContext & getMLIRContext()
This class organizes the cross-function state that is used while generating CIR code.
cir::GlobalOp getAddrOfUnnamedGlobalConstantDecl(const UnnamedGlobalConstantDecl *gcd)
mlir::Value getNullPointer(cir::PointerType ptrTy, QualType qt, mlir::Location loc)
Get target specific null pointer.
cir::GlobalOp getOrCreateStaticVarDecl(const VarDecl &d, cir::GlobalLinkageKind linkage)
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
cir::GlobalLinkageKind getCIRLinkageVarDefinition(const VarDecl *vd)
clang::ASTContext & getASTContext() const
CIRGenCUDARuntime & getCUDARuntime()
CIRGenBuilderTy & getBuilder()
std::string getUniqueGlobalName(const std::string &baseName)
cir::GlobalOp getAddrOfTemplateParamObject(const TemplateParamObjectDecl *tpo)
Get the GlobalOp of a template parameter object.
mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty, bool forEH=false)
Get the address of the RTTI descriptor for the given type.
mlir::TypedAttr emitNullConstantForBase(const CXXRecordDecl *record)
Return a null constant appropriate for zero-initializing a base class with the given type.
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::TypedAttr emitNullConstantAttr(QualType t)
const cir::CIRDataLayout getDataLayout() const
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...
static void setInitializer(cir::GlobalOp &op, mlir::Attribute value)
cir::GlobalViewAttr getAddrOfGlobalVarAttr(const VarDecl *d)
Return the mlir::GlobalViewAttr for the address of the given global.
const clang::LangOptions & getLangOpts() const
cir::GlobalOp createGlobalOp(mlir::Location loc, llvm::StringRef name, mlir::Type t, bool isConstant=false, mlir::ptr::MemorySpaceAttrInterface addrSpace={}, mlir::Operation *insertPoint=nullptr)
const TargetCIRGenInfo & getTargetCIRGenInfo()
mlir::Location getLoc(clang::SourceLocation cLoc)
Helpers to convert the presumed location of Clang's SourceLocation to an MLIR Location.
mlir::TypedAttr emitNullMemberAttr(QualType t, const MemberPointerType *mpt)
Returns a null attribute to represent either a null method or null data member, depending on the type...
cir::GlobalOp getAddrOfConstantCompoundLiteralIfEmitted(const CompoundLiteralExpr *e)
mlir::Value emitNullConstant(QualType t, mlir::Location loc)
Return the result of value-initializing the given type, i.e.
CIRGenCXXABI & getCXXABI() const
cir::GlobalViewAttr getAddrOfConstantStringFromLiteral(const StringLiteral *s, llvm::StringRef name=".str")
Return a global symbol reference to a constant array for the given string literal.
void setAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *e, cir::GlobalOp gv)
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.
cir::RecordType getBaseSubobjectCIRType() const
Return the "base subobject" LLVM type associated with this record.
bool hasNonVirtualBaseCIRField(const CXXRecordDecl *rd) const
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
bool isZeroInitializableAsBase() const
Check whether this struct can be C++ zero-initialized with a zeroinitializer when considered as a bas...
unsigned getNonVirtualBaseCIRFieldNo(const CXXRecordDecl *rd) const
const CIRGenRecordLayout & getCIRGenRecordLayout(const clang::RecordDecl *rd)
Return record layout info for the given record decl.
mlir::Type convertTypeForMem(clang::QualType, bool forBitField=false)
Convert type T into an mlir::Type.
void finalize(cir::GlobalOp gv)
mlir::Attribute emitForMemory(mlir::Attribute c, QualType destType)
mlir::Attribute emitNullForMemory(mlir::Location loc, QualType t)
mlir::TypedAttr tryEmitPrivate(const Expr *e, QualType destType)
mlir::Attribute tryEmitPrivateForVarInit(const VarDecl &d)
mlir::Attribute tryEmitPrivateForMemory(const Expr *e, QualType destTy)
mlir::Attribute emitAbstract(const Expr *e, QualType destType)
Emit the result of the given expression as an abstract constant, asserting that it succeeded.
bool isInConstantContext() const
mlir::Attribute tryEmitAbstract(const Expr *e, QualType destType)
const CIRGenFunction * cgf
mlir::Attribute tryEmitForInitializer(const VarDecl &d)
Try to emit the initializer of the given declaration as an abstract constant.
mlir::Attribute tryEmitAbstractForInitializer(const VarDecl &d)
Try to emit the initializer of the given declaration as an abstract constant.
mlir::Attribute emitForInitializer(const APValue &value, QualType destType)
mlir::Attribute tryEmitConstantExpr(const ConstantExpr *ce)
Represents a base class of a C++ class.
Expr * getArg(unsigned Arg)
Return the specified argument.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ constructor within a class.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
Expr * getExpr()
Get the initialization expression that will be used.
Represents a C++ struct/union/class.
bool isTypeOperand() const
QualType getTypeOperand(const ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
Expr * getExprOperand() const
SourceRange getSourceRange() const LLVM_READONLY
CastKind getCastKind() const
This is an opaque type for sizes expressed in character units.
bool isZero() const
Test whether the quantity equals zero.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits Zero()
Construct a CharUnits quantity of zero.
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
CompoundLiteralExpr - [C99 6.5.2.5].
const Expr * getInitializer() const
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Represents the canonical version of C arrays with a specified constant size.
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
APValue getAPValueResult() const
SourceLocation getBeginLoc() const LLVM_READONLY
bool hasAPValueResult() const
SourceLocation getBeginLoc() const LLVM_READONLY
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...
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...
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
bool isZeroSize(const ASTContext &Ctx) const
Determine if this field is a subobject of zero size, that is, either a zero-length bit-field or a fie...
bool isUnnamedBitField() const
Determines whether this is an unnamed bitfield.
bool isPotentiallyOverlapping() const
Determine if this field is of potentially-overlapping class type, that is, subobject with the [[no_un...
const Expr * getSubExpr() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Expr * getResultExpr()
Return the result expression of this controlling expression.
Describes an C or C++ initializer list.
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
const Expr * getInit(unsigned Init) const
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.
A pointer to member type per C++ 8.3.3 - Pointers to members.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation getBeginLoc() const LLVM_READONLY
const Expr * getSubExpr() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
StringLiteral * getFunctionName()
A (possibly-)qualified type.
PointerAuthQualifier getPointerAuth() const
bool isConstantStorage(const ASTContext &Ctx, bool ExcludeCtor, bool ExcludeDtor)
Represents a struct/union/class.
field_range fields() const
Encodes a location in the source.
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
Expr * getReplacement() const
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
CXXRecordDecl * castAsCXXRecordDecl() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isExtVectorBoolType() const
bool isMemberDataPointerType() const
RecordDecl * castAsRecordDecl() const
bool isVectorType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
Expr * getSubExpr() const
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.
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
const Expr * getInit() const
const APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
Represents a GCC generic vector type.
mlir::Type memberStorageType(mlir::Type memberTy)
The storage a member is stored as: the access unit for a bit-field member, and the member type itself...
bool memberOwnsBytes(mlir::Type memberTy)
Whether a record member occupies bytes of its record.
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...
bool isEmptyRecordForLayout(const ASTContext &Ctx, QualType T)
Return true iff a structure contains only empty base classes (per isEmptyRecordForLayout) and fields ...
const internal::VariadicAllOfMatcher< Attr > attr
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ComplexType > complexType
const internal::VariadicDynCastAllOfMatcher< Decl, FieldDecl > fieldDecl
Matches field declarations.
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ SD_Static
Static storage duration.
U cast(CodeGen::Address addr)
__DEVICE__ _Tp arg(const std::complex< _Tp > &__c)
static bool ctorConstLvalueToRvalueConversion()
static bool addressSpace()
static bool addressPointerAuthInfo()
static bool constEmitterArrayILE()
static bool constEmitterVectorILE()
Record with information about how a bitfield should be accessed.
unsigned offset
The offset within a contiguous run of bitfields that are represented as a single "field" within the c...
unsigned storageSize
The storage size in bits which should be used when accessing this bitfield.
unsigned size
The total size of the bit-field, in bits.
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() const
Return true if the evaluated expression has side effects.