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 =
859 VTableAddressPoint, *Authentication);
860 if (!VTableAddressPoint)
863 if (!AppendBytes(Offset, VTableAddressPoint))
869 SmallVector<BaseInfo, 8> Bases;
872 for (
const CXXBaseSpecifier &Base : CD->bases()) {
873 if (
Base.isVirtual())
875 const CXXRecordDecl *BD =
Base.getType()->getAsCXXRecordDecl();
877 Bases.push_back(BaseInfo(BD, BaseOffset, BaseNo));
880 llvm::stable_sort(Bases);
882 for (
const BaseInfo &Base : Bases) {
885 VTableClass, Offset +
Base.Offset,
false))
889 if (IsCompleteClass) {
893 for (
const CXXBaseSpecifier &Base : CD->vbases()) {
894 const CXXRecordDecl *BD =
Base.getType()->getAsCXXRecordDecl();
896 Bases.push_back(BaseInfo(BD, BaseOffset, BaseNo));
899 llvm::stable_sort(Bases);
901 for (
const BaseInfo &Base : Bases) {
904 IsPrimaryBase, VTableClass, Offset +
Base.Offset,
false))
911 unsigned FieldNo = 0;
914 bool ZeroFieldSize =
false;
917 bool AllowOverwrite =
false;
919 FieldEnd = RD->
field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
925 if (
Field->isUnnamedBitField() ||
932 llvm::Constant *EltInit =
938 llvm::ConstantInt *Disc;
939 llvm::Constant *AddrDisc;
943 Disc = llvm::ConstantInt::get(CGM.
Int64Ty, FieldSignature);
944 AddrDisc = llvm::ConstantPointerNull::get(CGM.
VoidPtrTy);
951 Disc = llvm::ConstantInt::get(CGM.
Int64Ty,
955 EltInit = llvm::ConstantPtrAuth::get(
956 EltInit, llvm::ConstantInt::get(CGM.
Int32Ty, 2), Disc, AddrDisc,
963 if (ZeroInitPadding) {
964 if (!DoZeroInitPadding(Layout, FieldNo, **Field, AllowOverwrite,
965 SizeSoFar, ZeroFieldSize))
972 if (!
Field->isBitField()) {
974 if (!AppendField(*Field, Layout.
getFieldOffset(FieldNo) + OffsetBits,
975 EltInit, AllowOverwrite))
979 if (
Field->hasAttr<NoUniqueAddressAttr>())
980 AllowOverwrite =
true;
983 if (!AppendBitField(*Field, Layout.
getFieldOffset(FieldNo) + OffsetBits,
984 EltInit, AllowOverwrite))
988 if (ZeroInitPadding && !DoZeroInitPadding(Layout, AllowOverwrite, SizeSoFar))
994bool ConstStructBuilder::DoZeroInitPadding(
995 const ASTRecordLayout &Layout,
unsigned FieldNo,
const FieldDecl &Field,
996 bool AllowOverwrite, CharUnits &SizeSoFar,
bool &ZeroFieldSize) {
999 if (SizeSoFar < StartOffset)
1000 if (!AppendBytes(SizeSoFar, getPadding(CGM, StartOffset - SizeSoFar),
1004 if (!
Field.isBitField()) {
1006 SizeSoFar = StartOffset + FieldSize;
1007 ZeroFieldSize = FieldSize.isZero();
1009 const CGRecordLayout &RL =
1017 ZeroFieldSize = Info.
Size == 0;
1022bool ConstStructBuilder::DoZeroInitPadding(
const ASTRecordLayout &Layout,
1023 bool AllowOverwrite,
1024 CharUnits SizeSoFar) {
1025 CharUnits TotalSize = Layout.
getSize();
1026 if (SizeSoFar < TotalSize)
1027 if (!AppendBytes(SizeSoFar, getPadding(CGM, TotalSize - SizeSoFar),
1030 SizeSoFar = TotalSize;
1034llvm::Constant *ConstStructBuilder::Finalize(QualType
Type) {
1036 auto *RD =
Type->castAsRecordDecl();
1041llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
1042 const InitListExpr *ILE,
1044 ConstantAggregateBuilder
Const(Emitter.
CGM);
1047 if (!Builder.Build(ILE,
false))
1050 return Builder.Finalize(ValTy);
1053llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
1056 ConstantAggregateBuilder
Const(Emitter.
CGM);
1060 const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD);
1064 return Builder.Finalize(ValTy);
1067bool ConstStructBuilder::UpdateStruct(ConstantEmitter &Emitter,
1068 ConstantAggregateBuilder &Const,
1070 const InitListExpr *Updater) {
1071 return ConstStructBuilder(Emitter, Const, Offset)
1072 .Build(Updater,
true);
1079static ConstantAddress
1081 const CompoundLiteralExpr *E) {
1082 CodeGenModule &CGM = emitter.
CGM;
1084 if (llvm::GlobalVariable *
Addr =
1086 return ConstantAddress(
Addr,
Addr->getValueType(), Align);
1093 "file-scope compound literal did not have constant initializer!");
1097 auto GV =
new llvm::GlobalVariable(
1100 llvm::GlobalValue::InternalLinkage,
C,
".compoundliteral",
nullptr,
1101 llvm::GlobalVariable::NotThreadLocal,
1106 return ConstantAddress(GV, GV->getValueType(), Align);
1109static llvm::Constant *
1110EmitArrayConstant(CodeGenModule &CGM, llvm::ArrayType *DesiredType,
1111 llvm::Type *CommonElementType, uint64_t
ArrayBound,
1112 SmallVectorImpl<llvm::Constant *> &Elements,
1113 llvm::Constant *Filler) {
1116 if (Elements.size() < NonzeroLength && Filler->isNullValue())
1117 NonzeroLength = Elements.size();
1118 if (NonzeroLength == Elements.size()) {
1119 while (NonzeroLength > 0 && Elements[NonzeroLength - 1]->isNullValue())
1123 if (NonzeroLength == 0)
1124 return llvm::ConstantAggregateZero::get(DesiredType);
1128 if (TrailingZeroes >= 8) {
1129 assert(Elements.size() >= NonzeroLength &&
1130 "missing initializer for non-zero element");
1134 if (CommonElementType && NonzeroLength >= 8) {
1135 llvm::Constant *Initial = llvm::ConstantArray::get(
1136 llvm::ArrayType::get(CommonElementType, NonzeroLength),
1137 ArrayRef(Elements).take_front(NonzeroLength));
1139 Elements[0] = Initial;
1141 Elements.resize(NonzeroLength + 1);
1145 CommonElementType ? CommonElementType : DesiredType->getElementType();
1146 FillerType = llvm::ArrayType::get(FillerType, TrailingZeroes);
1147 Elements.back() = llvm::ConstantAggregateZero::get(FillerType);
1148 CommonElementType =
nullptr;
1152 if (Filler->getType() != CommonElementType)
1153 CommonElementType =
nullptr;
1157 if (CommonElementType)
1158 return llvm::ConstantArray::get(
1159 llvm::ArrayType::get(CommonElementType,
ArrayBound), Elements);
1162 llvm::SmallVector<llvm::Type *, 16> Types;
1163 Types.reserve(Elements.size());
1164 for (llvm::Constant *Elt : Elements)
1165 Types.push_back(Elt->getType());
1166 llvm::StructType *SType =
1168 return llvm::ConstantStruct::get(SType, Elements);
1177class ConstExprEmitter
1178 :
public ConstStmtVisitor<ConstExprEmitter, llvm::Constant *, QualType> {
1180 ConstantEmitter &Emitter;
1181 llvm::LLVMContext &VMContext;
1183 ConstExprEmitter(ConstantEmitter &emitter)
1184 : CGM(emitter.CGM), Emitter(emitter), VMContext(CGM.getLLVMContext()) {
1191 llvm::Constant *VisitStmt(
const Stmt *S, QualType
T) {
return nullptr; }
1193 llvm::Constant *VisitConstantExpr(
const ConstantExpr *CE, QualType
T) {
1199 llvm::Constant *VisitParenExpr(
const ParenExpr *PE, QualType
T) {
1204 VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *PE,
1209 llvm::Constant *VisitGenericSelectionExpr(
const GenericSelectionExpr *GE,
1211 return Visit(
GE->getResultExpr(),
T);
1214 llvm::Constant *VisitChooseExpr(
const ChooseExpr *CE, QualType
T) {
1218 llvm::Constant *VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E,
1223 llvm::Constant *ProduceIntToIntCast(
const Expr *E, QualType DestType) {
1224 QualType FromType = E->
getType();
1227 if (llvm::Constant *
C = Visit(E, FromType))
1228 if (
auto *CI = dyn_cast<llvm::ConstantInt>(
C)) {
1231 if (DstWidth == SrcWidth)
1234 ? CI->getValue().sextOrTrunc(DstWidth)
1235 : CI->getValue().zextOrTrunc(DstWidth);
1241 llvm::Constant *VisitCastExpr(
const CastExpr *E, QualType destType) {
1242 if (
const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
1250 "Destination type is not union type!");
1255 if (!
C)
return nullptr;
1257 auto destTy = ConvertType(destType);
1258 if (
C->getType() == destTy)
return C;
1262 SmallVector<llvm::Constant*, 2> Elts;
1263 SmallVector<llvm::Type*, 2> Types;
1265 Types.push_back(
C->getType());
1266 unsigned CurSize = CGM.
getDataLayout().getTypeAllocSize(
C->getType());
1267 unsigned TotalSize = CGM.
getDataLayout().getTypeAllocSize(destTy);
1269 assert(CurSize <= TotalSize &&
"Union size mismatch!");
1270 if (
unsigned NumPadBytes = TotalSize - CurSize) {
1271 llvm::Constant *Padding =
1273 Elts.push_back(Padding);
1274 Types.push_back(Padding->getType());
1277 llvm::StructType *STy = llvm::StructType::get(VMContext, Types,
false);
1278 return llvm::ConstantStruct::get(STy, Elts);
1281 case CK_AddressSpaceConversion: {
1285 llvm::Type *destTy = ConvertType(E->
getType());
1289 case CK_LValueToRValue: {
1295 dyn_cast<CompoundLiteralExpr>(subExpr->
IgnoreParens()))
1296 return Visit(E->getInitializer(), destType);
1300 case CK_AtomicToNonAtomic:
1301 case CK_NonAtomicToAtomic:
1303 case CK_ConstructorConversion:
1304 return Visit(subExpr, destType);
1306 case CK_ArrayToPointerDecay:
1307 if (
const auto *S = dyn_cast<StringLiteral>(subExpr))
1310 case CK_NullToPointer:
1311 if (Visit(subExpr, destType))
1315 case CK_IntToOCLSampler:
1316 llvm_unreachable(
"global sampler variables are not generated");
1318 case CK_IntegralCast:
1319 return ProduceIntToIntCast(subExpr, destType);
1321 case CK_Dependent: llvm_unreachable(
"saw dependent cast!");
1323 case CK_BuiltinFnToFnPtr:
1324 llvm_unreachable(
"builtin functions are handled elsewhere");
1326 case CK_ReinterpretMemberPointer:
1327 case CK_DerivedToBaseMemberPointer:
1328 case CK_BaseToDerivedMemberPointer: {
1330 if (!
C)
return nullptr;
1335 case CK_ObjCObjectLValueCast:
1336 case CK_ARCProduceObject:
1337 case CK_ARCConsumeObject:
1338 case CK_ARCReclaimReturnedObject:
1339 case CK_ARCExtendBlockObject:
1340 case CK_CopyAndAutoreleaseBlockObject:
1348 case CK_LValueBitCast:
1349 case CK_LValueToRValueBitCast:
1350 case CK_NullToMemberPointer:
1351 case CK_UserDefinedConversion:
1352 case CK_CPointerToObjCPointerCast:
1353 case CK_BlockPointerToObjCPointerCast:
1354 case CK_AnyPointerToBlockPointerCast:
1355 case CK_FunctionToPointerDecay:
1356 case CK_BaseToDerived:
1357 case CK_DerivedToBase:
1358 case CK_UncheckedDerivedToBase:
1359 case CK_MemberPointerToBoolean:
1360 case CK_VectorSplat:
1361 case CK_FloatingRealToComplex:
1362 case CK_FloatingComplexToReal:
1363 case CK_FloatingComplexToBoolean:
1364 case CK_FloatingComplexCast:
1365 case CK_FloatingComplexToIntegralComplex:
1366 case CK_IntegralRealToComplex:
1367 case CK_IntegralComplexToReal:
1368 case CK_IntegralComplexToBoolean:
1369 case CK_IntegralComplexCast:
1370 case CK_IntegralComplexToFloatingComplex:
1371 case CK_PointerToIntegral:
1372 case CK_PointerToBoolean:
1373 case CK_BooleanToSignedIntegral:
1374 case CK_IntegralToPointer:
1375 case CK_IntegralToBoolean:
1376 case CK_IntegralToFloating:
1377 case CK_FloatingToIntegral:
1378 case CK_FloatingToBoolean:
1379 case CK_FloatingCast:
1380 case CK_FloatingToFixedPoint:
1381 case CK_FixedPointToFloating:
1382 case CK_FixedPointCast:
1383 case CK_FixedPointToBoolean:
1384 case CK_FixedPointToIntegral:
1385 case CK_IntegralToFixedPoint:
1386 case CK_ZeroToOCLOpaqueType:
1388 case CK_HLSLVectorTruncation:
1389 case CK_HLSLMatrixTruncation:
1390 case CK_HLSLArrayRValue:
1391 case CK_HLSLElementwiseCast:
1392 case CK_HLSLAggregateSplatCast:
1395 llvm_unreachable(
"Invalid CastKind");
1398 llvm::Constant *VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *DIE,
1405 llvm::Constant *VisitExprWithCleanups(
const ExprWithCleanups *E, QualType
T) {
1409 llvm::Constant *VisitIntegerLiteral(
const IntegerLiteral *I, QualType
T) {
1413 static APValue withDestType(ASTContext &Ctx,
const Expr *E, QualType SrcType,
1414 QualType DestType,
const llvm::APSInt &
Value) {
1419 llvm::RoundingMode RM =
1421 if (RM == llvm::RoundingMode::Dynamic)
1422 RM = llvm::RoundingMode::NearestTiesToEven;
1430 llvm::Constant *EmitArrayInitialization(
const InitListExpr *ILE, QualType
T) {
1432 assert(CAT &&
"can't emit array init for non-constant-bound array");
1434 const uint64_t NumElements = CAT->getZExtSize();
1436 if (
const auto *Embed =
1437 dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1438 NumInitElements += Embed->getDataElementCount() - 1;
1439 if (NumInitElements > NumElements) {
1440 NumInitElements = NumElements;
1448 uint64_t NumInitableElts = std::min<uint64_t>(NumInitElements, NumElements);
1450 QualType EltType = CAT->getElementType();
1453 llvm::Constant *fillC =
nullptr;
1461 SmallVector<llvm::Constant *, 16> Elts;
1462 if (fillC && fillC->isNullValue())
1463 Elts.reserve(NumInitableElts + 1);
1465 Elts.reserve(NumElements);
1467 llvm::Type *CommonElementType =
nullptr;
1468 auto Emit = [&](
const Expr *
Init,
unsigned ArrayIndex) {
1469 llvm::Constant *
C =
nullptr;
1473 if (ArrayIndex == 0)
1474 CommonElementType =
C->getType();
1475 else if (
C->getType() != CommonElementType)
1476 CommonElementType =
nullptr;
1481 unsigned ArrayIndex = 0;
1482 QualType DestTy = CAT->getElementType();
1483 for (
unsigned i = 0; i < ILE->
getNumInits(); ++i) {
1485 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1486 StringLiteral *SL = EmbedS->getDataStringLiteral();
1490 for (
unsigned I = EmbedS->getStartingElementPos(),
1491 N = EmbedS->getDataElementCount();
1492 I != EmbedS->getStartingElementPos() + N; ++I) {
1507 if ((ArrayIndex - EmbedS->getDataElementCount()) == 0)
1508 CommonElementType =
C->getType();
1509 else if (
C->getType() != CommonElementType)
1510 CommonElementType =
nullptr;
1512 if (!Emit(
Init, ArrayIndex))
1518 llvm::ArrayType *Desired =
1520 return EmitArrayConstant(CGM, Desired, CommonElementType, NumElements, Elts,
1524 llvm::Constant *EmitRecordInitialization(
const InitListExpr *ILE,
1526 return ConstStructBuilder::BuildStruct(Emitter, ILE,
T);
1529 llvm::Constant *VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E,
1534 llvm::Constant *VisitInitListExpr(
const InitListExpr *ILE, QualType
T) {
1539 return EmitArrayInitialization(ILE,
T);
1542 return EmitRecordInitialization(ILE,
T);
1548 VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E,
1549 QualType destType) {
1550 auto C = Visit(E->
getBase(), destType);
1554 ConstantAggregateBuilder
Const(CGM);
1557 if (!EmitDesignatedInitUpdater(Emitter, Const,
CharUnits::Zero(), destType,
1562 bool HasFlexibleArray =
false;
1565 return Const.build(ValTy, HasFlexibleArray);
1568 llvm::Constant *VisitCXXConstructExpr(
const CXXConstructExpr *E,
1575 assert(E->
getNumArgs() == 1 &&
"trivial ctor with > 1 argument");
1577 "trivial ctor has argument but isn't a copy/move ctor");
1579 const Expr *Arg = E->
getArg(0);
1581 "argument to copy ctor is of wrong type");
1585 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(Arg))
1586 return Visit(MTE->getSubExpr(), Ty);
1594 llvm::Constant *VisitStringLiteral(
const StringLiteral *E, QualType
T) {
1599 llvm::Constant *VisitObjCEncodeExpr(
const ObjCEncodeExpr *E, QualType
T) {
1606 assert(CAT &&
"String data not of constant array type!");
1611 return llvm::ConstantDataArray::getString(VMContext, Str,
false);
1614 llvm::Constant *VisitUnaryExtension(
const UnaryOperator *E, QualType
T) {
1618 llvm::Constant *VisitUnaryMinus(
const UnaryOperator *U, QualType
T) {
1620 if (
auto *CI = dyn_cast<llvm::ConstantInt>(
C))
1621 return llvm::ConstantInt::get(CGM.
getLLVMContext(), -CI->getValue());
1625 llvm::Constant *VisitPackIndexingExpr(
const PackIndexingExpr *E, QualType
T) {
1630 llvm::Type *ConvertType(QualType
T) {
1637llvm::Constant *ConstantEmitter::validateAndPopAbstract(llvm::Constant *
C,
1638 AbstractState saved) {
1639 Abstract = saved.OldValue;
1641 assert(saved.OldPlaceholdersSize == PlaceholderAddresses.size() &&
1642 "created a placeholder while doing an abstract emission?");
1651 auto state = pushAbstract();
1653 return validateAndPopAbstract(
C, state);
1658 auto state = pushAbstract();
1660 return validateAndPopAbstract(
C, state);
1665 auto state = pushAbstract();
1667 return validateAndPopAbstract(
C, state);
1676 RetType =
CGM.getContext().getLValueReferenceType(RetType);
1683 auto state = pushAbstract();
1685 C = validateAndPopAbstract(
C, state);
1688 "internal error: could not emit constant value \"abstractly\"");
1689 C =
CGM.EmitNullConstant(destType);
1697 bool EnablePtrAuthFunctionTypeDiscrimination) {
1698 auto state = pushAbstract();
1700 tryEmitPrivate(value, destType, EnablePtrAuthFunctionTypeDiscrimination);
1701 C = validateAndPopAbstract(
C, state);
1704 "internal error: could not emit constant value \"abstractly\"");
1705 C =
CGM.EmitNullConstant(destType);
1719 for (
auto [_, GV] : PlaceholderAddresses)
1720 GV->eraseFromParent();
1721 PlaceholderAddresses.clear();
1725 return markIfFailed(
Init);
1731 initializeNonAbstract(destAddrSpace);
1738 initializeNonAbstract(destAddrSpace);
1740 assert(
C &&
"couldn't emit constant value non-abstractly?");
1745 assert(!Abstract &&
"cannot get current address for abstract constant");
1751 auto global =
new llvm::GlobalVariable(
CGM.getModule(),
CGM.Int8Ty,
true,
1752 llvm::GlobalValue::PrivateLinkage,
1756 llvm::GlobalVariable::NotThreadLocal,
1757 CGM.getContext().getTargetAddressSpace(DestAddressSpace));
1759 PlaceholderAddresses.push_back(std::make_pair(
nullptr, global));
1765 llvm::GlobalValue *placeholder) {
1766 assert(!PlaceholderAddresses.empty());
1767 assert(PlaceholderAddresses.back().first ==
nullptr);
1768 assert(PlaceholderAddresses.back().second == placeholder);
1769 PlaceholderAddresses.back().first = signal;
1773 struct ReplacePlaceholders {
1777 llvm::Constant *
Base;
1778 llvm::Type *BaseValueTy =
nullptr;
1781 llvm::DenseMap<llvm::Constant*, llvm::GlobalVariable*> PlaceholderAddresses;
1784 llvm::DenseMap<llvm::GlobalVariable*, llvm::Constant*> Locations;
1792 ReplacePlaceholders(
CodeGenModule &CGM, llvm::Constant *base,
1793 ArrayRef<std::pair<llvm::Constant*,
1794 llvm::GlobalVariable*>> addresses)
1795 : CGM(CGM),
Base(base),
1796 PlaceholderAddresses(addresses.begin(), addresses.end()) {
1799 void replaceInInitializer(llvm::Constant *init) {
1801 BaseValueTy = init->getType();
1804 Indices.push_back(0);
1805 IndexValues.push_back(
nullptr);
1808 findLocations(init);
1811 assert(IndexValues.size() == Indices.size() &&
"mismatch");
1812 assert(Indices.size() == 1 &&
"didn't pop all indices");
1815 assert(Locations.size() == PlaceholderAddresses.size() &&
1816 "missed a placeholder?");
1822 for (
auto &entry : Locations) {
1823 assert(entry.first->getName() ==
"" &&
"not a placeholder!");
1824 entry.first->replaceAllUsesWith(entry.second);
1825 entry.first->eraseFromParent();
1830 void findLocations(llvm::Constant *init) {
1832 if (
auto agg = dyn_cast<llvm::ConstantAggregate>(init)) {
1833 for (
unsigned i = 0, e = agg->getNumOperands(); i != e; ++i) {
1834 Indices.push_back(i);
1835 IndexValues.push_back(
nullptr);
1837 findLocations(agg->getOperand(i));
1839 IndexValues.pop_back();
1847 auto it = PlaceholderAddresses.find(init);
1848 if (it != PlaceholderAddresses.end()) {
1849 setLocation(it->second);
1854 if (
auto expr = dyn_cast<llvm::ConstantExpr>(init)) {
1855 init =
expr->getOperand(0);
1862 void setLocation(llvm::GlobalVariable *placeholder) {
1863 assert(!Locations.contains(placeholder) &&
1864 "already found location for placeholder!");
1869 assert(Indices.size() == IndexValues.size());
1870 for (
size_t i = Indices.size() - 1; i !=
size_t(-1); --i) {
1871 if (IndexValues[i]) {
1873 for (
size_t j = 0; j != i + 1; ++j) {
1874 assert(IndexValues[j] &&
1883 IndexValues[i] = llvm::ConstantInt::get(CGM.
Int32Ty, Indices[i]);
1886 llvm::Constant *location = llvm::ConstantExpr::getInBoundsGetElementPtr(
1887 BaseValueTy, Base, IndexValues);
1889 Locations.insert({placeholder, location});
1895 assert(InitializedNonAbstract &&
1896 "finalizing emitter that was used for abstract emission?");
1897 assert(!Finalized &&
"finalizing emitter multiple times");
1898 assert(global->getInitializer());
1903 if (!PlaceholderAddresses.empty()) {
1904 ReplacePlaceholders(
CGM, global, PlaceholderAddresses)
1905 .replaceInInitializer(global->getInitializer());
1906 PlaceholderAddresses.clear();
1911 assert((!InitializedNonAbstract || Finalized || Failed) &&
1912 "not finalized after being initialized for non-abstract emission");
1913 assert(PlaceholderAddresses.empty() &&
"unhandled placeholders");
1919 type.getQualifiers());
1932 dyn_cast_or_null<CXXConstructExpr>(D.
getInit())) {
1942 assert(E &&
"No initializer to emit");
1946 if (llvm::Constant *
C = ConstExprEmitter(*this).Visit(E, nonMemoryDestType))
1953 assert(!value->allowConstexprUnknown() &&
1954 "Constexpr unknown values are not allowed in CodeGen");
1998 assert(Schema &&
"applying trivial ptrauth schema");
2001 return UnsignedPointer;
2003 unsigned Key = Schema.
getKey();
2006 llvm::GlobalValue *StorageAddress =
nullptr;
2015 llvm::ConstantInt *Discriminator =
2018 llvm::Constant *SignedPointer =
CGM.getConstantSignedPointer(
2019 UnsignedPointer, Key, StorageAddress, Discriminator);
2024 return SignedPointer;
2032 QualType destValueType = AT->getValueType();
2035 uint64_t innerSize =
CGM.getContext().getTypeSize(destValueType);
2036 uint64_t outerSize =
CGM.getContext().getTypeSize(destType);
2037 if (innerSize == outerSize)
2040 assert(innerSize < outerSize &&
"emitted over-large constant for atomic");
2041 llvm::Constant *elts[] = {
2043 llvm::ConstantAggregateZero::get(
2044 llvm::ArrayType::get(
CGM.Int8Ty, (outerSize - innerSize) / 8))
2046 return llvm::ConstantStruct::getAnon(elts);
2051 if ((
C->getType()->isIntegerTy(1) && !destType->
isBitIntType()) ||
2054 llvm::Type *boolTy =
CGM.getTypes().ConvertTypeForMem(destType);
2055 llvm::Constant *Res = llvm::ConstantFoldCastOperand(
2056 llvm::Instruction::ZExt,
C, boolTy,
CGM.getDataLayout());
2057 assert(Res &&
"Constant folding must succeed");
2062 llvm::Type *MemTy =
CGM.getTypes().ConvertTypeForMem(destType);
2063 if (
C->getType() != MemTy) {
2064 ConstantAggregateBuilder Builder(
CGM);
2065 llvm::Type *LoadStoreTy =
2066 CGM.getTypes().convertTypeForLoadStore(destType);
2070 llvm::Constant *Res = llvm::ConstantFoldCastOperand(
2072 ? llvm::Instruction::SExt
2073 : llvm::Instruction::ZExt,
2074 CI, LoadStoreTy,
CGM.getDataLayout());
2075 if (
CGM.getTypes().typeRequiresSplitIntoByteArray(destType,
2080 Builder.addBits(
Value, 0,
false);
2081 return Builder.build(MemTy,
false);
2092 assert(!destType->
isVoidType() &&
"can't emit a void constant");
2095 if (llvm::Constant *
C = ConstExprEmitter(*this).Visit(E, destType))
2120struct ConstantLValue {
2121 llvm::Constant *
Value;
2122 bool HasOffsetApplied;
2123 bool HasDestPointerAuth;
2125 ConstantLValue(llvm::Constant *value,
2126 bool hasOffsetApplied =
false,
2127 bool hasDestPointerAuth =
false)
2128 :
Value(value), HasOffsetApplied(hasOffsetApplied),
2129 HasDestPointerAuth(hasDestPointerAuth) {}
2132 : ConstantLValue(address.getPointer()) {}
2136class ConstantLValueEmitter :
public ConstStmtVisitor<ConstantLValueEmitter,
2139 ConstantEmitter &Emitter;
2142 bool EnablePtrAuthFunctionTypeDiscrimination;
2145 friend StmtVisitorBase;
2148 ConstantLValueEmitter(ConstantEmitter &emitter,
const APValue &value,
2150 bool EnablePtrAuthFunctionTypeDiscrimination =
true)
2151 : CGM(emitter.CGM), Emitter(emitter),
Value(value), DestType(destType),
2152 EnablePtrAuthFunctionTypeDiscrimination(
2153 EnablePtrAuthFunctionTypeDiscrimination) {}
2155 llvm::Constant *tryEmit();
2158 llvm::Constant *tryEmitAbsolute(llvm::Type *destTy);
2159 ConstantLValue tryEmitBase(
const APValue::LValueBase &base);
2161 ConstantLValue VisitStmt(
const Stmt *S) {
return nullptr; }
2162 ConstantLValue VisitConstantExpr(
const ConstantExpr *E);
2163 ConstantLValue VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
2164 ConstantLValue VisitStringLiteral(
const StringLiteral *E);
2165 ConstantLValue VisitObjCBoxedExpr(
const ObjCBoxedExpr *E);
2166 ConstantLValue VisitObjCEncodeExpr(
const ObjCEncodeExpr *E);
2167 ConstantLValue VisitObjCStringLiteral(
const ObjCStringLiteral *E);
2168 llvm::Constant *VisitObjCCollectionElement(
const Expr *E);
2169 ConstantLValue VisitObjCArrayLiteral(
const ObjCArrayLiteral *E);
2170 ConstantLValue VisitObjCDictionaryLiteral(
const ObjCDictionaryLiteral *E);
2171 ConstantLValue VisitPredefinedExpr(
const PredefinedExpr *E);
2172 ConstantLValue VisitAddrLabelExpr(
const AddrLabelExpr *E);
2173 ConstantLValue VisitCallExpr(
const CallExpr *E);
2174 ConstantLValue VisitBlockExpr(
const BlockExpr *E);
2175 ConstantLValue VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
2176 ConstantLValue VisitMaterializeTemporaryExpr(
2177 const MaterializeTemporaryExpr *E);
2179 ConstantLValue emitPointerAuthSignConstant(
const CallExpr *E);
2180 llvm::Constant *emitPointerAuthPointer(
const Expr *E);
2181 unsigned emitPointerAuthKey(
const Expr *E);
2182 std::pair<llvm::Constant *, llvm::ConstantInt *>
2183 emitPointerAuthDiscriminator(
const Expr *E);
2185 bool hasNonZeroOffset()
const {
2186 return !
Value.getLValueOffset().isZero();
2190 llvm::Constant *getOffset() {
2191 return llvm::ConstantInt::get(CGM.
Int64Ty,
2192 Value.getLValueOffset().getQuantity());
2196 llvm::Constant *applyOffset(llvm::Constant *
C) {
2197 if (!hasNonZeroOffset())
2200 return llvm::ConstantExpr::getPtrAdd(
C, getOffset());
2206llvm::Constant *ConstantLValueEmitter::tryEmit() {
2207 const APValue::LValueBase &base =
Value.getLValueBase();
2222 return tryEmitAbsolute(destTy);
2226 ConstantLValue result = tryEmitBase(base);
2229 llvm::Constant *value = result.Value;
2230 if (!value)
return nullptr;
2233 if (!result.HasOffsetApplied) {
2234 value = applyOffset(value);
2238 if (PointerAuthQualifier PointerAuth = DestType.
getPointerAuth();
2239 PointerAuth && !result.HasDestPointerAuth) {
2248 return llvm::ConstantExpr::getPointerCast(value, destTy);
2250 return llvm::ConstantExpr::getPtrToInt(value, destTy);
2256ConstantLValueEmitter::tryEmitAbsolute(llvm::Type *destTy) {
2259 if (
Value.isNullPointer()) {
2267 auto intptrTy = CGM.
getDataLayout().getIntPtrType(destPtrTy);
2269 C = llvm::ConstantFoldIntegerCast(getOffset(), intptrTy,
false,
2271 assert(
C &&
"Must have folded, as Offset is a ConstantInt");
2272 C = llvm::ConstantExpr::getIntToPtr(
C, destPtrTy);
2277ConstantLValueEmitter::tryEmitBase(
const APValue::LValueBase &base) {
2279 if (
const ValueDecl *D = base.
dyn_cast<
const ValueDecl*>()) {
2284 if (D->hasAttr<WeakRefAttr>())
2287 auto PtrAuthSign = [&](llvm::Constant *
C) {
2288 if (PointerAuthQualifier PointerAuth = DestType.
getPointerAuth()) {
2291 return ConstantLValue(
C,
true,
true);
2294 CGPointerAuthInfo AuthInfo;
2296 if (EnablePtrAuthFunctionTypeDiscrimination)
2300 if (hasNonZeroOffset())
2301 return ConstantLValue(
nullptr);
2305 C, AuthInfo.
getKey(),
nullptr,
2307 return ConstantLValue(
C,
true,
true);
2310 return ConstantLValue(
C);
2313 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
2315 if (FD->getType()->isCFIUncheckedCalleeFunctionType())
2317 return PtrAuthSign(
C);
2320 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
2322 if (!VD->hasLocalStorage()) {
2323 if (VD->isFileVarDecl() || VD->hasExternalStorage())
2326 if (VD->isLocalVarDecl()) {
2333 if (
const auto *GD = dyn_cast<MSGuidDecl>(D))
2336 if (
const auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D))
2339 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D))
2346 if (TypeInfoLValue TI = base.
dyn_cast<TypeInfoLValue>())
2350 return Visit(base.
get<
const Expr*>());
2354ConstantLValueEmitter::VisitConstantExpr(
const ConstantExpr *E) {
2361ConstantLValueEmitter::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
2362 ConstantEmitter CompoundLiteralEmitter(CGM, Emitter.
CGF);
2368ConstantLValueEmitter::VisitStringLiteral(
const StringLiteral *E) {
2373ConstantLValueEmitter::VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
2385ConstantLValueEmitter::VisitObjCStringLiteral(
const ObjCStringLiteral *E) {
2390ConstantLValueEmitter::VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
2397 "Non const NSNumber is being emitted as a constant");
2404 const bool IsBoolType =
2406 bool BoolValue =
false;
2412 Expr::EvalResult IntResult{};
2419 llvm::APFloat FloatValue(0.0);
2425 llvm_unreachable(
"SubExpr is expected to be evaluated as a numeric type");
2429ConstantLValueEmitter::VisitObjCCollectionElement(
const Expr *E) {
2432 QualType DestTy = CE->
getType();
2434 assert(CE->getCastKind() == CK_BitCast &&
2435 "Expected a CK_BitCast type for valid items in constant objc "
2436 "collection literals");
2439 ConstantLValue LV = Visit(Elm);
2441 llvm::Constant *Val = llvm::ConstantExpr::getBitCast(ConstVal, DstTy);
2446ConstantLValueEmitter::VisitObjCArrayLiteral(
const ObjCArrayLiteral *E) {
2447 SmallVector<llvm::Constant *, 16> ObjectExpressions;
2449 ObjectExpressions.reserve(NumElements);
2451 for (uint64_t i = 0; i < NumElements; i++) {
2452 llvm::Constant *Val = VisitObjCCollectionElement(E->
getElement(i));
2453 ObjectExpressions.push_back(Val);
2460ConstantLValue ConstantLValueEmitter::VisitObjCDictionaryLiteral(
2461 const ObjCDictionaryLiteral *E) {
2462 SmallVector<std::pair<llvm::Constant *, llvm::Constant *>, 16> KeysAndObjects;
2464 KeysAndObjects.reserve(NumElements);
2466 for (uint64_t i = 0; i < NumElements; i++) {
2467 llvm::Constant *Key =
2469 llvm::Constant *Val =
2471 KeysAndObjects.push_back({Key, Val});
2479ConstantLValueEmitter::VisitPredefinedExpr(
const PredefinedExpr *E) {
2484ConstantLValueEmitter::VisitAddrLabelExpr(
const AddrLabelExpr *E) {
2485 assert(Emitter.
CGF &&
"Invalid address of label expression outside function");
2491ConstantLValueEmitter::VisitCallExpr(
const CallExpr *E) {
2493 if (builtin == Builtin::BI__builtin_function_start)
2497 if (builtin == Builtin::BI__builtin_ptrauth_sign_constant)
2498 return emitPointerAuthSignConstant(E);
2500 if (builtin != Builtin::BI__builtin___CFStringMakeConstantString &&
2501 builtin != Builtin::BI__builtin___NSStringMakeConstantString)
2505 if (builtin == Builtin::BI__builtin___NSStringMakeConstantString) {
2514ConstantLValueEmitter::emitPointerAuthSignConstant(
const CallExpr *E) {
2515 llvm::Constant *UnsignedPointer = emitPointerAuthPointer(E->
getArg(0));
2516 unsigned Key = emitPointerAuthKey(E->
getArg(1));
2517 auto [StorageAddress, OtherDiscriminator] =
2518 emitPointerAuthDiscriminator(E->
getArg(2));
2521 UnsignedPointer, Key, StorageAddress, OtherDiscriminator);
2522 return SignedPointer;
2525llvm::Constant *ConstantLValueEmitter::emitPointerAuthPointer(
const Expr *E) {
2532 assert(
Result.Val.isLValue());
2534 assert(
Result.Val.getLValueOffset().isZero());
2535 return ConstantEmitter(CGM, Emitter.
CGF)
2539unsigned ConstantLValueEmitter::emitPointerAuthKey(
const Expr *E) {
2543std::pair<llvm::Constant *, llvm::ConstantInt *>
2544ConstantLValueEmitter::emitPointerAuthDiscriminator(
const Expr *E) {
2547 if (
const auto *
Call = dyn_cast<CallExpr>(E)) {
2548 if (
Call->getBuiltinCallee() ==
2549 Builtin::BI__builtin_ptrauth_blend_discriminator) {
2550 llvm::Constant *
Pointer = ConstantEmitter(CGM).emitAbstract(
2551 Call->getArg(0),
Call->getArg(0)->getType());
2553 Call->getArg(1),
Call->getArg(1)->getType()));
2558 llvm::Constant *
Result = ConstantEmitter(CGM).emitAbstract(E, E->
getType());
2559 if (
Result->getType()->isPointerTy())
2560 return {
Result,
nullptr};
2565ConstantLValueEmitter::VisitBlockExpr(
const BlockExpr *E) {
2566 StringRef functionName;
2567 if (
auto CGF = Emitter.
CGF)
2568 functionName = CGF->CurFn->getName();
2570 functionName =
"global";
2576ConstantLValueEmitter::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
2586ConstantLValueEmitter::VisitMaterializeTemporaryExpr(
2587 const MaterializeTemporaryExpr *E) {
2595 bool EnablePtrAuthFunctionTypeDiscrimination) {
2600 return llvm::UndefValue::get(
CGM.getTypes().ConvertType(DestType));
2602 return ConstantLValueEmitter(*
this,
Value, DestType,
2603 EnablePtrAuthFunctionTypeDiscrimination)
2608 (PointerAuth.authenticatesNullValues() ||
Value.getInt() != 0))
2610 return llvm::ConstantInt::get(
CGM.getLLVMContext(),
Value.getInt());
2612 return llvm::ConstantInt::get(
CGM.getLLVMContext(),
2613 Value.getFixedPoint().getValue());
2617 Complex[0] = llvm::ConstantInt::get(
CGM.getLLVMContext(),
2618 Value.getComplexIntReal());
2619 Complex[1] = llvm::ConstantInt::get(
CGM.getLLVMContext(),
2620 Value.getComplexIntImag());
2623 llvm::StructType *STy =
2625 return llvm::ConstantStruct::get(STy,
Complex);
2628 return llvm::ConstantFP::get(
CGM.getLLVMContext(),
Value.getFloat());
2632 Complex[0] = llvm::ConstantFP::get(
CGM.getLLVMContext(),
2633 Value.getComplexFloatReal());
2634 Complex[1] = llvm::ConstantFP::get(
CGM.getLLVMContext(),
2635 Value.getComplexFloatImag());
2638 llvm::StructType *STy =
2640 return llvm::ConstantStruct::get(STy,
Complex);
2643 unsigned NumElts =
Value.getVectorLength();
2646 for (
unsigned I = 0; I != NumElts; ++I) {
2649 Inits[I] = llvm::ConstantInt::get(
CGM.getLLVMContext(), Elt.
getInt());
2653 Inits[I] = llvm::UndefValue::get(
CGM.getTypes().ConvertType(
2656 llvm_unreachable(
"unsupported vector element type");
2658 return llvm::ConstantVector::get(
Inits);
2662 unsigned NumRows =
Value.getMatrixNumRows();
2663 unsigned NumCols =
Value.getMatrixNumColumns();
2664 unsigned NumElts = NumRows * NumCols;
2669 for (
unsigned Row = 0; Row != NumRows; ++Row) {
2670 for (
unsigned Col = 0; Col != NumCols; ++Col) {
2672 unsigned Idx = MT->getFlattenedIndex(Row, Col, IsRowMajor);
2675 llvm::ConstantInt::get(
CGM.getLLVMContext(), Elt.
getInt());
2678 llvm::ConstantFP::get(
CGM.getLLVMContext(), Elt.
getFloat());
2680 Inits[Idx] = llvm::PoisonValue::get(
2681 CGM.getTypes().ConvertType(MT->getElementType()));
2683 llvm_unreachable(
"unsupported matrix element type");
2686 return llvm::ConstantVector::get(
Inits);
2693 if (!LHS || !RHS)
return nullptr;
2696 llvm::Type *ResultType =
CGM.getTypes().ConvertType(DestType);
2697 LHS = llvm::ConstantExpr::getPtrToInt(LHS,
CGM.IntPtrTy);
2698 RHS = llvm::ConstantExpr::getPtrToInt(RHS,
CGM.IntPtrTy);
2699 llvm::Constant *AddrLabelDiff = llvm::ConstantExpr::getSub(LHS, RHS);
2704 return llvm::ConstantExpr::getTruncOrBitCast(AddrLabelDiff, ResultType);
2708 return ConstStructBuilder::BuildStruct(*
this,
Value, DestType);
2710 const ArrayType *ArrayTy =
CGM.getContext().getAsArrayType(DestType);
2711 unsigned NumElements =
Value.getArraySize();
2712 unsigned NumInitElts =
Value.getArrayInitializedElts();
2715 llvm::Constant *Filler =
nullptr;
2716 if (
Value.hasArrayFiller()) {
2725 if (Filler && Filler->isNullValue())
2726 Elts.reserve(NumInitElts + 1);
2728 Elts.reserve(NumElements);
2730 llvm::Type *CommonElementType =
nullptr;
2731 for (
unsigned I = 0; I < NumInitElts; ++I) {
2734 if (!
C)
return nullptr;
2737 CommonElementType =
C->getType();
2738 else if (
C->getType() != CommonElementType)
2739 CommonElementType =
nullptr;
2743 llvm::ArrayType *Desired =
2748 Desired = llvm::ArrayType::get(Desired->getElementType(), Elts.size());
2750 return EmitArrayConstant(
CGM, Desired, CommonElementType, NumElements, Elts,
2754 return CGM.getCXXABI().EmitMemberPointer(
Value, DestType);
2756 llvm_unreachable(
"Unknown APValue kind");
2761 return EmittedCompoundLiterals.lookup(E);
2766 bool Ok = EmittedCompoundLiterals.insert(std::make_pair(CLE, GV)).second;
2768 assert(
Ok &&
"CLE has already been emitted!");
2773 assert(E->
isFileScope() &&
"not a file-scope compound literal expr");
2786 return getCXXABI().EmitMemberFunctionPointer(method);
2796 llvm::Type *baseType,
2801 bool asCompleteObject) {
2803 llvm::StructType *structure =
2807 unsigned numElements = structure->getNumElements();
2808 std::vector<llvm::Constant *> elements(numElements);
2810 auto CXXR = dyn_cast<CXXRecordDecl>(record);
2813 for (
const auto &I : CXXR->bases()) {
2814 if (I.isVirtual()) {
2830 llvm::Type *baseType = structure->getElementType(fieldIndex);
2836 for (
const auto *Field : record->
fields()) {
2839 if (!Field->isBitField() &&
2847 if (Field->getIdentifier())
2849 if (
const auto *FieldRD = Field->getType()->getAsRecordDecl())
2850 if (FieldRD->findFirstNamedDataMember())
2856 if (CXXR && asCompleteObject) {
2857 for (
const auto &I : CXXR->vbases()) {
2866 if (elements[fieldIndex])
continue;
2868 llvm::Type *baseType = structure->getElementType(fieldIndex);
2874 for (
unsigned i = 0; i != numElements; ++i) {
2876 elements[i] = llvm::Constant::getNullValue(structure->getElementType(i));
2879 return llvm::ConstantStruct::get(structure, elements);
2884 llvm::Type *baseType,
2890 return llvm::Constant::getNullValue(baseType);
2903 llvm::Type *LT =
getTypes().ConvertTypeForMem(
T);
2904 if (
auto *PT = dyn_cast<llvm::PointerType>(LT))
2908 return llvm::Constant::getNullValue(LT);
2912 return llvm::Constant::getNullValue(
getTypes().ConvertTypeForMem(
T));
2915 llvm::ArrayType *ATy =
2920 llvm::Constant *Element =
2924 return llvm::ConstantArray::get(ATy, Array);
2927 if (
const auto *RD =
T->getAsRecordDecl())
2928 return ::EmitNullConstant(*
this, RD,
2931 assert(
T->isMemberDataPointerType() &&
2932 "Should only see pointers to data members here!");
2939 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.
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.
std::optional< PointerAuthQualifier > getVTablePointerAuthentication(const CXXRecordDecl *thisClass)
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)
The JSON file list parser is used to communicate input to InstallAPI.
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.