27#include "llvm/ADT/STLExtras.h"
28#include "llvm/ADT/Sequence.h"
29#include "llvm/Analysis/ConstantFolding.h"
30#include "llvm/IR/Constants.h"
31#include "llvm/IR/DataLayout.h"
32#include "llvm/IR/Function.h"
33#include "llvm/IR/GlobalVariable.h"
34#include "llvm/Support/SipHash.h"
44class ConstExprEmitter;
47 llvm::Type *Ty = CGM.
CharTy;
49 Ty = llvm::ArrayType::get(Ty, PadSize.
getQuantity());
51 return llvm::Constant::getNullValue(Ty);
53 return llvm::UndefValue::get(Ty);
56struct ConstantAggregateBuilderUtils {
59 ConstantAggregateBuilderUtils(CodeGenModule &CGM) : CGM(CGM) {}
61 CharUnits getAlignment(
const llvm::Constant *
C)
const {
66 CharUnits getSize(llvm::Type *Ty)
const {
70 CharUnits getSize(
const llvm::Constant *
C)
const {
71 return getSize(
C->getType());
74 llvm::Constant *getPadding(CharUnits PadSize)
const {
75 return ::getPadding(CGM, PadSize);
78 llvm::Constant *getZeroes(CharUnits ZeroSize)
const {
80 return llvm::ConstantAggregateZero::get(Ty);
86class ConstantAggregateBuilder :
private ConstantAggregateBuilderUtils {
95 llvm::SmallVector<llvm::Constant*, 32> Elems;
96 llvm::SmallVector<CharUnits, 32> Offsets;
105 bool NaturalLayout =
true;
107 bool split(
size_t Index, CharUnits Hint);
108 std::optional<size_t> splitAt(CharUnits Pos);
110 static llvm::Constant *buildFrom(CodeGenModule &CGM,
111 ArrayRef<llvm::Constant *> Elems,
112 ArrayRef<CharUnits> Offsets,
113 CharUnits StartOffset, CharUnits Size,
114 bool NaturalLayout, llvm::Type *DesiredTy,
115 bool AllowOversized);
118 ConstantAggregateBuilder(CodeGenModule &CGM)
119 : ConstantAggregateBuilderUtils(CGM) {}
126 bool add(llvm::Constant *
C, CharUnits Offset,
bool AllowOverwrite);
129 bool addBits(llvm::APInt Bits, uint64_t OffsetInBits,
bool AllowOverwrite);
133 void condense(CharUnits Offset, llvm::Type *DesiredTy);
140 llvm::Constant *build(llvm::Type *DesiredTy,
bool AllowOversized)
const {
142 NaturalLayout, DesiredTy, AllowOversized);
146template<
typename Container,
typename Range = std::initializer_list<
147 typename Container::value_type>>
148static void replace(Container &
C,
size_t BeginOff,
size_t EndOff, Range Vals) {
149 assert(BeginOff <= EndOff &&
"invalid replacement range");
150 llvm::replace(
C,
C.begin() + BeginOff,
C.begin() + EndOff, Vals);
153bool ConstantAggregateBuilder::add(llvm::Constant *
C,
CharUnits Offset,
154 bool AllowOverwrite) {
156 if (Offset >= Size) {
157 CharUnits Align = getAlignment(
C);
158 CharUnits AlignedSize =
Size.alignTo(Align);
159 if (AlignedSize > Offset || Offset.
alignTo(Align) != Offset)
160 NaturalLayout =
false;
161 else if (AlignedSize < Offset) {
162 Elems.push_back(getPadding(Offset - Size));
163 Offsets.push_back(Size);
166 Offsets.push_back(Offset);
167 Size = Offset + getSize(
C);
172 std::optional<size_t> FirstElemToReplace = splitAt(Offset);
173 if (!FirstElemToReplace)
176 CharUnits CSize = getSize(
C);
177 std::optional<size_t> LastElemToReplace = splitAt(Offset + CSize);
178 if (!LastElemToReplace)
181 assert((FirstElemToReplace == LastElemToReplace || AllowOverwrite) &&
182 "unexpectedly overwriting field");
184 replace(Elems, *FirstElemToReplace, *LastElemToReplace, {
C});
185 replace(Offsets, *FirstElemToReplace, *LastElemToReplace, {Offset});
186 Size = std::max(Size, Offset + CSize);
187 NaturalLayout =
false;
191bool ConstantAggregateBuilder::addBits(llvm::APInt Bits, uint64_t OffsetInBits,
192 bool AllowOverwrite) {
198 unsigned OffsetWithinChar = OffsetInBits % CharWidth;
202 for (CharUnits OffsetInChars =
206 unsigned WantedBits =
207 std::min((uint64_t)Bits.getBitWidth(), CharWidth - OffsetWithinChar);
211 llvm::APInt BitsThisChar = Bits;
212 if (BitsThisChar.getBitWidth() < CharWidth)
213 BitsThisChar = BitsThisChar.zext(CharWidth);
217 int Shift = Bits.getBitWidth() - CharWidth + OffsetWithinChar;
219 BitsThisChar.lshrInPlace(Shift);
221 BitsThisChar = BitsThisChar.shl(-Shift);
223 BitsThisChar = BitsThisChar.shl(OffsetWithinChar);
225 if (BitsThisChar.getBitWidth() > CharWidth)
226 BitsThisChar = BitsThisChar.trunc(CharWidth);
228 if (WantedBits == CharWidth) {
231 OffsetInChars, AllowOverwrite);
236 std::optional<size_t> FirstElemToUpdate = splitAt(OffsetInChars);
237 if (!FirstElemToUpdate)
239 std::optional<size_t> LastElemToUpdate =
241 if (!LastElemToUpdate)
243 assert(*LastElemToUpdate - *FirstElemToUpdate < 2 &&
244 "should have at most one element covering one byte");
247 llvm::APInt UpdateMask(CharWidth, 0);
249 UpdateMask.setBits(CharWidth - OffsetWithinChar - WantedBits,
250 CharWidth - OffsetWithinChar);
252 UpdateMask.setBits(OffsetWithinChar, OffsetWithinChar + WantedBits);
253 BitsThisChar &= UpdateMask;
255 if (*FirstElemToUpdate == *LastElemToUpdate ||
256 Elems[*FirstElemToUpdate]->isNullValue() ||
260 OffsetInChars,
true);
262 llvm::Constant *&ToUpdate = Elems[*FirstElemToUpdate];
265 auto *CI = dyn_cast<llvm::ConstantInt>(ToUpdate);
270 assert(CI->getBitWidth() == CharWidth &&
"splitAt failed");
271 assert((!(CI->getValue() & UpdateMask) || AllowOverwrite) &&
272 "unexpectedly overwriting bitfield");
273 BitsThisChar |= (CI->getValue() & ~UpdateMask);
274 ToUpdate = llvm::ConstantInt::get(CGM.
getLLVMContext(), BitsThisChar);
279 if (WantedBits == Bits.getBitWidth())
284 Bits.lshrInPlace(WantedBits);
285 Bits = Bits.trunc(Bits.getBitWidth() - WantedBits);
288 OffsetWithinChar = 0;
298std::optional<size_t> ConstantAggregateBuilder::splitAt(CharUnits Pos) {
300 return Offsets.size();
303 auto FirstAfterPos = llvm::upper_bound(Offsets, Pos);
304 if (FirstAfterPos == Offsets.begin())
308 size_t LastAtOrBeforePosIndex = FirstAfterPos - Offsets.begin() - 1;
309 if (Offsets[LastAtOrBeforePosIndex] == Pos)
310 return LastAtOrBeforePosIndex;
313 if (Offsets[LastAtOrBeforePosIndex] +
314 getSize(Elems[LastAtOrBeforePosIndex]) <= Pos)
315 return LastAtOrBeforePosIndex + 1;
318 if (!split(LastAtOrBeforePosIndex, Pos))
326bool ConstantAggregateBuilder::split(
size_t Index, CharUnits Hint) {
327 NaturalLayout =
false;
328 llvm::Constant *
C = Elems[Index];
329 CharUnits Offset = Offsets[Index];
331 if (
auto *CA = dyn_cast<llvm::ConstantAggregate>(
C)) {
334 replace(Elems, Index, Index + 1,
335 llvm::map_range(llvm::seq(0u, CA->getNumOperands()),
336 [&](
unsigned Op) { return CA->getOperand(Op); }));
341 llvm::GetElementPtrInst::getTypeAtIndex(CA->getType(), (uint64_t)0);
342 CharUnits ElemSize = getSize(ElemTy);
344 Offsets, Index, Index + 1,
345 llvm::map_range(llvm::seq(0u, CA->getNumOperands()),
346 [&](
unsigned Op) { return Offset + Op * ElemSize; }));
350 const llvm::StructLayout *Layout =
352 replace(Offsets, Index, Index + 1,
354 llvm::seq(0u, CA->getNumOperands()), [&](
unsigned Op) {
355 return Offset + CharUnits::fromQuantity(
356 Layout->getElementOffset(Op));
362 if (
auto *CDS = dyn_cast<llvm::ConstantDataSequential>(
C)) {
366 CharUnits ElemSize = getSize(CDS->getElementType());
367 replace(Elems, Index, Index + 1,
368 llvm::map_range(llvm::seq(
uint64_t(0u), CDS->getNumElements()),
370 return CDS->getElementAsConstant(Elem);
372 replace(Offsets, Index, Index + 1,
374 llvm::seq(
uint64_t(0u), CDS->getNumElements()),
375 [&](uint64_t Elem) { return Offset + Elem * ElemSize; }));
381 CharUnits ElemSize = getSize(
C);
382 assert(Hint > Offset && Hint < Offset + ElemSize &&
"nothing to split");
383 replace(Elems, Index, Index + 1,
384 {getZeroes(Hint - Offset), getZeroes(Offset + ElemSize - Hint)});
385 replace(Offsets, Index, Index + 1, {Offset, Hint});
391 replace(Elems, Index, Index + 1, {});
392 replace(Offsets, Index, Index + 1, {});
403static llvm::Constant *
404EmitArrayConstant(CodeGenModule &CGM, llvm::ArrayType *DesiredType,
405 llvm::Type *CommonElementType, uint64_t
ArrayBound,
406 SmallVectorImpl<llvm::Constant *> &Elements,
407 llvm::Constant *Filler);
409llvm::Constant *ConstantAggregateBuilder::buildFrom(
410 CodeGenModule &CGM, ArrayRef<llvm::Constant *> Elems,
411 ArrayRef<CharUnits> Offsets, CharUnits StartOffset, CharUnits Size,
412 bool NaturalLayout, llvm::Type *DesiredTy,
bool AllowOversized) {
413 ConstantAggregateBuilderUtils Utils(CGM);
416 return llvm::UndefValue::get(DesiredTy);
418 auto Offset = [&](
size_t I) {
return Offsets[I] - StartOffset; };
422 if (llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(DesiredTy)) {
423 assert(!AllowOversized &&
"oversized array emission not supported");
425 bool CanEmitArray =
true;
426 llvm::Type *CommonType = Elems[0]->getType();
427 llvm::Constant *Filler = llvm::Constant::getNullValue(CommonType);
428 CharUnits ElemSize = Utils.getSize(ATy->getElementType());
429 SmallVector<llvm::Constant*, 32> ArrayElements;
430 for (
size_t I = 0; I != Elems.size(); ++I) {
432 if (Elems[I]->isNullValue())
436 if (Elems[I]->
getType() != CommonType ||
437 !Offset(I).isMultipleOf(ElemSize)) {
438 CanEmitArray =
false;
441 ArrayElements.resize(Offset(I) / ElemSize + 1, Filler);
442 ArrayElements.back() = Elems[I];
446 return EmitArrayConstant(CGM, ATy, CommonType, ATy->getNumElements(),
447 ArrayElements, Filler);
456 CharUnits DesiredSize = Utils.getSize(DesiredTy);
457 if (Size > DesiredSize) {
458 assert(AllowOversized &&
"Elems are oversized");
464 for (llvm::Constant *
C : Elems)
465 Align = std::max(Align, Utils.getAlignment(
C));
468 CharUnits AlignedSize =
Size.alignTo(Align);
471 ArrayRef<llvm::Constant*> UnpackedElems = Elems;
472 llvm::SmallVector<llvm::Constant*, 32> UnpackedElemStorage;
473 if (DesiredSize < AlignedSize || DesiredSize.
alignTo(Align) != DesiredSize) {
475 NaturalLayout =
false;
477 }
else if (DesiredSize > AlignedSize) {
480 UnpackedElemStorage.assign(Elems.begin(), Elems.end());
481 UnpackedElemStorage.push_back(Utils.getPadding(DesiredSize - Size));
482 UnpackedElems = UnpackedElemStorage;
488 llvm::SmallVector<llvm::Constant*, 32> PackedElems;
489 if (!NaturalLayout) {
491 for (
size_t I = 0; I != Elems.size(); ++I) {
492 CharUnits Align = Utils.getAlignment(Elems[I]);
493 CharUnits NaturalOffset = SizeSoFar.
alignTo(Align);
494 CharUnits DesiredOffset = Offset(I);
495 assert(DesiredOffset >= SizeSoFar &&
"elements out of order");
497 if (DesiredOffset != NaturalOffset)
499 if (DesiredOffset != SizeSoFar)
500 PackedElems.push_back(Utils.getPadding(DesiredOffset - SizeSoFar));
501 PackedElems.push_back(Elems[I]);
502 SizeSoFar = DesiredOffset + Utils.getSize(Elems[I]);
507 assert(SizeSoFar <= DesiredSize &&
508 "requested size is too small for contents");
509 if (SizeSoFar < DesiredSize)
510 PackedElems.push_back(Utils.getPadding(DesiredSize - SizeSoFar));
514 llvm::StructType *STy = llvm::ConstantStruct::getTypeForElements(
519 if (llvm::StructType *DesiredSTy = dyn_cast<llvm::StructType>(DesiredTy)) {
520 if (DesiredSTy->isLayoutIdentical(STy))
524 return llvm::ConstantStruct::get(STy,
Packed ? PackedElems : UnpackedElems);
527void ConstantAggregateBuilder::condense(CharUnits Offset,
528 llvm::Type *DesiredTy) {
529 CharUnits
Size = getSize(DesiredTy);
531 std::optional<size_t> FirstElemToReplace = splitAt(Offset);
532 if (!FirstElemToReplace)
534 size_t First = *FirstElemToReplace;
536 std::optional<size_t> LastElemToReplace = splitAt(Offset + Size);
537 if (!LastElemToReplace)
539 size_t Last = *LastElemToReplace;
545 if (Length == 1 && Offsets[
First] == Offset &&
546 getSize(Elems[
First]) == Size) {
549 auto *STy = dyn_cast<llvm::StructType>(DesiredTy);
550 if (STy && STy->getNumElements() == 1 &&
551 STy->getElementType(0) == Elems[
First]->getType())
552 Elems[
First] = llvm::ConstantStruct::get(STy, Elems[
First]);
556 llvm::Constant *Replacement = buildFrom(
557 CGM, ArrayRef(Elems).slice(
First, Length),
558 ArrayRef(Offsets).slice(
First, Length), Offset, getSize(DesiredTy),
559 false, DesiredTy,
false);
560 replace(Elems,
First,
Last, {Replacement});
568class ConstStructBuilder {
570 ConstantEmitter &Emitter;
571 ConstantAggregateBuilder &Builder;
572 CharUnits StartOffset;
575 static llvm::Constant *BuildStruct(ConstantEmitter &Emitter,
576 const InitListExpr *ILE,
578 static llvm::Constant *BuildStruct(ConstantEmitter &Emitter,
580 static bool UpdateStruct(ConstantEmitter &Emitter,
581 ConstantAggregateBuilder &Const, CharUnits Offset,
582 const InitListExpr *Updater);
585 ConstStructBuilder(ConstantEmitter &Emitter,
586 ConstantAggregateBuilder &Builder, CharUnits StartOffset)
587 : CGM(Emitter.CGM), Emitter(Emitter), Builder(Builder),
588 StartOffset(StartOffset) {}
590 bool AppendField(
const FieldDecl *Field, uint64_t FieldOffset,
591 llvm::Constant *InitExpr,
bool AllowOverwrite =
false);
593 bool AppendBytes(CharUnits FieldOffsetInChars, llvm::Constant *InitCst,
594 bool AllowOverwrite =
false);
596 bool AppendBitField(
const FieldDecl *Field, uint64_t FieldOffset,
597 llvm::Constant *InitExpr,
bool AllowOverwrite =
false);
599 bool Build(
const InitListExpr *ILE,
bool AllowOverwrite);
600 bool Build(
const APValue &Val,
const RecordDecl *RD,
bool IsPrimaryBase,
601 const CXXRecordDecl *VTableClass, CharUnits BaseOffset);
602 bool DoZeroInitPadding(
const ASTRecordLayout &Layout,
unsigned FieldNo,
603 const FieldDecl &Field,
bool AllowOverwrite,
604 CharUnits &SizeSoFar,
bool &ZeroFieldSize);
605 bool DoZeroInitPadding(
const ASTRecordLayout &Layout,
bool AllowOverwrite,
606 CharUnits SizeSoFar);
607 llvm::Constant *
Finalize(QualType Ty);
610bool ConstStructBuilder::AppendField(
611 const FieldDecl *Field, uint64_t FieldOffset, llvm::Constant *InitCst,
612 bool AllowOverwrite) {
617 return AppendBytes(FieldOffsetInChars, InitCst, AllowOverwrite);
620bool ConstStructBuilder::AppendBytes(CharUnits FieldOffsetInChars,
621 llvm::Constant *InitCst,
622 bool AllowOverwrite) {
623 return Builder.add(InitCst, StartOffset + FieldOffsetInChars, AllowOverwrite);
626bool ConstStructBuilder::AppendBitField(
const FieldDecl *Field,
627 uint64_t FieldOffset, llvm::Constant *
C,
628 bool AllowOverwrite) {
630 llvm::ConstantInt *CI = dyn_cast<llvm::ConstantInt>(
C);
636 llvm::Type *LoadType =
638 llvm::Constant *FoldedConstant = llvm::ConstantFoldLoadFromConst(
640 CI = dyn_cast_if_present<llvm::ConstantInt>(FoldedConstant);
645 const CGRecordLayout &RL =
648 llvm::APInt FieldValue = CI->getValue();
654 if (Info.
Size > FieldValue.getBitWidth())
655 FieldValue = FieldValue.zext(Info.
Size);
658 if (Info.
Size < FieldValue.getBitWidth())
659 FieldValue = FieldValue.trunc(Info.
Size);
661 return Builder.addBits(FieldValue,
666static bool EmitDesignatedInitUpdater(ConstantEmitter &Emitter,
667 ConstantAggregateBuilder &Const,
668 CharUnits Offset, QualType
Type,
669 const InitListExpr *Updater) {
670 if (
Type->isRecordType())
671 return ConstStructBuilder::UpdateStruct(Emitter, Const, Offset, Updater);
680 llvm::Constant *FillC =
nullptr;
689 unsigned NumElementsToUpdate =
690 FillC ? CAT->getZExtSize() : Updater->
getNumInits();
691 for (
unsigned I = 0; I != NumElementsToUpdate; ++I, Offset += ElemSize) {
692 const Expr *
Init =
nullptr;
693 if (I < Updater->getNumInits())
696 if (!
Init && FillC) {
697 if (!
Const.add(FillC, Offset,
true))
701 }
else if (
const auto *ChildILE = dyn_cast<InitListExpr>(
Init)) {
702 if (!EmitDesignatedInitUpdater(Emitter, Const, Offset, ElemType,
706 Const.condense(Offset, ElemTy);
709 if (!
Const.add(Val, Offset,
true))
717bool ConstStructBuilder::Build(
const InitListExpr *ILE,
bool AllowOverwrite) {
721 unsigned FieldNo = -1;
722 unsigned ElementNo = 0;
727 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
728 if (CXXRD->getNumBases())
732 bool ZeroFieldSize =
false;
735 for (FieldDecl *Field : RD->fields()) {
744 if (
Field->isUnnamedBitField())
749 const Expr *
Init =
nullptr;
750 if (ElementNo < ILE->getNumInits())
752 if (isa_and_nonnull<NoInitExpr>(
Init)) {
753 if (ZeroInitPadding &&
754 !DoZeroInitPadding(Layout, FieldNo, *Field, AllowOverwrite, SizeSoFar,
768 if (ZeroInitPadding &&
769 !DoZeroInitPadding(Layout, FieldNo, *Field, AllowOverwrite, SizeSoFar,
776 if (AllowOverwrite &&
777 (
Field->getType()->isArrayType() ||
Field->getType()->isRecordType())) {
778 if (
auto *SubILE = dyn_cast<InitListExpr>(
Init)) {
781 if (!EmitDesignatedInitUpdater(Emitter, Builder, StartOffset + Offset,
782 Field->getType(), SubILE))
786 Builder.condense(StartOffset + Offset,
792 llvm::Constant *EltInit =
798 if (ZeroInitPadding && ZeroFieldSize)
802 if (!
Field->isBitField()) {
809 if (
Field->hasAttr<NoUniqueAddressAttr>())
810 AllowOverwrite =
true;
813 if (!AppendBitField(Field, Layout.
getFieldOffset(FieldNo), EltInit,
819 if (ZeroInitPadding && !DoZeroInitPadding(Layout, AllowOverwrite, SizeSoFar))
827 BaseInfo(
const CXXRecordDecl *
Decl, CharUnits Offset,
unsigned Index)
828 :
Decl(
Decl), Offset(Offset), Index(Index) {
831 const CXXRecordDecl *
Decl;
835 bool operator<(
const BaseInfo &O)
const {
return Offset < O.Offset; }
839bool ConstStructBuilder::Build(
const APValue &Val,
const RecordDecl *RD,
841 const CXXRecordDecl *VTableClass,
845 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
848 llvm::Constant *VTableAddressPoint =
853 VTableAddressPoint, *Authentication);
854 if (!VTableAddressPoint)
857 if (!AppendBytes(Offset, VTableAddressPoint))
863 SmallVector<BaseInfo, 8> Bases;
864 Bases.reserve(CD->getNumBases());
867 BaseEnd = CD->bases_end(); Base != BaseEnd; ++Base, ++BaseNo) {
868 assert(!
Base->isVirtual() &&
"should not have virtual bases here");
869 const CXXRecordDecl *BD =
Base->getType()->getAsCXXRecordDecl();
871 Bases.push_back(BaseInfo(BD, BaseOffset, BaseNo));
873 llvm::stable_sort(Bases);
875 for (
const BaseInfo &Base : Bases) {
878 VTableClass, Offset +
Base.Offset))
883 unsigned FieldNo = 0;
886 bool ZeroFieldSize =
false;
889 bool AllowOverwrite =
false;
891 FieldEnd = RD->
field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
897 if (
Field->isUnnamedBitField() ||
904 llvm::Constant *EltInit =
910 llvm::ConstantInt *Disc;
911 llvm::Constant *AddrDisc;
915 Disc = llvm::ConstantInt::get(CGM.
Int64Ty, FieldSignature);
916 AddrDisc = llvm::ConstantPointerNull::get(CGM.
VoidPtrTy);
923 Disc = llvm::ConstantInt::get(CGM.
Int64Ty,
927 EltInit = llvm::ConstantPtrAuth::get(
928 EltInit, llvm::ConstantInt::get(CGM.
Int32Ty, 2), Disc, AddrDisc,
935 if (ZeroInitPadding) {
936 if (!DoZeroInitPadding(Layout, FieldNo, **Field, AllowOverwrite,
937 SizeSoFar, ZeroFieldSize))
944 if (!
Field->isBitField()) {
946 if (!AppendField(*Field, Layout.
getFieldOffset(FieldNo) + OffsetBits,
947 EltInit, AllowOverwrite))
951 if (
Field->hasAttr<NoUniqueAddressAttr>())
952 AllowOverwrite =
true;
955 if (!AppendBitField(*Field, Layout.
getFieldOffset(FieldNo) + OffsetBits,
956 EltInit, AllowOverwrite))
960 if (ZeroInitPadding && !DoZeroInitPadding(Layout, AllowOverwrite, SizeSoFar))
966bool ConstStructBuilder::DoZeroInitPadding(
967 const ASTRecordLayout &Layout,
unsigned FieldNo,
const FieldDecl &Field,
968 bool AllowOverwrite, CharUnits &SizeSoFar,
bool &ZeroFieldSize) {
971 if (SizeSoFar < StartOffset)
972 if (!AppendBytes(SizeSoFar, getPadding(CGM, StartOffset - SizeSoFar),
976 if (!
Field.isBitField()) {
978 SizeSoFar = StartOffset + FieldSize;
979 ZeroFieldSize = FieldSize.isZero();
981 const CGRecordLayout &RL =
989 ZeroFieldSize = Info.
Size == 0;
994bool ConstStructBuilder::DoZeroInitPadding(
const ASTRecordLayout &Layout,
996 CharUnits SizeSoFar) {
997 CharUnits TotalSize = Layout.
getSize();
998 if (SizeSoFar < TotalSize)
999 if (!AppendBytes(SizeSoFar, getPadding(CGM, TotalSize - SizeSoFar),
1002 SizeSoFar = TotalSize;
1006llvm::Constant *ConstStructBuilder::Finalize(QualType
Type) {
1008 auto *RD =
Type->castAsRecordDecl();
1013llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
1014 const InitListExpr *ILE,
1016 ConstantAggregateBuilder
Const(Emitter.
CGM);
1019 if (!Builder.Build(ILE,
false))
1022 return Builder.Finalize(ValTy);
1025llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
1028 ConstantAggregateBuilder
Const(Emitter.
CGM);
1032 const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD);
1036 return Builder.Finalize(ValTy);
1039bool ConstStructBuilder::UpdateStruct(ConstantEmitter &Emitter,
1040 ConstantAggregateBuilder &Const,
1042 const InitListExpr *Updater) {
1043 return ConstStructBuilder(Emitter, Const, Offset)
1044 .Build(Updater,
true);
1051static ConstantAddress
1052tryEmitGlobalCompoundLiteral(ConstantEmitter &emitter,
1053 const CompoundLiteralExpr *E) {
1054 CodeGenModule &CGM = emitter.
CGM;
1056 if (llvm::GlobalVariable *
Addr =
1058 return ConstantAddress(
Addr,
Addr->getValueType(), Align);
1065 "file-scope compound literal did not have constant initializer!");
1069 auto GV =
new llvm::GlobalVariable(
1072 llvm::GlobalValue::InternalLinkage,
C,
".compoundliteral",
nullptr,
1073 llvm::GlobalVariable::NotThreadLocal,
1078 return ConstantAddress(GV, GV->getValueType(), Align);
1081static llvm::Constant *
1082EmitArrayConstant(CodeGenModule &CGM, llvm::ArrayType *DesiredType,
1083 llvm::Type *CommonElementType, uint64_t
ArrayBound,
1084 SmallVectorImpl<llvm::Constant *> &Elements,
1085 llvm::Constant *Filler) {
1088 if (Elements.size() < NonzeroLength && Filler->isNullValue())
1089 NonzeroLength = Elements.size();
1090 if (NonzeroLength == Elements.size()) {
1091 while (NonzeroLength > 0 && Elements[NonzeroLength - 1]->isNullValue())
1095 if (NonzeroLength == 0)
1096 return llvm::ConstantAggregateZero::get(DesiredType);
1100 if (TrailingZeroes >= 8) {
1101 assert(Elements.size() >= NonzeroLength &&
1102 "missing initializer for non-zero element");
1106 if (CommonElementType && NonzeroLength >= 8) {
1107 llvm::Constant *Initial = llvm::ConstantArray::get(
1108 llvm::ArrayType::get(CommonElementType, NonzeroLength),
1109 ArrayRef(Elements).take_front(NonzeroLength));
1111 Elements[0] = Initial;
1113 Elements.resize(NonzeroLength + 1);
1117 CommonElementType ? CommonElementType : DesiredType->getElementType();
1118 FillerType = llvm::ArrayType::get(FillerType, TrailingZeroes);
1119 Elements.back() = llvm::ConstantAggregateZero::get(FillerType);
1120 CommonElementType =
nullptr;
1124 if (Filler->getType() != CommonElementType)
1125 CommonElementType =
nullptr;
1129 if (CommonElementType)
1130 return llvm::ConstantArray::get(
1131 llvm::ArrayType::get(CommonElementType,
ArrayBound), Elements);
1134 llvm::SmallVector<llvm::Type *, 16> Types;
1135 Types.reserve(Elements.size());
1136 for (llvm::Constant *Elt : Elements)
1137 Types.push_back(Elt->getType());
1138 llvm::StructType *SType =
1140 return llvm::ConstantStruct::get(SType, Elements);
1149class ConstExprEmitter
1150 :
public ConstStmtVisitor<ConstExprEmitter, llvm::Constant *, QualType> {
1152 ConstantEmitter &Emitter;
1153 llvm::LLVMContext &VMContext;
1155 ConstExprEmitter(ConstantEmitter &emitter)
1156 : CGM(emitter.CGM), Emitter(emitter), VMContext(CGM.getLLVMContext()) {
1163 llvm::Constant *VisitStmt(
const Stmt *S, QualType T) {
return nullptr; }
1165 llvm::Constant *VisitConstantExpr(
const ConstantExpr *CE, QualType T) {
1171 llvm::Constant *VisitParenExpr(
const ParenExpr *PE, QualType T) {
1176 VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *PE,
1181 llvm::Constant *VisitGenericSelectionExpr(
const GenericSelectionExpr *GE,
1183 return Visit(
GE->getResultExpr(), T);
1186 llvm::Constant *VisitChooseExpr(
const ChooseExpr *CE, QualType T) {
1190 llvm::Constant *VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E,
1195 llvm::Constant *ProduceIntToIntCast(
const Expr *E, QualType DestType) {
1196 QualType FromType = E->
getType();
1199 if (llvm::Constant *
C = Visit(E, FromType))
1200 if (
auto *CI = dyn_cast<llvm::ConstantInt>(
C)) {
1203 if (DstWidth == SrcWidth)
1206 ? CI->getValue().sextOrTrunc(DstWidth)
1207 : CI->getValue().zextOrTrunc(DstWidth);
1213 llvm::Constant *VisitCastExpr(
const CastExpr *E, QualType destType) {
1214 if (
const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
1222 "Destination type is not union type!");
1227 if (!
C)
return nullptr;
1229 auto destTy = ConvertType(destType);
1230 if (
C->getType() == destTy)
return C;
1234 SmallVector<llvm::Constant*, 2> Elts;
1235 SmallVector<llvm::Type*, 2> Types;
1237 Types.push_back(
C->getType());
1238 unsigned CurSize = CGM.
getDataLayout().getTypeAllocSize(
C->getType());
1239 unsigned TotalSize = CGM.
getDataLayout().getTypeAllocSize(destTy);
1241 assert(CurSize <= TotalSize &&
"Union size mismatch!");
1242 if (
unsigned NumPadBytes = TotalSize - CurSize) {
1243 llvm::Constant *Padding =
1245 Elts.push_back(Padding);
1246 Types.push_back(Padding->getType());
1249 llvm::StructType *STy = llvm::StructType::get(VMContext, Types,
false);
1250 return llvm::ConstantStruct::get(STy, Elts);
1253 case CK_AddressSpaceConversion: {
1257 llvm::Type *destTy = ConvertType(E->
getType());
1261 case CK_LValueToRValue: {
1267 dyn_cast<CompoundLiteralExpr>(subExpr->
IgnoreParens()))
1268 return Visit(E->getInitializer(), destType);
1272 case CK_AtomicToNonAtomic:
1273 case CK_NonAtomicToAtomic:
1275 case CK_ConstructorConversion:
1276 return Visit(subExpr, destType);
1278 case CK_ArrayToPointerDecay:
1279 if (
const auto *S = dyn_cast<StringLiteral>(subExpr))
1282 case CK_NullToPointer:
1283 if (Visit(subExpr, destType))
1287 case CK_IntToOCLSampler:
1288 llvm_unreachable(
"global sampler variables are not generated");
1290 case CK_IntegralCast:
1291 return ProduceIntToIntCast(subExpr, destType);
1293 case CK_Dependent: llvm_unreachable(
"saw dependent cast!");
1295 case CK_BuiltinFnToFnPtr:
1296 llvm_unreachable(
"builtin functions are handled elsewhere");
1298 case CK_ReinterpretMemberPointer:
1299 case CK_DerivedToBaseMemberPointer:
1300 case CK_BaseToDerivedMemberPointer: {
1302 if (!
C)
return nullptr;
1307 case CK_ObjCObjectLValueCast:
1308 case CK_ARCProduceObject:
1309 case CK_ARCConsumeObject:
1310 case CK_ARCReclaimReturnedObject:
1311 case CK_ARCExtendBlockObject:
1312 case CK_CopyAndAutoreleaseBlockObject:
1320 case CK_LValueBitCast:
1321 case CK_LValueToRValueBitCast:
1322 case CK_NullToMemberPointer:
1323 case CK_UserDefinedConversion:
1324 case CK_CPointerToObjCPointerCast:
1325 case CK_BlockPointerToObjCPointerCast:
1326 case CK_AnyPointerToBlockPointerCast:
1327 case CK_FunctionToPointerDecay:
1328 case CK_BaseToDerived:
1329 case CK_DerivedToBase:
1330 case CK_UncheckedDerivedToBase:
1331 case CK_MemberPointerToBoolean:
1332 case CK_VectorSplat:
1333 case CK_FloatingRealToComplex:
1334 case CK_FloatingComplexToReal:
1335 case CK_FloatingComplexToBoolean:
1336 case CK_FloatingComplexCast:
1337 case CK_FloatingComplexToIntegralComplex:
1338 case CK_IntegralRealToComplex:
1339 case CK_IntegralComplexToReal:
1340 case CK_IntegralComplexToBoolean:
1341 case CK_IntegralComplexCast:
1342 case CK_IntegralComplexToFloatingComplex:
1343 case CK_PointerToIntegral:
1344 case CK_PointerToBoolean:
1345 case CK_BooleanToSignedIntegral:
1346 case CK_IntegralToPointer:
1347 case CK_IntegralToBoolean:
1348 case CK_IntegralToFloating:
1349 case CK_FloatingToIntegral:
1350 case CK_FloatingToBoolean:
1351 case CK_FloatingCast:
1352 case CK_FloatingToFixedPoint:
1353 case CK_FixedPointToFloating:
1354 case CK_FixedPointCast:
1355 case CK_FixedPointToBoolean:
1356 case CK_FixedPointToIntegral:
1357 case CK_IntegralToFixedPoint:
1358 case CK_ZeroToOCLOpaqueType:
1360 case CK_HLSLVectorTruncation:
1361 case CK_HLSLMatrixTruncation:
1362 case CK_HLSLArrayRValue:
1363 case CK_HLSLElementwiseCast:
1364 case CK_HLSLAggregateSplatCast:
1367 llvm_unreachable(
"Invalid CastKind");
1370 llvm::Constant *VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *DIE,
1374 return Visit(DIE->
getExpr(), T);
1377 llvm::Constant *VisitExprWithCleanups(
const ExprWithCleanups *E, QualType T) {
1381 llvm::Constant *VisitIntegerLiteral(
const IntegerLiteral *I, QualType T) {
1385 static APValue withDestType(ASTContext &Ctx,
const Expr *E, QualType SrcType,
1386 QualType DestType,
const llvm::APSInt &
Value) {
1391 llvm::RoundingMode RM =
1393 if (RM == llvm::RoundingMode::Dynamic)
1394 RM = llvm::RoundingMode::NearestTiesToEven;
1402 llvm::Constant *EmitArrayInitialization(
const InitListExpr *ILE, QualType T) {
1404 assert(CAT &&
"can't emit array init for non-constant-bound array");
1406 const uint64_t NumElements = CAT->getZExtSize();
1408 if (
const auto *Embed =
1409 dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1410 NumInitElements += Embed->getDataElementCount() - 1;
1411 if (NumInitElements > NumElements) {
1412 NumInitElements = NumElements;
1420 uint64_t NumInitableElts = std::min<uint64_t>(NumInitElements, NumElements);
1422 QualType EltType = CAT->getElementType();
1425 llvm::Constant *fillC =
nullptr;
1433 SmallVector<llvm::Constant *, 16> Elts;
1434 if (fillC && fillC->isNullValue())
1435 Elts.reserve(NumInitableElts + 1);
1437 Elts.reserve(NumElements);
1439 llvm::Type *CommonElementType =
nullptr;
1440 auto Emit = [&](
const Expr *
Init,
unsigned ArrayIndex) {
1441 llvm::Constant *
C =
nullptr;
1445 if (ArrayIndex == 0)
1446 CommonElementType =
C->getType();
1447 else if (
C->getType() != CommonElementType)
1448 CommonElementType =
nullptr;
1453 unsigned ArrayIndex = 0;
1454 QualType DestTy = CAT->getElementType();
1455 for (
unsigned i = 0; i < ILE->
getNumInits(); ++i) {
1457 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1458 StringLiteral *SL = EmbedS->getDataStringLiteral();
1462 for (
unsigned I = EmbedS->getStartingElementPos(),
1463 N = EmbedS->getDataElementCount();
1464 I != EmbedS->getStartingElementPos() + N; ++I) {
1479 if ((ArrayIndex - EmbedS->getDataElementCount()) == 0)
1480 CommonElementType =
C->getType();
1481 else if (
C->getType() != CommonElementType)
1482 CommonElementType =
nullptr;
1484 if (!Emit(
Init, ArrayIndex))
1490 llvm::ArrayType *Desired =
1492 return EmitArrayConstant(CGM, Desired, CommonElementType, NumElements, Elts,
1496 llvm::Constant *EmitRecordInitialization(
const InitListExpr *ILE,
1498 return ConstStructBuilder::BuildStruct(Emitter, ILE, T);
1501 llvm::Constant *VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E,
1506 llvm::Constant *VisitInitListExpr(
const InitListExpr *ILE, QualType T) {
1508 return Visit(ILE->
getInit(0), T);
1511 return EmitArrayInitialization(ILE, T);
1514 return EmitRecordInitialization(ILE, T);
1520 VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E,
1521 QualType destType) {
1522 auto C = Visit(E->
getBase(), destType);
1526 ConstantAggregateBuilder
Const(CGM);
1529 if (!EmitDesignatedInitUpdater(Emitter, Const,
CharUnits::Zero(), destType,
1534 bool HasFlexibleArray =
false;
1537 return Const.build(ValTy, HasFlexibleArray);
1540 llvm::Constant *VisitCXXConstructExpr(
const CXXConstructExpr *E,
1547 assert(E->
getNumArgs() == 1 &&
"trivial ctor with > 1 argument");
1549 "trivial ctor has argument but isn't a copy/move ctor");
1551 const Expr *Arg = E->
getArg(0);
1553 "argument to copy ctor is of wrong type");
1557 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(Arg))
1558 return Visit(MTE->getSubExpr(), Ty);
1566 llvm::Constant *VisitStringLiteral(
const StringLiteral *E, QualType T) {
1571 llvm::Constant *VisitObjCEncodeExpr(
const ObjCEncodeExpr *E, QualType T) {
1578 assert(CAT &&
"String data not of constant array type!");
1583 return llvm::ConstantDataArray::getString(VMContext, Str,
false);
1586 llvm::Constant *VisitUnaryExtension(
const UnaryOperator *E, QualType T) {
1590 llvm::Constant *VisitUnaryMinus(
const UnaryOperator *U, QualType T) {
1591 if (llvm::Constant *
C = Visit(U->
getSubExpr(), T))
1592 if (
auto *CI = dyn_cast<llvm::ConstantInt>(
C))
1593 return llvm::ConstantInt::get(CGM.
getLLVMContext(), -CI->getValue());
1597 llvm::Constant *VisitPackIndexingExpr(
const PackIndexingExpr *E, QualType T) {
1602 llvm::Type *ConvertType(QualType T) {
1609llvm::Constant *ConstantEmitter::validateAndPopAbstract(llvm::Constant *
C,
1610 AbstractState saved) {
1611 Abstract = saved.OldValue;
1613 assert(saved.OldPlaceholdersSize == PlaceholderAddresses.size() &&
1614 "created a placeholder while doing an abstract emission?");
1623 auto state = pushAbstract();
1625 return validateAndPopAbstract(
C, state);
1630 auto state = pushAbstract();
1632 return validateAndPopAbstract(
C, state);
1637 auto state = pushAbstract();
1639 return validateAndPopAbstract(
C, state);
1648 RetType =
CGM.getContext().getLValueReferenceType(RetType);
1655 auto state = pushAbstract();
1657 C = validateAndPopAbstract(
C, state);
1660 "internal error: could not emit constant value \"abstractly\"");
1661 C =
CGM.EmitNullConstant(destType);
1669 bool EnablePtrAuthFunctionTypeDiscrimination) {
1670 auto state = pushAbstract();
1672 tryEmitPrivate(value, destType, EnablePtrAuthFunctionTypeDiscrimination);
1673 C = validateAndPopAbstract(
C, state);
1676 "internal error: could not emit constant value \"abstractly\"");
1677 C =
CGM.EmitNullConstant(destType);
1691 for (
auto [_, GV] : PlaceholderAddresses)
1692 GV->eraseFromParent();
1693 PlaceholderAddresses.clear();
1697 return markIfFailed(
Init);
1703 initializeNonAbstract(destAddrSpace);
1710 initializeNonAbstract(destAddrSpace);
1712 assert(
C &&
"couldn't emit constant value non-abstractly?");
1717 assert(!Abstract &&
"cannot get current address for abstract constant");
1723 auto global =
new llvm::GlobalVariable(
CGM.getModule(),
CGM.Int8Ty,
true,
1724 llvm::GlobalValue::PrivateLinkage,
1728 llvm::GlobalVariable::NotThreadLocal,
1729 CGM.getContext().getTargetAddressSpace(DestAddressSpace));
1731 PlaceholderAddresses.push_back(std::make_pair(
nullptr, global));
1737 llvm::GlobalValue *placeholder) {
1738 assert(!PlaceholderAddresses.empty());
1739 assert(PlaceholderAddresses.back().first ==
nullptr);
1740 assert(PlaceholderAddresses.back().second == placeholder);
1741 PlaceholderAddresses.back().first = signal;
1745 struct ReplacePlaceholders {
1749 llvm::Constant *
Base;
1750 llvm::Type *BaseValueTy =
nullptr;
1753 llvm::DenseMap<llvm::Constant*, llvm::GlobalVariable*> PlaceholderAddresses;
1756 llvm::DenseMap<llvm::GlobalVariable*, llvm::Constant*> Locations;
1764 ReplacePlaceholders(
CodeGenModule &CGM, llvm::Constant *base,
1765 ArrayRef<std::pair<llvm::Constant*,
1766 llvm::GlobalVariable*>> addresses)
1767 : CGM(CGM),
Base(base),
1768 PlaceholderAddresses(addresses.begin(), addresses.end()) {
1771 void replaceInInitializer(llvm::Constant *init) {
1773 BaseValueTy = init->getType();
1776 Indices.push_back(0);
1777 IndexValues.push_back(
nullptr);
1780 findLocations(init);
1783 assert(IndexValues.size() == Indices.size() &&
"mismatch");
1784 assert(Indices.size() == 1 &&
"didn't pop all indices");
1787 assert(Locations.size() == PlaceholderAddresses.size() &&
1788 "missed a placeholder?");
1794 for (
auto &entry : Locations) {
1795 assert(entry.first->getName() ==
"" &&
"not a placeholder!");
1796 entry.first->replaceAllUsesWith(entry.second);
1797 entry.first->eraseFromParent();
1802 void findLocations(llvm::Constant *init) {
1804 if (
auto agg = dyn_cast<llvm::ConstantAggregate>(init)) {
1805 for (
unsigned i = 0, e = agg->getNumOperands(); i != e; ++i) {
1806 Indices.push_back(i);
1807 IndexValues.push_back(
nullptr);
1809 findLocations(agg->getOperand(i));
1811 IndexValues.pop_back();
1819 auto it = PlaceholderAddresses.find(init);
1820 if (it != PlaceholderAddresses.end()) {
1821 setLocation(it->second);
1826 if (
auto expr = dyn_cast<llvm::ConstantExpr>(init)) {
1827 init =
expr->getOperand(0);
1834 void setLocation(llvm::GlobalVariable *placeholder) {
1835 assert(!Locations.contains(placeholder) &&
1836 "already found location for placeholder!");
1841 assert(Indices.size() == IndexValues.size());
1842 for (
size_t i = Indices.size() - 1; i !=
size_t(-1); --i) {
1843 if (IndexValues[i]) {
1845 for (
size_t j = 0; j != i + 1; ++j) {
1846 assert(IndexValues[j] &&
1855 IndexValues[i] = llvm::ConstantInt::get(CGM.
Int32Ty, Indices[i]);
1858 llvm::Constant *location = llvm::ConstantExpr::getInBoundsGetElementPtr(
1859 BaseValueTy, Base, IndexValues);
1861 Locations.insert({placeholder, location});
1867 assert(InitializedNonAbstract &&
1868 "finalizing emitter that was used for abstract emission?");
1869 assert(!Finalized &&
"finalizing emitter multiple times");
1870 assert(global->getInitializer());
1875 if (!PlaceholderAddresses.empty()) {
1876 ReplacePlaceholders(
CGM, global, PlaceholderAddresses)
1877 .replaceInInitializer(global->getInitializer());
1878 PlaceholderAddresses.clear();
1883 assert((!InitializedNonAbstract || Finalized || Failed) &&
1884 "not finalized after being initialized for non-abstract emission");
1885 assert(PlaceholderAddresses.empty() &&
"unhandled placeholders");
1891 type.getQualifiers());
1904 dyn_cast_or_null<CXXConstructExpr>(D.
getInit())) {
1914 assert(E &&
"No initializer to emit");
1918 if (llvm::Constant *
C = ConstExprEmitter(*this).Visit(E, nonMemoryDestType))
1925 assert(!value->allowConstexprUnknown() &&
1926 "Constexpr unknown values are not allowed in CodeGen");
1970 assert(Schema &&
"applying trivial ptrauth schema");
1973 return UnsignedPointer;
1975 unsigned Key = Schema.
getKey();
1978 llvm::GlobalValue *StorageAddress =
nullptr;
1987 llvm::ConstantInt *Discriminator =
1990 llvm::Constant *SignedPointer =
CGM.getConstantSignedPointer(
1991 UnsignedPointer, Key, StorageAddress, Discriminator);
1996 return SignedPointer;
2004 QualType destValueType = AT->getValueType();
2007 uint64_t innerSize =
CGM.getContext().getTypeSize(destValueType);
2008 uint64_t outerSize =
CGM.getContext().getTypeSize(destType);
2009 if (innerSize == outerSize)
2012 assert(innerSize < outerSize &&
"emitted over-large constant for atomic");
2013 llvm::Constant *elts[] = {
2015 llvm::ConstantAggregateZero::get(
2016 llvm::ArrayType::get(
CGM.Int8Ty, (outerSize - innerSize) / 8))
2018 return llvm::ConstantStruct::getAnon(elts);
2023 if ((
C->getType()->isIntegerTy(1) && !destType->
isBitIntType()) ||
2026 llvm::Type *boolTy =
CGM.getTypes().ConvertTypeForMem(destType);
2027 llvm::Constant *Res = llvm::ConstantFoldCastOperand(
2028 llvm::Instruction::ZExt,
C, boolTy,
CGM.getDataLayout());
2029 assert(Res &&
"Constant folding must succeed");
2034 ConstantAggregateBuilder Builder(
CGM);
2035 llvm::Type *LoadStoreTy =
CGM.getTypes().convertTypeForLoadStore(destType);
2039 llvm::Constant *Res = llvm::ConstantFoldCastOperand(
2041 : llvm::Instruction::ZExt,
2042 CI, LoadStoreTy,
CGM.getDataLayout());
2043 if (
CGM.getTypes().typeRequiresSplitIntoByteArray(destType,
C->getType())) {
2046 llvm::Type *DesiredTy =
CGM.getTypes().ConvertTypeForMem(destType);
2048 Builder.addBits(
Value, 0,
false);
2049 return Builder.build(DesiredTy,
false);
2059 assert(!destType->
isVoidType() &&
"can't emit a void constant");
2062 if (llvm::Constant *
C = ConstExprEmitter(*this).Visit(E, destType))
2087struct ConstantLValue {
2088 llvm::Constant *
Value;
2089 bool HasOffsetApplied;
2090 bool HasDestPointerAuth;
2092 ConstantLValue(llvm::Constant *value,
2093 bool hasOffsetApplied =
false,
2094 bool hasDestPointerAuth =
false)
2095 :
Value(value), HasOffsetApplied(hasOffsetApplied),
2096 HasDestPointerAuth(hasDestPointerAuth) {}
2099 : ConstantLValue(address.getPointer()) {}
2103class ConstantLValueEmitter :
public ConstStmtVisitor<ConstantLValueEmitter,
2106 ConstantEmitter &Emitter;
2109 bool EnablePtrAuthFunctionTypeDiscrimination;
2112 friend StmtVisitorBase;
2115 ConstantLValueEmitter(ConstantEmitter &emitter,
const APValue &value,
2117 bool EnablePtrAuthFunctionTypeDiscrimination =
true)
2118 : CGM(emitter.CGM), Emitter(emitter),
Value(value), DestType(destType),
2119 EnablePtrAuthFunctionTypeDiscrimination(
2120 EnablePtrAuthFunctionTypeDiscrimination) {}
2122 llvm::Constant *tryEmit();
2125 llvm::Constant *tryEmitAbsolute(llvm::Type *destTy);
2126 ConstantLValue tryEmitBase(
const APValue::LValueBase &base);
2128 ConstantLValue VisitStmt(
const Stmt *S) {
return nullptr; }
2129 ConstantLValue VisitConstantExpr(
const ConstantExpr *E);
2130 ConstantLValue VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
2131 ConstantLValue VisitStringLiteral(
const StringLiteral *E);
2132 ConstantLValue VisitObjCBoxedExpr(
const ObjCBoxedExpr *E);
2133 ConstantLValue VisitObjCEncodeExpr(
const ObjCEncodeExpr *E);
2134 ConstantLValue VisitObjCStringLiteral(
const ObjCStringLiteral *E);
2135 ConstantLValue VisitPredefinedExpr(
const PredefinedExpr *E);
2136 ConstantLValue VisitAddrLabelExpr(
const AddrLabelExpr *E);
2137 ConstantLValue VisitCallExpr(
const CallExpr *E);
2138 ConstantLValue VisitBlockExpr(
const BlockExpr *E);
2139 ConstantLValue VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
2140 ConstantLValue VisitMaterializeTemporaryExpr(
2141 const MaterializeTemporaryExpr *E);
2143 ConstantLValue emitPointerAuthSignConstant(
const CallExpr *E);
2144 llvm::Constant *emitPointerAuthPointer(
const Expr *E);
2145 unsigned emitPointerAuthKey(
const Expr *E);
2146 std::pair<llvm::Constant *, llvm::ConstantInt *>
2147 emitPointerAuthDiscriminator(
const Expr *E);
2149 bool hasNonZeroOffset()
const {
2150 return !
Value.getLValueOffset().isZero();
2154 llvm::Constant *getOffset() {
2155 return llvm::ConstantInt::get(CGM.
Int64Ty,
2156 Value.getLValueOffset().getQuantity());
2160 llvm::Constant *applyOffset(llvm::Constant *
C) {
2161 if (!hasNonZeroOffset())
2164 return llvm::ConstantExpr::getPtrAdd(
C, getOffset());
2170llvm::Constant *ConstantLValueEmitter::tryEmit() {
2171 const APValue::LValueBase &base =
Value.getLValueBase();
2186 return tryEmitAbsolute(destTy);
2190 ConstantLValue result = tryEmitBase(base);
2193 llvm::Constant *value = result.Value;
2194 if (!value)
return nullptr;
2197 if (!result.HasOffsetApplied) {
2198 value = applyOffset(value);
2202 if (PointerAuthQualifier PointerAuth = DestType.
getPointerAuth();
2203 PointerAuth && !result.HasDestPointerAuth) {
2212 return llvm::ConstantExpr::getPointerCast(value, destTy);
2214 return llvm::ConstantExpr::getPtrToInt(value, destTy);
2220ConstantLValueEmitter::tryEmitAbsolute(llvm::Type *destTy) {
2223 if (
Value.isNullPointer()) {
2231 auto intptrTy = CGM.
getDataLayout().getIntPtrType(destPtrTy);
2233 C = llvm::ConstantFoldIntegerCast(getOffset(), intptrTy,
false,
2235 assert(
C &&
"Must have folded, as Offset is a ConstantInt");
2236 C = llvm::ConstantExpr::getIntToPtr(
C, destPtrTy);
2241ConstantLValueEmitter::tryEmitBase(
const APValue::LValueBase &base) {
2243 if (
const ValueDecl *D = base.
dyn_cast<
const ValueDecl*>()) {
2248 if (D->hasAttr<WeakRefAttr>())
2251 auto PtrAuthSign = [&](llvm::Constant *
C) {
2252 if (PointerAuthQualifier PointerAuth = DestType.
getPointerAuth()) {
2255 return ConstantLValue(
C,
true,
true);
2258 CGPointerAuthInfo AuthInfo;
2260 if (EnablePtrAuthFunctionTypeDiscrimination)
2264 if (hasNonZeroOffset())
2265 return ConstantLValue(
nullptr);
2269 C, AuthInfo.
getKey(),
nullptr,
2271 return ConstantLValue(
C,
true,
true);
2274 return ConstantLValue(
C);
2277 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
2279 if (FD->getType()->isCFIUncheckedCalleeFunctionType())
2281 return PtrAuthSign(
C);
2284 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
2286 if (!VD->hasLocalStorage()) {
2287 if (VD->isFileVarDecl() || VD->hasExternalStorage())
2290 if (VD->isLocalVarDecl()) {
2297 if (
const auto *GD = dyn_cast<MSGuidDecl>(D))
2300 if (
const auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D))
2303 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D))
2310 if (TypeInfoLValue TI = base.
dyn_cast<TypeInfoLValue>())
2314 return Visit(base.
get<
const Expr*>());
2318ConstantLValueEmitter::VisitConstantExpr(
const ConstantExpr *E) {
2325ConstantLValueEmitter::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
2326 ConstantEmitter CompoundLiteralEmitter(CGM, Emitter.
CGF);
2328 return tryEmitGlobalCompoundLiteral(CompoundLiteralEmitter, E);
2332ConstantLValueEmitter::VisitStringLiteral(
const StringLiteral *E) {
2337ConstantLValueEmitter::VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
2349ConstantLValueEmitter::VisitObjCStringLiteral(
const ObjCStringLiteral *E) {
2354ConstantLValueEmitter::VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
2356 "this boxed expression can't be emitted as a compile-time constant");
2362ConstantLValueEmitter::VisitPredefinedExpr(
const PredefinedExpr *E) {
2367ConstantLValueEmitter::VisitAddrLabelExpr(
const AddrLabelExpr *E) {
2368 assert(Emitter.
CGF &&
"Invalid address of label expression outside function");
2374ConstantLValueEmitter::VisitCallExpr(
const CallExpr *E) {
2376 if (builtin == Builtin::BI__builtin_function_start)
2380 if (builtin == Builtin::BI__builtin_ptrauth_sign_constant)
2381 return emitPointerAuthSignConstant(E);
2383 if (builtin != Builtin::BI__builtin___CFStringMakeConstantString &&
2384 builtin != Builtin::BI__builtin___NSStringMakeConstantString)
2388 if (builtin == Builtin::BI__builtin___NSStringMakeConstantString) {
2397ConstantLValueEmitter::emitPointerAuthSignConstant(
const CallExpr *E) {
2398 llvm::Constant *UnsignedPointer = emitPointerAuthPointer(E->
getArg(0));
2399 unsigned Key = emitPointerAuthKey(E->
getArg(1));
2400 auto [StorageAddress, OtherDiscriminator] =
2401 emitPointerAuthDiscriminator(E->
getArg(2));
2404 UnsignedPointer, Key, StorageAddress, OtherDiscriminator);
2405 return SignedPointer;
2408llvm::Constant *ConstantLValueEmitter::emitPointerAuthPointer(
const Expr *E) {
2415 assert(
Result.Val.isLValue());
2417 assert(
Result.Val.getLValueOffset().isZero());
2418 return ConstantEmitter(CGM, Emitter.
CGF)
2422unsigned ConstantLValueEmitter::emitPointerAuthKey(
const Expr *E) {
2426std::pair<llvm::Constant *, llvm::ConstantInt *>
2427ConstantLValueEmitter::emitPointerAuthDiscriminator(
const Expr *E) {
2430 if (
const auto *
Call = dyn_cast<CallExpr>(E)) {
2431 if (
Call->getBuiltinCallee() ==
2432 Builtin::BI__builtin_ptrauth_blend_discriminator) {
2433 llvm::Constant *
Pointer = ConstantEmitter(CGM).emitAbstract(
2434 Call->getArg(0),
Call->getArg(0)->getType());
2436 Call->getArg(1),
Call->getArg(1)->getType()));
2441 llvm::Constant *
Result = ConstantEmitter(CGM).emitAbstract(E, E->
getType());
2442 if (
Result->getType()->isPointerTy())
2443 return {
Result,
nullptr};
2448ConstantLValueEmitter::VisitBlockExpr(
const BlockExpr *E) {
2449 StringRef functionName;
2450 if (
auto CGF = Emitter.
CGF)
2451 functionName = CGF->CurFn->getName();
2453 functionName =
"global";
2459ConstantLValueEmitter::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
2469ConstantLValueEmitter::VisitMaterializeTemporaryExpr(
2470 const MaterializeTemporaryExpr *E) {
2478 bool EnablePtrAuthFunctionTypeDiscrimination) {
2483 return llvm::UndefValue::get(
CGM.getTypes().ConvertType(DestType));
2485 return ConstantLValueEmitter(*
this,
Value, DestType,
2486 EnablePtrAuthFunctionTypeDiscrimination)
2491 (PointerAuth.authenticatesNullValues() ||
Value.getInt() != 0))
2493 return llvm::ConstantInt::get(
CGM.getLLVMContext(),
Value.getInt());
2495 return llvm::ConstantInt::get(
CGM.getLLVMContext(),
2496 Value.getFixedPoint().getValue());
2500 Complex[0] = llvm::ConstantInt::get(
CGM.getLLVMContext(),
2501 Value.getComplexIntReal());
2502 Complex[1] = llvm::ConstantInt::get(
CGM.getLLVMContext(),
2503 Value.getComplexIntImag());
2506 llvm::StructType *STy =
2508 return llvm::ConstantStruct::get(STy,
Complex);
2511 const llvm::APFloat &
Init =
Value.getFloat();
2512 if (&
Init.getSemantics() == &llvm::APFloat::IEEEhalf() &&
2513 !
CGM.getContext().getLangOpts().NativeHalfType &&
2514 CGM.getContext().getTargetInfo().useFP16ConversionIntrinsics())
2515 return llvm::ConstantInt::get(
CGM.getLLVMContext(),
2516 Init.bitcastToAPInt());
2518 return llvm::ConstantFP::get(
CGM.getLLVMContext(),
Init);
2523 Complex[0] = llvm::ConstantFP::get(
CGM.getLLVMContext(),
2524 Value.getComplexFloatReal());
2525 Complex[1] = llvm::ConstantFP::get(
CGM.getLLVMContext(),
2526 Value.getComplexFloatImag());
2529 llvm::StructType *STy =
2531 return llvm::ConstantStruct::get(STy,
Complex);
2534 unsigned NumElts =
Value.getVectorLength();
2537 for (
unsigned I = 0; I != NumElts; ++I) {
2540 Inits[I] = llvm::ConstantInt::get(
CGM.getLLVMContext(), Elt.
getInt());
2544 Inits[I] = llvm::UndefValue::get(
CGM.getTypes().ConvertType(
2547 llvm_unreachable(
"unsupported vector element type");
2549 return llvm::ConstantVector::get(
Inits);
2556 if (!LHS || !RHS)
return nullptr;
2559 llvm::Type *ResultType =
CGM.getTypes().ConvertType(DestType);
2560 LHS = llvm::ConstantExpr::getPtrToInt(LHS,
CGM.IntPtrTy);
2561 RHS = llvm::ConstantExpr::getPtrToInt(RHS,
CGM.IntPtrTy);
2562 llvm::Constant *AddrLabelDiff = llvm::ConstantExpr::getSub(LHS, RHS);
2567 return llvm::ConstantExpr::getTruncOrBitCast(AddrLabelDiff, ResultType);
2571 return ConstStructBuilder::BuildStruct(*
this,
Value, DestType);
2573 const ArrayType *ArrayTy =
CGM.getContext().getAsArrayType(DestType);
2574 unsigned NumElements =
Value.getArraySize();
2575 unsigned NumInitElts =
Value.getArrayInitializedElts();
2578 llvm::Constant *Filler =
nullptr;
2579 if (
Value.hasArrayFiller()) {
2588 if (Filler && Filler->isNullValue())
2589 Elts.reserve(NumInitElts + 1);
2591 Elts.reserve(NumElements);
2593 llvm::Type *CommonElementType =
nullptr;
2594 for (
unsigned I = 0; I < NumInitElts; ++I) {
2597 if (!
C)
return nullptr;
2600 CommonElementType =
C->getType();
2601 else if (
C->getType() != CommonElementType)
2602 CommonElementType =
nullptr;
2606 llvm::ArrayType *Desired =
2611 Desired = llvm::ArrayType::get(Desired->getElementType(), Elts.size());
2613 return EmitArrayConstant(
CGM, Desired, CommonElementType, NumElements, Elts,
2617 return CGM.getCXXABI().EmitMemberPointer(
Value, DestType);
2619 llvm_unreachable(
"Unknown APValue kind");
2624 return EmittedCompoundLiterals.lookup(E);
2629 bool Ok = EmittedCompoundLiterals.insert(std::make_pair(CLE, GV)).second;
2631 assert(
Ok &&
"CLE has already been emitted!");
2636 assert(E->
isFileScope() &&
"not a file-scope compound literal expr");
2638 return tryEmitGlobalCompoundLiteral(emitter, E);
2649 return getCXXABI().EmitMemberFunctionPointer(method);
2659 llvm::Type *baseType,
2664 bool asCompleteObject) {
2666 llvm::StructType *structure =
2670 unsigned numElements = structure->getNumElements();
2671 std::vector<llvm::Constant *> elements(numElements);
2673 auto CXXR = dyn_cast<CXXRecordDecl>(record);
2676 for (
const auto &I : CXXR->bases()) {
2677 if (I.isVirtual()) {
2693 llvm::Type *baseType = structure->getElementType(fieldIndex);
2699 for (
const auto *Field : record->
fields()) {
2702 if (!Field->isBitField() &&
2710 if (Field->getIdentifier())
2712 if (
const auto *FieldRD = Field->getType()->getAsRecordDecl())
2713 if (FieldRD->findFirstNamedDataMember())
2719 if (CXXR && asCompleteObject) {
2720 for (
const auto &I : CXXR->vbases()) {
2729 if (elements[fieldIndex])
continue;
2731 llvm::Type *baseType = structure->getElementType(fieldIndex);
2737 for (
unsigned i = 0; i != numElements; ++i) {
2739 elements[i] = llvm::Constant::getNullValue(structure->getElementType(i));
2742 return llvm::ConstantStruct::get(structure, elements);
2747 llvm::Type *baseType,
2753 return llvm::Constant::getNullValue(baseType);
2769 if (
getTypes().isZeroInitializable(T))
2770 return llvm::Constant::getNullValue(
getTypes().ConvertTypeForMem(T));
2773 llvm::ArrayType *ATy =
2778 llvm::Constant *Element =
2782 return llvm::ConstantArray::get(ATy, Array);
2785 if (
const auto *RD = T->getAsRecordDecl())
2786 return ::EmitNullConstant(*
this, RD,
2789 assert(T->isMemberDataPointerType() &&
2790 "Should only see pointers to data members here!");
2797 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.
llvm::MachO::Record Record
llvm::APInt getValue() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
APValue & getStructField(unsigned i)
const FieldDecl * getUnionField() 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.
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.
const CXXBaseSpecifier * base_class_const_iterator
Iterator that traverses the base classes of a 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 GenerateConstantString(const StringLiteral *)=0
Generate a constant string object.
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.
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
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...
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.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
const ValueDecl * getAsBuiltinConstantDeclRef(const ASTContext &Context) const
If this expression is an unambiguous reference to a single declaration, in the style of __builtin_fun...
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()
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.
bool isExpressibleAsConstantInitializer() 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 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
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
const Expr * getInit() const
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
@ 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...
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
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, CodePtr OpPC, 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 operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
@ SD_Static
Static storage duration.
@ Result
The result type of a method or function.
@ 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.