16#include "mlir/IR/Builders.h"
22#include "llvm/IR/Value.h"
38 if (
const DeclRefExpr *dre = dyn_cast<DeclRefExpr>(e)) {
39 const VarDecl *
var = dyn_cast<VarDecl>(dre->getDecl());
40 return (var &&
var->hasAttr<BlocksAttr>());
49 if (op->isAssignmentOp() || op->isPtrMemOp())
53 if (op->getOpcode() == BO_Comma)
61 dyn_cast<AbstractConditionalOperator>(e)) {
67 if (
const Expr *src = op->getSourceExpr())
74 }
else if (
const CastExpr *
cast = dyn_cast<CastExpr>(e)) {
75 if (
cast->getCastKind() == CK_LValueToRValue)
81 }
else if (
const UnaryOperator *uop = dyn_cast<UnaryOperator>(e)) {
85 }
else if (
const MemberExpr *mem = dyn_cast<MemberExpr>(e)) {
96class AggExprEmitter :
public StmtVisitor<AggExprEmitter> {
107 void withReturnValueSlot(
const Expr *e,
108 llvm::function_ref<RValue(ReturnValueSlot)> fn);
110 AggValueSlot ensureSlot(mlir::Location loc, QualType t) {
111 if (!dest.isIgnored())
113 return cgf.createAggTemp(t, loc,
"agg.tmp.ensured");
116 void ensureDest(mlir::Location loc, QualType ty) {
117 if (!dest.isIgnored())
119 dest = cgf.createAggTemp(ty, loc,
"agg.tmp.ensured");
123 AggExprEmitter(CIRGenFunction &cgf, AggValueSlot dest)
124 : cgf(cgf), dest(dest) {}
129 void emitAggLoadOfLValue(
const Expr *e);
131 void emitArrayInit(Address destPtr, cir::ArrayType arrayTy, QualType arrayQTy,
132 Expr *exprToVisit, ArrayRef<Expr *> args,
135 void emitFinalDestCopy(QualType
type, RValue src);
138 void emitFinalDestCopy(QualType
type,
const LValue &src,
142 void emitCopy(QualType
type,
const AggValueSlot &dest,
143 const AggValueSlot &src);
145 void emitInitializationToLValue(Expr *e, LValue lv);
147 void emitNullInitializationToLValue(mlir::Location loc, LValue lv);
149 void Visit(Expr *e) { StmtVisitor<AggExprEmitter>::Visit(e); }
151 void VisitArraySubscriptExpr(ArraySubscriptExpr *e) {
152 emitAggLoadOfLValue(e);
155 void VisitCallExpr(
const CallExpr *e);
156 void VisitStmtExpr(
const StmtExpr *e) {
157 CIRGenFunction::StmtExprEvaluation eval(cgf);
160 (void)cgf.emitCompoundStmt(*e->
getSubStmt(), &retAlloca, dest);
163 void VisitBinAssign(
const BinaryOperator *e) {
166 assert(cgf.getContext().hasSameUnqualifiedType(e->
getLHS()->
getType(),
168 "Invalid assignment");
173 "block var reference with side effects");
177 LValue lhs = cgf.emitLValue(e->
getLHS());
193 cgf.emitAggExpr(e->
getRHS(), lhsSlot);
196 emitFinalDestCopy(e->
getType(), lhs);
198 if (!dest.isIgnored() && !dest.isExternallyDestructed() &&
204 void VisitDeclRefExpr(DeclRefExpr *e) { emitAggLoadOfLValue(e); }
206 void VisitInitListExpr(InitListExpr *e);
207 void VisitCXXConstructExpr(
const CXXConstructExpr *e);
209 void visitCXXParenListOrInitListExpr(Expr *e, ArrayRef<Expr *> args,
210 FieldDecl *initializedFieldInUnion,
212 void VisitCXXDefaultInitExpr(CXXDefaultInitExpr *die) {
213 CIRGenFunction::CXXDefaultInitExprScope Scope(cgf, die);
216 void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *e) {
219 bool wasExternallyDestructed = dest.isExternallyDestructed();
223 dest.setExternallyDestructed();
228 if (!wasExternallyDestructed)
232 void VisitExprWithCleanups(ExprWithCleanups *e);
237 case CK_LValueToRValueBitCast: {
238 if (dest.isIgnored()) {
244 LValue sourceLV = cgf.emitLValue(e->
getSubExpr());
245 Address sourceAddress =
246 sourceLV.getAddress().withElementType(cgf.getBuilder(), cgf.voidTy);
247 Address destAddress =
248 dest.getAddress().withElementType(cgf.getBuilder(), cgf.voidTy);
250 mlir::Location loc = cgf.getLoc(e->
getExprLoc());
252 mlir::Value sizeVal = cgf.getBuilder().getConstInt(
254 cgf.getContext().getTypeSizeInChars(e->
getType()).getQuantity());
255 cgf.getBuilder().createMemCpy(loc, destAddress.
getPointer(),
260 case CK_LValueToRValue:
265 "AggExprEmitter: volatile lvalue-to-rvalue cast");
268 case CK_UserDefinedConversion:
269 case CK_ConstructorConversion:
272 "Implicit cast types must be compatible");
277 std::string(
"AggExprEmitter: VisitCastExpr: ") +
282 void VisitStmt(Stmt *
s) {
283 cgf.cgm.errorNYI(
s->getSourceRange(),
284 std::string(
"AggExprEmitter::VisitStmt: ") +
285 s->getStmtClassName());
287 void VisitParenExpr(ParenExpr *pe) { Visit(pe->
getSubExpr()); }
288 void VisitGenericSelectionExpr(GenericSelectionExpr *ge) {
291 void VisitCoawaitExpr(CoawaitExpr *e) {
292 cgf.cgm.errorNYI(e->
getSourceRange(),
"AggExprEmitter: VisitCoawaitExpr");
294 void VisitCoyieldExpr(CoyieldExpr *e) {
295 cgf.cgm.errorNYI(e->
getSourceRange(),
"AggExprEmitter: VisitCoyieldExpr");
297 void VisitUnaryCoawait(UnaryOperator *e) {
298 cgf.cgm.errorNYI(e->
getSourceRange(),
"AggExprEmitter: VisitUnaryCoawait");
300 void VisitUnaryExtension(UnaryOperator *e) { Visit(e->
getSubExpr()); }
301 void VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *e) {
303 "AggExprEmitter: VisitSubstNonTypeTemplateParmExpr");
305 void VisitConstantExpr(ConstantExpr *e) {
306 cgf.cgm.errorNYI(e->
getSourceRange(),
"AggExprEmitter: VisitConstantExpr");
308 void VisitMemberExpr(MemberExpr *e) { emitAggLoadOfLValue(e); }
309 void VisitUnaryDeref(UnaryOperator *e) { emitAggLoadOfLValue(e); }
310 void VisitStringLiteral(StringLiteral *e) { emitAggLoadOfLValue(e); }
311 void VisitCompoundLiteralExpr(CompoundLiteralExpr *e);
313 void VisitPredefinedExpr(
const PredefinedExpr *e) {
315 "AggExprEmitter: VisitPredefinedExpr");
317 void VisitBinaryOperator(
const BinaryOperator *e) {
319 "AggExprEmitter: VisitBinaryOperator");
321 void VisitPointerToDataMemberBinaryOperator(
const BinaryOperator *e) {
323 "AggExprEmitter: VisitPointerToDataMemberBinaryOperator");
325 void VisitBinComma(
const BinaryOperator *e) {
326 cgf.emitIgnoredExpr(e->
getLHS());
329 void VisitBinCmp(
const BinaryOperator *e) {
332 const ComparisonCategoryInfo &cmpInfo =
333 cgf.getContext().CompCategories.getInfoForType(e->
getType());
335 "cannot copy non-trivially copyable aggregate");
342 cgf.cgm.errorNYI(e->
getBeginLoc(),
"aggregate three-way comparison");
345 CIRGenBuilderTy builder = cgf.getBuilder();
348 cgf.cgm.errorNYI(e->
getBeginLoc(),
"VisitBinCmp: complex type");
351 cgf.cgm.errorNYI(e->
getBeginLoc(),
"VisitBinCmp: aggregate type");
353 mlir::Value lhs = cgf.emitAnyExpr(e->
getLHS()).getValue();
354 mlir::Value rhs = cgf.emitAnyExpr(e->
getRHS()).getValue();
356 mlir::Value resultScalar;
365 cir::CmpOrdering ordering = cmpInfo.
isStrong()
366 ? cir::CmpOrdering::Strong
367 : cir::CmpOrdering::Weak;
369 loc, lhs, rhs, ltRes, eqRes, gtRes, ordering);
374 loc, lhs, rhs, ltRes, eqRes, gtRes, unorderedRes);
380 LValue destLVal = cgf.makeAddrLValue(dest.getAddress(), e->
getType());
385 LValue fieldLVal = cgf.emitLValueForFieldInitialization(
386 destLVal, resultField, resultField->
getName());
387 cgf.emitStoreThroughLValue(
RValue::get(resultScalar), fieldLVal);
392 void VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *e) {
394 "AggExprEmitter: VisitCXXRewrittenBinaryOperator");
396 void VisitObjCMessageExpr(ObjCMessageExpr *e) {
398 "AggExprEmitter: VisitObjCMessageExpr");
400 void VisitObjCIVarRefExpr(ObjCIvarRefExpr *e) {
402 "AggExprEmitter: VisitObjCIVarRefExpr");
405 void VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *e) {
407 LValue destLV = cgf.makeAddrLValue(dest.getAddress(), e->
getType());
408 emitInitializationToLValue(e->
getBase(), destLV);
411 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *e) {
414 CIRGenFunction::OpaqueValueMapping binding(cgf, e);
415 CIRGenFunction::ConditionalEvaluation eval(cgf);
418 bool isExternallyDestructed = dest.isExternallyDestructed();
419 bool destructNonTrivialCStruct =
420 !isExternallyDestructed &&
422 isExternallyDestructed |= destructNonTrivialCStruct;
424 cgf.emitIfOnBoolExpr(
427 [&](mlir::OpBuilder &
b, mlir::Location loc) {
428 eval.beginEvaluation();
430 CIRGenFunction::LexicalScope lexScope{cgf, loc,
431 b.getInsertionBlock()};
432 cgf.curLexScope->setAsTernary();
433 dest.setExternallyDestructed(isExternallyDestructed);
434 assert(!cir::MissingFeatures::incrementProfileCounter());
435 Visit(e->getTrueExpr());
436 cir::YieldOp::create(b, loc);
438 eval.endEvaluation();
442 [&](mlir::OpBuilder &
b, mlir::Location loc) {
443 eval.beginEvaluation();
445 CIRGenFunction::LexicalScope lexScope{cgf, loc,
446 b.getInsertionBlock()};
447 cgf.curLexScope->setAsTernary();
453 dest.setExternallyDestructed(isExternallyDestructed);
456 cir::YieldOp::create(
b, loc);
458 eval.endEvaluation();
462 if (destructNonTrivialCStruct)
465 "Abstract conditional aggregate: destructNonTrivialCStruct");
475 llvm::Value *outerBegin =
nullptr) {
477 "AggExprEmitter: VisitArrayInitLoopExpr");
481 "AggExprEmitter: VisitImplicitValueInitExpr");
492 "AggExprEmitter: VisitCXXInheritedCtorInitExpr");
503 assert(array.isSimple() &&
"initializer_list array not a simple lvalue");
504 Address arrayPtr = array.getAddress();
508 assert(
arrayType &&
"std::initializer_list constructed from non-array");
511 assert(record->getNumFields() == 2 &&
512 "Expected std::initializer_list to only have two fields");
515 assert(field != record->field_end() &&
516 ctx.
hasSameType(field->getType()->getPointeeType(),
518 "Expected std::initializer_list first field to be const E *");
529 assert(field != record->field_end() &&
530 "Expected std::initializer_list to have two fields");
540 assert(field->getType()->isPointerType() &&
541 ctx.
hasSameType(field->getType()->getPointeeType(),
543 "Expected std::initializer_list second field to be const E *");
551 "AggExprEmitter: VisitCXXScalarValueInitExpr");
553 void VisitCXXTypeidExpr(
CXXTypeidExpr *e) { emitAggLoadOfLValue(e); }
559 "AggExprEmitter: VisitOpaqueValueExpr");
564 "AggExprEmitter: VisitPseudoObjectExpr");
570 mlir::Value vaArgValue = cgf.
emitVAArg(e);
583 emitFinalDestCopy(e->
getType(), tmpLValue);
591 emitFinalDestCopy(e->
getType(), result);
604 if (
auto *ile = dyn_cast<InitListExpr>(e)) {
605 if (ile->getNumInits())
610 if (
const auto *cons = dyn_cast_or_null<CXXConstructExpr>(e))
611 return cons->getConstructor()->isDefaultConstructor() &&
612 cons->getConstructor()->isTrivial();
619void AggExprEmitter::emitAggLoadOfLValue(
const Expr *e) {
625 emitFinalDestCopy(e->
getType(), lv);
628void AggExprEmitter::VisitCompoundLiteralExpr(CompoundLiteralExpr *e) {
632 emitAggLoadOfLValue(e);
653void AggExprEmitter::emitArrayInit(Address destPtr, cir::ArrayType arrayTy,
654 QualType arrayQTy, Expr *e,
655 ArrayRef<Expr *> args, Expr *arrayFiller) {
659 const uint64_t numInitElements = args.size();
661 const QualType elementType =
665 cgf.
cgm.
errorNYI(loc,
"initialized array requires destruction");
671 const mlir::Type cirElementType = cgf.
convertType(elementType);
672 const cir::PointerType cirElementPtrType =
675 auto begin = cir::CastOp::create(builder, loc, cirElementPtrType,
676 cir::CastKind::array_to_ptrdecay,
679 const CharUnits elementSize =
681 const CharUnits elementAlign =
689 mlir::Value element = begin;
696 for (uint64_t i = 0; i != numInitElements; ++i) {
703 const Address address = Address(element, cirElementType, elementAlign);
704 const LValue elementLV = cgf.
makeAddrLValue(address, elementType);
705 emitInitializationToLValue(args[i], elementLV);
708 const uint64_t numArrayElements = arrayTy.getSize();
716 if (numInitElements != numArrayElements &&
717 !(dest.
isZeroed() && hasTrivialFiller &&
720 if (numInitElements) {
722 element = cir::PtrStrideOp::create(builder, loc, cirElementPtrType,
734 cir::ConstantOp numArrayElementsConst = builder.
getConstInt(
735 loc, mlir::cast<cir::IntType>(cgf.
ptrDiffTy), numArrayElements);
736 mlir::Value end = cir::PtrStrideOp::create(builder, loc, cirElementPtrType,
737 begin, numArrayElementsConst);
742 [&](mlir::OpBuilder &
b, mlir::Location loc) {
743 cir::LoadOp currentElement = builder.
createLoad(loc, tmpAddr);
744 cir::CmpOp cmp = cir::CmpOp::create(builder, loc, cir::CmpOpKind::ne,
745 currentElement, end);
749 [&](mlir::OpBuilder &
b, mlir::Location loc) {
750 cir::LoadOp currentElement = builder.
createLoad(loc, tmpAddr);
756 Address(currentElement, cirElementType, elementAlign),
759 emitInitializationToLValue(arrayFiller, elementLV);
761 emitNullInitializationToLValue(loc, elementLV);
765 cgf.
cgm.
errorNYI(loc,
"update destructed array element for EH");
771 loc, mlir::cast<cir::IntType>(cgf.
ptrDiffTy), 1);
772 auto nextElement = cir::PtrStrideOp::create(
773 builder, loc, cirElementPtrType, currentElement, one);
782void AggExprEmitter::emitFinalDestCopy(QualType
type, RValue src) {
783 assert(src.
isAggregate() &&
"value must be aggregate value!");
789void AggExprEmitter::emitFinalDestCopy(
790 QualType
type,
const LValue &src,
801 cgf.
cgm.
errorNYI(
"emitFinalDestCopy: EVK_RValue & PCK_Struct");
805 cgf.
cgm.
errorNYI(
"emitFinalDestCopy: !EVK_RValue & PCK_Struct");
816 emitCopy(
type, dest, srcAgg);
823void AggExprEmitter::emitCopy(QualType
type,
const AggValueSlot &dest,
824 const AggValueSlot &src) {
837void AggExprEmitter::emitInitializationToLValue(Expr *e, LValue lv) {
838 const QualType
type = lv.getType();
844 return emitNullInitializationToLValue(loc, lv);
850 if (
type->isReferenceType()) {
875void AggExprEmitter::VisitCXXConstructExpr(
const CXXConstructExpr *e) {
880void AggExprEmitter::emitNullInitializationToLValue(mlir::Location loc,
882 const QualType
type = lv.getType();
907void AggExprEmitter::VisitLambdaExpr(
LambdaExpr *e) {
910 [[maybe_unused]] LValue slotLV =
917 for (
auto [curField, capture, captureInit] : llvm::zip(
920 llvm::StringRef fieldName = curField->getName();
921 if (capture.capturesVariable()) {
922 assert(!curField->isBitField() &&
"lambdas don't have bitfield members!");
923 ValueDecl *v = capture.getCapturedVar();
926 }
else if (capture.capturesThis()) {
936 if (curField->hasCapturedVLAType())
939 emitInitializationToLValue(captureInit, lv);
943 curField->getType().isDestructedType())
948void AggExprEmitter::VisitExprWithCleanups(ExprWithCleanups *e) {
949 CIRGenFunction::RunCleanupsScope cleanups(cgf);
952 mlir::OpBuilder::InsertPoint scopeBegin;
960 cir::ScopeOp::create(builder, scopeLoc,
961 [&](mlir::OpBuilder &
b, mlir::Location loc) {
962 scopeBegin =
b.saveInsertionPoint();
966 mlir::OpBuilder::InsertionGuard guard(builder);
967 builder.restoreInsertionPoint(scopeBegin);
968 CIRGenFunction::LexicalScope lexScope{cgf, scopeLoc,
969 builder.getInsertionBlock()};
974void AggExprEmitter::VisitCallExpr(
const CallExpr *e) {
981 e, [&](ReturnValueSlot slot) {
return cgf.
emitCallExpr(e, slot); });
984void AggExprEmitter::withReturnValueSlot(
985 const Expr *e, llvm::function_ref<RValue(ReturnValueSlot)> fn) {
989 bool requiresDestruction =
991 if (requiresDestruction)
994 "withReturnValueSlot: return value requiring destruction is NYI");
1009 fn(ReturnValueSlot(retAddr));
1012void AggExprEmitter::VisitInitListExpr(InitListExpr *e) {
1014 llvm_unreachable(
"GNU array range designator extension");
1019 visitCXXParenListOrInitListExpr(
1023void AggExprEmitter::visitCXXParenListOrInitListExpr(
1024 Expr *e, ArrayRef<Expr *> args, FieldDecl *initializedFieldInUnion,
1025 Expr *arrayFiller) {
1028 const AggValueSlot dest = ensureSlot(loc, e->
getType());
1031 cir::ArrayType arrayTy =
1038 "visitCXXParenListOrInitListExpr variable array type");
1044 "visitCXXParenListOrInitListExpr array type");
1054 unsigned numInitElements = args.size();
1061 unsigned curInitIndex = 0;
1064 if (
auto *cxxrd = dyn_cast<CXXRecordDecl>(record)) {
1065 assert(numInitElements >= cxxrd->getNumBases() &&
1066 "missing initializer for base class");
1067 for (
auto &base : cxxrd->bases()) {
1068 assert(!base.isVirtual() &&
"should not see vbases here");
1069 CXXRecordDecl *baseRD = base.getType()->getAsCXXRecordDecl();
1079 if (base.getType().isDestructedType()) {
1081 "push deferred deactivation cleanup");
1088 CIRGenFunction::FieldConstructionScope fcScope(cgf, dest.
getAddress());
1092 if (record->isUnion()) {
1094 "visitCXXParenListOrInitListExpr union type");
1100 for (
const FieldDecl *field : record->fields()) {
1102 if (field->getType()->isIncompleteArrayType())
1106 if (field->isUnnamedBitField())
1112 if (curInitIndex == numInitElements && dest.
isZeroed() &&
1120 if (curInitIndex < numInitElements) {
1122 CIRGenFunction::SourceLocRAIIObject loc{
1123 cgf, cgf.
getLoc(record->getSourceRange())};
1124 emitInitializationToLValue(args[curInitIndex++], lv);
1133 if (field->getType().isDestructedType()) {
1135 "visitCXXParenListOrInitListExpr destructor");
1159 getContext().getASTRecordLayout(baseRD).getSize() <=
1168 AggExprEmitter(*
this, slot).Visit(
const_cast<Expr *
>(e));
1183 assert((record->hasTrivialCopyConstructor() ||
1184 record->hasTrivialCopyAssignment() ||
1185 record->hasTrivialMoveConstructor() ||
1186 record->hasTrivialMoveAssignment() ||
1187 record->hasAttr<TrivialABIAttr>() || record->isUnion()) &&
1188 "Trying to aggregate-copy a type without a trivial copy/move "
1189 "constructor or assignment operator");
1191 if (record->isEmpty())
1214 typeInfo =
getContext().getTypeInfoDataSizeInChars(ty);
1216 typeInfo =
getContext().getTypeInfoInChars(ty);
1226 cgm.errorNYI(
"emitAggregateCopy: GC");
1228 [[maybe_unused]] cir::CopyOp copyOp =
static bool isBlockVarRef(const Expr *E)
Is the value of the given expression possibly a reference to or into a __block variable?
static bool isTrivialFiller(Expr *e)
__device__ __2f16 float __ockl_bool s
cir::ConditionOp createCondition(mlir::Value condition)
Create a loop condition.
cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base, mlir::Value stride)
cir::PointerType getPointerTo(mlir::Type ty)
cir::DoWhileOp createDoWhile(mlir::Location loc, llvm::function_ref< void(mlir::OpBuilder &, mlir::Location)> condBuilder, llvm::function_ref< void(mlir::OpBuilder &, mlir::Location)> bodyBuilder)
Create a do-while operation.
cir::ConstantOp getConstantInt(mlir::Location loc, mlir::Type ty, int64_t value)
cir::YieldOp createYield(mlir::Location loc, mlir::ValueRange value={})
Create a yield operation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
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.
CharUnits getNonVirtualSize() const
getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Represents a loop initializing the elements of an array.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
QualType getElementType() const
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
A builtin binary operation expression such as "x + y" or "x <= y".
SourceLocation getBeginLoc() const LLVM_READONLY
mlir::Value getPointer() const
mlir::Type getElementType() const
clang::CharUnits getAlignment() const
mlir::Value emitRawPointer() const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
IsZeroed_t isZeroed() const
Overlap_t mayOverlap() const
static AggValueSlot forAddr(Address addr, clang::Qualifiers quals, IsDestructed_t isDestructed, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed)
IsDestructed_t isExternallyDestructed() const
static AggValueSlot forLValue(const LValue &LV, 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.
IsAliased_t isPotentiallyAliased() const
void setVolatile(bool flag)
cir::CmpThreeWayOp createThreeWayCmpTotalOrdering(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, const llvm::APSInt <Res, const llvm::APSInt &eqRes, const llvm::APSInt >Res, cir::CmpOrdering ordering)
cir::CmpThreeWayOp createThreeWayCmpPartialOrdering(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, const llvm::APSInt <Res, const llvm::APSInt &eqRes, const llvm::APSInt >Res, const llvm::APSInt &unorderedRes)
cir::ConstantOp getConstInt(mlir::Location loc, llvm::APSInt intVal)
cir::LoadOp createLoad(mlir::Location loc, Address addr, bool isVolatile=false)
static bool hasScalarEvaluationKind(clang::QualType type)
mlir::Type convertType(clang::QualType t)
static cir::TypeEvaluationKind getEvaluationKind(clang::QualType type)
Return the cir::TypeEvaluationKind of QualType type.
CIRGenTypes & getTypes() const
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,...
RValue emitCallExpr(const clang::CallExpr *e, ReturnValueSlot returnValue=ReturnValueSlot())
LValue emitLValue(const clang::Expr *e)
Emit code to compute a designator that specifies the location of the expression.
void emitAggregateCopy(LValue dest, LValue src, QualType eltTy, AggValueSlot::Overlap_t mayOverlap, bool isVolatile=false)
Emit an aggregate copy.
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
void emitAggregateStore(mlir::Value value, Address dest)
RValue emitAtomicExpr(AtomicExpr *e)
void emitNullInitialization(mlir::Location loc, Address destPtr, QualType ty)
RValue emitReferenceBindingToExpr(const Expr *e)
Emits a reference binding to the passed in expression.
AggValueSlot::Overlap_t getOverlapForFieldInit(const FieldDecl *fd)
void emitCXXConstructExpr(const clang::CXXConstructExpr *e, AggValueSlot dest)
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)
static bool hasAggregateEvaluationKind(clang::QualType type)
void emitScalarInit(const clang::Expr *init, mlir::Location loc, LValue lvalue, bool capturedByInit=false)
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...
mlir::Value emitScalarExpr(const clang::Expr *e, bool ignoreResultAssign=false)
Emit the computation of the specified expression of scalar type.
Address getAddressOfDirectBaseInCompleteClass(mlir::Location loc, Address value, const CXXRecordDecl *derived, const CXXRecordDecl *base, bool baseIsVirtual)
Convert the given pointer to a complete class to the given direct base.
CIRGenBuilderTy & getBuilder()
AggValueSlot::Overlap_t getOverlapForBaseInit(const CXXRecordDecl *rd, const CXXRecordDecl *baseRD, bool isVirtual)
Determine whether a base class initialization may overlap some other object.
void emitComplexExprIntoLValue(const Expr *e, LValue dest, bool isInit)
LValue makeAddrLValue(Address addr, QualType ty, AlignmentSource source=AlignmentSource::Type)
mlir::Value emitStoreThroughBitfieldLValue(RValue src, LValue dstresult)
std::optional< mlir::Location > currSrcLoc
Use to track source locations across nested visitor traversals.
clang::ASTContext & getContext() const
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 ...
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...
void emitAggExpr(const clang::Expr *e, AggValueSlot slot)
mlir::Value emitVAArg(VAArgExpr *ve)
Generate code to get an argument from the passed in pointer and update it accordingly.
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
const clang::LangOptions & getLangOpts() const
mlir::Value emitNullConstant(QualType t, mlir::Location loc)
Return the result of value-initializing the given type, i.e.
llvm::DenseMap< const clang::FieldDecl *, llvm::StringRef > lambdaFieldToName
Keep a map between lambda fields and names, this needs to be per module since lambdas might get gener...
bool isZeroInitializable(clang::QualType ty)
Return whether a type can be zero-initialized (in the C++ sense) with an LLVM zeroinitializer.
Address getAddress() 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)
CXXTemporary * getTemporary()
const Expr * getSubExpr() const
A default argument (C++ [dcl.fct.default]).
Expr * getExpr()
Get the initialization expression that will be used.
Represents a call to an inherited base class constructor from an inheriting constructor.
Represents a list-initialization with parenthesis.
MutableArrayRef< Expr * > getInitExprs()
FieldDecl * getInitializedFieldInUnion()
Represents a C++ struct/union/class.
bool isTriviallyCopyable() const
Determine whether this class is considered trivially copyable per (C++11 [class]p6).
SourceRange getSourceRange() const LLVM_READONLY
An expression "T()" which creates an rvalue of a non-class type T.
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
A C++ throw-expression (C++ [except.throw]).
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
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
static const char * getCastKindName(CastKind CK)
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
bool isPartial() const
True iff the comparison is not totally ordered.
const ValueInfo * getLess() const
const ValueInfo * getUnordered() const
const CXXRecordDecl * Record
The declaration for the comparison category type from the standard library.
bool isStrong() const
True iff the comparison is "strong".
const ValueInfo * getGreater() const
const ValueInfo * getEqualOrEquiv() const
const Expr * getInitializer() const
Represents the canonical version of C arrays with a specified constant size.
A reference to a declared variable, function, enum, etc.
InitListExpr * getUpdater() const
This represents one expression.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a member of a struct/union/class.
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.
const Expr * getSubExpr() const
Expr * getResultExpr()
Return the result expression of this controlling expression.
Represents an implicitly-generated value initialization of an object of a given type.
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.
bool hadArrayRangeDesignator() const
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
const Expr * getInit(unsigned Init) const
ArrayRef< Expr * > inits()
llvm::iterator_range< capture_init_iterator > capture_inits()
Retrieve the initialization expressions for this lambda's captures.
capture_range captures() const
Retrieve this lambda's captures.
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Represents a place-holder for an object not to be initialized by anything.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
const Expr * getSubExpr() const
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
bool isPODType(const ASTContext &Context) const
Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
@ PCK_Struct
The type is a struct containing a field whose type is neither PCK_Trivial nor PCK_VolatileTrivial.
Represents a struct/union/class.
field_range fields() const
specific_decl_iterator< FieldDecl > field_iterator
field_iterator field_begin() const
CompoundStmt * getSubStmt()
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...
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isConstantArrayType() const
bool isPointerType() const
bool isReferenceType() const
bool isVariableArrayType() const
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isAggregateType() const
Determines whether the type is a C++ aggregate type or C aggregate or union type.
RecordDecl * castAsRecordDecl() const
bool isAnyComplexType() const
bool isMemberPointerType() const
bool isRealFloatingType() const
Floating point categories.
bool isNullPtrType() const
bool isRecordType() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
Represents a call to the builtin function __builtin_va_arg.
Represents a variable declaration or definition.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ArrayType > arrayType
constexpr Variable var(Literal L)
Returns the variable of L.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
U cast(CodeGen::Address addr)
static bool emitLifetimeMarkers()
static bool aggValueSlotDestructedFlag()
static bool aggValueSlotGC()
static bool aggValueSlotAlias()
static bool opLoadStoreAtomic()
static bool aggEmitFinalDestCopyRValue()
static bool aggValueSlotVolatile()
static bool opScopeCleanupRegion()
static bool atomicTypes()
static bool cudaSupport()
static bool requiresCleanups()
static bool incrementProfileCounter()
clang::CharUnits getPointerAlign() const
llvm::APSInt getIntValue() const
Get the constant integer value used by this variable to represent the comparison category result type...