21 #include "llvm/IR/Constants.h"
22 #include "llvm/IR/Function.h"
23 #include "llvm/IR/GlobalVariable.h"
24 #include "llvm/IR/Intrinsics.h"
25 using namespace clang;
26 using namespace CodeGen;
33 class AggExprEmitter :
public StmtVisitor<AggExprEmitter> {
44 bool shouldUseDestForReturnSlot()
const {
45 return !(Dest.requiresGCollection() || Dest.isPotentiallyAliased());
49 if (!shouldUseDestForReturnSlot())
57 if (!Dest.isIgnored())
return Dest;
58 return CGF.CreateAggTemp(T,
"agg.tmp.ensured");
61 if (!Dest.isIgnored())
return;
62 Dest = CGF.CreateAggTemp(T,
"agg.tmp.ensured");
68 IsResultUnused(IsResultUnused) { }
77 void EmitAggLoadOfLValue(
const Expr *
E);
85 void EmitMoveFromReturnSlot(
const Expr *
E,
RValue Src);
87 void EmitArrayInit(
Address DestPtr, llvm::ArrayType *AType,
91 if (CGF.getLangOpts().getGC() && TypeRequiresGCollection(T))
96 bool TypeRequiresGCollection(
QualType T);
102 void Visit(
Expr *
E) {
107 void VisitStmt(
Stmt *
S) {
108 CGF.ErrorUnsupported(S,
"aggregate expression");
115 CGF.EmitCoawaitExpr(*E, Dest, IsResultUnused);
118 CGF.EmitCoyieldExpr(*E, Dest, IsResultUnused);
136 = CGF.tryEmitAsConstant(E)) {
137 EmitFinalDestCopy(E->
getType(), result.getReferenceLValue(CGF, E));
142 EmitAggLoadOfLValue(E);
145 void VisitMemberExpr(
MemberExpr *ME) { EmitAggLoadOfLValue(ME); }
146 void VisitUnaryDeref(
UnaryOperator *E) { EmitAggLoadOfLValue(E); }
147 void VisitStringLiteral(
StringLiteral *E) { EmitAggLoadOfLValue(E); }
150 EmitAggLoadOfLValue(E);
153 EmitAggLoadOfLValue(E);
158 void VisitCallExpr(
const CallExpr *E);
159 void VisitStmtExpr(
const StmtExpr *E);
161 void VisitPointerToDataMemberBinaryOperator(
const BinaryOperator *BO);
167 EmitAggLoadOfLValue(E);
192 void VisitCXXTypeidExpr(
CXXTypeidExpr *E) { EmitAggLoadOfLValue(E); }
198 LValue LV = CGF.EmitPseudoObjectLValue(E);
199 return EmitFinalDestCopy(E->
getType(), LV);
202 CGF.EmitPseudoObjectRValue(E, EnsureSlot(E->
getType()));
210 void VisitCXXThrowExpr(
const CXXThrowExpr *E) { CGF.EmitCXXThrowExpr(E); }
212 RValue Res = CGF.EmitAtomicExpr(E);
213 EmitFinalDestCopy(E->
getType(), Res);
225 void AggExprEmitter::EmitAggLoadOfLValue(
const Expr *E) {
226 LValue LV = CGF.EmitLValue(E);
230 CGF.EmitAtomicLoad(LV, E->
getExprLoc(), Dest);
234 EmitFinalDestCopy(E->
getType(), LV);
238 bool AggExprEmitter::TypeRequiresGCollection(
QualType T) {
241 if (!RecordTy)
return false;
245 if (isa<CXXRecordDecl>(Record) &&
246 (cast<CXXRecordDecl>(Record)->hasNonTrivialCopyConstructor() ||
247 !cast<CXXRecordDecl>(Record)->hasTrivialDestructor()))
264 void AggExprEmitter::EmitMoveFromReturnSlot(
const Expr *E,
RValue src) {
265 if (shouldUseDestForReturnSlot()) {
274 EmitFinalDestCopy(E->
getType(), src);
279 assert(src.
isAggregate() &&
"value must be aggregate value!");
281 EmitFinalDestCopy(type, srcLV);
285 void AggExprEmitter::EmitFinalDestCopy(
QualType type,
const LValue &src) {
290 if (Dest.isIgnored())
296 EmitCopy(type, Dest, srcAgg);
306 CharUnits sz = CGF.getContext().getTypeSizeInChars(type);
308 CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF,
330 assert(Array.
isSimple() &&
"initializer_list array not a simple lvalue");
335 assert(ArrayType &&
"std::initializer_list constructed from non-array");
341 CGF.ErrorUnsupported(E,
"weird std::initializer_list");
346 if (!Field->getType()->isPointerType() ||
347 !Ctx.
hasSameType(Field->getType()->getPointeeType(),
349 CGF.ErrorUnsupported(E,
"weird std::initializer_list");
355 LValue Start = CGF.EmitLValueForFieldInitialization(DestLV, *Field);
356 llvm::Value *Zero = llvm::ConstantInt::get(CGF.PtrDiffTy, 0);
359 Builder.CreateInBoundsGEP(ArrayPtr.getPointer(), IdxStart,
"arraystart");
360 CGF.EmitStoreThroughLValue(
RValue::get(ArrayStart), Start);
364 CGF.ErrorUnsupported(E,
"weird std::initializer_list");
369 LValue EndOrLength = CGF.EmitLValueForFieldInitialization(DestLV, *Field);
370 if (Field->getType()->isPointerType() &&
371 Ctx.
hasSameType(Field->getType()->getPointeeType(),
376 Builder.CreateInBoundsGEP(ArrayPtr.getPointer(), IdxEnd,
"arrayend");
377 CGF.EmitStoreThroughLValue(
RValue::get(ArrayEnd), EndOrLength);
380 CGF.EmitStoreThroughLValue(
RValue::get(Size), EndOrLength);
382 CGF.ErrorUnsupported(E,
"weird std::initializer_list");
393 if (isa<ImplicitValueInitExpr>(E))
396 if (
auto *ILE = dyn_cast<InitListExpr>(E)) {
397 if (ILE->getNumInits())
402 if (
auto *Cons = dyn_cast_or_null<CXXConstructExpr>(E))
403 return Cons->getConstructor()->isDefaultConstructor() &&
404 Cons->getConstructor()->isTrivial();
411 void AggExprEmitter::EmitArrayInit(
Address DestPtr, llvm::ArrayType *AType,
415 uint64_t NumArrayElements = AType->getNumElements();
416 assert(NumInitElements <= NumArrayElements);
420 llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0);
425 CharUnits elementSize = CGF.getContext().getTypeSizeInChars(elementType);
435 llvm::Instruction *cleanupDominator =
nullptr;
436 if (CGF.needsEHCleanup(dtorKind)) {
441 endOfInit = CGF.CreateTempAlloca(begin->getType(), CGF.getPointerAlign(),
442 "arrayinit.endOfInit");
443 cleanupDominator =
Builder.CreateStore(begin, endOfInit);
444 CGF.pushIrregularPartialArrayCleanup(begin, endOfInit, elementType,
446 CGF.getDestroyer(dtorKind));
447 cleanup = CGF.EHStack.stable_begin();
454 llvm::Value *one = llvm::ConstantInt::get(CGF.SizeTy, 1);
464 for (uint64_t i = 0; i != NumInitElements; ++i) {
467 element =
Builder.CreateInBoundsGEP(element, one,
"arrayinit.element");
476 CGF.MakeAddrLValue(
Address(element, elementAlign), elementType);
477 EmitInitializationToLValue(E->
getInit(i), elementLV);
487 if (NumInitElements != NumArrayElements &&
488 !(Dest.
isZeroed() && hasTrivialFiller &&
489 CGF.getTypes().isZeroInitializable(elementType))) {
495 if (NumInitElements) {
496 element =
Builder.CreateInBoundsGEP(element, one,
"arrayinit.start");
502 llvm::ConstantInt::get(CGF.SizeTy, NumArrayElements),
505 llvm::BasicBlock *entryBB =
Builder.GetInsertBlock();
506 llvm::BasicBlock *bodyBB = CGF.createBasicBlock(
"arrayinit.body");
509 CGF.EmitBlock(bodyBB);
510 llvm::PHINode *currentElement =
511 Builder.CreatePHI(element->getType(), 2,
"arrayinit.cur");
512 currentElement->addIncoming(element, entryBB);
523 CGF.MakeAddrLValue(
Address(currentElement, elementAlign), elementType);
525 EmitInitializationToLValue(filler, elementLV);
527 EmitNullInitializationToLValue(elementLV);
532 Builder.CreateInBoundsGEP(currentElement, one,
"arrayinit.next");
535 if (endOfInit.
isValid())
Builder.CreateStore(nextElement, endOfInit);
540 llvm::BasicBlock *endBB = CGF.createBasicBlock(
"arrayinit.end");
541 Builder.CreateCondBr(done, endBB, bodyBB);
542 currentElement->addIncoming(nextElement,
Builder.GetInsertBlock());
544 CGF.EmitBlock(endBB);
548 if (dtorKind) CGF.DeactivateCleanupBlock(cleanup, cleanupDominator);
560 EmitFinalDestCopy(e->
getType(), CGF.getOpaqueLValueMapping(e));
569 EmitAggLoadOfLValue(E);
582 if (
CastExpr *castE = dyn_cast<CastExpr>(op)) {
583 if (castE->getCastKind() ==
kind)
584 return castE->getSubExpr();
585 if (castE->getCastKind() == CK_NoOp)
592 void AggExprEmitter::VisitCastExpr(
CastExpr *E) {
593 if (
const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
594 CGF.CGM.EmitExplicitCastExprType(ECE, &CGF);
598 assert(isa<CXXDynamicCastExpr>(E) &&
"CK_Dynamic without a dynamic_cast?");
603 CGF.EmitDynamicCast(LV.
getAddress(), cast<CXXDynamicCastExpr>(
E));
605 CGF.CGM.ErrorUnsupported(E,
"non-simple lvalue dynamic_cast");
608 CGF.CGM.ErrorUnsupported(E,
"lvalue dynamic_cast with a destination");
625 CGF.MakeAddrLValue(CastPtr, Ty));
629 case CK_DerivedToBase:
630 case CK_BaseToDerived:
631 case CK_UncheckedDerivedToBase: {
632 llvm_unreachable(
"cannot perform hierarchy conversion in EmitAggExpr: "
633 "should have been unpacked before we got here");
636 case CK_NonAtomicToAtomic:
637 case CK_AtomicToNonAtomic: {
638 bool isToAtomic = (E->
getCastKind() == CK_NonAtomicToAtomic);
643 if (isToAtomic) std::swap(atomicType, valueType);
646 assert(CGF.getContext().hasSameUnqualifiedType(valueType,
651 if (Dest.
isIgnored() || !CGF.CGM.isPaddedAtomicType(atomicType)) {
656 (isToAtomic ? CK_AtomicToNonAtomic : CK_NonAtomicToAtomic);
660 assert(CGF.getContext().hasSameUnqualifiedType(op->getType(),
662 "peephole significantly changed types?");
670 if (!valueDest.
isIgnored() && CGF.CGM.isPaddedAtomicType(atomicType)) {
674 CGF.EmitNullInitialization(Dest.
getAddress(), atomicType);
678 CGF.Builder.CreateStructGEP(valueDest.
getAddress(), 0,
695 CGF.CreateAggTemp(atomicType,
"atomic-to-nonatomic.temp");
701 return EmitFinalDestCopy(valueType, rvalue);
704 case CK_LValueToRValue:
715 case CK_UserDefinedConversion:
716 case CK_ConstructorConversion:
719 "Implicit cast types must be compatible");
723 case CK_LValueBitCast:
724 llvm_unreachable(
"should not be emitting lvalue bitcast as rvalue");
728 case CK_ArrayToPointerDecay:
729 case CK_FunctionToPointerDecay:
730 case CK_NullToPointer:
731 case CK_NullToMemberPointer:
732 case CK_BaseToDerivedMemberPointer:
733 case CK_DerivedToBaseMemberPointer:
734 case CK_MemberPointerToBoolean:
735 case CK_ReinterpretMemberPointer:
736 case CK_IntegralToPointer:
737 case CK_PointerToIntegral:
738 case CK_PointerToBoolean:
741 case CK_IntegralCast:
742 case CK_BooleanToSignedIntegral:
743 case CK_IntegralToBoolean:
744 case CK_IntegralToFloating:
745 case CK_FloatingToIntegral:
746 case CK_FloatingToBoolean:
747 case CK_FloatingCast:
748 case CK_CPointerToObjCPointerCast:
749 case CK_BlockPointerToObjCPointerCast:
750 case CK_AnyPointerToBlockPointerCast:
751 case CK_ObjCObjectLValueCast:
752 case CK_FloatingRealToComplex:
753 case CK_FloatingComplexToReal:
754 case CK_FloatingComplexToBoolean:
755 case CK_FloatingComplexCast:
756 case CK_FloatingComplexToIntegralComplex:
757 case CK_IntegralRealToComplex:
758 case CK_IntegralComplexToReal:
759 case CK_IntegralComplexToBoolean:
760 case CK_IntegralComplexCast:
761 case CK_IntegralComplexToFloatingComplex:
762 case CK_ARCProduceObject:
763 case CK_ARCConsumeObject:
764 case CK_ARCReclaimReturnedObject:
765 case CK_ARCExtendBlockObject:
766 case CK_CopyAndAutoreleaseBlockObject:
767 case CK_BuiltinFnToFnPtr:
768 case CK_ZeroToOCLEvent:
769 case CK_ZeroToOCLQueue:
770 case CK_AddressSpaceConversion:
771 case CK_IntToOCLSampler:
772 llvm_unreachable(
"cast kind invalid for aggregate types");
776 void AggExprEmitter::VisitCallExpr(
const CallExpr *E) {
778 EmitAggLoadOfLValue(E);
782 RValue RV = CGF.EmitCallExpr(E, getReturnValueSlot());
783 EmitMoveFromReturnSlot(E, RV);
787 RValue RV = CGF.EmitObjCMessageExpr(E, getReturnValueSlot());
788 EmitMoveFromReturnSlot(E, RV);
792 CGF.EmitIgnoredExpr(E->
getLHS());
796 void AggExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
798 CGF.EmitCompoundStmt(*E->
getSubStmt(),
true, Dest);
801 void AggExprEmitter::VisitBinaryOperator(
const BinaryOperator *E) {
803 VisitPointerToDataMemberBinaryOperator(E);
805 CGF.ErrorUnsupported(E,
"aggregate binary expression");
808 void AggExprEmitter::VisitPointerToDataMemberBinaryOperator(
810 LValue LV = CGF.EmitPointerToDataMemberBinaryExpr(E);
811 EmitFinalDestCopy(E->
getType(), LV);
821 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
823 return (var && var->
hasAttr<BlocksAttr>());
832 if (op->isAssignmentOp() || op->isPtrMemOp())
836 if (op->getOpcode() == BO_Comma)
844 = dyn_cast<AbstractConditionalOperator>(E)) {
850 = dyn_cast<OpaqueValueExpr>(E)) {
851 if (
const Expr *src = op->getSourceExpr())
858 }
else if (
const CastExpr *
cast = dyn_cast<CastExpr>(E)) {
859 if (
cast->getCastKind() == CK_LValueToRValue)
865 }
else if (
const UnaryOperator *uop = dyn_cast<UnaryOperator>(E)) {
869 }
else if (
const MemberExpr *mem = dyn_cast<MemberExpr>(E)) {
883 assert(CGF.getContext().hasSameUnqualifiedType(E->
getLHS()->
getType(),
885 &&
"Invalid assignment");
901 if (LHS.getType()->isAtomicType() ||
902 CGF.LValueIsSuitableForInlineAtomic(LHS)) {
903 CGF.EmitAtomicStore(Dest.
asRValue(), LHS,
false);
920 CGF.LValueIsSuitableForInlineAtomic(LHS)) {
923 CGF.EmitAtomicStore(Dest.
asRValue(), LHS,
false);
937 CGF.EmitAggExpr(E->
getRHS(), LHSSlot);
940 EmitFinalDestCopy(E->
getType(), LHS);
943 void AggExprEmitter::
945 llvm::BasicBlock *LHSBlock = CGF.createBasicBlock(
"cond.true");
946 llvm::BasicBlock *RHSBlock = CGF.createBasicBlock(
"cond.false");
947 llvm::BasicBlock *ContBlock = CGF.createBasicBlock(
"cond.end");
953 CGF.EmitBranchOnBoolExpr(E->
getCond(), LHSBlock, RHSBlock,
954 CGF.getProfileCount(E));
960 CGF.EmitBlock(LHSBlock);
961 CGF.incrementProfileCounter(E);
965 assert(CGF.HaveInsertPoint() &&
"expression evaluation ended with no IP!");
966 CGF.Builder.CreateBr(ContBlock);
975 CGF.EmitBlock(RHSBlock);
979 CGF.EmitBlock(ContBlock);
982 void AggExprEmitter::VisitChooseExpr(
const ChooseExpr *CE) {
986 void AggExprEmitter::VisitVAArgExpr(
VAArgExpr *VE) {
988 Address ArgPtr = CGF.EmitVAArg(VE, ArgValue);
992 CGF.ErrorUnsupported(VE,
"aggregate va_arg expression");
996 EmitFinalDestCopy(VE->
getType(), CGF.MakeAddrLValue(ArgPtr, VE->
getType()));
1011 if (!wasExternallyDestructed)
1018 CGF.EmitCXXConstructExpr(E, Slot);
1021 void AggExprEmitter::VisitCXXInheritedCtorInitExpr(
1024 CGF.EmitInheritedCXXConstructorCall(
1030 AggExprEmitter::VisitLambdaExpr(
LambdaExpr *E) {
1032 CGF.EmitLambdaExpr(E, Slot);
1036 CGF.enterFullExpression(E);
1044 EmitNullInitializationToLValue(CGF.MakeAddrLValue(Slot.
getAddress(), T));
1050 EmitNullInitializationToLValue(CGF.MakeAddrLValue(Slot.
getAddress(), T));
1061 return IL->getValue() == 0;
1064 return FL->getValue().isPosZero();
1066 if ((isa<ImplicitValueInitExpr>(E) || isa<CXXScalarValueInitExpr>(E)) &&
1070 if (
const CastExpr *ICE = dyn_cast<CastExpr>(E))
1071 return ICE->getCastKind() == CK_NullToPointer &&
1075 return CL->getValue() == 0;
1083 AggExprEmitter::EmitInitializationToLValue(
Expr *E,
LValue LV) {
1090 }
else if (isa<ImplicitValueInitExpr>(E) || isa<CXXScalarValueInitExpr>(
E)) {
1091 return EmitNullInitializationToLValue(LV);
1092 }
else if (isa<NoInitExpr>(E)) {
1096 RValue RV = CGF.EmitReferenceBindingToExpr(E);
1097 return CGF.EmitStoreThroughLValue(RV, LV);
1100 switch (CGF.getEvaluationKind(type)) {
1102 CGF.EmitComplexExprIntoLValue(E, LV,
true);
1113 CGF.EmitScalarInit(E,
nullptr, LV,
false);
1115 CGF.EmitStoreThroughLValue(
RValue::get(CGF.EmitScalarExpr(E)), LV);
1119 llvm_unreachable(
"bad evaluation kind");
1122 void AggExprEmitter::EmitNullInitializationToLValue(
LValue lv) {
1127 if (Dest.
isZeroed() && CGF.getTypes().isZeroInitializable(type))
1130 if (CGF.hasScalarEvaluationKind(type)) {
1132 llvm::Value *null = CGF.CGM.EmitNullConstant(type);
1136 CGF.EmitStoreThroughBitfieldLValue(
RValue::get(null), lv);
1139 CGF.EmitStoreOfScalar(null, lv,
true);
1149 void AggExprEmitter::VisitInitListExpr(
InitListExpr *E) {
1156 if (llvm::Constant* C = CGF.CGM.EmitConstantExpr(E, E->
getType(), &CGF)) {
1157 llvm::GlobalVariable* GV =
1158 new llvm::GlobalVariable(CGF.CGM.getModule(),
C->getType(),
true,
1160 EmitFinalDestCopy(E->
getType(), CGF.MakeAddrLValue(GV, E->
getType()));
1165 CGF.ErrorUnsupported(E,
"GNU array range designator extension");
1177 CGF.getContext().getAsArrayType(E->
getType())->getElementType();
1180 EmitArrayInit(Dest.
getAddress(), AType, elementType,
E);
1196 llvm::Instruction *cleanupDominator =
nullptr;
1198 unsigned curInitIndex = 0;
1201 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(record)) {
1202 assert(E->
getNumInits() >= CXXRD->getNumBases() &&
1203 "missing initializer for base class");
1204 for (
auto &
Base : CXXRD->bases()) {
1205 assert(!
Base.isVirtual() &&
"should not see vbases here");
1206 auto *BaseRD =
Base.getType()->getAsCXXRecordDecl();
1207 Address V = CGF.GetAddressOfDirectBaseInCompleteClass(
1215 CGF.EmitAggExpr(E->
getInit(curInitIndex++), AggSlot);
1218 Base.getType().isDestructedType()) {
1219 CGF.pushDestroy(dtorKind, V,
Base.getType());
1220 cleanups.push_back(CGF.EHStack.stable_begin());
1237 for (
const auto *Field : record->
fields())
1238 assert(Field->isUnnamedBitfield() &&
"Only unnamed bitfields allowed");
1246 LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestLV, Field);
1247 if (NumInitElements) {
1249 EmitInitializationToLValue(E->
getInit(0), FieldLoc);
1252 EmitNullInitializationToLValue(FieldLoc);
1260 for (
const auto *field : record->
fields()) {
1262 if (field->getType()->isIncompleteArrayType())
1266 if (field->isUnnamedBitfield())
1272 if (curInitIndex == NumInitElements && Dest.
isZeroed() &&
1273 CGF.getTypes().isZeroInitializable(E->
getType()))
1277 LValue LV = CGF.EmitLValueForFieldInitialization(DestLV, field);
1281 if (curInitIndex < NumInitElements) {
1283 EmitInitializationToLValue(E->
getInit(curInitIndex++), LV);
1286 EmitNullInitializationToLValue(LV);
1292 bool pushedCleanup =
false;
1294 = field->getType().isDestructedType()) {
1296 if (CGF.needsEHCleanup(dtorKind)) {
1297 if (!cleanupDominator)
1298 cleanupDominator = CGF.Builder.CreateAlignedLoad(
1300 llvm::Constant::getNullValue(CGF.Int8PtrTy),
1304 CGF.getDestroyer(dtorKind),
false);
1305 cleanups.push_back(CGF.EHStack.stable_begin());
1306 pushedCleanup =
true;
1312 if (!pushedCleanup && LV.
isSimple())
1313 if (llvm::GetElementPtrInst *GEP =
1314 dyn_cast<llvm::GetElementPtrInst>(LV.
getPointer()))
1315 if (GEP->use_empty())
1316 GEP->eraseFromParent();
1321 for (
unsigned i = cleanups.size(); i != 0; --i)
1322 CGF.DeactivateCleanupBlock(cleanups[i-1], cleanupDominator);
1325 if (cleanupDominator)
1326 cleanupDominator->eraseFromParent();
1335 uint64_t numElements = E->
getArraySize().getZExtValue();
1341 llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0);
1353 CGF.getContext().getAsArrayType(E->
getType())->getElementType();
1354 CharUnits elementSize = CGF.getContext().getTypeSizeInChars(elementType);
1358 llvm::BasicBlock *entryBB =
Builder.GetInsertBlock();
1359 llvm::BasicBlock *bodyBB = CGF.createBasicBlock(
"arrayinit.body");
1362 CGF.EmitBlock(bodyBB);
1363 llvm::PHINode *index =
1364 Builder.CreatePHI(zero->getType(), 2,
"arrayinit.index");
1365 index->addIncoming(zero, entryBB);
1371 if (CGF.needsEHCleanup(dtorKind) && !InnerLoop) {
1372 if (outerBegin->getType() != element->getType())
1373 outerBegin =
Builder.CreateBitCast(outerBegin, element->getType());
1374 CGF.pushRegularPartialArrayCleanup(outerBegin, element, elementType,
1376 CGF.getDestroyer(dtorKind));
1377 cleanup = CGF.EHStack.stable_begin();
1389 CGF.MakeAddrLValue(
Address(element, elementAlign), elementType);
1396 AggExprEmitter(CGF, elementSlot,
false)
1397 .VisitArrayInitLoopExpr(InnerLoop, outerBegin);
1399 EmitInitializationToLValue(E->
getSubExpr(), elementLV);
1404 index, llvm::ConstantInt::get(CGF.SizeTy, 1),
"arrayinit.next");
1405 index->addIncoming(nextIndex,
Builder.GetInsertBlock());
1409 nextIndex, llvm::ConstantInt::get(CGF.SizeTy, numElements),
1411 llvm::BasicBlock *endBB = CGF.createBasicBlock(
"arrayinit.end");
1412 Builder.CreateCondBr(done, endBB, bodyBB);
1414 CGF.EmitBlock(endBB);
1418 CGF.DeactivateCleanupBlock(cleanup, index);
1425 EmitInitializationToLValue(E->
getBase(), DestLV);
1452 if (!RT->isUnionType()) {
1456 unsigned ILEElement = 0;
1457 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(SD))
1458 while (ILEElement != CXXRD->getNumBases())
1461 for (
const auto *Field : SD->
fields()) {
1480 return NumNonZeroBytes;
1486 for (
unsigned i = 0, e = ILE->
getNumInits(); i != e; ++i)
1488 return NumNonZeroBytes;
1505 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
1518 if (NumNonZeroBytes*4 > Size)
1541 "Invalid aggregate expression to emit");
1543 "slot has bits but no address");
1548 AggExprEmitter(*
this, Slot, Slot.
isIgnored()).Visit(const_cast<Expr*>(E));
1564 bool isAssignment) {
1575 "Trying to aggregate-copy a type without a trivial copy/move "
1576 "constructor or assignment operator");
1598 std::pair<CharUnits, CharUnits>
TypeInfo;
1605 if (TypeInfo.first.isZero()) {
1607 if (
auto *VAT = dyn_cast_or_null<VariableArrayType>(
1612 std::pair<CharUnits, CharUnits> LastElementTypeInfo;
1615 assert(!TypeInfo.first.isZero());
1616 SizeVal =
Builder.CreateNUWMul(
1618 llvm::ConstantInt::get(
SizeTy, TypeInfo.first.getQuantity()));
1619 if (!isAssignment) {
1620 SizeVal =
Builder.CreateNUWSub(
1622 llvm::ConstantInt::get(
SizeTy, TypeInfo.first.getQuantity()));
1623 SizeVal =
Builder.CreateNUWAdd(
1624 SizeVal, llvm::ConstantInt::get(
1625 SizeTy, LastElementTypeInfo.first.getQuantity()));
1630 SizeVal = llvm::ConstantInt::get(
SizeTy, TypeInfo.first.getQuantity());
1676 Inst->setMetadata(llvm::LLVMContext::MD_tbaa_struct, TBAAStructTag);
ReturnValueSlot - Contains the address where the return value of a function can be stored...
Defines the clang::ASTContext interface.
unsigned getNumInits() const
CastKind getCastKind() const
A (possibly-)qualified type.
bool isPODType(const ASTContext &Context) const
Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
llvm::Value * getPointer() const
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after...
CompoundStmt * getSubStmt()
static AggValueSlot forLValue(const LValue &LV, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, IsZeroed_t isZeroed=IsNotZeroed)
Stmt - This represents one statement.
const TargetInfo & getTarget() const
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
Expr * GetTemporaryExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
bool isRecordType() const
virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr, llvm::Value *Size)=0
llvm::MDNode * getTBAAStructInfo(QualType QTy)
Address getAddress() const
Defines the C++ template declaration subclasses.
ParenExpr - This represents a parethesized expression, e.g.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
const Expr * getResultExpr() const
The generic selection's result expression.
Represents a call to a C++ constructor.
void setZeroed(bool V=true)
const LangOptions & getLangOpts() const
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
Represents a prvalue temporary that is written into memory so that a reference can bind to it...
const llvm::APInt & getSize() const
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic, and whose semantics are that of the sole contained initializer)?
bool hadArrayRangeDesignator() const
static bool isBlockVarRef(const Expr *E)
Is the value of the given expression possibly a reference to or into a __block variable?
static Expr * findPeephole(Expr *op, CastKind kind)
Attempt to look through various unimportant expressions to find a cast of the given kind...
VarDecl - An instance of this class is created to represent a variable declaration or definition...
llvm::Type * getElementType() const
Return the type of the values stored in this address.
CompoundLiteralExpr - [C99 6.5.2.5].
static bool isSimpleZero(const Expr *E, CodeGenFunction &CGF)
isSimpleZero - If emitting this value will obviously just cause a store of zero to memory...
field_iterator field_begin() const
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
IsZeroed_t isZeroed() const
A C++ throw-expression (C++ [except.throw]).
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
The collection of all-type qualifiers we support.
bool hasTrivialCopyConstructor() const
Determine whether this class has a trivial copy constructor (C++ [class.copy]p6, C++11 [class...
static CharUnits GetNumNonZeroBytesInInit(const Expr *E, CodeGenFunction &CGF)
GetNumNonZeroBytesInInit - Get an approximate count of the number of non-zero bytes that will be stor...
RecordDecl - Represents a struct/union/class.
An object to manage conditionally-evaluated expressions.
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool isReferenceType() const
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
llvm::IntegerType * SizeTy
Represents a place-holder for an object not to be initialized by anything.
An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
static bool isTrivialFiller(Expr *E)
Determine if E is a trivial array filler, that is, one that is equivalent to zero-initialization.
void setNonGC(bool Value)
Describes an C or C++ initializer list.
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
Expr * getTrueExpr() const
Address CreateElementBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
Cast the element type of the given address to a different type, preserving information like the align...
CharUnits - This is an opaque type for sizes expressed in character units.
field_range fields() const
A builtin binary operation expression such as "x + y" or "x <= y".
RecordDecl * getDecl() const
llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)
Scope - A scope is a transient data structure that is used while parsing the program.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Represents binding an expression to a temporary.
CXXTemporary * getTemporary()
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
std::pair< CharUnits, CharUnits > getTypeInfoInChars(const Type *T) const
A default argument (C++ [dcl.fct.default]).
bool isUnnamedBitfield() const
Determines whether this is an unnamed bitfield.
Checking the operand of a load. Must be suitably sized and aligned.
field_iterator field_end() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
static CharUnits One()
One - Construct a CharUnits quantity of one.
CastKind
CastKind - The kind of operation required for a conversion.
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
const Expr * getExpr() const
Get the initialization expression that will be used.
Represents a call to the builtin function __builtin_va_arg.
std::pair< CharUnits, CharUnits > getTypeInfoDataSizeInChars(QualType T) const
bool isPointerZeroInitializable(QualType T)
Check if the pointer type can be zero-initialized (in the C++ sense) with an LLVM zeroinitializer...
CGObjCRuntime & getObjCRuntime()
Return a reference to the configured Objective-C runtime.
An expression "T()" which creates a value-initialized rvalue of type T, which is a non-class type...
llvm::Value * getPointer() const
Expr - This represents one expression.
bool isAnyComplexType() const
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
bool isAtomicType() const
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
An RAII object to record that we're evaluating a statement expression.
Expr * getSubExpr() const
An expression that sends a message to the given Objective-C object or class.
llvm::CallInst * CreateMemSet(Address Dest, llvm::Value *Value, llvm::Value *Size, bool IsVolatile=false)
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
llvm::APInt getArraySize() const
Represents a reference to a non-type template parameter that has been substituted with a template arg...
The scope of a CXXDefaultInitExpr.
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, IsZeroed_t isZeroed=IsNotZeroed)
forAddr - Make a slot for an aggregate value.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
InitListExpr * getUpdater() const
The scope of an ArrayInitLoopExpr.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
Represents a call to an inherited base class constructor from an inheriting constructor.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
ASTContext & getContext() const
A saved depth on the scope stack.
LValue EmitAggExprToLValue(const Expr *E)
EmitAggExprToLValue - Emit the computation of the specified expression of aggregate type into a tempo...
A scoped helper to set the current debug location to the specified location or preferred location of ...
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
const ConstantArrayType * getAsConstantArrayType(QualType T) const
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load, __atomic_store, and __atomic_compare_exchange_*, for the similarly-named C++11 instructions, and __c11 variants for <stdatomic.h>.
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
static void CheckAggExprForMemSetUse(AggValueSlot &Slot, const Expr *E, CodeGenFunction &CGF)
CheckAggExprForMemSetUse - If the initializer is large and has a lot of zeros in it, emit a memset and avoid storing the individual zeros.
const LangOptions & getLangOpts() const
const T * castAs() const
Member-template castAs<specific type>.
bool hasObjectMember() const
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool hasTrivialCopyAssignment() const
Determine whether this class has a trivial copy assignment operator (C++ [class.copy]p11, C++11 [class.copy]p25)
void setExternallyDestructed(bool destructed=true)
Represents a C11 generic selection.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
Expr * getReplacement() const
CharUnits getAlignment() const
Return the alignment of this pointer.
void setVolatile(bool flag)
llvm::Value * getAggregatePointer() const
const Expr * getExpr() const
[C99 6.4.2.2] - A predefined identifier such as func.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
static AggValueSlot ignored()
ignored - Returns an aggregate value slot indicating that the aggregate value is being ignored...
A scope within which we are constructing the fields of an object which might use a CXXDefaultInitExpr...
Represents a 'co_yield' expression.
U cast(CodeGen::Address addr)
IsAliased_t isPotentiallyAliased() const
bool hasTrivialMoveConstructor() const
Determine whether this class has a trivial move constructor (C++11 [class.copy]p12) ...
Checking the destination of a store. Must be suitably sized and aligned.
detail::InMemoryDirectory::const_iterator E
void EmitAggregateCopy(Address DestPtr, Address SrcPtr, QualType EltTy, bool isVolatile=false, bool isAssignment=false)
EmitAggregateCopy - Emit an aggregate copy.
IsDestructed_t isExternallyDestructed() const
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext, providing only those that are of type SpecificDecl (or a class derived from it).
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type. ...
static bool hasAggregateEvaluationKind(QualType T)
bool hasTrivialMoveAssignment() const
Determine whether this class has a trivial move assignment operator (C++11 [class.copy]p25)
llvm::PointerType * getType() const
Return the type of the pointer value.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
const T * getAs() const
Member-template getAs<specific type>'.
Expr * getFalseExpr() const
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
NeedsGCBarriers_t requiresGCollection() const
Represents a 'co_await' expression.
Address getAddress() const
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
bool inheritedFromVBase() const
Determine whether the inherited constructor is inherited from a virtual base of the object we constru...
const Expr * getInitializer() const
ObjCIvarRefExpr - A reference to an ObjC instance variable.
uint64_t getPointerWidth(unsigned AddrSpace) const
Return the width of pointers on this target, for the specified address space.
A use of a default initializer in a constructor or in aggregate initialization.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
const Expr * getSubExpr() const
Represents a C++ struct/union/class.
BoundNodesTreeBuilder *const Builder
Represents a loop initializing the elements of an array.
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
LValue MakeAddrLValue(Address Addr, QualType T, LValueBaseInfo BaseInfo=LValueBaseInfo(AlignmentSource::Type))
unsigned kind
All of the diagnostics that can be emitted by the frontend.
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
StringLiteral - This represents a string literal expression, e.g.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
bool constructsVBase() const
Determine whether this constructor is actually constructing a base class (rather than a complete obje...
bool isIncompleteArrayType() const
A reference to a declared variable, function, enum, etc.
static RValue get(llvm::Value *V)
QualType getElementType() const
const Expr * getInit(unsigned Init) const
const Expr * getSubExpr() const
FieldDecl * getInitializedFieldInUnion()
If this initializes a union, specifies which field in the union to initialize.
static RValue getAggregate(Address addr, bool isVolatile=false)
CodeGenTypes & getTypes() const
LValue - This represents an lvalue references.
Qualifiers getQualifiers() const
llvm::Value * emitArrayLength(const ArrayType *arrayType, QualType &baseType, Address &addr)
emitArrayLength - Compute the length of an array, even if it's a VLA, and drill down to the base elem...
Expr * getSubExpr() const
Get the initializer to use for each array element.
Address CreateMemTemp(QualType T, const Twine &Name="tmp", bool CastToDefaultAddrSpace=true)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignment...
Represents the canonical version of C arrays with a specified constant size.
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
bool isZeroInitializable(QualType T)
IsZeroInitializable - Return whether a type can be zero-initialized (in the C++ sense) with an LLVM z...
Represents an implicitly-generated value initialization of an object of a given type.
bool hasUserDeclaredConstructor() const
Determine whether this class has any user-declared constructors.
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.