18#include "mlir/IR/Attributes.h"
19#include "mlir/IR/BuiltinAttributeInterfaces.h"
20#include "mlir/IR/BuiltinAttributes.h"
32#include "llvm/ADT/ArrayRef.h"
33#include "llvm/ADT/STLExtras.h"
34#include "llvm/Support/ErrorHandling.h"
46class ConstExprEmitter;
54 return bld.
getConstArray(mlir::ArrayAttr::get(bld.getContext(), elts),
55 cir::ArrayType::get(eltTy, arSize));
58 return cir::ZeroAttr::get(eltTy);
62emitArrayConstant(
CIRGenModule &cgm, mlir::Type desiredType,
63 mlir::Type commonElementType,
unsigned arrayBound,
65 mlir::TypedAttr filler);
67struct ConstantAggregateBuilderUtils {
69 cir::CIRDataLayout dataLayout;
71 ConstantAggregateBuilderUtils(CIRGenModule &cgm)
72 : cgm(cgm), dataLayout{cgm.getModule()} {}
74 CharUnits getAlignment(
const mlir::TypedAttr
c)
const {
76 dataLayout.getAlignment(
c.getType(),
true));
79 CharUnits getSize(mlir::Type ty)
const {
83 CharUnits getSize(
const mlir::TypedAttr
c)
const {
84 return getSize(
c.getType());
87 mlir::TypedAttr getPadding(CharUnits size)
const {
88 return computePadding(cgm, size);
94class ConstantAggregateBuilder :
private ConstantAggregateBuilderUtils {
96 Element(mlir::TypedAttr element, CharUnits offset)
97 : element(element), offset(offset) {}
99 mlir::TypedAttr element;
110 llvm::SmallVector<Element, 32> elements;
119 bool naturalLayout =
true;
121 bool split(
size_t index, CharUnits hint);
122 std::optional<size_t> splitAt(CharUnits pos);
124 static mlir::Attribute buildFrom(CIRGenModule &cgm, ArrayRef<Element> elems,
125 CharUnits startOffset, CharUnits size,
126 bool naturalLayout, mlir::Type desiredTy,
127 bool allowOversized);
130 ConstantAggregateBuilder(CIRGenModule &cgm)
131 : ConstantAggregateBuilderUtils(cgm) {}
138 bool add(mlir::TypedAttr typedAttr, CharUnits offset,
bool allowOverwrite);
141 bool addBits(llvm::APInt bits, uint64_t offsetInBits,
bool allowOverwrite);
145 void condense(CharUnits offset, mlir::Type desiredTy);
152 mlir::Attribute build(mlir::Type desiredTy,
bool allowOversized)
const {
153 return buildFrom(cgm, elements,
CharUnits::Zero(), size, naturalLayout,
154 desiredTy, allowOversized);
158template <
typename Container,
typename Range = std::initializer_list<
159 typename Container::value_type>>
160static void replace(Container &
c,
size_t beginOff,
size_t endOff, Range vals) {
161 assert(beginOff <= endOff &&
"invalid replacement range");
162 llvm::replace(
c,
c.begin() + beginOff,
c.begin() + endOff, vals);
165bool ConstantAggregateBuilder::add(mlir::TypedAttr typedAttr,
CharUnits offset,
166 bool allowOverwrite) {
168 if (offset >= size) {
169 CharUnits
align = getAlignment(typedAttr);
170 CharUnits alignedSize = size.
alignTo(align);
171 if (alignedSize > offset || offset.
alignTo(align) != offset) {
172 naturalLayout =
false;
173 }
else if (alignedSize < offset) {
174 elements.emplace_back(getPadding(offset - size), size);
176 elements.emplace_back(typedAttr, offset);
177 size = offset + getSize(typedAttr);
182 std::optional<size_t> firstElemToReplace = splitAt(offset);
183 if (!firstElemToReplace)
186 CharUnits cSize = getSize(typedAttr);
187 std::optional<size_t> lastElemToReplace = splitAt(offset + cSize);
188 if (!lastElemToReplace)
191 assert((firstElemToReplace == lastElemToReplace || allowOverwrite) &&
192 "unexpectedly overwriting field");
194 Element newElt(typedAttr, offset);
195 replace(elements, *firstElemToReplace, *lastElemToReplace, {newElt});
196 size = std::max(size, offset + cSize);
197 naturalLayout =
false;
201bool ConstantAggregateBuilder::addBits(llvm::APInt bits, uint64_t offsetInBits,
202 bool allowOverwrite) {
209 unsigned offsetWithinChar = offsetInBits % charWidth;
213 for (CharUnits offsetInChars =
217 unsigned wantedBits =
218 std::min((uint64_t)bits.getBitWidth(), charWidth - offsetWithinChar);
222 llvm::APInt bitsThisChar = bits;
223 if (bitsThisChar.getBitWidth() < charWidth)
224 bitsThisChar = bitsThisChar.zext(charWidth);
228 int shift = bits.getBitWidth() - charWidth + offsetWithinChar;
230 bitsThisChar.lshrInPlace(shift);
232 bitsThisChar = bitsThisChar.shl(-shift);
234 bitsThisChar = bitsThisChar.shl(offsetWithinChar);
236 if (bitsThisChar.getBitWidth() > charWidth)
237 bitsThisChar = bitsThisChar.trunc(charWidth);
239 if (wantedBits == charWidth) {
241 add(cir::IntAttr::get(charTy, bitsThisChar), offsetInChars,
247 std::optional<size_t> firstElemToUpdate = splitAt(offsetInChars);
248 if (!firstElemToUpdate)
250 std::optional<size_t> lastElemToUpdate =
252 if (!lastElemToUpdate)
254 assert(*lastElemToUpdate - *firstElemToUpdate < 2 &&
255 "should have at most one element covering one byte");
258 llvm::APInt updateMask(charWidth, 0);
260 updateMask.setBits(charWidth - offsetWithinChar - wantedBits,
261 charWidth - offsetWithinChar);
263 updateMask.setBits(offsetWithinChar, offsetWithinChar + wantedBits);
264 bitsThisChar &= updateMask;
266 if (*firstElemToUpdate < elements.size()) {
267 auto firstEltToUpdate =
268 mlir::dyn_cast<cir::IntAttr>(elements[*firstElemToUpdate].element);
269 isNull = firstEltToUpdate && firstEltToUpdate.isNullValue();
272 if (*firstElemToUpdate == *lastElemToUpdate || isNull) {
274 add(cir::IntAttr::get(charTy, bitsThisChar), offsetInChars,
278 mlir::dyn_cast<cir::IntAttr>(elements[*firstElemToUpdate].element);
285 assert(ci.getBitWidth() == charWidth &&
"splitAt failed");
286 assert((!(ci.getValue() & updateMask) || allowOverwrite) &&
287 "unexpectedly overwriting bitfield");
288 bitsThisChar |= (ci.getValue() & ~updateMask);
289 elements[*firstElemToUpdate].element =
290 cir::IntAttr::get(charTy, bitsThisChar);
295 if (wantedBits == bits.getBitWidth())
300 bits.lshrInPlace(wantedBits);
301 bits = bits.trunc(bits.getBitWidth() - wantedBits);
304 offsetWithinChar = 0;
314std::optional<size_t> ConstantAggregateBuilder::splitAt(CharUnits pos) {
316 return elements.size();
321 llvm::upper_bound(elements, pos, [](CharUnits pos,
const Element &elt) {
322 return pos < elt.offset;
325 if (iter == elements.begin())
328 size_t index = iter - elements.begin() - 1;
329 const Element &elt = elements[index];
332 if (elt.offset == pos)
336 CharUnits eltEnd = elt.offset + getSize(elt.element);
341 if (!split(index, pos))
349bool ConstantAggregateBuilder::split(
size_t index, CharUnits hint) {
350 cgm.
errorNYI(
"split constant at index");
354void ConstantAggregateBuilder::condense(CharUnits offset,
355 mlir::Type desiredTy) {
356 CharUnits desiredSize = getSize(desiredTy);
358 std::optional<size_t> firstElemToReplace = splitAt(offset);
359 if (!firstElemToReplace)
361 size_t first = *firstElemToReplace;
363 std::optional<size_t> lastElemToReplace = splitAt(offset + desiredSize);
364 if (!lastElemToReplace)
366 size_t last = *lastElemToReplace;
368 size_t length = last - first;
372 if (
length == 1 && elements[first].offset == offset &&
373 getSize(elements[first].element) == desiredSize) {
374 cgm.
errorNYI(
"re-wrapping single element records");
379 SmallVector<Element> subElems(elements.begin() + first,
380 elements.begin() + last);
381 mlir::Attribute replacement =
382 buildFrom(cgm, subElems, offset, desiredSize,
383 false, desiredTy,
false);
386 Element newElt(mlir::cast<mlir::TypedAttr>(replacement), offset);
387 replace(elements, first, last, {newElt});
391ConstantAggregateBuilder::buildFrom(CIRGenModule &cgm, ArrayRef<Element> elems,
392 CharUnits startOffset, CharUnits size,
393 bool naturalLayout, mlir::Type desiredTy,
394 bool allowOversized) {
395 ConstantAggregateBuilderUtils utils(cgm);
398 return cir::UndefAttr::get(desiredTy);
402 if (mlir::isa<cir::ArrayType>(desiredTy)) {
403 cgm.
errorNYI(
"array aggregate constants");
410 CharUnits desiredSize = utils.getSize(desiredTy);
411 if (size > desiredSize) {
412 assert(allowOversized &&
"elems are oversized");
418 for (
auto [e, offset] : elems)
419 align = std::max(align, utils.getAlignment(e));
422 CharUnits alignedSize = size.
alignTo(align);
427 llvm::SmallVector<mlir::Attribute, 32> unpackedElems;
428 if (desiredSize < alignedSize || desiredSize.
alignTo(align) != desiredSize) {
429 naturalLayout =
false;
434 unpackedElems.reserve(elems.size() + 1);
435 llvm::transform(elems, std::back_inserter(unpackedElems),
436 std::mem_fn(&Element::element));
437 if (desiredSize > alignedSize)
438 unpackedElems.push_back(utils.getPadding(desiredSize - size));
444 llvm::SmallVector<mlir::Attribute, 32> packedElems;
445 packedElems.reserve(elems.size());
446 if (!naturalLayout) {
448 for (
auto [element, offset] : elems) {
449 CharUnits
align = utils.getAlignment(element);
450 CharUnits naturalOffset = sizeSoFar.
alignTo(align);
451 CharUnits desiredOffset = offset - startOffset;
452 assert(desiredOffset >= sizeSoFar &&
"elements out of order");
454 if (desiredOffset != naturalOffset)
456 if (desiredOffset != sizeSoFar)
457 packedElems.push_back(utils.getPadding(desiredOffset - sizeSoFar));
458 packedElems.push_back(element);
459 sizeSoFar = desiredOffset + utils.getSize(element);
464 assert(sizeSoFar <= desiredSize &&
465 "requested size is too small for contents");
467 if (sizeSoFar < desiredSize)
468 packedElems.push_back(utils.getPadding(desiredSize - sizeSoFar));
473 auto arrAttr = mlir::ArrayAttr::get(builder.getContext(),
474 packed ? packedElems : unpackedElems);
477 if (
auto desired = mlir::dyn_cast<cir::RecordType>(desiredTy))
488class ConstRecordBuilder {
490 ConstantEmitter &emitter;
491 ConstantAggregateBuilder &builder;
492 CharUnits startOffset;
495 static mlir::Attribute buildRecord(ConstantEmitter &emitter,
496 InitListExpr *ile, QualType valTy);
497 static mlir::Attribute buildRecord(ConstantEmitter &emitter,
498 const APValue &value, QualType valTy);
499 static bool updateRecord(ConstantEmitter &emitter,
500 ConstantAggregateBuilder &constant, CharUnits offset,
501 InitListExpr *updater);
504 ConstRecordBuilder(ConstantEmitter &emitter,
505 ConstantAggregateBuilder &builder, CharUnits startOffset)
506 : cgm(emitter.cgm), emitter(emitter), builder(builder),
507 startOffset(startOffset) {}
509 bool appendField(
const FieldDecl *field, uint64_t fieldOffset,
510 mlir::TypedAttr initCst,
bool allowOverwrite =
false);
512 bool appendBytes(CharUnits fieldOffsetInChars, mlir::TypedAttr initCst,
513 bool allowOverwrite =
false);
515 bool appendBitField(
const FieldDecl *field, uint64_t fieldOffset,
516 cir::IntAttr ci,
bool allowOverwrite =
false);
526 bool applyZeroInitPadding(
const ASTRecordLayout &layout,
unsigned fieldNo,
527 const FieldDecl &field,
bool allowOverwrite,
528 CharUnits &sizeSoFar,
bool &zeroFieldSize);
535 bool applyZeroInitPadding(
const ASTRecordLayout &layout,
bool allowOverwrite,
536 CharUnits &sizeSoFar);
538 bool build(InitListExpr *ile,
bool allowOverwrite);
539 bool build(
const APValue &val,
const RecordDecl *rd,
bool isPrimaryBase,
540 const CXXRecordDecl *vTableClass, CharUnits baseOffset);
542 mlir::Attribute
finalize(QualType ty);
545bool ConstRecordBuilder::appendField(
const FieldDecl *field,
546 uint64_t fieldOffset,
547 mlir::TypedAttr initCst,
548 bool allowOverwrite) {
553 return appendBytes(fieldOffsetInChars, initCst, allowOverwrite);
556bool ConstRecordBuilder::appendBytes(CharUnits fieldOffsetInChars,
557 mlir::TypedAttr initCst,
558 bool allowOverwrite) {
559 return builder.add(initCst, startOffset + fieldOffsetInChars, allowOverwrite);
562bool ConstRecordBuilder::appendBitField(
const FieldDecl *field,
563 uint64_t fieldOffset, cir::IntAttr ci,
564 bool allowOverwrite) {
565 const CIRGenRecordLayout &rl =
568 llvm::APInt fieldValue = ci.getValue();
574 if (info.
size > fieldValue.getBitWidth())
575 fieldValue = fieldValue.zext(info.
size);
578 if (info.
size < fieldValue.getBitWidth())
579 fieldValue = fieldValue.trunc(info.
size);
581 return builder.addBits(fieldValue,
586bool ConstRecordBuilder::applyZeroInitPadding(
587 const ASTRecordLayout &layout,
unsigned fieldNo,
const FieldDecl &field,
588 bool allowOverwrite, CharUnits &sizeSoFar,
bool &zeroFieldSize) {
590 CharUnits startOffset =
592 if (sizeSoFar < startOffset) {
593 if (!appendBytes(sizeSoFar, computePadding(cgm, startOffset - sizeSoFar),
599 CharUnits fieldSize =
601 sizeSoFar = startOffset + fieldSize;
602 zeroFieldSize = fieldSize.isZero();
604 const CIRGenRecordLayout &rl =
611 zeroFieldSize = info.
size == 0;
616bool ConstRecordBuilder::applyZeroInitPadding(
const ASTRecordLayout &layout,
618 CharUnits &sizeSoFar) {
619 CharUnits totalSize = layout.
getSize();
620 if (sizeSoFar < totalSize) {
621 if (!appendBytes(sizeSoFar, computePadding(cgm, totalSize - sizeSoFar),
625 sizeSoFar = totalSize;
629bool ConstRecordBuilder::build(InitListExpr *ile,
bool allowOverwrite) {
636 if (
auto *cxxrd = dyn_cast<CXXRecordDecl>(rd))
637 if (cxxrd->getNumBases())
641 bool zeroFieldSize =
false;
644 unsigned elementNo = 0;
645 for (
auto [index, field] : llvm::enumerate(rd->
fields())) {
658 Expr *init =
nullptr;
659 if (elementNo < ile->getNumInits())
660 init = ile->
getInit(elementNo++);
661 if (isa_and_nonnull<NoInitExpr>(init))
672 if (zeroInitPadding &&
673 !applyZeroInitPadding(layout, index, *field, allowOverwrite, sizeSoFar,
680 if (allowOverwrite &&
686 mlir::Attribute eltInitAttr =
693 mlir::TypedAttr eltInit = mlir::cast<mlir::TypedAttr>(eltInitAttr);
701 if (field->
hasAttr<NoUniqueAddressAttr>())
702 allowOverwrite =
true;
705 if (
auto constInt = dyn_cast<cir::IntAttr>(eltInit)) {
706 if (!appendBitField(field, layout.
getFieldOffset(index), constInt,
717 return !zeroInitPadding ||
718 applyZeroInitPadding(layout, allowOverwrite, sizeSoFar);
723 BaseInfo(
const CXXRecordDecl *decl, CharUnits offset,
unsigned index)
724 : decl(decl), offset(offset), index(index) {}
726 const CXXRecordDecl *decl;
730 bool operator<(
const BaseInfo &o)
const {
return offset < o.offset; }
734bool ConstRecordBuilder::build(
const APValue &val,
const RecordDecl *rd,
736 const CXXRecordDecl *vTableClass,
739 if (
const CXXRecordDecl *cd = dyn_cast<CXXRecordDecl>(rd)) {
743 cir::GlobalOp vtable =
745 clang::VTableLayout::AddressPointLocation addressPoint =
750 mlir::ArrayAttr indices = builder.getArrayAttr({
751 builder.getI32IntegerAttr(addressPoint.
VTableIndex),
754 cir::GlobalViewAttr vtableInit =
756 if (!appendBytes(offset, vtableInit))
762 SmallVector<BaseInfo> bases;
763 bases.reserve(cd->getNumBases());
764 for (
auto [index, base] : llvm::enumerate(cd->bases())) {
765 assert(!base.isVirtual() &&
"should not have virtual bases here");
766 const CXXRecordDecl *bd = base.getType()->getAsCXXRecordDecl();
768 bases.push_back(BaseInfo(bd, baseOffset, index));
770#ifdef EXPENSIVE_CHECKS
771 assert(llvm::is_sorted(bases) &&
"bases not sorted by offset");
774 for (BaseInfo &base : bases) {
776 build(val.
getStructBase(base.index), base.decl, isPrimaryBase,
777 vTableClass, offset + base.offset);
783 bool allowOverwrite =
false;
784 for (
auto [index, field] : llvm::enumerate(rd->
fields())) {
796 mlir::TypedAttr eltInit = mlir::cast<mlir::TypedAttr>(
803 if (!appendField(field, layout.
getFieldOffset(index) + offsetBits,
804 eltInit, allowOverwrite))
808 if (field->
hasAttr<NoUniqueAddressAttr>())
809 allowOverwrite =
true;
812 if (
auto constInt = dyn_cast<cir::IntAttr>(eltInit)) {
813 if (!appendBitField(field, layout.
getFieldOffset(index) + offsetBits,
814 constInt, allowOverwrite))
827mlir::Attribute ConstRecordBuilder::finalize(QualType
type) {
835mlir::Attribute ConstRecordBuilder::buildRecord(ConstantEmitter &emitter,
838 ConstantAggregateBuilder constant(emitter.
cgm);
841 if (!builder.build(ile,
false))
844 return builder.finalize(valTy);
847mlir::Attribute ConstRecordBuilder::buildRecord(ConstantEmitter &emitter,
850 ConstantAggregateBuilder constant(emitter.
cgm);
853 const RecordDecl *rd =
854 valTy->
castAs<clang::RecordType>()->getDecl()->getDefinitionOrSelf();
855 const CXXRecordDecl *cd = dyn_cast<CXXRecordDecl>(rd);
859 return builder.finalize(valTy);
862bool ConstRecordBuilder::updateRecord(ConstantEmitter &emitter,
863 ConstantAggregateBuilder &constant,
864 CharUnits offset, InitListExpr *updater) {
865 return ConstRecordBuilder(emitter, constant, offset)
866 .build(updater,
true);
880class ConstExprEmitter
881 :
public StmtVisitor<ConstExprEmitter, mlir::Attribute, QualType> {
883 [[maybe_unused]] ConstantEmitter &emitter;
886 ConstExprEmitter(ConstantEmitter &emitter)
887 : cgm(emitter.cgm), emitter(emitter) {}
893 mlir::Attribute VisitStmt(Stmt *
s, QualType t) {
return {}; }
895 mlir::Attribute VisitConstantExpr(ConstantExpr *ce, QualType t) {
901 mlir::Attribute VisitParenExpr(ParenExpr *pe, QualType t) {
906 VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *pe,
911 mlir::Attribute VisitGenericSelectionExpr(GenericSelectionExpr *ge,
916 mlir::Attribute VisitChooseExpr(ChooseExpr *ce, QualType t) {
920 mlir::Attribute VisitCompoundLiteralExpr(CompoundLiteralExpr *e, QualType t) {
924 mlir::Attribute VisitCastExpr(
CastExpr *e, QualType destType) {
925 if (
const auto *ece = dyn_cast<ExplicitCastExpr>(e))
927 const_cast<CIRGenFunction *
>(emitter.
cgf));
933 case CK_AddressSpaceConversion:
934 case CK_ReinterpretMemberPointer:
935 case CK_DerivedToBaseMemberPointer:
936 case CK_BaseToDerivedMemberPointer:
940 case CK_LValueToRValue:
941 case CK_AtomicToNonAtomic:
942 case CK_NonAtomicToAtomic:
944 case CK_ConstructorConversion:
945 return Visit(subExpr, destType);
947 case CK_IntToOCLSampler:
948 llvm_unreachable(
"global sampler variables are not generated");
951 llvm_unreachable(
"saw dependent cast!");
953 case CK_BuiltinFnToFnPtr:
954 llvm_unreachable(
"builtin functions are handled elsewhere");
957 case CK_ObjCObjectLValueCast:
958 case CK_ARCProduceObject:
959 case CK_ARCConsumeObject:
960 case CK_ARCReclaimReturnedObject:
961 case CK_ARCExtendBlockObject:
962 case CK_CopyAndAutoreleaseBlockObject:
970 case CK_LValueBitCast:
971 case CK_LValueToRValueBitCast:
972 case CK_NullToMemberPointer:
973 case CK_UserDefinedConversion:
974 case CK_CPointerToObjCPointerCast:
975 case CK_BlockPointerToObjCPointerCast:
976 case CK_AnyPointerToBlockPointerCast:
977 case CK_ArrayToPointerDecay:
978 case CK_FunctionToPointerDecay:
979 case CK_BaseToDerived:
980 case CK_DerivedToBase:
981 case CK_UncheckedDerivedToBase:
982 case CK_MemberPointerToBoolean:
984 case CK_FloatingRealToComplex:
985 case CK_FloatingComplexToReal:
986 case CK_FloatingComplexToBoolean:
987 case CK_FloatingComplexCast:
988 case CK_FloatingComplexToIntegralComplex:
989 case CK_IntegralRealToComplex:
990 case CK_IntegralComplexToReal:
991 case CK_IntegralComplexToBoolean:
992 case CK_IntegralComplexCast:
993 case CK_IntegralComplexToFloatingComplex:
994 case CK_PointerToIntegral:
995 case CK_PointerToBoolean:
996 case CK_NullToPointer:
997 case CK_IntegralCast:
998 case CK_BooleanToSignedIntegral:
999 case CK_IntegralToPointer:
1000 case CK_IntegralToBoolean:
1001 case CK_IntegralToFloating:
1002 case CK_FloatingToIntegral:
1003 case CK_FloatingToBoolean:
1004 case CK_FloatingCast:
1005 case CK_FloatingToFixedPoint:
1006 case CK_FixedPointToFloating:
1007 case CK_FixedPointCast:
1008 case CK_FixedPointToBoolean:
1009 case CK_FixedPointToIntegral:
1010 case CK_IntegralToFixedPoint:
1011 case CK_ZeroToOCLOpaqueType:
1013 case CK_HLSLArrayRValue:
1014 case CK_HLSLVectorTruncation:
1015 case CK_HLSLElementwiseCast:
1016 case CK_HLSLAggregateSplatCast:
1019 llvm_unreachable(
"Invalid CastKind");
1022 mlir::Attribute VisitCXXDefaultInitExpr(CXXDefaultInitExpr *die, QualType t) {
1025 return Visit(die->
getExpr(), t);
1028 mlir::Attribute VisitExprWithCleanups(ExprWithCleanups *e, QualType t) {
1033 mlir::Attribute VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *e,
1038 mlir::Attribute VisitImplicitValueInitExpr(ImplicitValueInitExpr *e,
1043 mlir::Attribute VisitInitListExpr(InitListExpr *ile, QualType t) {
1045 return Visit(ile->
getInit(0), t);
1055 return ConstRecordBuilder::buildRecord(emitter, ile, t);
1068 mlir::Attribute VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *e,
1069 QualType destType) {
1070 mlir::Attribute
c = Visit(e->
getBase(), destType);
1075 "ConstExprEmitter::VisitDesignatedInitUpdateExpr");
1079 mlir::Attribute VisitCXXConstructExpr(CXXConstructExpr *e, QualType ty) {
1085 assert(e->
getNumArgs() == 1 &&
"trivial ctor with > 1 argument");
1087 "trivial ctor has argument but isn't a copy/move ctor");
1091 "argument to copy ctor is of wrong type");
1095 if (
auto const *mte = dyn_cast<MaterializeTemporaryExpr>(arg))
1096 return Visit(mte->getSubExpr(), ty);
1109 mlir::Attribute VisitStringLiteral(StringLiteral *e, QualType t) {
1114 mlir::Attribute VisitObjCEncodeExpr(ObjCEncodeExpr *e, QualType t) {
1119 mlir::Attribute VisitUnaryExtension(
const UnaryOperator *e, QualType t) {
1124 mlir::Type convertType(QualType t) {
return cgm.
convertType(t); }
1129 if (
const auto *at =
type->getAs<AtomicType>()) {
1131 type.getQualifiers());
1136static mlir::Attribute
1137emitArrayConstant(CIRGenModule &cgm, mlir::Type desiredType,
1138 mlir::Type commonElementType,
unsigned arrayBound,
1139 SmallVectorImpl<mlir::TypedAttr> &elements,
1140 mlir::TypedAttr filler) {
1143 unsigned nonzeroLength = arrayBound;
1144 if (elements.size() < nonzeroLength && builder.
isNullValue(filler))
1145 nonzeroLength = elements.size();
1147 if (nonzeroLength == elements.size()) {
1148 while (nonzeroLength > 0 &&
1153 if (nonzeroLength == 0)
1154 return cir::ZeroAttr::get(desiredType);
1156 const unsigned trailingZeroes = arrayBound - nonzeroLength;
1159 if (trailingZeroes >= 8) {
1160 assert(elements.size() >= nonzeroLength &&
1161 "missing initializer for non-zero element");
1163 if (commonElementType && nonzeroLength >= 8) {
1167 SmallVector<mlir::Attribute> eles;
1168 eles.reserve(nonzeroLength);
1169 for (
const auto &element : elements)
1170 eles.push_back(element);
1171 auto initial = cir::ConstArrayAttr::get(
1172 cir::ArrayType::get(commonElementType, nonzeroLength),
1173 mlir::ArrayAttr::get(builder.getContext(), eles));
1175 elements[0] = initial;
1179 elements.resize(nonzeroLength + 1);
1182 mlir::Type fillerType =
1185 : mlir::cast<cir::ArrayType>(desiredType).getElementType();
1186 fillerType = cir::ArrayType::get(fillerType, trailingZeroes);
1187 elements.back() = cir::ZeroAttr::get(fillerType);
1188 commonElementType =
nullptr;
1189 }
else if (elements.size() != arrayBound) {
1190 elements.resize(arrayBound, filler);
1192 if (filler.getType() != commonElementType)
1193 commonElementType = {};
1196 if (commonElementType) {
1197 SmallVector<mlir::Attribute> eles;
1198 eles.reserve(elements.size());
1200 for (
const auto &element : elements)
1201 eles.push_back(element);
1203 return cir::ConstArrayAttr::get(
1204 cir::ArrayType::get(commonElementType, arrayBound),
1205 mlir::ArrayAttr::get(builder.getContext(), eles));
1208 SmallVector<mlir::Attribute> eles;
1209 eles.reserve(elements.size());
1210 for (
auto const &element : elements)
1211 eles.push_back(element);
1213 auto arrAttr = mlir::ArrayAttr::get(builder.getContext(), eles);
1226struct ConstantLValue {
1227 llvm::PointerUnion<mlir::Value, mlir::Attribute> value;
1228 bool hasOffsetApplied;
1230 ConstantLValue(std::nullptr_t)
1232 ConstantLValue(cir::GlobalViewAttr address)
1233 : value(address), hasOffsetApplied(
false) {}
1235 ConstantLValue() : value(
nullptr), hasOffsetApplied(
false) {}
1239class ConstantLValueEmitter
1240 :
public ConstStmtVisitor<ConstantLValueEmitter, ConstantLValue> {
1242 ConstantEmitter &emitter;
1247 friend StmtVisitorBase;
1250 ConstantLValueEmitter(ConstantEmitter &emitter,
const APValue &value,
1252 : cgm(emitter.cgm), emitter(emitter), value(value), destType(destType) {}
1254 mlir::Attribute tryEmit();
1257 mlir::Attribute tryEmitAbsolute(mlir::Type destTy);
1258 ConstantLValue tryEmitBase(
const APValue::LValueBase &base);
1260 ConstantLValue VisitStmt(
const Stmt *
s) {
return nullptr; }
1261 ConstantLValue VisitConstantExpr(
const ConstantExpr *e);
1262 ConstantLValue VisitCompoundLiteralExpr(
const CompoundLiteralExpr *e);
1263 ConstantLValue VisitStringLiteral(
const StringLiteral *e);
1264 ConstantLValue VisitObjCBoxedExpr(
const ObjCBoxedExpr *e);
1265 ConstantLValue VisitObjCEncodeExpr(
const ObjCEncodeExpr *e);
1266 ConstantLValue VisitObjCStringLiteral(
const ObjCStringLiteral *e);
1267 ConstantLValue VisitPredefinedExpr(
const PredefinedExpr *e);
1268 ConstantLValue VisitAddrLabelExpr(
const AddrLabelExpr *e);
1269 ConstantLValue VisitCallExpr(
const CallExpr *e);
1270 ConstantLValue VisitBlockExpr(
const BlockExpr *e);
1271 ConstantLValue VisitCXXTypeidExpr(
const CXXTypeidExpr *e);
1273 VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *e);
1276 mlir::ArrayAttr getOffset(mlir::Type ty) {
1278 cir::CIRDataLayout layout(cgm.
getModule());
1279 SmallVector<int64_t, 3> idxVec;
1283 llvm::SmallVector<mlir::Attribute, 3> indices;
1284 for (int64_t i : idxVec) {
1285 mlir::IntegerAttr intAttr = cgm.
getBuilder().getI32IntegerAttr(i);
1286 indices.push_back(intAttr);
1289 if (indices.empty())
1291 return cgm.
getBuilder().getArrayAttr(indices);
1295 ConstantLValue applyOffset(ConstantLValue &
c) {
1297 if (
auto attr = mlir::dyn_cast<mlir::Attribute>(
c.value)) {
1298 if (
auto gv = mlir::dyn_cast<cir::GlobalViewAttr>(attr)) {
1299 auto baseTy = mlir::cast<cir::PointerType>(gv.getType()).getPointee();
1301 assert(!gv.getIndices() &&
"Global view is already indexed");
1302 return cir::GlobalViewAttr::get(destTy, gv.getSymbol(),
1305 llvm_unreachable(
"Unsupported attribute type to offset");
1308 cgm.
errorNYI(
"ConstantLValue: non-attribute offset");
1315mlir::Attribute ConstantLValueEmitter::tryEmit() {
1326 assert(mlir::isa<cir::PointerType>(destTy));
1331 return tryEmitAbsolute(destTy);
1334 ConstantLValue result = tryEmitBase(base);
1337 llvm::PointerUnion<mlir::Value, mlir::Attribute> &value = result.value;
1342 if (!result.hasOffsetApplied)
1343 value = applyOffset(result).value;
1347 if (mlir::isa<cir::PointerType>(destTy)) {
1348 if (
auto attr = mlir::dyn_cast<mlir::Attribute>(value))
1350 cgm.
errorNYI(
"ConstantLValueEmitter: non-attribute pointer");
1354 cgm.
errorNYI(
"ConstantLValueEmitter: other?");
1360mlir::Attribute ConstantLValueEmitter::tryEmitAbsolute(mlir::Type destTy) {
1362 auto destPtrTy = mlir::cast<cir::PointerType>(destTy);
1364 destPtrTy, value.getLValueOffset().getQuantity());
1368ConstantLValueEmitter::tryEmitBase(
const APValue::LValueBase &base) {
1370 if (
const ValueDecl *d = base.
dyn_cast<
const ValueDecl *>()) {
1375 if (d->hasAttr<WeakRefAttr>()) {
1377 "ConstantLValueEmitter: emit pointer base for weakref");
1381 if (
auto *fd = dyn_cast<FunctionDecl>(d)) {
1384 mlir::MLIRContext *mlirContext = builder.getContext();
1385 return cir::GlobalViewAttr::get(
1387 mlir::FlatSymbolRefAttr::get(mlirContext, fop.getSymNameAttr()));
1390 if (
auto *vd = dyn_cast<VarDecl>(d)) {
1392 if (!vd->hasLocalStorage()) {
1393 if (vd->isFileVarDecl() || vd->hasExternalStorage())
1396 if (vd->isLocalVarDecl()) {
1398 "ConstantLValueEmitter: local var decl");
1409 "ConstantLValueEmitter: unhandled value decl");
1414 if (base.
dyn_cast<TypeInfoLValue>()) {
1415 cgm.
errorNYI(
"ConstantLValueEmitter: typeid");
1420 return Visit(base.
get<
const Expr *>());
1423ConstantLValue ConstantLValueEmitter::VisitConstantExpr(
const ConstantExpr *e) {
1429ConstantLValueEmitter::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *e) {
1435ConstantLValueEmitter::VisitStringLiteral(
const StringLiteral *e) {
1440ConstantLValueEmitter::VisitObjCEncodeExpr(
const ObjCEncodeExpr *e) {
1446ConstantLValueEmitter::VisitObjCStringLiteral(
const ObjCStringLiteral *e) {
1448 "ConstantLValueEmitter: objc string literal");
1453ConstantLValueEmitter::VisitObjCBoxedExpr(
const ObjCBoxedExpr *e) {
1459ConstantLValueEmitter::VisitPredefinedExpr(
const PredefinedExpr *e) {
1465ConstantLValueEmitter::VisitAddrLabelExpr(
const AddrLabelExpr *e) {
1470ConstantLValue ConstantLValueEmitter::VisitCallExpr(
const CallExpr *e) {
1475ConstantLValue ConstantLValueEmitter::VisitBlockExpr(
const BlockExpr *e) {
1481ConstantLValueEmitter::VisitCXXTypeidExpr(
const CXXTypeidExpr *e) {
1486ConstantLValue ConstantLValueEmitter::VisitMaterializeTemporaryExpr(
1487 const MaterializeTemporaryExpr *e) {
1489 "ConstantLValueEmitter: materialize temporary expr");
1498 initializeNonAbstract();
1503 assert(initializedNonAbstract &&
1504 "finalizing emitter that was used for abstract emission?");
1505 assert(!finalized &&
"finalizing emitter multiple times");
1506 assert(!gv.isDeclaration());
1515 AbstractStateRAII state(*
this,
true);
1520 assert((!initializedNonAbstract || finalized || failed) &&
1521 "not finalized after being initialized for non-abstract emission");
1531 if (
const auto *e = dyn_cast_or_null<CXXConstructExpr>(d.
getInit())) {
1539 if (cxxrd->getNumBases() != 0) {
1542 cgm.errorNYI(
"tryEmitPrivateForVarInit: cxx record with bases");
1545 if (!
cgm.getTypes().isZeroInitializable(cxxrd)) {
1549 "tryEmitPrivateForVarInit: non-zero-initializable cxx record");
1552 return cir::ZeroAttr::get(
cgm.convertType(d.
getType()));
1560 assert(e &&
"No initializer to emit");
1566 if (mlir::Attribute
c = ConstExprEmitter(*this).Visit(
const_cast<Expr *
>(e),
1585 retType =
cgm.getASTContext().getLValueReferenceType(retType);
1596 return mlir::cast<mlir::TypedAttr>(
attr);
1610 AbstractStateRAII state{*
this,
true};
1611 mlir::Attribute
c = mlir::cast<mlir::Attribute>(
tryEmitPrivate(e, destType));
1614 "emitAbstract failed, emit null constaant");
1621 AbstractStateRAII state(*
this,
true);
1624 cgm.errorNYI(loc,
"emitAbstract failed, emit null constaant");
1631 cir::ConstantOp cstOp =
1632 cgm.emitNullConstant(t, loc).getDefiningOp<cir::ConstantOp>();
1633 assert(cstOp &&
"expected cir.const op");
1641 cgm.errorNYI(
"emitForMemory: atomic type");
1653 cgm.errorNYI(
"atomic constants");
1661 assert(!destType->
isVoidType() &&
"can't emit a void constant");
1663 if (mlir::Attribute
c =
1664 ConstExprEmitter(*this).Visit(
const_cast<Expr *
>(e), destType))
1665 return llvm::dyn_cast<mlir::TypedAttr>(
c);
1669 bool success =
false;
1679 return llvm::dyn_cast<mlir::TypedAttr>(
c);
1687 auto &builder =
cgm.getBuilder();
1691 cgm.errorNYI(
"ConstExprEmitter::tryEmitPrivate none or indeterminate");
1694 mlir::Type ty =
cgm.convertType(destType);
1695 if (mlir::isa<cir::BoolType>(ty))
1697 assert(mlir::isa<cir::IntType>(ty) &&
"expected integral type");
1698 return cir::IntAttr::get(ty, value.
getInt());
1701 const llvm::APFloat &init = value.
getFloat();
1702 if (&init.getSemantics() == &llvm::APFloat::IEEEhalf() &&
1703 !
cgm.getASTContext().getLangOpts().NativeHalfType &&
1704 cgm.getASTContext().getTargetInfo().useFP16ConversionIntrinsics()) {
1705 cgm.errorNYI(
"ConstExprEmitter::tryEmitPrivate half");
1709 mlir::Type ty =
cgm.convertType(destType);
1710 assert(mlir::isa<cir::FPTypeInterface>(ty) &&
1711 "expected floating-point type");
1712 return cir::FPAttr::get(ty, init);
1715 const ArrayType *arrayTy =
cgm.getASTContext().getAsArrayType(destType);
1720 mlir::Attribute filler;
1729 elements.reserve(numInitElts + 1);
1731 elements.reserve(numInitElts);
1733 mlir::Type commonElementType;
1734 for (
unsigned i = 0; i < numInitElts; ++i) {
1736 const mlir::Attribute element =
1741 const mlir::TypedAttr elementTyped = mlir::cast<mlir::TypedAttr>(element);
1743 commonElementType = elementTyped.getType();
1744 else if (elementTyped.getType() != commonElementType) {
1745 commonElementType = {};
1748 elements.push_back(elementTyped);
1751 mlir::TypedAttr typedFiller = llvm::cast_or_null<mlir::TypedAttr>(filler);
1752 if (filler && !typedFiller)
1753 cgm.errorNYI(
"array filler should always be typed");
1755 mlir::Type desiredType =
cgm.convertType(destType);
1756 return emitArrayConstant(
cgm, desiredType, commonElementType, numElements,
1757 elements, typedFiller);
1765 elements.reserve(numElements);
1767 for (
unsigned i = 0; i < numElements; ++i) {
1768 const mlir::Attribute element =
1772 elements.push_back(element);
1775 const auto desiredVecTy =
1776 mlir::cast<cir::VectorType>(
cgm.convertType(destType));
1778 return cir::ConstVectorAttr::get(
1780 mlir::ArrayAttr::get(
cgm.getBuilder().getContext(), elements));
1783 cgm.errorNYI(
"ConstExprEmitter::tryEmitPrivate member pointer");
1787 return ConstantLValueEmitter(*
this, value, destType).tryEmit();
1790 return ConstRecordBuilder::buildRecord(*
this, value, destType);
1793 mlir::Type desiredType =
cgm.convertType(destType);
1794 auto complexType = mlir::dyn_cast<cir::ComplexType>(desiredType);
1796 mlir::Type complexElemTy =
complexType.getElementType();
1800 return cir::ConstComplexAttr::get(builder.getContext(),
complexType,
1801 cir::IntAttr::get(complexElemTy, real),
1802 cir::IntAttr::get(complexElemTy, imag));
1806 "expected floating-point type");
1809 return cir::ConstComplexAttr::get(builder.getContext(),
complexType,
1810 cir::FPAttr::get(complexElemTy, real),
1811 cir::FPAttr::get(complexElemTy, imag));
1816 "ConstExprEmitter::tryEmitPrivate fixed point, addr label diff");
1819 llvm_unreachable(
"Unknown APValue kind");
1824 return builder.getNullPtr(
getTypes().convertTypeForMem(t), loc);
1827 if (
getTypes().isZeroInitializable(t))
1828 return builder.getNullValue(
getTypes().convertTypeForMem(t), loc);
1831 errorNYI(
"CIRGenModule::emitNullConstant ConstantArrayType");
1835 errorNYI(
"CIRGenModule::emitNullConstant RecordType");
1838 "Should only see pointers to data members here!");
1840 errorNYI(
"CIRGenModule::emitNullConstant unsupported type");
Defines the clang::ASTContext interface.
Defines enum values for all the target-independent builtin functions.
static QualType getNonMemoryType(CodeGenModule &CGM, QualType type)
__device__ __2f16 float __ockl_bool s
__device__ __2f16 float c
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)
cir::PointerType getPointerTo(mlir::Type ty)
mlir::TypedAttr getZeroInitAttr(mlir::Type ty)
mlir::TypedAttr getConstPtrAttr(mlir::Type type, int64_t value)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool hasArrayFiller() const
const LValueBase getLValueBase() const
APValue & getArrayInitializedElt(unsigned I)
APValue & getStructField(unsigned i)
const FieldDecl * getUnionField() const
APSInt & getComplexIntImag()
ValueKind getKind() const
unsigned getArrayInitializedElts() const
APValue & getUnionValue()
CharUnits & getLValueOffset()
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()
APValue & getStructBase(unsigned i)
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.
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
bool hasOwnVFPtr() const
hasOwnVFPtr - Does this class provide its own virtual-function table pointer, rather than inheriting ...
CharUnits getSize() const
getSize - Get the record size in characters.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
cir::ConstRecordAttr getAnonConstRecord(mlir::ArrayAttr arrayAttr, bool packed=false, bool padded=false, mlir::Type ty={})
mlir::Attribute getConstRecordOrZeroAttr(mlir::ArrayAttr arrayAttr, bool packed=false, bool padded=false, mlir::Type type={})
bool isNullValue(mlir::Attribute attr) const
cir::RecordType getCompleteRecordType(mlir::ArrayAttr fields, bool packed=false, bool padded=false, llvm::StringRef name="")
void computeGlobalViewIndicesFromFlatOffset(int64_t offset, mlir::Type ty, cir::CIRDataLayout layout, llvm::SmallVectorImpl< int64_t > &indices)
cir::ConstArrayAttr getConstArray(mlir::Attribute attrs, cir::ArrayType arrayTy) const
cir::IntType getUIntNTy(int n)
virtual cir::GlobalOp getAddrOfVTable(const CXXRecordDecl *rd, CharUnits vptrOffset)=0
Get the address of the vtable for the given record decl which should be used for the vptr at the give...
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.
clang::ASTContext & getASTContext() const
mlir::Type convertType(clang::QualType type)
CIRGenBuilderTy & getBuilder()
ItaniumVTableContext & getItaniumVTableContext()
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.
void emitExplicitCastExprType(const ExplicitCastExpr *e, CIRGenFunction *cgf=nullptr)
Emit type info if type of an expression is a variably modified type.
const cir::CIRDataLayout getDataLayout() const
cir::GlobalViewAttr getAddrOfGlobalVarAttr(const VarDecl *d)
Return the mlir::GlobalViewAttr for the address of the given global.
mlir::Location getLoc(clang::SourceLocation cLoc)
Helpers to convert the presumed location of Clang's SourceLocation to an MLIR Location.
mlir::Value emitNullConstant(QualType t, mlir::Location loc)
Return the result of value-initializing the given type, i.e.
mlir::ModuleOp getModule() const
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.
bool shouldZeroInitPadding() const
mlir::Attribute getConstantArrayFromStringLiteral(const StringLiteral *e)
Return a constant array for the given string.
const CIRGenBitFieldInfo & getBitFieldInfo(const clang::FieldDecl *fd) const
Return the BitFieldInfo that corresponds to the field FD.
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.
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 tryEmitConstantExpr(const ConstantExpr *ce)
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.
SourceRange getSourceRange() const LLVM_READONLY
CastKind getCastKind() const
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
const Expr * getInitializer() const
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.
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...
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool isBitField() const
Determines whether this field is a bitfield.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
bool isZeroSize(const ASTContext &Ctx) const
Determine if this field is a subobject of zero size, that is, either a zero-length bit-field or a fie...
bool isUnnamedBitField() const
Determines whether this is an unnamed bitfield.
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.
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
FieldDecl * getInitializedFieldInUnion()
If this initializes a union, specifies which field in the union to initialize.
const Expr * getInit(unsigned Init) const
const VTableLayout & getVTableLayout(const CXXRecordDecl *RD)
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation getBeginLoc() const LLVM_READONLY
const Expr * getSubExpr() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
bool hasFlexibleArrayMember() const
field_range fields() const
RecordDecl * getDefinitionOrSelf() const
Encodes a location in the source.
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
CXXRecordDecl * castAsCXXRecordDecl() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() 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
AddressPointLocation getAddressPoint(BaseSubobject Base) const
Represents a variable declaration or definition.
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
const Expr * getInit() const
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
Represents a GCC generic vector type.
const internal::VariadicAllOfMatcher< Attr > attr
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ComplexType > complexType
const AstTypeMatcher< RecordType > recordType
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
void finalize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
U cast(CodeGen::Address addr)
__DEVICE__ _Tp arg(const std::complex< _Tp > &__c)
float __ovld __cnfn length(float)
Return the length of vector p, i.e., sqrt(p.x2 + p.y 2 + ...)
static bool ctorConstLvalueToRvalueConversion()
static bool addressPointerAuthInfo()
static bool constEmitterArrayILE()
static bool constEmitterVectorILE()
unsigned size
The total size of the bit-field, in bits.
mlir::Type uCharTy
ClangIR char.
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.
unsigned AddressPointIndex