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,
98 void EmitComparisonResult(
const Expr *E,
99 const ComparisonCategoryInfo &CmpInfo,
100 llvm::Value *ResultValue);
103 if (CGF.
getLangOpts().getGC() && TypeRequiresGCollection(
T))
108 bool TypeRequiresGCollection(QualType
T);
114 void Visit(Expr *E) {
115 ApplyDebugLocation DL(CGF, E);
116 StmtVisitor<AggExprEmitter>::Visit(E);
119 void VisitStmt(Stmt *S) { CGF.
ErrorUnsupported(S,
"aggregate expression"); }
120 void VisitParenExpr(ParenExpr *PE) { Visit(PE->
getSubExpr()); }
121 void VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
122 Visit(
GE->getResultExpr());
124 void VisitCoawaitExpr(CoawaitExpr *E) {
127 void VisitCoyieldExpr(CoyieldExpr *E) {
130 void VisitUnaryCoawait(UnaryOperator *E) { Visit(E->
getSubExpr()); }
131 void VisitUnaryExtension(UnaryOperator *E) { Visit(E->
getSubExpr()); }
132 void VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
136 void VisitConstantExpr(ConstantExpr *E) {
139 if (llvm::Value *
Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
142 llvm::TypeSize::getFixed(
152 void VisitDeclRefExpr(DeclRefExpr *E) { EmitAggLoadOfLValue(E); }
153 void VisitMemberExpr(MemberExpr *ME) { EmitAggLoadOfLValue(ME); }
154 void VisitUnaryDeref(UnaryOperator *E) { EmitAggLoadOfLValue(E); }
155 void VisitStringLiteral(StringLiteral *E) { EmitAggLoadOfLValue(E); }
156 void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
157 void VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
158 EmitAggLoadOfLValue(E);
160 void VisitPredefinedExpr(
const PredefinedExpr *E) { EmitAggLoadOfLValue(E); }
164 void VisitCallExpr(
const CallExpr *E);
165 void VisitStmtExpr(
const StmtExpr *E);
166 void VisitBinaryOperator(
const BinaryOperator *BO);
167 void VisitPointerToDataMemberBinaryOperator(
const BinaryOperator *BO);
168 void VisitBinAssign(
const BinaryOperator *E);
169 void VisitBinComma(
const BinaryOperator *E);
170 void VisitBinCmp(
const BinaryOperator *E);
171 void VisitTypeTraitExpr(
const TypeTraitExpr *E);
172 void VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) {
176 void VisitObjCMessageExpr(ObjCMessageExpr *E);
177 void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { EmitAggLoadOfLValue(E); }
179 void VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E);
180 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO);
181 void VisitChooseExpr(
const ChooseExpr *CE);
182 void VisitInitListExpr(InitListExpr *E);
183 void VisitCXXParenListOrInitListExpr(Expr *ExprToVisit, ArrayRef<Expr *> Args,
184 FieldDecl *InitializedFieldInUnion,
186 void VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E,
187 llvm::Value *outerBegin =
nullptr);
188 void VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);
189 void VisitNoInitExpr(NoInitExpr *E) {}
190 void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
191 CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
194 void VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
195 CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
198 void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
199 void VisitCXXConstructExpr(
const CXXConstructExpr *E);
200 void VisitCXXInheritedCtorInitExpr(
const CXXInheritedCtorInitExpr *E);
202 void VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E);
203 void VisitExprWithCleanups(ExprWithCleanups *E);
204 void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
205 void VisitCXXTypeidExpr(CXXTypeidExpr *E) { EmitAggLoadOfLValue(E); }
206 void VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E);
207 void VisitOpaqueValueExpr(OpaqueValueExpr *E);
209 void VisitPseudoObjectExpr(PseudoObjectExpr *E) {
212 return EmitFinalDestCopy(E->
getType(), LV);
215 AggValueSlot Slot = EnsureSlot(E->
getType());
216 bool NeedsDestruction =
219 if (NeedsDestruction)
222 if (NeedsDestruction)
227 void VisitVAArgExpr(VAArgExpr *E);
228 void VisitCXXParenListInitExpr(CXXParenListInitExpr *E);
229 void VisitCXXParenListOrInitListExpr(Expr *ExprToVisit, ArrayRef<Expr *> Args,
232 void EmitInitializationToLValue(Expr *E, LValue Address);
233 void EmitNullInitializationToLValue(LValue Address);
236 void VisitAtomicExpr(AtomicExpr *E) {
238 EmitFinalDestCopy(E->
getType(), Res);
240 void VisitPackIndexingExpr(PackIndexingExpr *E) {
253void AggExprEmitter::EmitAggLoadOfLValue(
const Expr *E) {
266 EmitFinalDestCopy(E->
getType(), LV);
270bool AggExprEmitter::TypeRequiresGCollection(QualType
T) {
286void AggExprEmitter::withReturnValueSlot(
287 const Expr *E, llvm::function_ref<RValue(ReturnValueSlot)> EmitCall) {
289 bool RequiresDestruction =
305 bool CanAggregateCopy =
310 : RetTy.isTriviallyCopyableType(CGF.getContext());
311 bool DestASMismatch = !Dest.
isIgnored() && CanAggregateCopy &&
314 ->stripPointerCasts()
316 ->getPointerAddressSpace() != SRetAS;
318 (RequiresDestruction && Dest.
isIgnored()) || DestASMismatch;
322 EHScopeStack::stable_iterator LifetimeEndBlock;
323 llvm::IntrinsicInst *LifetimeStartInst =
nullptr;
326 if (RetAddr.isValid() && RetAddr.getAddressSpace() != SRetAS) {
327 llvm::Type *SRetPtrTy =
329 RetAddr = RetAddr.withPointer(
331 RetAddr.isKnownNonNull());
338 assert(LifetimeStartInst->getIntrinsicID() ==
339 llvm::Intrinsic::lifetime_start &&
340 "Last insertion wasn't a lifetime.start?");
349 EmitCall(ReturnValueSlot(RetAddr, Dest.
isVolatile(), IsResultUnused,
357 EmitFinalDestCopy(E->
getType(), Src);
359 if (!RequiresDestruction && LifetimeStartInst) {
369void AggExprEmitter::EmitFinalDestCopy(QualType
type, RValue src) {
370 assert(src.
isAggregate() &&
"value must be aggregate value!");
376void AggExprEmitter::EmitFinalDestCopy(
377 QualType
type,
const LValue &src,
411 EmitCopy(
type, Dest, srcAgg);
418void AggExprEmitter::EmitCopy(QualType
type,
const AggValueSlot &dest,
419 const AggValueSlot &src) {
439void AggExprEmitter::VisitCXXStdInitializerListExpr(
440 CXXStdInitializerListExpr *E) {
445 assert(
Array.isSimple() &&
"initializer_list array not a simple lvalue");
448 const ConstantArrayType *ArrayType =
450 assert(ArrayType &&
"std::initializer_list constructed from non-array");
454 assert(Field !=
Record->field_end() &&
457 "Expected std::initializer_list first field to be const E *");
460 AggValueSlot Dest = EnsureSlot(E->
getType());
466 assert(Field !=
Record->field_end() &&
467 "Expected std::initializer_list to have two fields");
469 llvm::Value *
Size = Builder.getInt(ArrayType->
getSize());
477 assert(
Field->getType()->isPointerType() &&
480 "Expected std::initializer_list second field to be const E *");
481 llvm::Value *
Zero = llvm::ConstantInt::get(CGF.
PtrDiffTy, 0);
482 llvm::Value *IdxEnd[] = {
Zero,
Size};
483 llvm::Value *ArrayEnd = Builder.CreateInBoundsGEP(
489 assert(++Field ==
Record->field_end() &&
490 "Expected std::initializer_list to only have two fields");
502 if (
auto *ILE = dyn_cast<InitListExpr>(E)) {
503 if (ILE->getNumInits())
508 if (
auto *Cons = dyn_cast_or_null<CXXConstructExpr>(E))
509 return Cons->getConstructor()->isDefaultConstructor() &&
510 Cons->getConstructor()->isTrivial();
530 SrcTy = VT->getElementType();
531 assert(StoreList.size() <= VT->getNumElements() &&
532 "Cannot perform HLSL flat cast when vector source \
533 object has less elements than flattened destination \
537 for (
unsigned I = 0, Size = StoreList.size(); I < Size; I++) {
538 LValue DestLVal = StoreList[I];
558 assert(StoreList.size() <= LoadList.size() &&
559 "Cannot perform HLSL elementwise cast when flattened source object \
560 has less elements than flattened destination object.");
563 for (
unsigned I = 0, E = StoreList.size(); I < E; I++) {
564 LValue DestLVal = StoreList[I];
565 LValue SrcLVal = LoadList[I];
567 assert(RVal.
isScalar() &&
"All flattened source values should be scalars");
570 DestLVal.getType(), Loc);
577void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
578 QualType ArrayQTy, Expr *ExprToVisit,
579 ArrayRef<Expr *> Args, Expr *ArrayFiller) {
580 uint64_t NumInitElements = Args.size();
582 uint64_t NumArrayElements = AType->getNumElements();
583 for (
const auto *
Init : Args) {
584 if (
const auto *Embed = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
585 NumInitElements += Embed->getDataElementCount() - 1;
586 if (NumInitElements > NumArrayElements) {
587 NumInitElements = NumArrayElements;
593 assert(NumInitElements <= NumArrayElements);
595 QualType elementType =
598 CharUnits elementAlign =
605 if (NumInitElements * elementSize.
getQuantity() > 16 &&
607 CodeGen::CodeGenModule &CGM = CGF.
CGM;
608 ConstantEmitter Emitter(CGF);
613 if (llvm::Constant *
C =
614 Emitter.tryEmitForInitializer(ExprToVisit, AS, GVArrayQTy)) {
615 auto GV =
new llvm::GlobalVariable(
617 true, llvm::GlobalValue::PrivateLinkage,
C,
619 nullptr, llvm::GlobalVariable::NotThreadLocal,
621 Emitter.finalize(GV);
624 Address GVAddr(GV, GV->getValueType(), Align);
625 EmitFinalDestCopy(ArrayQTy, CGF.
MakeAddrLValue(GVAddr, GVArrayQTy));
635 CodeGenFunction::CleanupDeactivationScope deactivation(CGF);
639 CodeGenFunction::AllocaTrackerRAII allocaTracker(CGF);
644 llvm::Instruction *dominatingIP =
645 Builder.CreateFlagLoad(llvm::ConstantInt::getNullValue(CGF.
Int8PtrTy));
647 "arrayinit.endOfInit");
648 Builder.CreateStore(begin, endOfInit);
653 .AddAuxAllocas(allocaTracker.Take());
659 llvm::Value *one = llvm::ConstantInt::get(CGF.
SizeTy, 1);
662 llvm::Value *element = begin;
663 if (ArrayIndex > 0) {
665 element = Builder.CreateStructuredGEP(
666 AType, begin, llvm::ConstantInt::get(CGF.
SizeTy, ArrayIndex),
667 "arrayinit.element");
669 element = Builder.CreateInBoundsGEP(
670 llvmElementType, begin,
671 llvm::ConstantInt::get(CGF.
SizeTy, ArrayIndex),
672 "arrayinit.element");
678 Builder.CreateStore(element, endOfInit);
682 Address(element, llvmElementType, elementAlign), elementType);
683 EmitInitializationToLValue(
Init, elementLV);
687 unsigned ArrayIndex = 0;
689 for (uint64_t i = 0; i != NumInitElements; ++i) {
690 if (ArrayIndex >= NumInitElements)
692 if (
auto *EmbedS = dyn_cast<EmbedExpr>(Args[i]->IgnoreParenImpCasts())) {
693 EmbedS->doForEachDataElement(Emit, ArrayIndex);
695 Emit(Args[i], ArrayIndex);
706 if (NumInitElements != NumArrayElements &&
707 !(Dest.
isZeroed() && hasTrivialFiller &&
714 llvm::Value *element = begin;
715 if (NumInitElements) {
716 element = Builder.CreateInBoundsGEP(
717 llvmElementType, element,
718 llvm::ConstantInt::get(CGF.
SizeTy, NumInitElements),
721 Builder.CreateStore(element, endOfInit);
725 llvm::Value *end = Builder.CreateInBoundsGEP(
726 llvmElementType, begin,
727 llvm::ConstantInt::get(CGF.
SizeTy, NumArrayElements),
"arrayinit.end");
729 llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
734 llvm::PHINode *currentElement =
735 Builder.CreatePHI(element->getType(), 2,
"arrayinit.cur");
736 currentElement->addIncoming(element, entryBB);
748 CodeGenFunction::RunCleanupsScope CleanupsScope(CGF);
750 Address(currentElement, llvmElementType, elementAlign), elementType);
752 EmitInitializationToLValue(ArrayFiller, elementLV);
754 EmitNullInitializationToLValue(elementLV);
758 llvm::Value *nextElement = Builder.CreateInBoundsGEP(
759 llvmElementType, currentElement, one,
"arrayinit.next");
763 Builder.CreateStore(nextElement, endOfInit);
767 Builder.CreateICmpEQ(nextElement, end,
"arrayinit.done");
769 Builder.CreateCondBr(done, endBB, bodyBB);
770 currentElement->addIncoming(nextElement, Builder.GetInsertBlock());
783void AggExprEmitter::VisitMaterializeTemporaryExpr(
784 MaterializeTemporaryExpr *E) {
788void AggExprEmitter::VisitOpaqueValueExpr(OpaqueValueExpr *e) {
796void AggExprEmitter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
800 EmitAggLoadOfLValue(E);
804 AggValueSlot Slot = EnsureSlot(E->
getType());
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))
869 case CK_LValueToRValueBitCast: {
877 Address SourceAddress = SourceLV.getAddress().withElementType(CGF.
Int8Ty);
879 llvm::Value *SizeVal = llvm::ConstantInt::get(
882 Builder.CreateMemCpy(DestAddress, SourceAddress, SizeVal);
886 case CK_DerivedToBase: {
888 "Derived/Base casts in EmitAggExpr are only supported in HLSL");
899 AggValueSlot DestBaseSlot = Dest;
900 Dest = DerivedTmpSlot;
919 EmitCopy(E->
getType(), DestBaseSlot, SrcBaseSlot);
924 case CK_BaseToDerived:
925 case CK_UncheckedDerivedToBase: {
926 llvm_unreachable(
"cannot perform hierarchy conversion in EmitAggExpr: "
927 "should have been unpacked before we got here");
930 case CK_NonAtomicToAtomic:
931 case CK_AtomicToNonAtomic: {
932 bool isToAtomic = (E->
getCastKind() == CK_NonAtomicToAtomic);
936 QualType valueType = E->
getType();
942 valueType,
atomicType->castAs<AtomicType>()->getValueType()));
951 (isToAtomic ? CK_AtomicToNonAtomic : CK_NonAtomicToAtomic);
958 "peephole significantly changed types?");
965 AggValueSlot valueDest = Dest;
988 AggValueSlot atomicSlot =
994 return EmitFinalDestCopy(valueType, rvalue);
996 case CK_AddressSpaceConversion:
999 case CK_LValueToRValue:
1020 case CK_HLSLArrayRValue:
1027 case CK_HLSLAggregateSplatCast: {
1029 QualType SrcTy = Src->
getType();
1035 "RHS of HLSL splat cast must be a scalar.");
1040 case CK_HLSLElementwiseCast: {
1042 QualType SrcTy = Src->
getType();
1050 "HLSL Elementwise cast doesn't handle splatting.");
1054 "Can't perform HLSL Aggregate cast on a complex type.");
1062 case CK_UserDefinedConversion:
1063 case CK_ConstructorConversion:
1066 "Implicit cast types must be compatible");
1070 case CK_LValueBitCast:
1071 llvm_unreachable(
"should not be emitting lvalue bitcast as rvalue");
1075 case CK_ArrayToPointerDecay:
1076 case CK_FunctionToPointerDecay:
1077 case CK_NullToPointer:
1078 case CK_NullToMemberPointer:
1079 case CK_BaseToDerivedMemberPointer:
1080 case CK_DerivedToBaseMemberPointer:
1081 case CK_MemberPointerToBoolean:
1082 case CK_ReinterpretMemberPointer:
1083 case CK_IntegralToPointer:
1084 case CK_PointerToIntegral:
1085 case CK_PointerToBoolean:
1087 case CK_VectorSplat:
1088 case CK_IntegralCast:
1089 case CK_BooleanToSignedIntegral:
1090 case CK_IntegralToBoolean:
1091 case CK_IntegralToFloating:
1092 case CK_FloatingToIntegral:
1093 case CK_FloatingToBoolean:
1094 case CK_FloatingCast:
1095 case CK_CPointerToObjCPointerCast:
1096 case CK_BlockPointerToObjCPointerCast:
1097 case CK_AnyPointerToBlockPointerCast:
1098 case CK_ObjCObjectLValueCast:
1099 case CK_FloatingRealToComplex:
1100 case CK_FloatingComplexToReal:
1101 case CK_FloatingComplexToBoolean:
1102 case CK_FloatingComplexCast:
1103 case CK_FloatingComplexToIntegralComplex:
1104 case CK_IntegralRealToComplex:
1105 case CK_IntegralComplexToReal:
1106 case CK_IntegralComplexToBoolean:
1107 case CK_IntegralComplexCast:
1108 case CK_IntegralComplexToFloatingComplex:
1109 case CK_ARCProduceObject:
1110 case CK_ARCConsumeObject:
1111 case CK_ARCReclaimReturnedObject:
1112 case CK_ARCExtendBlockObject:
1113 case CK_CopyAndAutoreleaseBlockObject:
1114 case CK_BuiltinFnToFnPtr:
1115 case CK_ZeroToOCLOpaqueType:
1117 case CK_HLSLVectorTruncation:
1118 case CK_HLSLMatrixTruncation:
1119 case CK_IntToOCLSampler:
1120 case CK_FloatingToFixedPoint:
1121 case CK_FixedPointToFloating:
1122 case CK_FixedPointCast:
1123 case CK_FixedPointToBoolean:
1124 case CK_FixedPointToIntegral:
1125 case CK_IntegralToFixedPoint:
1126 llvm_unreachable(
"cast kind invalid for aggregate types");
1130void AggExprEmitter::VisitCallExpr(
const CallExpr *E) {
1132 EmitAggLoadOfLValue(E);
1136 withReturnValueSlot(
1137 E, [&](ReturnValueSlot Slot) {
return CGF.
EmitCallExpr(E, Slot); });
1140void AggExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
1141 withReturnValueSlot(E, [&](ReturnValueSlot Slot) {
1146void AggExprEmitter::VisitBinComma(
const BinaryOperator *E) {
1151void AggExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
1152 CodeGenFunction::StmtExprEvaluation eval(CGF);
1165 const char *NameSuffix =
"") {
1168 ArgTy = CT->getElementType();
1172 "member pointers may only be compared for equality");
1174 CGF, LHS, RHS, MPT,
false);
1178 struct CmpInstInfo {
1180 llvm::CmpInst::Predicate FCmp;
1181 llvm::CmpInst::Predicate SCmp;
1182 llvm::CmpInst::Predicate UCmp;
1184 CmpInstInfo InstInfo = [&]() -> CmpInstInfo {
1185 using FI = llvm::FCmpInst;
1186 using II = llvm::ICmpInst;
1189 return {
"cmp.lt", FI::FCMP_OLT, II::ICMP_SLT, II::ICMP_ULT};
1191 return {
"cmp.gt", FI::FCMP_OGT, II::ICMP_SGT, II::ICMP_UGT};
1193 return {
"cmp.eq", FI::FCMP_OEQ, II::ICMP_EQ, II::ICMP_EQ};
1195 llvm_unreachable(
"Unrecognised CompareKind enum");
1199 return Builder.CreateFCmp(InstInfo.FCmp, LHS, RHS,
1200 llvm::Twine(InstInfo.Name) + NameSuffix);
1204 return Builder.CreateICmp(Inst, LHS, RHS,
1205 llvm::Twine(InstInfo.Name) + NameSuffix);
1208 llvm_unreachable(
"unsupported aggregate binary expression should have "
1209 "already been handled");
1212void AggExprEmitter::EmitComparisonResult(
const Expr *E,
1213 const ComparisonCategoryInfo &CmpInfo,
1214 llvm::Value *ResultValue) {
1227void AggExprEmitter::VisitBinCmp(
const BinaryOperator *E) {
1228 using llvm::BasicBlock;
1229 using llvm::PHINode;
1233 const ComparisonCategoryInfo &CmpInfo =
1236 "cannot copy non-trivially copyable aggregate");
1248 auto EmitOperand = [&](Expr *E) -> std::pair<Value *, Value *> {
1257 auto LHSValues = EmitOperand(E->
getLHS()),
1258 RHSValues = EmitOperand(E->
getRHS());
1262 K, IsComplex ?
".r" :
"");
1267 RHSValues.second, K,
".i");
1268 return Builder.CreateAnd(
Cmp, CmpImag,
"and.eq");
1270 auto EmitCmpRes = [&](
const ComparisonCategoryInfo::ValueInfo *VInfo) {
1271 return Builder.getInt(VInfo->getIntValue());
1279 Builder.CreateSelect(EmitCmp(
CK_Less), EmitCmpRes(CmpInfo.
getLess()),
1281 Select = Builder.CreateSelect(EmitCmp(
CK_Equal),
1283 SelectOne,
"sel.eq");
1285 Value *SelectEq = Builder.CreateSelect(
1290 SelectEq,
"sel.gt");
1291 Select = Builder.CreateSelect(
1292 EmitCmp(
CK_Less), EmitCmpRes(CmpInfo.
getLess()), SelectGT,
"sel.lt");
1295 EmitComparisonResult(E, CmpInfo, Select);
1298void AggExprEmitter::VisitTypeTraitExpr(
const TypeTraitExpr *E) {
1300 "expected a strong_ordering type trait with a stored value");
1302 const ComparisonCategoryInfo &CmpInfo =
1306 llvm::Value *ResultValue =
1309 EmitComparisonResult(E, CmpInfo, ResultValue);
1312void AggExprEmitter::VisitBinaryOperator(
const BinaryOperator *E) {
1314 VisitPointerToDataMemberBinaryOperator(E);
1319void AggExprEmitter::VisitPointerToDataMemberBinaryOperator(
1320 const BinaryOperator *E) {
1322 EmitFinalDestCopy(E->
getType(), LV);
1332 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
1333 const VarDecl *var = dyn_cast<VarDecl>(DRE->getDecl());
1334 return (var && var->hasAttr<BlocksAttr>());
1343 if (op->isAssignmentOp() || op->isPtrMemOp())
1347 if (op->getOpcode() == BO_Comma)
1355 dyn_cast<AbstractConditionalOperator>(E)) {
1360 }
else if (
const OpaqueValueExpr *op = dyn_cast<OpaqueValueExpr>(E)) {
1361 if (
const Expr *src = op->getSourceExpr())
1368 }
else if (
const CastExpr *
cast = dyn_cast<CastExpr>(E)) {
1369 if (
cast->getCastKind() == CK_LValueToRValue)
1375 }
else if (
const UnaryOperator *uop = dyn_cast<UnaryOperator>(E)) {
1379 }
else if (
const MemberExpr *mem = dyn_cast<MemberExpr>(E)) {
1390void AggExprEmitter::VisitBinAssign(
const BinaryOperator *E) {
1396 "Invalid assignment");
1412 if (LHS.getType()->isAtomicType() ||
1431 if (LHS.getType()->isAtomicType() ||
1450 EmitFinalDestCopy(E->
getType(), LHS);
1458void AggExprEmitter::VisitAbstractConditionalOperator(
1459 const AbstractConditionalOperator *E) {
1465 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
1467 CodeGenFunction::ConditionalEvaluation eval(CGF);
1473 bool destructNonTrivialCStruct =
1474 !isExternallyDestructed &&
1476 isExternallyDestructed |= destructNonTrivialCStruct;
1485 assert(CGF.
HaveInsertPoint() &&
"expression evaluation ended with no IP!");
1486 CGF.
Builder.CreateBr(ContBlock);
1500 if (destructNonTrivialCStruct)
1507void AggExprEmitter::VisitChooseExpr(
const ChooseExpr *CE) {
1511void AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
1522void AggExprEmitter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
1534 if (!wasExternallyDestructed)
1538void AggExprEmitter::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
1539 AggValueSlot Slot = EnsureSlot(E->
getType());
1543void AggExprEmitter::VisitCXXInheritedCtorInitExpr(
1544 const CXXInheritedCtorInitExpr *E) {
1545 AggValueSlot Slot = EnsureSlot(E->
getType());
1551void AggExprEmitter::VisitLambdaExpr(
LambdaExpr *E) {
1552 AggValueSlot Slot = EnsureSlot(E->
getType());
1557 CodeGenFunction::CleanupDeactivationScope scope(CGF);
1562 i != e; ++i, ++CurField) {
1565 if (CurField->hasCapturedVLAType()) {
1570 EmitInitializationToLValue(*i, LV);
1574 CurField->getType().isDestructedType()) {
1575 assert(LV.isSimple());
1578 CurField->getType(),
1584void AggExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
1585 CodeGenFunction::RunCleanupsScope cleanups(CGF);
1589void AggExprEmitter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
1591 AggValueSlot Slot = EnsureSlot(
T);
1595void AggExprEmitter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
1597 AggValueSlot Slot = EnsureSlot(
T);
1608 case CK_UserDefinedConversion:
1609 case CK_ConstructorConversion:
1615 case CK_BooleanToSignedIntegral:
1616 case CK_FloatingCast:
1617 case CK_FloatingComplexCast:
1618 case CK_FloatingComplexToBoolean:
1619 case CK_FloatingComplexToIntegralComplex:
1620 case CK_FloatingComplexToReal:
1621 case CK_FloatingRealToComplex:
1622 case CK_FloatingToBoolean:
1623 case CK_FloatingToIntegral:
1624 case CK_IntegralCast:
1625 case CK_IntegralComplexCast:
1626 case CK_IntegralComplexToBoolean:
1627 case CK_IntegralComplexToFloatingComplex:
1628 case CK_IntegralComplexToReal:
1629 case CK_IntegralRealToComplex:
1630 case CK_IntegralToBoolean:
1631 case CK_IntegralToFloating:
1633 case CK_IntegralToPointer:
1634 case CK_PointerToIntegral:
1636 case CK_VectorSplat:
1638 case CK_NonAtomicToAtomic:
1639 case CK_AtomicToNonAtomic:
1640 case CK_HLSLVectorTruncation:
1641 case CK_HLSLMatrixTruncation:
1642 case CK_HLSLElementwiseCast:
1643 case CK_HLSLAggregateSplatCast:
1646 case CK_BaseToDerivedMemberPointer:
1647 case CK_DerivedToBaseMemberPointer:
1648 case CK_MemberPointerToBoolean:
1649 case CK_NullToMemberPointer:
1650 case CK_ReinterpretMemberPointer:
1654 case CK_AnyPointerToBlockPointerCast:
1655 case CK_BlockPointerToObjCPointerCast:
1656 case CK_CPointerToObjCPointerCast:
1657 case CK_ObjCObjectLValueCast:
1658 case CK_IntToOCLSampler:
1659 case CK_ZeroToOCLOpaqueType:
1663 case CK_FixedPointCast:
1664 case CK_FixedPointToBoolean:
1665 case CK_FixedPointToFloating:
1666 case CK_FixedPointToIntegral:
1667 case CK_FloatingToFixedPoint:
1668 case CK_IntegralToFixedPoint:
1672 case CK_AddressSpaceConversion:
1673 case CK_BaseToDerived:
1674 case CK_DerivedToBase:
1676 case CK_NullToPointer:
1677 case CK_PointerToBoolean:
1682 case CK_ARCConsumeObject:
1683 case CK_ARCExtendBlockObject:
1684 case CK_ARCProduceObject:
1685 case CK_ARCReclaimReturnedObject:
1686 case CK_CopyAndAutoreleaseBlockObject:
1687 case CK_ArrayToPointerDecay:
1688 case CK_FunctionToPointerDecay:
1689 case CK_BuiltinFnToFnPtr:
1691 case CK_LValueBitCast:
1692 case CK_LValueToRValue:
1693 case CK_LValueToRValueBitCast:
1694 case CK_UncheckedDerivedToBase:
1695 case CK_HLSLArrayRValue:
1698 llvm_unreachable(
"Unhandled clang::CastKind enum");
1706 while (
auto *CE = dyn_cast<CastExpr>(E)) {
1714 return IL->getValue() == 0;
1717 return FL->getValue().isPosZero();
1723 if (
const CastExpr *ICE = dyn_cast<CastExpr>(E))
1724 return ICE->getCastKind() == CK_NullToPointer &&
1729 return CL->getValue() == 0;
1735void AggExprEmitter::EmitInitializationToLValue(Expr *E, LValue LV) {
1736 QualType
type = LV.getType();
1743 return EmitNullInitializationToLValue(LV);
1747 }
else if (
type->isReferenceType()) {
1755void AggExprEmitter::EmitNullInitializationToLValue(LValue lv) {
1756 QualType
type = lv.getType();
1768 if (lv.isBitField()) {
1771 assert(lv.isSimple());
1782void AggExprEmitter::VisitCXXParenListInitExpr(CXXParenListInitExpr *E) {
1788void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
1795 VisitCXXParenListOrInitListExpr(
1799void AggExprEmitter::VisitCXXParenListOrInitListExpr(
1800 Expr *ExprToVisit, ArrayRef<Expr *> InitExprs,
1801 FieldDecl *InitializedFieldInUnion, Expr *ArrayFiller) {
1808 if (llvm::Constant *
C =
1809 CGF.
CGM.EmitConstantExpr(ExprToVisit, ExprToVisit->
getType(), &CGF)) {
1810 llvm::GlobalVariable* GV =
1811 new llvm::GlobalVariable(CGF.
CGM.
getModule(),
C->getType(),
true,
1812 llvm::GlobalValue::InternalLinkage,
C,
"");
1813 EmitFinalDestCopy(ExprToVisit->
getType(),
1831 AggValueSlot Dest = EnsureSlot(ExprToVisit->
getType());
1839 InitExprs, ArrayFiller);
1845 assert(InitExprs.size() == 0 &&
1846 "you can only use an empty initializer with VLAs");
1852 "Only support structs/unions here!");
1858 unsigned NumInitElements = InitExprs.size();
1863 CodeGenFunction::CleanupDeactivationScope DeactivateCleanups(CGF);
1865 unsigned curInitIndex = 0;
1868 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(record)) {
1869 assert(NumInitElements >= CXXRD->getNumBases() &&
1870 "missing initializer for base class");
1871 for (
auto &Base : CXXRD->bases()) {
1872 assert(!
Base.isVirtual() &&
"should not see vbases here");
1873 auto *BaseRD =
Base.getType()->getAsCXXRecordDecl();
1881 CGF.
EmitAggExpr(InitExprs[curInitIndex++], AggSlot);
1884 Base.getType().isDestructedType())
1890 CodeGenFunction::FieldConstructionScope FCS(CGF, Dest.
getAddress());
1892 const bool ZeroInitPadding =
1898 if (!InitializedFieldInUnion) {
1904 for (
const auto *Field : record->
fields())
1906 (
Field->isUnnamedBitField() ||
Field->isAnonymousStructOrUnion()) &&
1907 "Only unnamed bitfields or anonymous class allowed");
1913 FieldDecl *
Field = InitializedFieldInUnion;
1916 if (NumInitElements) {
1918 EmitInitializationToLValue(InitExprs[0], FieldLoc);
1919 if (ZeroInitPadding) {
1923 DoZeroInitPadding(FieldSize, TotalSize,
nullptr);
1927 if (ZeroInitPadding)
1928 EmitNullInitializationToLValue(DestLV);
1930 EmitNullInitializationToLValue(FieldLoc);
1940 for (
const auto *field : record->
fields()) {
1942 if (field->getType()->isIncompleteArrayType())
1946 if (field->isUnnamedBitField())
1952 if (curInitIndex == NumInitElements && Dest.
isZeroed() &&
1956 if (ZeroInitPadding)
1957 DoZeroInitPadding(PaddingStart,
1964 if (curInitIndex < NumInitElements) {
1966 EmitInitializationToLValue(InitExprs[curInitIndex++], LV);
1969 EmitNullInitializationToLValue(LV);
1976 field->getType().isDestructedType()) {
1977 assert(LV.isSimple());
1985 if (ZeroInitPadding) {
1988 DoZeroInitPadding(PaddingStart, TotalSize,
nullptr);
1992void AggExprEmitter::DoZeroInitPadding(uint64_t &PaddingStart,
1993 uint64_t PaddingEnd,
1994 const FieldDecl *NextField) {
2002 llvm::Constant *SizeVal = Builder.getInt64((End - Start).getQuantity());
2006 if (NextField !=
nullptr && NextField->
isBitField()) {
2009 const CGRecordLayout &RL =
2013 if (StorageStart + Info.
StorageSize > PaddingStart) {
2014 if (StorageStart > PaddingStart)
2015 InitBytes(PaddingStart, StorageStart);
2028 if (PaddingStart < PaddingEnd)
2029 InitBytes(PaddingStart, PaddingEnd);
2030 if (NextField !=
nullptr)
2035void AggExprEmitter::VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E,
2036 llvm::Value *outerBegin) {
2038 CodeGenFunction::OpaqueValueMapping binding(CGF, E->
getCommonExpr());
2047 llvm::Value *zero = llvm::ConstantInt::get(CGF.
SizeTy, 0);
2048 llvm::Value *indices[] = {zero, zero};
2049 llvm::Value *begin = Builder.CreateInBoundsGEP(destPtr.
getElementType(),
2051 indices,
"arrayinit.begin");
2057 ArrayInitLoopExpr *InnerLoop = dyn_cast<ArrayInitLoopExpr>(E->
getSubExpr());
2059 QualType elementType =
2062 CharUnits elementAlign =
2066 llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
2071 llvm::PHINode *index =
2072 Builder.CreatePHI(zero->getType(), 2,
"arrayinit.index");
2073 index->addIncoming(zero, entryBB);
2074 llvm::Value *element =
2075 Builder.CreateInBoundsGEP(llvmElementType, begin, index);
2082 EHScopeStack::stable_iterator
cleanup;
2084 if (outerBegin->getType() != element->getType())
2085 outerBegin = Builder.CreateBitCast(outerBegin, element->getType());
2098 CodeGenFunction::RunCleanupsScope CleanupsScope(CGF);
2099 CodeGenFunction::ArrayInitLoopExprScope Scope(CGF, index);
2101 Address(element, llvmElementType, elementAlign), elementType);
2109 AggExprEmitter(CGF, elementSlot,
false)
2110 .VisitArrayInitLoopExpr(InnerLoop, outerBegin);
2112 EmitInitializationToLValue(E->
getSubExpr(), elementLV);
2116 llvm::Value *nextIndex = Builder.CreateNUWAdd(
2117 index, llvm::ConstantInt::get(CGF.
SizeTy, 1),
"arrayinit.next");
2118 index->addIncoming(nextIndex, Builder.GetInsertBlock());
2121 llvm::Value *done = Builder.CreateICmpEQ(
2122 nextIndex, llvm::ConstantInt::get(CGF.
SizeTy, numElements),
2125 Builder.CreateCondBr(done, endBB, bodyBB);
2137void AggExprEmitter::VisitDesignatedInitUpdateExpr(
2138 DesignatedInitUpdateExpr *E) {
2139 AggValueSlot Dest = EnsureSlot(E->
getType());
2142 EmitInitializationToLValue(E->
getBase(), DestLV);
2154 if (
auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
2155 E = MTE->getSubExpr();
2166 ILE = dyn_cast<InitListExpr>(ILE->
getInit(0));
2174 if (!RT->isUnionType()) {
2178 unsigned ILEElement = 0;
2179 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(SD))
2180 while (ILEElement != CXXRD->getNumBases())
2183 for (
const auto *Field : SD->
fields()) {
2186 if (Field->getType()->isIncompleteArrayType() ||
2189 if (Field->isUnnamedBitField())
2195 if (Field->getType()->isReferenceType())
2202 return NumNonZeroBytes;
2208 for (
unsigned i = 0, e = ILE->
getNumInits(); i != e; ++i)
2210 return NumNonZeroBytes;
2241 if (NumNonZeroBytes * 4 > Size)
2245 llvm::Constant *SizeVal = CGF.
Builder.getInt64(Size.getQuantity());
2260 "Invalid aggregate expression to emit");
2262 "slot has bits but no address");
2267 AggExprEmitter(*
this, Slot, Slot.
isIgnored()).Visit(
const_cast<Expr *
>(E));
2284 return AggExprEmitter(*
this, Dest, Dest.
isIgnored())
2285 .EmitFinalDestCopy(
Type, Src, SrcKind);
2328 getContext().getASTRecordLayout(BaseRD).getSize() <=
2346 assert((
Record->hasTrivialCopyConstructor() ||
2347 Record->hasTrivialCopyAssignment() ||
2348 Record->hasTrivialMoveConstructor() ||
2349 Record->hasTrivialMoveAssignment() ||
2350 Record->hasAttr<TrivialABIAttr>() ||
Record->isUnion() ||
2353 "Trying to aggregate-copy a type without a trivial copy/move "
2354 "constructor or assignment operator");
2363 if (
getTargetHooks().emitCUDADeviceBuiltinSurfaceDeviceCopy(*
this, Dest,
2367 if (
getTargetHooks().emitCUDADeviceBuiltinTextureDeviceCopy(*
this, Dest,
2374 "copies of aggregates in hlsl_constant address space should be "
2375 "handled earlier by the HLSL runtime");
2397 llvm::Value *SizeVal =
nullptr;
2400 if (
auto *VAT = dyn_cast_or_null<VariableArrayType>(
2406 SizeVal =
Builder.CreateNUWMul(
2435 if (
Record->hasObjectMember()) {
2436 CGM.getObjCRuntime().EmitGCMemmoveCollectable(*
this, DestPtr, SrcPtr,
2442 if (
const auto *
Record = BaseType->getAsRecordDecl()) {
2443 if (
Record->hasObjectMember()) {
2444 CGM.getObjCRuntime().EmitGCMemmoveCollectable(*
this, DestPtr, SrcPtr,
2451 auto *Inst =
Builder.CreateMemCpy(DestPtr, SrcPtr, SizeVal, isVolatile);
2458 if (llvm::MDNode *TBAAStructTag =
CGM.getTBAAStructInfo(Ty))
2459 Inst->setMetadata(llvm::LLVMContext::MD_tbaa_struct, TBAAStructTag);
2461 if (
CGM.getCodeGenOpts().NewStructPathTBAA) {
2464 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.
Result
Implement __builtin_bit_cast and related operations.
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...
path_iterator path_begin()
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.
bool emitBufferCopy(CodeGenFunction &CGF, const Expr *E, const LValue &SrcLV, AggValueSlot &DestSlot)
bool emitGlobalResourceArray(CodeGenFunction &CGF, const Expr *E, AggValueSlot &DestSlot)
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.
Address GetAddressOfBaseClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue, SourceLocation Loc)
GetAddressOfBaseClass - This function will add the necessary delta to the load of 'this' and returns ...
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)
SmallVector< llvm::ConvergenceControlInst *, 4 > ConvergenceTokenStack
Stack to track the controlled convergence tokens.
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.
llvm::ConvergenceControlInst * emitConvergenceLoopToken(llvm::BasicBlock *BB)
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...
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.
bool shouldEmitConvergenceTokens() const
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 * getValueInfo(ComparisonCategoryResult ValueKind) const
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.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to 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.
bool isStoredAsComparisonResult() const
const APValue & getAPValue() const
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.
CXXRecordDecl * castAsCXXRecordDecl() const
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
bool isHLSLResourceRecordArray() 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)
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
@ Result
The result type of a method or function.
const FunctionProtoType * T
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
llvm::APSInt getIntValue() const
Get the constant integer value used by this variable to represent the comparison category result type...