29#include "llvm/ADT/STLExtras.h"
30#include "llvm/ADT/Sequence.h"
31#include "llvm/Analysis/ConstantFolding.h"
32#include "llvm/IR/Constants.h"
33#include "llvm/IR/DataLayout.h"
34#include "llvm/IR/Function.h"
35#include "llvm/IR/GlobalVariable.h"
36#include "llvm/Support/SipHash.h"
46class ConstExprEmitter;
49 llvm::Type *Ty = CGM.
CharTy;
51 Ty = llvm::ArrayType::get(Ty, PadSize.
getQuantity());
53 return llvm::Constant::getNullValue(Ty);
55 return llvm::UndefValue::get(Ty);
58struct ConstantAggregateBuilderUtils {
61 ConstantAggregateBuilderUtils(CodeGenModule &CGM) : CGM(CGM) {}
63 CharUnits getAlignment(
const llvm::Constant *
C)
const {
65 CGM.getDataLayout().getABITypeAlign(
C->getType()));
68 CharUnits getSize(llvm::Type *Ty)
const {
72 CharUnits getSize(
const llvm::Constant *
C)
const {
73 return getSize(
C->getType());
76 llvm::Constant *getPadding(CharUnits PadSize)
const {
77 return ::getPadding(CGM, PadSize);
80 llvm::Constant *getZeroes(CharUnits ZeroSize)
const {
81 llvm::Type *Ty = llvm::ArrayType::get(CGM.CharTy, ZeroSize.
getQuantity());
82 return llvm::ConstantAggregateZero::get(Ty);
88class ConstantAggregateBuilder :
private ConstantAggregateBuilderUtils {
97 llvm::SmallVector<llvm::Constant*, 32> Elems;
98 llvm::SmallVector<CharUnits, 32> Offsets;
107 bool NaturalLayout =
true;
109 bool split(
size_t Index, CharUnits Hint);
110 std::optional<size_t> splitAt(CharUnits Pos);
112 static llvm::Constant *buildFrom(CodeGenModule &CGM,
113 ArrayRef<llvm::Constant *> Elems,
114 ArrayRef<CharUnits> Offsets,
115 CharUnits StartOffset, CharUnits Size,
116 bool NaturalLayout, llvm::Type *DesiredTy,
117 bool AllowOversized);
120 ConstantAggregateBuilder(CodeGenModule &CGM)
121 : ConstantAggregateBuilderUtils(CGM) {}
128 bool add(llvm::Constant *
C, CharUnits Offset,
bool AllowOverwrite);
131 bool addBits(llvm::APInt Bits, uint64_t OffsetInBits,
bool AllowOverwrite);
135 void condense(CharUnits Offset, llvm::Type *DesiredTy);
142 llvm::Constant *build(llvm::Type *DesiredTy,
bool AllowOversized)
const {
144 NaturalLayout, DesiredTy, AllowOversized);
148template<
typename Container,
typename Range = std::initializer_list<
149 typename Container::value_type>>
150static void replace(Container &
C,
size_t BeginOff,
size_t EndOff, Range Vals) {
151 assert(BeginOff <= EndOff &&
"invalid replacement range");
152 llvm::replace(
C,
C.begin() + BeginOff,
C.begin() + EndOff, Vals);
155bool ConstantAggregateBuilder::add(llvm::Constant *
C,
CharUnits Offset,
156 bool AllowOverwrite) {
158 if (Offset >= Size) {
159 CharUnits Align = getAlignment(
C);
160 CharUnits AlignedSize =
Size.alignTo(Align);
161 if (AlignedSize > Offset || Offset.
alignTo(Align) != Offset)
162 NaturalLayout =
false;
163 else if (AlignedSize < Offset) {
164 Elems.push_back(getPadding(Offset - Size));
165 Offsets.push_back(Size);
168 Offsets.push_back(Offset);
169 Size = Offset + getSize(
C);
174 std::optional<size_t> FirstElemToReplace = splitAt(Offset);
175 if (!FirstElemToReplace)
178 CharUnits CSize = getSize(
C);
179 std::optional<size_t> LastElemToReplace = splitAt(Offset + CSize);
180 if (!LastElemToReplace)
183 assert((FirstElemToReplace == LastElemToReplace || AllowOverwrite) &&
184 "unexpectedly overwriting field");
186 replace(Elems, *FirstElemToReplace, *LastElemToReplace, {
C});
187 replace(Offsets, *FirstElemToReplace, *LastElemToReplace, {Offset});
188 Size = std::max(Size, Offset + CSize);
189 NaturalLayout =
false;
193bool ConstantAggregateBuilder::addBits(llvm::APInt Bits, uint64_t OffsetInBits,
194 bool AllowOverwrite) {
200 unsigned OffsetWithinChar = OffsetInBits % CharWidth;
204 for (CharUnits OffsetInChars =
208 unsigned WantedBits =
209 std::min((uint64_t)Bits.getBitWidth(), CharWidth - OffsetWithinChar);
213 llvm::APInt BitsThisChar = Bits;
214 if (BitsThisChar.getBitWidth() < CharWidth)
215 BitsThisChar = BitsThisChar.zext(CharWidth);
219 int Shift = Bits.getBitWidth() - CharWidth + OffsetWithinChar;
221 BitsThisChar.lshrInPlace(Shift);
223 BitsThisChar = BitsThisChar.shl(-Shift);
225 BitsThisChar = BitsThisChar.shl(OffsetWithinChar);
227 if (BitsThisChar.getBitWidth() > CharWidth)
228 BitsThisChar = BitsThisChar.trunc(CharWidth);
230 if (WantedBits == CharWidth) {
233 OffsetInChars, AllowOverwrite);
238 std::optional<size_t> FirstElemToUpdate = splitAt(OffsetInChars);
239 if (!FirstElemToUpdate)
241 std::optional<size_t> LastElemToUpdate =
243 if (!LastElemToUpdate)
245 assert(*LastElemToUpdate - *FirstElemToUpdate < 2 &&
246 "should have at most one element covering one byte");
249 llvm::APInt UpdateMask(CharWidth, 0);
251 UpdateMask.setBits(CharWidth - OffsetWithinChar - WantedBits,
252 CharWidth - OffsetWithinChar);
254 UpdateMask.setBits(OffsetWithinChar, OffsetWithinChar + WantedBits);
255 BitsThisChar &= UpdateMask;
257 if (*FirstElemToUpdate == *LastElemToUpdate ||
258 Elems[*FirstElemToUpdate]->isNullValue() ||
262 OffsetInChars,
true);
264 llvm::Constant *&ToUpdate = Elems[*FirstElemToUpdate];
267 auto *CI = dyn_cast<llvm::ConstantInt>(ToUpdate);
272 assert(CI->getBitWidth() == CharWidth &&
"splitAt failed");
273 assert((!(CI->getValue() & UpdateMask) || AllowOverwrite) &&
274 "unexpectedly overwriting bitfield");
275 BitsThisChar |= (CI->getValue() & ~UpdateMask);
276 ToUpdate = llvm::ConstantInt::get(CGM.
getLLVMContext(), BitsThisChar);
281 if (WantedBits == Bits.getBitWidth())
286 Bits.lshrInPlace(WantedBits);
287 Bits = Bits.trunc(Bits.getBitWidth() - WantedBits);
290 OffsetWithinChar = 0;
300std::optional<size_t> ConstantAggregateBuilder::splitAt(CharUnits Pos) {
302 return Offsets.size();
305 auto FirstAfterPos = llvm::upper_bound(Offsets, Pos);
306 if (FirstAfterPos == Offsets.begin())
310 size_t LastAtOrBeforePosIndex = FirstAfterPos - Offsets.begin() - 1;
311 if (Offsets[LastAtOrBeforePosIndex] == Pos)
312 return LastAtOrBeforePosIndex;
315 if (Offsets[LastAtOrBeforePosIndex] +
316 getSize(Elems[LastAtOrBeforePosIndex]) <= Pos)
317 return LastAtOrBeforePosIndex + 1;
320 if (!split(LastAtOrBeforePosIndex, Pos))
328bool ConstantAggregateBuilder::split(
size_t Index, CharUnits Hint) {
329 NaturalLayout =
false;
330 llvm::Constant *
C = Elems[Index];
331 CharUnits Offset = Offsets[Index];
333 if (
auto *CA = dyn_cast<llvm::ConstantAggregate>(
C)) {
336 replace(Elems, Index, Index + 1,
337 llvm::map_range(llvm::seq(0u, CA->getNumOperands()),
338 [&](
unsigned Op) { return CA->getOperand(Op); }));
343 llvm::GetElementPtrInst::getTypeAtIndex(CA->getType(), (uint64_t)0);
344 CharUnits ElemSize = getSize(ElemTy);
346 Offsets, Index, Index + 1,
347 llvm::map_range(llvm::seq(0u, CA->getNumOperands()),
348 [&](
unsigned Op) { return Offset + Op * ElemSize; }));
352 const llvm::StructLayout *Layout =
354 replace(Offsets, Index, Index + 1,
356 llvm::seq(0u, CA->getNumOperands()), [&](
unsigned Op) {
357 return Offset + CharUnits::fromQuantity(
358 Layout->getElementOffset(Op));
364 if (
auto *CDS = dyn_cast<llvm::ConstantDataSequential>(
C)) {
368 CharUnits ElemSize = getSize(CDS->getElementType());
369 replace(Elems, Index, Index + 1,
370 llvm::map_range(llvm::seq(
uint64_t(0u), CDS->getNumElements()),
372 return CDS->getElementAsConstant(Elem);
374 replace(Offsets, Index, Index + 1,
376 llvm::seq(
uint64_t(0u), CDS->getNumElements()),
377 [&](uint64_t Elem) { return Offset + Elem * ElemSize; }));
383 CharUnits ElemSize = getSize(
C);
384 assert(Hint > Offset && Hint < Offset + ElemSize &&
"nothing to split");
385 replace(Elems, Index, Index + 1,
386 {getZeroes(Hint - Offset), getZeroes(Offset + ElemSize - Hint)});
387 replace(Offsets, Index, Index + 1, {Offset, Hint});
393 replace(Elems, Index, Index + 1, {});
394 replace(Offsets, Index, Index + 1, {});
405static llvm::Constant *
406EmitArrayConstant(CodeGenModule &CGM, llvm::ArrayType *DesiredType,
407 llvm::Type *CommonElementType, uint64_t
ArrayBound,
408 SmallVectorImpl<llvm::Constant *> &Elements,
409 llvm::Constant *Filler);
411llvm::Constant *ConstantAggregateBuilder::buildFrom(
412 CodeGenModule &CGM, ArrayRef<llvm::Constant *> Elems,
413 ArrayRef<CharUnits> Offsets, CharUnits StartOffset, CharUnits Size,
414 bool NaturalLayout, llvm::Type *DesiredTy,
bool AllowOversized) {
415 ConstantAggregateBuilderUtils Utils(CGM);
418 return llvm::UndefValue::get(DesiredTy);
420 auto Offset = [&](
size_t I) {
return Offsets[I] - StartOffset; };
424 if (llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(DesiredTy)) {
425 assert(!AllowOversized &&
"oversized array emission not supported");
427 bool CanEmitArray =
true;
428 llvm::Type *CommonType = Elems[0]->getType();
429 llvm::Constant *Filler = llvm::Constant::getNullValue(CommonType);
430 CharUnits ElemSize = Utils.getSize(ATy->getElementType());
431 SmallVector<llvm::Constant*, 32> ArrayElements;
432 for (
size_t I = 0; I != Elems.size(); ++I) {
434 if (Elems[I]->isNullValue())
438 if (Elems[I]->
getType() != CommonType ||
439 !Offset(I).isMultipleOf(ElemSize)) {
440 CanEmitArray =
false;
443 ArrayElements.resize(Offset(I) / ElemSize + 1, Filler);
444 ArrayElements.back() = Elems[I];
448 return EmitArrayConstant(CGM, ATy, CommonType, ATy->getNumElements(),
449 ArrayElements, Filler);
458 CharUnits DesiredSize = Utils.getSize(DesiredTy);
459 if (Size > DesiredSize) {
460 assert(AllowOversized &&
"Elems are oversized");
466 for (llvm::Constant *
C : Elems)
467 Align = std::max(Align, Utils.getAlignment(
C));
470 CharUnits AlignedSize =
Size.alignTo(Align);
473 ArrayRef<llvm::Constant*> UnpackedElems = Elems;
474 llvm::SmallVector<llvm::Constant*, 32> UnpackedElemStorage;
475 if (DesiredSize < AlignedSize || DesiredSize.
alignTo(Align) != DesiredSize) {
477 NaturalLayout =
false;
479 }
else if (DesiredSize > AlignedSize) {
482 UnpackedElemStorage.assign(Elems.begin(), Elems.end());
483 UnpackedElemStorage.push_back(Utils.getPadding(DesiredSize - Size));
484 UnpackedElems = UnpackedElemStorage;
490 llvm::SmallVector<llvm::Constant*, 32> PackedElems;
491 if (!NaturalLayout) {
493 for (
size_t I = 0; I != Elems.size(); ++I) {
494 CharUnits Align = Utils.getAlignment(Elems[I]);
495 CharUnits NaturalOffset = SizeSoFar.
alignTo(Align);
496 CharUnits DesiredOffset = Offset(I);
497 assert(DesiredOffset >= SizeSoFar &&
"elements out of order");
499 if (DesiredOffset != NaturalOffset)
501 if (DesiredOffset != SizeSoFar)
502 PackedElems.push_back(Utils.getPadding(DesiredOffset - SizeSoFar));
503 PackedElems.push_back(Elems[I]);
504 SizeSoFar = DesiredOffset + Utils.getSize(Elems[I]);
509 assert(SizeSoFar <= DesiredSize &&
510 "requested size is too small for contents");
511 if (SizeSoFar < DesiredSize)
512 PackedElems.push_back(Utils.getPadding(DesiredSize - SizeSoFar));
516 llvm::StructType *STy = llvm::ConstantStruct::getTypeForElements(
521 if (llvm::StructType *DesiredSTy = dyn_cast<llvm::StructType>(DesiredTy)) {
522 if (DesiredSTy->isLayoutIdentical(STy))
526 return llvm::ConstantStruct::get(STy,
Packed ? PackedElems : UnpackedElems);
529void ConstantAggregateBuilder::condense(CharUnits Offset,
530 llvm::Type *DesiredTy) {
531 CharUnits
Size = getSize(DesiredTy);
533 std::optional<size_t> FirstElemToReplace = splitAt(Offset);
534 if (!FirstElemToReplace)
536 size_t First = *FirstElemToReplace;
538 std::optional<size_t> LastElemToReplace = splitAt(Offset + Size);
539 if (!LastElemToReplace)
541 size_t Last = *LastElemToReplace;
547 if (Length == 1 && Offsets[
First] == Offset &&
548 getSize(Elems[
First]) == Size) {
551 auto *STy = dyn_cast<llvm::StructType>(DesiredTy);
552 if (STy && STy->getNumElements() == 1 &&
553 STy->getElementType(0) == Elems[
First]->getType())
554 Elems[
First] = llvm::ConstantStruct::get(STy, Elems[
First]);
558 llvm::Constant *Replacement = buildFrom(
559 CGM, ArrayRef(Elems).slice(
First, Length),
560 ArrayRef(Offsets).slice(
First, Length), Offset, getSize(DesiredTy),
561 false, DesiredTy,
false);
562 replace(Elems,
First,
Last, {Replacement});
570class ConstStructBuilder {
572 ConstantEmitter &Emitter;
573 ConstantAggregateBuilder &Builder;
574 CharUnits StartOffset;
577 static llvm::Constant *BuildStruct(ConstantEmitter &Emitter,
578 const InitListExpr *ILE,
580 static llvm::Constant *BuildStruct(ConstantEmitter &Emitter,
582 static bool UpdateStruct(ConstantEmitter &Emitter,
583 ConstantAggregateBuilder &Const, CharUnits Offset,
584 const InitListExpr *Updater);
587 ConstStructBuilder(ConstantEmitter &Emitter,
588 ConstantAggregateBuilder &Builder, CharUnits StartOffset)
589 : CGM(Emitter.CGM), Emitter(Emitter), Builder(Builder),
590 StartOffset(StartOffset) {}
592 bool AppendField(
const FieldDecl *Field, uint64_t FieldOffset,
593 llvm::Constant *InitExpr,
bool AllowOverwrite =
false);
595 bool AppendBytes(CharUnits FieldOffsetInChars, llvm::Constant *InitCst,
596 bool AllowOverwrite =
false);
598 bool AppendBitField(
const FieldDecl *Field, uint64_t FieldOffset,
599 llvm::Constant *InitExpr,
bool AllowOverwrite =
false);
601 bool Build(
const InitListExpr *ILE,
bool AllowOverwrite);
602 bool Build(
const APValue &Val,
const RecordDecl *RD,
bool IsPrimaryBase,
603 const CXXRecordDecl *VTableClass, CharUnits BaseOffset,
604 bool IsCompleteClass =
true);
605 bool DoZeroInitPadding(
const ASTRecordLayout &Layout,
unsigned FieldNo,
606 const FieldDecl &Field,
bool AllowOverwrite,
607 CharUnits &SizeSoFar,
bool &ZeroFieldSize);
608 bool DoZeroInitPadding(
const ASTRecordLayout &Layout,
bool AllowOverwrite,
609 CharUnits SizeSoFar);
610 llvm::Constant *
Finalize(QualType Ty);
613bool ConstStructBuilder::AppendField(
614 const FieldDecl *Field, uint64_t FieldOffset, llvm::Constant *InitCst,
615 bool AllowOverwrite) {
620 return AppendBytes(FieldOffsetInChars, InitCst, AllowOverwrite);
623bool ConstStructBuilder::AppendBytes(CharUnits FieldOffsetInChars,
624 llvm::Constant *InitCst,
625 bool AllowOverwrite) {
626 return Builder.add(InitCst, StartOffset + FieldOffsetInChars, AllowOverwrite);
629bool ConstStructBuilder::AppendBitField(
const FieldDecl *Field,
630 uint64_t FieldOffset, llvm::Constant *
C,
631 bool AllowOverwrite) {
633 llvm::ConstantInt *CI = dyn_cast<llvm::ConstantInt>(
C);
639 llvm::Type *LoadType =
641 llvm::Constant *FoldedConstant = llvm::ConstantFoldLoadFromConst(
643 CI = dyn_cast_if_present<llvm::ConstantInt>(FoldedConstant);
648 const CGRecordLayout &RL =
651 llvm::APInt FieldValue = CI->getValue();
657 if (Info.
Size > FieldValue.getBitWidth())
658 FieldValue = FieldValue.zext(Info.
Size);
661 if (Info.
Size < FieldValue.getBitWidth())
662 FieldValue = FieldValue.trunc(Info.
Size);
664 return Builder.addBits(FieldValue,
669static bool EmitDesignatedInitUpdater(ConstantEmitter &Emitter,
670 ConstantAggregateBuilder &Const,
671 CharUnits Offset, QualType
Type,
672 const InitListExpr *Updater) {
673 if (
Type->isRecordType())
674 return ConstStructBuilder::UpdateStruct(Emitter, Const, Offset, Updater);
683 llvm::Constant *FillC =
nullptr;
692 unsigned NumElementsToUpdate =
693 FillC ? CAT->getZExtSize() : Updater->
getNumInits();
694 for (
unsigned I = 0; I != NumElementsToUpdate; ++I, Offset += ElemSize) {
695 const Expr *
Init =
nullptr;
696 if (I < Updater->getNumInits())
699 if (!
Init && FillC) {
700 if (!
Const.add(FillC, Offset,
true))
704 }
else if (
const auto *ChildILE = dyn_cast<InitListExpr>(
Init)) {
705 if (!EmitDesignatedInitUpdater(Emitter, Const, Offset, ElemType,
709 Const.condense(Offset, ElemTy);
712 if (!
Const.add(Val, Offset,
true))
720bool ConstStructBuilder::Build(
const InitListExpr *ILE,
bool AllowOverwrite) {
724 unsigned FieldNo = -1;
725 unsigned ElementNo = 0;
730 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
731 if (CXXRD->getNumBases())
735 bool ZeroFieldSize =
false;
738 for (FieldDecl *Field : RD->fields()) {
747 if (
Field->isUnnamedBitField())
752 const Expr *
Init =
nullptr;
753 if (ElementNo < ILE->getNumInits())
755 if (isa_and_nonnull<NoInitExpr>(
Init)) {
756 if (ZeroInitPadding &&
757 !DoZeroInitPadding(Layout, FieldNo, *Field, AllowOverwrite, SizeSoFar,
771 if (ZeroInitPadding &&
772 !DoZeroInitPadding(Layout, FieldNo, *Field, AllowOverwrite, SizeSoFar,
779 if (AllowOverwrite &&
780 (
Field->getType()->isArrayType() ||
Field->getType()->isRecordType())) {
781 if (
auto *SubILE = dyn_cast<InitListExpr>(
Init)) {
784 if (!EmitDesignatedInitUpdater(Emitter, Builder, StartOffset + Offset,
785 Field->getType(), SubILE))
789 Builder.condense(StartOffset + Offset,
795 llvm::Constant *EltInit =
801 if (ZeroInitPadding && ZeroFieldSize)
805 if (!
Field->isBitField()) {
812 if (
Field->hasAttr<NoUniqueAddressAttr>())
813 AllowOverwrite =
true;
816 if (!AppendBitField(Field, Layout.
getFieldOffset(FieldNo), EltInit,
822 if (ZeroInitPadding && !DoZeroInitPadding(Layout, AllowOverwrite, SizeSoFar))
830 BaseInfo(
const CXXRecordDecl *Decl, CharUnits Offset,
unsigned Index)
831 : Decl(Decl), Offset(Offset), Index(Index) {
834 const CXXRecordDecl *Decl;
838 bool operator<(
const BaseInfo &O)
const {
return Offset < O.Offset; }
842bool ConstStructBuilder::Build(
const APValue &Val,
const RecordDecl *RD,
844 const CXXRecordDecl *VTableClass,
845 CharUnits Offset,
bool IsCompleteClass) {
851 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
854 llvm::Constant *VTableAddressPoint =
857 if (
auto Authentication =
861 VTableAddressPoint, *Authentication);
862 if (!VTableAddressPoint)
865 if (!AppendBytes(Offset, VTableAddressPoint))
871 SmallVector<BaseInfo, 8> Bases;
874 for (
const CXXBaseSpecifier &Base : CD->bases()) {
875 if (
Base.isVirtual())
877 const CXXRecordDecl *BD =
Base.getType()->getAsCXXRecordDecl();
879 Bases.push_back(BaseInfo(BD, BaseOffset, BaseNo));
882 llvm::stable_sort(Bases);
884 for (
const BaseInfo &Base : Bases) {
887 VTableClass, Offset +
Base.Offset,
false))
891 if (IsCompleteClass) {
895 for (
const CXXBaseSpecifier &Base : CD->vbases()) {
896 const CXXRecordDecl *BD =
Base.getType()->getAsCXXRecordDecl();
898 Bases.push_back(BaseInfo(BD, BaseOffset, BaseNo));
901 llvm::stable_sort(Bases);
903 for (
const BaseInfo &Base : Bases) {
906 IsPrimaryBase, VTableClass, Offset +
Base.Offset,
false))
913 unsigned FieldNo = 0;
916 bool ZeroFieldSize =
false;
919 bool AllowOverwrite =
false;
921 FieldEnd = RD->
field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
927 if (
Field->isUnnamedBitField() ||
934 llvm::Constant *EltInit =
940 llvm::ConstantInt *Disc;
941 llvm::Constant *AddrDisc;
945 Disc = llvm::ConstantInt::get(CGM.
Int64Ty, FieldSignature);
946 AddrDisc = llvm::ConstantPointerNull::get(CGM.
VoidPtrTy);
953 Disc = llvm::ConstantInt::get(CGM.
Int64Ty,
957 EltInit = llvm::ConstantPtrAuth::get(
958 EltInit, llvm::ConstantInt::get(CGM.
Int32Ty, 2), Disc, AddrDisc,
965 if (ZeroInitPadding) {
966 if (!DoZeroInitPadding(Layout, FieldNo, **Field, AllowOverwrite,
967 SizeSoFar, ZeroFieldSize))
974 if (!
Field->isBitField()) {
976 if (!AppendField(*Field, Layout.
getFieldOffset(FieldNo) + OffsetBits,
977 EltInit, AllowOverwrite))
981 if (
Field->hasAttr<NoUniqueAddressAttr>())
982 AllowOverwrite =
true;
985 if (!AppendBitField(*Field, Layout.
getFieldOffset(FieldNo) + OffsetBits,
986 EltInit, AllowOverwrite))
990 if (ZeroInitPadding && !DoZeroInitPadding(Layout, AllowOverwrite, SizeSoFar))
996bool ConstStructBuilder::DoZeroInitPadding(
997 const ASTRecordLayout &Layout,
unsigned FieldNo,
const FieldDecl &Field,
998 bool AllowOverwrite, CharUnits &SizeSoFar,
bool &ZeroFieldSize) {
1001 if (SizeSoFar < StartOffset)
1002 if (!AppendBytes(SizeSoFar, getPadding(CGM, StartOffset - SizeSoFar),
1006 if (!
Field.isBitField()) {
1008 SizeSoFar = StartOffset + FieldSize;
1009 ZeroFieldSize = FieldSize.isZero();
1011 const CGRecordLayout &RL =
1019 ZeroFieldSize = Info.
Size == 0;
1024bool ConstStructBuilder::DoZeroInitPadding(
const ASTRecordLayout &Layout,
1025 bool AllowOverwrite,
1026 CharUnits SizeSoFar) {
1027 CharUnits TotalSize = Layout.
getSize();
1028 if (SizeSoFar < TotalSize)
1029 if (!AppendBytes(SizeSoFar, getPadding(CGM, TotalSize - SizeSoFar),
1032 SizeSoFar = TotalSize;
1036llvm::Constant *ConstStructBuilder::Finalize(QualType
Type) {
1038 auto *RD =
Type->castAsRecordDecl();
1043llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
1044 const InitListExpr *ILE,
1046 ConstantAggregateBuilder
Const(Emitter.
CGM);
1049 if (!Builder.Build(ILE,
false))
1052 return Builder.Finalize(ValTy);
1055llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
1058 ConstantAggregateBuilder
Const(Emitter.
CGM);
1062 const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD);
1066 return Builder.Finalize(ValTy);
1069bool ConstStructBuilder::UpdateStruct(ConstantEmitter &Emitter,
1070 ConstantAggregateBuilder &Const,
1072 const InitListExpr *Updater) {
1073 return ConstStructBuilder(Emitter, Const, Offset)
1074 .Build(Updater,
true);
1081static ConstantAddress
1083 const CompoundLiteralExpr *E) {
1084 CodeGenModule &CGM = emitter.
CGM;
1086 if (llvm::GlobalVariable *
Addr =
1088 return ConstantAddress(
Addr,
Addr->getValueType(), Align);
1095 "file-scope compound literal did not have constant initializer!");
1099 auto GV =
new llvm::GlobalVariable(
1102 llvm::GlobalValue::InternalLinkage,
C,
".compoundliteral",
nullptr,
1103 llvm::GlobalVariable::NotThreadLocal,
1108 return ConstantAddress(GV, GV->getValueType(), Align);
1111static llvm::Constant *
1112EmitArrayConstant(CodeGenModule &CGM, llvm::ArrayType *DesiredType,
1113 llvm::Type *CommonElementType, uint64_t
ArrayBound,
1114 SmallVectorImpl<llvm::Constant *> &Elements,
1115 llvm::Constant *Filler) {
1118 if (Elements.size() < NonzeroLength && Filler->isNullValue())
1119 NonzeroLength = Elements.size();
1120 if (NonzeroLength == Elements.size()) {
1121 while (NonzeroLength > 0 && Elements[NonzeroLength - 1]->isNullValue())
1125 if (NonzeroLength == 0)
1126 return llvm::ConstantAggregateZero::get(DesiredType);
1130 if (TrailingZeroes >= 8) {
1131 assert(Elements.size() >= NonzeroLength &&
1132 "missing initializer for non-zero element");
1136 if (CommonElementType && NonzeroLength >= 8) {
1137 llvm::Constant *Initial = llvm::ConstantArray::get(
1138 llvm::ArrayType::get(CommonElementType, NonzeroLength),
1139 ArrayRef(Elements).take_front(NonzeroLength));
1141 Elements[0] = Initial;
1143 Elements.resize(NonzeroLength + 1);
1147 CommonElementType ? CommonElementType : DesiredType->getElementType();
1148 FillerType = llvm::ArrayType::get(FillerType, TrailingZeroes);
1149 Elements.back() = llvm::ConstantAggregateZero::get(FillerType);
1150 CommonElementType =
nullptr;
1154 if (Filler->getType() != CommonElementType)
1155 CommonElementType =
nullptr;
1159 if (CommonElementType)
1160 return llvm::ConstantArray::get(
1161 llvm::ArrayType::get(CommonElementType,
ArrayBound), Elements);
1164 llvm::SmallVector<llvm::Type *, 16> Types;
1165 Types.reserve(Elements.size());
1166 for (llvm::Constant *Elt : Elements)
1167 Types.push_back(Elt->getType());
1168 llvm::StructType *SType =
1170 return llvm::ConstantStruct::get(SType, Elements);
1179class ConstExprEmitter
1180 :
public ConstStmtVisitor<ConstExprEmitter, llvm::Constant *, QualType> {
1182 ConstantEmitter &Emitter;
1183 llvm::LLVMContext &VMContext;
1185 ConstExprEmitter(ConstantEmitter &emitter)
1186 : CGM(emitter.CGM), Emitter(emitter), VMContext(CGM.getLLVMContext()) {
1193 llvm::Constant *VisitStmt(
const Stmt *S, QualType
T) {
return nullptr; }
1195 llvm::Constant *VisitConstantExpr(
const ConstantExpr *CE, QualType
T) {
1201 llvm::Constant *VisitParenExpr(
const ParenExpr *PE, QualType
T) {
1206 VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *PE,
1211 llvm::Constant *VisitGenericSelectionExpr(
const GenericSelectionExpr *GE,
1213 return Visit(
GE->getResultExpr(),
T);
1216 llvm::Constant *VisitChooseExpr(
const ChooseExpr *CE, QualType
T) {
1220 llvm::Constant *VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E,
1225 llvm::Constant *ProduceIntToIntCast(
const Expr *E, QualType DestType) {
1226 QualType FromType = E->
getType();
1229 if (llvm::Constant *
C = Visit(E, FromType))
1230 if (
auto *CI = dyn_cast<llvm::ConstantInt>(
C)) {
1233 if (DstWidth == SrcWidth)
1236 ? CI->getValue().sextOrTrunc(DstWidth)
1237 : CI->getValue().zextOrTrunc(DstWidth);
1243 llvm::Constant *VisitCastExpr(
const CastExpr *E, QualType destType) {
1244 if (
const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
1252 "Destination type is not union type!");
1257 if (!
C)
return nullptr;
1259 auto destTy = ConvertType(destType);
1260 if (
C->getType() == destTy)
return C;
1264 SmallVector<llvm::Constant*, 2> Elts;
1265 SmallVector<llvm::Type*, 2> Types;
1267 Types.push_back(
C->getType());
1268 unsigned CurSize = CGM.
getDataLayout().getTypeAllocSize(
C->getType());
1269 unsigned TotalSize = CGM.
getDataLayout().getTypeAllocSize(destTy);
1271 assert(CurSize <= TotalSize &&
"Union size mismatch!");
1272 if (
unsigned NumPadBytes = TotalSize - CurSize) {
1273 llvm::Constant *Padding =
1275 Elts.push_back(Padding);
1276 Types.push_back(Padding->getType());
1279 llvm::StructType *STy = llvm::StructType::get(VMContext, Types,
false);
1280 return llvm::ConstantStruct::get(STy, Elts);
1283 case CK_AddressSpaceConversion: {
1287 llvm::Type *destTy = ConvertType(E->
getType());
1291 case CK_LValueToRValue: {
1297 dyn_cast<CompoundLiteralExpr>(subExpr->
IgnoreParens()))
1298 return Visit(E->getInitializer(), destType);
1302 case CK_AtomicToNonAtomic:
1303 case CK_NonAtomicToAtomic:
1305 case CK_ConstructorConversion:
1306 return Visit(subExpr, destType);
1308 case CK_ArrayToPointerDecay:
1309 if (
const auto *S = dyn_cast<StringLiteral>(subExpr))
1312 case CK_NullToPointer:
1313 if (Visit(subExpr, destType))
1317 case CK_IntToOCLSampler:
1318 llvm_unreachable(
"global sampler variables are not generated");
1320 case CK_IntegralCast:
1321 return ProduceIntToIntCast(subExpr, destType);
1323 case CK_Dependent: llvm_unreachable(
"saw dependent cast!");
1325 case CK_BuiltinFnToFnPtr:
1326 llvm_unreachable(
"builtin functions are handled elsewhere");
1328 case CK_ReinterpretMemberPointer:
1329 case CK_DerivedToBaseMemberPointer:
1330 case CK_BaseToDerivedMemberPointer: {
1332 if (!
C)
return nullptr;
1337 case CK_ObjCObjectLValueCast:
1338 case CK_ARCProduceObject:
1339 case CK_ARCConsumeObject:
1340 case CK_ARCReclaimReturnedObject:
1341 case CK_ARCExtendBlockObject:
1342 case CK_CopyAndAutoreleaseBlockObject:
1350 case CK_LValueBitCast:
1351 case CK_LValueToRValueBitCast:
1352 case CK_NullToMemberPointer:
1353 case CK_UserDefinedConversion:
1354 case CK_CPointerToObjCPointerCast:
1355 case CK_BlockPointerToObjCPointerCast:
1356 case CK_AnyPointerToBlockPointerCast:
1357 case CK_FunctionToPointerDecay:
1358 case CK_BaseToDerived:
1359 case CK_DerivedToBase:
1360 case CK_UncheckedDerivedToBase:
1361 case CK_MemberPointerToBoolean:
1362 case CK_VectorSplat:
1363 case CK_FloatingRealToComplex:
1364 case CK_FloatingComplexToReal:
1365 case CK_FloatingComplexToBoolean:
1366 case CK_FloatingComplexCast:
1367 case CK_FloatingComplexToIntegralComplex:
1368 case CK_IntegralRealToComplex:
1369 case CK_IntegralComplexToReal:
1370 case CK_IntegralComplexToBoolean:
1371 case CK_IntegralComplexCast:
1372 case CK_IntegralComplexToFloatingComplex:
1373 case CK_PointerToIntegral:
1374 case CK_PointerToBoolean:
1375 case CK_BooleanToSignedIntegral:
1376 case CK_IntegralToPointer:
1377 case CK_IntegralToBoolean:
1378 case CK_IntegralToFloating:
1379 case CK_FloatingToIntegral:
1380 case CK_FloatingToBoolean:
1381 case CK_FloatingCast:
1382 case CK_FloatingToFixedPoint:
1383 case CK_FixedPointToFloating:
1384 case CK_FixedPointCast:
1385 case CK_FixedPointToBoolean:
1386 case CK_FixedPointToIntegral:
1387 case CK_IntegralToFixedPoint:
1388 case CK_ZeroToOCLOpaqueType:
1390 case CK_HLSLVectorTruncation:
1391 case CK_HLSLMatrixTruncation:
1392 case CK_HLSLArrayRValue:
1393 case CK_HLSLElementwiseCast:
1394 case CK_HLSLAggregateSplatCast:
1397 llvm_unreachable(
"Invalid CastKind");
1400 llvm::Constant *VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *DIE,
1407 llvm::Constant *VisitExprWithCleanups(
const ExprWithCleanups *E, QualType
T) {
1411 llvm::Constant *VisitIntegerLiteral(
const IntegerLiteral *I, QualType
T) {
1415 static APValue withDestType(ASTContext &Ctx,
const Expr *E, QualType SrcType,
1416 QualType DestType,
const llvm::APSInt &
Value) {
1421 llvm::RoundingMode RM =
1423 if (RM == llvm::RoundingMode::Dynamic)
1424 RM = llvm::RoundingMode::NearestTiesToEven;
1432 llvm::Constant *EmitArrayInitialization(
const InitListExpr *ILE, QualType
T) {
1434 assert(CAT &&
"can't emit array init for non-constant-bound array");
1436 const uint64_t NumElements = CAT->getZExtSize();
1438 if (
const auto *Embed =
1439 dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1440 NumInitElements += Embed->getDataElementCount() - 1;
1441 if (NumInitElements > NumElements) {
1442 NumInitElements = NumElements;
1450 uint64_t NumInitableElts = std::min<uint64_t>(NumInitElements, NumElements);
1452 QualType EltType = CAT->getElementType();
1455 llvm::Constant *fillC =
nullptr;
1463 SmallVector<llvm::Constant *, 16> Elts;
1464 if (fillC && fillC->isNullValue())
1465 Elts.reserve(NumInitableElts + 1);
1467 Elts.reserve(NumElements);
1469 llvm::Type *CommonElementType =
nullptr;
1470 auto Emit = [&](
const Expr *
Init,
unsigned ArrayIndex) {
1471 llvm::Constant *
C =
nullptr;
1475 if (ArrayIndex == 0)
1476 CommonElementType =
C->getType();
1477 else if (
C->getType() != CommonElementType)
1478 CommonElementType =
nullptr;
1483 unsigned ArrayIndex = 0;
1484 QualType DestTy = CAT->getElementType();
1485 for (
unsigned i = 0; i < ILE->
getNumInits(); ++i) {
1487 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1488 StringLiteral *SL = EmbedS->getDataStringLiteral();
1492 for (
unsigned I = EmbedS->getStartingElementPos(),
1493 N = EmbedS->getDataElementCount();
1494 I != EmbedS->getStartingElementPos() + N; ++I) {
1509 if ((ArrayIndex - EmbedS->getDataElementCount()) == 0)
1510 CommonElementType =
C->getType();
1511 else if (
C->getType() != CommonElementType)
1512 CommonElementType =
nullptr;
1514 if (!Emit(
Init, ArrayIndex))
1520 llvm::ArrayType *Desired =
1522 return EmitArrayConstant(CGM, Desired, CommonElementType, NumElements, Elts,
1526 llvm::Constant *EmitRecordInitialization(
const InitListExpr *ILE,
1528 return ConstStructBuilder::BuildStruct(Emitter, ILE,
T);
1531 llvm::Constant *VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E,
1536 llvm::Constant *VisitInitListExpr(
const InitListExpr *ILE, QualType
T) {
1541 return EmitArrayInitialization(ILE,
T);
1544 return EmitRecordInitialization(ILE,
T);
1550 VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E,
1551 QualType destType) {
1552 auto C = Visit(E->
getBase(), destType);
1556 ConstantAggregateBuilder
Const(CGM);
1559 if (!EmitDesignatedInitUpdater(Emitter, Const,
CharUnits::Zero(), destType,
1564 bool HasFlexibleArray =
false;
1567 return Const.build(ValTy, HasFlexibleArray);
1570 llvm::Constant *VisitCXXConstructExpr(
const CXXConstructExpr *E,
1577 assert(E->
getNumArgs() == 1 &&
"trivial ctor with > 1 argument");
1579 "trivial ctor has argument but isn't a copy/move ctor");
1581 const Expr *Arg = E->
getArg(0);
1583 "argument to copy ctor is of wrong type");
1587 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(Arg))
1588 return Visit(MTE->getSubExpr(), Ty);
1596 llvm::Constant *VisitStringLiteral(
const StringLiteral *E, QualType
T) {
1601 llvm::Constant *VisitObjCEncodeExpr(
const ObjCEncodeExpr *E, QualType
T) {
1608 assert(CAT &&
"String data not of constant array type!");
1613 return llvm::ConstantDataArray::getString(VMContext, Str,
false);
1616 llvm::Constant *VisitUnaryExtension(
const UnaryOperator *E, QualType
T) {
1620 llvm::Constant *VisitUnaryMinus(
const UnaryOperator *U, QualType
T) {
1622 if (
auto *CI = dyn_cast<llvm::ConstantInt>(
C))
1623 return llvm::ConstantInt::get(CGM.
getLLVMContext(), -CI->getValue());
1627 llvm::Constant *VisitPackIndexingExpr(
const PackIndexingExpr *E, QualType
T) {
1632 llvm::Type *ConvertType(QualType
T) {
1639llvm::Constant *ConstantEmitter::validateAndPopAbstract(llvm::Constant *
C,
1640 AbstractState saved) {
1641 Abstract = saved.OldValue;
1643 assert(saved.OldPlaceholdersSize == PlaceholderAddresses.size() &&
1644 "created a placeholder while doing an abstract emission?");
1653 auto state = pushAbstract();
1655 return validateAndPopAbstract(
C, state);
1660 auto state = pushAbstract();
1662 return validateAndPopAbstract(
C, state);
1667 auto state = pushAbstract();
1669 return validateAndPopAbstract(
C, state);
1678 RetType =
CGM.getContext().getLValueReferenceType(RetType);
1685 auto state = pushAbstract();
1687 C = validateAndPopAbstract(
C, state);
1690 "internal error: could not emit constant value \"abstractly\"");
1691 C =
CGM.EmitNullConstant(destType);
1699 bool EnablePtrAuthFunctionTypeDiscrimination) {
1700 auto state = pushAbstract();
1702 tryEmitPrivate(value, destType, EnablePtrAuthFunctionTypeDiscrimination);
1703 C = validateAndPopAbstract(
C, state);
1706 "internal error: could not emit constant value \"abstractly\"");
1707 C =
CGM.EmitNullConstant(destType);
1721 for (
auto [_, GV] : PlaceholderAddresses)
1722 GV->eraseFromParent();
1723 PlaceholderAddresses.clear();
1727 return markIfFailed(
Init);
1733 initializeNonAbstract(destAddrSpace);
1740 initializeNonAbstract(destAddrSpace);
1742 assert(
C &&
"couldn't emit constant value non-abstractly?");
1747 assert(!Abstract &&
"cannot get current address for abstract constant");
1753 auto global =
new llvm::GlobalVariable(
CGM.getModule(),
CGM.Int8Ty,
true,
1754 llvm::GlobalValue::PrivateLinkage,
1758 llvm::GlobalVariable::NotThreadLocal,
1759 CGM.getContext().getTargetAddressSpace(DestAddressSpace));
1761 PlaceholderAddresses.push_back(std::make_pair(
nullptr, global));
1767 llvm::GlobalValue *placeholder) {
1768 assert(!PlaceholderAddresses.empty());
1769 assert(PlaceholderAddresses.back().first ==
nullptr);
1770 assert(PlaceholderAddresses.back().second == placeholder);
1771 PlaceholderAddresses.back().first = signal;
1775 struct ReplacePlaceholders {
1779 llvm::Constant *
Base;
1780 llvm::Type *BaseValueTy =
nullptr;
1783 llvm::DenseMap<llvm::Constant*, llvm::GlobalVariable*> PlaceholderAddresses;
1786 llvm::DenseMap<llvm::GlobalVariable*, llvm::Constant*> Locations;
1794 ReplacePlaceholders(
CodeGenModule &CGM, llvm::Constant *base,
1795 ArrayRef<std::pair<llvm::Constant*,
1796 llvm::GlobalVariable*>> addresses)
1797 : CGM(CGM),
Base(base),
1798 PlaceholderAddresses(addresses.begin(), addresses.end()) {
1801 void replaceInInitializer(llvm::Constant *init) {
1803 BaseValueTy = init->getType();
1806 Indices.push_back(0);
1807 IndexValues.push_back(
nullptr);
1810 findLocations(init);
1813 assert(IndexValues.size() == Indices.size() &&
"mismatch");
1814 assert(Indices.size() == 1 &&
"didn't pop all indices");
1817 assert(Locations.size() == PlaceholderAddresses.size() &&
1818 "missed a placeholder?");
1824 for (
auto &entry : Locations) {
1825 assert(entry.first->getName() ==
"" &&
"not a placeholder!");
1826 entry.first->replaceAllUsesWith(entry.second);
1827 entry.first->eraseFromParent();
1832 void findLocations(llvm::Constant *init) {
1834 if (
auto agg = dyn_cast<llvm::ConstantAggregate>(init)) {
1835 for (
unsigned i = 0, e = agg->getNumOperands(); i != e; ++i) {
1836 Indices.push_back(i);
1837 IndexValues.push_back(
nullptr);
1839 findLocations(agg->getOperand(i));
1841 IndexValues.pop_back();
1849 auto it = PlaceholderAddresses.find(init);
1850 if (it != PlaceholderAddresses.end()) {
1851 setLocation(it->second);
1856 if (
auto expr = dyn_cast<llvm::ConstantExpr>(init)) {
1857 init =
expr->getOperand(0);
1864 void setLocation(llvm::GlobalVariable *placeholder) {
1865 assert(!Locations.contains(placeholder) &&
1866 "already found location for placeholder!");
1871 assert(Indices.size() == IndexValues.size());
1872 for (
size_t i = Indices.size() - 1; i !=
size_t(-1); --i) {
1873 if (IndexValues[i]) {
1875 for (
size_t j = 0; j != i + 1; ++j) {
1876 assert(IndexValues[j] &&
1885 IndexValues[i] = llvm::ConstantInt::get(CGM.
Int32Ty, Indices[i]);
1888 llvm::Constant *location = llvm::ConstantExpr::getInBoundsGetElementPtr(
1889 BaseValueTy, Base, IndexValues);
1891 Locations.insert({placeholder, location});
1897 assert(InitializedNonAbstract &&
1898 "finalizing emitter that was used for abstract emission?");
1899 assert(!Finalized &&
"finalizing emitter multiple times");
1900 assert(global->getInitializer());
1905 if (!PlaceholderAddresses.empty()) {
1906 ReplacePlaceholders(
CGM, global, PlaceholderAddresses)
1907 .replaceInInitializer(global->getInitializer());
1908 PlaceholderAddresses.clear();
1913 assert((!InitializedNonAbstract || Finalized || Failed) &&
1914 "not finalized after being initialized for non-abstract emission");
1915 assert(PlaceholderAddresses.empty() &&
"unhandled placeholders");
1921 type.getQualifiers());
1934 dyn_cast_or_null<CXXConstructExpr>(D.
getInit())) {
1944 assert(E &&
"No initializer to emit");
1948 if (llvm::Constant *
C = ConstExprEmitter(*this).Visit(E, nonMemoryDestType))
1955 assert(!value->allowConstexprUnknown() &&
1956 "Constexpr unknown values are not allowed in CodeGen");
2000 assert(Schema &&
"applying trivial ptrauth schema");
2003 return UnsignedPointer;
2005 unsigned Key = Schema.
getKey();
2008 llvm::GlobalValue *StorageAddress =
nullptr;
2017 llvm::ConstantInt *Discriminator =
2020 llvm::Constant *SignedPointer =
CGM.getConstantSignedPointer(
2021 UnsignedPointer, Key, StorageAddress, Discriminator);
2026 return SignedPointer;
2034 QualType destValueType = AT->getValueType();
2037 uint64_t innerSize =
CGM.getContext().getTypeSize(destValueType);
2038 uint64_t outerSize =
CGM.getContext().getTypeSize(destType);
2039 if (innerSize == outerSize)
2042 assert(innerSize < outerSize &&
"emitted over-large constant for atomic");
2043 llvm::Constant *elts[] = {
2045 llvm::ConstantAggregateZero::get(
2046 llvm::ArrayType::get(
CGM.Int8Ty, (outerSize - innerSize) / 8))
2048 return llvm::ConstantStruct::getAnon(elts);
2053 if ((
C->getType()->isIntegerTy(1) && !destType->
isBitIntType()) ||
2056 llvm::Type *boolTy =
CGM.getTypes().ConvertTypeForMem(destType);
2057 llvm::Constant *Res = llvm::ConstantFoldCastOperand(
2058 llvm::Instruction::ZExt,
C, boolTy,
CGM.getDataLayout());
2059 assert(Res &&
"Constant folding must succeed");
2064 llvm::Type *MemTy =
CGM.getTypes().ConvertTypeForMem(destType);
2065 if (
C->getType() != MemTy) {
2066 ConstantAggregateBuilder Builder(
CGM);
2067 llvm::Type *LoadStoreTy =
2068 CGM.getTypes().convertTypeForLoadStore(destType);
2072 llvm::Constant *Res = llvm::ConstantFoldCastOperand(
2074 ? llvm::Instruction::SExt
2075 : llvm::Instruction::ZExt,
2076 CI, LoadStoreTy,
CGM.getDataLayout());
2077 if (
CGM.getTypes().typeRequiresSplitIntoByteArray(destType,
2082 Builder.addBits(
Value, 0,
false);
2083 return Builder.build(MemTy,
false);
2094 assert(!destType->
isVoidType() &&
"can't emit a void constant");
2097 if (llvm::Constant *
C = ConstExprEmitter(*this).Visit(E, destType))
2122struct ConstantLValue {
2123 llvm::Constant *
Value;
2124 bool HasOffsetApplied;
2125 bool HasDestPointerAuth;
2127 ConstantLValue(llvm::Constant *value,
2128 bool hasOffsetApplied =
false,
2129 bool hasDestPointerAuth =
false)
2130 :
Value(value), HasOffsetApplied(hasOffsetApplied),
2131 HasDestPointerAuth(hasDestPointerAuth) {}
2134 : ConstantLValue(address.getPointer()) {}
2138class ConstantLValueEmitter :
public ConstStmtVisitor<ConstantLValueEmitter,
2141 ConstantEmitter &Emitter;
2144 bool EnablePtrAuthFunctionTypeDiscrimination;
2147 friend StmtVisitorBase;
2150 ConstantLValueEmitter(ConstantEmitter &emitter,
const APValue &value,
2152 bool EnablePtrAuthFunctionTypeDiscrimination =
true)
2153 : CGM(emitter.CGM), Emitter(emitter),
Value(value), DestType(destType),
2154 EnablePtrAuthFunctionTypeDiscrimination(
2155 EnablePtrAuthFunctionTypeDiscrimination) {}
2157 llvm::Constant *tryEmit();
2160 llvm::Constant *tryEmitAbsolute(llvm::Type *destTy);
2161 ConstantLValue tryEmitBase(
const APValue::LValueBase &base);
2163 ConstantLValue VisitStmt(
const Stmt *S) {
return nullptr; }
2164 ConstantLValue VisitConstantExpr(
const ConstantExpr *E);
2165 ConstantLValue VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
2166 ConstantLValue VisitStringLiteral(
const StringLiteral *E);
2167 ConstantLValue VisitObjCBoxedExpr(
const ObjCBoxedExpr *E);
2168 ConstantLValue VisitObjCEncodeExpr(
const ObjCEncodeExpr *E);
2169 ConstantLValue VisitObjCStringLiteral(
const ObjCStringLiteral *E);
2170 llvm::Constant *VisitObjCCollectionElement(
const Expr *E);
2171 ConstantLValue VisitObjCArrayLiteral(
const ObjCArrayLiteral *E);
2172 ConstantLValue VisitObjCDictionaryLiteral(
const ObjCDictionaryLiteral *E);
2173 ConstantLValue VisitPredefinedExpr(
const PredefinedExpr *E);
2174 ConstantLValue VisitAddrLabelExpr(
const AddrLabelExpr *E);
2175 ConstantLValue VisitCallExpr(
const CallExpr *E);
2176 ConstantLValue VisitBlockExpr(
const BlockExpr *E);
2177 ConstantLValue VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
2178 ConstantLValue VisitMaterializeTemporaryExpr(
2179 const MaterializeTemporaryExpr *E);
2181 ConstantLValue emitPointerAuthSignConstant(
const CallExpr *E);
2182 llvm::Constant *emitPointerAuthPointer(
const Expr *E);
2183 unsigned emitPointerAuthKey(
const Expr *E);
2184 std::pair<llvm::Constant *, llvm::ConstantInt *>
2185 emitPointerAuthDiscriminator(
const Expr *E);
2187 bool hasNonZeroOffset()
const {
2188 return !
Value.getLValueOffset().isZero();
2192 llvm::Constant *getOffset() {
2193 return llvm::ConstantInt::get(CGM.
Int64Ty,
2194 Value.getLValueOffset().getQuantity());
2198 llvm::Constant *applyOffset(llvm::Constant *
C) {
2199 if (!hasNonZeroOffset())
2202 return llvm::ConstantExpr::getPtrAdd(
C, getOffset());
2208llvm::Constant *ConstantLValueEmitter::tryEmit() {
2209 const APValue::LValueBase &base =
Value.getLValueBase();
2224 return tryEmitAbsolute(destTy);
2228 ConstantLValue result = tryEmitBase(base);
2231 llvm::Constant *value = result.Value;
2232 if (!value)
return nullptr;
2235 if (!result.HasOffsetApplied) {
2236 value = applyOffset(value);
2240 if (PointerAuthQualifier PointerAuth = DestType.
getPointerAuth();
2241 PointerAuth && !result.HasDestPointerAuth) {
2250 return llvm::ConstantExpr::getPointerCast(value, destTy);
2252 return llvm::ConstantExpr::getPtrToInt(value, destTy);
2258ConstantLValueEmitter::tryEmitAbsolute(llvm::Type *destTy) {
2261 if (
Value.isNullPointer()) {
2269 auto intptrTy = CGM.
getDataLayout().getIntPtrType(destPtrTy);
2271 C = llvm::ConstantFoldIntegerCast(getOffset(), intptrTy,
false,
2273 assert(
C &&
"Must have folded, as Offset is a ConstantInt");
2274 C = llvm::ConstantExpr::getIntToPtr(
C, destPtrTy);
2279ConstantLValueEmitter::tryEmitBase(
const APValue::LValueBase &base) {
2281 if (
const ValueDecl *D = base.
dyn_cast<
const ValueDecl*>()) {
2286 if (D->hasAttr<WeakRefAttr>())
2289 auto PtrAuthSign = [&](llvm::Constant *
C) {
2290 if (PointerAuthQualifier PointerAuth = DestType.
getPointerAuth()) {
2293 return ConstantLValue(
C,
true,
true);
2296 CGPointerAuthInfo AuthInfo;
2298 if (EnablePtrAuthFunctionTypeDiscrimination)
2302 if (hasNonZeroOffset())
2303 return ConstantLValue(
nullptr);
2307 C, AuthInfo.
getKey(),
nullptr,
2309 return ConstantLValue(
C,
true,
true);
2312 return ConstantLValue(
C);
2315 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
2317 if (FD->getType()->isCFIUncheckedCalleeFunctionType())
2319 return PtrAuthSign(
C);
2322 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
2324 if (!VD->hasLocalStorage()) {
2325 if (VD->isFileVarDecl() || VD->hasExternalStorage())
2328 if (VD->isLocalVarDecl()) {
2335 if (
const auto *GD = dyn_cast<MSGuidDecl>(D))
2338 if (
const auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D))
2341 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D))
2348 if (TypeInfoLValue TI = base.
dyn_cast<TypeInfoLValue>())
2352 return Visit(base.
get<
const Expr*>());
2356ConstantLValueEmitter::VisitConstantExpr(
const ConstantExpr *E) {
2363ConstantLValueEmitter::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
2364 ConstantEmitter CompoundLiteralEmitter(CGM, Emitter.
CGF);
2370ConstantLValueEmitter::VisitStringLiteral(
const StringLiteral *E) {
2375ConstantLValueEmitter::VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
2387ConstantLValueEmitter::VisitObjCStringLiteral(
const ObjCStringLiteral *E) {
2392ConstantLValueEmitter::VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
2399 "Non const NSNumber is being emitted as a constant");
2406 const bool IsBoolType =
2408 bool BoolValue =
false;
2414 Expr::EvalResult IntResult{};
2421 llvm::APFloat FloatValue(0.0);
2427 llvm_unreachable(
"SubExpr is expected to be evaluated as a numeric type");
2431ConstantLValueEmitter::VisitObjCCollectionElement(
const Expr *E) {
2434 QualType DestTy = CE->
getType();
2436 assert(CE->getCastKind() == CK_BitCast &&
2437 "Expected a CK_BitCast type for valid items in constant objc "
2438 "collection literals");
2441 ConstantLValue LV = Visit(Elm);
2443 llvm::Constant *Val = llvm::ConstantExpr::getBitCast(ConstVal, DstTy);
2448ConstantLValueEmitter::VisitObjCArrayLiteral(
const ObjCArrayLiteral *E) {
2449 SmallVector<llvm::Constant *, 16> ObjectExpressions;
2451 ObjectExpressions.reserve(NumElements);
2453 for (uint64_t i = 0; i < NumElements; i++) {
2454 llvm::Constant *Val = VisitObjCCollectionElement(E->
getElement(i));
2455 ObjectExpressions.push_back(Val);
2462ConstantLValue ConstantLValueEmitter::VisitObjCDictionaryLiteral(
2463 const ObjCDictionaryLiteral *E) {
2464 SmallVector<std::pair<llvm::Constant *, llvm::Constant *>, 16> KeysAndObjects;
2466 KeysAndObjects.reserve(NumElements);
2468 for (uint64_t i = 0; i < NumElements; i++) {
2469 llvm::Constant *Key =
2471 llvm::Constant *Val =
2473 KeysAndObjects.push_back({Key, Val});
2481ConstantLValueEmitter::VisitPredefinedExpr(
const PredefinedExpr *E) {
2486ConstantLValueEmitter::VisitAddrLabelExpr(
const AddrLabelExpr *E) {
2487 assert(Emitter.
CGF &&
"Invalid address of label expression outside function");
2493ConstantLValueEmitter::VisitCallExpr(
const CallExpr *E) {
2495 if (builtin == Builtin::BI__builtin_function_start)
2499 if (builtin == Builtin::BI__builtin_ptrauth_sign_constant)
2500 return emitPointerAuthSignConstant(E);
2502 if (builtin != Builtin::BI__builtin___CFStringMakeConstantString &&
2503 builtin != Builtin::BI__builtin___NSStringMakeConstantString)
2507 if (builtin == Builtin::BI__builtin___NSStringMakeConstantString) {
2516ConstantLValueEmitter::emitPointerAuthSignConstant(
const CallExpr *E) {
2517 llvm::Constant *UnsignedPointer = emitPointerAuthPointer(E->
getArg(0));
2518 unsigned Key = emitPointerAuthKey(E->
getArg(1));
2519 auto [StorageAddress, OtherDiscriminator] =
2520 emitPointerAuthDiscriminator(E->
getArg(2));
2523 UnsignedPointer, Key, StorageAddress, OtherDiscriminator);
2524 return SignedPointer;
2527llvm::Constant *ConstantLValueEmitter::emitPointerAuthPointer(
const Expr *E) {
2534 assert(
Result.Val.isLValue());
2536 assert(
Result.Val.getLValueOffset().isZero());
2537 return ConstantEmitter(CGM, Emitter.
CGF)
2541unsigned ConstantLValueEmitter::emitPointerAuthKey(
const Expr *E) {
2545std::pair<llvm::Constant *, llvm::ConstantInt *>
2546ConstantLValueEmitter::emitPointerAuthDiscriminator(
const Expr *E) {
2549 if (
const auto *
Call = dyn_cast<CallExpr>(E)) {
2550 if (
Call->getBuiltinCallee() ==
2551 Builtin::BI__builtin_ptrauth_blend_discriminator) {
2552 llvm::Constant *
Pointer = ConstantEmitter(CGM).emitAbstract(
2553 Call->getArg(0),
Call->getArg(0)->getType());
2555 Call->getArg(1),
Call->getArg(1)->getType()));
2560 llvm::Constant *
Result = ConstantEmitter(CGM).emitAbstract(E, E->
getType());
2561 if (
Result->getType()->isPointerTy())
2562 return {
Result,
nullptr};
2567ConstantLValueEmitter::VisitBlockExpr(
const BlockExpr *E) {
2568 StringRef functionName;
2569 if (
auto CGF = Emitter.
CGF)
2570 functionName = CGF->CurFn->getName();
2572 functionName =
"global";
2578ConstantLValueEmitter::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
2588ConstantLValueEmitter::VisitMaterializeTemporaryExpr(
2589 const MaterializeTemporaryExpr *E) {
2597 bool EnablePtrAuthFunctionTypeDiscrimination) {
2602 return llvm::UndefValue::get(
CGM.getTypes().ConvertType(DestType));
2604 return ConstantLValueEmitter(*
this,
Value, DestType,
2605 EnablePtrAuthFunctionTypeDiscrimination)
2610 (PointerAuth.authenticatesNullValues() ||
Value.getInt() != 0))
2612 return llvm::ConstantInt::get(
CGM.getLLVMContext(),
Value.getInt());
2614 return llvm::ConstantInt::get(
CGM.getLLVMContext(),
2615 Value.getFixedPoint().getValue());
2619 Complex[0] = llvm::ConstantInt::get(
CGM.getLLVMContext(),
2620 Value.getComplexIntReal());
2621 Complex[1] = llvm::ConstantInt::get(
CGM.getLLVMContext(),
2622 Value.getComplexIntImag());
2625 llvm::StructType *STy =
2627 return llvm::ConstantStruct::get(STy,
Complex);
2630 return llvm::ConstantFP::get(
CGM.getLLVMContext(),
Value.getFloat());
2634 Complex[0] = llvm::ConstantFP::get(
CGM.getLLVMContext(),
2635 Value.getComplexFloatReal());
2636 Complex[1] = llvm::ConstantFP::get(
CGM.getLLVMContext(),
2637 Value.getComplexFloatImag());
2640 llvm::StructType *STy =
2642 return llvm::ConstantStruct::get(STy,
Complex);
2645 unsigned NumElts =
Value.getVectorLength();
2648 for (
unsigned I = 0; I != NumElts; ++I) {
2651 Inits[I] = llvm::ConstantInt::get(
CGM.getLLVMContext(), Elt.
getInt());
2655 Inits[I] = llvm::UndefValue::get(
CGM.getTypes().ConvertType(
2658 llvm_unreachable(
"unsupported vector element type");
2660 return llvm::ConstantVector::get(
Inits);
2664 unsigned NumRows =
Value.getMatrixNumRows();
2665 unsigned NumCols =
Value.getMatrixNumColumns();
2666 unsigned NumElts = NumRows * NumCols;
2671 for (
unsigned Row = 0; Row != NumRows; ++Row) {
2672 for (
unsigned Col = 0; Col != NumCols; ++Col) {
2674 unsigned Idx = MT->getFlattenedIndex(Row, Col, IsRowMajor);
2677 llvm::ConstantInt::get(
CGM.getLLVMContext(), Elt.
getInt());
2680 llvm::ConstantFP::get(
CGM.getLLVMContext(), Elt.
getFloat());
2682 Inits[Idx] = llvm::PoisonValue::get(
2683 CGM.getTypes().ConvertType(MT->getElementType()));
2685 llvm_unreachable(
"unsupported matrix element type");
2688 return llvm::ConstantVector::get(
Inits);
2695 if (!LHS || !RHS)
return nullptr;
2698 llvm::Type *ResultType =
CGM.getTypes().ConvertType(DestType);
2699 LHS = llvm::ConstantExpr::getPtrToInt(LHS,
CGM.IntPtrTy);
2700 RHS = llvm::ConstantExpr::getPtrToInt(RHS,
CGM.IntPtrTy);
2701 llvm::Constant *AddrLabelDiff = llvm::ConstantExpr::getSub(LHS, RHS);
2706 return llvm::ConstantExpr::getTruncOrBitCast(AddrLabelDiff, ResultType);
2710 return ConstStructBuilder::BuildStruct(*
this,
Value, DestType);
2712 const ArrayType *ArrayTy =
CGM.getContext().getAsArrayType(DestType);
2713 unsigned NumElements =
Value.getArraySize();
2714 unsigned NumInitElts =
Value.getArrayInitializedElts();
2717 llvm::Constant *Filler =
nullptr;
2718 if (
Value.hasArrayFiller()) {
2727 if (Filler && Filler->isNullValue())
2728 Elts.reserve(NumInitElts + 1);
2730 Elts.reserve(NumElements);
2732 llvm::Type *CommonElementType =
nullptr;
2733 for (
unsigned I = 0; I < NumInitElts; ++I) {
2736 if (!
C)
return nullptr;
2739 CommonElementType =
C->getType();
2740 else if (
C->getType() != CommonElementType)
2741 CommonElementType =
nullptr;
2745 llvm::ArrayType *Desired =
2750 Desired = llvm::ArrayType::get(Desired->getElementType(), Elts.size());
2752 return EmitArrayConstant(
CGM, Desired, CommonElementType, NumElements, Elts,
2756 return CGM.getCXXABI().EmitMemberPointer(
Value, DestType);
2758 llvm_unreachable(
"Unknown APValue kind");
2763 return EmittedCompoundLiterals.lookup(E);
2768 bool Ok = EmittedCompoundLiterals.insert(std::make_pair(CLE, GV)).second;
2770 assert(
Ok &&
"CLE has already been emitted!");
2775 assert(E->
isFileScope() &&
"not a file-scope compound literal expr");
2788 return getCXXABI().EmitMemberFunctionPointer(method);
2798 llvm::Type *baseType,
2803 bool asCompleteObject) {
2805 llvm::StructType *structure =
2809 unsigned numElements = structure->getNumElements();
2810 std::vector<llvm::Constant *> elements(numElements);
2812 auto CXXR = dyn_cast<CXXRecordDecl>(record);
2815 for (
const auto &I : CXXR->bases()) {
2816 if (I.isVirtual()) {
2832 llvm::Type *baseType = structure->getElementType(fieldIndex);
2838 for (
const auto *Field : record->
fields()) {
2841 if (!Field->isBitField() &&
2849 if (Field->getIdentifier())
2851 if (
const auto *FieldRD = Field->getType()->getAsRecordDecl())
2852 if (FieldRD->findFirstNamedDataMember())
2858 if (CXXR && asCompleteObject) {
2859 for (
const auto &I : CXXR->vbases()) {
2868 if (elements[fieldIndex])
continue;
2870 llvm::Type *baseType = structure->getElementType(fieldIndex);
2876 for (
unsigned i = 0; i != numElements; ++i) {
2878 elements[i] = llvm::Constant::getNullValue(structure->getElementType(i));
2881 return llvm::ConstantStruct::get(structure, elements);
2886 llvm::Type *baseType,
2892 return llvm::Constant::getNullValue(baseType);
2905 llvm::Type *LT =
getTypes().ConvertTypeForMem(
T);
2906 if (
auto *PT = dyn_cast<llvm::PointerType>(LT))
2910 return llvm::Constant::getNullValue(LT);
2914 return llvm::Constant::getNullValue(
getTypes().ConvertTypeForMem(
T));
2917 llvm::ArrayType *ATy =
2922 llvm::Constant *Element =
2926 return llvm::ConstantArray::get(ATy, Array);
2929 if (
const auto *RD =
T->getAsRecordDecl())
2930 return ::EmitNullConstant(*
this, RD,
2933 assert(
T->isMemberDataPointerType() &&
2934 "Should only see pointers to data members here!");
2941 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.
static cir::GlobalViewAttr tryEmitGlobalCompoundLiteral(ConstantEmitter &emitter, const CompoundLiteralExpr *e)
Result
Implement __builtin_bit_cast and related operations.
llvm::MachO::Record Record
Defines AST-level helper utilities for matrix types.
llvm::APInt getValue() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
APValue & getStructField(unsigned i)
const FieldDecl * getUnionField() const
APValue & getStructVirtualBase(unsigned i)
unsigned getStructNumBases() const
unsigned getStructNumVirtualBases() const
APValue & getUnionValue()
bool isIndeterminate() const
@ 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)
const ConstantArrayType * getAsConstantArrayType(QualType T) const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
bool isPFPField(const FieldDecl *Field) const
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,...
const LangOptions & getLangOpts() const
bool arePFPFieldsTriviallyCopyable(const RecordDecl *RD) const
Returns whether this record's PFP fields (if any) are trivially copyable (i.e.
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.
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.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
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.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
bool hasOwnVFPtr() const
hasOwnVFPtr - Does this class provide its own virtual-function table pointer, rather than inheriting ...
CharUnits getSize() const
getSize - Get the record size in characters.
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 getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - 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
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.
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 isTypeOperand() const
QualType getTypeOperand(const ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
Expr * getExprOperand() const
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.
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.
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
virtual llvm::Constant * getVTableAddressPoint(BaseSubobject Base, const CXXRecordDecl *VTableClass)=0
Get the address point of the vtable for the given base subobject.
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 ConstantAddress GenerateConstantNumber(const bool Value, const QualType &Ty)=0
virtual ConstantAddress GenerateConstantDictionary(const ObjCDictionaryLiteral *E, ArrayRef< std::pair< llvm::Constant *, llvm::Constant * > > KeysAndObjects)=0
virtual ConstantAddress GenerateConstantString(const StringLiteral *)=0
Generate a constant string object.
virtual ConstantAddress GenerateConstantArray(const ArrayRef< llvm::Constant * > &Objects)=0
llvm::Value * getDiscriminator() const
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.
llvm::BlockAddress * GetAddrOfLabel(const LabelDecl *L)
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
llvm::GlobalValue * getPFPDeactivationSymbol(const FieldDecl *FD)
llvm::Constant * performAddrSpaceCast(llvm::Constant *Src, llvm::Type *DestTy)
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.
std::optional< PointerAuthQualifier > getVTablePointerAuthentication(const CXXRecordDecl *thisClass, bool IsVTTEntry=false)
llvm::Constant * getRawFunctionPointer(GlobalDecl GD, llvm::Type *Ty=nullptr)
Return a function pointer for a reference to the given function.
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
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)
Returns LLVM linkage for a declarator.
llvm::Constant * getMemberPointerConstant(const UnaryOperator *e)
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
ConstantAddress GetWeakRefReference(const ValueDecl *VD)
Get a reference to the target of VD.
std::string getPFPFieldName(const FieldDecl *FD)
CGPointerAuthInfo getFunctionPointerAuthInfo(QualType T)
Return the abstract pointer authentication schema for a pointer to the given function type.
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 shouldZeroInitPadding() const
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.
llvm::Constant * getConstantSignedPointer(llvm::Constant *Pointer, const PointerAuthSchema &Schema, llvm::Constant *StorageAddress, GlobalDecl SchemaDecl, QualType SchemaType)
Sign a constant pointer using the given scheme, producing a constant with the same IR type.
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.
llvm::Type * convertTypeForLoadStore(QualType T, llvm::Type *LLVMTy=nullptr)
Given that T is a scalar type, return the IR type that should be used for load and store operations.
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
A specialization of Address that requires the address to be an LLVM Constant.
ConstantAddress withElementType(llvm::Type *ElemTy) const
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)
bool isInConstantContext() const
llvm::Constant * tryEmitAbstract(const Expr *E, QualType T)
Try to emit the result of the given expression as an abstract constant.
CodeGenFunction *const CGF
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)
bool isAbstract() const
Is the current emission context abstract?
llvm::Constant * tryEmitConstantSignedPointer(llvm::Constant *Ptr, PointerAuthQualifier Auth)
Try to emit a constant signed pointer, given a raw pointer and the destination ptrauth qualifier.
CompoundLiteralExpr - [C99 6.5.2.5].
const Expr * getInitializer() const
Represents the canonical version of C arrays with a specified constant size.
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
APValue getAPValueResult() const
bool hasAPValueResult() const
Represents a concrete matrix type with constant number of rows and columns.
InitListExpr * getUpdater() const
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...
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Returns the set of floating point options that apply to this expression.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating 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 isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
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...
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
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...
RoundingMode getRoundingMode() const
const Expr * getSubExpr() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
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
ArrayRef< Expr * > inits() const
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.
Expr * getElement(unsigned Index)
getElement - Return the Element at the specified index.
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c array literal.
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c dictionary literal.
ObjCDictionaryElement getKeyValueElement(unsigned Index) const
QualType getEncodedType() const
StringLiteral * getString()
Expr * getSelectedExpr() const
const Expr * getSubExpr() const
Pointer-authentication qualifiers.
bool isAddressDiscriminated() const
unsigned getExtraDiscriminator() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
StringLiteral * getFunctionName()
A (possibly-)qualified type.
PointerAuthQualifier getPointerAuth() const
LangAS getAddressSpace() const
Return the address space of this type.
bool isConstantStorage(const ASTContext &Ctx, bool ExcludeCtor, bool ExcludeDtor)
Represents a struct/union/class.
bool hasFlexibleArrayMember() const
field_iterator field_end() const
field_range fields() const
specific_decl_iterator< FieldDecl > field_iterator
field_iterator field_begin() const
Encodes a location in the source.
StringLiteral - This represents a string literal expression, e.g.
uint32_t getCodeUnit(size_t i) const
Expr * getReplacement() const
bool isBooleanType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isPackedVectorBoolType(const ASTContext &ctx) const
bool isIncompleteArrayType() const
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
CXXRecordDecl * castAsCXXRecordDecl() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isExtVectorBoolType() const
bool isBitIntType() const
RecordDecl * castAsRecordDecl() const
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
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.
TLSKind getTLSKind() const
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
const Expr * getInit() const
const APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
@ TLS_None
Not a TLS variable.
Represents a GCC generic vector type.
QualType getElementType() const
bool isEmptyRecordForLayout(const ASTContext &Context, QualType T)
isEmptyRecordForLayout - Return true iff a structure contains only empty base classes (per isEmptyRec...
bool isEmptyFieldForLayout(const ASTContext &Context, const FieldDecl *FD)
isEmptyFieldForLayout - Return true iff the field is "empty", that is, either a zero-width bit-field ...
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.
uint32_t Literal
Literals are represented as positive integers.
bool Const(InterpState &S, const T &Arg)
bool GE(InterpState &S, CodePtr OpPC)
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
@ Success
Annotation was successful.
@ Finalize
'finalize' clause, allowed on 'exit data' directive.
bool isMatrixRowMajor(const LangOptions &LangOpts, QualType T)
Returns true if matrices of T should be laid out in row-major order.
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
@ SD_Static
Static storage duration.
@ Result
The result type of a method or function.
const FunctionProtoType * T
@ Type
The name was classified as a type.
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.
U cast(CodeGen::Address addr)
@ ArrayBound
Array bound in array declarator or new-expression.
unsigned Size
The total size of the bit-field, in bits.
llvm::PointerType * VoidPtrTy
llvm::IntegerType * Int64Ty
llvm::IntegerType * CharTy
char
llvm::IntegerType * Int32Ty
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
Expr * Value
The value of the dictionary element.
Expr * Key
The key for the dictionary element.