27#include "llvm/ADT/STLExtras.h"
28#include "llvm/ADT/Sequence.h"
29#include "llvm/Analysis/ConstantFolding.h"
30#include "llvm/IR/Constants.h"
31#include "llvm/IR/DataLayout.h"
32#include "llvm/IR/Function.h"
33#include "llvm/IR/GlobalVariable.h"
43class ConstExprEmitter;
46 llvm::Type *Ty = CGM.
CharTy;
48 Ty = llvm::ArrayType::get(Ty, PadSize.
getQuantity());
50 return llvm::Constant::getNullValue(Ty);
52 return llvm::UndefValue::get(Ty);
55struct ConstantAggregateBuilderUtils {
58 ConstantAggregateBuilderUtils(CodeGenModule &CGM) : CGM(CGM) {}
60 CharUnits getAlignment(
const llvm::Constant *
C)
const {
65 CharUnits getSize(llvm::Type *Ty)
const {
69 CharUnits getSize(
const llvm::Constant *
C)
const {
70 return getSize(
C->getType());
73 llvm::Constant *getPadding(CharUnits PadSize)
const {
74 return ::getPadding(CGM, PadSize);
77 llvm::Constant *getZeroes(CharUnits ZeroSize)
const {
79 return llvm::ConstantAggregateZero::get(Ty);
85class ConstantAggregateBuilder :
private ConstantAggregateBuilderUtils {
94 llvm::SmallVector<llvm::Constant*, 32> Elems;
95 llvm::SmallVector<CharUnits, 32> Offsets;
104 bool NaturalLayout =
true;
106 bool split(
size_t Index, CharUnits Hint);
107 std::optional<size_t> splitAt(CharUnits Pos);
109 static llvm::Constant *buildFrom(CodeGenModule &CGM,
110 ArrayRef<llvm::Constant *> Elems,
111 ArrayRef<CharUnits> Offsets,
112 CharUnits StartOffset, CharUnits Size,
113 bool NaturalLayout, llvm::Type *DesiredTy,
114 bool AllowOversized);
117 ConstantAggregateBuilder(CodeGenModule &CGM)
118 : ConstantAggregateBuilderUtils(CGM) {}
125 bool add(llvm::Constant *
C, CharUnits Offset,
bool AllowOverwrite);
128 bool addBits(llvm::APInt Bits, uint64_t OffsetInBits,
bool AllowOverwrite);
132 void condense(CharUnits Offset, llvm::Type *DesiredTy);
139 llvm::Constant *build(llvm::Type *DesiredTy,
bool AllowOversized)
const {
141 NaturalLayout, DesiredTy, AllowOversized);
145template<
typename Container,
typename Range = std::initializer_list<
146 typename Container::value_type>>
147static void replace(Container &
C,
size_t BeginOff,
size_t EndOff, Range Vals) {
148 assert(BeginOff <= EndOff &&
"invalid replacement range");
149 llvm::replace(
C,
C.begin() + BeginOff,
C.begin() + EndOff, Vals);
152bool ConstantAggregateBuilder::add(llvm::Constant *
C,
CharUnits Offset,
153 bool AllowOverwrite) {
155 if (Offset >= Size) {
156 CharUnits Align = getAlignment(
C);
157 CharUnits AlignedSize =
Size.alignTo(Align);
158 if (AlignedSize > Offset || Offset.
alignTo(Align) != Offset)
159 NaturalLayout =
false;
160 else if (AlignedSize < Offset) {
161 Elems.push_back(getPadding(Offset - Size));
162 Offsets.push_back(Size);
165 Offsets.push_back(Offset);
166 Size = Offset + getSize(
C);
171 std::optional<size_t> FirstElemToReplace = splitAt(Offset);
172 if (!FirstElemToReplace)
175 CharUnits CSize = getSize(
C);
176 std::optional<size_t> LastElemToReplace = splitAt(Offset + CSize);
177 if (!LastElemToReplace)
180 assert((FirstElemToReplace == LastElemToReplace || AllowOverwrite) &&
181 "unexpectedly overwriting field");
183 replace(Elems, *FirstElemToReplace, *LastElemToReplace, {
C});
184 replace(Offsets, *FirstElemToReplace, *LastElemToReplace, {Offset});
185 Size = std::max(Size, Offset + CSize);
186 NaturalLayout =
false;
190bool ConstantAggregateBuilder::addBits(llvm::APInt Bits, uint64_t OffsetInBits,
191 bool AllowOverwrite) {
197 unsigned OffsetWithinChar = OffsetInBits % CharWidth;
201 for (CharUnits OffsetInChars =
205 unsigned WantedBits =
206 std::min((uint64_t)Bits.getBitWidth(), CharWidth - OffsetWithinChar);
210 llvm::APInt BitsThisChar = Bits;
211 if (BitsThisChar.getBitWidth() < CharWidth)
212 BitsThisChar = BitsThisChar.zext(CharWidth);
216 int Shift = Bits.getBitWidth() - CharWidth + OffsetWithinChar;
218 BitsThisChar.lshrInPlace(Shift);
220 BitsThisChar = BitsThisChar.shl(-Shift);
222 BitsThisChar = BitsThisChar.shl(OffsetWithinChar);
224 if (BitsThisChar.getBitWidth() > CharWidth)
225 BitsThisChar = BitsThisChar.trunc(CharWidth);
227 if (WantedBits == CharWidth) {
230 OffsetInChars, AllowOverwrite);
235 std::optional<size_t> FirstElemToUpdate = splitAt(OffsetInChars);
236 if (!FirstElemToUpdate)
238 std::optional<size_t> LastElemToUpdate =
240 if (!LastElemToUpdate)
242 assert(*LastElemToUpdate - *FirstElemToUpdate < 2 &&
243 "should have at most one element covering one byte");
246 llvm::APInt UpdateMask(CharWidth, 0);
248 UpdateMask.setBits(CharWidth - OffsetWithinChar - WantedBits,
249 CharWidth - OffsetWithinChar);
251 UpdateMask.setBits(OffsetWithinChar, OffsetWithinChar + WantedBits);
252 BitsThisChar &= UpdateMask;
254 if (*FirstElemToUpdate == *LastElemToUpdate ||
255 Elems[*FirstElemToUpdate]->isNullValue() ||
259 OffsetInChars,
true);
261 llvm::Constant *&ToUpdate = Elems[*FirstElemToUpdate];
264 auto *CI = dyn_cast<llvm::ConstantInt>(ToUpdate);
269 assert(CI->getBitWidth() == CharWidth &&
"splitAt failed");
270 assert((!(CI->getValue() & UpdateMask) || AllowOverwrite) &&
271 "unexpectedly overwriting bitfield");
272 BitsThisChar |= (CI->getValue() & ~UpdateMask);
273 ToUpdate = llvm::ConstantInt::get(CGM.
getLLVMContext(), BitsThisChar);
278 if (WantedBits == Bits.getBitWidth())
283 Bits.lshrInPlace(WantedBits);
284 Bits = Bits.trunc(Bits.getBitWidth() - WantedBits);
287 OffsetWithinChar = 0;
297std::optional<size_t> ConstantAggregateBuilder::splitAt(CharUnits Pos) {
299 return Offsets.size();
302 auto FirstAfterPos = llvm::upper_bound(Offsets, Pos);
303 if (FirstAfterPos == Offsets.begin())
307 size_t LastAtOrBeforePosIndex = FirstAfterPos - Offsets.begin() - 1;
308 if (Offsets[LastAtOrBeforePosIndex] == Pos)
309 return LastAtOrBeforePosIndex;
312 if (Offsets[LastAtOrBeforePosIndex] +
313 getSize(Elems[LastAtOrBeforePosIndex]) <= Pos)
314 return LastAtOrBeforePosIndex + 1;
317 if (!split(LastAtOrBeforePosIndex, Pos))
325bool ConstantAggregateBuilder::split(
size_t Index, CharUnits Hint) {
326 NaturalLayout =
false;
327 llvm::Constant *
C = Elems[Index];
328 CharUnits Offset = Offsets[Index];
330 if (
auto *CA = dyn_cast<llvm::ConstantAggregate>(
C)) {
333 replace(Elems, Index, Index + 1,
334 llvm::map_range(llvm::seq(0u, CA->getNumOperands()),
335 [&](
unsigned Op) { return CA->getOperand(Op); }));
340 llvm::GetElementPtrInst::getTypeAtIndex(CA->getType(), (uint64_t)0);
341 CharUnits ElemSize = getSize(ElemTy);
343 Offsets, Index, Index + 1,
344 llvm::map_range(llvm::seq(0u, CA->getNumOperands()),
345 [&](
unsigned Op) { return Offset + Op * ElemSize; }));
349 const llvm::StructLayout *Layout =
351 replace(Offsets, Index, Index + 1,
353 llvm::seq(0u, CA->getNumOperands()), [&](
unsigned Op) {
354 return Offset + CharUnits::fromQuantity(
355 Layout->getElementOffset(Op));
361 if (
auto *CDS = dyn_cast<llvm::ConstantDataSequential>(
C)) {
365 CharUnits ElemSize = getSize(CDS->getElementType());
366 replace(Elems, Index, Index + 1,
367 llvm::map_range(llvm::seq(
uint64_t(0u), CDS->getNumElements()),
369 return CDS->getElementAsConstant(Elem);
371 replace(Offsets, Index, Index + 1,
373 llvm::seq(
uint64_t(0u), CDS->getNumElements()),
374 [&](uint64_t Elem) { return Offset + Elem * ElemSize; }));
380 CharUnits ElemSize = getSize(
C);
381 assert(Hint > Offset && Hint < Offset + ElemSize &&
"nothing to split");
382 replace(Elems, Index, Index + 1,
383 {getZeroes(Hint - Offset), getZeroes(Offset + ElemSize - Hint)});
384 replace(Offsets, Index, Index + 1, {Offset, Hint});
390 replace(Elems, Index, Index + 1, {});
391 replace(Offsets, Index, Index + 1, {});
402static llvm::Constant *
403EmitArrayConstant(CodeGenModule &CGM, llvm::ArrayType *DesiredType,
404 llvm::Type *CommonElementType, uint64_t
ArrayBound,
405 SmallVectorImpl<llvm::Constant *> &Elements,
406 llvm::Constant *Filler);
408llvm::Constant *ConstantAggregateBuilder::buildFrom(
409 CodeGenModule &CGM, ArrayRef<llvm::Constant *> Elems,
410 ArrayRef<CharUnits> Offsets, CharUnits StartOffset, CharUnits Size,
411 bool NaturalLayout, llvm::Type *DesiredTy,
bool AllowOversized) {
412 ConstantAggregateBuilderUtils Utils(CGM);
415 return llvm::UndefValue::get(DesiredTy);
417 auto Offset = [&](
size_t I) {
return Offsets[I] - StartOffset; };
421 if (llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(DesiredTy)) {
422 assert(!AllowOversized &&
"oversized array emission not supported");
424 bool CanEmitArray =
true;
425 llvm::Type *CommonType = Elems[0]->getType();
426 llvm::Constant *Filler = llvm::Constant::getNullValue(CommonType);
427 CharUnits ElemSize = Utils.getSize(ATy->getElementType());
428 SmallVector<llvm::Constant*, 32> ArrayElements;
429 for (
size_t I = 0; I != Elems.size(); ++I) {
431 if (Elems[I]->isNullValue())
435 if (Elems[I]->
getType() != CommonType ||
436 Offset(I) % ElemSize != 0) {
437 CanEmitArray =
false;
440 ArrayElements.resize(Offset(I) / ElemSize + 1, Filler);
441 ArrayElements.back() = Elems[I];
445 return EmitArrayConstant(CGM, ATy, CommonType, ATy->getNumElements(),
446 ArrayElements, Filler);
455 CharUnits DesiredSize = Utils.getSize(DesiredTy);
456 if (Size > DesiredSize) {
457 assert(AllowOversized &&
"Elems are oversized");
463 for (llvm::Constant *
C : Elems)
464 Align = std::max(Align, Utils.getAlignment(
C));
467 CharUnits AlignedSize =
Size.alignTo(Align);
470 ArrayRef<llvm::Constant*> UnpackedElems = Elems;
471 llvm::SmallVector<llvm::Constant*, 32> UnpackedElemStorage;
472 if (DesiredSize < AlignedSize || DesiredSize.
alignTo(Align) != DesiredSize) {
474 NaturalLayout =
false;
476 }
else if (DesiredSize > AlignedSize) {
479 UnpackedElemStorage.assign(Elems.begin(), Elems.end());
480 UnpackedElemStorage.push_back(Utils.getPadding(DesiredSize - Size));
481 UnpackedElems = UnpackedElemStorage;
487 llvm::SmallVector<llvm::Constant*, 32> PackedElems;
488 if (!NaturalLayout) {
490 for (
size_t I = 0; I != Elems.size(); ++I) {
491 CharUnits Align = Utils.getAlignment(Elems[I]);
492 CharUnits NaturalOffset = SizeSoFar.
alignTo(Align);
493 CharUnits DesiredOffset = Offset(I);
494 assert(DesiredOffset >= SizeSoFar &&
"elements out of order");
496 if (DesiredOffset != NaturalOffset)
498 if (DesiredOffset != SizeSoFar)
499 PackedElems.push_back(Utils.getPadding(DesiredOffset - SizeSoFar));
500 PackedElems.push_back(Elems[I]);
501 SizeSoFar = DesiredOffset + Utils.getSize(Elems[I]);
506 assert(SizeSoFar <= DesiredSize &&
507 "requested size is too small for contents");
508 if (SizeSoFar < DesiredSize)
509 PackedElems.push_back(Utils.getPadding(DesiredSize - SizeSoFar));
513 llvm::StructType *STy = llvm::ConstantStruct::getTypeForElements(
518 if (llvm::StructType *DesiredSTy = dyn_cast<llvm::StructType>(DesiredTy)) {
519 if (DesiredSTy->isLayoutIdentical(STy))
523 return llvm::ConstantStruct::get(STy,
Packed ? PackedElems : UnpackedElems);
526void ConstantAggregateBuilder::condense(CharUnits Offset,
527 llvm::Type *DesiredTy) {
528 CharUnits
Size = getSize(DesiredTy);
530 std::optional<size_t> FirstElemToReplace = splitAt(Offset);
531 if (!FirstElemToReplace)
533 size_t First = *FirstElemToReplace;
535 std::optional<size_t> LastElemToReplace = splitAt(Offset + Size);
536 if (!LastElemToReplace)
538 size_t Last = *LastElemToReplace;
544 if (Length == 1 && Offsets[
First] == Offset &&
545 getSize(Elems[
First]) == Size) {
548 auto *STy = dyn_cast<llvm::StructType>(DesiredTy);
549 if (STy && STy->getNumElements() == 1 &&
550 STy->getElementType(0) == Elems[
First]->getType())
551 Elems[
First] = llvm::ConstantStruct::get(STy, Elems[
First]);
555 llvm::Constant *Replacement = buildFrom(
556 CGM, ArrayRef(Elems).slice(
First, Length),
557 ArrayRef(Offsets).slice(
First, Length), Offset, getSize(DesiredTy),
558 false, DesiredTy,
false);
559 replace(Elems,
First,
Last, {Replacement});
567class ConstStructBuilder {
569 ConstantEmitter &Emitter;
570 ConstantAggregateBuilder &Builder;
571 CharUnits StartOffset;
574 static llvm::Constant *BuildStruct(ConstantEmitter &Emitter,
575 const InitListExpr *ILE,
577 static llvm::Constant *BuildStruct(ConstantEmitter &Emitter,
579 static bool UpdateStruct(ConstantEmitter &Emitter,
580 ConstantAggregateBuilder &Const, CharUnits Offset,
581 const InitListExpr *Updater);
584 ConstStructBuilder(ConstantEmitter &Emitter,
585 ConstantAggregateBuilder &Builder, CharUnits StartOffset)
586 : CGM(Emitter.CGM), Emitter(Emitter), Builder(Builder),
587 StartOffset(StartOffset) {}
589 bool AppendField(
const FieldDecl *Field, uint64_t FieldOffset,
590 llvm::Constant *InitExpr,
bool AllowOverwrite =
false);
592 bool AppendBytes(CharUnits FieldOffsetInChars, llvm::Constant *InitCst,
593 bool AllowOverwrite =
false);
595 bool AppendBitField(
const FieldDecl *Field, uint64_t FieldOffset,
596 llvm::Constant *InitExpr,
bool AllowOverwrite =
false);
598 bool Build(
const InitListExpr *ILE,
bool AllowOverwrite);
599 bool Build(
const APValue &Val,
const RecordDecl *RD,
bool IsPrimaryBase,
600 const CXXRecordDecl *VTableClass, CharUnits BaseOffset);
601 bool DoZeroInitPadding(
const ASTRecordLayout &Layout,
unsigned FieldNo,
602 const FieldDecl &Field,
bool AllowOverwrite,
603 CharUnits &SizeSoFar,
bool &ZeroFieldSize);
604 bool DoZeroInitPadding(
const ASTRecordLayout &Layout,
bool AllowOverwrite,
605 CharUnits SizeSoFar);
606 llvm::Constant *
Finalize(QualType Ty);
609bool ConstStructBuilder::AppendField(
610 const FieldDecl *Field, uint64_t FieldOffset, llvm::Constant *InitCst,
611 bool AllowOverwrite) {
616 return AppendBytes(FieldOffsetInChars, InitCst, AllowOverwrite);
619bool ConstStructBuilder::AppendBytes(CharUnits FieldOffsetInChars,
620 llvm::Constant *InitCst,
621 bool AllowOverwrite) {
622 return Builder.add(InitCst, StartOffset + FieldOffsetInChars, AllowOverwrite);
625bool ConstStructBuilder::AppendBitField(
const FieldDecl *Field,
626 uint64_t FieldOffset, llvm::Constant *
C,
627 bool AllowOverwrite) {
629 llvm::ConstantInt *CI = dyn_cast<llvm::ConstantInt>(
C);
635 llvm::Type *LoadType =
637 llvm::Constant *FoldedConstant = llvm::ConstantFoldLoadFromConst(
639 CI = dyn_cast_if_present<llvm::ConstantInt>(FoldedConstant);
644 const CGRecordLayout &RL =
647 llvm::APInt FieldValue = CI->getValue();
653 if (Info.
Size > FieldValue.getBitWidth())
654 FieldValue = FieldValue.zext(Info.
Size);
657 if (Info.
Size < FieldValue.getBitWidth())
658 FieldValue = FieldValue.trunc(Info.
Size);
660 return Builder.addBits(FieldValue,
665static bool EmitDesignatedInitUpdater(ConstantEmitter &Emitter,
666 ConstantAggregateBuilder &Const,
667 CharUnits Offset, QualType
Type,
668 const InitListExpr *Updater) {
669 if (
Type->isRecordType())
670 return ConstStructBuilder::UpdateStruct(Emitter, Const, Offset, Updater);
679 llvm::Constant *FillC =
nullptr;
688 unsigned NumElementsToUpdate =
689 FillC ? CAT->getZExtSize() : Updater->
getNumInits();
690 for (
unsigned I = 0; I != NumElementsToUpdate; ++I, Offset += ElemSize) {
691 const Expr *
Init =
nullptr;
692 if (I < Updater->getNumInits())
695 if (!
Init && FillC) {
696 if (!
Const.add(FillC, Offset,
true))
700 }
else if (
const auto *ChildILE = dyn_cast<InitListExpr>(
Init)) {
701 if (!EmitDesignatedInitUpdater(Emitter, Const, Offset, ElemType,
705 Const.condense(Offset, ElemTy);
708 if (!
Const.add(Val, Offset,
true))
716bool ConstStructBuilder::Build(
const InitListExpr *ILE,
bool AllowOverwrite) {
720 unsigned FieldNo = -1;
721 unsigned ElementNo = 0;
726 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
727 if (CXXRD->getNumBases())
731 bool ZeroFieldSize =
false;
734 for (FieldDecl *Field : RD->fields()) {
743 if (
Field->isUnnamedBitField())
748 const Expr *
Init =
nullptr;
749 if (ElementNo < ILE->getNumInits())
751 if (isa_and_nonnull<NoInitExpr>(
Init)) {
752 if (ZeroInitPadding &&
753 !DoZeroInitPadding(Layout, FieldNo, *Field, AllowOverwrite, SizeSoFar,
767 if (ZeroInitPadding &&
768 !DoZeroInitPadding(Layout, FieldNo, *Field, AllowOverwrite, SizeSoFar,
775 if (AllowOverwrite &&
776 (
Field->getType()->isArrayType() ||
Field->getType()->isRecordType())) {
777 if (
auto *SubILE = dyn_cast<InitListExpr>(
Init)) {
780 if (!EmitDesignatedInitUpdater(Emitter, Builder, StartOffset + Offset,
781 Field->getType(), SubILE))
785 Builder.condense(StartOffset + Offset,
791 llvm::Constant *EltInit =
797 if (ZeroInitPadding && ZeroFieldSize)
801 if (!
Field->isBitField()) {
808 if (
Field->hasAttr<NoUniqueAddressAttr>())
809 AllowOverwrite =
true;
812 if (!AppendBitField(Field, Layout.
getFieldOffset(FieldNo), EltInit,
818 if (ZeroInitPadding && !DoZeroInitPadding(Layout, AllowOverwrite, SizeSoFar))
826 BaseInfo(
const CXXRecordDecl *
Decl, CharUnits Offset,
unsigned Index)
827 :
Decl(
Decl), Offset(Offset), Index(Index) {
830 const CXXRecordDecl *
Decl;
834 bool operator<(
const BaseInfo &O)
const {
return Offset < O.Offset; }
838bool ConstStructBuilder::Build(
const APValue &Val,
const RecordDecl *RD,
840 const CXXRecordDecl *VTableClass,
844 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
847 llvm::Constant *VTableAddressPoint =
852 VTableAddressPoint, *Authentication);
853 if (!VTableAddressPoint)
856 if (!AppendBytes(Offset, VTableAddressPoint))
862 SmallVector<BaseInfo, 8> Bases;
863 Bases.reserve(CD->getNumBases());
866 BaseEnd = CD->bases_end(); Base != BaseEnd; ++Base, ++BaseNo) {
867 assert(!
Base->isVirtual() &&
"should not have virtual bases here");
868 const CXXRecordDecl *BD =
Base->getType()->getAsCXXRecordDecl();
870 Bases.push_back(BaseInfo(BD, BaseOffset, BaseNo));
872 llvm::stable_sort(Bases);
874 for (
const BaseInfo &Base : Bases) {
877 VTableClass, Offset +
Base.Offset))
882 unsigned FieldNo = 0;
885 bool ZeroFieldSize =
false;
888 bool AllowOverwrite =
false;
890 FieldEnd = RD->
field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
896 if (
Field->isUnnamedBitField() ||
903 llvm::Constant *EltInit =
908 if (ZeroInitPadding) {
909 if (!DoZeroInitPadding(Layout, FieldNo, **Field, AllowOverwrite,
910 SizeSoFar, ZeroFieldSize))
917 if (!
Field->isBitField()) {
919 if (!AppendField(*Field, Layout.
getFieldOffset(FieldNo) + OffsetBits,
920 EltInit, AllowOverwrite))
924 if (
Field->hasAttr<NoUniqueAddressAttr>())
925 AllowOverwrite =
true;
928 if (!AppendBitField(*Field, Layout.
getFieldOffset(FieldNo) + OffsetBits,
929 EltInit, AllowOverwrite))
933 if (ZeroInitPadding && !DoZeroInitPadding(Layout, AllowOverwrite, SizeSoFar))
939bool ConstStructBuilder::DoZeroInitPadding(
940 const ASTRecordLayout &Layout,
unsigned FieldNo,
const FieldDecl &Field,
941 bool AllowOverwrite, CharUnits &SizeSoFar,
bool &ZeroFieldSize) {
944 if (SizeSoFar < StartOffset)
945 if (!AppendBytes(SizeSoFar, getPadding(CGM, StartOffset - SizeSoFar),
949 if (!
Field.isBitField()) {
951 SizeSoFar = StartOffset + FieldSize;
952 ZeroFieldSize = FieldSize.isZero();
954 const CGRecordLayout &RL =
962 ZeroFieldSize = Info.
Size == 0;
967bool ConstStructBuilder::DoZeroInitPadding(
const ASTRecordLayout &Layout,
969 CharUnits SizeSoFar) {
970 CharUnits TotalSize = Layout.
getSize();
971 if (SizeSoFar < TotalSize)
972 if (!AppendBytes(SizeSoFar, getPadding(CGM, TotalSize - SizeSoFar),
975 SizeSoFar = TotalSize;
979llvm::Constant *ConstStructBuilder::Finalize(QualType
Type) {
981 auto *RD =
Type->castAsRecordDecl();
986llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
987 const InitListExpr *ILE,
989 ConstantAggregateBuilder
Const(Emitter.
CGM);
992 if (!Builder.Build(ILE,
false))
995 return Builder.Finalize(ValTy);
998llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
1001 ConstantAggregateBuilder
Const(Emitter.
CGM);
1005 const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD);
1009 return Builder.Finalize(ValTy);
1012bool ConstStructBuilder::UpdateStruct(ConstantEmitter &Emitter,
1013 ConstantAggregateBuilder &Const,
1015 const InitListExpr *Updater) {
1016 return ConstStructBuilder(Emitter, Const, Offset)
1017 .Build(Updater,
true);
1024static ConstantAddress
1025tryEmitGlobalCompoundLiteral(ConstantEmitter &emitter,
1026 const CompoundLiteralExpr *E) {
1027 CodeGenModule &CGM = emitter.
CGM;
1029 if (llvm::GlobalVariable *
Addr =
1031 return ConstantAddress(
Addr,
Addr->getValueType(), Align);
1038 "file-scope compound literal did not have constant initializer!");
1042 auto GV =
new llvm::GlobalVariable(
1045 llvm::GlobalValue::InternalLinkage,
C,
".compoundliteral",
nullptr,
1046 llvm::GlobalVariable::NotThreadLocal,
1051 return ConstantAddress(GV, GV->getValueType(), Align);
1054static llvm::Constant *
1055EmitArrayConstant(CodeGenModule &CGM, llvm::ArrayType *DesiredType,
1056 llvm::Type *CommonElementType, uint64_t
ArrayBound,
1057 SmallVectorImpl<llvm::Constant *> &Elements,
1058 llvm::Constant *Filler) {
1061 if (Elements.size() < NonzeroLength && Filler->isNullValue())
1062 NonzeroLength = Elements.size();
1063 if (NonzeroLength == Elements.size()) {
1064 while (NonzeroLength > 0 && Elements[NonzeroLength - 1]->isNullValue())
1068 if (NonzeroLength == 0)
1069 return llvm::ConstantAggregateZero::get(DesiredType);
1073 if (TrailingZeroes >= 8) {
1074 assert(Elements.size() >= NonzeroLength &&
1075 "missing initializer for non-zero element");
1079 if (CommonElementType && NonzeroLength >= 8) {
1080 llvm::Constant *Initial = llvm::ConstantArray::get(
1081 llvm::ArrayType::get(CommonElementType, NonzeroLength),
1082 ArrayRef(Elements).take_front(NonzeroLength));
1084 Elements[0] = Initial;
1086 Elements.resize(NonzeroLength + 1);
1090 CommonElementType ? CommonElementType : DesiredType->getElementType();
1091 FillerType = llvm::ArrayType::get(FillerType, TrailingZeroes);
1092 Elements.back() = llvm::ConstantAggregateZero::get(FillerType);
1093 CommonElementType =
nullptr;
1097 if (Filler->getType() != CommonElementType)
1098 CommonElementType =
nullptr;
1102 if (CommonElementType)
1103 return llvm::ConstantArray::get(
1104 llvm::ArrayType::get(CommonElementType,
ArrayBound), Elements);
1107 llvm::SmallVector<llvm::Type *, 16> Types;
1108 Types.reserve(Elements.size());
1109 for (llvm::Constant *Elt : Elements)
1110 Types.push_back(Elt->getType());
1111 llvm::StructType *SType =
1113 return llvm::ConstantStruct::get(SType, Elements);
1122class ConstExprEmitter
1123 :
public ConstStmtVisitor<ConstExprEmitter, llvm::Constant *, QualType> {
1125 ConstantEmitter &Emitter;
1126 llvm::LLVMContext &VMContext;
1128 ConstExprEmitter(ConstantEmitter &emitter)
1129 : CGM(emitter.CGM), Emitter(emitter), VMContext(CGM.getLLVMContext()) {
1136 llvm::Constant *VisitStmt(
const Stmt *S, QualType
T) {
return nullptr; }
1138 llvm::Constant *VisitConstantExpr(
const ConstantExpr *CE, QualType
T) {
1144 llvm::Constant *VisitParenExpr(
const ParenExpr *PE, QualType
T) {
1149 VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *PE,
1154 llvm::Constant *VisitGenericSelectionExpr(
const GenericSelectionExpr *GE,
1156 return Visit(
GE->getResultExpr(),
T);
1159 llvm::Constant *VisitChooseExpr(
const ChooseExpr *CE, QualType
T) {
1163 llvm::Constant *VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E,
1168 llvm::Constant *ProduceIntToIntCast(
const Expr *E, QualType DestType) {
1169 QualType FromType = E->
getType();
1172 if (llvm::Constant *
C = Visit(E, FromType))
1173 if (
auto *CI = dyn_cast<llvm::ConstantInt>(
C)) {
1176 if (DstWidth == SrcWidth)
1179 ? CI->getValue().sextOrTrunc(DstWidth)
1180 : CI->getValue().zextOrTrunc(DstWidth);
1186 llvm::Constant *VisitCastExpr(
const CastExpr *E, QualType destType) {
1187 if (
const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
1195 "Destination type is not union type!");
1200 if (!
C)
return nullptr;
1202 auto destTy = ConvertType(destType);
1203 if (
C->getType() == destTy)
return C;
1207 SmallVector<llvm::Constant*, 2> Elts;
1208 SmallVector<llvm::Type*, 2> Types;
1210 Types.push_back(
C->getType());
1211 unsigned CurSize = CGM.
getDataLayout().getTypeAllocSize(
C->getType());
1212 unsigned TotalSize = CGM.
getDataLayout().getTypeAllocSize(destTy);
1214 assert(CurSize <= TotalSize &&
"Union size mismatch!");
1215 if (
unsigned NumPadBytes = TotalSize - CurSize) {
1216 llvm::Constant *Padding =
1218 Elts.push_back(Padding);
1219 Types.push_back(Padding->getType());
1222 llvm::StructType *STy = llvm::StructType::get(VMContext, Types,
false);
1223 return llvm::ConstantStruct::get(STy, Elts);
1226 case CK_AddressSpaceConversion: {
1231 llvm::Type *destTy = ConvertType(E->
getType());
1236 case CK_LValueToRValue: {
1242 dyn_cast<CompoundLiteralExpr>(subExpr->
IgnoreParens()))
1243 return Visit(E->getInitializer(), destType);
1247 case CK_AtomicToNonAtomic:
1248 case CK_NonAtomicToAtomic:
1250 case CK_ConstructorConversion:
1251 return Visit(subExpr, destType);
1253 case CK_ArrayToPointerDecay:
1254 if (
const auto *S = dyn_cast<StringLiteral>(subExpr))
1257 case CK_NullToPointer:
1258 if (Visit(subExpr, destType))
1262 case CK_IntToOCLSampler:
1263 llvm_unreachable(
"global sampler variables are not generated");
1265 case CK_IntegralCast:
1266 return ProduceIntToIntCast(subExpr, destType);
1268 case CK_Dependent: llvm_unreachable(
"saw dependent cast!");
1270 case CK_BuiltinFnToFnPtr:
1271 llvm_unreachable(
"builtin functions are handled elsewhere");
1273 case CK_ReinterpretMemberPointer:
1274 case CK_DerivedToBaseMemberPointer:
1275 case CK_BaseToDerivedMemberPointer: {
1277 if (!
C)
return nullptr;
1282 case CK_ObjCObjectLValueCast:
1283 case CK_ARCProduceObject:
1284 case CK_ARCConsumeObject:
1285 case CK_ARCReclaimReturnedObject:
1286 case CK_ARCExtendBlockObject:
1287 case CK_CopyAndAutoreleaseBlockObject:
1295 case CK_LValueBitCast:
1296 case CK_LValueToRValueBitCast:
1297 case CK_NullToMemberPointer:
1298 case CK_UserDefinedConversion:
1299 case CK_CPointerToObjCPointerCast:
1300 case CK_BlockPointerToObjCPointerCast:
1301 case CK_AnyPointerToBlockPointerCast:
1302 case CK_FunctionToPointerDecay:
1303 case CK_BaseToDerived:
1304 case CK_DerivedToBase:
1305 case CK_UncheckedDerivedToBase:
1306 case CK_MemberPointerToBoolean:
1307 case CK_VectorSplat:
1308 case CK_FloatingRealToComplex:
1309 case CK_FloatingComplexToReal:
1310 case CK_FloatingComplexToBoolean:
1311 case CK_FloatingComplexCast:
1312 case CK_FloatingComplexToIntegralComplex:
1313 case CK_IntegralRealToComplex:
1314 case CK_IntegralComplexToReal:
1315 case CK_IntegralComplexToBoolean:
1316 case CK_IntegralComplexCast:
1317 case CK_IntegralComplexToFloatingComplex:
1318 case CK_PointerToIntegral:
1319 case CK_PointerToBoolean:
1320 case CK_BooleanToSignedIntegral:
1321 case CK_IntegralToPointer:
1322 case CK_IntegralToBoolean:
1323 case CK_IntegralToFloating:
1324 case CK_FloatingToIntegral:
1325 case CK_FloatingToBoolean:
1326 case CK_FloatingCast:
1327 case CK_FloatingToFixedPoint:
1328 case CK_FixedPointToFloating:
1329 case CK_FixedPointCast:
1330 case CK_FixedPointToBoolean:
1331 case CK_FixedPointToIntegral:
1332 case CK_IntegralToFixedPoint:
1333 case CK_ZeroToOCLOpaqueType:
1335 case CK_HLSLVectorTruncation:
1336 case CK_HLSLArrayRValue:
1337 case CK_HLSLElementwiseCast:
1338 case CK_HLSLAggregateSplatCast:
1341 llvm_unreachable(
"Invalid CastKind");
1344 llvm::Constant *VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *DIE,
1351 llvm::Constant *VisitExprWithCleanups(
const ExprWithCleanups *E, QualType
T) {
1355 llvm::Constant *VisitIntegerLiteral(
const IntegerLiteral *I, QualType
T) {
1359 static APValue withDestType(ASTContext &Ctx,
const Expr *E, QualType SrcType,
1360 QualType DestType,
const llvm::APSInt &
Value) {
1365 llvm::RoundingMode RM =
1367 if (RM == llvm::RoundingMode::Dynamic)
1368 RM = llvm::RoundingMode::NearestTiesToEven;
1376 llvm::Constant *EmitArrayInitialization(
const InitListExpr *ILE, QualType
T) {
1378 assert(CAT &&
"can't emit array init for non-constant-bound array");
1380 const uint64_t NumElements = CAT->getZExtSize();
1382 if (
const auto *Embed =
1383 dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1384 NumInitElements += Embed->getDataElementCount() - 1;
1385 if (NumInitElements > NumElements) {
1386 NumInitElements = NumElements;
1394 uint64_t NumInitableElts = std::min<uint64_t>(NumInitElements, NumElements);
1396 QualType EltType = CAT->getElementType();
1399 llvm::Constant *fillC =
nullptr;
1407 SmallVector<llvm::Constant *, 16> Elts;
1408 if (fillC && fillC->isNullValue())
1409 Elts.reserve(NumInitableElts + 1);
1411 Elts.reserve(NumElements);
1413 llvm::Type *CommonElementType =
nullptr;
1414 auto Emit = [&](
const Expr *
Init,
unsigned ArrayIndex) {
1415 llvm::Constant *
C =
nullptr;
1419 if (ArrayIndex == 0)
1420 CommonElementType =
C->getType();
1421 else if (
C->getType() != CommonElementType)
1422 CommonElementType =
nullptr;
1427 unsigned ArrayIndex = 0;
1428 QualType DestTy = CAT->getElementType();
1429 for (
unsigned i = 0; i < ILE->
getNumInits(); ++i) {
1431 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1432 StringLiteral *SL = EmbedS->getDataStringLiteral();
1436 for (
unsigned I = EmbedS->getStartingElementPos(),
1437 N = EmbedS->getDataElementCount();
1438 I != EmbedS->getStartingElementPos() + N; ++I) {
1453 if ((ArrayIndex - EmbedS->getDataElementCount()) == 0)
1454 CommonElementType =
C->getType();
1455 else if (
C->getType() != CommonElementType)
1456 CommonElementType =
nullptr;
1458 if (!Emit(
Init, ArrayIndex))
1464 llvm::ArrayType *Desired =
1466 return EmitArrayConstant(CGM, Desired, CommonElementType, NumElements, Elts,
1470 llvm::Constant *EmitRecordInitialization(
const InitListExpr *ILE,
1472 return ConstStructBuilder::BuildStruct(Emitter, ILE,
T);
1475 llvm::Constant *VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E,
1480 llvm::Constant *VisitInitListExpr(
const InitListExpr *ILE, QualType
T) {
1485 return EmitArrayInitialization(ILE,
T);
1488 return EmitRecordInitialization(ILE,
T);
1494 VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E,
1495 QualType destType) {
1496 auto C = Visit(E->
getBase(), destType);
1500 ConstantAggregateBuilder
Const(CGM);
1503 if (!EmitDesignatedInitUpdater(Emitter, Const,
CharUnits::Zero(), destType,
1508 bool HasFlexibleArray =
false;
1511 return Const.build(ValTy, HasFlexibleArray);
1514 llvm::Constant *VisitCXXConstructExpr(
const CXXConstructExpr *E,
1521 assert(E->
getNumArgs() == 1 &&
"trivial ctor with > 1 argument");
1523 "trivial ctor has argument but isn't a copy/move ctor");
1525 const Expr *Arg = E->
getArg(0);
1527 "argument to copy ctor is of wrong type");
1531 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(Arg))
1532 return Visit(MTE->getSubExpr(), Ty);
1540 llvm::Constant *VisitStringLiteral(
const StringLiteral *E, QualType
T) {
1545 llvm::Constant *VisitObjCEncodeExpr(
const ObjCEncodeExpr *E, QualType
T) {
1552 assert(CAT &&
"String data not of constant array type!");
1557 return llvm::ConstantDataArray::getString(VMContext, Str,
false);
1560 llvm::Constant *VisitUnaryExtension(
const UnaryOperator *E, QualType
T) {
1564 llvm::Constant *VisitUnaryMinus(
const UnaryOperator *U, QualType
T) {
1566 if (
auto *CI = dyn_cast<llvm::ConstantInt>(
C))
1567 return llvm::ConstantInt::get(CGM.
getLLVMContext(), -CI->getValue());
1571 llvm::Constant *VisitPackIndexingExpr(
const PackIndexingExpr *E, QualType
T) {
1576 llvm::Type *ConvertType(QualType
T) {
1583llvm::Constant *ConstantEmitter::validateAndPopAbstract(llvm::Constant *
C,
1584 AbstractState saved) {
1585 Abstract = saved.OldValue;
1587 assert(saved.OldPlaceholdersSize == PlaceholderAddresses.size() &&
1588 "created a placeholder while doing an abstract emission?");
1597 auto state = pushAbstract();
1599 return validateAndPopAbstract(
C, state);
1604 auto state = pushAbstract();
1606 return validateAndPopAbstract(
C, state);
1611 auto state = pushAbstract();
1613 return validateAndPopAbstract(
C, state);
1622 RetType =
CGM.getContext().getLValueReferenceType(RetType);
1629 auto state = pushAbstract();
1631 C = validateAndPopAbstract(
C, state);
1634 "internal error: could not emit constant value \"abstractly\"");
1635 C =
CGM.EmitNullConstant(destType);
1643 bool EnablePtrAuthFunctionTypeDiscrimination) {
1644 auto state = pushAbstract();
1646 tryEmitPrivate(value, destType, EnablePtrAuthFunctionTypeDiscrimination);
1647 C = validateAndPopAbstract(
C, state);
1650 "internal error: could not emit constant value \"abstractly\"");
1651 C =
CGM.EmitNullConstant(destType);
1664 initializeNonAbstract(destAddrSpace);
1671 initializeNonAbstract(destAddrSpace);
1673 assert(
C &&
"couldn't emit constant value non-abstractly?");
1678 assert(!Abstract &&
"cannot get current address for abstract constant");
1684 auto global =
new llvm::GlobalVariable(
CGM.getModule(),
CGM.Int8Ty,
true,
1685 llvm::GlobalValue::PrivateLinkage,
1689 llvm::GlobalVariable::NotThreadLocal,
1690 CGM.getContext().getTargetAddressSpace(DestAddressSpace));
1692 PlaceholderAddresses.push_back(std::make_pair(
nullptr, global));
1698 llvm::GlobalValue *placeholder) {
1699 assert(!PlaceholderAddresses.empty());
1700 assert(PlaceholderAddresses.back().first ==
nullptr);
1701 assert(PlaceholderAddresses.back().second == placeholder);
1702 PlaceholderAddresses.back().first = signal;
1706 struct ReplacePlaceholders {
1710 llvm::Constant *
Base;
1711 llvm::Type *BaseValueTy =
nullptr;
1714 llvm::DenseMap<llvm::Constant*, llvm::GlobalVariable*> PlaceholderAddresses;
1717 llvm::DenseMap<llvm::GlobalVariable*, llvm::Constant*> Locations;
1725 ReplacePlaceholders(
CodeGenModule &CGM, llvm::Constant *base,
1726 ArrayRef<std::pair<llvm::Constant*,
1727 llvm::GlobalVariable*>> addresses)
1728 : CGM(CGM),
Base(base),
1729 PlaceholderAddresses(addresses.begin(), addresses.end()) {
1732 void replaceInInitializer(llvm::Constant *init) {
1734 BaseValueTy = init->getType();
1737 Indices.push_back(0);
1738 IndexValues.push_back(
nullptr);
1741 findLocations(init);
1744 assert(IndexValues.size() == Indices.size() &&
"mismatch");
1745 assert(Indices.size() == 1 &&
"didn't pop all indices");
1748 assert(Locations.size() == PlaceholderAddresses.size() &&
1749 "missed a placeholder?");
1755 for (
auto &entry : Locations) {
1756 assert(entry.first->getName() ==
"" &&
"not a placeholder!");
1757 entry.first->replaceAllUsesWith(entry.second);
1758 entry.first->eraseFromParent();
1763 void findLocations(llvm::Constant *init) {
1765 if (
auto agg = dyn_cast<llvm::ConstantAggregate>(init)) {
1766 for (
unsigned i = 0, e = agg->getNumOperands(); i != e; ++i) {
1767 Indices.push_back(i);
1768 IndexValues.push_back(
nullptr);
1770 findLocations(agg->getOperand(i));
1772 IndexValues.pop_back();
1780 auto it = PlaceholderAddresses.find(init);
1781 if (it != PlaceholderAddresses.end()) {
1782 setLocation(it->second);
1787 if (
auto expr = dyn_cast<llvm::ConstantExpr>(init)) {
1788 init =
expr->getOperand(0);
1795 void setLocation(llvm::GlobalVariable *placeholder) {
1796 assert(!Locations.contains(placeholder) &&
1797 "already found location for placeholder!");
1802 assert(Indices.size() == IndexValues.size());
1803 for (
size_t i = Indices.size() - 1; i !=
size_t(-1); --i) {
1804 if (IndexValues[i]) {
1806 for (
size_t j = 0; j != i + 1; ++j) {
1807 assert(IndexValues[j] &&
1816 IndexValues[i] = llvm::ConstantInt::get(CGM.
Int32Ty, Indices[i]);
1819 llvm::Constant *location = llvm::ConstantExpr::getInBoundsGetElementPtr(
1820 BaseValueTy, Base, IndexValues);
1822 Locations.insert({placeholder, location});
1828 assert(InitializedNonAbstract &&
1829 "finalizing emitter that was used for abstract emission?");
1830 assert(!Finalized &&
"finalizing emitter multiple times");
1831 assert(global->getInitializer());
1836 if (!PlaceholderAddresses.empty()) {
1837 ReplacePlaceholders(
CGM, global, PlaceholderAddresses)
1838 .replaceInInitializer(global->getInitializer());
1839 PlaceholderAddresses.clear();
1844 assert((!InitializedNonAbstract || Finalized || Failed) &&
1845 "not finalized after being initialized for non-abstract emission");
1846 assert(PlaceholderAddresses.empty() &&
"unhandled placeholders");
1852 type.getQualifiers());
1865 dyn_cast_or_null<CXXConstructExpr>(D.
getInit())) {
1875 assert(E &&
"No initializer to emit");
1879 if (llvm::Constant *
C = ConstExprEmitter(*this).Visit(E, nonMemoryDestType))
1886 assert(!value->allowConstexprUnknown() &&
1887 "Constexpr unknown values are not allowed in CodeGen");
1931 assert(Schema &&
"applying trivial ptrauth schema");
1934 return UnsignedPointer;
1936 unsigned Key = Schema.
getKey();
1939 llvm::GlobalValue *StorageAddress =
nullptr;
1948 llvm::ConstantInt *Discriminator =
1951 llvm::Constant *SignedPointer =
CGM.getConstantSignedPointer(
1952 UnsignedPointer, Key, StorageAddress, Discriminator);
1957 return SignedPointer;
1965 QualType destValueType = AT->getValueType();
1968 uint64_t innerSize =
CGM.getContext().getTypeSize(destValueType);
1969 uint64_t outerSize =
CGM.getContext().getTypeSize(destType);
1970 if (innerSize == outerSize)
1973 assert(innerSize < outerSize &&
"emitted over-large constant for atomic");
1974 llvm::Constant *elts[] = {
1976 llvm::ConstantAggregateZero::get(
1977 llvm::ArrayType::get(
CGM.Int8Ty, (outerSize - innerSize) / 8))
1979 return llvm::ConstantStruct::getAnon(elts);
1984 if ((
C->getType()->isIntegerTy(1) && !destType->
isBitIntType()) ||
1987 llvm::Type *boolTy =
CGM.getTypes().ConvertTypeForMem(destType);
1988 llvm::Constant *Res = llvm::ConstantFoldCastOperand(
1989 llvm::Instruction::ZExt,
C, boolTy,
CGM.getDataLayout());
1990 assert(Res &&
"Constant folding must succeed");
1995 ConstantAggregateBuilder Builder(
CGM);
1996 llvm::Type *LoadStoreTy =
CGM.getTypes().convertTypeForLoadStore(destType);
2000 llvm::Constant *Res = llvm::ConstantFoldCastOperand(
2002 : llvm::Instruction::ZExt,
2003 CI, LoadStoreTy,
CGM.getDataLayout());
2004 if (
CGM.getTypes().typeRequiresSplitIntoByteArray(destType,
C->getType())) {
2007 llvm::Type *DesiredTy =
CGM.getTypes().ConvertTypeForMem(destType);
2009 Builder.addBits(
Value, 0,
false);
2010 return Builder.build(DesiredTy,
false);
2020 assert(!destType->
isVoidType() &&
"can't emit a void constant");
2023 if (llvm::Constant *
C = ConstExprEmitter(*this).Visit(E, destType))
2048struct ConstantLValue {
2049 llvm::Constant *
Value;
2050 bool HasOffsetApplied;
2051 bool HasDestPointerAuth;
2053 ConstantLValue(llvm::Constant *value,
2054 bool hasOffsetApplied =
false,
2055 bool hasDestPointerAuth =
false)
2056 :
Value(value), HasOffsetApplied(hasOffsetApplied),
2057 HasDestPointerAuth(hasDestPointerAuth) {}
2060 : ConstantLValue(address.getPointer()) {}
2064class ConstantLValueEmitter :
public ConstStmtVisitor<ConstantLValueEmitter,
2067 ConstantEmitter &Emitter;
2070 bool EnablePtrAuthFunctionTypeDiscrimination;
2073 friend StmtVisitorBase;
2076 ConstantLValueEmitter(ConstantEmitter &emitter,
const APValue &value,
2078 bool EnablePtrAuthFunctionTypeDiscrimination =
true)
2079 : CGM(emitter.CGM), Emitter(emitter),
Value(value), DestType(destType),
2080 EnablePtrAuthFunctionTypeDiscrimination(
2081 EnablePtrAuthFunctionTypeDiscrimination) {}
2083 llvm::Constant *tryEmit();
2086 llvm::Constant *tryEmitAbsolute(llvm::Type *destTy);
2087 ConstantLValue tryEmitBase(
const APValue::LValueBase &base);
2089 ConstantLValue VisitStmt(
const Stmt *S) {
return nullptr; }
2090 ConstantLValue VisitConstantExpr(
const ConstantExpr *E);
2091 ConstantLValue VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
2092 ConstantLValue VisitStringLiteral(
const StringLiteral *E);
2093 ConstantLValue VisitObjCBoxedExpr(
const ObjCBoxedExpr *E);
2094 ConstantLValue VisitObjCEncodeExpr(
const ObjCEncodeExpr *E);
2095 ConstantLValue VisitObjCStringLiteral(
const ObjCStringLiteral *E);
2096 ConstantLValue VisitPredefinedExpr(
const PredefinedExpr *E);
2097 ConstantLValue VisitAddrLabelExpr(
const AddrLabelExpr *E);
2098 ConstantLValue VisitCallExpr(
const CallExpr *E);
2099 ConstantLValue VisitBlockExpr(
const BlockExpr *E);
2100 ConstantLValue VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
2101 ConstantLValue VisitMaterializeTemporaryExpr(
2102 const MaterializeTemporaryExpr *E);
2104 ConstantLValue emitPointerAuthSignConstant(
const CallExpr *E);
2105 llvm::Constant *emitPointerAuthPointer(
const Expr *E);
2106 unsigned emitPointerAuthKey(
const Expr *E);
2107 std::pair<llvm::Constant *, llvm::ConstantInt *>
2108 emitPointerAuthDiscriminator(
const Expr *E);
2110 bool hasNonZeroOffset()
const {
2111 return !
Value.getLValueOffset().isZero();
2115 llvm::Constant *getOffset() {
2116 return llvm::ConstantInt::get(CGM.
Int64Ty,
2117 Value.getLValueOffset().getQuantity());
2121 llvm::Constant *applyOffset(llvm::Constant *
C) {
2122 if (!hasNonZeroOffset())
2125 return llvm::ConstantExpr::getGetElementPtr(CGM.
Int8Ty,
C, getOffset());
2131llvm::Constant *ConstantLValueEmitter::tryEmit() {
2132 const APValue::LValueBase &base =
Value.getLValueBase();
2147 return tryEmitAbsolute(destTy);
2151 ConstantLValue result = tryEmitBase(base);
2154 llvm::Constant *value = result.Value;
2155 if (!value)
return nullptr;
2158 if (!result.HasOffsetApplied) {
2159 value = applyOffset(value);
2163 if (PointerAuthQualifier PointerAuth = DestType.
getPointerAuth();
2164 PointerAuth && !result.HasDestPointerAuth) {
2173 return llvm::ConstantExpr::getPointerCast(value, destTy);
2175 return llvm::ConstantExpr::getPtrToInt(value, destTy);
2181ConstantLValueEmitter::tryEmitAbsolute(llvm::Type *destTy) {
2184 if (
Value.isNullPointer()) {
2192 auto intptrTy = CGM.
getDataLayout().getIntPtrType(destPtrTy);
2194 C = llvm::ConstantFoldIntegerCast(getOffset(), intptrTy,
false,
2196 assert(
C &&
"Must have folded, as Offset is a ConstantInt");
2197 C = llvm::ConstantExpr::getIntToPtr(
C, destPtrTy);
2202ConstantLValueEmitter::tryEmitBase(
const APValue::LValueBase &base) {
2204 if (
const ValueDecl *D = base.
dyn_cast<
const ValueDecl*>()) {
2209 if (D->hasAttr<WeakRefAttr>())
2212 auto PtrAuthSign = [&](llvm::Constant *
C) {
2213 if (PointerAuthQualifier PointerAuth = DestType.
getPointerAuth()) {
2216 return ConstantLValue(
C,
true,
true);
2219 CGPointerAuthInfo AuthInfo;
2221 if (EnablePtrAuthFunctionTypeDiscrimination)
2225 if (hasNonZeroOffset())
2226 return ConstantLValue(
nullptr);
2230 C, AuthInfo.
getKey(),
nullptr,
2232 return ConstantLValue(
C,
true,
true);
2235 return ConstantLValue(
C);
2238 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
2240 if (FD->getType()->isCFIUncheckedCalleeFunctionType())
2242 return PtrAuthSign(
C);
2245 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
2247 if (!VD->hasLocalStorage()) {
2248 if (VD->isFileVarDecl() || VD->hasExternalStorage())
2251 if (VD->isLocalVarDecl()) {
2258 if (
const auto *GD = dyn_cast<MSGuidDecl>(D))
2261 if (
const auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D))
2264 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D))
2271 if (TypeInfoLValue TI = base.
dyn_cast<TypeInfoLValue>())
2275 return Visit(base.
get<
const Expr*>());
2279ConstantLValueEmitter::VisitConstantExpr(
const ConstantExpr *E) {
2286ConstantLValueEmitter::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
2287 ConstantEmitter CompoundLiteralEmitter(CGM, Emitter.
CGF);
2289 return tryEmitGlobalCompoundLiteral(CompoundLiteralEmitter, E);
2293ConstantLValueEmitter::VisitStringLiteral(
const StringLiteral *E) {
2298ConstantLValueEmitter::VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
2310ConstantLValueEmitter::VisitObjCStringLiteral(
const ObjCStringLiteral *E) {
2315ConstantLValueEmitter::VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
2317 "this boxed expression can't be emitted as a compile-time constant");
2323ConstantLValueEmitter::VisitPredefinedExpr(
const PredefinedExpr *E) {
2328ConstantLValueEmitter::VisitAddrLabelExpr(
const AddrLabelExpr *E) {
2329 assert(Emitter.
CGF &&
"Invalid address of label expression outside function");
2335ConstantLValueEmitter::VisitCallExpr(
const CallExpr *E) {
2337 if (builtin == Builtin::BI__builtin_function_start)
2341 if (builtin == Builtin::BI__builtin_ptrauth_sign_constant)
2342 return emitPointerAuthSignConstant(E);
2344 if (builtin != Builtin::BI__builtin___CFStringMakeConstantString &&
2345 builtin != Builtin::BI__builtin___NSStringMakeConstantString)
2349 if (builtin == Builtin::BI__builtin___NSStringMakeConstantString) {
2358ConstantLValueEmitter::emitPointerAuthSignConstant(
const CallExpr *E) {
2359 llvm::Constant *UnsignedPointer = emitPointerAuthPointer(E->
getArg(0));
2360 unsigned Key = emitPointerAuthKey(E->
getArg(1));
2361 auto [StorageAddress, OtherDiscriminator] =
2362 emitPointerAuthDiscriminator(E->
getArg(2));
2365 UnsignedPointer, Key, StorageAddress, OtherDiscriminator);
2366 return SignedPointer;
2369llvm::Constant *ConstantLValueEmitter::emitPointerAuthPointer(
const Expr *E) {
2376 assert(
Result.Val.isLValue());
2378 assert(
Result.Val.getLValueOffset().isZero());
2379 return ConstantEmitter(CGM, Emitter.
CGF)
2383unsigned ConstantLValueEmitter::emitPointerAuthKey(
const Expr *E) {
2387std::pair<llvm::Constant *, llvm::ConstantInt *>
2388ConstantLValueEmitter::emitPointerAuthDiscriminator(
const Expr *E) {
2391 if (
const auto *
Call = dyn_cast<CallExpr>(E)) {
2392 if (
Call->getBuiltinCallee() ==
2393 Builtin::BI__builtin_ptrauth_blend_discriminator) {
2394 llvm::Constant *
Pointer = ConstantEmitter(CGM).emitAbstract(
2395 Call->getArg(0),
Call->getArg(0)->getType());
2397 Call->getArg(1),
Call->getArg(1)->getType()));
2402 llvm::Constant *
Result = ConstantEmitter(CGM).emitAbstract(E, E->
getType());
2403 if (
Result->getType()->isPointerTy())
2404 return {
Result,
nullptr};
2409ConstantLValueEmitter::VisitBlockExpr(
const BlockExpr *E) {
2410 StringRef functionName;
2411 if (
auto CGF = Emitter.
CGF)
2412 functionName = CGF->CurFn->getName();
2414 functionName =
"global";
2420ConstantLValueEmitter::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
2430ConstantLValueEmitter::VisitMaterializeTemporaryExpr(
2431 const MaterializeTemporaryExpr *E) {
2439 bool EnablePtrAuthFunctionTypeDiscrimination) {
2444 return llvm::UndefValue::get(
CGM.getTypes().ConvertType(DestType));
2446 return ConstantLValueEmitter(*
this,
Value, DestType,
2447 EnablePtrAuthFunctionTypeDiscrimination)
2452 (PointerAuth.authenticatesNullValues() ||
Value.getInt() != 0))
2454 return llvm::ConstantInt::get(
CGM.getLLVMContext(),
Value.getInt());
2456 return llvm::ConstantInt::get(
CGM.getLLVMContext(),
2457 Value.getFixedPoint().getValue());
2461 Complex[0] = llvm::ConstantInt::get(
CGM.getLLVMContext(),
2462 Value.getComplexIntReal());
2463 Complex[1] = llvm::ConstantInt::get(
CGM.getLLVMContext(),
2464 Value.getComplexIntImag());
2467 llvm::StructType *STy =
2469 return llvm::ConstantStruct::get(STy,
Complex);
2472 const llvm::APFloat &
Init =
Value.getFloat();
2473 if (&
Init.getSemantics() == &llvm::APFloat::IEEEhalf() &&
2474 !
CGM.getContext().getLangOpts().NativeHalfType &&
2475 CGM.getContext().getTargetInfo().useFP16ConversionIntrinsics())
2476 return llvm::ConstantInt::get(
CGM.getLLVMContext(),
2477 Init.bitcastToAPInt());
2479 return llvm::ConstantFP::get(
CGM.getLLVMContext(),
Init);
2484 Complex[0] = llvm::ConstantFP::get(
CGM.getLLVMContext(),
2485 Value.getComplexFloatReal());
2486 Complex[1] = llvm::ConstantFP::get(
CGM.getLLVMContext(),
2487 Value.getComplexFloatImag());
2490 llvm::StructType *STy =
2492 return llvm::ConstantStruct::get(STy,
Complex);
2495 unsigned NumElts =
Value.getVectorLength();
2498 for (
unsigned I = 0; I != NumElts; ++I) {
2501 Inits[I] = llvm::ConstantInt::get(
CGM.getLLVMContext(), Elt.
getInt());
2503 Inits[I] = llvm::ConstantFP::get(
CGM.getLLVMContext(), Elt.
getFloat());
2505 Inits[I] = llvm::UndefValue::get(
CGM.getTypes().ConvertType(
2508 llvm_unreachable(
"unsupported vector element type");
2510 return llvm::ConstantVector::get(Inits);
2517 if (!LHS || !RHS)
return nullptr;
2520 llvm::Type *ResultType =
CGM.getTypes().ConvertType(DestType);
2521 LHS = llvm::ConstantExpr::getPtrToInt(LHS,
CGM.IntPtrTy);
2522 RHS = llvm::ConstantExpr::getPtrToInt(RHS,
CGM.IntPtrTy);
2523 llvm::Constant *AddrLabelDiff = llvm::ConstantExpr::getSub(LHS, RHS);
2528 return llvm::ConstantExpr::getTruncOrBitCast(AddrLabelDiff, ResultType);
2532 return ConstStructBuilder::BuildStruct(*
this,
Value, DestType);
2534 const ArrayType *ArrayTy =
CGM.getContext().getAsArrayType(DestType);
2535 unsigned NumElements =
Value.getArraySize();
2536 unsigned NumInitElts =
Value.getArrayInitializedElts();
2539 llvm::Constant *Filler =
nullptr;
2540 if (
Value.hasArrayFiller()) {
2549 if (Filler && Filler->isNullValue())
2550 Elts.reserve(NumInitElts + 1);
2552 Elts.reserve(NumElements);
2554 llvm::Type *CommonElementType =
nullptr;
2555 for (
unsigned I = 0; I < NumInitElts; ++I) {
2558 if (!
C)
return nullptr;
2561 CommonElementType =
C->getType();
2562 else if (
C->getType() != CommonElementType)
2563 CommonElementType =
nullptr;
2567 llvm::ArrayType *Desired =
2572 Desired = llvm::ArrayType::get(Desired->getElementType(), Elts.size());
2574 return EmitArrayConstant(
CGM, Desired, CommonElementType, NumElements, Elts,
2578 return CGM.getCXXABI().EmitMemberPointer(
Value, DestType);
2580 llvm_unreachable(
"Unknown APValue kind");
2585 return EmittedCompoundLiterals.lookup(E);
2590 bool Ok = EmittedCompoundLiterals.insert(std::make_pair(CLE, GV)).second;
2592 assert(
Ok &&
"CLE has already been emitted!");
2597 assert(E->
isFileScope() &&
"not a file-scope compound literal expr");
2599 return tryEmitGlobalCompoundLiteral(emitter, E);
2610 return getCXXABI().EmitMemberFunctionPointer(method);
2619 llvm::Type *baseType,
2624 bool asCompleteObject) {
2626 llvm::StructType *structure =
2630 unsigned numElements = structure->getNumElements();
2631 std::vector<llvm::Constant *> elements(numElements);
2633 auto CXXR = dyn_cast<CXXRecordDecl>(record);
2636 for (
const auto &I : CXXR->bases()) {
2637 if (I.isVirtual()) {
2653 llvm::Type *baseType = structure->getElementType(fieldIndex);
2659 for (
const auto *Field : record->
fields()) {
2662 if (!Field->isBitField() &&
2670 if (Field->getIdentifier())
2672 if (
const auto *FieldRD = Field->getType()->getAsRecordDecl())
2673 if (FieldRD->findFirstNamedDataMember())
2679 if (CXXR && asCompleteObject) {
2680 for (
const auto &I : CXXR->vbases()) {
2689 if (elements[fieldIndex])
continue;
2691 llvm::Type *baseType = structure->getElementType(fieldIndex);
2697 for (
unsigned i = 0; i != numElements; ++i) {
2699 elements[i] = llvm::Constant::getNullValue(structure->getElementType(i));
2702 return llvm::ConstantStruct::get(structure, elements);
2707 llvm::Type *baseType,
2713 return llvm::Constant::getNullValue(baseType);
2730 return llvm::Constant::getNullValue(
getTypes().ConvertTypeForMem(
T));
2733 llvm::ArrayType *ATy =
2738 llvm::Constant *Element =
2742 return llvm::ConstantArray::get(ATy, Array);
2745 if (
const auto *RD =
T->getAsRecordDecl())
2746 return ::EmitNullConstant(*
this, RD,
2749 assert(
T->isMemberDataPointerType() &&
2750 "Should only see pointers to data members here!");
2757 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.
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,...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
const LangOptions & getLangOpts() const
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.
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
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.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
unsigned getTargetAddressSpace(LangAS AS) const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
bool hasOwnVFPtr() const
hasOwnVFPtr - Does this class provide its own virtual-function table pointer, rather than inheriting ...
CharUnits getSize() const
getSize - Get the record size in characters.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
CharUnits getNonVirtualSize() const
getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...
AddrLabelExpr - The GNU address of label extension, representing &&label.
LabelDecl * getLabel() const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
Represents a call to a C++ constructor.
Expr * getArg(unsigned Arg)
Return the specified argument.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ constructor within a class.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
Expr * getExpr()
Get the initialization expression that will be used.
Represents a static or instance method of a struct/union/class.
Represents a C++ struct/union/class.
const CXXBaseSpecifier * base_class_const_iterator
Iterator that traverses the base classes of a class.
bool isTypeOperand() const
QualType getTypeOperand(const ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
Expr * getExprOperand() const
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
CastKind getCastKind() const
const FieldDecl * getTargetUnionField() const
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
virtual llvm::Constant * getVTableAddressPoint(BaseSubobject Base, const CXXRecordDecl *VTableClass)=0
Get the address point of the vtable for the given base subobject.
virtual llvm::Value * EmitMemberPointerConversion(CodeGenFunction &CGF, const CastExpr *E, llvm::Value *Src)
Perform a derived-to-base, base-to-derived, or bitcast member pointer conversion.
virtual ConstantAddress GenerateConstantString(const StringLiteral *)=0
Generate a constant string object.
llvm::Value * getDiscriminator() const
CGRecordLayout - This class handles struct and union layout info while lowering AST types to LLVM typ...
unsigned getNonVirtualBaseLLVMFieldNo(const CXXRecordDecl *RD) const
llvm::StructType * getLLVMType() const
Return the "complete object" LLVM type associated with this record.
const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const
Return the BitFieldInfo that corresponds to the field FD.
bool isZeroInitializableAsBase() const
Check whether this struct can be C++ zero-initialized with a zeroinitializer when considered as a bas...
llvm::StructType * getBaseSubobjectLLVMType() const
Return the "base subobject" LLVM type associated with this record.
unsigned getLLVMFieldNo(const FieldDecl *FD) const
Return llvm::StructType element number that corresponds to the field FD.
unsigned getVirtualBaseIndex(const CXXRecordDecl *base) const
Return the LLVM field index corresponding to the given virtual base.
llvm::BlockAddress * GetAddrOfLabel(const LabelDecl *L)
This class organizes the cross-function state that is used while generating LLVM code.
ConstantAddress GetAddrOfMSGuidDecl(const MSGuidDecl *GD)
Get the address of a GUID.
void EmitExplicitCastExprType(const ExplicitCastExpr *E, CodeGenFunction *CGF=nullptr)
Emit type info if type of an expression is a variably modified type.
llvm::Module & getModule() const
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.
CGPointerAuthInfo getFunctionPointerAuthInfo(QualType T)
Return the abstract pointer authentication schema for a pointer to the given function type.
llvm::Constant * GetFunctionStart(const ValueDecl *Decl)
llvm::GlobalVariable * getAddrOfConstantCompoundLiteralIfEmitted(const CompoundLiteralExpr *E)
If it's been emitted already, returns the GlobalVariable corresponding to a compound literal.
std::optional< PointerAuthQualifier > getVTablePointerAuthentication(const CXXRecordDecl *thisClass)
llvm::Constant * getOrCreateStaticVarDecl(const VarDecl &D, llvm::GlobalValue::LinkageTypes Linkage)
ConstantAddress GetAddrOfConstantCFString(const StringLiteral *Literal)
Return a pointer to a constant CFString object for the given string.
ConstantAddress GetAddrOfConstantStringFromLiteral(const StringLiteral *S, StringRef Name=".str")
Return a pointer to a constant array for the given string literal.
ASTContext & getContext() const
ConstantAddress GetAddrOfTemplateParamObject(const TemplateParamObjectDecl *TPO)
Get the address of a template parameter object.
ConstantAddress GetAddrOfUnnamedGlobalConstantDecl(const UnnamedGlobalConstantDecl *GCD)
Get the address of a UnnamedGlobalConstant.
llvm::Constant * GetAddrOfGlobalVar(const VarDecl *D, llvm::Type *Ty=nullptr, ForDefinition_t IsForDefinition=NotForDefinition)
Return the llvm::Constant for the address of the given global variable.
void setAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *CLE, llvm::GlobalVariable *GV)
Notes that CLE's GlobalVariable is GV.
const TargetCodeGenInfo & getTargetCodeGenInfo()
llvm::Constant * GetConstantArrayFromStringLiteral(const StringLiteral *E)
Return a constant array for the given string.
llvm::LLVMContext & getLLVMContext()
bool shouldZeroInitPadding() const
CGObjCRuntime & getObjCRuntime()
Return a reference to the configured Objective-C runtime.
ConstantAddress GetAddrOfGlobalTemporary(const MaterializeTemporaryExpr *E, const Expr *Inner)
Returns a pointer to a global variable representing a temporary with static or thread storage duratio...
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
llvm::Constant * getConstantSignedPointer(llvm::Constant *Pointer, const PointerAuthSchema &Schema, llvm::Constant *StorageAddress, GlobalDecl SchemaDecl, QualType SchemaType)
Sign a constant pointer using the given scheme, producing a constant with the same IR type.
ConstantAddress GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *)
Return a pointer to a constant array for the given ObjCEncodeExpr node.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
llvm::Type * convertTypeForLoadStore(QualType T, llvm::Type *LLVMTy=nullptr)
Given that T is a scalar type, return the IR type that should be used for load and store operations.
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
A specialization of Address that requires the address to be an LLVM Constant.
static ConstantAddress invalid()
llvm::Constant * getPointer() const
llvm::Constant * tryEmitPrivateForMemory(const Expr *E, QualType T)
llvm::Constant * tryEmitForInitializer(const VarDecl &D)
Try to emit the initiaizer of the given declaration as an abstract constant.
llvm::Constant * tryEmitPrivateForVarInit(const VarDecl &D)
llvm::Constant * tryEmitPrivate(const Expr *E, QualType T)
void finalize(llvm::GlobalVariable *global)
llvm::Constant * tryEmitAbstractForInitializer(const VarDecl &D)
Try to emit the initializer of the given declaration as an abstract constant.
llvm::Constant * emitAbstract(const Expr *E, QualType T)
Emit the result of the given expression as an abstract constant, asserting that it succeeded.
llvm::GlobalValue * getCurrentAddrPrivate()
Get the address of the current location.
llvm::Constant * tryEmitConstantExpr(const ConstantExpr *CE)
llvm::Constant * emitForMemory(llvm::Constant *C, QualType T)
llvm::Constant * emitNullForMemory(QualType T)
bool isInConstantContext() const
llvm::Constant * tryEmitAbstract(const Expr *E, QualType T)
Try to emit the result of the given expression as an abstract constant.
CodeGenFunction *const CGF
void registerCurrentAddrPrivate(llvm::Constant *signal, llvm::GlobalValue *placeholder)
Register a 'signal' value with the emitter to inform it where to resolve a placeholder.
llvm::Constant * emitForInitializer(const APValue &value, LangAS destAddrSpace, QualType destType)
llvm::Constant * tryEmitAbstractForMemory(const Expr *E, QualType T)
bool isAbstract() const
Is the current emission context abstract?
llvm::Constant * tryEmitConstantSignedPointer(llvm::Constant *Ptr, PointerAuthQualifier Auth)
Try to emit a constant signed pointer, given a raw pointer and the destination ptrauth qualifier.
Address performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, Address Addr, LangAS SrcAddr, llvm::Type *DestTy, bool IsNonNull=false) const
CompoundLiteralExpr - [C99 6.5.2.5].
const Expr * getInitializer() const
Represents the canonical version of C arrays with a specified constant size.
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
APValue getAPValueResult() const
bool hasAPValueResult() const
InitListExpr * getUpdater() const
This represents one expression.
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Returns the set of floating point options that apply to this expression.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
const ValueDecl * getAsBuiltinConstantDeclRef(const ASTContext &Context) const
If this expression is an unambiguous reference to a single declaration, in the style of __builtin_fun...
RoundingMode getRoundingMode() const
const Expr * getSubExpr() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
FieldDecl * getInitializedFieldInUnion()
If this initializes a union, specifies which field in the union to initialize.
unsigned getNumInits() const
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
const Expr * getInit(unsigned Init) const
ArrayRef< Expr * > inits()
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
A pointer to member type per C++ 8.3.3 - Pointers to members.
bool isExpressibleAsConstantInitializer() const
QualType getEncodedType() const
StringLiteral * getString()
Expr * getSelectedExpr() const
const Expr * getSubExpr() const
Pointer-authentication qualifiers.
bool isAddressDiscriminated() const
unsigned getExtraDiscriminator() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
StringLiteral * getFunctionName()
A (possibly-)qualified type.
PointerAuthQualifier getPointerAuth() const
LangAS getAddressSpace() const
Return the address space of this type.
bool isConstantStorage(const ASTContext &Ctx, bool ExcludeCtor, bool ExcludeDtor)
Represents a struct/union/class.
bool hasFlexibleArrayMember() const
field_iterator field_end() const
field_range fields() const
specific_decl_iterator< FieldDecl > field_iterator
field_iterator field_begin() const
Encodes a location in the source.
StringLiteral - This represents a string literal expression, e.g.
uint32_t getCodeUnit(size_t i) const
Expr * getReplacement() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isPackedVectorBoolType(const ASTContext &ctx) const
bool isIncompleteArrayType() const
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
CXXRecordDecl * castAsCXXRecordDecl() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
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.
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.
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.
const FunctionProtoType * T
@ Type
The name was classified as a type.
LangAS
Defines the address space values used by the address space qualifier of QualType.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
U cast(CodeGen::Address addr)
@ ArrayBound
Array bound in array declarator or new-expression.
unsigned Size
The total size of the bit-field, in bits.
llvm::IntegerType * Int64Ty
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * CharTy
char
llvm::IntegerType * Int32Ty
EvalResult is a struct with detailed info about an evaluated expression.