28#include "llvm/IR/Constants.h"
29#include "llvm/IR/Function.h"
30#include "llvm/IR/GlobalVariable.h"
31#include "llvm/IR/Instruction.h"
32#include "llvm/IR/IntrinsicInst.h"
33#include "llvm/IR/Intrinsics.h"
42class AggExprEmitter :
public StmtVisitor<AggExprEmitter> {
48 AggValueSlot EnsureSlot(QualType T) {
53 void EnsureDest(QualType T) {
65 void withReturnValueSlot(
const Expr *E,
66 llvm::function_ref<RValue(ReturnValueSlot)> Fn);
68 void DoZeroInitPadding(uint64_t &PaddingStart, uint64_t PaddingEnd,
69 const FieldDecl *NextField);
72 AggExprEmitter(CodeGenFunction &cgf, AggValueSlot Dest,
bool IsResultUnused)
73 : CGF(cgf), Builder(CGF.Builder), Dest(Dest),
74 IsResultUnused(IsResultUnused) {}
83 void EmitAggLoadOfLValue(
const Expr *E);
87 void EmitFinalDestCopy(QualType
type,
const LValue &src,
90 void EmitFinalDestCopy(QualType
type, RValue src);
91 void EmitCopy(QualType
type,
const AggValueSlot &dest,
92 const AggValueSlot &src);
94 void EmitArrayInit(Address DestPtr, llvm::ArrayType *AType, QualType ArrayQTy,
95 Expr *ExprToVisit, ArrayRef<Expr *> Args,
99 if (CGF.
getLangOpts().getGC() && TypeRequiresGCollection(T))
104 bool TypeRequiresGCollection(QualType T);
110 void Visit(Expr *E) {
111 ApplyDebugLocation DL(CGF, E);
112 StmtVisitor<AggExprEmitter>::Visit(E);
115 void VisitStmt(Stmt *S) { CGF.
ErrorUnsupported(S,
"aggregate expression"); }
116 void VisitParenExpr(ParenExpr *PE) { Visit(PE->
getSubExpr()); }
117 void VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
118 Visit(
GE->getResultExpr());
120 void VisitCoawaitExpr(CoawaitExpr *E) {
123 void VisitCoyieldExpr(CoyieldExpr *E) {
126 void VisitUnaryCoawait(UnaryOperator *E) { Visit(E->
getSubExpr()); }
127 void VisitUnaryExtension(UnaryOperator *E) { Visit(E->
getSubExpr()); }
128 void VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
132 void VisitConstantExpr(ConstantExpr *E) {
135 if (llvm::Value *
Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
138 llvm::TypeSize::getFixed(
148 void VisitDeclRefExpr(DeclRefExpr *E) { EmitAggLoadOfLValue(E); }
149 void VisitMemberExpr(MemberExpr *ME) { EmitAggLoadOfLValue(ME); }
150 void VisitUnaryDeref(UnaryOperator *E) { EmitAggLoadOfLValue(E); }
151 void VisitStringLiteral(StringLiteral *E) { EmitAggLoadOfLValue(E); }
152 void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
153 void VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
154 EmitAggLoadOfLValue(E);
156 void VisitPredefinedExpr(
const PredefinedExpr *E) { EmitAggLoadOfLValue(E); }
160 void VisitCallExpr(
const CallExpr *E);
161 void VisitStmtExpr(
const StmtExpr *E);
162 void VisitBinaryOperator(
const BinaryOperator *BO);
163 void VisitPointerToDataMemberBinaryOperator(
const BinaryOperator *BO);
164 void VisitBinAssign(
const BinaryOperator *E);
165 void VisitBinComma(
const BinaryOperator *E);
166 void VisitBinCmp(
const BinaryOperator *E);
167 void VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) {
171 void VisitObjCMessageExpr(ObjCMessageExpr *E);
172 void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { EmitAggLoadOfLValue(E); }
174 void VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E);
175 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO);
176 void VisitChooseExpr(
const ChooseExpr *CE);
177 void VisitInitListExpr(InitListExpr *E);
178 void VisitCXXParenListOrInitListExpr(Expr *ExprToVisit, ArrayRef<Expr *> Args,
179 FieldDecl *InitializedFieldInUnion,
181 void VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E,
182 llvm::Value *outerBegin =
nullptr);
183 void VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);
184 void VisitNoInitExpr(NoInitExpr *E) {}
185 void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
186 CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
189 void VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
190 CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
193 void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
194 void VisitCXXConstructExpr(
const CXXConstructExpr *E);
195 void VisitCXXInheritedCtorInitExpr(
const CXXInheritedCtorInitExpr *E);
197 void VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E);
198 void VisitExprWithCleanups(ExprWithCleanups *E);
199 void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
200 void VisitCXXTypeidExpr(CXXTypeidExpr *E) { EmitAggLoadOfLValue(E); }
201 void VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E);
202 void VisitOpaqueValueExpr(OpaqueValueExpr *E);
204 void VisitPseudoObjectExpr(PseudoObjectExpr *E) {
207 return EmitFinalDestCopy(E->
getType(), LV);
210 AggValueSlot Slot = EnsureSlot(E->
getType());
211 bool NeedsDestruction =
214 if (NeedsDestruction)
217 if (NeedsDestruction)
222 void VisitVAArgExpr(VAArgExpr *E);
223 void VisitCXXParenListInitExpr(CXXParenListInitExpr *E);
224 void VisitCXXParenListOrInitListExpr(Expr *ExprToVisit, ArrayRef<Expr *> Args,
227 void EmitInitializationToLValue(Expr *E, LValue Address);
228 void EmitNullInitializationToLValue(LValue Address);
231 void VisitAtomicExpr(AtomicExpr *E) {
233 EmitFinalDestCopy(E->
getType(), Res);
235 void VisitPackIndexingExpr(PackIndexingExpr *E) {
248void AggExprEmitter::EmitAggLoadOfLValue(
const Expr *E) {
257 EmitFinalDestCopy(E->
getType(), LV);
261bool AggExprEmitter::TypeRequiresGCollection(QualType T) {
277void AggExprEmitter::withReturnValueSlot(
278 const Expr *E, llvm::function_ref<RValue(ReturnValueSlot)> EmitCall) {
280 bool RequiresDestruction =
296 bool CanAggregateCopy =
301 : RetTy.isTriviallyCopyableType(CGF.getContext());
302 bool DestASMismatch = !Dest.
isIgnored() && CanAggregateCopy &&
305 ->stripPointerCasts()
307 ->getPointerAddressSpace() != SRetAS;
309 (RequiresDestruction && Dest.
isIgnored()) || DestASMismatch;
313 EHScopeStack::stable_iterator LifetimeEndBlock;
314 llvm::IntrinsicInst *LifetimeStartInst =
nullptr;
317 if (RetAddr.isValid() && RetAddr.getAddressSpace() != SRetAS) {
318 llvm::Type *SRetPtrTy =
320 RetAddr = RetAddr.withPointer(
322 RetAddr.isKnownNonNull());
329 assert(LifetimeStartInst->getIntrinsicID() ==
330 llvm::Intrinsic::lifetime_start &&
331 "Last insertion wasn't a lifetime.start?");
340 EmitCall(ReturnValueSlot(RetAddr, Dest.
isVolatile(), IsResultUnused,
348 EmitFinalDestCopy(E->
getType(), Src);
350 if (!RequiresDestruction && LifetimeStartInst) {
360void AggExprEmitter::EmitFinalDestCopy(QualType
type, RValue src) {
361 assert(src.
isAggregate() &&
"value must be aggregate value!");
367void AggExprEmitter::EmitFinalDestCopy(
368 QualType
type,
const LValue &src,
402 EmitCopy(
type, Dest, srcAgg);
409void AggExprEmitter::EmitCopy(QualType
type,
const AggValueSlot &dest,
410 const AggValueSlot &src) {
430void AggExprEmitter::VisitCXXStdInitializerListExpr(
431 CXXStdInitializerListExpr *E) {
436 assert(
Array.isSimple() &&
"initializer_list array not a simple lvalue");
439 const ConstantArrayType *ArrayType =
441 assert(ArrayType &&
"std::initializer_list constructed from non-array");
445 assert(Field !=
Record->field_end() &&
448 "Expected std::initializer_list first field to be const E *");
451 AggValueSlot Dest = EnsureSlot(E->
getType());
457 assert(Field !=
Record->field_end() &&
458 "Expected std::initializer_list to have two fields");
460 llvm::Value *
Size = Builder.getInt(ArrayType->
getSize());
468 assert(
Field->getType()->isPointerType() &&
471 "Expected std::initializer_list second field to be const E *");
472 llvm::Value *
Zero = llvm::ConstantInt::get(CGF.
PtrDiffTy, 0);
473 llvm::Value *IdxEnd[] = {
Zero,
Size};
474 llvm::Value *ArrayEnd = Builder.CreateInBoundsGEP(
480 assert(++Field ==
Record->field_end() &&
481 "Expected std::initializer_list to only have two fields");
493 if (
auto *ILE = dyn_cast<InitListExpr>(E)) {
494 if (ILE->getNumInits())
499 if (
auto *Cons = dyn_cast_or_null<CXXConstructExpr>(E))
500 return Cons->getConstructor()->isDefaultConstructor() &&
501 Cons->getConstructor()->isTrivial();
521 SrcTy = VT->getElementType();
522 assert(StoreList.size() <= VT->getNumElements() &&
523 "Cannot perform HLSL flat cast when vector source \
524 object has less elements than flattened destination \
528 for (
unsigned I = 0, Size = StoreList.size(); I < Size; I++) {
529 LValue DestLVal = StoreList[I];
549 assert(StoreList.size() <= LoadList.size() &&
550 "Cannot perform HLSL elementwise cast when flattened source object \
551 has less elements than flattened destination object.");
554 for (
unsigned I = 0, E = StoreList.size(); I < E; I++) {
555 LValue DestLVal = StoreList[I];
556 LValue SrcLVal = LoadList[I];
558 assert(RVal.
isScalar() &&
"All flattened source values should be scalars");
561 DestLVal.getType(), Loc);
568void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
569 QualType ArrayQTy, Expr *ExprToVisit,
570 ArrayRef<Expr *> Args, Expr *ArrayFiller) {
571 uint64_t NumInitElements = Args.size();
573 uint64_t NumArrayElements = AType->getNumElements();
574 for (
const auto *
Init : Args) {
575 if (
const auto *Embed = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
576 NumInitElements += Embed->getDataElementCount() - 1;
577 if (NumInitElements > NumArrayElements) {
578 NumInitElements = NumArrayElements;
584 assert(NumInitElements <= NumArrayElements);
586 QualType elementType =
589 CharUnits elementAlign =
596 if (NumInitElements * elementSize.
getQuantity() > 16 &&
598 CodeGen::CodeGenModule &CGM = CGF.
CGM;
599 ConstantEmitter Emitter(CGF);
604 if (llvm::Constant *
C =
605 Emitter.tryEmitForInitializer(ExprToVisit, AS, GVArrayQTy)) {
606 auto GV =
new llvm::GlobalVariable(
608 true, llvm::GlobalValue::PrivateLinkage,
C,
610 nullptr, llvm::GlobalVariable::NotThreadLocal,
612 Emitter.finalize(GV);
615 Address GVAddr(GV, GV->getValueType(), Align);
616 EmitFinalDestCopy(ArrayQTy, CGF.
MakeAddrLValue(GVAddr, GVArrayQTy));
626 CodeGenFunction::CleanupDeactivationScope deactivation(CGF);
630 CodeGenFunction::AllocaTrackerRAII allocaTracker(CGF);
635 llvm::Instruction *dominatingIP =
636 Builder.CreateFlagLoad(llvm::ConstantInt::getNullValue(CGF.
Int8PtrTy));
638 "arrayinit.endOfInit");
639 Builder.CreateStore(begin, endOfInit);
644 .AddAuxAllocas(allocaTracker.Take());
650 llvm::Value *one = llvm::ConstantInt::get(CGF.
SizeTy, 1);
653 llvm::Value *element = begin;
654 if (ArrayIndex > 0) {
656 element = Builder.CreateStructuredGEP(
657 AType, begin, llvm::ConstantInt::get(CGF.
SizeTy, ArrayIndex),
658 "arrayinit.element");
660 element = Builder.CreateInBoundsGEP(
661 llvmElementType, begin,
662 llvm::ConstantInt::get(CGF.
SizeTy, ArrayIndex),
663 "arrayinit.element");
669 Builder.CreateStore(element, endOfInit);
673 Address(element, llvmElementType, elementAlign), elementType);
674 EmitInitializationToLValue(
Init, elementLV);
678 unsigned ArrayIndex = 0;
680 for (uint64_t i = 0; i != NumInitElements; ++i) {
681 if (ArrayIndex >= NumInitElements)
683 if (
auto *EmbedS = dyn_cast<EmbedExpr>(Args[i]->IgnoreParenImpCasts())) {
684 EmbedS->doForEachDataElement(Emit, ArrayIndex);
686 Emit(Args[i], ArrayIndex);
697 if (NumInitElements != NumArrayElements &&
698 !(Dest.
isZeroed() && hasTrivialFiller &&
705 llvm::Value *element = begin;
706 if (NumInitElements) {
707 element = Builder.CreateInBoundsGEP(
708 llvmElementType, element,
709 llvm::ConstantInt::get(CGF.
SizeTy, NumInitElements),
712 Builder.CreateStore(element, endOfInit);
716 llvm::Value *end = Builder.CreateInBoundsGEP(
717 llvmElementType, begin,
718 llvm::ConstantInt::get(CGF.
SizeTy, NumArrayElements),
"arrayinit.end");
720 llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
725 llvm::PHINode *currentElement =
726 Builder.CreatePHI(element->getType(), 2,
"arrayinit.cur");
727 currentElement->addIncoming(element, entryBB);
736 CodeGenFunction::RunCleanupsScope CleanupsScope(CGF);
738 Address(currentElement, llvmElementType, elementAlign), elementType);
740 EmitInitializationToLValue(ArrayFiller, elementLV);
742 EmitNullInitializationToLValue(elementLV);
746 llvm::Value *nextElement = Builder.CreateInBoundsGEP(
747 llvmElementType, currentElement, one,
"arrayinit.next");
751 Builder.CreateStore(nextElement, endOfInit);
755 Builder.CreateICmpEQ(nextElement, end,
"arrayinit.done");
757 Builder.CreateCondBr(done, endBB, bodyBB);
758 currentElement->addIncoming(nextElement, Builder.GetInsertBlock());
768void AggExprEmitter::VisitMaterializeTemporaryExpr(
769 MaterializeTemporaryExpr *E) {
773void AggExprEmitter::VisitOpaqueValueExpr(OpaqueValueExpr *e) {
781void AggExprEmitter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
785 EmitAggLoadOfLValue(E);
789 AggValueSlot Slot = EnsureSlot(E->
getType());
811 if (
auto castE = dyn_cast<CastExpr>(op)) {
812 if (castE->getCastKind() ==
kind)
813 return castE->getSubExpr();
818void AggExprEmitter::VisitCastExpr(
CastExpr *E) {
819 if (
const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
854 case CK_LValueToRValueBitCast: {
862 Address SourceAddress = SourceLV.getAddress().withElementType(CGF.
Int8Ty);
864 llvm::Value *SizeVal = llvm::ConstantInt::get(
867 Builder.CreateMemCpy(DestAddress, SourceAddress, SizeVal);
871 case CK_DerivedToBase:
872 case CK_BaseToDerived:
873 case CK_UncheckedDerivedToBase: {
874 llvm_unreachable(
"cannot perform hierarchy conversion in EmitAggExpr: "
875 "should have been unpacked before we got here");
878 case CK_NonAtomicToAtomic:
879 case CK_AtomicToNonAtomic: {
880 bool isToAtomic = (E->
getCastKind() == CK_NonAtomicToAtomic);
884 QualType valueType = E->
getType();
890 valueType,
atomicType->castAs<AtomicType>()->getValueType()));
899 (isToAtomic ? CK_AtomicToNonAtomic : CK_NonAtomicToAtomic);
906 "peephole significantly changed types?");
913 AggValueSlot valueDest = Dest;
936 AggValueSlot atomicSlot =
942 return EmitFinalDestCopy(valueType, rvalue);
944 case CK_AddressSpaceConversion:
947 case CK_LValueToRValue:
968 case CK_HLSLArrayRValue:
971 case CK_HLSLAggregateSplatCast: {
973 QualType SrcTy = Src->
getType();
979 "RHS of HLSL splat cast must be a scalar.");
984 case CK_HLSLElementwiseCast: {
986 QualType SrcTy = Src->
getType();
994 "HLSL Elementwise cast doesn't handle splatting.");
998 "Can't perform HLSL Aggregate cast on a complex type.");
1006 case CK_UserDefinedConversion:
1007 case CK_ConstructorConversion:
1010 "Implicit cast types must be compatible");
1014 case CK_LValueBitCast:
1015 llvm_unreachable(
"should not be emitting lvalue bitcast as rvalue");
1019 case CK_ArrayToPointerDecay:
1020 case CK_FunctionToPointerDecay:
1021 case CK_NullToPointer:
1022 case CK_NullToMemberPointer:
1023 case CK_BaseToDerivedMemberPointer:
1024 case CK_DerivedToBaseMemberPointer:
1025 case CK_MemberPointerToBoolean:
1026 case CK_ReinterpretMemberPointer:
1027 case CK_IntegralToPointer:
1028 case CK_PointerToIntegral:
1029 case CK_PointerToBoolean:
1031 case CK_VectorSplat:
1032 case CK_IntegralCast:
1033 case CK_BooleanToSignedIntegral:
1034 case CK_IntegralToBoolean:
1035 case CK_IntegralToFloating:
1036 case CK_FloatingToIntegral:
1037 case CK_FloatingToBoolean:
1038 case CK_FloatingCast:
1039 case CK_CPointerToObjCPointerCast:
1040 case CK_BlockPointerToObjCPointerCast:
1041 case CK_AnyPointerToBlockPointerCast:
1042 case CK_ObjCObjectLValueCast:
1043 case CK_FloatingRealToComplex:
1044 case CK_FloatingComplexToReal:
1045 case CK_FloatingComplexToBoolean:
1046 case CK_FloatingComplexCast:
1047 case CK_FloatingComplexToIntegralComplex:
1048 case CK_IntegralRealToComplex:
1049 case CK_IntegralComplexToReal:
1050 case CK_IntegralComplexToBoolean:
1051 case CK_IntegralComplexCast:
1052 case CK_IntegralComplexToFloatingComplex:
1053 case CK_ARCProduceObject:
1054 case CK_ARCConsumeObject:
1055 case CK_ARCReclaimReturnedObject:
1056 case CK_ARCExtendBlockObject:
1057 case CK_CopyAndAutoreleaseBlockObject:
1058 case CK_BuiltinFnToFnPtr:
1059 case CK_ZeroToOCLOpaqueType:
1061 case CK_HLSLVectorTruncation:
1062 case CK_HLSLMatrixTruncation:
1063 case CK_IntToOCLSampler:
1064 case CK_FloatingToFixedPoint:
1065 case CK_FixedPointToFloating:
1066 case CK_FixedPointCast:
1067 case CK_FixedPointToBoolean:
1068 case CK_FixedPointToIntegral:
1069 case CK_IntegralToFixedPoint:
1070 llvm_unreachable(
"cast kind invalid for aggregate types");
1074void AggExprEmitter::VisitCallExpr(
const CallExpr *E) {
1076 EmitAggLoadOfLValue(E);
1080 withReturnValueSlot(
1081 E, [&](ReturnValueSlot Slot) {
return CGF.
EmitCallExpr(E, Slot); });
1084void AggExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
1085 withReturnValueSlot(E, [&](ReturnValueSlot Slot) {
1090void AggExprEmitter::VisitBinComma(
const BinaryOperator *E) {
1095void AggExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
1096 CodeGenFunction::StmtExprEvaluation eval(CGF);
1109 const char *NameSuffix =
"") {
1112 ArgTy = CT->getElementType();
1116 "member pointers may only be compared for equality");
1118 CGF, LHS, RHS, MPT,
false);
1122 struct CmpInstInfo {
1124 llvm::CmpInst::Predicate FCmp;
1125 llvm::CmpInst::Predicate SCmp;
1126 llvm::CmpInst::Predicate UCmp;
1128 CmpInstInfo InstInfo = [&]() -> CmpInstInfo {
1129 using FI = llvm::FCmpInst;
1130 using II = llvm::ICmpInst;
1133 return {
"cmp.lt", FI::FCMP_OLT, II::ICMP_SLT, II::ICMP_ULT};
1135 return {
"cmp.gt", FI::FCMP_OGT, II::ICMP_SGT, II::ICMP_UGT};
1137 return {
"cmp.eq", FI::FCMP_OEQ, II::ICMP_EQ, II::ICMP_EQ};
1139 llvm_unreachable(
"Unrecognised CompareKind enum");
1143 return Builder.CreateFCmp(InstInfo.FCmp, LHS, RHS,
1144 llvm::Twine(InstInfo.Name) + NameSuffix);
1148 return Builder.CreateICmp(Inst, LHS, RHS,
1149 llvm::Twine(InstInfo.Name) + NameSuffix);
1152 llvm_unreachable(
"unsupported aggregate binary expression should have "
1153 "already been handled");
1156void AggExprEmitter::VisitBinCmp(
const BinaryOperator *E) {
1157 using llvm::BasicBlock;
1158 using llvm::PHINode;
1162 const ComparisonCategoryInfo &CmpInfo =
1165 "cannot copy non-trivially copyable aggregate");
1177 auto EmitOperand = [&](Expr *E) -> std::pair<Value *, Value *> {
1186 auto LHSValues = EmitOperand(E->
getLHS()),
1187 RHSValues = EmitOperand(E->
getRHS());
1191 K, IsComplex ?
".r" :
"");
1196 RHSValues.second, K,
".i");
1197 return Builder.CreateAnd(
Cmp, CmpImag,
"and.eq");
1199 auto EmitCmpRes = [&](
const ComparisonCategoryInfo::ValueInfo *VInfo) {
1200 return Builder.getInt(VInfo->getIntValue());
1208 Builder.CreateSelect(EmitCmp(
CK_Less), EmitCmpRes(CmpInfo.
getLess()),
1210 Select = Builder.CreateSelect(EmitCmp(
CK_Equal),
1212 SelectOne,
"sel.eq");
1214 Value *SelectEq = Builder.CreateSelect(
1219 SelectEq,
"sel.gt");
1220 Select = Builder.CreateSelect(
1221 EmitCmp(
CK_Less), EmitCmpRes(CmpInfo.
getLess()), SelectGT,
"sel.lt");
1236void AggExprEmitter::VisitBinaryOperator(
const BinaryOperator *E) {
1238 VisitPointerToDataMemberBinaryOperator(E);
1243void AggExprEmitter::VisitPointerToDataMemberBinaryOperator(
1244 const BinaryOperator *E) {
1246 EmitFinalDestCopy(E->
getType(), LV);
1256 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
1257 const VarDecl *var = dyn_cast<VarDecl>(DRE->getDecl());
1258 return (var && var->hasAttr<BlocksAttr>());
1267 if (op->isAssignmentOp() || op->isPtrMemOp())
1271 if (op->getOpcode() == BO_Comma)
1279 dyn_cast<AbstractConditionalOperator>(E)) {
1284 }
else if (
const OpaqueValueExpr *op = dyn_cast<OpaqueValueExpr>(E)) {
1285 if (
const Expr *src = op->getSourceExpr())
1292 }
else if (
const CastExpr *
cast = dyn_cast<CastExpr>(E)) {
1293 if (
cast->getCastKind() == CK_LValueToRValue)
1299 }
else if (
const UnaryOperator *uop = dyn_cast<UnaryOperator>(E)) {
1303 }
else if (
const MemberExpr *mem = dyn_cast<MemberExpr>(E)) {
1314void AggExprEmitter::VisitBinAssign(
const BinaryOperator *E) {
1320 "Invalid assignment");
1336 if (LHS.getType()->isAtomicType() ||
1355 if (LHS.getType()->isAtomicType() ||
1374 EmitFinalDestCopy(E->
getType(), LHS);
1382void AggExprEmitter::VisitAbstractConditionalOperator(
1383 const AbstractConditionalOperator *E) {
1389 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
1391 CodeGenFunction::ConditionalEvaluation eval(CGF);
1397 bool destructNonTrivialCStruct =
1398 !isExternallyDestructed &&
1400 isExternallyDestructed |= destructNonTrivialCStruct;
1409 assert(CGF.
HaveInsertPoint() &&
"expression evaluation ended with no IP!");
1410 CGF.
Builder.CreateBr(ContBlock);
1424 if (destructNonTrivialCStruct)
1431void AggExprEmitter::VisitChooseExpr(
const ChooseExpr *CE) {
1435void AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
1446void AggExprEmitter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
1458 if (!wasExternallyDestructed)
1462void AggExprEmitter::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
1463 AggValueSlot Slot = EnsureSlot(E->
getType());
1467void AggExprEmitter::VisitCXXInheritedCtorInitExpr(
1468 const CXXInheritedCtorInitExpr *E) {
1469 AggValueSlot Slot = EnsureSlot(E->
getType());
1475void AggExprEmitter::VisitLambdaExpr(
LambdaExpr *E) {
1476 AggValueSlot Slot = EnsureSlot(E->
getType());
1481 CodeGenFunction::CleanupDeactivationScope scope(CGF);
1486 i != e; ++i, ++CurField) {
1489 if (CurField->hasCapturedVLAType()) {
1494 EmitInitializationToLValue(*i, LV);
1498 CurField->getType().isDestructedType()) {
1499 assert(LV.isSimple());
1502 CurField->getType(),
1508void AggExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
1509 CodeGenFunction::RunCleanupsScope cleanups(CGF);
1513void AggExprEmitter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
1515 AggValueSlot Slot = EnsureSlot(T);
1519void AggExprEmitter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
1521 AggValueSlot Slot = EnsureSlot(T);
1532 case CK_UserDefinedConversion:
1533 case CK_ConstructorConversion:
1539 case CK_BooleanToSignedIntegral:
1540 case CK_FloatingCast:
1541 case CK_FloatingComplexCast:
1542 case CK_FloatingComplexToBoolean:
1543 case CK_FloatingComplexToIntegralComplex:
1544 case CK_FloatingComplexToReal:
1545 case CK_FloatingRealToComplex:
1546 case CK_FloatingToBoolean:
1547 case CK_FloatingToIntegral:
1548 case CK_IntegralCast:
1549 case CK_IntegralComplexCast:
1550 case CK_IntegralComplexToBoolean:
1551 case CK_IntegralComplexToFloatingComplex:
1552 case CK_IntegralComplexToReal:
1553 case CK_IntegralRealToComplex:
1554 case CK_IntegralToBoolean:
1555 case CK_IntegralToFloating:
1557 case CK_IntegralToPointer:
1558 case CK_PointerToIntegral:
1560 case CK_VectorSplat:
1562 case CK_NonAtomicToAtomic:
1563 case CK_AtomicToNonAtomic:
1564 case CK_HLSLVectorTruncation:
1565 case CK_HLSLMatrixTruncation:
1566 case CK_HLSLElementwiseCast:
1567 case CK_HLSLAggregateSplatCast:
1570 case CK_BaseToDerivedMemberPointer:
1571 case CK_DerivedToBaseMemberPointer:
1572 case CK_MemberPointerToBoolean:
1573 case CK_NullToMemberPointer:
1574 case CK_ReinterpretMemberPointer:
1578 case CK_AnyPointerToBlockPointerCast:
1579 case CK_BlockPointerToObjCPointerCast:
1580 case CK_CPointerToObjCPointerCast:
1581 case CK_ObjCObjectLValueCast:
1582 case CK_IntToOCLSampler:
1583 case CK_ZeroToOCLOpaqueType:
1587 case CK_FixedPointCast:
1588 case CK_FixedPointToBoolean:
1589 case CK_FixedPointToFloating:
1590 case CK_FixedPointToIntegral:
1591 case CK_FloatingToFixedPoint:
1592 case CK_IntegralToFixedPoint:
1596 case CK_AddressSpaceConversion:
1597 case CK_BaseToDerived:
1598 case CK_DerivedToBase:
1600 case CK_NullToPointer:
1601 case CK_PointerToBoolean:
1606 case CK_ARCConsumeObject:
1607 case CK_ARCExtendBlockObject:
1608 case CK_ARCProduceObject:
1609 case CK_ARCReclaimReturnedObject:
1610 case CK_CopyAndAutoreleaseBlockObject:
1611 case CK_ArrayToPointerDecay:
1612 case CK_FunctionToPointerDecay:
1613 case CK_BuiltinFnToFnPtr:
1615 case CK_LValueBitCast:
1616 case CK_LValueToRValue:
1617 case CK_LValueToRValueBitCast:
1618 case CK_UncheckedDerivedToBase:
1619 case CK_HLSLArrayRValue:
1622 llvm_unreachable(
"Unhandled clang::CastKind enum");
1630 while (
auto *CE = dyn_cast<CastExpr>(E)) {
1638 return IL->getValue() == 0;
1641 return FL->getValue().isPosZero();
1647 if (
const CastExpr *ICE = dyn_cast<CastExpr>(E))
1648 return ICE->getCastKind() == CK_NullToPointer &&
1653 return CL->getValue() == 0;
1659void AggExprEmitter::EmitInitializationToLValue(Expr *E, LValue LV) {
1660 QualType
type = LV.getType();
1667 return EmitNullInitializationToLValue(LV);
1671 }
else if (
type->isReferenceType()) {
1679void AggExprEmitter::EmitNullInitializationToLValue(LValue lv) {
1680 QualType
type = lv.getType();
1692 if (lv.isBitField()) {
1695 assert(lv.isSimple());
1706void AggExprEmitter::VisitCXXParenListInitExpr(CXXParenListInitExpr *E) {
1712void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
1719 VisitCXXParenListOrInitListExpr(
1723void AggExprEmitter::VisitCXXParenListOrInitListExpr(
1724 Expr *ExprToVisit, ArrayRef<Expr *> InitExprs,
1725 FieldDecl *InitializedFieldInUnion, Expr *ArrayFiller) {
1732 if (llvm::Constant *
C =
1733 CGF.
CGM.EmitConstantExpr(ExprToVisit, ExprToVisit->
getType(), &CGF)) {
1734 llvm::GlobalVariable* GV =
1735 new llvm::GlobalVariable(CGF.
CGM.
getModule(),
C->getType(),
true,
1736 llvm::GlobalValue::InternalLinkage,
C,
"");
1737 EmitFinalDestCopy(ExprToVisit->
getType(),
1755 AggValueSlot Dest = EnsureSlot(ExprToVisit->
getType());
1763 InitExprs, ArrayFiller);
1769 assert(InitExprs.size() == 0 &&
1770 "you can only use an empty initializer with VLAs");
1776 "Only support structs/unions here!");
1782 unsigned NumInitElements = InitExprs.size();
1787 CodeGenFunction::CleanupDeactivationScope DeactivateCleanups(CGF);
1789 unsigned curInitIndex = 0;
1792 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(record)) {
1793 assert(NumInitElements >= CXXRD->getNumBases() &&
1794 "missing initializer for base class");
1795 for (
auto &Base : CXXRD->bases()) {
1796 assert(!
Base.isVirtual() &&
"should not see vbases here");
1797 auto *BaseRD =
Base.getType()->getAsCXXRecordDecl();
1805 CGF.
EmitAggExpr(InitExprs[curInitIndex++], AggSlot);
1808 Base.getType().isDestructedType())
1814 CodeGenFunction::FieldConstructionScope FCS(CGF, Dest.
getAddress());
1816 const bool ZeroInitPadding =
1822 if (!InitializedFieldInUnion) {
1828 for (
const auto *Field : record->
fields())
1830 (
Field->isUnnamedBitField() ||
Field->isAnonymousStructOrUnion()) &&
1831 "Only unnamed bitfields or anonymous class allowed");
1837 FieldDecl *
Field = InitializedFieldInUnion;
1840 if (NumInitElements) {
1842 EmitInitializationToLValue(InitExprs[0], FieldLoc);
1843 if (ZeroInitPadding) {
1847 DoZeroInitPadding(FieldSize, TotalSize,
nullptr);
1851 if (ZeroInitPadding)
1852 EmitNullInitializationToLValue(DestLV);
1854 EmitNullInitializationToLValue(FieldLoc);
1864 for (
const auto *field : record->
fields()) {
1866 if (field->getType()->isIncompleteArrayType())
1870 if (field->isUnnamedBitField())
1876 if (curInitIndex == NumInitElements && Dest.
isZeroed() &&
1880 if (ZeroInitPadding)
1881 DoZeroInitPadding(PaddingStart,
1888 if (curInitIndex < NumInitElements) {
1890 EmitInitializationToLValue(InitExprs[curInitIndex++], LV);
1893 EmitNullInitializationToLValue(LV);
1900 field->getType().isDestructedType()) {
1901 assert(LV.isSimple());
1909 if (ZeroInitPadding) {
1912 DoZeroInitPadding(PaddingStart, TotalSize,
nullptr);
1916void AggExprEmitter::DoZeroInitPadding(uint64_t &PaddingStart,
1917 uint64_t PaddingEnd,
1918 const FieldDecl *NextField) {
1926 llvm::Constant *SizeVal = Builder.getInt64((End - Start).getQuantity());
1930 if (NextField !=
nullptr && NextField->
isBitField()) {
1933 const CGRecordLayout &RL =
1937 if (StorageStart + Info.
StorageSize > PaddingStart) {
1938 if (StorageStart > PaddingStart)
1939 InitBytes(PaddingStart, StorageStart);
1952 if (PaddingStart < PaddingEnd)
1953 InitBytes(PaddingStart, PaddingEnd);
1954 if (NextField !=
nullptr)
1959void AggExprEmitter::VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E,
1960 llvm::Value *outerBegin) {
1962 CodeGenFunction::OpaqueValueMapping binding(CGF, E->
getCommonExpr());
1971 llvm::Value *zero = llvm::ConstantInt::get(CGF.
SizeTy, 0);
1972 llvm::Value *indices[] = {zero, zero};
1973 llvm::Value *begin = Builder.CreateInBoundsGEP(destPtr.
getElementType(),
1975 indices,
"arrayinit.begin");
1981 ArrayInitLoopExpr *InnerLoop = dyn_cast<ArrayInitLoopExpr>(E->
getSubExpr());
1983 QualType elementType =
1986 CharUnits elementAlign =
1990 llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
1995 llvm::PHINode *index =
1996 Builder.CreatePHI(zero->getType(), 2,
"arrayinit.index");
1997 index->addIncoming(zero, entryBB);
1998 llvm::Value *element =
1999 Builder.CreateInBoundsGEP(llvmElementType, begin, index);
2003 EHScopeStack::stable_iterator
cleanup;
2005 if (outerBegin->getType() != element->getType())
2006 outerBegin = Builder.CreateBitCast(outerBegin, element->getType());
2019 CodeGenFunction::RunCleanupsScope CleanupsScope(CGF);
2020 CodeGenFunction::ArrayInitLoopExprScope Scope(CGF, index);
2022 Address(element, llvmElementType, elementAlign), elementType);
2030 AggExprEmitter(CGF, elementSlot,
false)
2031 .VisitArrayInitLoopExpr(InnerLoop, outerBegin);
2033 EmitInitializationToLValue(E->
getSubExpr(), elementLV);
2037 llvm::Value *nextIndex = Builder.CreateNUWAdd(
2038 index, llvm::ConstantInt::get(CGF.
SizeTy, 1),
"arrayinit.next");
2039 index->addIncoming(nextIndex, Builder.GetInsertBlock());
2042 llvm::Value *done = Builder.CreateICmpEQ(
2043 nextIndex, llvm::ConstantInt::get(CGF.
SizeTy, numElements),
2046 Builder.CreateCondBr(done, endBB, bodyBB);
2055void AggExprEmitter::VisitDesignatedInitUpdateExpr(
2056 DesignatedInitUpdateExpr *E) {
2057 AggValueSlot Dest = EnsureSlot(E->
getType());
2060 EmitInitializationToLValue(E->
getBase(), DestLV);
2072 if (
auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
2073 E = MTE->getSubExpr();
2084 ILE = dyn_cast<InitListExpr>(ILE->
getInit(0));
2092 if (!RT->isUnionType()) {
2096 unsigned ILEElement = 0;
2097 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(SD))
2098 while (ILEElement != CXXRD->getNumBases())
2101 for (
const auto *Field : SD->
fields()) {
2104 if (Field->getType()->isIncompleteArrayType() ||
2107 if (Field->isUnnamedBitField())
2113 if (Field->getType()->isReferenceType())
2120 return NumNonZeroBytes;
2126 for (
unsigned i = 0, e = ILE->
getNumInits(); i != e; ++i)
2128 return NumNonZeroBytes;
2159 if (NumNonZeroBytes * 4 > Size)
2163 llvm::Constant *SizeVal = CGF.
Builder.getInt64(Size.getQuantity());
2178 "Invalid aggregate expression to emit");
2180 "slot has bits but no address");
2185 AggExprEmitter(*
this, Slot, Slot.
isIgnored()).Visit(
const_cast<Expr *
>(E));
2202 return AggExprEmitter(*
this, Dest, Dest.
isIgnored())
2203 .EmitFinalDestCopy(
Type, Src, SrcKind);
2246 getContext().getASTRecordLayout(BaseRD).getSize() <=
2264 assert((
Record->hasTrivialCopyConstructor() ||
2265 Record->hasTrivialCopyAssignment() ||
2266 Record->hasTrivialMoveConstructor() ||
2267 Record->hasTrivialMoveAssignment() ||
2268 Record->hasAttr<TrivialABIAttr>() ||
Record->isUnion()) &&
2269 "Trying to aggregate-copy a type without a trivial copy/move "
2270 "constructor or assignment operator");
2279 if (
getTargetHooks().emitCUDADeviceBuiltinSurfaceDeviceCopy(*
this, Dest,
2283 if (
getTargetHooks().emitCUDADeviceBuiltinTextureDeviceCopy(*
this, Dest,
2290 if (
CGM.getHLSLRuntime().emitBufferCopy(*
this, DestPtr, SrcPtr, Ty))
2313 llvm::Value *SizeVal =
nullptr;
2316 if (
auto *VAT = dyn_cast_or_null<VariableArrayType>(
2322 SizeVal =
Builder.CreateNUWMul(
2351 if (
Record->hasObjectMember()) {
2352 CGM.getObjCRuntime().EmitGCMemmoveCollectable(*
this, DestPtr, SrcPtr,
2358 if (
const auto *
Record = BaseType->getAsRecordDecl()) {
2359 if (
Record->hasObjectMember()) {
2360 CGM.getObjCRuntime().EmitGCMemmoveCollectable(*
this, DestPtr, SrcPtr,
2367 auto *Inst =
Builder.CreateMemCpy(DestPtr, SrcPtr, SizeVal, isVolatile);
2374 if (llvm::MDNode *TBAAStructTag =
CGM.getTBAAStructInfo(Ty))
2375 Inst->setMetadata(llvm::LLVMContext::MD_tbaa_struct, TBAAStructTag);
2377 if (
CGM.getCodeGenOpts().NewStructPathTBAA) {
2380 CGM.DecorateInstructionWithTBAA(Inst, TBAAInfo);
Defines the clang::ASTContext interface.
static CharUnits GetNumNonZeroBytesInInit(const Expr *E, CodeGenFunction &CGF)
GetNumNonZeroBytesInInit - Get an approximate count of the number of non-zero bytes that will be stor...
static Expr * findPeephole(Expr *op, CastKind kind, const ASTContext &ctx)
Attempt to look through various unimportant expressions to find a cast of the given kind.
static bool isBlockVarRef(const Expr *E)
Is the value of the given expression possibly a reference to or into a __block variable?
static bool isSimpleZero(const Expr *E, CodeGenFunction &CGF)
isSimpleZero - If emitting this value will obviously just cause a store of zero to memory,...
static llvm::Value * EmitCompare(CGBuilderTy &Builder, CodeGenFunction &CGF, const BinaryOperator *E, llvm::Value *LHS, llvm::Value *RHS, CompareKind Kind, const char *NameSuffix="")
static void EmitHLSLElementwiseCast(CodeGenFunction &CGF, LValue DestVal, LValue SrcVal, SourceLocation Loc)
static bool castPreservesZero(const CastExpr *CE)
Determine whether the given cast kind is known to always convert values with all zero bits in their v...
static void CheckAggExprForMemSetUse(AggValueSlot &Slot, const Expr *E, CodeGenFunction &CGF)
CheckAggExprForMemSetUse - If the initializer is large and has a lot of zeros in it,...
static void EmitHLSLScalarElementwiseAndSplatCasts(CodeGenFunction &CGF, LValue DestVal, llvm::Value *SrcVal, QualType SrcTy, SourceLocation Loc)
static bool isTrivialFiller(Expr *e)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
llvm::MachO::Record Record
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
static bool isVector(QualType QT, QualType ElementType)
This helper function returns true if QT is a vector type that has element type ElementType.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
ComparisonCategories CompCategories
Types and expressions required to build C++2a three-way comparisons using operator<=>,...
QualType removeAddrSpaceQualType(QualType T) const
Remove any existing address space on the type and returns the type with qualifiers intact (or that's ...
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
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>.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
unsigned getTargetAddressSpace(LangAS AS) const
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
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 * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
llvm::APInt getArraySize() const
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Expr * getSubExpr() const
Get the initializer to use for each array element.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
QualType getElementType() const
A builtin binary operation expression such as "x + y" or "x <= y".
CXXTemporary * getTemporary()
const Expr * getSubExpr() const
Expr * getExpr()
Get the initialization expression that will be used.
bool constructsVBase() const
Determine whether this constructor is actually constructing a base class (rather than a complete obje...
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
bool inheritedFromVBase() const
Determine whether the inherited constructor is inherited from a virtual base of the object we constru...
MutableArrayRef< Expr * > getInitExprs()
FieldDecl * getInitializedFieldInUnion()
Represents a C++ struct/union/class.
bool hasTrivialMoveAssignment() const
Determine whether this class has a trivial move assignment operator (C++11 [class....
bool isTriviallyCopyable() const
Determine whether this class is considered trivially copyable per (C++11 [class]p6).
bool hasTrivialMoveConstructor() const
Determine whether this class has a trivial move constructor (C++11 [class.copy]p12)
bool hasTrivialCopyConstructor() const
Determine whether this class has a trivial copy constructor (C++ [class.copy]p6, C++11 [class....
bool hasTrivialCopyAssignment() const
Determine whether this class has a trivial copy assignment operator (C++ [class.copy]p11,...
bool hasUserDeclaredConstructor() const
Determine whether this class has any user-declared constructors.
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
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
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * getBasePointer() const
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CharUnits getAlignment() const
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
void setVolatile(bool flag)
static AggValueSlot ignored()
ignored - Returns an aggregate value slot indicating that the aggregate value is being ignored.
Address getAddress() const
CharUnits getPreferredSize(ASTContext &Ctx, QualType Type) const
Get the preferred size to use when storing a value to this slot.
NeedsGCBarriers_t requiresGCollection() const
void setExternallyDestructed(bool destructed=true)
void setZeroed(bool V=true)
IsZeroed_t isZeroed() const
Qualifiers getQualifiers() const
static AggValueSlot forLValue(const LValue &LV, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
IsAliased_t isPotentiallyAliased() const
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
forAddr - Make a slot for an aggregate value.
IsDestructed_t isExternallyDestructed() const
Overlap_t mayOverlap() const
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
llvm::CallInst * CreateMemSet(Address Dest, llvm::Value *Value, llvm::Value *Size, bool IsVolatile=false)
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
virtual llvm::Value * EmitMemberPointerComparison(CodeGenFunction &CGF, llvm::Value *L, llvm::Value *R, const MemberPointerType *MPT, bool Inequality)
Emit a comparison between two member pointers. Returns an i1.
void emitInitListOpaqueValues(CodeGenFunction &CGF, InitListExpr *E)
virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr, llvm::Value *Size)=0
const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const
Return the BitFieldInfo that corresponds to the field FD.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr, const VarDecl *ConditionalDecl=nullptr)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())
void EmitCXXConstructExpr(const CXXConstructExpr *E, AggValueSlot Dest)
AggValueSlot::Overlap_t getOverlapForFieldInit(const FieldDecl *FD)
Determine whether a field initialization may overlap some other object.
llvm::Value * performAddrSpaceCast(llvm::Value *Src, llvm::Type *DestTy)
@ UseSkipPath
Skip (false)
void callCStructMoveConstructor(LValue Dst, LValue Src)
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
static bool hasScalarEvaluationKind(QualType T)
llvm::Type * ConvertType(QualType T)
void EmitAggFinalDestCopy(QualType Type, AggValueSlot Dest, const LValue &Src, ExprValueKind SrcKind)
EmitAggFinalDestCopy - Emit copy of the specified aggregate into destination address.
void pushRegularPartialArrayCleanup(llvm::Value *arrayBegin, llvm::Value *arrayEnd, QualType elementType, CharUnits elementAlignment, Destroyer *destroyer)
pushRegularPartialArrayCleanup - Push an EH cleanup to destroy already-constructed elements of the gi...
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, llvm::Value **Result=nullptr)
EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints as EmitStoreThroughLValue.
bool hasVolatileMember(QualType T)
hasVolatileMember - returns true if aggregate type has a volatile member.
llvm::SmallVector< DeferredDeactivateCleanup > DeferredDeactivationCleanupStack
RValue EmitVAArg(VAArgExpr *VE, Address &VAListAddr, AggValueSlot Slot=AggValueSlot::ignored())
Generate code to get an argument from the passed in pointer and update it accordingly.
RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e, AggValueSlot slot=AggValueSlot::ignored())
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)
See CGDebugInfo::addInstToCurrentSourceAtom.
AggValueSlot::Overlap_t getOverlapForBaseInit(const CXXRecordDecl *RD, const CXXRecordDecl *BaseRD, bool IsVirtual)
Determine whether a base class initialization may overlap some other object.
const LangOptions & getLangOpts() const
RValue EmitReferenceBindingToExpr(const Expr *E)
Emits a reference binding to the passed in expression.
LValue EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E)
void pushDestroy(QualType::DestructionKind dtorKind, Address addr, QualType type)
pushDestroy - Push the standard destructor for the given type as at least a normal cleanup.
@ TCK_Store
Checking the destination of a store. Must be suitably sized and aligned.
@ TCK_Load
Checking the operand of a load. Must be suitably sized and aligned.
void pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin, Address arrayEndPointer, QualType elementType, CharUnits elementAlignment, Destroyer *destroyer)
pushIrregularPartialArrayCleanup - Push a NormalAndEHCleanup to destroy already-constructed elements ...
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
LValue EmitPseudoObjectLValue(const PseudoObjectExpr *e)
void CreateCoercedStore(llvm::Value *Src, QualType SrcFETy, Address Dst, llvm::TypeSize DstSize, bool DstIsVolatile)
Create a store to.
void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)
EmitAggregateCopy - Emit an aggregate copy.
const TargetInfo & getTarget() const
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
RValue EmitCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue=ReturnValueSlot(), llvm::CallBase **CallOrInvoke=nullptr)
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
void pushDestroyAndDeferDeactivation(QualType::DestructionKind dtorKind, Address addr, QualType type)
void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *DominatingIP)
DeactivateCleanupBlock - Deactivates the given cleanup block.
void callCStructCopyAssignmentOperator(LValue Dst, LValue Src)
void pushFullExprCleanup(CleanupKind kind, As... A)
pushFullExprCleanup - Push a cleanup to be run at the end of the current full-expression.
LValue EmitAggExprToLValue(const Expr *E)
EmitAggExprToLValue - Emit the computation of the specified expression of aggregate type into a tempo...
RValue EmitCoyieldExpr(const CoyieldExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
AggValueSlot CreateAggTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateAggTemp - Create a temporary memory object for the given aggregate type.
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...
void callCStructCopyConstructor(LValue Dst, LValue Src)
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
RValue EmitAtomicLoad(LValue LV, SourceLocation SL, AggValueSlot Slot=AggValueSlot::ignored())
CGDebugInfo * getDebugInfo()
llvm::Value * getTypeSize(QualType Ty)
Returns calculated size of the specified type.
bool EmitLifetimeStart(llvm::Value *Addr)
Emit a lifetime.begin marker if some criteria are satisfied.
LValue EmitLValueForFieldInitialization(LValue Base, const FieldDecl *Field)
EmitLValueForFieldInitialization - Like EmitLValueForField, except that if the Field is a reference,...
Address GetAddressOfDirectBaseInCompleteClass(Address Value, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, bool BaseIsVirtual)
GetAddressOfBaseOfCompleteClass - Convert the given pointer to a complete class to the given direct b...
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its LValue mapping if it exists, otherwise create one.
const TargetCodeGenInfo & getTargetHooks() const
void EmitLifetimeEnd(llvm::Value *Addr)
RawAddress CreateMemTempWithoutCast(QualType T, const Twine &Name="tmp")
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen without...
void callCStructMoveAssignmentOperator(LValue Dst, LValue Src)
ASTContext & getContext() const
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
void pushLifetimeExtendedDestroy(CleanupKind kind, Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)
Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
EmitCompoundStmt - Emit a compound statement {..} node.
RValue EmitAnyExpr(const Expr *E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
EmitAnyExpr - Emit code to compute the specified expression which can have any type.
bool needsEHCleanup(QualType::DestructionKind kind)
Determines whether an EH cleanup is required to destroy a type with the given destruction kind.
CleanupKind getCleanupKind(QualType::DestructionKind kind)
llvm::Type * ConvertTypeForMem(QualType T)
RValue EmitAtomicExpr(AtomicExpr *E)
void emitPFPPostCopyUpdates(Address DestPtr, Address SrcPtr, QualType Ty)
Copy all PFP fields from SrcPtr to DestPtr while updating signatures, assuming that DestPtr was alrea...
CodeGenTypes & getTypes() const
void FlattenAccessAndTypeLValue(LValue LVal, SmallVectorImpl< LValue > &AccessList)
RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
void EmitCXXTemporary(const CXXTemporary *Temporary, QualType TempType, Address Ptr)
Emits all the code to cause the given temporary to be cleaned up.
bool LValueIsSuitableForInlineAtomic(LValue Src)
An LValue is a candidate for having its loads and stores be made atomic if we are operating under /vo...
LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK)
Same as EmitLValue but additionally we generate checking code to guard against undefined behavior.
void EmitInheritedCXXConstructorCall(const CXXConstructorDecl *D, bool ForVirtualBase, Address This, bool InheritedFromVBase, const CXXInheritedCtorInitExpr *E)
Emit a call to a constructor inherited from a base class, passing the current constructor's arguments...
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
void EmitInitializationToLValue(const Expr *E, LValue LV, AggValueSlot::IsZeroed_t IsZeroed=AggValueSlot::IsNotZeroed)
EmitInitializationToLValue - Emit an initializer to an LValue.
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
static bool hasAggregateEvaluationKind(QualType T)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitLambdaVLACapture(const VariableArrayType *VAT, LValue LV)
void EmitAtomicStore(RValue rvalue, LValue lvalue, bool isInit)
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
void ErrorUnsupported(const Stmt *S, const char *Type)
ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet.
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
llvm::LLVMContext & getLLVMContext()
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
llvm::Value * EmitScalarConversion(llvm::Value *Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified type to the specified destination type, both of which are LLVM s...
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
llvm::Value * EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
void EmitExplicitCastExprType(const ExplicitCastExpr *E, CodeGenFunction *CGF=nullptr)
Emit type info if type of an expression is a variably modified type.
CGHLSLRuntime & getHLSLRuntime()
Return a reference to the configured HLSL runtime.
llvm::Module & getModule() const
bool isPaddedAtomicType(QualType type)
void ErrorUnsupported(const Stmt *S, const char *Type)
Print out an error that codegen doesn't support the specified stmt yet.
CGCXXABI & getCXXABI() const
ASTContext & getContext() const
const TargetCodeGenInfo & getTargetCodeGenInfo()
bool shouldZeroInitPadding() const
CGObjCRuntime & getObjCRuntime()
Return a reference to the configured Objective-C runtime.
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
LangAS GetGlobalConstantAddressSpace() const
Return the AST address space of constant literal, which is used to emit the constant literal as globa...
bool isPointerZeroInitializable(QualType T)
Check if the pointer type can be zero-initialized (in the C++ sense) with an LLVM zeroinitializer.
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
bool isZeroInitializable(QualType T)
IsZeroInitializable - Return whether a type can be zero-initialized (in the C++ sense) with an LLVM z...
stable_iterator stable_begin() const
Create a stable reference to the top of the EH stack.
iterator find(stable_iterator save) const
Turn a stable reference to a scope depth into a unstable pointer to the EH stack.
LValue - This represents an lvalue references.
Address getAddress() const
TBAAAccessInfo getTBAAInfo() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
llvm::Value * getAggregatePointer(QualType PointeeType, CodeGenFunction &CGF) const
static RValue get(llvm::Value *V)
static RValue getAggregate(Address addr, bool isVolatile=false)
Convert an Address to an RValue.
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
virtual LangAS getSRetAddrSpace(const CXXRecordDecl *RD) const
Get the address space for an indirect (sret) return of the given type.
const ComparisonCategoryInfo & getInfoForType(QualType Ty) const
Return the comparison category information as specified by getCategoryForType(Ty).
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.
const ValueInfo * getGreater() const
const ValueInfo * getEqualOrEquiv() const
Complex values, per C99 6.2.5p11.
const Expr * getInitializer() const
llvm::APInt getSize() const
Return the constant array size as an APInt.
A reference to a declared variable, function, enum, etc.
InitListExpr * getUpdater() const
This represents one expression.
Expr * IgnoreParenNoopCasts(const ASTContext &Ctx) LLVM_READONLY
Skip past any parentheses and casts which do not change the value (including ptr->int casts of the sa...
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.
bool isBitField() const
Determines whether this field is a bitfield.
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
Describes an C or C++ initializer list.
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.
unsigned getNumInits() const
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() const
capture_init_iterator capture_init_end()
Retrieve the iterator pointing one past the last initialization argument for this lambda expression.
Expr *const * const_capture_init_iterator
Const iterator that walks over the capture initialization arguments.
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
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.
A pointer to member type per C++ 8.3.3 - Pointers to members.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Expr * getSelectedExpr() const
const Expr * getSubExpr() const
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
LangAS getAddressSpace() const
Return the address space of this type.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
@ PCK_Struct
The type is a struct containing a field whose type is neither PCK_Trivial nor PCK_VolatileTrivial.
Represents a struct/union/class.
bool hasObjectMember() const
field_range fields() const
specific_decl_iterator< FieldDecl > field_iterator
RecordDecl * getDefinitionOrSelf() const
field_iterator field_begin() const
Encodes a location in the source.
CompoundStmt * getSubStmt()
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Expr * getReplacement() const
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isConstantArrayType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isPointerType() const
bool isReferenceType() const
bool isScalarType() const
bool isVariableArrayType() const
bool isCUDADeviceBuiltinSurfaceType() const
Check if the type is the CUDA device builtin surface type.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
RecordDecl * castAsRecordDecl() const
bool isAnyComplexType() const
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
bool isMemberPointerType() const
bool isCUDADeviceBuiltinTextureType() const
Check if the type is the CUDA device builtin texture type.
bool hasFloatingRepresentation() const
Determine whether this type has a floating-point representation of some sort, e.g....
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
Represents a variable declaration or definition.
Represents a GCC generic vector type.
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< AtomicType > atomicType
@ Address
A pointer to a ValueDecl.
bool GE(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ Result
The result type of a method or function.
LangAS
Defines the address space values used by the address space qualifier of QualType.
CastKind
CastKind - The kind of operation required for a conversion.
U cast(CodeGen::Address addr)
CharUnits StorageOffset
The offset of the bitfield storage from the start of the struct.
unsigned StorageSize
The storage size in bits which should be used when accessing this bitfield.
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * CharTy
char
llvm::IntegerType * SizeTy
llvm::PointerType * Int8PtrTy
llvm::IntegerType * PtrDiffTy
CharUnits getPointerAlign() const