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"
35using namespace CodeGen;
46class AggExprEmitter :
public StmtVisitor<AggExprEmitter> {
67 void withReturnValueSlot(
const Expr *
E,
70 void DoZeroInitPadding(uint64_t &PaddingStart, uint64_t PaddingEnd,
75 : CGF(cgf), Builder(CGF.Builder), Dest(Dest),
76 IsResultUnused(IsResultUnused) { }
85 void EmitAggLoadOfLValue(
const Expr *
E);
96 void EmitArrayInit(
Address DestPtr, llvm::ArrayType *AType,
QualType ArrayQTy,
101 if (CGF.
getLangOpts().getGC() && TypeRequiresGCollection(
T))
106 bool TypeRequiresGCollection(
QualType T);
117 void VisitStmt(
Stmt *S) {
133 return Visit(
E->getReplacement());
142 llvm::TypeSize::getFixed(
148 return Visit(
E->getSubExpr());
152 void VisitDeclRefExpr(
DeclRefExpr *
E) { EmitAggLoadOfLValue(
E); }
153 void VisitMemberExpr(
MemberExpr *ME) { EmitAggLoadOfLValue(ME); }
158 EmitAggLoadOfLValue(
E);
161 EmitAggLoadOfLValue(
E);
169 void VisitPointerToDataMemberBinaryOperator(
const BinaryOperator *BO);
174 Visit(
E->getSemanticForm());
179 EmitAggLoadOfLValue(
E);
190 llvm::Value *outerBegin =
nullptr);
215 return EmitFinalDestCopy(
E->
getType(), LV);
219 bool NeedsDestruction =
222 if (NeedsDestruction)
225 if (NeedsDestruction)
241 EmitFinalDestCopy(
E->
getType(), Res);
244 Visit(
E->getSelectedExpr());
256void AggExprEmitter::EmitAggLoadOfLValue(
const Expr *
E) {
265 EmitFinalDestCopy(
E->
getType(), LV);
269bool AggExprEmitter::TypeRequiresGCollection(
QualType T) {
276 if (isa<CXXRecordDecl>(
Record) &&
277 (cast<CXXRecordDecl>(
Record)->hasNonTrivialCopyConstructor() ||
278 !cast<CXXRecordDecl>(
Record)->hasTrivialDestructor()))
285void AggExprEmitter::withReturnValueSlot(
288 bool RequiresDestruction =
298 (RequiresDestruction && Dest.
isIgnored());
303 llvm::IntrinsicInst *LifetimeStartInst =
nullptr;
310 cast<llvm::IntrinsicInst>(std::prev(Builder.GetInsertPoint()));
311 assert(LifetimeStartInst->getIntrinsicID() ==
312 llvm::Intrinsic::lifetime_start &&
313 "Last insertion wasn't a lifetime.start?");
330 EmitFinalDestCopy(
E->
getType(), Src);
332 if (!RequiresDestruction && LifetimeStartInst) {
343 assert(src.
isAggregate() &&
"value must be aggregate value!");
349void AggExprEmitter::EmitFinalDestCopy(
384 EmitCopy(
type, Dest, srcAgg);
420 assert(Array.isSimple() &&
"initializer_list array not a simple lvalue");
421 Address ArrayPtr = Array.getAddress();
425 assert(
ArrayType &&
"std::initializer_list constructed from non-array");
429 assert(Field !=
Record->field_end() &&
432 "Expected std::initializer_list first field to be const E *");
441 assert(Field !=
Record->field_end() &&
442 "Expected std::initializer_list to have two fields");
452 assert(
Field->getType()->isPointerType() &&
455 "Expected std::initializer_list second field to be const E *");
456 llvm::Value *
Zero = llvm::ConstantInt::get(CGF.
PtrDiffTy, 0);
457 llvm::Value *IdxEnd[] = {
Zero,
Size };
458 llvm::Value *ArrayEnd = Builder.CreateInBoundsGEP(
464 assert(++Field ==
Record->field_end() &&
465 "Expected std::initializer_list to only have two fields");
474 if (isa<ImplicitValueInitExpr>(
E))
477 if (
auto *ILE = dyn_cast<InitListExpr>(
E)) {
478 if (ILE->getNumInits())
483 if (
auto *Cons = dyn_cast_or_null<CXXConstructExpr>(
E))
484 return Cons->getConstructor()->isDefaultConstructor() &&
485 Cons->getConstructor()->isTrivial();
492 QualType DestTy, llvm::Value *SrcVal,
500 assert(SrcTy->
isScalarType() &&
"Invalid HLSL Aggregate splat cast.");
501 for (
unsigned I = 0, Size = StoreGEPList.size(); I < Size; ++I) {
506 llvm::Value *Idx = StoreGEPList[I].second;
510 Cast = CGF.
Builder.CreateInsertElement(
V, Cast, Idx);
518 QualType DestTy, llvm::Value *SrcVal,
526 assert(SrcTy->
isVectorType() &&
"HLSL Flat cast doesn't handle splatting.");
530 "Cannot perform HLSL flat cast when vector source \
531 object has less elements than flattened destination \
533 for (
unsigned I = 0, Size = StoreGEPList.size(); I < Size; I++) {
534 llvm::Value *Load = CGF.
Builder.CreateExtractElement(SrcVal, I,
"vec.load");
539 llvm::Value *Idx = StoreGEPList[I].second;
543 Cast = CGF.
Builder.CreateInsertElement(
V, Cast, Idx);
564 assert(StoreGEPList.size() <= LoadGEPList.size() &&
565 "Cannot perform HLSL flat cast when flattened source object \
566 has less elements than flattened destination object.");
569 for (
unsigned I = 0,
E = StoreGEPList.size(); I <
E; I++) {
570 llvm::Value *Idx = LoadGEPList[I].second;
573 Idx ? CGF.
Builder.CreateExtractElement(Load, Idx,
"vec.extract") : Load;
578 Idx = StoreGEPList[I].second;
582 Cast = CGF.
Builder.CreateInsertElement(
V, Cast, Idx);
590void AggExprEmitter::EmitArrayInit(
Address DestPtr, llvm::ArrayType *AType,
593 uint64_t NumInitElements = Args.size();
595 uint64_t NumArrayElements = AType->getNumElements();
596 for (
const auto *
Init : Args) {
597 if (
const auto *Embed = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
598 NumInitElements += Embed->getDataElementCount() - 1;
599 if (NumInitElements > NumArrayElements) {
600 NumInitElements = NumArrayElements;
606 assert(NumInitElements <= NumArrayElements);
618 if (NumInitElements * elementSize.
getQuantity() > 16 &&
626 if (llvm::Constant *
C =
627 Emitter.tryEmitForInitializer(ExprToVisit, AS, GVArrayQTy)) {
628 auto GV =
new llvm::GlobalVariable(
630 true, llvm::GlobalValue::PrivateLinkage,
C,
632 nullptr, llvm::GlobalVariable::NotThreadLocal,
637 Address GVAddr(GV, GV->getValueType(), Align);
638 EmitFinalDestCopy(ArrayQTy, CGF.
MakeAddrLValue(GVAddr, GVArrayQTy));
657 llvm::Instruction *dominatingIP =
658 Builder.CreateFlagLoad(llvm::ConstantInt::getNullValue(CGF.
Int8PtrTy));
660 "arrayinit.endOfInit");
661 Builder.CreateStore(begin, endOfInit);
666 .AddAuxAllocas(allocaTracker.Take());
672 llvm::Value *one = llvm::ConstantInt::get(CGF.
SizeTy, 1);
675 llvm::Value *element = begin;
676 if (ArrayIndex > 0) {
677 element = Builder.CreateInBoundsGEP(
678 llvmElementType, begin,
679 llvm::ConstantInt::get(CGF.
SizeTy, ArrayIndex),
"arrayinit.element");
685 Builder.CreateStore(element, endOfInit);
689 Address(element, llvmElementType, elementAlign), elementType);
690 EmitInitializationToLValue(
Init, elementLV);
694 unsigned ArrayIndex = 0;
696 for (uint64_t i = 0; i != NumInitElements; ++i) {
697 if (ArrayIndex >= NumInitElements)
699 if (
auto *EmbedS = dyn_cast<EmbedExpr>(Args[i]->IgnoreParenImpCasts())) {
700 EmbedS->doForEachDataElement(Emit, ArrayIndex);
702 Emit(Args[i], ArrayIndex);
713 if (NumInitElements != NumArrayElements &&
714 !(Dest.
isZeroed() && hasTrivialFiller &&
721 llvm::Value *element = begin;
722 if (NumInitElements) {
723 element = Builder.CreateInBoundsGEP(
724 llvmElementType, element,
725 llvm::ConstantInt::get(CGF.
SizeTy, NumInitElements),
727 if (endOfInit.
isValid()) Builder.CreateStore(element, endOfInit);
731 llvm::Value *end = Builder.CreateInBoundsGEP(
732 llvmElementType, begin,
733 llvm::ConstantInt::get(CGF.
SizeTy, NumArrayElements),
"arrayinit.end");
735 llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
740 llvm::PHINode *currentElement =
741 Builder.CreatePHI(element->getType(), 2,
"arrayinit.cur");
742 currentElement->addIncoming(element, entryBB);
753 Address(currentElement, llvmElementType, elementAlign), elementType);
755 EmitInitializationToLValue(ArrayFiller, elementLV);
757 EmitNullInitializationToLValue(elementLV);
761 llvm::Value *nextElement = Builder.CreateInBoundsGEP(
762 llvmElementType, currentElement, one,
"arrayinit.next");
765 if (endOfInit.
isValid()) Builder.CreateStore(nextElement, endOfInit);
768 llvm::Value *done = Builder.CreateICmpEQ(nextElement, end,
771 Builder.CreateCondBr(done, endBB, bodyBB);
772 currentElement->addIncoming(nextElement, Builder.GetInsertBlock());
783 Visit(
E->getSubExpr());
800 EmitAggLoadOfLValue(
E);
826 if (
auto castE = dyn_cast<CastExpr>(op)) {
827 if (castE->getCastKind() == kind)
828 return castE->getSubExpr();
833void AggExprEmitter::VisitCastExpr(
CastExpr *
E) {
834 if (
const auto *ECE = dyn_cast<ExplicitCastExpr>(
E))
836 switch (
E->getCastKind()) {
839 assert(isa<CXXDynamicCastExpr>(
E) &&
"CK_Dynamic without a dynamic_cast?");
864 EmitInitializationToLValue(
E->getSubExpr(),
869 case CK_LValueToRValueBitCast: {
879 llvm::Value *SizeVal = llvm::ConstantInt::get(
882 Builder.CreateMemCpy(DestAddress, SourceAddress, SizeVal);
886 case CK_DerivedToBase:
887 case CK_BaseToDerived:
888 case CK_UncheckedDerivedToBase: {
889 llvm_unreachable(
"cannot perform hierarchy conversion in EmitAggExpr: "
890 "should have been unpacked before we got here");
893 case CK_NonAtomicToAtomic:
894 case CK_AtomicToNonAtomic: {
895 bool isToAtomic = (
E->getCastKind() == CK_NonAtomicToAtomic);
900 if (isToAtomic) std::swap(
atomicType, valueType);
909 return Visit(
E->getSubExpr());
913 (isToAtomic ? CK_AtomicToNonAtomic : CK_NonAtomicToAtomic);
920 "peephole significantly changed types?");
958 return EmitFinalDestCopy(valueType, rvalue);
960 case CK_AddressSpaceConversion:
961 return Visit(
E->getSubExpr());
963 case CK_LValueToRValue:
973 Visit(
E->getSubExpr());
984 case CK_HLSLArrayRValue:
985 Visit(
E->getSubExpr());
987 case CK_HLSLAggregateSplatCast: {
988 Expr *Src =
E->getSubExpr();
995 assert(RV.
isScalar() &&
"RHS of HLSL splat cast must be a scalar.");
1000 case CK_HLSLElementwiseCast: {
1001 Expr *Src =
E->getSubExpr();
1013 "Can't perform HLSL Aggregate cast on a complex type.");
1020 case CK_UserDefinedConversion:
1021 case CK_ConstructorConversion:
1024 "Implicit cast types must be compatible");
1025 Visit(
E->getSubExpr());
1028 case CK_LValueBitCast:
1029 llvm_unreachable(
"should not be emitting lvalue bitcast as rvalue");
1033 case CK_ArrayToPointerDecay:
1034 case CK_FunctionToPointerDecay:
1035 case CK_NullToPointer:
1036 case CK_NullToMemberPointer:
1037 case CK_BaseToDerivedMemberPointer:
1038 case CK_DerivedToBaseMemberPointer:
1039 case CK_MemberPointerToBoolean:
1040 case CK_ReinterpretMemberPointer:
1041 case CK_IntegralToPointer:
1042 case CK_PointerToIntegral:
1043 case CK_PointerToBoolean:
1045 case CK_VectorSplat:
1046 case CK_IntegralCast:
1047 case CK_BooleanToSignedIntegral:
1048 case CK_IntegralToBoolean:
1049 case CK_IntegralToFloating:
1050 case CK_FloatingToIntegral:
1051 case CK_FloatingToBoolean:
1052 case CK_FloatingCast:
1053 case CK_CPointerToObjCPointerCast:
1054 case CK_BlockPointerToObjCPointerCast:
1055 case CK_AnyPointerToBlockPointerCast:
1056 case CK_ObjCObjectLValueCast:
1057 case CK_FloatingRealToComplex:
1058 case CK_FloatingComplexToReal:
1059 case CK_FloatingComplexToBoolean:
1060 case CK_FloatingComplexCast:
1061 case CK_FloatingComplexToIntegralComplex:
1062 case CK_IntegralRealToComplex:
1063 case CK_IntegralComplexToReal:
1064 case CK_IntegralComplexToBoolean:
1065 case CK_IntegralComplexCast:
1066 case CK_IntegralComplexToFloatingComplex:
1067 case CK_ARCProduceObject:
1068 case CK_ARCConsumeObject:
1069 case CK_ARCReclaimReturnedObject:
1070 case CK_ARCExtendBlockObject:
1071 case CK_CopyAndAutoreleaseBlockObject:
1072 case CK_BuiltinFnToFnPtr:
1073 case CK_ZeroToOCLOpaqueType:
1075 case CK_HLSLVectorTruncation:
1077 case CK_IntToOCLSampler:
1078 case CK_FloatingToFixedPoint:
1079 case CK_FixedPointToFloating:
1080 case CK_FixedPointCast:
1081 case CK_FixedPointToBoolean:
1082 case CK_FixedPointToIntegral:
1083 case CK_IntegralToFixedPoint:
1084 llvm_unreachable(
"cast kind invalid for aggregate types");
1088void AggExprEmitter::VisitCallExpr(
const CallExpr *
E) {
1089 if (
E->getCallReturnType(CGF.
getContext())->isReferenceType()) {
1090 EmitAggLoadOfLValue(
E);
1110void AggExprEmitter::VisitStmtExpr(
const StmtExpr *
E) {
1124 const char *NameSuffix =
"") {
1127 ArgTy = CT->getElementType();
1131 "member pointers may only be compared for equality");
1133 CGF, LHS, RHS, MPT,
false);
1137 struct CmpInstInfo {
1139 llvm::CmpInst::Predicate FCmp;
1140 llvm::CmpInst::Predicate SCmp;
1141 llvm::CmpInst::Predicate UCmp;
1143 CmpInstInfo InstInfo = [&]() -> CmpInstInfo {
1144 using FI = llvm::FCmpInst;
1145 using II = llvm::ICmpInst;
1148 return {
"cmp.lt", FI::FCMP_OLT, II::ICMP_SLT, II::ICMP_ULT};
1150 return {
"cmp.gt", FI::FCMP_OGT, II::ICMP_SGT, II::ICMP_UGT};
1152 return {
"cmp.eq", FI::FCMP_OEQ, II::ICMP_EQ, II::ICMP_EQ};
1154 llvm_unreachable(
"Unrecognised CompareKind enum");
1158 return Builder.CreateFCmp(InstInfo.FCmp, LHS, RHS,
1159 llvm::Twine(InstInfo.Name) + NameSuffix);
1163 return Builder.CreateICmp(Inst, LHS, RHS,
1164 llvm::Twine(InstInfo.Name) + NameSuffix);
1167 llvm_unreachable(
"unsupported aggregate binary expression should have "
1168 "already been handled");
1172 using llvm::BasicBlock;
1173 using llvm::PHINode;
1180 "cannot copy non-trivially copyable aggregate");
1192 auto EmitOperand = [&](
Expr *
E) -> std::pair<Value *, Value *> {
1201 auto LHSValues = EmitOperand(
E->getLHS()),
1202 RHSValues = EmitOperand(
E->getRHS());
1206 K, IsComplex ?
".r" :
"");
1211 RHSValues.second, K,
".i");
1212 return Builder.CreateAnd(Cmp, CmpImag,
"and.eq");
1215 return Builder.getInt(VInfo->getIntValue());
1223 Builder.CreateSelect(EmitCmp(
CK_Less), EmitCmpRes(CmpInfo.
getLess()),
1225 Select = Builder.CreateSelect(EmitCmp(
CK_Equal),
1227 SelectOne,
"sel.eq");
1229 Value *SelectEq = Builder.CreateSelect(
1234 SelectEq,
"sel.gt");
1235 Select = Builder.CreateSelect(
1236 EmitCmp(
CK_Less), EmitCmpRes(CmpInfo.
getLess()), SelectGT,
"sel.lt");
1252 if (
E->getOpcode() == BO_PtrMemD ||
E->getOpcode() == BO_PtrMemI)
1253 VisitPointerToDataMemberBinaryOperator(
E);
1258void AggExprEmitter::VisitPointerToDataMemberBinaryOperator(
1261 EmitFinalDestCopy(
E->
getType(), LV);
1271 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
E)) {
1272 const VarDecl *var = dyn_cast<VarDecl>(DRE->getDecl());
1273 return (var && var->hasAttr<BlocksAttr>());
1282 if (op->isAssignmentOp() || op->isPtrMemOp())
1286 if (op->getOpcode() == BO_Comma)
1294 = dyn_cast<AbstractConditionalOperator>(
E)) {
1300 = dyn_cast<OpaqueValueExpr>(
E)) {
1301 if (
const Expr *src = op->getSourceExpr())
1309 if (
cast->getCastKind() == CK_LValueToRValue)
1315 }
else if (
const UnaryOperator *uop = dyn_cast<UnaryOperator>(
E)) {
1319 }
else if (
const MemberExpr *mem = dyn_cast<MemberExpr>(
E)) {
1336 &&
"Invalid assignment");
1345 EnsureDest(
E->getRHS()->
getType());
1373 EnsureDest(
E->getRHS()->
getType());
1391 EmitFinalDestCopy(
E->
getType(), LHS);
1399void AggExprEmitter::
1414 bool destructNonTrivialCStruct =
1415 !isExternallyDestructed &&
1417 isExternallyDestructed |= destructNonTrivialCStruct;
1426 Visit(
E->getTrueExpr());
1429 assert(CGF.
HaveInsertPoint() &&
"expression evaluation ended with no IP!");
1430 CGF.
Builder.CreateBr(ContBlock);
1442 Visit(
E->getFalseExpr());
1445 if (destructNonTrivialCStruct)
1454void AggExprEmitter::VisitChooseExpr(
const ChooseExpr *CE) {
1458void AggExprEmitter::VisitVAArgExpr(
VAArgExpr *VE) {
1478 Visit(
E->getSubExpr());
1481 if (!wasExternallyDestructed)
1491void AggExprEmitter::VisitCXXInheritedCtorInitExpr(
1495 E->getConstructor(),
E->constructsVBase(), Slot.
getAddress(),
1496 E->inheritedFromVBase(),
E);
1510 e =
E->capture_init_end();
1511 i != e; ++i, ++CurField) {
1514 if (CurField->hasCapturedVLAType()) {
1519 EmitInitializationToLValue(*i, LV);
1523 CurField->getType().isDestructedType()) {
1527 CurField->getType(),
1535 Visit(
E->getSubExpr());
1557 case CK_UserDefinedConversion:
1558 case CK_ConstructorConversion:
1564 case CK_BooleanToSignedIntegral:
1565 case CK_FloatingCast:
1566 case CK_FloatingComplexCast:
1567 case CK_FloatingComplexToBoolean:
1568 case CK_FloatingComplexToIntegralComplex:
1569 case CK_FloatingComplexToReal:
1570 case CK_FloatingRealToComplex:
1571 case CK_FloatingToBoolean:
1572 case CK_FloatingToIntegral:
1573 case CK_IntegralCast:
1574 case CK_IntegralComplexCast:
1575 case CK_IntegralComplexToBoolean:
1576 case CK_IntegralComplexToFloatingComplex:
1577 case CK_IntegralComplexToReal:
1578 case CK_IntegralRealToComplex:
1579 case CK_IntegralToBoolean:
1580 case CK_IntegralToFloating:
1582 case CK_IntegralToPointer:
1583 case CK_PointerToIntegral:
1585 case CK_VectorSplat:
1587 case CK_NonAtomicToAtomic:
1588 case CK_AtomicToNonAtomic:
1589 case CK_HLSLVectorTruncation:
1590 case CK_HLSLElementwiseCast:
1591 case CK_HLSLAggregateSplatCast:
1594 case CK_BaseToDerivedMemberPointer:
1595 case CK_DerivedToBaseMemberPointer:
1596 case CK_MemberPointerToBoolean:
1597 case CK_NullToMemberPointer:
1598 case CK_ReinterpretMemberPointer:
1602 case CK_AnyPointerToBlockPointerCast:
1603 case CK_BlockPointerToObjCPointerCast:
1604 case CK_CPointerToObjCPointerCast:
1605 case CK_ObjCObjectLValueCast:
1606 case CK_IntToOCLSampler:
1607 case CK_ZeroToOCLOpaqueType:
1611 case CK_FixedPointCast:
1612 case CK_FixedPointToBoolean:
1613 case CK_FixedPointToFloating:
1614 case CK_FixedPointToIntegral:
1615 case CK_FloatingToFixedPoint:
1616 case CK_IntegralToFixedPoint:
1620 case CK_AddressSpaceConversion:
1621 case CK_BaseToDerived:
1622 case CK_DerivedToBase:
1624 case CK_NullToPointer:
1625 case CK_PointerToBoolean:
1630 case CK_ARCConsumeObject:
1631 case CK_ARCExtendBlockObject:
1632 case CK_ARCProduceObject:
1633 case CK_ARCReclaimReturnedObject:
1634 case CK_CopyAndAutoreleaseBlockObject:
1635 case CK_ArrayToPointerDecay:
1636 case CK_FunctionToPointerDecay:
1637 case CK_BuiltinFnToFnPtr:
1639 case CK_LValueBitCast:
1640 case CK_LValueToRValue:
1641 case CK_LValueToRValueBitCast:
1642 case CK_UncheckedDerivedToBase:
1643 case CK_HLSLArrayRValue:
1646 llvm_unreachable(
"Unhandled clang::CastKind enum");
1654 while (
auto *CE = dyn_cast<CastExpr>(
E)) {
1662 return IL->getValue() == 0;
1665 return FL->getValue().isPosZero();
1667 if ((isa<ImplicitValueInitExpr>(
E) || isa<CXXScalarValueInitExpr>(
E)) &&
1671 if (
const CastExpr *ICE = dyn_cast<CastExpr>(
E))
1672 return ICE->getCastKind() == CK_NullToPointer &&
1677 return CL->getValue() == 0;
1685AggExprEmitter::EmitInitializationToLValue(
Expr *
E,
LValue LV) {
1692 }
else if (isa<ImplicitValueInitExpr>(
E) || isa<CXXScalarValueInitExpr>(
E)) {
1693 return EmitNullInitializationToLValue(LV);
1694 }
else if (isa<NoInitExpr>(
E)) {
1697 }
else if (
type->isReferenceType()) {
1705void AggExprEmitter::EmitNullInitializationToLValue(
LValue lv) {
1733 VisitCXXParenListOrInitListExpr(
E,
E->getInitExprs(),
1734 E->getInitializedFieldInUnion(),
1735 E->getArrayFiller());
1739 if (
E->hadArrayRangeDesignator())
1742 if (
E->isTransparent())
1743 return Visit(
E->getInit(0));
1745 VisitCXXParenListOrInitListExpr(
1746 E,
E->inits(),
E->getInitializedFieldInUnion(),
E->getArrayFiller());
1749void AggExprEmitter::VisitCXXParenListOrInitListExpr(
1758 if (llvm::Constant *
C =
1759 CGF.
CGM.EmitConstantExpr(ExprToVisit, ExprToVisit->
getType(), &CGF)) {
1760 llvm::GlobalVariable* GV =
1761 new llvm::GlobalVariable(CGF.
CGM.
getModule(),
C->getType(),
true,
1762 llvm::GlobalValue::InternalLinkage,
C,
"");
1763 EmitFinalDestCopy(ExprToVisit->
getType(),
1777 if (CGF.
getLangOpts().HLSL && isa<InitListExpr>(ExprToVisit))
1779 CGF, cast<InitListExpr>(ExprToVisit));
1789 InitExprs, ArrayFiller);
1795 assert(InitExprs.size() == 0 &&
1796 "you can only use an empty initializer with VLAs");
1802 "Only support structs/unions here!");
1808 unsigned NumInitElements = InitExprs.size();
1815 unsigned curInitIndex = 0;
1818 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(record)) {
1819 assert(NumInitElements >= CXXRD->getNumBases() &&
1820 "missing initializer for base class");
1821 for (
auto &
Base : CXXRD->bases()) {
1822 assert(!
Base.isVirtual() &&
"should not see vbases here");
1823 auto *BaseRD =
Base.getType()->getAsCXXRecordDecl();
1833 CGF.
EmitAggExpr(InitExprs[curInitIndex++], AggSlot);
1836 Base.getType().isDestructedType())
1844 const bool ZeroInitPadding =
1850 if (!InitializedFieldInUnion) {
1856 for (
const auto *Field : record->
fields())
1858 (
Field->isUnnamedBitField() ||
Field->isAnonymousStructOrUnion()) &&
1859 "Only unnamed bitfields or anonymous class allowed");
1868 if (NumInitElements) {
1870 EmitInitializationToLValue(InitExprs[0], FieldLoc);
1871 if (ZeroInitPadding) {
1875 DoZeroInitPadding(FieldSize, TotalSize,
nullptr);
1879 if (ZeroInitPadding)
1880 EmitNullInitializationToLValue(DestLV);
1882 EmitNullInitializationToLValue(FieldLoc);
1892 for (
const auto *field : record->
fields()) {
1894 if (field->getType()->isIncompleteArrayType())
1898 if (field->isUnnamedBitField())
1904 if (curInitIndex == NumInitElements && Dest.
isZeroed() &&
1908 if (ZeroInitPadding)
1909 DoZeroInitPadding(PaddingStart,
1916 if (curInitIndex < NumInitElements) {
1918 EmitInitializationToLValue(InitExprs[curInitIndex++], LV);
1921 EmitNullInitializationToLValue(LV);
1928 = field->getType().isDestructedType()) {
1937 if (ZeroInitPadding) {
1940 DoZeroInitPadding(PaddingStart, TotalSize,
nullptr);
1944void AggExprEmitter::DoZeroInitPadding(uint64_t &PaddingStart,
1945 uint64_t PaddingEnd,
1954 llvm::Constant *SizeVal = Builder.getInt64((End - Start).getQuantity());
1958 if (NextField !=
nullptr && NextField->
isBitField()) {
1965 if (StorageStart + Info.
StorageSize > PaddingStart) {
1966 if (StorageStart > PaddingStart)
1967 InitBytes(PaddingStart, StorageStart);
1980 if (PaddingStart < PaddingEnd)
1981 InitBytes(PaddingStart, PaddingEnd);
1982 if (NextField !=
nullptr)
1988 llvm::Value *outerBegin) {
1993 uint64_t numElements =
E->getArraySize().getZExtValue();
1999 llvm::Value *zero = llvm::ConstantInt::get(CGF.
SizeTy, 0);
2000 llvm::Value *indices[] = {zero, zero};
2001 llvm::Value *begin = Builder.CreateInBoundsGEP(destPtr.
getElementType(),
2003 indices,
"arrayinit.begin");
2018 llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
2023 llvm::PHINode *index =
2024 Builder.CreatePHI(zero->getType(), 2,
"arrayinit.index");
2025 index->addIncoming(zero, entryBB);
2026 llvm::Value *element =
2027 Builder.CreateInBoundsGEP(llvmElementType, begin, index);
2033 if (outerBegin->getType() != element->getType())
2034 outerBegin = Builder.CreateBitCast(outerBegin, element->getType());
2050 Address(element, llvmElementType, elementAlign), elementType);
2058 AggExprEmitter(CGF, elementSlot,
false)
2059 .VisitArrayInitLoopExpr(InnerLoop, outerBegin);
2061 EmitInitializationToLValue(
E->getSubExpr(), elementLV);
2065 llvm::Value *nextIndex = Builder.CreateNUWAdd(
2066 index, llvm::ConstantInt::get(CGF.
SizeTy, 1),
"arrayinit.next");
2067 index->addIncoming(nextIndex, Builder.GetInsertBlock());
2070 llvm::Value *done = Builder.CreateICmpEQ(
2071 nextIndex, llvm::ConstantInt::get(CGF.
SizeTy, numElements),
2074 Builder.CreateCondBr(done, endBB, bodyBB);
2087 EmitInitializationToLValue(
E->getBase(), DestLV);
2088 VisitInitListExpr(
E->getUpdater());
2099 if (
auto *MTE = dyn_cast<MaterializeTemporaryExpr>(
E))
2100 E = MTE->getSubExpr();
2110 ILE = dyn_cast<InitListExpr>(ILE->
getInit(0));
2118 if (!RT->isUnionType()) {
2122 unsigned ILEElement = 0;
2123 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(SD))
2124 while (ILEElement != CXXRD->getNumBases())
2127 for (
const auto *Field : SD->
fields()) {
2130 if (Field->getType()->isIncompleteArrayType() ||
2133 if (Field->isUnnamedBitField())
2139 if (Field->getType()->isReferenceType())
2146 return NumNonZeroBytes;
2152 for (
unsigned i = 0, e = ILE->
getNumInits(); i != e; ++i)
2154 return NumNonZeroBytes;
2172 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getOriginalDecl());
2185 if (NumNonZeroBytes*4 > Size)
2189 llvm::Constant *SizeVal = CGF.
Builder.getInt64(Size.getQuantity());
2207 "Invalid aggregate expression to emit");
2209 "slot has bits but no address");
2214 AggExprEmitter(*
this, Slot, Slot.
isIgnored()).Visit(
const_cast<Expr*
>(
E));
2231 return AggExprEmitter(*
this, Dest, Dest.
isIgnored())
2232 .EmitFinalDestCopy(
Type, Src, SrcKind);
2275 getContext().getASTRecordLayout(BaseRD).getSize() <=
2293 assert((
Record->hasTrivialCopyConstructor() ||
2294 Record->hasTrivialCopyAssignment() ||
2295 Record->hasTrivialMoveConstructor() ||
2296 Record->hasTrivialMoveAssignment() ||
2297 Record->hasAttr<TrivialABIAttr>() ||
Record->isUnion()) &&
2298 "Trying to aggregate-copy a type without a trivial copy/move "
2299 "constructor or assignment operator");
2308 if (
getTargetHooks().emitCUDADeviceBuiltinSurfaceDeviceCopy(*
this, Dest,
2312 if (
getTargetHooks().emitCUDADeviceBuiltinTextureDeviceCopy(*
this, Dest,
2338 llvm::Value *SizeVal =
nullptr;
2341 if (
auto *VAT = dyn_cast_or_null<VariableArrayType>(
2347 SizeVal =
Builder.CreateNUWMul(
2376 if (
Record->hasObjectMember()) {
2384 if (
Record->hasObjectMember()) {
2399 Inst->setMetadata(llvm::LLVMContext::MD_tbaa_struct, TBAAStructTag);
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 void EmitHLSLScalarFlatCast(CodeGenFunction &CGF, Address DestVal, QualType DestTy, llvm::Value *SrcVal, QualType SrcTy, SourceLocation Loc)
static bool isBlockVarRef(const Expr *E)
Is the value of the given expression possibly a reference to or into a __block variable?
static void EmitHLSLElementwiseCast(CodeGenFunction &CGF, Address DestVal, QualType DestTy, Address SrcVal, QualType SrcTy, SourceLocation Loc)
static bool isTrivialFiller(Expr *E)
Determine if E is a trivial array filler, that is, one that is equivalent to zero-initialization.
static bool isSimpleZero(const Expr *E, CodeGenFunction &CGF)
isSimpleZero - If emitting this value will obviously just cause a store of zero to memory,...
static void EmitHLSLAggregateSplatCast(CodeGenFunction &CGF, Address DestVal, QualType DestTy, llvm::Value *SrcVal, QualType SrcTy, SourceLocation Loc)
static llvm::Value * EmitCompare(CGBuilderTy &Builder, CodeGenFunction &CGF, const BinaryOperator *E, llvm::Value *LHS, llvm::Value *RHS, CompareKind Kind, const char *NameSuffix="")
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,...
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
llvm::MachO::Record Record
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,...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
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 ...
TypeInfoChars getTypeInfoDataSizeInChars(QualType T) const
TypeInfoChars getTypeInfoInChars(const Type *T) const
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
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.
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
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...
Represents a loop initializing the elements of an array.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
A builtin binary operation expression such as "x + y" or "x <= y".
Represents binding an expression to a temporary.
Represents a call to a C++ constructor.
A default argument (C++ [dcl.fct.default]).
A use of a default initializer in a constructor or in aggregate initialization.
Expr * getExpr()
Get the initialization expression that will be used.
Represents a call to an inherited base class constructor from an inheriting constructor.
Represents a list-initialization with parenthesis.
Represents a C++ struct/union/class.
bool isTriviallyCopyable() const
Determine whether this class is considered trivially copyable per (C++11 [class]p6).
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]).
A rewritten comparison expression that was originally written using operator syntax.
An expression "T()" which creates an rvalue of a non-class type T.
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
A C++ throw-expression (C++ [except.throw]).
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
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.
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
Represents a 'co_await' expression.
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.
llvm::PointerType * getType() const
Return the type of the pointer value.
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
A scoped helper to set the current source atom group for CGDebugInfo::addInstToCurrentSourceAtom.
A scoped helper to set the current debug location to the specified location or preferred location of ...
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::CallInst * CreateMemSet(Address Dest, llvm::Value *Value, llvm::Value *Size, bool IsVolatile=false)
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)
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
CGRecordLayout - This class handles struct and union layout info while lowering AST types to LLVM typ...
const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const
Return the BitFieldInfo that corresponds to the field FD.
The scope of an ArrayInitLoopExpr.
The scope of a CXXDefaultInitExpr.
An object to manage conditionally-evaluated expressions.
A scope within which we are constructing the fields of an object which might use a CXXDefaultInitExpr...
An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
An RAII object to record that we're evaluating a statement expression.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void CreateCoercedStore(llvm::Value *Src, Address Dst, llvm::TypeSize DstSize, bool DstIsVolatile)
Create a store to.
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.
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 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)
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 incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
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)
CodeGenTypes & getTypes() const
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.
void FlattenAccessAndType(Address Addr, QualType AddrTy, SmallVectorImpl< std::pair< Address, llvm::Value * > > &AccessList, SmallVectorImpl< QualType > &FlatTypes)
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()
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.
This class organizes the cross-function state that is used while generating LLVM code.
void EmitExplicitCastExprType(const ExplicitCastExpr *E, CodeGenFunction *CGF=nullptr)
Emit type info if type of an expression is a variably modified type.
llvm::MDNode * getTBAAStructInfo(QualType QTy)
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.
TBAAAccessInfo mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo, TBAAAccessInfo SrcInfo)
mergeTBAAInfoForMemoryTransfer - Get merged TBAA information for the purposes of memory transfer call...
const LangOptions & getLangOpts() const
CGCXXABI & getCXXABI() const
void DecorateInstructionWithTBAA(llvm::Instruction *Inst, TBAAAccessInfo TBAAInfo)
DecorateInstructionWithTBAA - Decorate the instruction with a TBAA tag.
ASTContext & getContext() const
const CodeGenOptions & getCodeGenOpts() const
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...
A saved depth on the scope stack.
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
void setNonGC(bool Value)
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.
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
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.
CompoundLiteralExpr - [C99 6.5.2.5].
Represents the canonical version of C arrays with a specified constant size.
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Represents a 'co_yield' expression.
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
A reference to a declared variable, function, enum, etc.
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
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.
Represents a C11 generic selection.
Represents an implicitly-generated value initialization of an object of a given type.
Describes an C or C++ initializer list.
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
unsigned getNumInits() const
const Expr * getInit(unsigned Init) const
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Expr *const * const_capture_init_iterator
Const iterator that walks over the capture initialization arguments.
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
A pointer to member type per C++ 8.3.3 - Pointers to members.
Represents a place-holder for an object not to be initialized by anything.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
An expression that sends a message to the given Objective-C object or class.
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 ...
ParenExpr - This represents a parenthesized expression, e.g.
const Expr * getSubExpr() const
[C99 6.4.2.2] - A predefined identifier such as func.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
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.
bool isPODType(const ASTContext &Context) const
Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
@ PCK_Struct
The type is a struct containing a field whose type is neither PCK_Trivial nor PCK_VolatileTrivial.
The collection of all-type qualifiers we support.
Represents a struct/union/class.
bool hasObjectMember() const
field_range fields() const
RecordDecl * getDefinitionOrSelf() const
field_iterator field_begin() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Scope - A scope is a transient data structure that is used while parsing the program.
Encodes a location in the source.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
RetTy Visit(PTR(Stmt) S, ParamTys... P)
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Stmt - This represents one statement.
StringLiteral - This represents a string literal expression, e.g.
Represents a reference to a non-type template parameter that has been substituted with a template arg...
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
The base class of the type hierarchy.
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 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 isAtomicType() 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),...
Represents a call to the builtin function __builtin_va_arg.
Represents a variable declaration or definition.
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
@ 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
Matches atomic types.
bool GE(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
LangAS
Defines the address space values used by the address space qualifier of QualType.
CastKind
CastKind - The kind of operation required for a conversion.
const FunctionProtoType * T
U cast(CodeGen::Address addr)
Diagnostic wrappers for TextAPI types for error reporting.
cl::opt< bool > EnableSingleByteCoverage
Structure with information about how a bitfield should be accessed.
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