30#include "llvm/ADT/STLExtras.h"
31#include "llvm/ADT/Sequence.h"
32#include "llvm/Analysis/ConstantFolding.h"
33#include "llvm/IR/Constants.h"
34#include "llvm/IR/DataLayout.h"
35#include "llvm/IR/Function.h"
36#include "llvm/IR/GlobalVariable.h"
37#include "llvm/Support/SipHash.h"
47class ConstExprEmitter;
50 llvm::Type *Ty = CGM.
CharTy;
52 Ty = llvm::ArrayType::get(Ty, PadSize.
getQuantity());
54 return llvm::Constant::getNullValue(Ty);
56 return llvm::UndefValue::get(Ty);
59struct ConstantAggregateBuilderUtils {
62 ConstantAggregateBuilderUtils(CodeGenModule &CGM) : CGM(CGM) {}
64 CharUnits getAlignment(
const llvm::Constant *
C)
const {
66 CGM.getDataLayout().getABITypeAlign(
C->getType()));
69 CharUnits getSize(llvm::Type *Ty)
const {
73 CharUnits getSize(
const llvm::Constant *
C)
const {
74 return getSize(
C->getType());
77 llvm::Constant *getPadding(CharUnits PadSize)
const {
78 return ::getPadding(CGM, PadSize);
81 llvm::Constant *getZeroes(CharUnits ZeroSize)
const {
82 llvm::Type *Ty = llvm::ArrayType::get(CGM.CharTy, ZeroSize.
getQuantity());
83 return llvm::ConstantAggregateZero::get(Ty);
89class ConstantAggregateBuilder :
private ConstantAggregateBuilderUtils {
98 llvm::SmallVector<llvm::Constant*, 32> Elems;
99 llvm::SmallVector<CharUnits, 32> Offsets;
108 bool NaturalLayout =
true;
110 bool split(
size_t Index, CharUnits Hint);
111 std::optional<size_t> splitAt(CharUnits Pos);
113 static llvm::Constant *buildFrom(CodeGenModule &CGM,
114 ArrayRef<llvm::Constant *> Elems,
115 ArrayRef<CharUnits> Offsets,
116 CharUnits StartOffset, CharUnits Size,
117 bool NaturalLayout, llvm::Type *DesiredTy,
118 bool AllowOversized);
121 ConstantAggregateBuilder(CodeGenModule &CGM)
122 : ConstantAggregateBuilderUtils(CGM) {}
129 bool add(llvm::Constant *
C, CharUnits Offset,
bool AllowOverwrite);
132 bool addBits(llvm::APInt Bits, uint64_t OffsetInBits,
bool AllowOverwrite);
136 void condense(CharUnits Offset, llvm::Type *DesiredTy);
143 llvm::Constant *build(llvm::Type *DesiredTy,
bool AllowOversized)
const {
145 NaturalLayout, DesiredTy, AllowOversized);
149template<
typename Container,
typename Range = std::initializer_list<
150 typename Container::value_type>>
151static void replace(Container &
C,
size_t BeginOff,
size_t EndOff, Range Vals) {
152 assert(BeginOff <= EndOff &&
"invalid replacement range");
153 llvm::replace(
C,
C.begin() + BeginOff,
C.begin() + EndOff, Vals);
156bool ConstantAggregateBuilder::add(llvm::Constant *
C,
CharUnits Offset,
157 bool AllowOverwrite) {
159 if (Offset >= Size) {
160 CharUnits Align = getAlignment(
C);
161 CharUnits AlignedSize =
Size.alignTo(Align);
162 if (AlignedSize > Offset || Offset.
alignTo(Align) != Offset)
163 NaturalLayout =
false;
164 else if (AlignedSize < Offset) {
165 Elems.push_back(getPadding(Offset - Size));
166 Offsets.push_back(Size);
169 Offsets.push_back(Offset);
170 Size = Offset + getSize(
C);
175 std::optional<size_t> FirstElemToReplace = splitAt(Offset);
176 if (!FirstElemToReplace)
179 CharUnits CSize = getSize(
C);
180 std::optional<size_t> LastElemToReplace = splitAt(Offset + CSize);
181 if (!LastElemToReplace)
184 assert((FirstElemToReplace == LastElemToReplace || AllowOverwrite) &&
185 "unexpectedly overwriting field");
187 replace(Elems, *FirstElemToReplace, *LastElemToReplace, {
C});
188 replace(Offsets, *FirstElemToReplace, *LastElemToReplace, {Offset});
189 Size = std::max(Size, Offset + CSize);
190 NaturalLayout =
false;
194bool ConstantAggregateBuilder::addBits(llvm::APInt Bits, uint64_t OffsetInBits,
195 bool AllowOverwrite) {
201 unsigned OffsetWithinChar = OffsetInBits % CharWidth;
205 for (CharUnits OffsetInChars =
209 unsigned WantedBits =
210 std::min((uint64_t)Bits.getBitWidth(), CharWidth - OffsetWithinChar);
214 llvm::APInt BitsThisChar = Bits;
215 if (BitsThisChar.getBitWidth() < CharWidth)
216 BitsThisChar = BitsThisChar.zext(CharWidth);
220 int Shift = Bits.getBitWidth() - CharWidth + OffsetWithinChar;
222 BitsThisChar.lshrInPlace(Shift);
224 BitsThisChar = BitsThisChar.shl(-Shift);
226 BitsThisChar = BitsThisChar.shl(OffsetWithinChar);
228 if (BitsThisChar.getBitWidth() > CharWidth)
229 BitsThisChar = BitsThisChar.trunc(CharWidth);
231 if (WantedBits == CharWidth) {
234 OffsetInChars, AllowOverwrite);
239 std::optional<size_t> FirstElemToUpdate = splitAt(OffsetInChars);
240 if (!FirstElemToUpdate)
242 std::optional<size_t> LastElemToUpdate =
244 if (!LastElemToUpdate)
246 assert(*LastElemToUpdate - *FirstElemToUpdate < 2 &&
247 "should have at most one element covering one byte");
250 llvm::APInt UpdateMask(CharWidth, 0);
252 UpdateMask.setBits(CharWidth - OffsetWithinChar - WantedBits,
253 CharWidth - OffsetWithinChar);
255 UpdateMask.setBits(OffsetWithinChar, OffsetWithinChar + WantedBits);
256 BitsThisChar &= UpdateMask;
258 if (*FirstElemToUpdate == *LastElemToUpdate ||
259 Elems[*FirstElemToUpdate]->isNullValue() ||
263 OffsetInChars,
true);
265 llvm::Constant *&ToUpdate = Elems[*FirstElemToUpdate];
268 auto *CI = dyn_cast<llvm::ConstantInt>(ToUpdate);
273 assert(CI->getBitWidth() == CharWidth &&
"splitAt failed");
274 assert((!(CI->getValue() & UpdateMask) || AllowOverwrite) &&
275 "unexpectedly overwriting bitfield");
276 BitsThisChar |= (CI->getValue() & ~UpdateMask);
277 ToUpdate = llvm::ConstantInt::get(CGM.
getLLVMContext(), BitsThisChar);
282 if (WantedBits == Bits.getBitWidth())
287 Bits.lshrInPlace(WantedBits);
288 Bits = Bits.trunc(Bits.getBitWidth() - WantedBits);
291 OffsetWithinChar = 0;
301std::optional<size_t> ConstantAggregateBuilder::splitAt(CharUnits Pos) {
303 return Offsets.size();
306 auto FirstAfterPos = llvm::upper_bound(Offsets, Pos);
307 if (FirstAfterPos == Offsets.begin())
311 size_t LastAtOrBeforePosIndex = FirstAfterPos - Offsets.begin() - 1;
312 if (Offsets[LastAtOrBeforePosIndex] == Pos)
313 return LastAtOrBeforePosIndex;
316 if (Offsets[LastAtOrBeforePosIndex] +
317 getSize(Elems[LastAtOrBeforePosIndex]) <= Pos)
318 return LastAtOrBeforePosIndex + 1;
321 if (!split(LastAtOrBeforePosIndex, Pos))
329bool ConstantAggregateBuilder::split(
size_t Index, CharUnits Hint) {
330 NaturalLayout =
false;
331 llvm::Constant *
C = Elems[Index];
332 CharUnits Offset = Offsets[Index];
334 if (
auto *CA = dyn_cast<llvm::ConstantAggregate>(
C)) {
337 replace(Elems, Index, Index + 1,
338 llvm::map_range(llvm::seq(0u, CA->getNumOperands()),
339 [&](
unsigned Op) { return CA->getOperand(Op); }));
344 llvm::GetElementPtrInst::getTypeAtIndex(CA->getType(), (uint64_t)0);
345 CharUnits ElemSize = getSize(ElemTy);
347 Offsets, Index, Index + 1,
348 llvm::map_range(llvm::seq(0u, CA->getNumOperands()),
349 [&](
unsigned Op) { return Offset + Op * ElemSize; }));
353 const llvm::StructLayout *Layout =
355 replace(Offsets, Index, Index + 1,
357 llvm::seq(0u, CA->getNumOperands()), [&](
unsigned Op) {
358 return Offset + CharUnits::fromQuantity(
359 Layout->getElementOffset(Op));
365 if (
auto *CDS = dyn_cast<llvm::ConstantDataSequential>(
C)) {
369 CharUnits ElemSize = getSize(CDS->getElementType());
370 replace(Elems, Index, Index + 1,
371 llvm::map_range(llvm::seq(
uint64_t(0u), CDS->getNumElements()),
373 return CDS->getElementAsConstant(Elem);
375 replace(Offsets, Index, Index + 1,
377 llvm::seq(
uint64_t(0u), CDS->getNumElements()),
378 [&](uint64_t Elem) { return Offset + Elem * ElemSize; }));
384 CharUnits ElemSize = getSize(
C);
385 assert(Hint > Offset && Hint < Offset + ElemSize &&
"nothing to split");
386 replace(Elems, Index, Index + 1,
387 {getZeroes(Hint - Offset), getZeroes(Offset + ElemSize - Hint)});
388 replace(Offsets, Index, Index + 1, {Offset, Hint});
394 replace(Elems, Index, Index + 1, {});
395 replace(Offsets, Index, Index + 1, {});
406static llvm::Constant *
407EmitArrayConstant(CodeGenModule &CGM, llvm::ArrayType *DesiredType,
408 llvm::Type *CommonElementType, uint64_t
ArrayBound,
409 SmallVectorImpl<llvm::Constant *> &Elements,
410 llvm::Constant *Filler);
412llvm::Constant *ConstantAggregateBuilder::buildFrom(
413 CodeGenModule &CGM, ArrayRef<llvm::Constant *> Elems,
414 ArrayRef<CharUnits> Offsets, CharUnits StartOffset, CharUnits Size,
415 bool NaturalLayout, llvm::Type *DesiredTy,
bool AllowOversized) {
416 ConstantAggregateBuilderUtils Utils(CGM);
419 return llvm::UndefValue::get(DesiredTy);
421 auto Offset = [&](
size_t I) {
return Offsets[I] - StartOffset; };
425 if (llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(DesiredTy)) {
426 assert(!AllowOversized &&
"oversized array emission not supported");
428 bool CanEmitArray =
true;
429 llvm::Type *CommonType = Elems[0]->getType();
430 llvm::Constant *Filler = llvm::Constant::getNullValue(CommonType);
431 CharUnits ElemSize = Utils.getSize(ATy->getElementType());
432 SmallVector<llvm::Constant*, 32> ArrayElements;
433 for (
size_t I = 0; I != Elems.size(); ++I) {
435 if (Elems[I]->isNullValue())
439 if (Elems[I]->
getType() != CommonType ||
440 !Offset(I).isMultipleOf(ElemSize)) {
441 CanEmitArray =
false;
444 ArrayElements.resize(Offset(I) / ElemSize + 1, Filler);
445 ArrayElements.back() = Elems[I];
449 return EmitArrayConstant(CGM, ATy, CommonType, ATy->getNumElements(),
450 ArrayElements, Filler);
459 CharUnits DesiredSize = Utils.getSize(DesiredTy);
460 if (Size > DesiredSize) {
461 assert(AllowOversized &&
"Elems are oversized");
467 for (llvm::Constant *
C : Elems)
468 Align = std::max(Align, Utils.getAlignment(
C));
471 CharUnits AlignedSize =
Size.alignTo(Align);
474 ArrayRef<llvm::Constant*> UnpackedElems = Elems;
475 llvm::SmallVector<llvm::Constant*, 32> UnpackedElemStorage;
476 if (DesiredSize < AlignedSize || DesiredSize.
alignTo(Align) != DesiredSize) {
478 NaturalLayout =
false;
480 }
else if (DesiredSize > AlignedSize) {
483 UnpackedElemStorage.assign(Elems.begin(), Elems.end());
484 UnpackedElemStorage.push_back(Utils.getPadding(DesiredSize - Size));
485 UnpackedElems = UnpackedElemStorage;
491 llvm::SmallVector<llvm::Constant*, 32> PackedElems;
492 if (!NaturalLayout) {
494 for (
size_t I = 0; I != Elems.size(); ++I) {
495 CharUnits Align = Utils.getAlignment(Elems[I]);
496 CharUnits NaturalOffset = SizeSoFar.
alignTo(Align);
497 CharUnits DesiredOffset = Offset(I);
498 assert(DesiredOffset >= SizeSoFar &&
"elements out of order");
500 if (DesiredOffset != NaturalOffset)
502 if (DesiredOffset != SizeSoFar)
503 PackedElems.push_back(Utils.getPadding(DesiredOffset - SizeSoFar));
504 PackedElems.push_back(Elems[I]);
505 SizeSoFar = DesiredOffset + Utils.getSize(Elems[I]);
510 assert(SizeSoFar <= DesiredSize &&
511 "requested size is too small for contents");
512 if (SizeSoFar < DesiredSize)
513 PackedElems.push_back(Utils.getPadding(DesiredSize - SizeSoFar));
517 llvm::StructType *STy = llvm::ConstantStruct::getTypeForElements(
522 if (llvm::StructType *DesiredSTy = dyn_cast<llvm::StructType>(DesiredTy)) {
523 if (DesiredSTy->isLayoutIdentical(STy))
527 return llvm::ConstantStruct::get(STy,
Packed ? PackedElems : UnpackedElems);
530void ConstantAggregateBuilder::condense(CharUnits Offset,
531 llvm::Type *DesiredTy) {
532 CharUnits
Size = getSize(DesiredTy);
534 std::optional<size_t> FirstElemToReplace = splitAt(Offset);
535 if (!FirstElemToReplace)
537 size_t First = *FirstElemToReplace;
539 std::optional<size_t> LastElemToReplace = splitAt(Offset + Size);
540 if (!LastElemToReplace)
542 size_t Last = *LastElemToReplace;
548 if (Length == 1 && Offsets[
First] == Offset &&
549 getSize(Elems[
First]) == Size) {
552 auto *STy = dyn_cast<llvm::StructType>(DesiredTy);
553 if (STy && STy->getNumElements() == 1 &&
554 STy->getElementType(0) == Elems[
First]->getType())
555 Elems[
First] = llvm::ConstantStruct::get(STy, Elems[
First]);
559 llvm::Constant *Replacement = buildFrom(
560 CGM, ArrayRef(Elems).slice(
First, Length),
561 ArrayRef(Offsets).slice(
First, Length), Offset, getSize(DesiredTy),
562 false, DesiredTy,
false);
563 replace(Elems,
First,
Last, {Replacement});
571class ConstStructBuilder {
573 ConstantEmitter &Emitter;
574 ConstantAggregateBuilder &Builder;
575 CharUnits StartOffset;
578 static llvm::Constant *BuildStruct(ConstantEmitter &Emitter,
579 const InitListExpr *ILE,
581 static llvm::Constant *BuildStruct(ConstantEmitter &Emitter,
583 static bool UpdateStruct(ConstantEmitter &Emitter,
584 ConstantAggregateBuilder &Const, CharUnits Offset,
585 const InitListExpr *Updater);
588 ConstStructBuilder(ConstantEmitter &Emitter,
589 ConstantAggregateBuilder &Builder, CharUnits StartOffset)
590 : CGM(Emitter.CGM), Emitter(Emitter), Builder(Builder),
591 StartOffset(StartOffset) {}
593 bool AppendField(
const FieldDecl *Field, uint64_t FieldOffset,
594 llvm::Constant *InitExpr,
bool AllowOverwrite =
false);
596 bool AppendBytes(CharUnits FieldOffsetInChars, llvm::Constant *InitCst,
597 bool AllowOverwrite =
false);
599 bool AppendBitField(
const FieldDecl *Field, uint64_t FieldOffset,
600 llvm::Constant *InitExpr,
bool AllowOverwrite =
false);
602 bool Build(
const InitListExpr *ILE,
bool AllowOverwrite);
603 bool Build(
const APValue &Val,
const RecordDecl *RD,
bool IsPrimaryBase,
604 const CXXRecordDecl *VTableClass, CharUnits BaseOffset,
605 bool IsCompleteClass =
true);
606 bool DoZeroInitPadding(
const ASTRecordLayout &Layout,
unsigned FieldNo,
607 const FieldDecl &Field,
bool AllowOverwrite,
608 CharUnits &SizeSoFar,
bool &ZeroFieldSize);
609 bool DoZeroInitPadding(
const ASTRecordLayout &Layout,
bool AllowOverwrite,
610 CharUnits SizeSoFar);
611 llvm::Constant *
Finalize(QualType Ty);
614bool ConstStructBuilder::AppendField(
615 const FieldDecl *Field, uint64_t FieldOffset, llvm::Constant *InitCst,
616 bool AllowOverwrite) {
621 return AppendBytes(FieldOffsetInChars, InitCst, AllowOverwrite);
624bool ConstStructBuilder::AppendBytes(CharUnits FieldOffsetInChars,
625 llvm::Constant *InitCst,
626 bool AllowOverwrite) {
627 return Builder.add(InitCst, StartOffset + FieldOffsetInChars, AllowOverwrite);
630bool ConstStructBuilder::AppendBitField(
const FieldDecl *Field,
631 uint64_t FieldOffset, llvm::Constant *
C,
632 bool AllowOverwrite) {
634 llvm::ConstantInt *CI = dyn_cast<llvm::ConstantInt>(
C);
640 llvm::Type *LoadType =
642 llvm::Constant *FoldedConstant = llvm::ConstantFoldLoadFromConst(
644 CI = dyn_cast_if_present<llvm::ConstantInt>(FoldedConstant);
649 const CGRecordLayout &RL =
652 llvm::APInt FieldValue = CI->getValue();
658 if (Info.
Size > FieldValue.getBitWidth())
659 FieldValue = FieldValue.zext(Info.
Size);
662 if (Info.
Size < FieldValue.getBitWidth())
663 FieldValue = FieldValue.trunc(Info.
Size);
665 return Builder.addBits(FieldValue,
670static bool EmitDesignatedInitUpdater(ConstantEmitter &Emitter,
671 ConstantAggregateBuilder &Const,
672 CharUnits Offset, QualType
Type,
673 const InitListExpr *Updater) {
674 if (
Type->isRecordType())
675 return ConstStructBuilder::UpdateStruct(Emitter, Const, Offset, Updater);
684 llvm::Constant *FillC =
nullptr;
693 unsigned NumElementsToUpdate =
694 FillC ? CAT->getZExtSize() : Updater->
getNumInits();
695 for (
unsigned I = 0; I != NumElementsToUpdate; ++I, Offset += ElemSize) {
696 const Expr *
Init =
nullptr;
697 if (I < Updater->getNumInits())
700 if (!
Init && FillC) {
701 if (!
Const.add(FillC, Offset,
true))
705 }
else if (
const auto *ChildILE = dyn_cast<InitListExpr>(
Init)) {
706 if (!EmitDesignatedInitUpdater(Emitter, Const, Offset, ElemType,
710 Const.condense(Offset, ElemTy);
713 if (!
Const.add(Val, Offset,
true))
721bool ConstStructBuilder::Build(
const InitListExpr *ILE,
bool AllowOverwrite) {
725 unsigned FieldNo = -1;
726 unsigned ElementNo = 0;
731 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
732 if (CXXRD->getNumBases())
736 bool ZeroFieldSize =
false;
739 for (FieldDecl *Field : RD->fields()) {
748 if (
Field->isUnnamedBitField())
753 const Expr *
Init =
nullptr;
754 if (ElementNo < ILE->getNumInits())
756 if (isa_and_nonnull<NoInitExpr>(
Init)) {
757 if (ZeroInitPadding &&
758 !DoZeroInitPadding(Layout, FieldNo, *Field, AllowOverwrite, SizeSoFar,
772 if (ZeroInitPadding &&
773 !DoZeroInitPadding(Layout, FieldNo, *Field, AllowOverwrite, SizeSoFar,
780 if (AllowOverwrite &&
781 (
Field->getType()->isArrayType() ||
Field->getType()->isRecordType())) {
782 if (
auto *SubILE = dyn_cast<InitListExpr>(
Init)) {
785 if (!EmitDesignatedInitUpdater(Emitter, Builder, StartOffset + Offset,
786 Field->getType(), SubILE))
790 Builder.condense(StartOffset + Offset,
796 llvm::Constant *EltInit =
802 if (ZeroInitPadding && ZeroFieldSize)
806 if (!
Field->isBitField()) {
813 if (
Field->hasAttr<NoUniqueAddressAttr>())
814 AllowOverwrite =
true;
817 if (!AppendBitField(Field, Layout.
getFieldOffset(FieldNo), EltInit,
823 if (ZeroInitPadding && !DoZeroInitPadding(Layout, AllowOverwrite, SizeSoFar))
831 BaseInfo(
const CXXRecordDecl *Decl, CharUnits Offset,
unsigned Index)
832 : Decl(Decl), Offset(Offset), Index(Index) {
835 const CXXRecordDecl *Decl;
839 bool operator<(
const BaseInfo &O)
const {
return Offset < O.Offset; }
843bool ConstStructBuilder::Build(
const APValue &Val,
const RecordDecl *RD,
845 const CXXRecordDecl *VTableClass,
846 CharUnits Offset,
bool IsCompleteClass) {
852 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
855 llvm::Constant *VTableAddressPoint =
858 if (
auto Authentication =
862 VTableAddressPoint, *Authentication);
863 if (!VTableAddressPoint)
866 if (!AppendBytes(Offset, VTableAddressPoint))
872 SmallVector<BaseInfo, 8> Bases;
875 for (
const CXXBaseSpecifier &Base : CD->bases()) {
876 if (
Base.isVirtual())
878 const CXXRecordDecl *BD =
Base.getType()->getAsCXXRecordDecl();
880 Bases.push_back(BaseInfo(BD, BaseOffset, BaseNo));
883 llvm::stable_sort(Bases);
885 for (
const BaseInfo &Base : Bases) {
888 VTableClass, Offset +
Base.Offset,
false))
892 if (IsCompleteClass) {
896 for (
const CXXBaseSpecifier &Base : CD->vbases()) {
897 const CXXRecordDecl *BD =
Base.getType()->getAsCXXRecordDecl();
899 Bases.push_back(BaseInfo(BD, BaseOffset, BaseNo));
902 llvm::stable_sort(Bases);
904 for (
const BaseInfo &Base : Bases) {
907 IsPrimaryBase, VTableClass, Offset +
Base.Offset,
false))
914 unsigned FieldNo = 0;
917 bool ZeroFieldSize =
false;
920 bool AllowOverwrite =
false;
922 FieldEnd = RD->
field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
928 if (
Field->isUnnamedBitField() ||
935 llvm::Constant *EltInit =
941 llvm::ConstantInt *Disc;
942 llvm::Constant *AddrDisc;
946 Disc = llvm::ConstantInt::get(CGM.
Int64Ty, FieldSignature);
947 AddrDisc = llvm::ConstantPointerNull::get(CGM.
VoidPtrTy);
954 Disc = llvm::ConstantInt::get(CGM.
Int64Ty,
958 EltInit = llvm::ConstantPtrAuth::get(
959 EltInit, llvm::ConstantInt::get(CGM.
Int32Ty, 2), Disc, AddrDisc,
966 if (ZeroInitPadding) {
967 if (!DoZeroInitPadding(Layout, FieldNo, **Field, AllowOverwrite,
968 SizeSoFar, ZeroFieldSize))
975 if (!
Field->isBitField()) {
977 if (!AppendField(*Field, Layout.
getFieldOffset(FieldNo) + OffsetBits,
978 EltInit, AllowOverwrite))
982 if (
Field->hasAttr<NoUniqueAddressAttr>())
983 AllowOverwrite =
true;
986 if (!AppendBitField(*Field, Layout.
getFieldOffset(FieldNo) + OffsetBits,
987 EltInit, AllowOverwrite))
991 if (ZeroInitPadding && !DoZeroInitPadding(Layout, AllowOverwrite, SizeSoFar))
997bool ConstStructBuilder::DoZeroInitPadding(
998 const ASTRecordLayout &Layout,
unsigned FieldNo,
const FieldDecl &Field,
999 bool AllowOverwrite, CharUnits &SizeSoFar,
bool &ZeroFieldSize) {
1002 if (SizeSoFar < StartOffset)
1003 if (!AppendBytes(SizeSoFar, getPadding(CGM, StartOffset - SizeSoFar),
1007 if (!
Field.isBitField()) {
1009 SizeSoFar = StartOffset + FieldSize;
1010 ZeroFieldSize = FieldSize.isZero();
1012 const CGRecordLayout &RL =
1020 ZeroFieldSize = Info.
Size == 0;
1025bool ConstStructBuilder::DoZeroInitPadding(
const ASTRecordLayout &Layout,
1026 bool AllowOverwrite,
1027 CharUnits SizeSoFar) {
1028 CharUnits TotalSize = Layout.
getSize();
1029 if (SizeSoFar < TotalSize)
1030 if (!AppendBytes(SizeSoFar, getPadding(CGM, TotalSize - SizeSoFar),
1033 SizeSoFar = TotalSize;
1037llvm::Constant *ConstStructBuilder::Finalize(QualType
Type) {
1039 auto *RD =
Type->castAsRecordDecl();
1044llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
1045 const InitListExpr *ILE,
1047 ConstantAggregateBuilder
Const(Emitter.
CGM);
1050 if (!Builder.Build(ILE,
false))
1053 return Builder.Finalize(ValTy);
1056llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
1059 ConstantAggregateBuilder
Const(Emitter.
CGM);
1063 const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD);
1067 return Builder.Finalize(ValTy);
1070bool ConstStructBuilder::UpdateStruct(ConstantEmitter &Emitter,
1071 ConstantAggregateBuilder &Const,
1073 const InitListExpr *Updater) {
1074 return ConstStructBuilder(Emitter, Const, Offset)
1075 .Build(Updater,
true);
1082static ConstantAddress
1084 const CompoundLiteralExpr *E) {
1085 CodeGenModule &CGM = emitter.
CGM;
1087 if (llvm::GlobalVariable *
Addr =
1089 return ConstantAddress(
Addr,
Addr->getValueType(), Align);
1096 "file-scope compound literal did not have constant initializer!");
1100 auto GV =
new llvm::GlobalVariable(
1103 llvm::GlobalValue::InternalLinkage,
C,
".compoundliteral",
nullptr,
1104 llvm::GlobalVariable::NotThreadLocal,
1109 return ConstantAddress(GV, GV->getValueType(), Align);
1112static llvm::Constant *
1113EmitArrayConstant(CodeGenModule &CGM, llvm::ArrayType *DesiredType,
1114 llvm::Type *CommonElementType, uint64_t
ArrayBound,
1115 SmallVectorImpl<llvm::Constant *> &Elements,
1116 llvm::Constant *Filler) {
1119 if (Elements.size() < NonzeroLength && Filler->isNullValue())
1120 NonzeroLength = Elements.size();
1121 if (NonzeroLength == Elements.size()) {
1122 while (NonzeroLength > 0 && Elements[NonzeroLength - 1]->isNullValue())
1126 if (NonzeroLength == 0)
1127 return llvm::ConstantAggregateZero::get(DesiredType);
1131 if (TrailingZeroes >= 8) {
1132 assert(Elements.size() >= NonzeroLength &&
1133 "missing initializer for non-zero element");
1137 if (CommonElementType && NonzeroLength >= 8) {
1138 llvm::Constant *Initial = llvm::ConstantArray::get(
1139 llvm::ArrayType::get(CommonElementType, NonzeroLength),
1140 ArrayRef(Elements).take_front(NonzeroLength));
1142 Elements[0] = Initial;
1144 Elements.resize(NonzeroLength + 1);
1148 CommonElementType ? CommonElementType : DesiredType->getElementType();
1149 FillerType = llvm::ArrayType::get(FillerType, TrailingZeroes);
1150 Elements.back() = llvm::ConstantAggregateZero::get(FillerType);
1151 CommonElementType =
nullptr;
1155 if (Filler->getType() != CommonElementType)
1156 CommonElementType =
nullptr;
1160 if (CommonElementType)
1161 return llvm::ConstantArray::get(
1162 llvm::ArrayType::get(CommonElementType,
ArrayBound), Elements);
1165 llvm::SmallVector<llvm::Type *, 16> Types;
1166 Types.reserve(Elements.size());
1167 for (llvm::Constant *Elt : Elements)
1168 Types.push_back(Elt->getType());
1169 llvm::StructType *SType =
1171 return llvm::ConstantStruct::get(SType, Elements);
1180class ConstExprEmitter
1181 :
public ConstStmtVisitor<ConstExprEmitter, llvm::Constant *, QualType> {
1183 ConstantEmitter &Emitter;
1184 llvm::LLVMContext &VMContext;
1186 ConstExprEmitter(ConstantEmitter &emitter)
1187 : CGM(emitter.CGM), Emitter(emitter), VMContext(CGM.getLLVMContext()) {
1194 llvm::Constant *VisitStmt(
const Stmt *S, QualType
T) {
return nullptr; }
1196 llvm::Constant *VisitConstantExpr(
const ConstantExpr *CE, QualType
T) {
1202 llvm::Constant *VisitParenExpr(
const ParenExpr *PE, QualType
T) {
1207 VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *PE,
1212 llvm::Constant *VisitGenericSelectionExpr(
const GenericSelectionExpr *GE,
1214 return Visit(
GE->getResultExpr(),
T);
1217 llvm::Constant *VisitChooseExpr(
const ChooseExpr *CE, QualType
T) {
1221 llvm::Constant *VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E,
1226 llvm::Constant *ProduceIntToIntCast(
const Expr *E, QualType DestType) {
1227 QualType FromType = E->
getType();
1230 if (llvm::Constant *
C = Visit(E, FromType))
1231 if (
auto *CI = dyn_cast<llvm::ConstantInt>(
C)) {
1234 if (DstWidth == SrcWidth)
1237 ? CI->getValue().sextOrTrunc(DstWidth)
1238 : CI->getValue().zextOrTrunc(DstWidth);
1244 llvm::Constant *VisitCastExpr(
const CastExpr *E, QualType destType) {
1245 if (
const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
1253 "Destination type is not union type!");
1258 if (!
C)
return nullptr;
1260 auto destTy = ConvertType(destType);
1261 if (
C->getType() == destTy)
return C;
1265 SmallVector<llvm::Constant*, 2> Elts;
1266 SmallVector<llvm::Type*, 2> Types;
1268 Types.push_back(
C->getType());
1269 unsigned CurSize = CGM.
getDataLayout().getTypeAllocSize(
C->getType());
1270 unsigned TotalSize = CGM.
getDataLayout().getTypeAllocSize(destTy);
1272 assert(CurSize <= TotalSize &&
"Union size mismatch!");
1273 if (
unsigned NumPadBytes = TotalSize - CurSize) {
1274 llvm::Constant *Padding =
1276 Elts.push_back(Padding);
1277 Types.push_back(Padding->getType());
1280 llvm::StructType *STy = llvm::StructType::get(VMContext, Types,
false);
1281 return llvm::ConstantStruct::get(STy, Elts);
1284 case CK_AddressSpaceConversion: {
1288 llvm::Type *destTy = ConvertType(E->
getType());
1292 case CK_LValueToRValue: {
1298 dyn_cast<CompoundLiteralExpr>(subExpr->
IgnoreParens()))
1299 return Visit(E->getInitializer(), destType);
1303 case CK_AtomicToNonAtomic:
1304 case CK_NonAtomicToAtomic:
1306 case CK_ConstructorConversion:
1307 return Visit(subExpr, destType);
1309 case CK_ArrayToPointerDecay:
1310 if (
const auto *S = dyn_cast<StringLiteral>(subExpr))
1313 case CK_NullToPointer:
1314 if (Visit(subExpr, destType))
1318 case CK_IntToOCLSampler:
1319 llvm_unreachable(
"global sampler variables are not generated");
1321 case CK_IntegralCast:
1322 return ProduceIntToIntCast(subExpr, destType);
1324 case CK_Dependent: llvm_unreachable(
"saw dependent cast!");
1326 case CK_BuiltinFnToFnPtr:
1327 llvm_unreachable(
"builtin functions are handled elsewhere");
1329 case CK_ReinterpretMemberPointer:
1330 case CK_DerivedToBaseMemberPointer:
1331 case CK_BaseToDerivedMemberPointer: {
1333 if (!
C)
return nullptr;
1338 case CK_ObjCObjectLValueCast:
1339 case CK_ARCProduceObject:
1340 case CK_ARCConsumeObject:
1341 case CK_ARCReclaimReturnedObject:
1342 case CK_ARCExtendBlockObject:
1343 case CK_CopyAndAutoreleaseBlockObject:
1351 case CK_LValueBitCast:
1352 case CK_LValueToRValueBitCast:
1353 case CK_NullToMemberPointer:
1354 case CK_UserDefinedConversion:
1355 case CK_CPointerToObjCPointerCast:
1356 case CK_BlockPointerToObjCPointerCast:
1357 case CK_AnyPointerToBlockPointerCast:
1358 case CK_FunctionToPointerDecay:
1359 case CK_BaseToDerived:
1360 case CK_DerivedToBase:
1361 case CK_UncheckedDerivedToBase:
1362 case CK_MemberPointerToBoolean:
1363 case CK_VectorSplat:
1364 case CK_FloatingRealToComplex:
1365 case CK_FloatingComplexToReal:
1366 case CK_FloatingComplexToBoolean:
1367 case CK_FloatingComplexCast:
1368 case CK_FloatingComplexToIntegralComplex:
1369 case CK_IntegralRealToComplex:
1370 case CK_IntegralComplexToReal:
1371 case CK_IntegralComplexToBoolean:
1372 case CK_IntegralComplexCast:
1373 case CK_IntegralComplexToFloatingComplex:
1374 case CK_PointerToIntegral:
1375 case CK_PointerToBoolean:
1376 case CK_BooleanToSignedIntegral:
1377 case CK_IntegralToPointer:
1378 case CK_IntegralToBoolean:
1379 case CK_IntegralToFloating:
1380 case CK_FloatingToIntegral:
1381 case CK_FloatingToBoolean:
1382 case CK_FloatingCast:
1383 case CK_FloatingToFixedPoint:
1384 case CK_FixedPointToFloating:
1385 case CK_FixedPointCast:
1386 case CK_FixedPointToBoolean:
1387 case CK_FixedPointToIntegral:
1388 case CK_IntegralToFixedPoint:
1389 case CK_ZeroToOCLOpaqueType:
1391 case CK_HLSLVectorTruncation:
1392 case CK_HLSLMatrixTruncation:
1393 case CK_HLSLArrayRValue:
1394 case CK_HLSLElementwiseCast:
1395 case CK_HLSLAggregateSplatCast:
1398 llvm_unreachable(
"Invalid CastKind");
1401 llvm::Constant *VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *DIE,
1408 llvm::Constant *VisitExprWithCleanups(
const ExprWithCleanups *E, QualType
T) {
1412 llvm::Constant *VisitIntegerLiteral(
const IntegerLiteral *I, QualType
T) {
1416 static APValue withDestType(ASTContext &Ctx,
const Expr *E, QualType SrcType,
1417 QualType DestType,
const llvm::APSInt &
Value) {
1422 llvm::RoundingMode RM =
1424 if (RM == llvm::RoundingMode::Dynamic)
1425 RM = llvm::RoundingMode::NearestTiesToEven;
1433 llvm::Constant *EmitArrayInitialization(
const InitListExpr *ILE, QualType
T) {
1435 assert(CAT &&
"can't emit array init for non-constant-bound array");
1437 const uint64_t NumElements = CAT->getZExtSize();
1439 if (
const auto *Embed =
1440 dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1441 NumInitElements += Embed->getDataElementCount() - 1;
1442 if (NumInitElements > NumElements) {
1443 NumInitElements = NumElements;
1451 uint64_t NumInitableElts = std::min<uint64_t>(NumInitElements, NumElements);
1453 QualType EltType = CAT->getElementType();
1456 llvm::Constant *fillC =
nullptr;
1464 SmallVector<llvm::Constant *, 16> Elts;
1465 if (fillC && fillC->isNullValue())
1466 Elts.reserve(NumInitableElts + 1);
1468 Elts.reserve(NumElements);
1470 llvm::Type *CommonElementType =
nullptr;
1471 auto Emit = [&](
const Expr *
Init,
unsigned ArrayIndex) {
1472 llvm::Constant *
C =
nullptr;
1476 if (ArrayIndex == 0)
1477 CommonElementType =
C->getType();
1478 else if (
C->getType() != CommonElementType)
1479 CommonElementType =
nullptr;
1484 unsigned ArrayIndex = 0;
1485 QualType DestTy = CAT->getElementType();
1486 for (
unsigned i = 0; i < ILE->
getNumInits(); ++i) {
1488 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1489 StringLiteral *SL = EmbedS->getDataStringLiteral();
1493 for (
unsigned I = EmbedS->getStartingElementPos(),
1494 N = EmbedS->getDataElementCount();
1495 I != EmbedS->getStartingElementPos() + N; ++I) {
1510 if ((ArrayIndex - EmbedS->getDataElementCount()) == 0)
1511 CommonElementType =
C->getType();
1512 else if (
C->getType() != CommonElementType)
1513 CommonElementType =
nullptr;
1515 if (!Emit(
Init, ArrayIndex))
1521 llvm::ArrayType *Desired =
1523 return EmitArrayConstant(CGM, Desired, CommonElementType, NumElements, Elts,
1527 llvm::Constant *EmitRecordInitialization(
const InitListExpr *ILE,
1529 return ConstStructBuilder::BuildStruct(Emitter, ILE,
T);
1532 llvm::Constant *VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E,
1537 llvm::Constant *VisitInitListExpr(
const InitListExpr *ILE, QualType
T) {
1542 return EmitArrayInitialization(ILE,
T);
1545 return EmitRecordInitialization(ILE,
T);
1551 VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E,
1552 QualType destType) {
1553 auto C = Visit(E->
getBase(), destType);
1557 ConstantAggregateBuilder
Const(CGM);
1560 if (!EmitDesignatedInitUpdater(Emitter, Const,
CharUnits::Zero(), destType,
1565 bool HasFlexibleArray =
false;
1568 return Const.build(ValTy, HasFlexibleArray);
1571 llvm::Constant *VisitCXXConstructExpr(
const CXXConstructExpr *E,
1578 assert(E->
getNumArgs() == 1 &&
"trivial ctor with > 1 argument");
1580 "trivial ctor has argument but isn't a copy/move ctor");
1582 const Expr *Arg = E->
getArg(0);
1584 "argument to copy ctor is of wrong type");
1588 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(Arg))
1589 return Visit(MTE->getSubExpr(), Ty);
1597 llvm::Constant *VisitStringLiteral(
const StringLiteral *E, QualType
T) {
1602 llvm::Constant *VisitObjCEncodeExpr(
const ObjCEncodeExpr *E, QualType
T) {
1609 assert(CAT &&
"String data not of constant array type!");
1614 return llvm::ConstantDataArray::getString(VMContext, Str,
false);
1617 llvm::Constant *VisitUnaryExtension(
const UnaryOperator *E, QualType
T) {
1621 llvm::Constant *VisitUnaryMinus(
const UnaryOperator *U, QualType
T) {
1623 if (
auto *CI = dyn_cast<llvm::ConstantInt>(
C))
1624 return llvm::ConstantInt::get(CGM.
getLLVMContext(), -CI->getValue());
1628 llvm::Constant *VisitPackIndexingExpr(
const PackIndexingExpr *E, QualType
T) {
1633 llvm::Type *ConvertType(QualType
T) {
1640llvm::Constant *ConstantEmitter::validateAndPopAbstract(llvm::Constant *
C,
1641 AbstractState saved) {
1642 Abstract = saved.OldValue;
1644 assert(saved.OldPlaceholdersSize == PlaceholderAddresses.size() &&
1645 "created a placeholder while doing an abstract emission?");
1654 auto state = pushAbstract();
1656 return validateAndPopAbstract(
C, state);
1661 auto state = pushAbstract();
1663 return validateAndPopAbstract(
C, state);
1668 auto state = pushAbstract();
1670 return validateAndPopAbstract(
C, state);
1679 RetType =
CGM.getContext().getLValueReferenceType(RetType);
1686 auto state = pushAbstract();
1688 C = validateAndPopAbstract(
C, state);
1691 "internal error: could not emit constant value \"abstractly\"");
1692 C =
CGM.EmitNullConstant(destType);
1700 bool EnablePtrAuthFunctionTypeDiscrimination) {
1701 auto state = pushAbstract();
1703 tryEmitPrivate(value, destType, EnablePtrAuthFunctionTypeDiscrimination);
1704 C = validateAndPopAbstract(
C, state);
1707 "internal error: could not emit constant value \"abstractly\"");
1708 C =
CGM.EmitNullConstant(destType);
1722 for (
auto [_, GV] : PlaceholderAddresses)
1723 GV->eraseFromParent();
1724 PlaceholderAddresses.clear();
1728 return markIfFailed(
Init);
1734 initializeNonAbstract(destAddrSpace);
1741 initializeNonAbstract(destAddrSpace);
1743 assert(
C &&
"couldn't emit constant value non-abstractly?");
1748 assert(!Abstract &&
"cannot get current address for abstract constant");
1754 auto global =
new llvm::GlobalVariable(
CGM.getModule(),
CGM.Int8Ty,
true,
1755 llvm::GlobalValue::PrivateLinkage,
1759 llvm::GlobalVariable::NotThreadLocal,
1760 CGM.getContext().getTargetAddressSpace(DestAddressSpace));
1762 PlaceholderAddresses.push_back(std::make_pair(
nullptr, global));
1768 llvm::GlobalValue *placeholder) {
1769 assert(!PlaceholderAddresses.empty());
1770 assert(PlaceholderAddresses.back().first ==
nullptr);
1771 assert(PlaceholderAddresses.back().second == placeholder);
1772 PlaceholderAddresses.back().first = signal;
1776 struct ReplacePlaceholders {
1780 llvm::Constant *
Base;
1781 llvm::Type *BaseValueTy =
nullptr;
1784 llvm::DenseMap<llvm::Constant*, llvm::GlobalVariable*> PlaceholderAddresses;
1787 llvm::DenseMap<llvm::GlobalVariable*, llvm::Constant*> Locations;
1795 ReplacePlaceholders(
CodeGenModule &CGM, llvm::Constant *base,
1796 ArrayRef<std::pair<llvm::Constant*,
1797 llvm::GlobalVariable*>> addresses)
1798 : CGM(CGM),
Base(base),
1799 PlaceholderAddresses(addresses.begin(), addresses.end()) {
1802 void replaceInInitializer(llvm::Constant *init) {
1804 BaseValueTy = init->getType();
1807 Indices.push_back(0);
1808 IndexValues.push_back(
nullptr);
1811 findLocations(init);
1814 assert(IndexValues.size() == Indices.size() &&
"mismatch");
1815 assert(Indices.size() == 1 &&
"didn't pop all indices");
1818 assert(Locations.size() == PlaceholderAddresses.size() &&
1819 "missed a placeholder?");
1825 for (
auto &entry : Locations) {
1826 assert(entry.first->getName() ==
"" &&
"not a placeholder!");
1827 entry.first->replaceAllUsesWith(entry.second);
1828 entry.first->eraseFromParent();
1833 void findLocations(llvm::Constant *init) {
1835 if (
auto agg = dyn_cast<llvm::ConstantAggregate>(init)) {
1836 for (
unsigned i = 0, e = agg->getNumOperands(); i != e; ++i) {
1837 Indices.push_back(i);
1838 IndexValues.push_back(
nullptr);
1840 findLocations(agg->getOperand(i));
1842 IndexValues.pop_back();
1850 auto it = PlaceholderAddresses.find(init);
1851 if (it != PlaceholderAddresses.end()) {
1852 setLocation(it->second);
1857 if (
auto expr = dyn_cast<llvm::ConstantExpr>(init)) {
1858 init =
expr->getOperand(0);
1865 void setLocation(llvm::GlobalVariable *placeholder) {
1866 assert(!Locations.contains(placeholder) &&
1867 "already found location for placeholder!");
1872 assert(Indices.size() == IndexValues.size());
1873 for (
size_t i = Indices.size() - 1; i !=
size_t(-1); --i) {
1874 if (IndexValues[i]) {
1876 for (
size_t j = 0; j != i + 1; ++j) {
1877 assert(IndexValues[j] &&
1886 IndexValues[i] = llvm::ConstantInt::get(CGM.
Int32Ty, Indices[i]);
1889 llvm::Constant *location = llvm::ConstantExpr::getGetElementPtr(
1891 llvm::GEPNoWrapFlags::inBounds());
1893 Locations.insert({placeholder, location});
1899 assert(InitializedNonAbstract &&
1900 "finalizing emitter that was used for abstract emission?");
1901 assert(!Finalized &&
"finalizing emitter multiple times");
1902 assert(global->getInitializer());
1907 if (!PlaceholderAddresses.empty()) {
1908 ReplacePlaceholders(
CGM, global, PlaceholderAddresses)
1909 .replaceInInitializer(global->getInitializer());
1910 PlaceholderAddresses.clear();
1915 assert((!InitializedNonAbstract || Finalized || Failed) &&
1916 "not finalized after being initialized for non-abstract emission");
1917 assert(PlaceholderAddresses.empty() &&
"unhandled placeholders");
1923 type.getQualifiers());
1936 dyn_cast_or_null<CXXConstructExpr>(D.
getInit())) {
1946 assert(E &&
"No initializer to emit");
1950 if (llvm::Constant *
C = ConstExprEmitter(*this).Visit(E, nonMemoryDestType))
1957 assert(!value->allowConstexprUnknown() &&
1958 "Constexpr unknown values are not allowed in CodeGen");
2002 assert(Schema &&
"applying trivial ptrauth schema");
2005 return UnsignedPointer;
2007 unsigned Key = Schema.
getKey();
2010 llvm::GlobalValue *StorageAddress =
nullptr;
2019 llvm::ConstantInt *Discriminator =
2022 llvm::Constant *SignedPointer =
CGM.getConstantSignedPointer(
2023 UnsignedPointer, Key, StorageAddress, Discriminator);
2028 return SignedPointer;
2036 QualType destValueType = AT->getValueType();
2039 uint64_t innerSize =
CGM.getContext().getTypeSize(destValueType);
2040 uint64_t outerSize =
CGM.getContext().getTypeSize(destType);
2041 if (innerSize == outerSize)
2044 assert(innerSize < outerSize &&
"emitted over-large constant for atomic");
2045 llvm::Constant *elts[] = {
2047 llvm::ConstantAggregateZero::get(
2048 llvm::ArrayType::get(
CGM.Int8Ty, (outerSize - innerSize) / 8))
2050 return llvm::ConstantStruct::getAnon(elts);
2055 if ((
C->getType()->isIntegerTy(1) && !destType->
isBitIntType()) ||
2058 llvm::Type *boolTy =
CGM.getTypes().ConvertTypeForMem(destType);
2059 llvm::Constant *Res = llvm::ConstantFoldCastOperand(
2060 llvm::Instruction::ZExt,
C, boolTy,
CGM.getDataLayout());
2061 assert(Res &&
"Constant folding must succeed");
2066 llvm::Type *MemTy =
CGM.getTypes().ConvertTypeForMem(destType);
2067 if (
C->getType() != MemTy) {
2068 ConstantAggregateBuilder Builder(
CGM);
2069 llvm::Type *LoadStoreTy =
2070 CGM.getTypes().convertTypeForLoadStore(destType);
2074 llvm::Constant *Res = llvm::ConstantFoldCastOperand(
2076 ? llvm::Instruction::SExt
2077 : llvm::Instruction::ZExt,
2078 CI, LoadStoreTy,
CGM.getDataLayout());
2079 if (
CGM.getTypes().typeRequiresSplitIntoByteArray(destType,
2084 Builder.addBits(
Value, 0,
false);
2085 return Builder.build(MemTy,
false);
2095 for (
unsigned Row = 0; Row != MT->getNumRows(); ++Row)
2096 for (
unsigned Col = 0; Col != MT->getNumColumns(); ++Col)
2097 Inits[MT->getRowMajorFlattenedIndex(Row, Col)] =
2098 C->getAggregateElement(MT->getColumnMajorFlattenedIndex(Row, Col));
2099 llvm::Constant *MemoryValue = llvm::ConstantVector::get(
Inits);
2101 llvm::Constant *Res = llvm::ConstantFoldCastOperand(
2102 llvm::Instruction::ZExt, MemoryValue,
2103 CGM.getTypes().convertTypeForLoadStore(destType),
2104 CGM.getDataLayout());
2105 assert(Res &&
"Constant folding must succeed");
2116 assert(!destType->
isVoidType() &&
"can't emit a void constant");
2119 if (llvm::Constant *
C = ConstExprEmitter(*this).Visit(E, destType))
2144struct ConstantLValue {
2145 llvm::Constant *
Value;
2146 bool HasOffsetApplied;
2147 bool HasDestPointerAuth;
2149 ConstantLValue(llvm::Constant *value,
2150 bool hasOffsetApplied =
false,
2151 bool hasDestPointerAuth =
false)
2152 :
Value(value), HasOffsetApplied(hasOffsetApplied),
2153 HasDestPointerAuth(hasDestPointerAuth) {}
2156 : ConstantLValue(address.getPointer()) {}
2160class ConstantLValueEmitter :
public ConstStmtVisitor<ConstantLValueEmitter,
2163 ConstantEmitter &Emitter;
2166 bool EnablePtrAuthFunctionTypeDiscrimination;
2169 friend StmtVisitorBase;
2172 ConstantLValueEmitter(ConstantEmitter &emitter,
const APValue &value,
2174 bool EnablePtrAuthFunctionTypeDiscrimination =
true)
2175 : CGM(emitter.CGM), Emitter(emitter),
Value(value), DestType(destType),
2176 EnablePtrAuthFunctionTypeDiscrimination(
2177 EnablePtrAuthFunctionTypeDiscrimination) {}
2179 llvm::Constant *tryEmit();
2182 llvm::Constant *tryEmitAbsolute(llvm::Type *destTy);
2183 ConstantLValue tryEmitBase(
const APValue::LValueBase &base);
2185 ConstantLValue VisitStmt(
const Stmt *S) {
return nullptr; }
2186 ConstantLValue VisitConstantExpr(
const ConstantExpr *E);
2187 ConstantLValue VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
2188 ConstantLValue VisitStringLiteral(
const StringLiteral *E);
2189 ConstantLValue VisitObjCBoxedExpr(
const ObjCBoxedExpr *E);
2190 ConstantLValue VisitObjCEncodeExpr(
const ObjCEncodeExpr *E);
2191 ConstantLValue VisitObjCStringLiteral(
const ObjCStringLiteral *E);
2192 llvm::Constant *VisitObjCCollectionElement(
const Expr *E);
2193 ConstantLValue VisitObjCArrayLiteral(
const ObjCArrayLiteral *E);
2194 ConstantLValue VisitObjCDictionaryLiteral(
const ObjCDictionaryLiteral *E);
2195 ConstantLValue VisitPredefinedExpr(
const PredefinedExpr *E);
2196 ConstantLValue VisitAddrLabelExpr(
const AddrLabelExpr *E);
2197 ConstantLValue VisitCallExpr(
const CallExpr *E);
2198 ConstantLValue VisitBlockExpr(
const BlockExpr *E);
2199 ConstantLValue VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
2200 ConstantLValue VisitMaterializeTemporaryExpr(
2201 const MaterializeTemporaryExpr *E);
2203 ConstantLValue emitPointerAuthSignConstant(
const CallExpr *E);
2204 llvm::Constant *emitPointerAuthPointer(
const Expr *E);
2205 unsigned emitPointerAuthKey(
const Expr *E);
2206 std::pair<llvm::Constant *, llvm::ConstantInt *>
2207 emitPointerAuthDiscriminator(
const Expr *E);
2209 bool hasNonZeroOffset()
const {
2210 return !
Value.getLValueOffset().isZero();
2214 llvm::Constant *getOffset() {
2215 return llvm::ConstantInt::get(CGM.
Int64Ty,
2216 Value.getLValueOffset().getQuantity());
2220 llvm::Constant *applyOffset(llvm::Constant *
C) {
2221 if (!hasNonZeroOffset())
2224 return llvm::ConstantExpr::getPtrAdd(
C, getOffset());
2230llvm::Constant *ConstantLValueEmitter::tryEmit() {
2231 const APValue::LValueBase &base =
Value.getLValueBase();
2246 return tryEmitAbsolute(destTy);
2250 ConstantLValue result = tryEmitBase(base);
2253 llvm::Constant *value = result.Value;
2254 if (!value)
return nullptr;
2257 if (!result.HasOffsetApplied) {
2258 value = applyOffset(value);
2262 if (PointerAuthQualifier PointerAuth = DestType.
getPointerAuth();
2263 PointerAuth && !result.HasDestPointerAuth) {
2272 return llvm::ConstantExpr::getPointerCast(value, destTy);
2274 return llvm::ConstantExpr::getPtrToInt(value, destTy);
2280ConstantLValueEmitter::tryEmitAbsolute(llvm::Type *destTy) {
2283 if (
Value.isNullPointer()) {
2291 auto intptrTy = CGM.
getDataLayout().getIntPtrType(destPtrTy);
2293 C = llvm::ConstantFoldIntegerCast(getOffset(), intptrTy,
false,
2295 assert(
C &&
"Must have folded, as Offset is a ConstantInt");
2296 C = llvm::ConstantExpr::getIntToPtr(
C, destPtrTy);
2301ConstantLValueEmitter::tryEmitBase(
const APValue::LValueBase &base) {
2303 if (
const ValueDecl *D = base.
dyn_cast<
const ValueDecl*>()) {
2308 if (D->hasAttr<WeakRefAttr>())
2311 auto PtrAuthSign = [&](llvm::Constant *
C) {
2312 if (PointerAuthQualifier PointerAuth = DestType.
getPointerAuth()) {
2315 return ConstantLValue(
C,
true,
true);
2318 CGPointerAuthInfo AuthInfo;
2320 if (EnablePtrAuthFunctionTypeDiscrimination)
2324 if (hasNonZeroOffset())
2325 return ConstantLValue(
nullptr);
2329 C, AuthInfo.
getKey(),
nullptr,
2331 return ConstantLValue(
C,
true,
true);
2334 return ConstantLValue(
C);
2337 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
2339 if (FD->getType()->isCFIUncheckedCalleeFunctionType())
2341 return PtrAuthSign(
C);
2344 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
2346 if (!VD->hasLocalStorage()) {
2347 if (VD->isFileVarDecl() || VD->hasExternalStorage())
2350 if (VD->isLocalVarDecl()) {
2357 if (
const auto *GD = dyn_cast<MSGuidDecl>(D))
2360 if (
const auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D))
2363 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D))
2370 if (TypeInfoLValue TI = base.
dyn_cast<TypeInfoLValue>())
2374 return Visit(base.
get<
const Expr*>());
2378ConstantLValueEmitter::VisitConstantExpr(
const ConstantExpr *E) {
2385ConstantLValueEmitter::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
2386 ConstantEmitter CompoundLiteralEmitter(CGM, Emitter.
CGF);
2392ConstantLValueEmitter::VisitStringLiteral(
const StringLiteral *E) {
2397ConstantLValueEmitter::VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
2409ConstantLValueEmitter::VisitObjCStringLiteral(
const ObjCStringLiteral *E) {
2414ConstantLValueEmitter::VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
2421 "Non const NSNumber is being emitted as a constant");
2428 const bool IsBoolType =
2430 bool BoolValue =
false;
2436 Expr::EvalResult IntResult{};
2443 llvm::APFloat FloatValue(0.0);
2449 llvm_unreachable(
"SubExpr is expected to be evaluated as a numeric type");
2453ConstantLValueEmitter::VisitObjCCollectionElement(
const Expr *E) {
2456 QualType DestTy = CE->
getType();
2458 assert(CE->getCastKind() == CK_BitCast &&
2459 "Expected a CK_BitCast type for valid items in constant objc "
2460 "collection literals");
2463 ConstantLValue LV = Visit(Elm);
2465 llvm::Constant *Val = llvm::ConstantExpr::getBitCast(ConstVal, DstTy);
2470ConstantLValueEmitter::VisitObjCArrayLiteral(
const ObjCArrayLiteral *E) {
2471 SmallVector<llvm::Constant *, 16> ObjectExpressions;
2473 ObjectExpressions.reserve(NumElements);
2475 for (uint64_t i = 0; i < NumElements; i++) {
2476 llvm::Constant *Val = VisitObjCCollectionElement(E->
getElement(i));
2477 ObjectExpressions.push_back(Val);
2484ConstantLValue ConstantLValueEmitter::VisitObjCDictionaryLiteral(
2485 const ObjCDictionaryLiteral *E) {
2486 SmallVector<std::pair<llvm::Constant *, llvm::Constant *>, 16> KeysAndObjects;
2488 KeysAndObjects.reserve(NumElements);
2490 for (uint64_t i = 0; i < NumElements; i++) {
2491 llvm::Constant *Key =
2493 llvm::Constant *Val =
2495 KeysAndObjects.push_back({Key, Val});
2503ConstantLValueEmitter::VisitPredefinedExpr(
const PredefinedExpr *E) {
2508ConstantLValueEmitter::VisitAddrLabelExpr(
const AddrLabelExpr *E) {
2509 assert(Emitter.
CGF &&
"Invalid address of label expression outside function");
2515ConstantLValueEmitter::VisitCallExpr(
const CallExpr *E) {
2517 if (builtin == Builtin::BI__builtin_function_start)
2521 if (builtin == Builtin::BI__builtin_ptrauth_sign_constant)
2522 return emitPointerAuthSignConstant(E);
2524 if (builtin != Builtin::BI__builtin___CFStringMakeConstantString &&
2525 builtin != Builtin::BI__builtin___NSStringMakeConstantString)
2529 if (builtin == Builtin::BI__builtin___NSStringMakeConstantString) {
2538ConstantLValueEmitter::emitPointerAuthSignConstant(
const CallExpr *E) {
2539 llvm::Constant *UnsignedPointer = emitPointerAuthPointer(E->
getArg(0));
2540 unsigned Key = emitPointerAuthKey(E->
getArg(1));
2541 auto [StorageAddress, OtherDiscriminator] =
2542 emitPointerAuthDiscriminator(E->
getArg(2));
2545 UnsignedPointer, Key, StorageAddress, OtherDiscriminator);
2546 return SignedPointer;
2549llvm::Constant *ConstantLValueEmitter::emitPointerAuthPointer(
const Expr *E) {
2556 assert(
Result.Val.isLValue());
2558 assert(
Result.Val.getLValueOffset().isZero());
2559 return ConstantEmitter(CGM, Emitter.
CGF)
2563unsigned ConstantLValueEmitter::emitPointerAuthKey(
const Expr *E) {
2567std::pair<llvm::Constant *, llvm::ConstantInt *>
2568ConstantLValueEmitter::emitPointerAuthDiscriminator(
const Expr *E) {
2571 if (
const auto *
Call = dyn_cast<CallExpr>(E)) {
2572 if (
Call->getBuiltinCallee() ==
2573 Builtin::BI__builtin_ptrauth_blend_discriminator) {
2574 llvm::Constant *
Pointer = ConstantEmitter(CGM).emitAbstract(
2575 Call->getArg(0),
Call->getArg(0)->getType());
2577 Call->getArg(1),
Call->getArg(1)->getType()));
2582 llvm::Constant *
Result = ConstantEmitter(CGM).emitAbstract(E, E->
getType());
2583 if (
Result->getType()->isPointerTy())
2584 return {
Result,
nullptr};
2589ConstantLValueEmitter::VisitBlockExpr(
const BlockExpr *E) {
2590 StringRef functionName;
2591 if (
auto CGF = Emitter.
CGF)
2592 functionName = CGF->CurFn->getName();
2594 functionName =
"global";
2600ConstantLValueEmitter::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
2610ConstantLValueEmitter::VisitMaterializeTemporaryExpr(
2611 const MaterializeTemporaryExpr *E) {
2619 bool EnablePtrAuthFunctionTypeDiscrimination) {
2624 return llvm::UndefValue::get(
CGM.getTypes().ConvertType(DestType));
2626 return ConstantLValueEmitter(*
this,
Value, DestType,
2627 EnablePtrAuthFunctionTypeDiscrimination)
2632 (PointerAuth.authenticatesNullValues() ||
Value.getInt() != 0))
2634 return llvm::ConstantInt::get(
CGM.getLLVMContext(),
Value.getInt());
2636 return llvm::ConstantInt::get(
CGM.getLLVMContext(),
2637 Value.getFixedPoint().getValue());
2641 Complex[0] = llvm::ConstantInt::get(
CGM.getLLVMContext(),
2642 Value.getComplexIntReal());
2643 Complex[1] = llvm::ConstantInt::get(
CGM.getLLVMContext(),
2644 Value.getComplexIntImag());
2647 llvm::StructType *STy =
2649 return llvm::ConstantStruct::get(STy,
Complex);
2652 return llvm::ConstantFP::get(
CGM.getLLVMContext(),
Value.getFloat());
2656 Complex[0] = llvm::ConstantFP::get(
CGM.getLLVMContext(),
2657 Value.getComplexFloatReal());
2658 Complex[1] = llvm::ConstantFP::get(
CGM.getLLVMContext(),
2659 Value.getComplexFloatImag());
2662 llvm::StructType *STy =
2664 return llvm::ConstantStruct::get(STy,
Complex);
2667 unsigned NumElts =
Value.getVectorLength();
2670 for (
unsigned I = 0; I != NumElts; ++I) {
2673 Inits[I] = llvm::ConstantInt::get(
CGM.getLLVMContext(), Elt.
getInt());
2677 Inits[I] = llvm::UndefValue::get(
CGM.getTypes().ConvertType(
2680 llvm_unreachable(
"unsupported vector element type");
2682 return llvm::ConstantVector::get(
Inits);
2686 unsigned NumRows =
Value.getMatrixNumRows();
2687 unsigned NumCols =
Value.getMatrixNumColumns();
2688 unsigned NumElts = NumRows * NumCols;
2691 for (
unsigned Row = 0; Row != NumRows; ++Row) {
2692 for (
unsigned Col = 0; Col != NumCols; ++Col) {
2694 unsigned Idx = MT->getColumnMajorFlattenedIndex(Row, Col);
2697 llvm::ConstantInt::get(
CGM.getLLVMContext(), Elt.
getInt());
2700 llvm::ConstantFP::get(
CGM.getLLVMContext(), Elt.
getFloat());
2702 Inits[Idx] = llvm::PoisonValue::get(
2703 CGM.getTypes().ConvertType(MT->getElementType()));
2705 llvm_unreachable(
"unsupported matrix element type");
2708 return llvm::ConstantVector::get(
Inits);
2715 if (!LHS || !RHS)
return nullptr;
2718 llvm::Type *ResultType =
CGM.getTypes().ConvertType(DestType);
2719 LHS = llvm::ConstantExpr::getPtrToInt(LHS,
CGM.IntPtrTy);
2720 RHS = llvm::ConstantExpr::getPtrToInt(RHS,
CGM.IntPtrTy);
2721 llvm::Constant *AddrLabelDiff = llvm::ConstantExpr::getSub(LHS, RHS);
2726 return llvm::ConstantExpr::getTruncOrBitCast(AddrLabelDiff, ResultType);
2730 return ConstStructBuilder::BuildStruct(*
this,
Value, DestType);
2732 const ArrayType *ArrayTy =
CGM.getContext().getAsArrayType(DestType);
2733 unsigned NumElements =
Value.getArraySize();
2734 unsigned NumInitElts =
Value.getArrayInitializedElts();
2737 llvm::Constant *Filler =
nullptr;
2738 if (
Value.hasArrayFiller()) {
2747 if (Filler && Filler->isNullValue())
2748 Elts.reserve(NumInitElts + 1);
2750 Elts.reserve(NumElements);
2752 llvm::Type *CommonElementType =
nullptr;
2753 for (
unsigned I = 0; I < NumInitElts; ++I) {
2756 if (!
C)
return nullptr;
2759 CommonElementType =
C->getType();
2760 else if (
C->getType() != CommonElementType)
2761 CommonElementType =
nullptr;
2765 llvm::ArrayType *Desired =
2770 Desired = llvm::ArrayType::get(Desired->getElementType(), Elts.size());
2772 return EmitArrayConstant(
CGM, Desired, CommonElementType, NumElements, Elts,
2776 return CGM.getCXXABI().EmitMemberPointer(
Value, DestType);
2778 llvm_unreachable(
"std::meta::info is consteval-only type");
2780 llvm_unreachable(
"Unknown APValue kind");
2785 return EmittedCompoundLiterals.lookup(E);
2790 bool Ok = EmittedCompoundLiterals.insert(std::make_pair(CLE, GV)).second;
2792 assert(Ok &&
"CLE has already been emitted!");
2797 assert(E->
isFileScope() &&
"not a file-scope compound literal expr");
2810 return getCXXABI().EmitMemberFunctionPointer(method);
2820 llvm::Type *baseType,
2825 bool asCompleteObject) {
2827 llvm::StructType *structure =
2831 unsigned numElements = structure->getNumElements();
2832 std::vector<llvm::Constant *> elements(numElements);
2834 auto CXXR = dyn_cast<CXXRecordDecl>(record);
2837 for (
const auto &I : CXXR->bases()) {
2838 if (I.isVirtual()) {
2854 llvm::Type *baseType = structure->getElementType(fieldIndex);
2860 for (
const auto *Field : record->
fields()) {
2863 if (!Field->isBitField() &&
2871 if (Field->getIdentifier())
2873 if (
const auto *FieldRD = Field->getType()->getAsRecordDecl())
2874 if (FieldRD->findFirstNamedDataMember())
2880 if (CXXR && asCompleteObject) {
2881 for (
const auto &I : CXXR->vbases()) {
2890 if (elements[fieldIndex])
continue;
2892 llvm::Type *baseType = structure->getElementType(fieldIndex);
2898 for (
unsigned i = 0; i != numElements; ++i) {
2900 elements[i] = llvm::Constant::getNullValue(structure->getElementType(i));
2903 return llvm::ConstantStruct::get(structure, elements);
2908 llvm::Type *baseType,
2914 return llvm::Constant::getNullValue(baseType);
2927 llvm::Type *LT =
getTypes().ConvertTypeForMem(
T);
2928 if (
auto *PT = dyn_cast<llvm::PointerType>(LT))
2932 return llvm::Constant::getNullValue(LT);
2936 return llvm::Constant::getNullValue(
getTypes().ConvertTypeForMem(
T));
2939 llvm::ArrayType *ATy =
2944 llvm::Constant *Element =
2948 return llvm::ConstantArray::get(ATy, Array);
2951 if (
const auto *RD =
T->getAsRecordDecl())
2952 return ::EmitNullConstant(*
this, RD,
2955 assert(
T->isMemberDataPointerType() &&
2956 "Should only see pointers to data members here!");
2963 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.
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 isPFPField(const FieldDecl *Field)
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
This is an opaque type for sizes expressed in character units.
bool isZero() const
Test whether the quantity equals zero.
CharUnits alignTo(CharUnits Align) const
Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is a multiple...
llvm::Align getAsAlign() const
Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit bytes.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits One()
Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
static CharUnits 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
Return the code unit at the given position.
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 isConstantMatrixType() 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
bool isConstantMatrixBoolType() 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 isEmptyFieldForLayout(const ASTContext &Ctx, const FieldDecl *FD)
Return true iff the field is "empty", that is, either a zero-width bit-field or an isEmptyRecordForLa...
bool isEmptyRecordForLayout(const ASTContext &Ctx, QualType T)
Return true iff a structure contains only empty base classes (per isEmptyRecordForLayout) and fields ...
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
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.