29#include "llvm/ADT/STLExtras.h"
30#include "llvm/ADT/Sequence.h"
31#include "llvm/Analysis/ConstantFolding.h"
32#include "llvm/IR/Constants.h"
33#include "llvm/IR/DataLayout.h"
34#include "llvm/IR/Function.h"
35#include "llvm/IR/GlobalVariable.h"
36#include "llvm/Support/SipHash.h"
46class ConstExprEmitter;
49 llvm::Type *Ty = CGM.
CharTy;
51 Ty = llvm::ArrayType::get(Ty, PadSize.
getQuantity());
53 return llvm::Constant::getNullValue(Ty);
55 return llvm::UndefValue::get(Ty);
58struct ConstantAggregateBuilderUtils {
61 ConstantAggregateBuilderUtils(CodeGenModule &CGM) : CGM(CGM) {}
63 CharUnits getAlignment(
const llvm::Constant *
C)
const {
68 CharUnits getSize(llvm::Type *Ty)
const {
72 CharUnits getSize(
const llvm::Constant *
C)
const {
73 return getSize(
C->getType());
76 llvm::Constant *getPadding(CharUnits PadSize)
const {
77 return ::getPadding(CGM, PadSize);
80 llvm::Constant *getZeroes(CharUnits ZeroSize)
const {
82 return llvm::ConstantAggregateZero::get(Ty);
88class ConstantAggregateBuilder :
private ConstantAggregateBuilderUtils {
97 llvm::SmallVector<llvm::Constant*, 32> Elems;
98 llvm::SmallVector<CharUnits, 32> Offsets;
107 bool NaturalLayout =
true;
109 bool split(
size_t Index, CharUnits Hint);
110 std::optional<size_t> splitAt(CharUnits Pos);
112 static llvm::Constant *buildFrom(CodeGenModule &CGM,
113 ArrayRef<llvm::Constant *> Elems,
114 ArrayRef<CharUnits> Offsets,
115 CharUnits StartOffset, CharUnits Size,
116 bool NaturalLayout, llvm::Type *DesiredTy,
117 bool AllowOversized);
120 ConstantAggregateBuilder(CodeGenModule &CGM)
121 : ConstantAggregateBuilderUtils(CGM) {}
128 bool add(llvm::Constant *
C, CharUnits Offset,
bool AllowOverwrite);
131 bool addBits(llvm::APInt Bits, uint64_t OffsetInBits,
bool AllowOverwrite);
135 void condense(CharUnits Offset, llvm::Type *DesiredTy);
142 llvm::Constant *build(llvm::Type *DesiredTy,
bool AllowOversized)
const {
144 NaturalLayout, DesiredTy, AllowOversized);
148template<
typename Container,
typename Range = std::initializer_list<
149 typename Container::value_type>>
150static void replace(Container &
C,
size_t BeginOff,
size_t EndOff, Range Vals) {
151 assert(BeginOff <= EndOff &&
"invalid replacement range");
152 llvm::replace(
C,
C.begin() + BeginOff,
C.begin() + EndOff, Vals);
155bool ConstantAggregateBuilder::add(llvm::Constant *
C,
CharUnits Offset,
156 bool AllowOverwrite) {
158 if (Offset >= Size) {
159 CharUnits Align = getAlignment(
C);
160 CharUnits AlignedSize =
Size.alignTo(Align);
161 if (AlignedSize > Offset || Offset.
alignTo(Align) != Offset)
162 NaturalLayout =
false;
163 else if (AlignedSize < Offset) {
164 Elems.push_back(getPadding(Offset - Size));
165 Offsets.push_back(Size);
168 Offsets.push_back(Offset);
169 Size = Offset + getSize(
C);
174 std::optional<size_t> FirstElemToReplace = splitAt(Offset);
175 if (!FirstElemToReplace)
178 CharUnits CSize = getSize(
C);
179 std::optional<size_t> LastElemToReplace = splitAt(Offset + CSize);
180 if (!LastElemToReplace)
183 assert((FirstElemToReplace == LastElemToReplace || AllowOverwrite) &&
184 "unexpectedly overwriting field");
186 replace(Elems, *FirstElemToReplace, *LastElemToReplace, {
C});
187 replace(Offsets, *FirstElemToReplace, *LastElemToReplace, {Offset});
188 Size = std::max(Size, Offset + CSize);
189 NaturalLayout =
false;
193bool ConstantAggregateBuilder::addBits(llvm::APInt Bits, uint64_t OffsetInBits,
194 bool AllowOverwrite) {
200 unsigned OffsetWithinChar = OffsetInBits % CharWidth;
204 for (CharUnits OffsetInChars =
208 unsigned WantedBits =
209 std::min((uint64_t)Bits.getBitWidth(), CharWidth - OffsetWithinChar);
213 llvm::APInt BitsThisChar = Bits;
214 if (BitsThisChar.getBitWidth() < CharWidth)
215 BitsThisChar = BitsThisChar.zext(CharWidth);
219 int Shift = Bits.getBitWidth() - CharWidth + OffsetWithinChar;
221 BitsThisChar.lshrInPlace(Shift);
223 BitsThisChar = BitsThisChar.shl(-Shift);
225 BitsThisChar = BitsThisChar.shl(OffsetWithinChar);
227 if (BitsThisChar.getBitWidth() > CharWidth)
228 BitsThisChar = BitsThisChar.trunc(CharWidth);
230 if (WantedBits == CharWidth) {
233 OffsetInChars, AllowOverwrite);
238 std::optional<size_t> FirstElemToUpdate = splitAt(OffsetInChars);
239 if (!FirstElemToUpdate)
241 std::optional<size_t> LastElemToUpdate =
243 if (!LastElemToUpdate)
245 assert(*LastElemToUpdate - *FirstElemToUpdate < 2 &&
246 "should have at most one element covering one byte");
249 llvm::APInt UpdateMask(CharWidth, 0);
251 UpdateMask.setBits(CharWidth - OffsetWithinChar - WantedBits,
252 CharWidth - OffsetWithinChar);
254 UpdateMask.setBits(OffsetWithinChar, OffsetWithinChar + WantedBits);
255 BitsThisChar &= UpdateMask;
257 if (*FirstElemToUpdate == *LastElemToUpdate ||
258 Elems[*FirstElemToUpdate]->isNullValue() ||
262 OffsetInChars,
true);
264 llvm::Constant *&ToUpdate = Elems[*FirstElemToUpdate];
267 auto *CI = dyn_cast<llvm::ConstantInt>(ToUpdate);
272 assert(CI->getBitWidth() == CharWidth &&
"splitAt failed");
273 assert((!(CI->getValue() & UpdateMask) || AllowOverwrite) &&
274 "unexpectedly overwriting bitfield");
275 BitsThisChar |= (CI->getValue() & ~UpdateMask);
276 ToUpdate = llvm::ConstantInt::get(CGM.
getLLVMContext(), BitsThisChar);
281 if (WantedBits == Bits.getBitWidth())
286 Bits.lshrInPlace(WantedBits);
287 Bits = Bits.trunc(Bits.getBitWidth() - WantedBits);
290 OffsetWithinChar = 0;
300std::optional<size_t> ConstantAggregateBuilder::splitAt(CharUnits Pos) {
302 return Offsets.size();
305 auto FirstAfterPos = llvm::upper_bound(Offsets, Pos);
306 if (FirstAfterPos == Offsets.begin())
310 size_t LastAtOrBeforePosIndex = FirstAfterPos - Offsets.begin() - 1;
311 if (Offsets[LastAtOrBeforePosIndex] == Pos)
312 return LastAtOrBeforePosIndex;
315 if (Offsets[LastAtOrBeforePosIndex] +
316 getSize(Elems[LastAtOrBeforePosIndex]) <= Pos)
317 return LastAtOrBeforePosIndex + 1;
320 if (!split(LastAtOrBeforePosIndex, Pos))
328bool ConstantAggregateBuilder::split(
size_t Index, CharUnits Hint) {
329 NaturalLayout =
false;
330 llvm::Constant *
C = Elems[Index];
331 CharUnits Offset = Offsets[Index];
333 if (
auto *CA = dyn_cast<llvm::ConstantAggregate>(
C)) {
336 replace(Elems, Index, Index + 1,
337 llvm::map_range(llvm::seq(0u, CA->getNumOperands()),
338 [&](
unsigned Op) { return CA->getOperand(Op); }));
343 llvm::GetElementPtrInst::getTypeAtIndex(CA->getType(), (uint64_t)0);
344 CharUnits ElemSize = getSize(ElemTy);
346 Offsets, Index, Index + 1,
347 llvm::map_range(llvm::seq(0u, CA->getNumOperands()),
348 [&](
unsigned Op) { return Offset + Op * ElemSize; }));
352 const llvm::StructLayout *Layout =
354 replace(Offsets, Index, Index + 1,
356 llvm::seq(0u, CA->getNumOperands()), [&](
unsigned Op) {
357 return Offset + CharUnits::fromQuantity(
358 Layout->getElementOffset(Op));
364 if (
auto *CDS = dyn_cast<llvm::ConstantDataSequential>(
C)) {
368 CharUnits ElemSize = getSize(CDS->getElementType());
369 replace(Elems, Index, Index + 1,
370 llvm::map_range(llvm::seq(
uint64_t(0u), CDS->getNumElements()),
372 return CDS->getElementAsConstant(Elem);
374 replace(Offsets, Index, Index + 1,
376 llvm::seq(
uint64_t(0u), CDS->getNumElements()),
377 [&](uint64_t Elem) { return Offset + Elem * ElemSize; }));
383 CharUnits ElemSize = getSize(
C);
384 assert(Hint > Offset && Hint < Offset + ElemSize &&
"nothing to split");
385 replace(Elems, Index, Index + 1,
386 {getZeroes(Hint - Offset), getZeroes(Offset + ElemSize - Hint)});
387 replace(Offsets, Index, Index + 1, {Offset, Hint});
393 replace(Elems, Index, Index + 1, {});
394 replace(Offsets, Index, Index + 1, {});
405static llvm::Constant *
406EmitArrayConstant(CodeGenModule &CGM, llvm::ArrayType *DesiredType,
407 llvm::Type *CommonElementType, uint64_t
ArrayBound,
408 SmallVectorImpl<llvm::Constant *> &Elements,
409 llvm::Constant *Filler);
411llvm::Constant *ConstantAggregateBuilder::buildFrom(
412 CodeGenModule &CGM, ArrayRef<llvm::Constant *> Elems,
413 ArrayRef<CharUnits> Offsets, CharUnits StartOffset, CharUnits Size,
414 bool NaturalLayout, llvm::Type *DesiredTy,
bool AllowOversized) {
415 ConstantAggregateBuilderUtils Utils(CGM);
418 return llvm::UndefValue::get(DesiredTy);
420 auto Offset = [&](
size_t I) {
return Offsets[I] - StartOffset; };
424 if (llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(DesiredTy)) {
425 assert(!AllowOversized &&
"oversized array emission not supported");
427 bool CanEmitArray =
true;
428 llvm::Type *CommonType = Elems[0]->getType();
429 llvm::Constant *Filler = llvm::Constant::getNullValue(CommonType);
430 CharUnits ElemSize = Utils.getSize(ATy->getElementType());
431 SmallVector<llvm::Constant*, 32> ArrayElements;
432 for (
size_t I = 0; I != Elems.size(); ++I) {
434 if (Elems[I]->isNullValue())
438 if (Elems[I]->
getType() != CommonType ||
439 !Offset(I).isMultipleOf(ElemSize)) {
440 CanEmitArray =
false;
443 ArrayElements.resize(Offset(I) / ElemSize + 1, Filler);
444 ArrayElements.back() = Elems[I];
448 return EmitArrayConstant(CGM, ATy, CommonType, ATy->getNumElements(),
449 ArrayElements, Filler);
458 CharUnits DesiredSize = Utils.getSize(DesiredTy);
459 if (Size > DesiredSize) {
460 assert(AllowOversized &&
"Elems are oversized");
466 for (llvm::Constant *
C : Elems)
467 Align = std::max(Align, Utils.getAlignment(
C));
470 CharUnits AlignedSize =
Size.alignTo(Align);
473 ArrayRef<llvm::Constant*> UnpackedElems = Elems;
474 llvm::SmallVector<llvm::Constant*, 32> UnpackedElemStorage;
475 if (DesiredSize < AlignedSize || DesiredSize.
alignTo(Align) != DesiredSize) {
477 NaturalLayout =
false;
479 }
else if (DesiredSize > AlignedSize) {
482 UnpackedElemStorage.assign(Elems.begin(), Elems.end());
483 UnpackedElemStorage.push_back(Utils.getPadding(DesiredSize - Size));
484 UnpackedElems = UnpackedElemStorage;
490 llvm::SmallVector<llvm::Constant*, 32> PackedElems;
491 if (!NaturalLayout) {
493 for (
size_t I = 0; I != Elems.size(); ++I) {
494 CharUnits Align = Utils.getAlignment(Elems[I]);
495 CharUnits NaturalOffset = SizeSoFar.
alignTo(Align);
496 CharUnits DesiredOffset = Offset(I);
497 assert(DesiredOffset >= SizeSoFar &&
"elements out of order");
499 if (DesiredOffset != NaturalOffset)
501 if (DesiredOffset != SizeSoFar)
502 PackedElems.push_back(Utils.getPadding(DesiredOffset - SizeSoFar));
503 PackedElems.push_back(Elems[I]);
504 SizeSoFar = DesiredOffset + Utils.getSize(Elems[I]);
509 assert(SizeSoFar <= DesiredSize &&
510 "requested size is too small for contents");
511 if (SizeSoFar < DesiredSize)
512 PackedElems.push_back(Utils.getPadding(DesiredSize - SizeSoFar));
516 llvm::StructType *STy = llvm::ConstantStruct::getTypeForElements(
521 if (llvm::StructType *DesiredSTy = dyn_cast<llvm::StructType>(DesiredTy)) {
522 if (DesiredSTy->isLayoutIdentical(STy))
526 return llvm::ConstantStruct::get(STy,
Packed ? PackedElems : UnpackedElems);
529void ConstantAggregateBuilder::condense(CharUnits Offset,
530 llvm::Type *DesiredTy) {
531 CharUnits
Size = getSize(DesiredTy);
533 std::optional<size_t> FirstElemToReplace = splitAt(Offset);
534 if (!FirstElemToReplace)
536 size_t First = *FirstElemToReplace;
538 std::optional<size_t> LastElemToReplace = splitAt(Offset + Size);
539 if (!LastElemToReplace)
541 size_t Last = *LastElemToReplace;
547 if (Length == 1 && Offsets[
First] == Offset &&
548 getSize(Elems[
First]) == Size) {
551 auto *STy = dyn_cast<llvm::StructType>(DesiredTy);
552 if (STy && STy->getNumElements() == 1 &&
553 STy->getElementType(0) == Elems[
First]->getType())
554 Elems[
First] = llvm::ConstantStruct::get(STy, Elems[
First]);
558 llvm::Constant *Replacement = buildFrom(
559 CGM, ArrayRef(Elems).slice(
First, Length),
560 ArrayRef(Offsets).slice(
First, Length), Offset, getSize(DesiredTy),
561 false, DesiredTy,
false);
562 replace(Elems,
First,
Last, {Replacement});
570class ConstStructBuilder {
572 ConstantEmitter &Emitter;
573 ConstantAggregateBuilder &Builder;
574 CharUnits StartOffset;
577 static llvm::Constant *BuildStruct(ConstantEmitter &Emitter,
578 const InitListExpr *ILE,
580 static llvm::Constant *BuildStruct(ConstantEmitter &Emitter,
582 static bool UpdateStruct(ConstantEmitter &Emitter,
583 ConstantAggregateBuilder &Const, CharUnits Offset,
584 const InitListExpr *Updater);
587 ConstStructBuilder(ConstantEmitter &Emitter,
588 ConstantAggregateBuilder &Builder, CharUnits StartOffset)
589 : CGM(Emitter.CGM), Emitter(Emitter), Builder(Builder),
590 StartOffset(StartOffset) {}
592 bool AppendField(
const FieldDecl *Field, uint64_t FieldOffset,
593 llvm::Constant *InitExpr,
bool AllowOverwrite =
false);
595 bool AppendBytes(CharUnits FieldOffsetInChars, llvm::Constant *InitCst,
596 bool AllowOverwrite =
false);
598 bool AppendBitField(
const FieldDecl *Field, uint64_t FieldOffset,
599 llvm::Constant *InitExpr,
bool AllowOverwrite =
false);
601 bool Build(
const InitListExpr *ILE,
bool AllowOverwrite);
602 bool Build(
const APValue &Val,
const RecordDecl *RD,
bool IsPrimaryBase,
603 const CXXRecordDecl *VTableClass, CharUnits BaseOffset);
604 bool DoZeroInitPadding(
const ASTRecordLayout &Layout,
unsigned FieldNo,
605 const FieldDecl &Field,
bool AllowOverwrite,
606 CharUnits &SizeSoFar,
bool &ZeroFieldSize);
607 bool DoZeroInitPadding(
const ASTRecordLayout &Layout,
bool AllowOverwrite,
608 CharUnits SizeSoFar);
609 llvm::Constant *
Finalize(QualType Ty);
612bool ConstStructBuilder::AppendField(
613 const FieldDecl *Field, uint64_t FieldOffset, llvm::Constant *InitCst,
614 bool AllowOverwrite) {
619 return AppendBytes(FieldOffsetInChars, InitCst, AllowOverwrite);
622bool ConstStructBuilder::AppendBytes(CharUnits FieldOffsetInChars,
623 llvm::Constant *InitCst,
624 bool AllowOverwrite) {
625 return Builder.add(InitCst, StartOffset + FieldOffsetInChars, AllowOverwrite);
628bool ConstStructBuilder::AppendBitField(
const FieldDecl *Field,
629 uint64_t FieldOffset, llvm::Constant *
C,
630 bool AllowOverwrite) {
632 llvm::ConstantInt *CI = dyn_cast<llvm::ConstantInt>(
C);
638 llvm::Type *LoadType =
640 llvm::Constant *FoldedConstant = llvm::ConstantFoldLoadFromConst(
642 CI = dyn_cast_if_present<llvm::ConstantInt>(FoldedConstant);
647 const CGRecordLayout &RL =
650 llvm::APInt FieldValue = CI->getValue();
656 if (Info.
Size > FieldValue.getBitWidth())
657 FieldValue = FieldValue.zext(Info.
Size);
660 if (Info.
Size < FieldValue.getBitWidth())
661 FieldValue = FieldValue.trunc(Info.
Size);
663 return Builder.addBits(FieldValue,
668static bool EmitDesignatedInitUpdater(ConstantEmitter &Emitter,
669 ConstantAggregateBuilder &Const,
670 CharUnits Offset, QualType
Type,
671 const InitListExpr *Updater) {
672 if (
Type->isRecordType())
673 return ConstStructBuilder::UpdateStruct(Emitter, Const, Offset, Updater);
682 llvm::Constant *FillC =
nullptr;
691 unsigned NumElementsToUpdate =
692 FillC ? CAT->getZExtSize() : Updater->
getNumInits();
693 for (
unsigned I = 0; I != NumElementsToUpdate; ++I, Offset += ElemSize) {
694 const Expr *
Init =
nullptr;
695 if (I < Updater->getNumInits())
698 if (!
Init && FillC) {
699 if (!
Const.add(FillC, Offset,
true))
703 }
else if (
const auto *ChildILE = dyn_cast<InitListExpr>(
Init)) {
704 if (!EmitDesignatedInitUpdater(Emitter, Const, Offset, ElemType,
708 Const.condense(Offset, ElemTy);
711 if (!
Const.add(Val, Offset,
true))
719bool ConstStructBuilder::Build(
const InitListExpr *ILE,
bool AllowOverwrite) {
723 unsigned FieldNo = -1;
724 unsigned ElementNo = 0;
729 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
730 if (CXXRD->getNumBases())
734 bool ZeroFieldSize =
false;
737 for (FieldDecl *Field : RD->fields()) {
746 if (
Field->isUnnamedBitField())
751 const Expr *
Init =
nullptr;
752 if (ElementNo < ILE->getNumInits())
754 if (isa_and_nonnull<NoInitExpr>(
Init)) {
755 if (ZeroInitPadding &&
756 !DoZeroInitPadding(Layout, FieldNo, *Field, AllowOverwrite, SizeSoFar,
770 if (ZeroInitPadding &&
771 !DoZeroInitPadding(Layout, FieldNo, *Field, AllowOverwrite, SizeSoFar,
778 if (AllowOverwrite &&
779 (
Field->getType()->isArrayType() ||
Field->getType()->isRecordType())) {
780 if (
auto *SubILE = dyn_cast<InitListExpr>(
Init)) {
783 if (!EmitDesignatedInitUpdater(Emitter, Builder, StartOffset + Offset,
784 Field->getType(), SubILE))
788 Builder.condense(StartOffset + Offset,
794 llvm::Constant *EltInit =
800 if (ZeroInitPadding && ZeroFieldSize)
804 if (!
Field->isBitField()) {
811 if (
Field->hasAttr<NoUniqueAddressAttr>())
812 AllowOverwrite =
true;
815 if (!AppendBitField(Field, Layout.
getFieldOffset(FieldNo), EltInit,
821 if (ZeroInitPadding && !DoZeroInitPadding(Layout, AllowOverwrite, SizeSoFar))
829 BaseInfo(
const CXXRecordDecl *
Decl, CharUnits Offset,
unsigned Index)
830 :
Decl(
Decl), Offset(Offset), Index(Index) {
833 const CXXRecordDecl *
Decl;
837 bool operator<(
const BaseInfo &O)
const {
return Offset < O.Offset; }
841bool ConstStructBuilder::Build(
const APValue &Val,
const RecordDecl *RD,
843 const CXXRecordDecl *VTableClass,
847 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
850 llvm::Constant *VTableAddressPoint =
855 VTableAddressPoint, *Authentication);
856 if (!VTableAddressPoint)
859 if (!AppendBytes(Offset, VTableAddressPoint))
865 SmallVector<BaseInfo, 8> Bases;
866 Bases.reserve(CD->getNumBases());
869 BaseEnd = CD->bases_end(); Base != BaseEnd; ++Base, ++BaseNo) {
870 assert(!
Base->isVirtual() &&
"should not have virtual bases here");
871 const CXXRecordDecl *BD =
Base->getType()->getAsCXXRecordDecl();
873 Bases.push_back(BaseInfo(BD, BaseOffset, BaseNo));
875 llvm::stable_sort(Bases);
877 for (
const BaseInfo &Base : Bases) {
880 VTableClass, Offset +
Base.Offset))
885 unsigned FieldNo = 0;
888 bool ZeroFieldSize =
false;
891 bool AllowOverwrite =
false;
893 FieldEnd = RD->
field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
899 if (
Field->isUnnamedBitField() ||
906 llvm::Constant *EltInit =
912 llvm::ConstantInt *Disc;
913 llvm::Constant *AddrDisc;
917 Disc = llvm::ConstantInt::get(CGM.
Int64Ty, FieldSignature);
918 AddrDisc = llvm::ConstantPointerNull::get(CGM.
VoidPtrTy);
925 Disc = llvm::ConstantInt::get(CGM.
Int64Ty,
929 EltInit = llvm::ConstantPtrAuth::get(
930 EltInit, llvm::ConstantInt::get(CGM.
Int32Ty, 2), Disc, AddrDisc,
937 if (ZeroInitPadding) {
938 if (!DoZeroInitPadding(Layout, FieldNo, **Field, AllowOverwrite,
939 SizeSoFar, ZeroFieldSize))
946 if (!
Field->isBitField()) {
948 if (!AppendField(*Field, Layout.
getFieldOffset(FieldNo) + OffsetBits,
949 EltInit, AllowOverwrite))
953 if (
Field->hasAttr<NoUniqueAddressAttr>())
954 AllowOverwrite =
true;
957 if (!AppendBitField(*Field, Layout.
getFieldOffset(FieldNo) + OffsetBits,
958 EltInit, AllowOverwrite))
962 if (ZeroInitPadding && !DoZeroInitPadding(Layout, AllowOverwrite, SizeSoFar))
968bool ConstStructBuilder::DoZeroInitPadding(
969 const ASTRecordLayout &Layout,
unsigned FieldNo,
const FieldDecl &Field,
970 bool AllowOverwrite, CharUnits &SizeSoFar,
bool &ZeroFieldSize) {
973 if (SizeSoFar < StartOffset)
974 if (!AppendBytes(SizeSoFar, getPadding(CGM, StartOffset - SizeSoFar),
978 if (!
Field.isBitField()) {
980 SizeSoFar = StartOffset + FieldSize;
981 ZeroFieldSize = FieldSize.isZero();
983 const CGRecordLayout &RL =
991 ZeroFieldSize = Info.
Size == 0;
996bool ConstStructBuilder::DoZeroInitPadding(
const ASTRecordLayout &Layout,
998 CharUnits SizeSoFar) {
999 CharUnits TotalSize = Layout.
getSize();
1000 if (SizeSoFar < TotalSize)
1001 if (!AppendBytes(SizeSoFar, getPadding(CGM, TotalSize - SizeSoFar),
1004 SizeSoFar = TotalSize;
1008llvm::Constant *ConstStructBuilder::Finalize(QualType
Type) {
1010 auto *RD =
Type->castAsRecordDecl();
1015llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
1016 const InitListExpr *ILE,
1018 ConstantAggregateBuilder
Const(Emitter.
CGM);
1021 if (!Builder.Build(ILE,
false))
1024 return Builder.Finalize(ValTy);
1027llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
1030 ConstantAggregateBuilder
Const(Emitter.
CGM);
1034 const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD);
1038 return Builder.Finalize(ValTy);
1041bool ConstStructBuilder::UpdateStruct(ConstantEmitter &Emitter,
1042 ConstantAggregateBuilder &Const,
1044 const InitListExpr *Updater) {
1045 return ConstStructBuilder(Emitter, Const, Offset)
1046 .Build(Updater,
true);
1053static ConstantAddress
1055 const CompoundLiteralExpr *E) {
1056 CodeGenModule &CGM = emitter.
CGM;
1058 if (llvm::GlobalVariable *
Addr =
1060 return ConstantAddress(
Addr,
Addr->getValueType(), Align);
1067 "file-scope compound literal did not have constant initializer!");
1071 auto GV =
new llvm::GlobalVariable(
1074 llvm::GlobalValue::InternalLinkage,
C,
".compoundliteral",
nullptr,
1075 llvm::GlobalVariable::NotThreadLocal,
1080 return ConstantAddress(GV, GV->getValueType(), Align);
1083static llvm::Constant *
1084EmitArrayConstant(CodeGenModule &CGM, llvm::ArrayType *DesiredType,
1085 llvm::Type *CommonElementType, uint64_t
ArrayBound,
1086 SmallVectorImpl<llvm::Constant *> &Elements,
1087 llvm::Constant *Filler) {
1090 if (Elements.size() < NonzeroLength && Filler->isNullValue())
1091 NonzeroLength = Elements.size();
1092 if (NonzeroLength == Elements.size()) {
1093 while (NonzeroLength > 0 && Elements[NonzeroLength - 1]->isNullValue())
1097 if (NonzeroLength == 0)
1098 return llvm::ConstantAggregateZero::get(DesiredType);
1102 if (TrailingZeroes >= 8) {
1103 assert(Elements.size() >= NonzeroLength &&
1104 "missing initializer for non-zero element");
1108 if (CommonElementType && NonzeroLength >= 8) {
1109 llvm::Constant *Initial = llvm::ConstantArray::get(
1110 llvm::ArrayType::get(CommonElementType, NonzeroLength),
1111 ArrayRef(Elements).take_front(NonzeroLength));
1113 Elements[0] = Initial;
1115 Elements.resize(NonzeroLength + 1);
1119 CommonElementType ? CommonElementType : DesiredType->getElementType();
1120 FillerType = llvm::ArrayType::get(FillerType, TrailingZeroes);
1121 Elements.back() = llvm::ConstantAggregateZero::get(FillerType);
1122 CommonElementType =
nullptr;
1126 if (Filler->getType() != CommonElementType)
1127 CommonElementType =
nullptr;
1131 if (CommonElementType)
1132 return llvm::ConstantArray::get(
1133 llvm::ArrayType::get(CommonElementType,
ArrayBound), Elements);
1136 llvm::SmallVector<llvm::Type *, 16> Types;
1137 Types.reserve(Elements.size());
1138 for (llvm::Constant *Elt : Elements)
1139 Types.push_back(Elt->getType());
1140 llvm::StructType *SType =
1142 return llvm::ConstantStruct::get(SType, Elements);
1151class ConstExprEmitter
1152 :
public ConstStmtVisitor<ConstExprEmitter, llvm::Constant *, QualType> {
1154 ConstantEmitter &Emitter;
1155 llvm::LLVMContext &VMContext;
1157 ConstExprEmitter(ConstantEmitter &emitter)
1158 : CGM(emitter.CGM), Emitter(emitter), VMContext(CGM.getLLVMContext()) {
1165 llvm::Constant *VisitStmt(
const Stmt *S, QualType T) {
return nullptr; }
1167 llvm::Constant *VisitConstantExpr(
const ConstantExpr *CE, QualType T) {
1173 llvm::Constant *VisitParenExpr(
const ParenExpr *PE, QualType T) {
1178 VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *PE,
1183 llvm::Constant *VisitGenericSelectionExpr(
const GenericSelectionExpr *GE,
1185 return Visit(
GE->getResultExpr(), T);
1188 llvm::Constant *VisitChooseExpr(
const ChooseExpr *CE, QualType T) {
1192 llvm::Constant *VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E,
1197 llvm::Constant *ProduceIntToIntCast(
const Expr *E, QualType DestType) {
1198 QualType FromType = E->
getType();
1201 if (llvm::Constant *
C = Visit(E, FromType))
1202 if (
auto *CI = dyn_cast<llvm::ConstantInt>(
C)) {
1205 if (DstWidth == SrcWidth)
1208 ? CI->getValue().sextOrTrunc(DstWidth)
1209 : CI->getValue().zextOrTrunc(DstWidth);
1215 llvm::Constant *VisitCastExpr(
const CastExpr *E, QualType destType) {
1216 if (
const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
1224 "Destination type is not union type!");
1229 if (!
C)
return nullptr;
1231 auto destTy = ConvertType(destType);
1232 if (
C->getType() == destTy)
return C;
1236 SmallVector<llvm::Constant*, 2> Elts;
1237 SmallVector<llvm::Type*, 2> Types;
1239 Types.push_back(
C->getType());
1240 unsigned CurSize = CGM.
getDataLayout().getTypeAllocSize(
C->getType());
1241 unsigned TotalSize = CGM.
getDataLayout().getTypeAllocSize(destTy);
1243 assert(CurSize <= TotalSize &&
"Union size mismatch!");
1244 if (
unsigned NumPadBytes = TotalSize - CurSize) {
1245 llvm::Constant *Padding =
1247 Elts.push_back(Padding);
1248 Types.push_back(Padding->getType());
1251 llvm::StructType *STy = llvm::StructType::get(VMContext, Types,
false);
1252 return llvm::ConstantStruct::get(STy, Elts);
1255 case CK_AddressSpaceConversion: {
1259 llvm::Type *destTy = ConvertType(E->
getType());
1263 case CK_LValueToRValue: {
1269 dyn_cast<CompoundLiteralExpr>(subExpr->
IgnoreParens()))
1270 return Visit(E->getInitializer(), destType);
1274 case CK_AtomicToNonAtomic:
1275 case CK_NonAtomicToAtomic:
1277 case CK_ConstructorConversion:
1278 return Visit(subExpr, destType);
1280 case CK_ArrayToPointerDecay:
1281 if (
const auto *S = dyn_cast<StringLiteral>(subExpr))
1284 case CK_NullToPointer:
1285 if (Visit(subExpr, destType))
1289 case CK_IntToOCLSampler:
1290 llvm_unreachable(
"global sampler variables are not generated");
1292 case CK_IntegralCast:
1293 return ProduceIntToIntCast(subExpr, destType);
1295 case CK_Dependent: llvm_unreachable(
"saw dependent cast!");
1297 case CK_BuiltinFnToFnPtr:
1298 llvm_unreachable(
"builtin functions are handled elsewhere");
1300 case CK_ReinterpretMemberPointer:
1301 case CK_DerivedToBaseMemberPointer:
1302 case CK_BaseToDerivedMemberPointer: {
1304 if (!
C)
return nullptr;
1309 case CK_ObjCObjectLValueCast:
1310 case CK_ARCProduceObject:
1311 case CK_ARCConsumeObject:
1312 case CK_ARCReclaimReturnedObject:
1313 case CK_ARCExtendBlockObject:
1314 case CK_CopyAndAutoreleaseBlockObject:
1322 case CK_LValueBitCast:
1323 case CK_LValueToRValueBitCast:
1324 case CK_NullToMemberPointer:
1325 case CK_UserDefinedConversion:
1326 case CK_CPointerToObjCPointerCast:
1327 case CK_BlockPointerToObjCPointerCast:
1328 case CK_AnyPointerToBlockPointerCast:
1329 case CK_FunctionToPointerDecay:
1330 case CK_BaseToDerived:
1331 case CK_DerivedToBase:
1332 case CK_UncheckedDerivedToBase:
1333 case CK_MemberPointerToBoolean:
1334 case CK_VectorSplat:
1335 case CK_FloatingRealToComplex:
1336 case CK_FloatingComplexToReal:
1337 case CK_FloatingComplexToBoolean:
1338 case CK_FloatingComplexCast:
1339 case CK_FloatingComplexToIntegralComplex:
1340 case CK_IntegralRealToComplex:
1341 case CK_IntegralComplexToReal:
1342 case CK_IntegralComplexToBoolean:
1343 case CK_IntegralComplexCast:
1344 case CK_IntegralComplexToFloatingComplex:
1345 case CK_PointerToIntegral:
1346 case CK_PointerToBoolean:
1347 case CK_BooleanToSignedIntegral:
1348 case CK_IntegralToPointer:
1349 case CK_IntegralToBoolean:
1350 case CK_IntegralToFloating:
1351 case CK_FloatingToIntegral:
1352 case CK_FloatingToBoolean:
1353 case CK_FloatingCast:
1354 case CK_FloatingToFixedPoint:
1355 case CK_FixedPointToFloating:
1356 case CK_FixedPointCast:
1357 case CK_FixedPointToBoolean:
1358 case CK_FixedPointToIntegral:
1359 case CK_IntegralToFixedPoint:
1360 case CK_ZeroToOCLOpaqueType:
1362 case CK_HLSLVectorTruncation:
1363 case CK_HLSLMatrixTruncation:
1364 case CK_HLSLArrayRValue:
1365 case CK_HLSLElementwiseCast:
1366 case CK_HLSLAggregateSplatCast:
1369 llvm_unreachable(
"Invalid CastKind");
1372 llvm::Constant *VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *DIE,
1376 return Visit(DIE->
getExpr(), T);
1379 llvm::Constant *VisitExprWithCleanups(
const ExprWithCleanups *E, QualType T) {
1383 llvm::Constant *VisitIntegerLiteral(
const IntegerLiteral *I, QualType T) {
1387 static APValue withDestType(ASTContext &Ctx,
const Expr *E, QualType SrcType,
1388 QualType DestType,
const llvm::APSInt &
Value) {
1393 llvm::RoundingMode RM =
1395 if (RM == llvm::RoundingMode::Dynamic)
1396 RM = llvm::RoundingMode::NearestTiesToEven;
1404 llvm::Constant *EmitArrayInitialization(
const InitListExpr *ILE, QualType T) {
1406 assert(CAT &&
"can't emit array init for non-constant-bound array");
1408 const uint64_t NumElements = CAT->getZExtSize();
1410 if (
const auto *Embed =
1411 dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1412 NumInitElements += Embed->getDataElementCount() - 1;
1413 if (NumInitElements > NumElements) {
1414 NumInitElements = NumElements;
1422 uint64_t NumInitableElts = std::min<uint64_t>(NumInitElements, NumElements);
1424 QualType EltType = CAT->getElementType();
1427 llvm::Constant *fillC =
nullptr;
1435 SmallVector<llvm::Constant *, 16> Elts;
1436 if (fillC && fillC->isNullValue())
1437 Elts.reserve(NumInitableElts + 1);
1439 Elts.reserve(NumElements);
1441 llvm::Type *CommonElementType =
nullptr;
1442 auto Emit = [&](
const Expr *
Init,
unsigned ArrayIndex) {
1443 llvm::Constant *
C =
nullptr;
1447 if (ArrayIndex == 0)
1448 CommonElementType =
C->getType();
1449 else if (
C->getType() != CommonElementType)
1450 CommonElementType =
nullptr;
1455 unsigned ArrayIndex = 0;
1456 QualType DestTy = CAT->getElementType();
1457 for (
unsigned i = 0; i < ILE->
getNumInits(); ++i) {
1459 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1460 StringLiteral *SL = EmbedS->getDataStringLiteral();
1464 for (
unsigned I = EmbedS->getStartingElementPos(),
1465 N = EmbedS->getDataElementCount();
1466 I != EmbedS->getStartingElementPos() + N; ++I) {
1481 if ((ArrayIndex - EmbedS->getDataElementCount()) == 0)
1482 CommonElementType =
C->getType();
1483 else if (
C->getType() != CommonElementType)
1484 CommonElementType =
nullptr;
1486 if (!Emit(
Init, ArrayIndex))
1492 llvm::ArrayType *Desired =
1494 return EmitArrayConstant(CGM, Desired, CommonElementType, NumElements, Elts,
1498 llvm::Constant *EmitRecordInitialization(
const InitListExpr *ILE,
1500 return ConstStructBuilder::BuildStruct(Emitter, ILE, T);
1503 llvm::Constant *VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E,
1508 llvm::Constant *VisitInitListExpr(
const InitListExpr *ILE, QualType T) {
1510 return Visit(ILE->
getInit(0), T);
1513 return EmitArrayInitialization(ILE, T);
1516 return EmitRecordInitialization(ILE, T);
1522 VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E,
1523 QualType destType) {
1524 auto C = Visit(E->
getBase(), destType);
1528 ConstantAggregateBuilder
Const(CGM);
1531 if (!EmitDesignatedInitUpdater(Emitter, Const,
CharUnits::Zero(), destType,
1536 bool HasFlexibleArray =
false;
1539 return Const.build(ValTy, HasFlexibleArray);
1542 llvm::Constant *VisitCXXConstructExpr(
const CXXConstructExpr *E,
1549 assert(E->
getNumArgs() == 1 &&
"trivial ctor with > 1 argument");
1551 "trivial ctor has argument but isn't a copy/move ctor");
1553 const Expr *Arg = E->
getArg(0);
1555 "argument to copy ctor is of wrong type");
1559 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(Arg))
1560 return Visit(MTE->getSubExpr(), Ty);
1568 llvm::Constant *VisitStringLiteral(
const StringLiteral *E, QualType T) {
1573 llvm::Constant *VisitObjCEncodeExpr(
const ObjCEncodeExpr *E, QualType T) {
1580 assert(CAT &&
"String data not of constant array type!");
1585 return llvm::ConstantDataArray::getString(VMContext, Str,
false);
1588 llvm::Constant *VisitUnaryExtension(
const UnaryOperator *E, QualType T) {
1592 llvm::Constant *VisitUnaryMinus(
const UnaryOperator *U, QualType T) {
1593 if (llvm::Constant *
C = Visit(U->
getSubExpr(), T))
1594 if (
auto *CI = dyn_cast<llvm::ConstantInt>(
C))
1595 return llvm::ConstantInt::get(CGM.
getLLVMContext(), -CI->getValue());
1599 llvm::Constant *VisitPackIndexingExpr(
const PackIndexingExpr *E, QualType T) {
1604 llvm::Type *ConvertType(QualType T) {
1611llvm::Constant *ConstantEmitter::validateAndPopAbstract(llvm::Constant *
C,
1612 AbstractState saved) {
1613 Abstract = saved.OldValue;
1615 assert(saved.OldPlaceholdersSize == PlaceholderAddresses.size() &&
1616 "created a placeholder while doing an abstract emission?");
1625 auto state = pushAbstract();
1627 return validateAndPopAbstract(
C, state);
1632 auto state = pushAbstract();
1634 return validateAndPopAbstract(
C, state);
1639 auto state = pushAbstract();
1641 return validateAndPopAbstract(
C, state);
1650 RetType =
CGM.getContext().getLValueReferenceType(RetType);
1657 auto state = pushAbstract();
1659 C = validateAndPopAbstract(
C, state);
1662 "internal error: could not emit constant value \"abstractly\"");
1663 C =
CGM.EmitNullConstant(destType);
1671 bool EnablePtrAuthFunctionTypeDiscrimination) {
1672 auto state = pushAbstract();
1674 tryEmitPrivate(value, destType, EnablePtrAuthFunctionTypeDiscrimination);
1675 C = validateAndPopAbstract(
C, state);
1678 "internal error: could not emit constant value \"abstractly\"");
1679 C =
CGM.EmitNullConstant(destType);
1693 for (
auto [_, GV] : PlaceholderAddresses)
1694 GV->eraseFromParent();
1695 PlaceholderAddresses.clear();
1699 return markIfFailed(
Init);
1705 initializeNonAbstract(destAddrSpace);
1712 initializeNonAbstract(destAddrSpace);
1714 assert(
C &&
"couldn't emit constant value non-abstractly?");
1719 assert(!Abstract &&
"cannot get current address for abstract constant");
1725 auto global =
new llvm::GlobalVariable(
CGM.getModule(),
CGM.Int8Ty,
true,
1726 llvm::GlobalValue::PrivateLinkage,
1730 llvm::GlobalVariable::NotThreadLocal,
1731 CGM.getContext().getTargetAddressSpace(DestAddressSpace));
1733 PlaceholderAddresses.push_back(std::make_pair(
nullptr, global));
1739 llvm::GlobalValue *placeholder) {
1740 assert(!PlaceholderAddresses.empty());
1741 assert(PlaceholderAddresses.back().first ==
nullptr);
1742 assert(PlaceholderAddresses.back().second == placeholder);
1743 PlaceholderAddresses.back().first = signal;
1747 struct ReplacePlaceholders {
1751 llvm::Constant *
Base;
1752 llvm::Type *BaseValueTy =
nullptr;
1755 llvm::DenseMap<llvm::Constant*, llvm::GlobalVariable*> PlaceholderAddresses;
1758 llvm::DenseMap<llvm::GlobalVariable*, llvm::Constant*> Locations;
1766 ReplacePlaceholders(
CodeGenModule &CGM, llvm::Constant *base,
1767 ArrayRef<std::pair<llvm::Constant*,
1768 llvm::GlobalVariable*>> addresses)
1769 : CGM(CGM),
Base(base),
1770 PlaceholderAddresses(addresses.begin(), addresses.end()) {
1773 void replaceInInitializer(llvm::Constant *init) {
1775 BaseValueTy = init->getType();
1778 Indices.push_back(0);
1779 IndexValues.push_back(
nullptr);
1782 findLocations(init);
1785 assert(IndexValues.size() == Indices.size() &&
"mismatch");
1786 assert(Indices.size() == 1 &&
"didn't pop all indices");
1789 assert(Locations.size() == PlaceholderAddresses.size() &&
1790 "missed a placeholder?");
1796 for (
auto &entry : Locations) {
1797 assert(entry.first->getName() ==
"" &&
"not a placeholder!");
1798 entry.first->replaceAllUsesWith(entry.second);
1799 entry.first->eraseFromParent();
1804 void findLocations(llvm::Constant *init) {
1806 if (
auto agg = dyn_cast<llvm::ConstantAggregate>(init)) {
1807 for (
unsigned i = 0, e = agg->getNumOperands(); i != e; ++i) {
1808 Indices.push_back(i);
1809 IndexValues.push_back(
nullptr);
1811 findLocations(agg->getOperand(i));
1813 IndexValues.pop_back();
1821 auto it = PlaceholderAddresses.find(init);
1822 if (it != PlaceholderAddresses.end()) {
1823 setLocation(it->second);
1828 if (
auto expr = dyn_cast<llvm::ConstantExpr>(init)) {
1829 init =
expr->getOperand(0);
1836 void setLocation(llvm::GlobalVariable *placeholder) {
1837 assert(!Locations.contains(placeholder) &&
1838 "already found location for placeholder!");
1843 assert(Indices.size() == IndexValues.size());
1844 for (
size_t i = Indices.size() - 1; i !=
size_t(-1); --i) {
1845 if (IndexValues[i]) {
1847 for (
size_t j = 0; j != i + 1; ++j) {
1848 assert(IndexValues[j] &&
1857 IndexValues[i] = llvm::ConstantInt::get(CGM.
Int32Ty, Indices[i]);
1860 llvm::Constant *location = llvm::ConstantExpr::getInBoundsGetElementPtr(
1861 BaseValueTy, Base, IndexValues);
1863 Locations.insert({placeholder, location});
1869 assert(InitializedNonAbstract &&
1870 "finalizing emitter that was used for abstract emission?");
1871 assert(!Finalized &&
"finalizing emitter multiple times");
1872 assert(global->getInitializer());
1877 if (!PlaceholderAddresses.empty()) {
1878 ReplacePlaceholders(
CGM, global, PlaceholderAddresses)
1879 .replaceInInitializer(global->getInitializer());
1880 PlaceholderAddresses.clear();
1885 assert((!InitializedNonAbstract || Finalized || Failed) &&
1886 "not finalized after being initialized for non-abstract emission");
1887 assert(PlaceholderAddresses.empty() &&
"unhandled placeholders");
1893 type.getQualifiers());
1906 dyn_cast_or_null<CXXConstructExpr>(D.
getInit())) {
1916 assert(E &&
"No initializer to emit");
1920 if (llvm::Constant *
C = ConstExprEmitter(*this).Visit(E, nonMemoryDestType))
1927 assert(!value->allowConstexprUnknown() &&
1928 "Constexpr unknown values are not allowed in CodeGen");
1972 assert(Schema &&
"applying trivial ptrauth schema");
1975 return UnsignedPointer;
1977 unsigned Key = Schema.
getKey();
1980 llvm::GlobalValue *StorageAddress =
nullptr;
1989 llvm::ConstantInt *Discriminator =
1992 llvm::Constant *SignedPointer =
CGM.getConstantSignedPointer(
1993 UnsignedPointer, Key, StorageAddress, Discriminator);
1998 return SignedPointer;
2006 QualType destValueType = AT->getValueType();
2009 uint64_t innerSize =
CGM.getContext().getTypeSize(destValueType);
2010 uint64_t outerSize =
CGM.getContext().getTypeSize(destType);
2011 if (innerSize == outerSize)
2014 assert(innerSize < outerSize &&
"emitted over-large constant for atomic");
2015 llvm::Constant *elts[] = {
2017 llvm::ConstantAggregateZero::get(
2018 llvm::ArrayType::get(
CGM.Int8Ty, (outerSize - innerSize) / 8))
2020 return llvm::ConstantStruct::getAnon(elts);
2025 if ((
C->getType()->isIntegerTy(1) && !destType->
isBitIntType()) ||
2028 llvm::Type *boolTy =
CGM.getTypes().ConvertTypeForMem(destType);
2029 llvm::Constant *Res = llvm::ConstantFoldCastOperand(
2030 llvm::Instruction::ZExt,
C, boolTy,
CGM.getDataLayout());
2031 assert(Res &&
"Constant folding must succeed");
2036 llvm::Type *MemTy =
CGM.getTypes().ConvertTypeForMem(destType);
2037 if (
C->getType() != MemTy) {
2038 ConstantAggregateBuilder Builder(
CGM);
2039 llvm::Type *LoadStoreTy =
2040 CGM.getTypes().convertTypeForLoadStore(destType);
2044 llvm::Constant *Res = llvm::ConstantFoldCastOperand(
2046 ? llvm::Instruction::SExt
2047 : llvm::Instruction::ZExt,
2048 CI, LoadStoreTy,
CGM.getDataLayout());
2049 if (
CGM.getTypes().typeRequiresSplitIntoByteArray(destType,
2054 Builder.addBits(
Value, 0,
false);
2055 return Builder.build(MemTy,
false);
2066 assert(!destType->
isVoidType() &&
"can't emit a void constant");
2069 if (llvm::Constant *
C = ConstExprEmitter(*this).Visit(E, destType))
2094struct ConstantLValue {
2095 llvm::Constant *
Value;
2096 bool HasOffsetApplied;
2097 bool HasDestPointerAuth;
2099 ConstantLValue(llvm::Constant *value,
2100 bool hasOffsetApplied =
false,
2101 bool hasDestPointerAuth =
false)
2102 :
Value(value), HasOffsetApplied(hasOffsetApplied),
2103 HasDestPointerAuth(hasDestPointerAuth) {}
2106 : ConstantLValue(address.getPointer()) {}
2110class ConstantLValueEmitter :
public ConstStmtVisitor<ConstantLValueEmitter,
2113 ConstantEmitter &Emitter;
2116 bool EnablePtrAuthFunctionTypeDiscrimination;
2119 friend StmtVisitorBase;
2122 ConstantLValueEmitter(ConstantEmitter &emitter,
const APValue &value,
2124 bool EnablePtrAuthFunctionTypeDiscrimination =
true)
2125 : CGM(emitter.CGM), Emitter(emitter),
Value(value), DestType(destType),
2126 EnablePtrAuthFunctionTypeDiscrimination(
2127 EnablePtrAuthFunctionTypeDiscrimination) {}
2129 llvm::Constant *tryEmit();
2132 llvm::Constant *tryEmitAbsolute(llvm::Type *destTy);
2133 ConstantLValue tryEmitBase(
const APValue::LValueBase &base);
2135 ConstantLValue VisitStmt(
const Stmt *S) {
return nullptr; }
2136 ConstantLValue VisitConstantExpr(
const ConstantExpr *E);
2137 ConstantLValue VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
2138 ConstantLValue VisitStringLiteral(
const StringLiteral *E);
2139 ConstantLValue VisitObjCBoxedExpr(
const ObjCBoxedExpr *E);
2140 ConstantLValue VisitObjCEncodeExpr(
const ObjCEncodeExpr *E);
2141 ConstantLValue VisitObjCStringLiteral(
const ObjCStringLiteral *E);
2142 llvm::Constant *VisitObjCCollectionElement(
const Expr *E);
2143 ConstantLValue VisitObjCArrayLiteral(
const ObjCArrayLiteral *E);
2144 ConstantLValue VisitObjCDictionaryLiteral(
const ObjCDictionaryLiteral *E);
2145 ConstantLValue VisitPredefinedExpr(
const PredefinedExpr *E);
2146 ConstantLValue VisitAddrLabelExpr(
const AddrLabelExpr *E);
2147 ConstantLValue VisitCallExpr(
const CallExpr *E);
2148 ConstantLValue VisitBlockExpr(
const BlockExpr *E);
2149 ConstantLValue VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
2150 ConstantLValue VisitMaterializeTemporaryExpr(
2151 const MaterializeTemporaryExpr *E);
2153 ConstantLValue emitPointerAuthSignConstant(
const CallExpr *E);
2154 llvm::Constant *emitPointerAuthPointer(
const Expr *E);
2155 unsigned emitPointerAuthKey(
const Expr *E);
2156 std::pair<llvm::Constant *, llvm::ConstantInt *>
2157 emitPointerAuthDiscriminator(
const Expr *E);
2159 bool hasNonZeroOffset()
const {
2160 return !
Value.getLValueOffset().isZero();
2164 llvm::Constant *getOffset() {
2165 return llvm::ConstantInt::get(CGM.
Int64Ty,
2166 Value.getLValueOffset().getQuantity());
2170 llvm::Constant *applyOffset(llvm::Constant *
C) {
2171 if (!hasNonZeroOffset())
2174 return llvm::ConstantExpr::getPtrAdd(
C, getOffset());
2180llvm::Constant *ConstantLValueEmitter::tryEmit() {
2181 const APValue::LValueBase &base =
Value.getLValueBase();
2196 return tryEmitAbsolute(destTy);
2200 ConstantLValue result = tryEmitBase(base);
2203 llvm::Constant *value = result.Value;
2204 if (!value)
return nullptr;
2207 if (!result.HasOffsetApplied) {
2208 value = applyOffset(value);
2212 if (PointerAuthQualifier PointerAuth = DestType.
getPointerAuth();
2213 PointerAuth && !result.HasDestPointerAuth) {
2222 return llvm::ConstantExpr::getPointerCast(value, destTy);
2224 return llvm::ConstantExpr::getPtrToInt(value, destTy);
2230ConstantLValueEmitter::tryEmitAbsolute(llvm::Type *destTy) {
2233 if (
Value.isNullPointer()) {
2241 auto intptrTy = CGM.
getDataLayout().getIntPtrType(destPtrTy);
2243 C = llvm::ConstantFoldIntegerCast(getOffset(), intptrTy,
false,
2245 assert(
C &&
"Must have folded, as Offset is a ConstantInt");
2246 C = llvm::ConstantExpr::getIntToPtr(
C, destPtrTy);
2251ConstantLValueEmitter::tryEmitBase(
const APValue::LValueBase &base) {
2253 if (
const ValueDecl *D = base.
dyn_cast<
const ValueDecl*>()) {
2258 if (D->hasAttr<WeakRefAttr>())
2261 auto PtrAuthSign = [&](llvm::Constant *
C) {
2262 if (PointerAuthQualifier PointerAuth = DestType.
getPointerAuth()) {
2265 return ConstantLValue(
C,
true,
true);
2268 CGPointerAuthInfo AuthInfo;
2270 if (EnablePtrAuthFunctionTypeDiscrimination)
2274 if (hasNonZeroOffset())
2275 return ConstantLValue(
nullptr);
2279 C, AuthInfo.
getKey(),
nullptr,
2281 return ConstantLValue(
C,
true,
true);
2284 return ConstantLValue(
C);
2287 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
2289 if (FD->getType()->isCFIUncheckedCalleeFunctionType())
2291 return PtrAuthSign(
C);
2294 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
2296 if (!VD->hasLocalStorage()) {
2297 if (VD->isFileVarDecl() || VD->hasExternalStorage())
2300 if (VD->isLocalVarDecl()) {
2307 if (
const auto *GD = dyn_cast<MSGuidDecl>(D))
2310 if (
const auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D))
2313 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D))
2320 if (TypeInfoLValue TI = base.
dyn_cast<TypeInfoLValue>())
2324 return Visit(base.
get<
const Expr*>());
2328ConstantLValueEmitter::VisitConstantExpr(
const ConstantExpr *E) {
2335ConstantLValueEmitter::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
2336 ConstantEmitter CompoundLiteralEmitter(CGM, Emitter.
CGF);
2342ConstantLValueEmitter::VisitStringLiteral(
const StringLiteral *E) {
2347ConstantLValueEmitter::VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
2359ConstantLValueEmitter::VisitObjCStringLiteral(
const ObjCStringLiteral *E) {
2364ConstantLValueEmitter::VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
2371 "Non const NSNumber is being emitted as a constant");
2378 const bool IsBoolType =
2380 bool BoolValue =
false;
2386 Expr::EvalResult IntResult{};
2393 llvm::APFloat FloatValue(0.0);
2399 llvm_unreachable(
"SubExpr is expected to be evaluated as a numeric type");
2403ConstantLValueEmitter::VisitObjCCollectionElement(
const Expr *E) {
2406 QualType DestTy = CE->
getType();
2408 assert(CE->getCastKind() == CK_BitCast &&
2409 "Expected a CK_BitCast type for valid items in constant objc "
2410 "collection literals");
2413 ConstantLValue LV = Visit(Elm);
2415 llvm::Constant *Val = llvm::ConstantExpr::getBitCast(ConstVal, DstTy);
2420ConstantLValueEmitter::VisitObjCArrayLiteral(
const ObjCArrayLiteral *E) {
2421 SmallVector<llvm::Constant *, 16> ObjectExpressions;
2423 ObjectExpressions.reserve(NumElements);
2425 for (uint64_t i = 0; i < NumElements; i++) {
2426 llvm::Constant *Val = VisitObjCCollectionElement(E->
getElement(i));
2427 ObjectExpressions.push_back(Val);
2434ConstantLValue ConstantLValueEmitter::VisitObjCDictionaryLiteral(
2435 const ObjCDictionaryLiteral *E) {
2436 SmallVector<std::pair<llvm::Constant *, llvm::Constant *>, 16> KeysAndObjects;
2438 KeysAndObjects.reserve(NumElements);
2440 for (uint64_t i = 0; i < NumElements; i++) {
2441 llvm::Constant *Key =
2443 llvm::Constant *Val =
2445 KeysAndObjects.push_back({Key, Val});
2453ConstantLValueEmitter::VisitPredefinedExpr(
const PredefinedExpr *E) {
2458ConstantLValueEmitter::VisitAddrLabelExpr(
const AddrLabelExpr *E) {
2459 assert(Emitter.
CGF &&
"Invalid address of label expression outside function");
2465ConstantLValueEmitter::VisitCallExpr(
const CallExpr *E) {
2467 if (builtin == Builtin::BI__builtin_function_start)
2471 if (builtin == Builtin::BI__builtin_ptrauth_sign_constant)
2472 return emitPointerAuthSignConstant(E);
2474 if (builtin != Builtin::BI__builtin___CFStringMakeConstantString &&
2475 builtin != Builtin::BI__builtin___NSStringMakeConstantString)
2479 if (builtin == Builtin::BI__builtin___NSStringMakeConstantString) {
2488ConstantLValueEmitter::emitPointerAuthSignConstant(
const CallExpr *E) {
2489 llvm::Constant *UnsignedPointer = emitPointerAuthPointer(E->
getArg(0));
2490 unsigned Key = emitPointerAuthKey(E->
getArg(1));
2491 auto [StorageAddress, OtherDiscriminator] =
2492 emitPointerAuthDiscriminator(E->
getArg(2));
2495 UnsignedPointer, Key, StorageAddress, OtherDiscriminator);
2496 return SignedPointer;
2499llvm::Constant *ConstantLValueEmitter::emitPointerAuthPointer(
const Expr *E) {
2506 assert(
Result.Val.isLValue());
2508 assert(
Result.Val.getLValueOffset().isZero());
2509 return ConstantEmitter(CGM, Emitter.
CGF)
2513unsigned ConstantLValueEmitter::emitPointerAuthKey(
const Expr *E) {
2517std::pair<llvm::Constant *, llvm::ConstantInt *>
2518ConstantLValueEmitter::emitPointerAuthDiscriminator(
const Expr *E) {
2521 if (
const auto *
Call = dyn_cast<CallExpr>(E)) {
2522 if (
Call->getBuiltinCallee() ==
2523 Builtin::BI__builtin_ptrauth_blend_discriminator) {
2524 llvm::Constant *
Pointer = ConstantEmitter(CGM).emitAbstract(
2525 Call->getArg(0),
Call->getArg(0)->getType());
2527 Call->getArg(1),
Call->getArg(1)->getType()));
2532 llvm::Constant *
Result = ConstantEmitter(CGM).emitAbstract(E, E->
getType());
2533 if (
Result->getType()->isPointerTy())
2534 return {
Result,
nullptr};
2539ConstantLValueEmitter::VisitBlockExpr(
const BlockExpr *E) {
2540 StringRef functionName;
2541 if (
auto CGF = Emitter.
CGF)
2542 functionName = CGF->CurFn->getName();
2544 functionName =
"global";
2550ConstantLValueEmitter::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
2560ConstantLValueEmitter::VisitMaterializeTemporaryExpr(
2561 const MaterializeTemporaryExpr *E) {
2569 bool EnablePtrAuthFunctionTypeDiscrimination) {
2574 return llvm::UndefValue::get(
CGM.getTypes().ConvertType(DestType));
2576 return ConstantLValueEmitter(*
this,
Value, DestType,
2577 EnablePtrAuthFunctionTypeDiscrimination)
2582 (PointerAuth.authenticatesNullValues() ||
Value.getInt() != 0))
2584 return llvm::ConstantInt::get(
CGM.getLLVMContext(),
Value.getInt());
2586 return llvm::ConstantInt::get(
CGM.getLLVMContext(),
2587 Value.getFixedPoint().getValue());
2591 Complex[0] = llvm::ConstantInt::get(
CGM.getLLVMContext(),
2592 Value.getComplexIntReal());
2593 Complex[1] = llvm::ConstantInt::get(
CGM.getLLVMContext(),
2594 Value.getComplexIntImag());
2597 llvm::StructType *STy =
2599 return llvm::ConstantStruct::get(STy,
Complex);
2602 const llvm::APFloat &
Init =
Value.getFloat();
2603 if (&
Init.getSemantics() == &llvm::APFloat::IEEEhalf() &&
2604 !
CGM.getContext().getLangOpts().NativeHalfType &&
2605 CGM.getContext().getTargetInfo().useFP16ConversionIntrinsics())
2606 return llvm::ConstantInt::get(
CGM.getLLVMContext(),
2607 Init.bitcastToAPInt());
2609 return llvm::ConstantFP::get(
CGM.getLLVMContext(),
Init);
2614 Complex[0] = llvm::ConstantFP::get(
CGM.getLLVMContext(),
2615 Value.getComplexFloatReal());
2616 Complex[1] = llvm::ConstantFP::get(
CGM.getLLVMContext(),
2617 Value.getComplexFloatImag());
2620 llvm::StructType *STy =
2622 return llvm::ConstantStruct::get(STy,
Complex);
2625 unsigned NumElts =
Value.getVectorLength();
2628 for (
unsigned I = 0; I != NumElts; ++I) {
2631 Inits[I] = llvm::ConstantInt::get(
CGM.getLLVMContext(), Elt.
getInt());
2635 Inits[I] = llvm::UndefValue::get(
CGM.getTypes().ConvertType(
2638 llvm_unreachable(
"unsupported vector element type");
2640 return llvm::ConstantVector::get(
Inits);
2644 unsigned NumRows =
Value.getMatrixNumRows();
2645 unsigned NumCols =
Value.getMatrixNumColumns();
2646 unsigned NumElts = NumRows * NumCols;
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");
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.
static cir::GlobalViewAttr tryEmitGlobalCompoundLiteral(ConstantEmitter &emitter, const CompoundLiteralExpr *e)
Result
Implement __builtin_bit_cast and related operations.
llvm::MachO::Record Record
Defines AST-level helper utilities for matrix types.
llvm::APInt getValue() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
APValue & getStructField(unsigned i)
const FieldDecl * getUnionField() const
APValue & 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() const
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
A pointer to member type per C++ 8.3.3 - Pointers to members.
Expr * getElement(unsigned Index)
getElement - Return the Element at the specified index.
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c array literal.
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c dictionary literal.
ObjCDictionaryElement getKeyValueElement(unsigned Index) const
QualType getEncodedType() const
StringLiteral * getString()
Expr * getSelectedExpr() const
const Expr * getSubExpr() const
Pointer-authentication qualifiers.
bool isAddressDiscriminated() const
unsigned getExtraDiscriminator() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
StringLiteral * getFunctionName()
A (possibly-)qualified type.
PointerAuthQualifier getPointerAuth() const
LangAS getAddressSpace() const
Return the address space of this type.
bool isConstantStorage(const ASTContext &Ctx, bool ExcludeCtor, bool ExcludeDtor)
Represents a struct/union/class.
bool hasFlexibleArrayMember() const
field_iterator field_end() const
field_range fields() const
specific_decl_iterator< FieldDecl > field_iterator
field_iterator field_begin() const
Encodes a location in the source.
StringLiteral - This represents a string literal expression, e.g.
uint32_t getCodeUnit(size_t i) const
Expr * getReplacement() const
bool isBooleanType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isPackedVectorBoolType(const ASTContext &ctx) const
bool isIncompleteArrayType() const
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
CXXRecordDecl * castAsCXXRecordDecl() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isExtVectorBoolType() const
bool isBitIntType() const
RecordDecl * castAsRecordDecl() const
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
TLSKind getTLSKind() const
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 isMatrixRowMajor(const LangOptions &LangOpts, QualType T)
Returns true if matrices of T should be laid out in row-major order.
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
@ SD_Static
Static storage duration.
@ Result
The result type of a method or function.
@ 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.