28#include "llvm/ADT/STLExtras.h"
29#include "llvm/ADT/Sequence.h"
30#include "llvm/Analysis/ConstantFolding.h"
31#include "llvm/IR/Constants.h"
32#include "llvm/IR/DataLayout.h"
33#include "llvm/IR/Function.h"
34#include "llvm/IR/GlobalVariable.h"
35#include "llvm/Support/SipHash.h"
45class ConstExprEmitter;
48 llvm::Type *Ty = CGM.
CharTy;
50 Ty = llvm::ArrayType::get(Ty, PadSize.
getQuantity());
52 return llvm::Constant::getNullValue(Ty);
54 return llvm::UndefValue::get(Ty);
57struct ConstantAggregateBuilderUtils {
60 ConstantAggregateBuilderUtils(CodeGenModule &CGM) : CGM(CGM) {}
62 CharUnits getAlignment(
const llvm::Constant *
C)
const {
67 CharUnits getSize(llvm::Type *Ty)
const {
71 CharUnits getSize(
const llvm::Constant *
C)
const {
72 return getSize(
C->getType());
75 llvm::Constant *getPadding(CharUnits PadSize)
const {
76 return ::getPadding(CGM, PadSize);
79 llvm::Constant *getZeroes(CharUnits ZeroSize)
const {
81 return llvm::ConstantAggregateZero::get(Ty);
87class ConstantAggregateBuilder :
private ConstantAggregateBuilderUtils {
96 llvm::SmallVector<llvm::Constant*, 32> Elems;
97 llvm::SmallVector<CharUnits, 32> Offsets;
106 bool NaturalLayout =
true;
108 bool split(
size_t Index, CharUnits Hint);
109 std::optional<size_t> splitAt(CharUnits Pos);
111 static llvm::Constant *buildFrom(CodeGenModule &CGM,
112 ArrayRef<llvm::Constant *> Elems,
113 ArrayRef<CharUnits> Offsets,
114 CharUnits StartOffset, CharUnits Size,
115 bool NaturalLayout, llvm::Type *DesiredTy,
116 bool AllowOversized);
119 ConstantAggregateBuilder(CodeGenModule &CGM)
120 : ConstantAggregateBuilderUtils(CGM) {}
127 bool add(llvm::Constant *
C, CharUnits Offset,
bool AllowOverwrite);
130 bool addBits(llvm::APInt Bits, uint64_t OffsetInBits,
bool AllowOverwrite);
134 void condense(CharUnits Offset, llvm::Type *DesiredTy);
141 llvm::Constant *build(llvm::Type *DesiredTy,
bool AllowOversized)
const {
143 NaturalLayout, DesiredTy, AllowOversized);
147template<
typename Container,
typename Range = std::initializer_list<
148 typename Container::value_type>>
149static void replace(Container &
C,
size_t BeginOff,
size_t EndOff, Range Vals) {
150 assert(BeginOff <= EndOff &&
"invalid replacement range");
151 llvm::replace(
C,
C.begin() + BeginOff,
C.begin() + EndOff, Vals);
154bool ConstantAggregateBuilder::add(llvm::Constant *
C,
CharUnits Offset,
155 bool AllowOverwrite) {
157 if (Offset >= Size) {
158 CharUnits Align = getAlignment(
C);
159 CharUnits AlignedSize =
Size.alignTo(Align);
160 if (AlignedSize > Offset || Offset.
alignTo(Align) != Offset)
161 NaturalLayout =
false;
162 else if (AlignedSize < Offset) {
163 Elems.push_back(getPadding(Offset - Size));
164 Offsets.push_back(Size);
167 Offsets.push_back(Offset);
168 Size = Offset + getSize(
C);
173 std::optional<size_t> FirstElemToReplace = splitAt(Offset);
174 if (!FirstElemToReplace)
177 CharUnits CSize = getSize(
C);
178 std::optional<size_t> LastElemToReplace = splitAt(Offset + CSize);
179 if (!LastElemToReplace)
182 assert((FirstElemToReplace == LastElemToReplace || AllowOverwrite) &&
183 "unexpectedly overwriting field");
185 replace(Elems, *FirstElemToReplace, *LastElemToReplace, {
C});
186 replace(Offsets, *FirstElemToReplace, *LastElemToReplace, {Offset});
187 Size = std::max(Size, Offset + CSize);
188 NaturalLayout =
false;
192bool ConstantAggregateBuilder::addBits(llvm::APInt Bits, uint64_t OffsetInBits,
193 bool AllowOverwrite) {
199 unsigned OffsetWithinChar = OffsetInBits % CharWidth;
203 for (CharUnits OffsetInChars =
207 unsigned WantedBits =
208 std::min((uint64_t)Bits.getBitWidth(), CharWidth - OffsetWithinChar);
212 llvm::APInt BitsThisChar = Bits;
213 if (BitsThisChar.getBitWidth() < CharWidth)
214 BitsThisChar = BitsThisChar.zext(CharWidth);
218 int Shift = Bits.getBitWidth() - CharWidth + OffsetWithinChar;
220 BitsThisChar.lshrInPlace(Shift);
222 BitsThisChar = BitsThisChar.shl(-Shift);
224 BitsThisChar = BitsThisChar.shl(OffsetWithinChar);
226 if (BitsThisChar.getBitWidth() > CharWidth)
227 BitsThisChar = BitsThisChar.trunc(CharWidth);
229 if (WantedBits == CharWidth) {
232 OffsetInChars, AllowOverwrite);
237 std::optional<size_t> FirstElemToUpdate = splitAt(OffsetInChars);
238 if (!FirstElemToUpdate)
240 std::optional<size_t> LastElemToUpdate =
242 if (!LastElemToUpdate)
244 assert(*LastElemToUpdate - *FirstElemToUpdate < 2 &&
245 "should have at most one element covering one byte");
248 llvm::APInt UpdateMask(CharWidth, 0);
250 UpdateMask.setBits(CharWidth - OffsetWithinChar - WantedBits,
251 CharWidth - OffsetWithinChar);
253 UpdateMask.setBits(OffsetWithinChar, OffsetWithinChar + WantedBits);
254 BitsThisChar &= UpdateMask;
256 if (*FirstElemToUpdate == *LastElemToUpdate ||
257 Elems[*FirstElemToUpdate]->isNullValue() ||
261 OffsetInChars,
true);
263 llvm::Constant *&ToUpdate = Elems[*FirstElemToUpdate];
266 auto *CI = dyn_cast<llvm::ConstantInt>(ToUpdate);
271 assert(CI->getBitWidth() == CharWidth &&
"splitAt failed");
272 assert((!(CI->getValue() & UpdateMask) || AllowOverwrite) &&
273 "unexpectedly overwriting bitfield");
274 BitsThisChar |= (CI->getValue() & ~UpdateMask);
275 ToUpdate = llvm::ConstantInt::get(CGM.
getLLVMContext(), BitsThisChar);
280 if (WantedBits == Bits.getBitWidth())
285 Bits.lshrInPlace(WantedBits);
286 Bits = Bits.trunc(Bits.getBitWidth() - WantedBits);
289 OffsetWithinChar = 0;
299std::optional<size_t> ConstantAggregateBuilder::splitAt(CharUnits Pos) {
301 return Offsets.size();
304 auto FirstAfterPos = llvm::upper_bound(Offsets, Pos);
305 if (FirstAfterPos == Offsets.begin())
309 size_t LastAtOrBeforePosIndex = FirstAfterPos - Offsets.begin() - 1;
310 if (Offsets[LastAtOrBeforePosIndex] == Pos)
311 return LastAtOrBeforePosIndex;
314 if (Offsets[LastAtOrBeforePosIndex] +
315 getSize(Elems[LastAtOrBeforePosIndex]) <= Pos)
316 return LastAtOrBeforePosIndex + 1;
319 if (!split(LastAtOrBeforePosIndex, Pos))
327bool ConstantAggregateBuilder::split(
size_t Index, CharUnits Hint) {
328 NaturalLayout =
false;
329 llvm::Constant *
C = Elems[Index];
330 CharUnits Offset = Offsets[Index];
332 if (
auto *CA = dyn_cast<llvm::ConstantAggregate>(
C)) {
335 replace(Elems, Index, Index + 1,
336 llvm::map_range(llvm::seq(0u, CA->getNumOperands()),
337 [&](
unsigned Op) { return CA->getOperand(Op); }));
342 llvm::GetElementPtrInst::getTypeAtIndex(CA->getType(), (uint64_t)0);
343 CharUnits ElemSize = getSize(ElemTy);
345 Offsets, Index, Index + 1,
346 llvm::map_range(llvm::seq(0u, CA->getNumOperands()),
347 [&](
unsigned Op) { return Offset + Op * ElemSize; }));
351 const llvm::StructLayout *Layout =
353 replace(Offsets, Index, Index + 1,
355 llvm::seq(0u, CA->getNumOperands()), [&](
unsigned Op) {
356 return Offset + CharUnits::fromQuantity(
357 Layout->getElementOffset(Op));
363 if (
auto *CDS = dyn_cast<llvm::ConstantDataSequential>(
C)) {
367 CharUnits ElemSize = getSize(CDS->getElementType());
368 replace(Elems, Index, Index + 1,
369 llvm::map_range(llvm::seq(
uint64_t(0u), CDS->getNumElements()),
371 return CDS->getElementAsConstant(Elem);
373 replace(Offsets, Index, Index + 1,
375 llvm::seq(
uint64_t(0u), CDS->getNumElements()),
376 [&](uint64_t Elem) { return Offset + Elem * ElemSize; }));
382 CharUnits ElemSize = getSize(
C);
383 assert(Hint > Offset && Hint < Offset + ElemSize &&
"nothing to split");
384 replace(Elems, Index, Index + 1,
385 {getZeroes(Hint - Offset), getZeroes(Offset + ElemSize - Hint)});
386 replace(Offsets, Index, Index + 1, {Offset, Hint});
392 replace(Elems, Index, Index + 1, {});
393 replace(Offsets, Index, Index + 1, {});
404static llvm::Constant *
405EmitArrayConstant(CodeGenModule &CGM, llvm::ArrayType *DesiredType,
406 llvm::Type *CommonElementType, uint64_t
ArrayBound,
407 SmallVectorImpl<llvm::Constant *> &Elements,
408 llvm::Constant *Filler);
410llvm::Constant *ConstantAggregateBuilder::buildFrom(
411 CodeGenModule &CGM, ArrayRef<llvm::Constant *> Elems,
412 ArrayRef<CharUnits> Offsets, CharUnits StartOffset, CharUnits Size,
413 bool NaturalLayout, llvm::Type *DesiredTy,
bool AllowOversized) {
414 ConstantAggregateBuilderUtils Utils(CGM);
417 return llvm::UndefValue::get(DesiredTy);
419 auto Offset = [&](
size_t I) {
return Offsets[I] - StartOffset; };
423 if (llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(DesiredTy)) {
424 assert(!AllowOversized &&
"oversized array emission not supported");
426 bool CanEmitArray =
true;
427 llvm::Type *CommonType = Elems[0]->getType();
428 llvm::Constant *Filler = llvm::Constant::getNullValue(CommonType);
429 CharUnits ElemSize = Utils.getSize(ATy->getElementType());
430 SmallVector<llvm::Constant*, 32> ArrayElements;
431 for (
size_t I = 0; I != Elems.size(); ++I) {
433 if (Elems[I]->isNullValue())
437 if (Elems[I]->
getType() != CommonType ||
438 !Offset(I).isMultipleOf(ElemSize)) {
439 CanEmitArray =
false;
442 ArrayElements.resize(Offset(I) / ElemSize + 1, Filler);
443 ArrayElements.back() = Elems[I];
447 return EmitArrayConstant(CGM, ATy, CommonType, ATy->getNumElements(),
448 ArrayElements, Filler);
457 CharUnits DesiredSize = Utils.getSize(DesiredTy);
458 if (Size > DesiredSize) {
459 assert(AllowOversized &&
"Elems are oversized");
465 for (llvm::Constant *
C : Elems)
466 Align = std::max(Align, Utils.getAlignment(
C));
469 CharUnits AlignedSize =
Size.alignTo(Align);
472 ArrayRef<llvm::Constant*> UnpackedElems = Elems;
473 llvm::SmallVector<llvm::Constant*, 32> UnpackedElemStorage;
474 if (DesiredSize < AlignedSize || DesiredSize.
alignTo(Align) != DesiredSize) {
476 NaturalLayout =
false;
478 }
else if (DesiredSize > AlignedSize) {
481 UnpackedElemStorage.assign(Elems.begin(), Elems.end());
482 UnpackedElemStorage.push_back(Utils.getPadding(DesiredSize - Size));
483 UnpackedElems = UnpackedElemStorage;
489 llvm::SmallVector<llvm::Constant*, 32> PackedElems;
490 if (!NaturalLayout) {
492 for (
size_t I = 0; I != Elems.size(); ++I) {
493 CharUnits Align = Utils.getAlignment(Elems[I]);
494 CharUnits NaturalOffset = SizeSoFar.
alignTo(Align);
495 CharUnits DesiredOffset = Offset(I);
496 assert(DesiredOffset >= SizeSoFar &&
"elements out of order");
498 if (DesiredOffset != NaturalOffset)
500 if (DesiredOffset != SizeSoFar)
501 PackedElems.push_back(Utils.getPadding(DesiredOffset - SizeSoFar));
502 PackedElems.push_back(Elems[I]);
503 SizeSoFar = DesiredOffset + Utils.getSize(Elems[I]);
508 assert(SizeSoFar <= DesiredSize &&
509 "requested size is too small for contents");
510 if (SizeSoFar < DesiredSize)
511 PackedElems.push_back(Utils.getPadding(DesiredSize - SizeSoFar));
515 llvm::StructType *STy = llvm::ConstantStruct::getTypeForElements(
520 if (llvm::StructType *DesiredSTy = dyn_cast<llvm::StructType>(DesiredTy)) {
521 if (DesiredSTy->isLayoutIdentical(STy))
525 return llvm::ConstantStruct::get(STy,
Packed ? PackedElems : UnpackedElems);
528void ConstantAggregateBuilder::condense(CharUnits Offset,
529 llvm::Type *DesiredTy) {
530 CharUnits
Size = getSize(DesiredTy);
532 std::optional<size_t> FirstElemToReplace = splitAt(Offset);
533 if (!FirstElemToReplace)
535 size_t First = *FirstElemToReplace;
537 std::optional<size_t> LastElemToReplace = splitAt(Offset + Size);
538 if (!LastElemToReplace)
540 size_t Last = *LastElemToReplace;
546 if (Length == 1 && Offsets[
First] == Offset &&
547 getSize(Elems[
First]) == Size) {
550 auto *STy = dyn_cast<llvm::StructType>(DesiredTy);
551 if (STy && STy->getNumElements() == 1 &&
552 STy->getElementType(0) == Elems[
First]->getType())
553 Elems[
First] = llvm::ConstantStruct::get(STy, Elems[
First]);
557 llvm::Constant *Replacement = buildFrom(
558 CGM, ArrayRef(Elems).slice(
First, Length),
559 ArrayRef(Offsets).slice(
First, Length), Offset, getSize(DesiredTy),
560 false, DesiredTy,
false);
561 replace(Elems,
First,
Last, {Replacement});
569class ConstStructBuilder {
571 ConstantEmitter &Emitter;
572 ConstantAggregateBuilder &Builder;
573 CharUnits StartOffset;
576 static llvm::Constant *BuildStruct(ConstantEmitter &Emitter,
577 const InitListExpr *ILE,
579 static llvm::Constant *BuildStruct(ConstantEmitter &Emitter,
581 static bool UpdateStruct(ConstantEmitter &Emitter,
582 ConstantAggregateBuilder &Const, CharUnits Offset,
583 const InitListExpr *Updater);
586 ConstStructBuilder(ConstantEmitter &Emitter,
587 ConstantAggregateBuilder &Builder, CharUnits StartOffset)
588 : CGM(Emitter.CGM), Emitter(Emitter), Builder(Builder),
589 StartOffset(StartOffset) {}
591 bool AppendField(
const FieldDecl *Field, uint64_t FieldOffset,
592 llvm::Constant *InitExpr,
bool AllowOverwrite =
false);
594 bool AppendBytes(CharUnits FieldOffsetInChars, llvm::Constant *InitCst,
595 bool AllowOverwrite =
false);
597 bool AppendBitField(
const FieldDecl *Field, uint64_t FieldOffset,
598 llvm::Constant *InitExpr,
bool AllowOverwrite =
false);
600 bool Build(
const InitListExpr *ILE,
bool AllowOverwrite);
601 bool Build(
const APValue &Val,
const RecordDecl *RD,
bool IsPrimaryBase,
602 const CXXRecordDecl *VTableClass, CharUnits BaseOffset);
603 bool DoZeroInitPadding(
const ASTRecordLayout &Layout,
unsigned FieldNo,
604 const FieldDecl &Field,
bool AllowOverwrite,
605 CharUnits &SizeSoFar,
bool &ZeroFieldSize);
606 bool DoZeroInitPadding(
const ASTRecordLayout &Layout,
bool AllowOverwrite,
607 CharUnits SizeSoFar);
608 llvm::Constant *
Finalize(QualType Ty);
611bool ConstStructBuilder::AppendField(
612 const FieldDecl *Field, uint64_t FieldOffset, llvm::Constant *InitCst,
613 bool AllowOverwrite) {
618 return AppendBytes(FieldOffsetInChars, InitCst, AllowOverwrite);
621bool ConstStructBuilder::AppendBytes(CharUnits FieldOffsetInChars,
622 llvm::Constant *InitCst,
623 bool AllowOverwrite) {
624 return Builder.add(InitCst, StartOffset + FieldOffsetInChars, AllowOverwrite);
627bool ConstStructBuilder::AppendBitField(
const FieldDecl *Field,
628 uint64_t FieldOffset, llvm::Constant *
C,
629 bool AllowOverwrite) {
631 llvm::ConstantInt *CI = dyn_cast<llvm::ConstantInt>(
C);
637 llvm::Type *LoadType =
639 llvm::Constant *FoldedConstant = llvm::ConstantFoldLoadFromConst(
641 CI = dyn_cast_if_present<llvm::ConstantInt>(FoldedConstant);
646 const CGRecordLayout &RL =
649 llvm::APInt FieldValue = CI->getValue();
655 if (Info.
Size > FieldValue.getBitWidth())
656 FieldValue = FieldValue.zext(Info.
Size);
659 if (Info.
Size < FieldValue.getBitWidth())
660 FieldValue = FieldValue.trunc(Info.
Size);
662 return Builder.addBits(FieldValue,
667static bool EmitDesignatedInitUpdater(ConstantEmitter &Emitter,
668 ConstantAggregateBuilder &Const,
669 CharUnits Offset, QualType
Type,
670 const InitListExpr *Updater) {
671 if (
Type->isRecordType())
672 return ConstStructBuilder::UpdateStruct(Emitter, Const, Offset, Updater);
681 llvm::Constant *FillC =
nullptr;
690 unsigned NumElementsToUpdate =
691 FillC ? CAT->getZExtSize() : Updater->
getNumInits();
692 for (
unsigned I = 0; I != NumElementsToUpdate; ++I, Offset += ElemSize) {
693 const Expr *
Init =
nullptr;
694 if (I < Updater->getNumInits())
697 if (!
Init && FillC) {
698 if (!
Const.add(FillC, Offset,
true))
702 }
else if (
const auto *ChildILE = dyn_cast<InitListExpr>(
Init)) {
703 if (!EmitDesignatedInitUpdater(Emitter, Const, Offset, ElemType,
707 Const.condense(Offset, ElemTy);
710 if (!
Const.add(Val, Offset,
true))
718bool ConstStructBuilder::Build(
const InitListExpr *ILE,
bool AllowOverwrite) {
722 unsigned FieldNo = -1;
723 unsigned ElementNo = 0;
728 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
729 if (CXXRD->getNumBases())
733 bool ZeroFieldSize =
false;
736 for (FieldDecl *Field : RD->fields()) {
745 if (
Field->isUnnamedBitField())
750 const Expr *
Init =
nullptr;
751 if (ElementNo < ILE->getNumInits())
753 if (isa_and_nonnull<NoInitExpr>(
Init)) {
754 if (ZeroInitPadding &&
755 !DoZeroInitPadding(Layout, FieldNo, *Field, AllowOverwrite, SizeSoFar,
769 if (ZeroInitPadding &&
770 !DoZeroInitPadding(Layout, FieldNo, *Field, AllowOverwrite, SizeSoFar,
777 if (AllowOverwrite &&
778 (
Field->getType()->isArrayType() ||
Field->getType()->isRecordType())) {
779 if (
auto *SubILE = dyn_cast<InitListExpr>(
Init)) {
782 if (!EmitDesignatedInitUpdater(Emitter, Builder, StartOffset + Offset,
783 Field->getType(), SubILE))
787 Builder.condense(StartOffset + Offset,
793 llvm::Constant *EltInit =
799 if (ZeroInitPadding && ZeroFieldSize)
803 if (!
Field->isBitField()) {
810 if (
Field->hasAttr<NoUniqueAddressAttr>())
811 AllowOverwrite =
true;
814 if (!AppendBitField(Field, Layout.
getFieldOffset(FieldNo), EltInit,
820 if (ZeroInitPadding && !DoZeroInitPadding(Layout, AllowOverwrite, SizeSoFar))
828 BaseInfo(
const CXXRecordDecl *
Decl, CharUnits Offset,
unsigned Index)
829 :
Decl(
Decl), Offset(Offset), Index(Index) {
832 const CXXRecordDecl *
Decl;
836 bool operator<(
const BaseInfo &O)
const {
return Offset < O.Offset; }
840bool ConstStructBuilder::Build(
const APValue &Val,
const RecordDecl *RD,
842 const CXXRecordDecl *VTableClass,
846 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
849 llvm::Constant *VTableAddressPoint =
854 VTableAddressPoint, *Authentication);
855 if (!VTableAddressPoint)
858 if (!AppendBytes(Offset, VTableAddressPoint))
864 SmallVector<BaseInfo, 8> Bases;
865 Bases.reserve(CD->getNumBases());
868 BaseEnd = CD->bases_end(); Base != BaseEnd; ++Base, ++BaseNo) {
869 assert(!
Base->isVirtual() &&
"should not have virtual bases here");
870 const CXXRecordDecl *BD =
Base->getType()->getAsCXXRecordDecl();
872 Bases.push_back(BaseInfo(BD, BaseOffset, BaseNo));
874 llvm::stable_sort(Bases);
876 for (
const BaseInfo &Base : Bases) {
879 VTableClass, Offset +
Base.Offset))
884 unsigned FieldNo = 0;
887 bool ZeroFieldSize =
false;
890 bool AllowOverwrite =
false;
892 FieldEnd = RD->
field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
898 if (
Field->isUnnamedBitField() ||
905 llvm::Constant *EltInit =
911 llvm::ConstantInt *Disc;
912 llvm::Constant *AddrDisc;
916 Disc = llvm::ConstantInt::get(CGM.
Int64Ty, FieldSignature);
917 AddrDisc = llvm::ConstantPointerNull::get(CGM.
VoidPtrTy);
924 Disc = llvm::ConstantInt::get(CGM.
Int64Ty,
928 EltInit = llvm::ConstantPtrAuth::get(
929 EltInit, llvm::ConstantInt::get(CGM.
Int32Ty, 2), Disc, AddrDisc,
936 if (ZeroInitPadding) {
937 if (!DoZeroInitPadding(Layout, FieldNo, **Field, AllowOverwrite,
938 SizeSoFar, ZeroFieldSize))
945 if (!
Field->isBitField()) {
947 if (!AppendField(*Field, Layout.
getFieldOffset(FieldNo) + OffsetBits,
948 EltInit, AllowOverwrite))
952 if (
Field->hasAttr<NoUniqueAddressAttr>())
953 AllowOverwrite =
true;
956 if (!AppendBitField(*Field, Layout.
getFieldOffset(FieldNo) + OffsetBits,
957 EltInit, AllowOverwrite))
961 if (ZeroInitPadding && !DoZeroInitPadding(Layout, AllowOverwrite, SizeSoFar))
967bool ConstStructBuilder::DoZeroInitPadding(
968 const ASTRecordLayout &Layout,
unsigned FieldNo,
const FieldDecl &Field,
969 bool AllowOverwrite, CharUnits &SizeSoFar,
bool &ZeroFieldSize) {
972 if (SizeSoFar < StartOffset)
973 if (!AppendBytes(SizeSoFar, getPadding(CGM, StartOffset - SizeSoFar),
977 if (!
Field.isBitField()) {
979 SizeSoFar = StartOffset + FieldSize;
980 ZeroFieldSize = FieldSize.isZero();
982 const CGRecordLayout &RL =
990 ZeroFieldSize = Info.
Size == 0;
995bool ConstStructBuilder::DoZeroInitPadding(
const ASTRecordLayout &Layout,
997 CharUnits SizeSoFar) {
998 CharUnits TotalSize = Layout.
getSize();
999 if (SizeSoFar < TotalSize)
1000 if (!AppendBytes(SizeSoFar, getPadding(CGM, TotalSize - SizeSoFar),
1003 SizeSoFar = TotalSize;
1007llvm::Constant *ConstStructBuilder::Finalize(QualType
Type) {
1009 auto *RD =
Type->castAsRecordDecl();
1014llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
1015 const InitListExpr *ILE,
1017 ConstantAggregateBuilder
Const(Emitter.
CGM);
1020 if (!Builder.Build(ILE,
false))
1023 return Builder.Finalize(ValTy);
1026llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
1029 ConstantAggregateBuilder
Const(Emitter.
CGM);
1033 const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD);
1037 return Builder.Finalize(ValTy);
1040bool ConstStructBuilder::UpdateStruct(ConstantEmitter &Emitter,
1041 ConstantAggregateBuilder &Const,
1043 const InitListExpr *Updater) {
1044 return ConstStructBuilder(Emitter, Const, Offset)
1045 .Build(Updater,
true);
1052static ConstantAddress
1053tryEmitGlobalCompoundLiteral(ConstantEmitter &emitter,
1054 const CompoundLiteralExpr *E) {
1055 CodeGenModule &CGM = emitter.
CGM;
1057 if (llvm::GlobalVariable *
Addr =
1059 return ConstantAddress(
Addr,
Addr->getValueType(), Align);
1066 "file-scope compound literal did not have constant initializer!");
1070 auto GV =
new llvm::GlobalVariable(
1073 llvm::GlobalValue::InternalLinkage,
C,
".compoundliteral",
nullptr,
1074 llvm::GlobalVariable::NotThreadLocal,
1079 return ConstantAddress(GV, GV->getValueType(), Align);
1082static llvm::Constant *
1083EmitArrayConstant(CodeGenModule &CGM, llvm::ArrayType *DesiredType,
1084 llvm::Type *CommonElementType, uint64_t
ArrayBound,
1085 SmallVectorImpl<llvm::Constant *> &Elements,
1086 llvm::Constant *Filler) {
1089 if (Elements.size() < NonzeroLength && Filler->isNullValue())
1090 NonzeroLength = Elements.size();
1091 if (NonzeroLength == Elements.size()) {
1092 while (NonzeroLength > 0 && Elements[NonzeroLength - 1]->isNullValue())
1096 if (NonzeroLength == 0)
1097 return llvm::ConstantAggregateZero::get(DesiredType);
1101 if (TrailingZeroes >= 8) {
1102 assert(Elements.size() >= NonzeroLength &&
1103 "missing initializer for non-zero element");
1107 if (CommonElementType && NonzeroLength >= 8) {
1108 llvm::Constant *Initial = llvm::ConstantArray::get(
1109 llvm::ArrayType::get(CommonElementType, NonzeroLength),
1110 ArrayRef(Elements).take_front(NonzeroLength));
1112 Elements[0] = Initial;
1114 Elements.resize(NonzeroLength + 1);
1118 CommonElementType ? CommonElementType : DesiredType->getElementType();
1119 FillerType = llvm::ArrayType::get(FillerType, TrailingZeroes);
1120 Elements.back() = llvm::ConstantAggregateZero::get(FillerType);
1121 CommonElementType =
nullptr;
1125 if (Filler->getType() != CommonElementType)
1126 CommonElementType =
nullptr;
1130 if (CommonElementType)
1131 return llvm::ConstantArray::get(
1132 llvm::ArrayType::get(CommonElementType,
ArrayBound), Elements);
1135 llvm::SmallVector<llvm::Type *, 16> Types;
1136 Types.reserve(Elements.size());
1137 for (llvm::Constant *Elt : Elements)
1138 Types.push_back(Elt->getType());
1139 llvm::StructType *SType =
1141 return llvm::ConstantStruct::get(SType, Elements);
1150class ConstExprEmitter
1151 :
public ConstStmtVisitor<ConstExprEmitter, llvm::Constant *, QualType> {
1153 ConstantEmitter &Emitter;
1154 llvm::LLVMContext &VMContext;
1156 ConstExprEmitter(ConstantEmitter &emitter)
1157 : CGM(emitter.CGM), Emitter(emitter), VMContext(CGM.getLLVMContext()) {
1164 llvm::Constant *VisitStmt(
const Stmt *S, QualType T) {
return nullptr; }
1166 llvm::Constant *VisitConstantExpr(
const ConstantExpr *CE, QualType T) {
1172 llvm::Constant *VisitParenExpr(
const ParenExpr *PE, QualType T) {
1177 VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *PE,
1182 llvm::Constant *VisitGenericSelectionExpr(
const GenericSelectionExpr *GE,
1184 return Visit(
GE->getResultExpr(), T);
1187 llvm::Constant *VisitChooseExpr(
const ChooseExpr *CE, QualType T) {
1191 llvm::Constant *VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E,
1196 llvm::Constant *ProduceIntToIntCast(
const Expr *E, QualType DestType) {
1197 QualType FromType = E->
getType();
1200 if (llvm::Constant *
C = Visit(E, FromType))
1201 if (
auto *CI = dyn_cast<llvm::ConstantInt>(
C)) {
1204 if (DstWidth == SrcWidth)
1207 ? CI->getValue().sextOrTrunc(DstWidth)
1208 : CI->getValue().zextOrTrunc(DstWidth);
1214 llvm::Constant *VisitCastExpr(
const CastExpr *E, QualType destType) {
1215 if (
const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
1223 "Destination type is not union type!");
1228 if (!
C)
return nullptr;
1230 auto destTy = ConvertType(destType);
1231 if (
C->getType() == destTy)
return C;
1235 SmallVector<llvm::Constant*, 2> Elts;
1236 SmallVector<llvm::Type*, 2> Types;
1238 Types.push_back(
C->getType());
1239 unsigned CurSize = CGM.
getDataLayout().getTypeAllocSize(
C->getType());
1240 unsigned TotalSize = CGM.
getDataLayout().getTypeAllocSize(destTy);
1242 assert(CurSize <= TotalSize &&
"Union size mismatch!");
1243 if (
unsigned NumPadBytes = TotalSize - CurSize) {
1244 llvm::Constant *Padding =
1246 Elts.push_back(Padding);
1247 Types.push_back(Padding->getType());
1250 llvm::StructType *STy = llvm::StructType::get(VMContext, Types,
false);
1251 return llvm::ConstantStruct::get(STy, Elts);
1254 case CK_AddressSpaceConversion: {
1258 llvm::Type *destTy = ConvertType(E->
getType());
1262 case CK_LValueToRValue: {
1268 dyn_cast<CompoundLiteralExpr>(subExpr->
IgnoreParens()))
1269 return Visit(E->getInitializer(), destType);
1273 case CK_AtomicToNonAtomic:
1274 case CK_NonAtomicToAtomic:
1276 case CK_ConstructorConversion:
1277 return Visit(subExpr, destType);
1279 case CK_ArrayToPointerDecay:
1280 if (
const auto *S = dyn_cast<StringLiteral>(subExpr))
1283 case CK_NullToPointer:
1284 if (Visit(subExpr, destType))
1288 case CK_IntToOCLSampler:
1289 llvm_unreachable(
"global sampler variables are not generated");
1291 case CK_IntegralCast:
1292 return ProduceIntToIntCast(subExpr, destType);
1294 case CK_Dependent: llvm_unreachable(
"saw dependent cast!");
1296 case CK_BuiltinFnToFnPtr:
1297 llvm_unreachable(
"builtin functions are handled elsewhere");
1299 case CK_ReinterpretMemberPointer:
1300 case CK_DerivedToBaseMemberPointer:
1301 case CK_BaseToDerivedMemberPointer: {
1303 if (!
C)
return nullptr;
1308 case CK_ObjCObjectLValueCast:
1309 case CK_ARCProduceObject:
1310 case CK_ARCConsumeObject:
1311 case CK_ARCReclaimReturnedObject:
1312 case CK_ARCExtendBlockObject:
1313 case CK_CopyAndAutoreleaseBlockObject:
1321 case CK_LValueBitCast:
1322 case CK_LValueToRValueBitCast:
1323 case CK_NullToMemberPointer:
1324 case CK_UserDefinedConversion:
1325 case CK_CPointerToObjCPointerCast:
1326 case CK_BlockPointerToObjCPointerCast:
1327 case CK_AnyPointerToBlockPointerCast:
1328 case CK_FunctionToPointerDecay:
1329 case CK_BaseToDerived:
1330 case CK_DerivedToBase:
1331 case CK_UncheckedDerivedToBase:
1332 case CK_MemberPointerToBoolean:
1333 case CK_VectorSplat:
1334 case CK_FloatingRealToComplex:
1335 case CK_FloatingComplexToReal:
1336 case CK_FloatingComplexToBoolean:
1337 case CK_FloatingComplexCast:
1338 case CK_FloatingComplexToIntegralComplex:
1339 case CK_IntegralRealToComplex:
1340 case CK_IntegralComplexToReal:
1341 case CK_IntegralComplexToBoolean:
1342 case CK_IntegralComplexCast:
1343 case CK_IntegralComplexToFloatingComplex:
1344 case CK_PointerToIntegral:
1345 case CK_PointerToBoolean:
1346 case CK_BooleanToSignedIntegral:
1347 case CK_IntegralToPointer:
1348 case CK_IntegralToBoolean:
1349 case CK_IntegralToFloating:
1350 case CK_FloatingToIntegral:
1351 case CK_FloatingToBoolean:
1352 case CK_FloatingCast:
1353 case CK_FloatingToFixedPoint:
1354 case CK_FixedPointToFloating:
1355 case CK_FixedPointCast:
1356 case CK_FixedPointToBoolean:
1357 case CK_FixedPointToIntegral:
1358 case CK_IntegralToFixedPoint:
1359 case CK_ZeroToOCLOpaqueType:
1361 case CK_HLSLVectorTruncation:
1362 case CK_HLSLMatrixTruncation:
1363 case CK_HLSLArrayRValue:
1364 case CK_HLSLElementwiseCast:
1365 case CK_HLSLAggregateSplatCast:
1368 llvm_unreachable(
"Invalid CastKind");
1371 llvm::Constant *VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *DIE,
1375 return Visit(DIE->
getExpr(), T);
1378 llvm::Constant *VisitExprWithCleanups(
const ExprWithCleanups *E, QualType T) {
1382 llvm::Constant *VisitIntegerLiteral(
const IntegerLiteral *I, QualType T) {
1386 static APValue withDestType(ASTContext &Ctx,
const Expr *E, QualType SrcType,
1387 QualType DestType,
const llvm::APSInt &
Value) {
1392 llvm::RoundingMode RM =
1394 if (RM == llvm::RoundingMode::Dynamic)
1395 RM = llvm::RoundingMode::NearestTiesToEven;
1403 llvm::Constant *EmitArrayInitialization(
const InitListExpr *ILE, QualType T) {
1405 assert(CAT &&
"can't emit array init for non-constant-bound array");
1407 const uint64_t NumElements = CAT->getZExtSize();
1409 if (
const auto *Embed =
1410 dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1411 NumInitElements += Embed->getDataElementCount() - 1;
1412 if (NumInitElements > NumElements) {
1413 NumInitElements = NumElements;
1421 uint64_t NumInitableElts = std::min<uint64_t>(NumInitElements, NumElements);
1423 QualType EltType = CAT->getElementType();
1426 llvm::Constant *fillC =
nullptr;
1434 SmallVector<llvm::Constant *, 16> Elts;
1435 if (fillC && fillC->isNullValue())
1436 Elts.reserve(NumInitableElts + 1);
1438 Elts.reserve(NumElements);
1440 llvm::Type *CommonElementType =
nullptr;
1441 auto Emit = [&](
const Expr *
Init,
unsigned ArrayIndex) {
1442 llvm::Constant *
C =
nullptr;
1446 if (ArrayIndex == 0)
1447 CommonElementType =
C->getType();
1448 else if (
C->getType() != CommonElementType)
1449 CommonElementType =
nullptr;
1454 unsigned ArrayIndex = 0;
1455 QualType DestTy = CAT->getElementType();
1456 for (
unsigned i = 0; i < ILE->
getNumInits(); ++i) {
1458 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1459 StringLiteral *SL = EmbedS->getDataStringLiteral();
1463 for (
unsigned I = EmbedS->getStartingElementPos(),
1464 N = EmbedS->getDataElementCount();
1465 I != EmbedS->getStartingElementPos() + N; ++I) {
1480 if ((ArrayIndex - EmbedS->getDataElementCount()) == 0)
1481 CommonElementType =
C->getType();
1482 else if (
C->getType() != CommonElementType)
1483 CommonElementType =
nullptr;
1485 if (!Emit(
Init, ArrayIndex))
1491 llvm::ArrayType *Desired =
1493 return EmitArrayConstant(CGM, Desired, CommonElementType, NumElements, Elts,
1497 llvm::Constant *EmitRecordInitialization(
const InitListExpr *ILE,
1499 return ConstStructBuilder::BuildStruct(Emitter, ILE, T);
1502 llvm::Constant *VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E,
1507 llvm::Constant *VisitInitListExpr(
const InitListExpr *ILE, QualType T) {
1509 return Visit(ILE->
getInit(0), T);
1512 return EmitArrayInitialization(ILE, T);
1515 return EmitRecordInitialization(ILE, T);
1521 VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E,
1522 QualType destType) {
1523 auto C = Visit(E->
getBase(), destType);
1527 ConstantAggregateBuilder
Const(CGM);
1530 if (!EmitDesignatedInitUpdater(Emitter, Const,
CharUnits::Zero(), destType,
1535 bool HasFlexibleArray =
false;
1538 return Const.build(ValTy, HasFlexibleArray);
1541 llvm::Constant *VisitCXXConstructExpr(
const CXXConstructExpr *E,
1548 assert(E->
getNumArgs() == 1 &&
"trivial ctor with > 1 argument");
1550 "trivial ctor has argument but isn't a copy/move ctor");
1552 const Expr *Arg = E->
getArg(0);
1554 "argument to copy ctor is of wrong type");
1558 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(Arg))
1559 return Visit(MTE->getSubExpr(), Ty);
1567 llvm::Constant *VisitStringLiteral(
const StringLiteral *E, QualType T) {
1572 llvm::Constant *VisitObjCEncodeExpr(
const ObjCEncodeExpr *E, QualType T) {
1579 assert(CAT &&
"String data not of constant array type!");
1584 return llvm::ConstantDataArray::getString(VMContext, Str,
false);
1587 llvm::Constant *VisitUnaryExtension(
const UnaryOperator *E, QualType T) {
1591 llvm::Constant *VisitUnaryMinus(
const UnaryOperator *U, QualType T) {
1592 if (llvm::Constant *
C = Visit(U->
getSubExpr(), T))
1593 if (
auto *CI = dyn_cast<llvm::ConstantInt>(
C))
1594 return llvm::ConstantInt::get(CGM.
getLLVMContext(), -CI->getValue());
1598 llvm::Constant *VisitPackIndexingExpr(
const PackIndexingExpr *E, QualType T) {
1603 llvm::Type *ConvertType(QualType T) {
1610llvm::Constant *ConstantEmitter::validateAndPopAbstract(llvm::Constant *
C,
1611 AbstractState saved) {
1612 Abstract = saved.OldValue;
1614 assert(saved.OldPlaceholdersSize == PlaceholderAddresses.size() &&
1615 "created a placeholder while doing an abstract emission?");
1624 auto state = pushAbstract();
1626 return validateAndPopAbstract(
C, state);
1631 auto state = pushAbstract();
1633 return validateAndPopAbstract(
C, state);
1638 auto state = pushAbstract();
1640 return validateAndPopAbstract(
C, state);
1649 RetType =
CGM.getContext().getLValueReferenceType(RetType);
1656 auto state = pushAbstract();
1658 C = validateAndPopAbstract(
C, state);
1661 "internal error: could not emit constant value \"abstractly\"");
1662 C =
CGM.EmitNullConstant(destType);
1670 bool EnablePtrAuthFunctionTypeDiscrimination) {
1671 auto state = pushAbstract();
1673 tryEmitPrivate(value, destType, EnablePtrAuthFunctionTypeDiscrimination);
1674 C = validateAndPopAbstract(
C, state);
1677 "internal error: could not emit constant value \"abstractly\"");
1678 C =
CGM.EmitNullConstant(destType);
1692 for (
auto [_, GV] : PlaceholderAddresses)
1693 GV->eraseFromParent();
1694 PlaceholderAddresses.clear();
1698 return markIfFailed(
Init);
1704 initializeNonAbstract(destAddrSpace);
1711 initializeNonAbstract(destAddrSpace);
1713 assert(
C &&
"couldn't emit constant value non-abstractly?");
1718 assert(!Abstract &&
"cannot get current address for abstract constant");
1724 auto global =
new llvm::GlobalVariable(
CGM.getModule(),
CGM.Int8Ty,
true,
1725 llvm::GlobalValue::PrivateLinkage,
1729 llvm::GlobalVariable::NotThreadLocal,
1730 CGM.getContext().getTargetAddressSpace(DestAddressSpace));
1732 PlaceholderAddresses.push_back(std::make_pair(
nullptr, global));
1738 llvm::GlobalValue *placeholder) {
1739 assert(!PlaceholderAddresses.empty());
1740 assert(PlaceholderAddresses.back().first ==
nullptr);
1741 assert(PlaceholderAddresses.back().second == placeholder);
1742 PlaceholderAddresses.back().first = signal;
1746 struct ReplacePlaceholders {
1750 llvm::Constant *
Base;
1751 llvm::Type *BaseValueTy =
nullptr;
1754 llvm::DenseMap<llvm::Constant*, llvm::GlobalVariable*> PlaceholderAddresses;
1757 llvm::DenseMap<llvm::GlobalVariable*, llvm::Constant*> Locations;
1765 ReplacePlaceholders(
CodeGenModule &CGM, llvm::Constant *base,
1766 ArrayRef<std::pair<llvm::Constant*,
1767 llvm::GlobalVariable*>> addresses)
1768 : CGM(CGM),
Base(base),
1769 PlaceholderAddresses(addresses.begin(), addresses.end()) {
1772 void replaceInInitializer(llvm::Constant *init) {
1774 BaseValueTy = init->getType();
1777 Indices.push_back(0);
1778 IndexValues.push_back(
nullptr);
1781 findLocations(init);
1784 assert(IndexValues.size() == Indices.size() &&
"mismatch");
1785 assert(Indices.size() == 1 &&
"didn't pop all indices");
1788 assert(Locations.size() == PlaceholderAddresses.size() &&
1789 "missed a placeholder?");
1795 for (
auto &entry : Locations) {
1796 assert(entry.first->getName() ==
"" &&
"not a placeholder!");
1797 entry.first->replaceAllUsesWith(entry.second);
1798 entry.first->eraseFromParent();
1803 void findLocations(llvm::Constant *init) {
1805 if (
auto agg = dyn_cast<llvm::ConstantAggregate>(init)) {
1806 for (
unsigned i = 0, e = agg->getNumOperands(); i != e; ++i) {
1807 Indices.push_back(i);
1808 IndexValues.push_back(
nullptr);
1810 findLocations(agg->getOperand(i));
1812 IndexValues.pop_back();
1820 auto it = PlaceholderAddresses.find(init);
1821 if (it != PlaceholderAddresses.end()) {
1822 setLocation(it->second);
1827 if (
auto expr = dyn_cast<llvm::ConstantExpr>(init)) {
1828 init =
expr->getOperand(0);
1835 void setLocation(llvm::GlobalVariable *placeholder) {
1836 assert(!Locations.contains(placeholder) &&
1837 "already found location for placeholder!");
1842 assert(Indices.size() == IndexValues.size());
1843 for (
size_t i = Indices.size() - 1; i !=
size_t(-1); --i) {
1844 if (IndexValues[i]) {
1846 for (
size_t j = 0; j != i + 1; ++j) {
1847 assert(IndexValues[j] &&
1856 IndexValues[i] = llvm::ConstantInt::get(CGM.
Int32Ty, Indices[i]);
1859 llvm::Constant *location = llvm::ConstantExpr::getInBoundsGetElementPtr(
1860 BaseValueTy, Base, IndexValues);
1862 Locations.insert({placeholder, location});
1868 assert(InitializedNonAbstract &&
1869 "finalizing emitter that was used for abstract emission?");
1870 assert(!Finalized &&
"finalizing emitter multiple times");
1871 assert(global->getInitializer());
1876 if (!PlaceholderAddresses.empty()) {
1877 ReplacePlaceholders(
CGM, global, PlaceholderAddresses)
1878 .replaceInInitializer(global->getInitializer());
1879 PlaceholderAddresses.clear();
1884 assert((!InitializedNonAbstract || Finalized || Failed) &&
1885 "not finalized after being initialized for non-abstract emission");
1886 assert(PlaceholderAddresses.empty() &&
"unhandled placeholders");
1892 type.getQualifiers());
1905 dyn_cast_or_null<CXXConstructExpr>(D.
getInit())) {
1915 assert(E &&
"No initializer to emit");
1919 if (llvm::Constant *
C = ConstExprEmitter(*this).Visit(E, nonMemoryDestType))
1926 assert(!value->allowConstexprUnknown() &&
1927 "Constexpr unknown values are not allowed in CodeGen");
1971 assert(Schema &&
"applying trivial ptrauth schema");
1974 return UnsignedPointer;
1976 unsigned Key = Schema.
getKey();
1979 llvm::GlobalValue *StorageAddress =
nullptr;
1988 llvm::ConstantInt *Discriminator =
1991 llvm::Constant *SignedPointer =
CGM.getConstantSignedPointer(
1992 UnsignedPointer, Key, StorageAddress, Discriminator);
1997 return SignedPointer;
2005 QualType destValueType = AT->getValueType();
2008 uint64_t innerSize =
CGM.getContext().getTypeSize(destValueType);
2009 uint64_t outerSize =
CGM.getContext().getTypeSize(destType);
2010 if (innerSize == outerSize)
2013 assert(innerSize < outerSize &&
"emitted over-large constant for atomic");
2014 llvm::Constant *elts[] = {
2016 llvm::ConstantAggregateZero::get(
2017 llvm::ArrayType::get(
CGM.Int8Ty, (outerSize - innerSize) / 8))
2019 return llvm::ConstantStruct::getAnon(elts);
2024 if ((
C->getType()->isIntegerTy(1) && !destType->
isBitIntType()) ||
2027 llvm::Type *boolTy =
CGM.getTypes().ConvertTypeForMem(destType);
2028 llvm::Constant *Res = llvm::ConstantFoldCastOperand(
2029 llvm::Instruction::ZExt,
C, boolTy,
CGM.getDataLayout());
2030 assert(Res &&
"Constant folding must succeed");
2035 llvm::Type *MemTy =
CGM.getTypes().ConvertTypeForMem(destType);
2036 if (
C->getType() != MemTy) {
2037 ConstantAggregateBuilder Builder(
CGM);
2038 llvm::Type *LoadStoreTy =
2039 CGM.getTypes().convertTypeForLoadStore(destType);
2043 llvm::Constant *Res = llvm::ConstantFoldCastOperand(
2045 ? llvm::Instruction::SExt
2046 : llvm::Instruction::ZExt,
2047 CI, LoadStoreTy,
CGM.getDataLayout());
2048 if (
CGM.getTypes().typeRequiresSplitIntoByteArray(destType,
2053 Builder.addBits(
Value, 0,
false);
2054 return Builder.build(MemTy,
false);
2065 assert(!destType->
isVoidType() &&
"can't emit a void constant");
2068 if (llvm::Constant *
C = ConstExprEmitter(*this).Visit(E, destType))
2093struct ConstantLValue {
2094 llvm::Constant *
Value;
2095 bool HasOffsetApplied;
2096 bool HasDestPointerAuth;
2098 ConstantLValue(llvm::Constant *value,
2099 bool hasOffsetApplied =
false,
2100 bool hasDestPointerAuth =
false)
2101 :
Value(value), HasOffsetApplied(hasOffsetApplied),
2102 HasDestPointerAuth(hasDestPointerAuth) {}
2105 : ConstantLValue(address.getPointer()) {}
2109class ConstantLValueEmitter :
public ConstStmtVisitor<ConstantLValueEmitter,
2112 ConstantEmitter &Emitter;
2115 bool EnablePtrAuthFunctionTypeDiscrimination;
2118 friend StmtVisitorBase;
2121 ConstantLValueEmitter(ConstantEmitter &emitter,
const APValue &value,
2123 bool EnablePtrAuthFunctionTypeDiscrimination =
true)
2124 : CGM(emitter.CGM), Emitter(emitter),
Value(value), DestType(destType),
2125 EnablePtrAuthFunctionTypeDiscrimination(
2126 EnablePtrAuthFunctionTypeDiscrimination) {}
2128 llvm::Constant *tryEmit();
2131 llvm::Constant *tryEmitAbsolute(llvm::Type *destTy);
2132 ConstantLValue tryEmitBase(
const APValue::LValueBase &base);
2134 ConstantLValue VisitStmt(
const Stmt *S) {
return nullptr; }
2135 ConstantLValue VisitConstantExpr(
const ConstantExpr *E);
2136 ConstantLValue VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
2137 ConstantLValue VisitStringLiteral(
const StringLiteral *E);
2138 ConstantLValue VisitObjCBoxedExpr(
const ObjCBoxedExpr *E);
2139 ConstantLValue VisitObjCEncodeExpr(
const ObjCEncodeExpr *E);
2140 ConstantLValue VisitObjCStringLiteral(
const ObjCStringLiteral *E);
2141 llvm::Constant *VisitObjCCollectionElement(
const Expr *E);
2142 ConstantLValue VisitObjCArrayLiteral(
const ObjCArrayLiteral *E);
2143 ConstantLValue VisitObjCDictionaryLiteral(
const ObjCDictionaryLiteral *E);
2144 ConstantLValue VisitPredefinedExpr(
const PredefinedExpr *E);
2145 ConstantLValue VisitAddrLabelExpr(
const AddrLabelExpr *E);
2146 ConstantLValue VisitCallExpr(
const CallExpr *E);
2147 ConstantLValue VisitBlockExpr(
const BlockExpr *E);
2148 ConstantLValue VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
2149 ConstantLValue VisitMaterializeTemporaryExpr(
2150 const MaterializeTemporaryExpr *E);
2152 ConstantLValue emitPointerAuthSignConstant(
const CallExpr *E);
2153 llvm::Constant *emitPointerAuthPointer(
const Expr *E);
2154 unsigned emitPointerAuthKey(
const Expr *E);
2155 std::pair<llvm::Constant *, llvm::ConstantInt *>
2156 emitPointerAuthDiscriminator(
const Expr *E);
2158 bool hasNonZeroOffset()
const {
2159 return !
Value.getLValueOffset().isZero();
2163 llvm::Constant *getOffset() {
2164 return llvm::ConstantInt::get(CGM.
Int64Ty,
2165 Value.getLValueOffset().getQuantity());
2169 llvm::Constant *applyOffset(llvm::Constant *
C) {
2170 if (!hasNonZeroOffset())
2173 return llvm::ConstantExpr::getPtrAdd(
C, getOffset());
2179llvm::Constant *ConstantLValueEmitter::tryEmit() {
2180 const APValue::LValueBase &base =
Value.getLValueBase();
2195 return tryEmitAbsolute(destTy);
2199 ConstantLValue result = tryEmitBase(base);
2202 llvm::Constant *value = result.Value;
2203 if (!value)
return nullptr;
2206 if (!result.HasOffsetApplied) {
2207 value = applyOffset(value);
2211 if (PointerAuthQualifier PointerAuth = DestType.
getPointerAuth();
2212 PointerAuth && !result.HasDestPointerAuth) {
2221 return llvm::ConstantExpr::getPointerCast(value, destTy);
2223 return llvm::ConstantExpr::getPtrToInt(value, destTy);
2229ConstantLValueEmitter::tryEmitAbsolute(llvm::Type *destTy) {
2232 if (
Value.isNullPointer()) {
2240 auto intptrTy = CGM.
getDataLayout().getIntPtrType(destPtrTy);
2242 C = llvm::ConstantFoldIntegerCast(getOffset(), intptrTy,
false,
2244 assert(
C &&
"Must have folded, as Offset is a ConstantInt");
2245 C = llvm::ConstantExpr::getIntToPtr(
C, destPtrTy);
2250ConstantLValueEmitter::tryEmitBase(
const APValue::LValueBase &base) {
2252 if (
const ValueDecl *D = base.
dyn_cast<
const ValueDecl*>()) {
2257 if (D->hasAttr<WeakRefAttr>())
2260 auto PtrAuthSign = [&](llvm::Constant *
C) {
2261 if (PointerAuthQualifier PointerAuth = DestType.
getPointerAuth()) {
2264 return ConstantLValue(
C,
true,
true);
2267 CGPointerAuthInfo AuthInfo;
2269 if (EnablePtrAuthFunctionTypeDiscrimination)
2273 if (hasNonZeroOffset())
2274 return ConstantLValue(
nullptr);
2278 C, AuthInfo.
getKey(),
nullptr,
2280 return ConstantLValue(
C,
true,
true);
2283 return ConstantLValue(
C);
2286 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
2288 if (FD->getType()->isCFIUncheckedCalleeFunctionType())
2290 return PtrAuthSign(
C);
2293 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
2295 if (!VD->hasLocalStorage()) {
2296 if (VD->isFileVarDecl() || VD->hasExternalStorage())
2299 if (VD->isLocalVarDecl()) {
2306 if (
const auto *GD = dyn_cast<MSGuidDecl>(D))
2309 if (
const auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D))
2312 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D))
2319 if (TypeInfoLValue TI = base.
dyn_cast<TypeInfoLValue>())
2323 return Visit(base.
get<
const Expr*>());
2327ConstantLValueEmitter::VisitConstantExpr(
const ConstantExpr *E) {
2334ConstantLValueEmitter::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
2335 ConstantEmitter CompoundLiteralEmitter(CGM, Emitter.
CGF);
2337 return tryEmitGlobalCompoundLiteral(CompoundLiteralEmitter, E);
2341ConstantLValueEmitter::VisitStringLiteral(
const StringLiteral *E) {
2346ConstantLValueEmitter::VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
2358ConstantLValueEmitter::VisitObjCStringLiteral(
const ObjCStringLiteral *E) {
2363ConstantLValueEmitter::VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
2370 "Non const NSNumber is being emitted as a constant");
2377 const bool IsBoolType =
2379 bool BoolValue =
false;
2385 Expr::EvalResult IntResult{};
2392 llvm::APFloat FloatValue(0.0);
2398 llvm_unreachable(
"SubExpr is expected to be evaluated as a numeric type");
2402ConstantLValueEmitter::VisitObjCCollectionElement(
const Expr *E) {
2405 QualType DestTy = CE->
getType();
2407 assert(CE->getCastKind() == CK_BitCast &&
2408 "Expected a CK_BitCast type for valid items in constant objc "
2409 "collection literals");
2412 ConstantLValue LV = Visit(Elm);
2414 llvm::Constant *Val = llvm::ConstantExpr::getBitCast(ConstVal, DstTy);
2419ConstantLValueEmitter::VisitObjCArrayLiteral(
const ObjCArrayLiteral *E) {
2420 SmallVector<llvm::Constant *, 16> ObjectExpressions;
2422 ObjectExpressions.reserve(NumElements);
2424 for (uint64_t i = 0; i < NumElements; i++) {
2425 llvm::Constant *Val = VisitObjCCollectionElement(E->
getElement(i));
2426 ObjectExpressions.push_back(Val);
2433ConstantLValue ConstantLValueEmitter::VisitObjCDictionaryLiteral(
2434 const ObjCDictionaryLiteral *E) {
2435 SmallVector<std::pair<llvm::Constant *, llvm::Constant *>, 16> KeysAndObjects;
2437 KeysAndObjects.reserve(NumElements);
2439 for (uint64_t i = 0; i < NumElements; i++) {
2440 llvm::Constant *Key =
2442 llvm::Constant *Val =
2444 KeysAndObjects.push_back({Key, Val});
2452ConstantLValueEmitter::VisitPredefinedExpr(
const PredefinedExpr *E) {
2457ConstantLValueEmitter::VisitAddrLabelExpr(
const AddrLabelExpr *E) {
2458 assert(Emitter.
CGF &&
"Invalid address of label expression outside function");
2464ConstantLValueEmitter::VisitCallExpr(
const CallExpr *E) {
2466 if (builtin == Builtin::BI__builtin_function_start)
2470 if (builtin == Builtin::BI__builtin_ptrauth_sign_constant)
2471 return emitPointerAuthSignConstant(E);
2473 if (builtin != Builtin::BI__builtin___CFStringMakeConstantString &&
2474 builtin != Builtin::BI__builtin___NSStringMakeConstantString)
2478 if (builtin == Builtin::BI__builtin___NSStringMakeConstantString) {
2487ConstantLValueEmitter::emitPointerAuthSignConstant(
const CallExpr *E) {
2488 llvm::Constant *UnsignedPointer = emitPointerAuthPointer(E->
getArg(0));
2489 unsigned Key = emitPointerAuthKey(E->
getArg(1));
2490 auto [StorageAddress, OtherDiscriminator] =
2491 emitPointerAuthDiscriminator(E->
getArg(2));
2494 UnsignedPointer, Key, StorageAddress, OtherDiscriminator);
2495 return SignedPointer;
2498llvm::Constant *ConstantLValueEmitter::emitPointerAuthPointer(
const Expr *E) {
2505 assert(
Result.Val.isLValue());
2507 assert(
Result.Val.getLValueOffset().isZero());
2508 return ConstantEmitter(CGM, Emitter.
CGF)
2512unsigned ConstantLValueEmitter::emitPointerAuthKey(
const Expr *E) {
2516std::pair<llvm::Constant *, llvm::ConstantInt *>
2517ConstantLValueEmitter::emitPointerAuthDiscriminator(
const Expr *E) {
2520 if (
const auto *
Call = dyn_cast<CallExpr>(E)) {
2521 if (
Call->getBuiltinCallee() ==
2522 Builtin::BI__builtin_ptrauth_blend_discriminator) {
2523 llvm::Constant *
Pointer = ConstantEmitter(CGM).emitAbstract(
2524 Call->getArg(0),
Call->getArg(0)->getType());
2526 Call->getArg(1),
Call->getArg(1)->getType()));
2531 llvm::Constant *
Result = ConstantEmitter(CGM).emitAbstract(E, E->
getType());
2532 if (
Result->getType()->isPointerTy())
2533 return {
Result,
nullptr};
2538ConstantLValueEmitter::VisitBlockExpr(
const BlockExpr *E) {
2539 StringRef functionName;
2540 if (
auto CGF = Emitter.
CGF)
2541 functionName = CGF->CurFn->getName();
2543 functionName =
"global";
2549ConstantLValueEmitter::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
2559ConstantLValueEmitter::VisitMaterializeTemporaryExpr(
2560 const MaterializeTemporaryExpr *E) {
2568 bool EnablePtrAuthFunctionTypeDiscrimination) {
2573 return llvm::UndefValue::get(
CGM.getTypes().ConvertType(DestType));
2575 return ConstantLValueEmitter(*
this,
Value, DestType,
2576 EnablePtrAuthFunctionTypeDiscrimination)
2581 (PointerAuth.authenticatesNullValues() ||
Value.getInt() != 0))
2583 return llvm::ConstantInt::get(
CGM.getLLVMContext(),
Value.getInt());
2585 return llvm::ConstantInt::get(
CGM.getLLVMContext(),
2586 Value.getFixedPoint().getValue());
2590 Complex[0] = llvm::ConstantInt::get(
CGM.getLLVMContext(),
2591 Value.getComplexIntReal());
2592 Complex[1] = llvm::ConstantInt::get(
CGM.getLLVMContext(),
2593 Value.getComplexIntImag());
2596 llvm::StructType *STy =
2598 return llvm::ConstantStruct::get(STy,
Complex);
2601 const llvm::APFloat &
Init =
Value.getFloat();
2602 if (&
Init.getSemantics() == &llvm::APFloat::IEEEhalf() &&
2603 !
CGM.getContext().getLangOpts().NativeHalfType &&
2604 CGM.getContext().getTargetInfo().useFP16ConversionIntrinsics())
2605 return llvm::ConstantInt::get(
CGM.getLLVMContext(),
2606 Init.bitcastToAPInt());
2608 return llvm::ConstantFP::get(
CGM.getLLVMContext(),
Init);
2613 Complex[0] = llvm::ConstantFP::get(
CGM.getLLVMContext(),
2614 Value.getComplexFloatReal());
2615 Complex[1] = llvm::ConstantFP::get(
CGM.getLLVMContext(),
2616 Value.getComplexFloatImag());
2619 llvm::StructType *STy =
2621 return llvm::ConstantStruct::get(STy,
Complex);
2624 unsigned NumElts =
Value.getVectorLength();
2627 for (
unsigned I = 0; I != NumElts; ++I) {
2630 Inits[I] = llvm::ConstantInt::get(
CGM.getLLVMContext(), Elt.
getInt());
2634 Inits[I] = llvm::UndefValue::get(
CGM.getTypes().ConvertType(
2637 llvm_unreachable(
"unsupported vector element type");
2639 return llvm::ConstantVector::get(
Inits);
2643 unsigned NumRows =
Value.getMatrixNumRows();
2644 unsigned NumCols =
Value.getMatrixNumColumns();
2645 unsigned NumElts = NumRows * NumCols;
2648 bool IsRowMajor =
CGM.getLangOpts().getDefaultMatrixMemoryLayout() ==
2651 for (
unsigned Row = 0; Row != NumRows; ++Row) {
2652 for (
unsigned Col = 0; Col != NumCols; ++Col) {
2654 unsigned Idx = MT->getFlattenedIndex(Row, Col, IsRowMajor);
2657 llvm::ConstantInt::get(
CGM.getLLVMContext(), Elt.
getInt());
2660 llvm::ConstantFP::get(
CGM.getLLVMContext(), Elt.
getFloat());
2662 Inits[Idx] = llvm::PoisonValue::get(
2663 CGM.getTypes().ConvertType(MT->getElementType()));
2665 llvm_unreachable(
"unsupported matrix element type");
2668 return llvm::ConstantVector::get(
Inits);
2675 if (!LHS || !RHS)
return nullptr;
2678 llvm::Type *ResultType =
CGM.getTypes().ConvertType(DestType);
2679 LHS = llvm::ConstantExpr::getPtrToInt(LHS,
CGM.IntPtrTy);
2680 RHS = llvm::ConstantExpr::getPtrToInt(RHS,
CGM.IntPtrTy);
2681 llvm::Constant *AddrLabelDiff = llvm::ConstantExpr::getSub(LHS, RHS);
2686 return llvm::ConstantExpr::getTruncOrBitCast(AddrLabelDiff, ResultType);
2690 return ConstStructBuilder::BuildStruct(*
this,
Value, DestType);
2692 const ArrayType *ArrayTy =
CGM.getContext().getAsArrayType(DestType);
2693 unsigned NumElements =
Value.getArraySize();
2694 unsigned NumInitElts =
Value.getArrayInitializedElts();
2697 llvm::Constant *Filler =
nullptr;
2698 if (
Value.hasArrayFiller()) {
2707 if (Filler && Filler->isNullValue())
2708 Elts.reserve(NumInitElts + 1);
2710 Elts.reserve(NumElements);
2712 llvm::Type *CommonElementType =
nullptr;
2713 for (
unsigned I = 0; I < NumInitElts; ++I) {
2716 if (!
C)
return nullptr;
2719 CommonElementType =
C->getType();
2720 else if (
C->getType() != CommonElementType)
2721 CommonElementType =
nullptr;
2725 llvm::ArrayType *Desired =
2730 Desired = llvm::ArrayType::get(Desired->getElementType(), Elts.size());
2732 return EmitArrayConstant(
CGM, Desired, CommonElementType, NumElements, Elts,
2736 return CGM.getCXXABI().EmitMemberPointer(
Value, DestType);
2738 llvm_unreachable(
"Unknown APValue kind");
2743 return EmittedCompoundLiterals.lookup(E);
2748 bool Ok = EmittedCompoundLiterals.insert(std::make_pair(CLE, GV)).second;
2750 assert(
Ok &&
"CLE has already been emitted!");
2755 assert(E->
isFileScope() &&
"not a file-scope compound literal expr");
2757 return tryEmitGlobalCompoundLiteral(emitter, E);
2768 return getCXXABI().EmitMemberFunctionPointer(method);
2778 llvm::Type *baseType,
2783 bool asCompleteObject) {
2785 llvm::StructType *structure =
2789 unsigned numElements = structure->getNumElements();
2790 std::vector<llvm::Constant *> elements(numElements);
2792 auto CXXR = dyn_cast<CXXRecordDecl>(record);
2795 for (
const auto &I : CXXR->bases()) {
2796 if (I.isVirtual()) {
2812 llvm::Type *baseType = structure->getElementType(fieldIndex);
2818 for (
const auto *Field : record->
fields()) {
2821 if (!Field->isBitField() &&
2829 if (Field->getIdentifier())
2831 if (
const auto *FieldRD = Field->getType()->getAsRecordDecl())
2832 if (FieldRD->findFirstNamedDataMember())
2838 if (CXXR && asCompleteObject) {
2839 for (
const auto &I : CXXR->vbases()) {
2848 if (elements[fieldIndex])
continue;
2850 llvm::Type *baseType = structure->getElementType(fieldIndex);
2856 for (
unsigned i = 0; i != numElements; ++i) {
2858 elements[i] = llvm::Constant::getNullValue(structure->getElementType(i));
2861 return llvm::ConstantStruct::get(structure, elements);
2866 llvm::Type *baseType,
2872 return llvm::Constant::getNullValue(baseType);
2888 if (
getTypes().isZeroInitializable(T))
2889 return llvm::Constant::getNullValue(
getTypes().ConvertTypeForMem(T));
2892 llvm::ArrayType *ATy =
2897 llvm::Constant *Element =
2901 return llvm::ConstantArray::get(ATy, Array);
2904 if (
const auto *RD = T->getAsRecordDecl())
2905 return ::EmitNullConstant(*
this, RD,
2908 assert(T->isMemberDataPointerType() &&
2909 "Should only see pointers to data members here!");
2916 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 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()
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
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.
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.