26#include "llvm/ADT/STLExtras.h"
27#include "llvm/ADT/Sequence.h"
28#include "llvm/IR/Constants.h"
29#include "llvm/IR/DataLayout.h"
30#include "llvm/IR/Function.h"
31#include "llvm/IR/GlobalVariable.h"
34using namespace CodeGen;
41class ConstExprEmitter;
43struct ConstantAggregateBuilderUtils {
46 ConstantAggregateBuilderUtils(
CodeGenModule &CGM) : CGM(CGM) {}
48 CharUnits getAlignment(
const llvm::Constant *
C)
const {
57 CharUnits getSize(
const llvm::Constant *
C)
const {
58 return getSize(
C->getType());
61 llvm::Constant *getPadding(
CharUnits PadSize)
const {
62 llvm::Type *Ty = CGM.
CharTy;
64 Ty = llvm::ArrayType::get(Ty, PadSize.
getQuantity());
65 return llvm::UndefValue::get(Ty);
68 llvm::Constant *getZeroes(
CharUnits ZeroSize)
const {
70 return llvm::ConstantAggregateZero::get(Ty);
76class ConstantAggregateBuilder :
private ConstantAggregateBuilderUtils {
95 bool NaturalLayout =
true;
98 std::optional<size_t> splitAt(
CharUnits Pos);
104 bool NaturalLayout, llvm::Type *DesiredTy,
105 bool AllowOversized);
109 : ConstantAggregateBuilderUtils(CGM) {}
119 bool addBits(llvm::APInt Bits, uint64_t OffsetInBits,
bool AllowOverwrite);
130 llvm::Constant *build(llvm::Type *DesiredTy,
bool AllowOversized)
const {
132 NaturalLayout, DesiredTy, AllowOversized);
136template<
typename Container,
typename Range = std::initializer_list<
137 typename Container::value_type>>
138static void replace(Container &
C,
size_t BeginOff,
size_t EndOff, Range Vals) {
139 assert(BeginOff <= EndOff &&
"invalid replacement range");
140 llvm::replace(
C,
C.begin() + BeginOff,
C.begin() + EndOff, Vals);
144 bool AllowOverwrite) {
150 NaturalLayout =
false;
151 else if (AlignedSize <
Offset) {
152 Elems.push_back(getPadding(
Offset - Size));
153 Offsets.push_back(Size);
156 Offsets.push_back(
Offset);
162 std::optional<size_t> FirstElemToReplace = splitAt(
Offset);
163 if (!FirstElemToReplace)
167 std::optional<size_t> LastElemToReplace = splitAt(
Offset + CSize);
168 if (!LastElemToReplace)
171 assert((FirstElemToReplace == LastElemToReplace || AllowOverwrite) &&
172 "unexpectedly overwriting field");
174 replace(Elems, *FirstElemToReplace, *LastElemToReplace, {
C});
175 replace(Offsets, *FirstElemToReplace, *LastElemToReplace, {
Offset});
177 NaturalLayout =
false;
181bool ConstantAggregateBuilder::addBits(llvm::APInt Bits, uint64_t OffsetInBits,
182 bool AllowOverwrite) {
188 unsigned OffsetWithinChar = OffsetInBits % CharWidth;
196 unsigned WantedBits =
197 std::min((uint64_t)Bits.getBitWidth(), CharWidth - OffsetWithinChar);
201 llvm::APInt BitsThisChar = Bits;
202 if (BitsThisChar.getBitWidth() < CharWidth)
203 BitsThisChar = BitsThisChar.zext(CharWidth);
207 int Shift = Bits.getBitWidth() - CharWidth + OffsetWithinChar;
209 BitsThisChar.lshrInPlace(Shift);
211 BitsThisChar = BitsThisChar.shl(-Shift);
213 BitsThisChar = BitsThisChar.shl(OffsetWithinChar);
215 if (BitsThisChar.getBitWidth() > CharWidth)
216 BitsThisChar = BitsThisChar.trunc(CharWidth);
218 if (WantedBits == CharWidth) {
221 OffsetInChars, AllowOverwrite);
226 std::optional<size_t> FirstElemToUpdate = splitAt(OffsetInChars);
227 if (!FirstElemToUpdate)
229 std::optional<size_t> LastElemToUpdate =
231 if (!LastElemToUpdate)
233 assert(*LastElemToUpdate - *FirstElemToUpdate < 2 &&
234 "should have at most one element covering one byte");
237 llvm::APInt UpdateMask(CharWidth, 0);
239 UpdateMask.setBits(CharWidth - OffsetWithinChar - WantedBits,
240 CharWidth - OffsetWithinChar);
242 UpdateMask.setBits(OffsetWithinChar, OffsetWithinChar + WantedBits);
243 BitsThisChar &= UpdateMask;
245 if (*FirstElemToUpdate == *LastElemToUpdate ||
246 Elems[*FirstElemToUpdate]->isNullValue() ||
247 isa<llvm::UndefValue>(Elems[*FirstElemToUpdate])) {
250 OffsetInChars,
true);
252 llvm::Constant *&ToUpdate = Elems[*FirstElemToUpdate];
255 auto *CI = dyn_cast<llvm::ConstantInt>(ToUpdate);
260 assert(CI->getBitWidth() == CharWidth &&
"splitAt failed");
261 assert((!(CI->getValue() & UpdateMask) || AllowOverwrite) &&
262 "unexpectedly overwriting bitfield");
263 BitsThisChar |= (CI->getValue() & ~UpdateMask);
264 ToUpdate = llvm::ConstantInt::get(CGM.
getLLVMContext(), BitsThisChar);
269 if (WantedBits == Bits.getBitWidth())
274 Bits.lshrInPlace(WantedBits);
275 Bits = Bits.trunc(Bits.getBitWidth() - WantedBits);
278 OffsetWithinChar = 0;
288std::optional<size_t> ConstantAggregateBuilder::splitAt(
CharUnits Pos) {
290 return Offsets.size();
293 auto FirstAfterPos = llvm::upper_bound(Offsets, Pos);
294 if (FirstAfterPos == Offsets.begin())
298 size_t LastAtOrBeforePosIndex = FirstAfterPos - Offsets.begin() - 1;
299 if (Offsets[LastAtOrBeforePosIndex] == Pos)
300 return LastAtOrBeforePosIndex;
303 if (Offsets[LastAtOrBeforePosIndex] +
304 getSize(Elems[LastAtOrBeforePosIndex]) <= Pos)
305 return LastAtOrBeforePosIndex + 1;
308 if (!split(LastAtOrBeforePosIndex, Pos))
316bool ConstantAggregateBuilder::split(
size_t Index,
CharUnits Hint) {
317 NaturalLayout =
false;
318 llvm::Constant *
C = Elems[Index];
321 if (
auto *CA = dyn_cast<llvm::ConstantAggregate>(
C)) {
324 replace(Elems, Index, Index + 1,
325 llvm::map_range(llvm::seq(0u, CA->getNumOperands()),
326 [&](
unsigned Op) { return CA->getOperand(Op); }));
327 if (isa<llvm::ArrayType>(CA->getType()) ||
328 isa<llvm::VectorType>(CA->getType())) {
331 llvm::GetElementPtrInst::getTypeAtIndex(CA->getType(), (uint64_t)0);
334 Offsets, Index, Index + 1,
335 llvm::map_range(llvm::seq(0u, CA->getNumOperands()),
336 [&](
unsigned Op) { return Offset + Op * ElemSize; }));
339 auto *ST = cast<llvm::StructType>(CA->getType());
340 const llvm::StructLayout *Layout =
342 replace(Offsets, Index, Index + 1,
344 llvm::seq(0u, CA->getNumOperands()), [&](
unsigned Op) {
345 return Offset + CharUnits::fromQuantity(
346 Layout->getElementOffset(Op));
352 if (
auto *CDS = dyn_cast<llvm::ConstantDataSequential>(
C)) {
356 CharUnits ElemSize = getSize(CDS->getElementType());
357 replace(Elems, Index, Index + 1,
358 llvm::map_range(llvm::seq(0u, CDS->getNumElements()),
360 return CDS->getElementAsConstant(Elem);
362 replace(Offsets, Index, Index + 1,
364 llvm::seq(0u, CDS->getNumElements()),
365 [&](
unsigned Elem) { return Offset + Elem * ElemSize; }));
369 if (isa<llvm::ConstantAggregateZero>(
C)) {
372 assert(Hint >
Offset && Hint <
Offset + ElemSize &&
"nothing to split");
373 replace(Elems, Index, Index + 1,
374 {getZeroes(Hint -
Offset), getZeroes(
Offset + ElemSize - Hint)});
375 replace(Offsets, Index, Index + 1, {
Offset, Hint});
379 if (isa<llvm::UndefValue>(
C)) {
381 replace(Elems, Index, Index + 1, {});
382 replace(Offsets, Index, Index + 1, {});
393static llvm::Constant *
394EmitArrayConstant(
CodeGenModule &CGM, llvm::ArrayType *DesiredType,
395 llvm::Type *CommonElementType,
unsigned ArrayBound,
397 llvm::Constant *Filler);
399llvm::Constant *ConstantAggregateBuilder::buildFrom(
402 bool NaturalLayout, llvm::Type *DesiredTy,
bool AllowOversized) {
403 ConstantAggregateBuilderUtils Utils(CGM);
406 return llvm::UndefValue::get(DesiredTy);
408 auto Offset = [&](
size_t I) {
return Offsets[I] - StartOffset; };
412 if (llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(DesiredTy)) {
413 assert(!AllowOversized &&
"oversized array emission not supported");
415 bool CanEmitArray =
true;
416 llvm::Type *CommonType = Elems[0]->getType();
417 llvm::Constant *Filler = llvm::Constant::getNullValue(CommonType);
418 CharUnits ElemSize = Utils.getSize(ATy->getElementType());
420 for (
size_t I = 0; I != Elems.size(); ++I) {
422 if (Elems[I]->isNullValue())
426 if (Elems[I]->getType() != CommonType ||
427 Offset(I) % ElemSize != 0) {
428 CanEmitArray =
false;
431 ArrayElements.resize(
Offset(I) / ElemSize + 1, Filler);
432 ArrayElements.back() = Elems[I];
436 return EmitArrayConstant(CGM, ATy, CommonType, ATy->getNumElements(),
437 ArrayElements, Filler);
446 CharUnits DesiredSize = Utils.getSize(DesiredTy);
447 if (Size > DesiredSize) {
448 assert(AllowOversized &&
"Elems are oversized");
454 for (llvm::Constant *
C : Elems)
455 Align = std::max(Align, Utils.getAlignment(
C));
463 if (DesiredSize < AlignedSize || DesiredSize.
alignTo(Align) != DesiredSize) {
465 NaturalLayout =
false;
467 }
else if (DesiredSize > AlignedSize) {
470 UnpackedElemStorage.assign(Elems.begin(), Elems.end());
471 UnpackedElemStorage.push_back(Utils.getPadding(DesiredSize - Size));
472 UnpackedElems = UnpackedElemStorage;
479 if (!NaturalLayout) {
481 for (
size_t I = 0; I != Elems.size(); ++I) {
482 CharUnits Align = Utils.getAlignment(Elems[I]);
485 assert(DesiredOffset >= SizeSoFar &&
"elements out of order");
487 if (DesiredOffset != NaturalOffset)
489 if (DesiredOffset != SizeSoFar)
490 PackedElems.push_back(Utils.getPadding(DesiredOffset - SizeSoFar));
491 PackedElems.push_back(Elems[I]);
492 SizeSoFar = DesiredOffset + Utils.getSize(Elems[I]);
497 assert(SizeSoFar <= DesiredSize &&
498 "requested size is too small for contents");
499 if (SizeSoFar < DesiredSize)
500 PackedElems.push_back(Utils.getPadding(DesiredSize - SizeSoFar));
504 llvm::StructType *STy = llvm::ConstantStruct::getTypeForElements(
505 CGM.
getLLVMContext(), Packed ? PackedElems : UnpackedElems, Packed);
509 if (llvm::StructType *DesiredSTy = dyn_cast<llvm::StructType>(DesiredTy)) {
510 if (DesiredSTy->isLayoutIdentical(STy))
514 return llvm::ConstantStruct::get(STy, Packed ? PackedElems : UnpackedElems);
518 llvm::Type *DesiredTy) {
521 std::optional<size_t> FirstElemToReplace = splitAt(
Offset);
522 if (!FirstElemToReplace)
524 size_t First = *FirstElemToReplace;
526 std::optional<size_t> LastElemToReplace = splitAt(
Offset + Size);
527 if (!LastElemToReplace)
529 size_t Last = *LastElemToReplace;
536 getSize(Elems[
First]) == Size) {
539 auto *STy = dyn_cast<llvm::StructType>(DesiredTy);
540 if (STy && STy->getNumElements() == 1 &&
541 STy->getElementType(0) == Elems[
First]->getType())
542 Elems[
First] = llvm::ConstantStruct::get(STy, Elems[
First]);
546 llvm::Constant *Replacement = buildFrom(
549 false, DesiredTy,
false);
550 replace(Elems,
First,
Last, {Replacement});
558class ConstStructBuilder {
561 ConstantAggregateBuilder &Builder;
575 ConstantAggregateBuilder &Builder,
CharUnits StartOffset)
577 StartOffset(StartOffset) {}
579 bool AppendField(
const FieldDecl *Field, uint64_t FieldOffset,
580 llvm::Constant *InitExpr,
bool AllowOverwrite =
false);
582 bool AppendBytes(
CharUnits FieldOffsetInChars, llvm::Constant *InitCst,
583 bool AllowOverwrite =
false);
585 bool AppendBitField(
const FieldDecl *Field, uint64_t FieldOffset,
586 llvm::ConstantInt *InitExpr,
bool AllowOverwrite =
false);
591 llvm::Constant *Finalize(
QualType Ty);
594bool ConstStructBuilder::AppendField(
595 const FieldDecl *Field, uint64_t FieldOffset, llvm::Constant *InitCst,
596 bool AllowOverwrite) {
601 return AppendBytes(FieldOffsetInChars, InitCst, AllowOverwrite);
604bool ConstStructBuilder::AppendBytes(
CharUnits FieldOffsetInChars,
605 llvm::Constant *InitCst,
606 bool AllowOverwrite) {
607 return Builder.add(InitCst, StartOffset + FieldOffsetInChars, AllowOverwrite);
610bool ConstStructBuilder::AppendBitField(
611 const FieldDecl *Field, uint64_t FieldOffset, llvm::ConstantInt *CI,
612 bool AllowOverwrite) {
616 llvm::APInt FieldValue = CI->getValue();
622 if (Info.
Size > FieldValue.getBitWidth())
623 FieldValue = FieldValue.zext(Info.
Size);
626 if (Info.
Size < FieldValue.getBitWidth())
627 FieldValue = FieldValue.trunc(Info.
Size);
629 return Builder.addBits(FieldValue,
635 ConstantAggregateBuilder &Const,
639 return ConstStructBuilder::UpdateStruct(
Emitter, Const,
Offset, Updater);
641 auto CAT =
Emitter.CGM.getContext().getAsConstantArrayType(
Type);
644 QualType ElemType = CAT->getElementType();
646 llvm::Type *ElemTy =
Emitter.CGM.getTypes().ConvertTypeForMem(ElemType);
648 llvm::Constant *FillC =
nullptr;
650 if (!isa<NoInitExpr>(Filler)) {
651 FillC =
Emitter.tryEmitAbstractForMemory(Filler, ElemType);
657 unsigned NumElementsToUpdate =
658 FillC ? CAT->getSize().getZExtValue() : Updater->
getNumInits();
659 for (
unsigned I = 0; I != NumElementsToUpdate; ++I,
Offset += ElemSize) {
660 Expr *Init =
nullptr;
661 if (I < Updater->getNumInits())
664 if (!Init && FillC) {
667 }
else if (!Init || isa<NoInitExpr>(Init)) {
669 }
else if (
InitListExpr *ChildILE = dyn_cast<InitListExpr>(Init)) {
670 if (!EmitDesignatedInitUpdater(
Emitter, Const,
Offset, ElemType,
676 llvm::Constant *Val =
Emitter.tryEmitPrivateForMemory(Init, ElemType);
685bool ConstStructBuilder::Build(
InitListExpr *ILE,
bool AllowOverwrite) {
689 unsigned FieldNo = -1;
690 unsigned ElementNo = 0;
695 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
696 if (CXXRD->getNumBases())
708 if (
Field->isUnnamedBitfield())
713 Expr *Init =
nullptr;
714 if (ElementNo < ILE->getNumInits())
715 Init = ILE->
getInit(ElementNo++);
716 if (Init && isa<NoInitExpr>(Init))
730 if (AllowOverwrite &&
731 (
Field->getType()->isArrayType() ||
Field->getType()->isRecordType())) {
732 if (
auto *SubILE = dyn_cast<InitListExpr>(Init)) {
735 if (!EmitDesignatedInitUpdater(
Emitter, Builder, StartOffset +
Offset,
736 Field->getType(), SubILE))
740 Builder.condense(StartOffset +
Offset,
746 llvm::Constant *EltInit =
747 Init ?
Emitter.tryEmitPrivateForMemory(Init,
Field->getType())
752 if (!
Field->isBitField()) {
759 if (
Field->hasAttr<NoUniqueAddressAttr>())
760 AllowOverwrite =
true;
763 if (
auto *CI = dyn_cast<llvm::ConstantInt>(EltInit)) {
801 llvm::Constant *VTableAddressPoint =
804 if (!AppendBytes(
Offset, VTableAddressPoint))
811 Bases.reserve(CD->getNumBases());
814 BaseEnd = CD->bases_end();
Base != BaseEnd; ++
Base, ++BaseNo) {
815 assert(!
Base->isVirtual() &&
"should not have virtual bases here");
818 Bases.push_back(BaseInfo(BD, BaseOffset, BaseNo));
820 llvm::stable_sort(Bases);
822 for (
unsigned I = 0, N = Bases.size(); I != N; ++I) {
823 BaseInfo &
Base = Bases[I];
831 unsigned FieldNo = 0;
834 bool AllowOverwrite =
false;
836 FieldEnd = RD->
field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
848 llvm::Constant *EltInit =
849 Emitter.tryEmitPrivateForMemory(FieldValue,
Field->getType());
853 if (!
Field->isBitField()) {
855 if (!AppendField(*Field, Layout.
getFieldOffset(FieldNo) + OffsetBits,
856 EltInit, AllowOverwrite))
860 if (
Field->hasAttr<NoUniqueAddressAttr>())
861 AllowOverwrite =
true;
864 if (!AppendBitField(*Field, Layout.
getFieldOffset(FieldNo) + OffsetBits,
865 cast<llvm::ConstantInt>(EltInit), AllowOverwrite))
873llvm::Constant *ConstStructBuilder::Finalize(
QualType Type) {
886 if (!Builder.Build(ILE,
false))
889 return Builder.Finalize(ValTy);
903 return Builder.Finalize(ValTy);
907 ConstantAggregateBuilder &Const,
910 .Build(Updater,
true);
922 if (llvm::GlobalVariable *Addr =
931 "file-scope compound literal did not have constant initializer!");
935 auto GV =
new llvm::GlobalVariable(
938 llvm::GlobalValue::InternalLinkage,
C,
".compoundliteral",
nullptr,
939 llvm::GlobalVariable::NotThreadLocal,
947static llvm::Constant *
948EmitArrayConstant(
CodeGenModule &CGM, llvm::ArrayType *DesiredType,
949 llvm::Type *CommonElementType,
unsigned ArrayBound,
951 llvm::Constant *Filler) {
953 unsigned NonzeroLength = ArrayBound;
954 if (Elements.size() < NonzeroLength && Filler->isNullValue())
955 NonzeroLength = Elements.size();
956 if (NonzeroLength == Elements.size()) {
957 while (NonzeroLength > 0 && Elements[NonzeroLength - 1]->isNullValue())
961 if (NonzeroLength == 0)
962 return llvm::ConstantAggregateZero::get(DesiredType);
965 unsigned TrailingZeroes = ArrayBound - NonzeroLength;
966 if (TrailingZeroes >= 8) {
967 assert(Elements.size() >= NonzeroLength &&
968 "missing initializer for non-zero element");
972 if (CommonElementType && NonzeroLength >= 8) {
973 llvm::Constant *Initial = llvm::ConstantArray::get(
974 llvm::ArrayType::get(CommonElementType, NonzeroLength),
975 ArrayRef(Elements).take_front(NonzeroLength));
977 Elements[0] = Initial;
979 Elements.resize(NonzeroLength + 1);
983 CommonElementType ? CommonElementType : DesiredType->getElementType();
984 FillerType = llvm::ArrayType::get(FillerType, TrailingZeroes);
985 Elements.back() = llvm::ConstantAggregateZero::get(FillerType);
986 CommonElementType =
nullptr;
987 }
else if (Elements.size() != ArrayBound) {
989 Elements.resize(ArrayBound, Filler);
990 if (Filler->getType() != CommonElementType)
991 CommonElementType =
nullptr;
995 if (CommonElementType)
996 return llvm::ConstantArray::get(
997 llvm::ArrayType::get(CommonElementType, ArrayBound), Elements);
1001 Types.reserve(Elements.size());
1002 for (llvm::Constant *Elt : Elements)
1003 Types.push_back(Elt->getType());
1004 llvm::StructType *SType =
1006 return llvm::ConstantStruct::get(SType, Elements);
1015class ConstExprEmitter :
1016 public StmtVisitor<ConstExprEmitter, llvm::Constant*, QualType> {
1019 llvm::LLVMContext &VMContext;
1022 : CGM(emitter.CGM),
Emitter(emitter), VMContext(CGM.getLLVMContext()) {
1034 if (llvm::Constant *Result =
Emitter.tryEmitConstantExpr(CE))
1051 return Visit(
GE->getResultExpr(), T);
1063 if (
const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
1071 "Destination type is not union type!");
1075 auto C =
Emitter.tryEmitPrivateForMemory(subExpr, field->getType());
1076 if (!
C)
return nullptr;
1078 auto destTy = ConvertType(destType);
1079 if (
C->getType() == destTy)
return C;
1086 Types.push_back(
C->getType());
1087 unsigned CurSize = CGM.
getDataLayout().getTypeAllocSize(
C->getType());
1088 unsigned TotalSize = CGM.
getDataLayout().getTypeAllocSize(destTy);
1090 assert(CurSize <= TotalSize &&
"Union size mismatch!");
1091 if (
unsigned NumPadBytes = TotalSize - CurSize) {
1092 llvm::Type *Ty = CGM.
CharTy;
1093 if (NumPadBytes > 1)
1094 Ty = llvm::ArrayType::get(Ty, NumPadBytes);
1096 Elts.push_back(llvm::UndefValue::get(Ty));
1097 Types.push_back(Ty);
1100 llvm::StructType *STy = llvm::StructType::get(VMContext, Types,
false);
1101 return llvm::ConstantStruct::get(STy, Elts);
1104 case CK_AddressSpaceConversion: {
1106 if (!
C)
return nullptr;
1109 llvm::Type *destTy = ConvertType(E->
getType());
1114 case CK_LValueToRValue: {
1119 if (
auto *E = dyn_cast<CompoundLiteralExpr>(subExpr->
IgnoreParens()))
1120 return Visit(E->getInitializer(), destType);
1124 case CK_AtomicToNonAtomic:
1125 case CK_NonAtomicToAtomic:
1127 case CK_ConstructorConversion:
1128 return Visit(subExpr, destType);
1130 case CK_IntToOCLSampler:
1131 llvm_unreachable(
"global sampler variables are not generated");
1133 case CK_Dependent: llvm_unreachable(
"saw dependent cast!");
1135 case CK_BuiltinFnToFnPtr:
1136 llvm_unreachable(
"builtin functions are handled elsewhere");
1138 case CK_ReinterpretMemberPointer:
1139 case CK_DerivedToBaseMemberPointer:
1140 case CK_BaseToDerivedMemberPointer: {
1142 if (!
C)
return nullptr;
1147 case CK_ObjCObjectLValueCast:
1148 case CK_ARCProduceObject:
1149 case CK_ARCConsumeObject:
1150 case CK_ARCReclaimReturnedObject:
1151 case CK_ARCExtendBlockObject:
1152 case CK_CopyAndAutoreleaseBlockObject:
1160 case CK_LValueBitCast:
1161 case CK_LValueToRValueBitCast:
1162 case CK_NullToMemberPointer:
1163 case CK_UserDefinedConversion:
1164 case CK_CPointerToObjCPointerCast:
1165 case CK_BlockPointerToObjCPointerCast:
1166 case CK_AnyPointerToBlockPointerCast:
1167 case CK_ArrayToPointerDecay:
1168 case CK_FunctionToPointerDecay:
1169 case CK_BaseToDerived:
1170 case CK_DerivedToBase:
1171 case CK_UncheckedDerivedToBase:
1172 case CK_MemberPointerToBoolean:
1173 case CK_VectorSplat:
1174 case CK_FloatingRealToComplex:
1175 case CK_FloatingComplexToReal:
1176 case CK_FloatingComplexToBoolean:
1177 case CK_FloatingComplexCast:
1178 case CK_FloatingComplexToIntegralComplex:
1179 case CK_IntegralRealToComplex:
1180 case CK_IntegralComplexToReal:
1181 case CK_IntegralComplexToBoolean:
1182 case CK_IntegralComplexCast:
1183 case CK_IntegralComplexToFloatingComplex:
1184 case CK_PointerToIntegral:
1185 case CK_PointerToBoolean:
1186 case CK_NullToPointer:
1187 case CK_IntegralCast:
1188 case CK_BooleanToSignedIntegral:
1189 case CK_IntegralToPointer:
1190 case CK_IntegralToBoolean:
1191 case CK_IntegralToFloating:
1192 case CK_FloatingToIntegral:
1193 case CK_FloatingToBoolean:
1194 case CK_FloatingCast:
1195 case CK_FloatingToFixedPoint:
1196 case CK_FixedPointToFloating:
1197 case CK_FixedPointCast:
1198 case CK_FixedPointToBoolean:
1199 case CK_FixedPointToIntegral:
1200 case CK_IntegralToFixedPoint:
1201 case CK_ZeroToOCLOpaqueType:
1205 llvm_unreachable(
"Invalid CastKind");
1225 assert(CAT &&
"can't emit array init for non-constant-bound array");
1227 unsigned NumElements = CAT->getSize().getZExtValue();
1231 unsigned NumInitableElts = std::min(NumInitElements, NumElements);
1233 QualType EltType = CAT->getElementType();
1236 llvm::Constant *fillC =
nullptr;
1238 fillC =
Emitter.tryEmitAbstractForMemory(filler, EltType);
1245 if (fillC && fillC->isNullValue())
1246 Elts.reserve(NumInitableElts + 1);
1248 Elts.reserve(NumElements);
1250 llvm::Type *CommonElementType =
nullptr;
1251 for (
unsigned i = 0; i < NumInitableElts; ++i) {
1253 llvm::Constant *
C =
Emitter.tryEmitPrivateForMemory(Init, EltType);
1257 CommonElementType =
C->getType();
1258 else if (
C->getType() != CommonElementType)
1259 CommonElementType =
nullptr;
1263 llvm::ArrayType *Desired =
1265 return EmitArrayConstant(CGM, Desired, CommonElementType, NumElements, Elts,
1270 return ConstStructBuilder::BuildStruct(
Emitter, ILE, T);
1283 return EmitArrayInitialization(ILE, T);
1286 return EmitRecordInitialization(ILE, T);
1297 ConstantAggregateBuilder
Const(CGM);
1305 bool HasFlexibleArray =
false;
1307 HasFlexibleArray = RT->getDecl()->hasFlexibleArrayMember();
1308 return Const.build(ValTy, HasFlexibleArray);
1317 assert(E->
getNumArgs() == 1 &&
"trivial ctor with > 1 argument");
1319 "trivial ctor has argument but isn't a copy/move ctor");
1323 "argument to copy ctor is of wrong type");
1325 return Visit(Arg, Ty);
1343 assert(CAT &&
"String data not of constant array type!");
1347 Str.resize(CAT->
getSize().getZExtValue(),
'\0');
1348 return llvm::ConstantDataArray::getString(VMContext, Str,
false);
1356 llvm::Type *ConvertType(
QualType T) {
1363llvm::Constant *ConstantEmitter::validateAndPopAbstract(llvm::Constant *
C,
1364 AbstractState saved) {
1365 Abstract = saved.OldValue;
1367 assert(saved.OldPlaceholdersSize == PlaceholderAddresses.size() &&
1368 "created a placeholder while doing an abstract emission?");
1377 auto state = pushAbstract();
1379 return validateAndPopAbstract(
C, state);
1384 auto state = pushAbstract();
1386 return validateAndPopAbstract(
C, state);
1391 auto state = pushAbstract();
1393 return validateAndPopAbstract(
C, state);
1409 auto state = pushAbstract();
1411 C = validateAndPopAbstract(
C, state);
1414 "internal error: could not emit constant value \"abstractly\"");
1423 auto state = pushAbstract();
1425 C = validateAndPopAbstract(
C, state);
1428 "internal error: could not emit constant value \"abstractly\"");
1442 initializeNonAbstract(destAddrSpace);
1449 initializeNonAbstract(destAddrSpace);
1451 assert(
C &&
"couldn't emit constant value non-abstractly?");
1456 assert(!Abstract &&
"cannot get current address for abstract constant");
1463 llvm::GlobalValue::PrivateLinkage,
1467 llvm::GlobalVariable::NotThreadLocal,
1470 PlaceholderAddresses.push_back(std::make_pair(
nullptr, global));
1476 llvm::GlobalValue *placeholder) {
1477 assert(!PlaceholderAddresses.empty());
1478 assert(PlaceholderAddresses.back().first ==
nullptr);
1479 assert(PlaceholderAddresses.back().second == placeholder);
1480 PlaceholderAddresses.back().first = signal;
1484 struct ReplacePlaceholders {
1488 llvm::Constant *
Base;
1489 llvm::Type *BaseValueTy =
nullptr;
1492 llvm::DenseMap<llvm::Constant*, llvm::GlobalVariable*> PlaceholderAddresses;
1495 llvm::DenseMap<llvm::GlobalVariable*, llvm::Constant*> Locations;
1503 ReplacePlaceholders(
CodeGenModule &CGM, llvm::Constant *base,
1504 ArrayRef<std::pair<llvm::Constant*,
1505 llvm::GlobalVariable*>> addresses)
1506 : CGM(CGM),
Base(base),
1507 PlaceholderAddresses(addresses.begin(), addresses.end()) {
1510 void replaceInInitializer(llvm::Constant *init) {
1512 BaseValueTy = init->getType();
1515 Indices.push_back(0);
1516 IndexValues.push_back(
nullptr);
1519 findLocations(init);
1522 assert(IndexValues.size() == Indices.size() &&
"mismatch");
1523 assert(Indices.size() == 1 &&
"didn't pop all indices");
1526 assert(Locations.size() == PlaceholderAddresses.size() &&
1527 "missed a placeholder?");
1533 for (
auto &entry : Locations) {
1534 assert(entry.first->getParent() ==
nullptr &&
"not a placeholder!");
1535 entry.first->replaceAllUsesWith(entry.second);
1536 entry.first->eraseFromParent();
1541 void findLocations(llvm::Constant *init) {
1543 if (
auto agg = dyn_cast<llvm::ConstantAggregate>(init)) {
1544 for (
unsigned i = 0, e = agg->getNumOperands(); i != e; ++i) {
1545 Indices.push_back(i);
1546 IndexValues.push_back(
nullptr);
1548 findLocations(agg->getOperand(i));
1550 IndexValues.pop_back();
1558 auto it = PlaceholderAddresses.find(init);
1559 if (it != PlaceholderAddresses.end()) {
1560 setLocation(it->second);
1565 if (
auto expr = dyn_cast<llvm::ConstantExpr>(init)) {
1566 init =
expr->getOperand(0);
1573 void setLocation(llvm::GlobalVariable *placeholder) {
1574 assert(!Locations.contains(placeholder) &&
1575 "already found location for placeholder!");
1580 assert(Indices.size() == IndexValues.size());
1581 for (
size_t i = Indices.size() - 1; i !=
size_t(-1); --i) {
1582 if (IndexValues[i]) {
1584 for (
size_t j = 0; j != i + 1; ++j) {
1585 assert(IndexValues[j] &&
1586 isa<llvm::ConstantInt>(IndexValues[j]) &&
1587 cast<llvm::ConstantInt>(IndexValues[j])->getZExtValue()
1594 IndexValues[i] = llvm::ConstantInt::get(CGM.
Int32Ty, Indices[i]);
1599 llvm::Constant *location =
1600 llvm::ConstantExpr::getInBoundsGetElementPtr(BaseValueTy,
1602 location = llvm::ConstantExpr::getBitCast(location,
1603 placeholder->getType());
1605 Locations.insert({placeholder, location});
1611 assert(InitializedNonAbstract &&
1612 "finalizing emitter that was used for abstract emission?");
1613 assert(!Finalized &&
"finalizing emitter multiple times");
1614 assert(global->getInitializer());
1619 if (!PlaceholderAddresses.empty()) {
1620 ReplacePlaceholders(
CGM, global, PlaceholderAddresses)
1621 .replaceInInitializer(global->getInitializer());
1622 PlaceholderAddresses.clear();
1627 assert((!InitializedNonAbstract || Finalized || Failed) &&
1628 "not finalized after being initialized for non-abstract emission");
1629 assert(PlaceholderAddresses.empty() &&
"unhandled placeholders");
1635 type.getQualifiers());
1648 dyn_cast_or_null<CXXConstructExpr>(D.
getInit())) {
1674 assert(E &&
"No initializer to emit");
1678 ConstExprEmitter(*this).Visit(
const_cast<Expr*
>(E), nonMemoryDestType);
1716 QualType destValueType = AT->getValueType();
1721 if (innerSize == outerSize)
1724 assert(innerSize < outerSize &&
"emitted over-large constant for atomic");
1725 llvm::Constant *elts[] = {
1727 llvm::ConstantAggregateZero::get(
1728 llvm::ArrayType::get(
CGM.
Int8Ty, (outerSize - innerSize) / 8))
1730 return llvm::ConstantStruct::getAnon(elts);
1734 if (
C->getType()->isIntegerTy(1) && !destType->
isBitIntType()) {
1736 return llvm::ConstantExpr::getZExt(
C, boolTy);
1744 assert(!destType->
isVoidType() &&
"can't emit a void constant");
1748 bool Success =
false;
1756 if (Success && !
Result.HasSideEffects)
1759 C = ConstExprEmitter(*this).Visit(
const_cast<Expr*
>(E), destType);
1771struct ConstantLValue {
1772 llvm::Constant *
Value;
1773 bool HasOffsetApplied;
1775 ConstantLValue(llvm::Constant *value,
1776 bool hasOffsetApplied =
false)
1777 :
Value(value), HasOffsetApplied(hasOffsetApplied) {}
1780 : ConstantLValue(address.getPointer()) {}
1784class ConstantLValueEmitter :
public ConstStmtVisitor<ConstantLValueEmitter,
1797 : CGM(emitter.CGM),
Emitter(emitter),
Value(value), DestType(destType) {}
1799 llvm::Constant *tryEmit();
1802 llvm::Constant *tryEmitAbsolute(llvm::Type *destTy);
1805 ConstantLValue VisitStmt(
const Stmt *S) {
return nullptr; }
1806 ConstantLValue VisitConstantExpr(
const ConstantExpr *E);
1814 ConstantLValue VisitCallExpr(
const CallExpr *E);
1815 ConstantLValue VisitBlockExpr(
const BlockExpr *E);
1817 ConstantLValue VisitMaterializeTemporaryExpr(
1820 bool hasNonZeroOffset()
const {
1821 return !
Value.getLValueOffset().isZero();
1825 llvm::Constant *getOffset() {
1826 return llvm::ConstantInt::get(CGM.
Int64Ty,
1827 Value.getLValueOffset().getQuantity());
1831 llvm::Constant *applyOffset(llvm::Constant *
C) {
1832 if (!hasNonZeroOffset())
1835 llvm::Type *origPtrTy =
C->getType();
1836 unsigned AS = origPtrTy->getPointerAddressSpace();
1837 llvm::Type *charPtrTy = CGM.
Int8Ty->getPointerTo(AS);
1838 C = llvm::ConstantExpr::getBitCast(
C, charPtrTy);
1839 C = llvm::ConstantExpr::getGetElementPtr(CGM.
Int8Ty,
C, getOffset());
1840 C = llvm::ConstantExpr::getPointerCast(
C, origPtrTy);
1847llvm::Constant *ConstantLValueEmitter::tryEmit() {
1858 assert(isa<llvm::IntegerType>(destTy) || isa<llvm::PointerType>(destTy));
1863 return tryEmitAbsolute(destTy);
1867 ConstantLValue result = tryEmitBase(base);
1870 llvm::Constant *value = result.Value;
1871 if (!value)
return nullptr;
1874 if (!result.HasOffsetApplied) {
1875 value = applyOffset(value);
1880 if (isa<llvm::PointerType>(destTy))
1881 return llvm::ConstantExpr::getPointerCast(value, destTy);
1883 return llvm::ConstantExpr::getPtrToInt(value, destTy);
1889ConstantLValueEmitter::tryEmitAbsolute(llvm::Type *destTy) {
1891 auto destPtrTy = cast<llvm::PointerType>(destTy);
1892 if (
Value.isNullPointer()) {
1900 auto intptrTy = CGM.
getDataLayout().getIntPtrType(destPtrTy);
1902 C = llvm::ConstantExpr::getIntegerCast(getOffset(), intptrTy,
1904 C = llvm::ConstantExpr::getIntToPtr(
C, destPtrTy);
1914 D = cast<ValueDecl>(D->getMostRecentDecl());
1916 if (D->hasAttr<WeakRefAttr>())
1919 if (
auto FD = dyn_cast<FunctionDecl>(D))
1922 if (
auto VD = dyn_cast<VarDecl>(D)) {
1924 if (!VD->hasLocalStorage()) {
1925 if (VD->isFileVarDecl() || VD->hasExternalStorage())
1928 if (VD->isLocalVarDecl()) {
1935 if (
auto *GD = dyn_cast<MSGuidDecl>(D))
1938 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D))
1941 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(D))
1949 llvm::Type *StdTypeInfoPtrTy =
1953 if (
TypeInfo->getType() != StdTypeInfoPtrTy)
1959 return Visit(base.
get<
const Expr*>());
1963ConstantLValueEmitter::VisitConstantExpr(
const ConstantExpr *E) {
1964 if (llvm::Constant *
Result =
Emitter.tryEmitConstantExpr(E))
1972 CompoundLiteralEmitter.setInConstantContext(
Emitter.isInConstantContext());
1973 return tryEmitGlobalCompoundLiteral(CompoundLiteralEmitter, E);
1977ConstantLValueEmitter::VisitStringLiteral(
const StringLiteral *E) {
1982ConstantLValueEmitter::VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
1999ConstantLValueEmitter::VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
2001 "this boxed expression can't be emitted as a compile-time constant");
2007ConstantLValueEmitter::VisitPredefinedExpr(
const PredefinedExpr *E) {
2012ConstantLValueEmitter::VisitAddrLabelExpr(
const AddrLabelExpr *E) {
2013 assert(
Emitter.CGF &&
"Invalid address of label expression outside function");
2015 Ptr = llvm::ConstantExpr::getBitCast(Ptr,
2021ConstantLValueEmitter::VisitCallExpr(
const CallExpr *E) {
2023 if (builtin == Builtin::BI__builtin_function_start)
2026 if (builtin != Builtin::BI__builtin___CFStringMakeConstantString &&
2027 builtin != Builtin::BI__builtin___NSStringMakeConstantString)
2031 if (builtin == Builtin::BI__builtin___NSStringMakeConstantString) {
2040ConstantLValueEmitter::VisitBlockExpr(
const BlockExpr *E) {
2041 StringRef functionName;
2043 functionName = CGF->CurFn->
getName();
2045 functionName =
"global";
2051ConstantLValueEmitter::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
2061ConstantLValueEmitter::VisitMaterializeTemporaryExpr(
2079 return ConstantLValueEmitter(*
this,
Value, DestType).tryEmit();
2084 Value.getFixedPoint().getValue());
2089 Value.getComplexIntReal());
2091 Value.getComplexIntImag());
2094 llvm::StructType *STy =
2095 llvm::StructType::get(
Complex[0]->getType(),
Complex[1]->getType());
2096 return llvm::ConstantStruct::get(STy,
Complex);
2099 const llvm::APFloat &Init =
Value.getFloat();
2100 if (&Init.getSemantics() == &llvm::APFloat::IEEEhalf() &&
2104 Init.bitcastToAPInt());
2112 Value.getComplexFloatReal());
2114 Value.getComplexFloatImag());
2117 llvm::StructType *STy =
2118 llvm::StructType::get(
Complex[0]->getType(),
Complex[1]->getType());
2119 return llvm::ConstantStruct::get(STy,
Complex);
2122 unsigned NumElts =
Value.getVectorLength();
2125 for (
unsigned I = 0; I != NumElts; ++I) {
2132 llvm_unreachable(
"unsupported vector element type");
2134 return llvm::ConstantVector::get(Inits);
2141 if (!LHS || !RHS)
return nullptr;
2145 LHS = llvm::ConstantExpr::getPtrToInt(LHS,
CGM.
IntPtrTy);
2146 RHS = llvm::ConstantExpr::getPtrToInt(RHS,
CGM.
IntPtrTy);
2147 llvm::Constant *AddrLabelDiff = llvm::ConstantExpr::getSub(LHS, RHS);
2152 return llvm::ConstantExpr::getTruncOrBitCast(AddrLabelDiff, ResultType);
2156 return ConstStructBuilder::BuildStruct(*
this,
Value, DestType);
2159 unsigned NumElements =
Value.getArraySize();
2160 unsigned NumInitElts =
Value.getArrayInitializedElts();
2163 llvm::Constant *Filler =
nullptr;
2164 if (
Value.hasArrayFiller()) {
2173 if (Filler && Filler->isNullValue())
2174 Elts.reserve(NumInitElts + 1);
2176 Elts.reserve(NumElements);
2178 llvm::Type *CommonElementType =
nullptr;
2179 for (
unsigned I = 0; I < NumInitElts; ++I) {
2182 if (!
C)
return nullptr;
2185 CommonElementType =
C->getType();
2186 else if (
C->getType() != CommonElementType)
2187 CommonElementType =
nullptr;
2191 llvm::ArrayType *Desired =
2196 Desired = llvm::ArrayType::get(Desired->getElementType(), Elts.size());
2198 return EmitArrayConstant(
CGM, Desired, CommonElementType, NumElements, Elts,
2204 llvm_unreachable(
"Unknown APValue kind");
2209 return EmittedCompoundLiterals.lookup(E);
2214 bool Ok = EmittedCompoundLiterals.insert(std::make_pair(CLE, GV)).second;
2216 assert(Ok &&
"CLE has already been emitted!");
2221 assert(E->
isFileScope() &&
"not a file-scope compound literal expr");
2223 return tryEmitGlobalCompoundLiteral(emitter, E);
2243 llvm::Type *baseType,
2248 bool asCompleteObject) {
2250 llvm::StructType *structure =
2254 unsigned numElements = structure->getNumElements();
2255 std::vector<llvm::Constant *> elements(numElements);
2257 auto CXXR = dyn_cast<CXXRecordDecl>(record);
2260 for (
const auto &I : CXXR->bases()) {
2261 if (I.isVirtual()) {
2277 llvm::Type *baseType = structure->getElementType(fieldIndex);
2283 for (
const auto *Field : record->
fields()) {
2286 if (!Field->isBitField() && !Field->isZeroSize(CGM.
getContext())) {
2293 if (Field->getIdentifier())
2295 if (
const auto *FieldRD = Field->getType()->getAsRecordDecl())
2296 if (FieldRD->findFirstNamedDataMember())
2302 if (CXXR && asCompleteObject) {
2303 for (
const auto &I : CXXR->vbases()) {
2314 if (elements[fieldIndex])
continue;
2316 llvm::Type *baseType = structure->getElementType(fieldIndex);
2322 for (
unsigned i = 0; i != numElements; ++i) {
2324 elements[i] = llvm::Constant::getNullValue(structure->getElementType(i));
2327 return llvm::ConstantStruct::get(structure, elements);
2332 llvm::Type *baseType,
2338 return llvm::Constant::getNullValue(baseType);
2352 cast<llvm::PointerType>(
getTypes().ConvertTypeForMem(T)), T);
2354 if (
getTypes().isZeroInitializable(T))
2355 return llvm::Constant::getNullValue(
getTypes().ConvertTypeForMem(T));
2358 llvm::ArrayType *ATy =
2359 cast<llvm::ArrayType>(
getTypes().ConvertTypeForMem(T));
2363 llvm::Constant *Element =
2365 unsigned NumElements = CAT->
getSize().getZExtValue();
2367 return llvm::ConstantArray::get(ATy, Array);
2371 return ::EmitNullConstant(*
this, RT->getDecl(),
true);
2374 "Should only see pointers to data members here!");
2381 return ::EmitNullConstant(*
this, Record,
false);
Defines the clang::ASTContext interface.
Defines enum values for all the target-independent builtin functions.
static QualType getNonMemoryType(CodeGenModule &CGM, QualType type)
static llvm::Constant * EmitNullConstant(CodeGenModule &CGM, const RecordDecl *record, bool asCompleteObject)
static ConstantLValue emitConstantObjCStringLiteral(const StringLiteral *S, QualType T, CodeGenModule &CGM)
static llvm::Constant * EmitNullConstantForBase(CodeGenModule &CGM, llvm::Type *baseType, const CXXRecordDecl *base)
Emit the null constant for a base subobject.
QualType getTypeInfoType() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
APValue & getStructField(unsigned i)
const FieldDecl * getUnionField() const
APValue & getUnionValue()
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
@ None
There is no such object (it's outside its lifetime).
APValue & getStructBase(unsigned i)
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.
uint64_t getFieldOffset(const ValueDecl *FD) const
Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const
Emit the Objective-CC type encoding for the given type T into S.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
const LangOptions & getLangOpts() const
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
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.
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
unsigned getTargetAddressSpace(LangAS AS) const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
bool hasOwnVFPtr() const
hasOwnVFPtr - Does this class provide its own virtual-function table pointer, rather than inheriting ...
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.
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
CharUnits getNonVirtualSize() const
getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...
AddrLabelExpr - The GNU address of label extension, representing &&label.
LabelDecl * getLabel() const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Represents a base class of a C++ class.
Represents a call to a C++ constructor.
Expr * getArg(unsigned Arg)
Return the specified argument.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ constructor within a class.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
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 static or instance method of a struct/union/class.
Represents a C++ struct/union/class.
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
QualType getTypeOperand(ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
bool isTypeOperand() const
Expr * getExprOperand() const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CastKind getCastKind() const
const FieldDecl * getTargetUnionField() 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.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
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.
llvm::StringRef getName() const
Return the IR name of the pointer value.
virtual llvm::Constant * EmitNullMemberPointer(const MemberPointerType *MPT)
Create a null member pointer of the given type.
virtual llvm::Constant * EmitMemberPointer(const APValue &MP, QualType MPT)
Create a member pointer for the given member pointer constant.
virtual llvm::Constant * getVTableAddressPointForConstExpr(BaseSubobject Base, const CXXRecordDecl *VTableClass)=0
Get the address point of the vtable for the given base subobject while building a constexpr.
virtual llvm::Constant * EmitMemberDataPointer(const MemberPointerType *MPT, CharUnits offset)
Create a member pointer for the given field.
virtual llvm::Value * EmitMemberPointerConversion(CodeGenFunction &CGF, const CastExpr *E, llvm::Value *Src)
Perform a derived-to-base, base-to-derived, or bitcast member pointer conversion.
virtual llvm::Constant * EmitMemberFunctionPointer(const CXXMethodDecl *MD)
Create a member pointer for the given method.
virtual ConstantAddress GenerateConstantString(const StringLiteral *)=0
Generate a constant string object.
CGRecordLayout - This class handles struct and union layout info while lowering AST types to LLVM typ...
unsigned getNonVirtualBaseLLVMFieldNo(const CXXRecordDecl *RD) const
llvm::StructType * getLLVMType() const
Return the "complete object" LLVM type associated with this record.
const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const
Return the BitFieldInfo that corresponds to the field FD.
bool isZeroInitializableAsBase() const
Check whether this struct can be C++ zero-initialized with a zeroinitializer when considered as a bas...
llvm::StructType * getBaseSubobjectLLVMType() const
Return the "base subobject" LLVM type associated with this record.
unsigned getLLVMFieldNo(const FieldDecl *FD) const
Return llvm::StructType element number that corresponds to the field FD.
unsigned getVirtualBaseIndex(const CXXRecordDecl *base) const
Return the LLVM field index corresponding to the given virtual base.
This class organizes the cross-function state that is used while generating LLVM code.
ConstantAddress GetAddrOfMSGuidDecl(const MSGuidDecl *GD)
Get the address of a GUID.
void EmitExplicitCastExprType(const ExplicitCastExpr *E, CodeGenFunction *CGF=nullptr)
Emit type info if type of an expression is a variably modified type.
llvm::Module & getModule() const
ConstantAddress GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *E)
Returns a pointer to a constant global variable for the given file-scope compound literal expression.
llvm::Constant * EmitNullConstantForBase(const CXXRecordDecl *Record)
Return a null constant appropriate for zero-initializing a base class with the given type.
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
llvm::Constant * GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty=nullptr, bool ForVTable=false, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
Return the address of the given function.
llvm::Constant * getNullPointer(llvm::PointerType *T, QualType QT)
Get target specific null pointer.
llvm::Constant * GetAddrOfGlobalBlock(const BlockExpr *BE, StringRef Name)
Gets the address of a block which requires no captures.
CodeGenTypes & getTypes()
llvm::GlobalValue::LinkageTypes getLLVMLinkageVarDefinition(const VarDecl *VD, bool IsConstant)
Returns LLVM linkage for a declarator.
llvm::Constant * getMemberPointerConstant(const UnaryOperator *e)
const llvm::DataLayout & getDataLayout() const
void Error(SourceLocation loc, StringRef error)
Emit a general error that something can't be done.
CGCXXABI & getCXXABI() const
ConstantAddress GetWeakRefReference(const ValueDecl *VD)
Get a reference to the target of VD.
llvm::Constant * GetFunctionStart(const ValueDecl *Decl)
llvm::GlobalVariable * getAddrOfConstantCompoundLiteralIfEmitted(const CompoundLiteralExpr *E)
If it's been emitted already, returns the GlobalVariable corresponding to a compound literal.
llvm::Constant * getOrCreateStaticVarDecl(const VarDecl &D, llvm::GlobalValue::LinkageTypes Linkage)
ConstantAddress GetAddrOfConstantCFString(const StringLiteral *Literal)
Return a pointer to a constant CFString object for the given string.
ConstantAddress GetAddrOfConstantStringFromLiteral(const StringLiteral *S, StringRef Name=".str")
Return a pointer to a constant array for the given string literal.
ASTContext & getContext() const
ConstantAddress GetAddrOfTemplateParamObject(const TemplateParamObjectDecl *TPO)
Get the address of a template parameter object.
ConstantAddress GetAddrOfUnnamedGlobalConstantDecl(const UnnamedGlobalConstantDecl *GCD)
Get the address of a UnnamedGlobalConstant.
llvm::Constant * GetAddrOfGlobalVar(const VarDecl *D, llvm::Type *Ty=nullptr, ForDefinition_t IsForDefinition=NotForDefinition)
Return the llvm::Constant for the address of the given global variable.
void setAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *CLE, llvm::GlobalVariable *GV)
Notes that CLE's GlobalVariable is GV.
const TargetCodeGenInfo & getTargetCodeGenInfo()
llvm::Constant * GetConstantArrayFromStringLiteral(const StringLiteral *E)
Return a constant array for the given string.
llvm::LLVMContext & getLLVMContext()
bool isTypeConstant(QualType QTy, bool ExcludeCtor, bool ExcludeDtor)
isTypeConstant - Determine whether an object of this type can be emitted as a constant.
CGObjCRuntime & getObjCRuntime()
Return a reference to the configured Objective-C runtime.
ConstantAddress GetAddrOfGlobalTemporary(const MaterializeTemporaryExpr *E, const Expr *Inner)
Returns a pointer to a global variable representing a temporary with static or thread storage duratio...
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
ConstantAddress GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *)
Return a pointer to a constant array for the given ObjCEncodeExpr node.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
llvm::Type * ConvertTypeForMem(QualType T, bool ForBitField=false)
ConvertTypeForMem - Convert type T into a llvm::Type.
A specialization of Address that requires the address to be an LLVM Constant.
static ConstantAddress invalid()
llvm::Constant * getPointer() const
llvm::Constant * tryEmitPrivateForMemory(const Expr *E, QualType T)
llvm::Constant * tryEmitForInitializer(const VarDecl &D)
Try to emit the initiaizer of the given declaration as an abstract constant.
llvm::Constant * tryEmitPrivateForVarInit(const VarDecl &D)
llvm::Constant * tryEmitPrivate(const Expr *E, QualType T)
void finalize(llvm::GlobalVariable *global)
llvm::Constant * tryEmitAbstractForInitializer(const VarDecl &D)
Try to emit the initializer of the given declaration as an abstract constant.
llvm::Constant * emitAbstract(const Expr *E, QualType T)
Emit the result of the given expression as an abstract constant, asserting that it succeeded.
llvm::GlobalValue * getCurrentAddrPrivate()
Get the address of the current location.
llvm::Constant * tryEmitConstantExpr(const ConstantExpr *CE)
llvm::Constant * emitForMemory(llvm::Constant *C, QualType T)
llvm::Constant * emitNullForMemory(QualType T)
llvm::Constant * tryEmitAbstract(const Expr *E, QualType T)
Try to emit the result of the given expression as an abstract constant.
void registerCurrentAddrPrivate(llvm::Constant *signal, llvm::GlobalValue *placeholder)
Register a 'signal' value with the emitter to inform it where to resolve a placeholder.
llvm::Constant * emitForInitializer(const APValue &value, LangAS destAddrSpace, QualType destType)
llvm::Constant * tryEmitAbstractForMemory(const Expr *E, QualType T)
virtual llvm::Value * performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, llvm::Value *V, LangAS SrcAddr, LangAS DestAddr, llvm::Type *DestTy, bool IsNonNull=false) const
Perform address space cast of an expression of pointer type.
virtual llvm::Constant * getNullPointer(const CodeGen::CodeGenModule &CGM, llvm::PointerType *T, QualType QT) const
Get target specific null pointer.
CompoundLiteralExpr - [C99 6.5.2.5].
const Expr * getInitializer() const
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Represents the canonical version of C arrays with a specified constant size.
const llvm::APInt & getSize() const
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
APValue getAPValueResult() const
SourceLocation getBeginLoc() const LLVM_READONLY
bool hasAPValueResult() const
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
Decl - This represents one declaration (or definition), e.g.
InitListExpr * getUpdater() const
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
This represents one expression.
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
const ValueDecl * getAsBuiltinConstantDeclRef(const ASTContext &Context) const
If this expression is an unambiguous reference to a single declaration, in the style of __builtin_fun...
Represents a member of a struct/union/class.
const Expr * getSubExpr() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
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,...
FieldDecl * getInitializedFieldInUnion()
If this initializes a union, specifies which field in the union to initialize.
unsigned getNumInits() 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
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
A pointer to member type per C++ 8.3.3 - Pointers to members.
ObjCBoxedExpr - used for generalized expression boxing.
bool isExpressibleAsConstantInitializer() const
ObjCEncodeExpr, used for @encode in Objective-C.
QualType getEncodedType() const
ObjCStringLiteral, used for Objective-C string literals i.e.
StringLiteral * getString()
ParenExpr - This represents a parethesized expression, e.g.
const Expr * getSubExpr() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
[C99 6.4.2.2] - A predefined identifier such as func.
StringLiteral * getFunctionName()
A (possibly-)qualified type.
LangAS getAddressSpace() const
Return the address space of this type.
Represents a struct/union/class.
bool hasFlexibleArrayMember() const
field_iterator field_end() const
field_range fields() 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...
RecordDecl * getDecl() const
Encodes a location in the source.
StmtVisitorBase - This class implements a simple visitor for Stmt subclasses.
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...
Expr * getReplacement() const
virtual bool useFP16ConversionIntrinsics() const
Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used to convert to and from __fp...
Symbolic representation of typeid(T) for some type T.
The base class of the type hierarchy.
bool isIncompleteArrayType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isMemberDataPointerType() const
bool isBitIntType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
const Expr * getInit() const
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
bool Const(InterpState &S, CodePtr OpPC, const T &Arg)
bool GE(InterpState &S, CodePtr OpPC)
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
@ C
Languages that the frontend can parse and compile.
@ SD_Static
Static storage duration.
@ Result
The result type of a method or function.
LangAS
Defines the address space values used by the address space qualifier of QualType.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
Structure with information about how a bitfield should be accessed.
unsigned Size
The total size of the bit-field, in bits.
llvm::IntegerType * Int64Ty
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * CharTy
char
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
EvalResult is a struct with detailed info about an evaluated expression.