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"
36using namespace CodeGen;
43class ConstExprEmitter;
45struct ConstantAggregateBuilderUtils {
48 ConstantAggregateBuilderUtils(
CodeGenModule &CGM) : CGM(CGM) {}
50 CharUnits getAlignment(
const llvm::Constant *
C)
const {
59 CharUnits getSize(
const llvm::Constant *
C)
const {
60 return getSize(
C->getType());
63 llvm::Constant *getPadding(
CharUnits PadSize)
const {
64 llvm::Type *Ty = CGM.
CharTy;
66 Ty = llvm::ArrayType::get(Ty, PadSize.
getQuantity());
67 return llvm::UndefValue::get(Ty);
70 llvm::Constant *getZeroes(
CharUnits ZeroSize)
const {
72 return llvm::ConstantAggregateZero::get(Ty);
78class ConstantAggregateBuilder :
private ConstantAggregateBuilderUtils {
97 bool NaturalLayout =
true;
100 std::optional<size_t> splitAt(
CharUnits Pos);
106 bool NaturalLayout, llvm::Type *DesiredTy,
107 bool AllowOversized);
111 : ConstantAggregateBuilderUtils(CGM) {}
118 bool add(llvm::Constant *
C,
CharUnits Offset,
bool AllowOverwrite);
121 bool addBits(llvm::APInt Bits, uint64_t OffsetInBits,
bool AllowOverwrite);
125 void condense(
CharUnits Offset, llvm::Type *DesiredTy);
132 llvm::Constant *build(llvm::Type *DesiredTy,
bool AllowOversized)
const {
134 NaturalLayout, DesiredTy, AllowOversized);
138template<
typename Container,
typename Range = std::initializer_list<
139 typename Container::value_type>>
140static void replace(Container &
C,
size_t BeginOff,
size_t EndOff,
Range Vals) {
141 assert(BeginOff <= EndOff &&
"invalid replacement range");
142 llvm::replace(
C,
C.begin() + BeginOff,
C.begin() + EndOff, Vals);
145bool ConstantAggregateBuilder::add(llvm::Constant *
C,
CharUnits Offset,
146 bool AllowOverwrite) {
148 if (Offset >= Size) {
151 if (AlignedSize > Offset || Offset.alignTo(Align) != Offset)
152 NaturalLayout =
false;
153 else if (AlignedSize < Offset) {
154 Elems.push_back(getPadding(Offset - Size));
155 Offsets.push_back(Size);
158 Offsets.push_back(Offset);
159 Size = Offset + getSize(
C);
164 std::optional<size_t> FirstElemToReplace = splitAt(Offset);
165 if (!FirstElemToReplace)
169 std::optional<size_t> LastElemToReplace = splitAt(Offset + CSize);
170 if (!LastElemToReplace)
173 assert((FirstElemToReplace == LastElemToReplace || AllowOverwrite) &&
174 "unexpectedly overwriting field");
176 replace(Elems, *FirstElemToReplace, *LastElemToReplace, {
C});
177 replace(Offsets, *FirstElemToReplace, *LastElemToReplace, {Offset});
178 Size = std::max(Size, Offset + CSize);
179 NaturalLayout =
false;
183bool ConstantAggregateBuilder::addBits(llvm::APInt Bits, uint64_t OffsetInBits,
184 bool AllowOverwrite) {
190 unsigned OffsetWithinChar = OffsetInBits % CharWidth;
198 unsigned WantedBits =
199 std::min((uint64_t)Bits.getBitWidth(), CharWidth - OffsetWithinChar);
203 llvm::APInt BitsThisChar = Bits;
204 if (BitsThisChar.getBitWidth() < CharWidth)
205 BitsThisChar = BitsThisChar.zext(CharWidth);
209 int Shift = Bits.getBitWidth() - CharWidth + OffsetWithinChar;
211 BitsThisChar.lshrInPlace(Shift);
213 BitsThisChar = BitsThisChar.shl(-Shift);
215 BitsThisChar = BitsThisChar.shl(OffsetWithinChar);
217 if (BitsThisChar.getBitWidth() > CharWidth)
218 BitsThisChar = BitsThisChar.trunc(CharWidth);
220 if (WantedBits == CharWidth) {
223 OffsetInChars, AllowOverwrite);
228 std::optional<size_t> FirstElemToUpdate = splitAt(OffsetInChars);
229 if (!FirstElemToUpdate)
231 std::optional<size_t> LastElemToUpdate =
233 if (!LastElemToUpdate)
235 assert(*LastElemToUpdate - *FirstElemToUpdate < 2 &&
236 "should have at most one element covering one byte");
239 llvm::APInt UpdateMask(CharWidth, 0);
241 UpdateMask.setBits(CharWidth - OffsetWithinChar - WantedBits,
242 CharWidth - OffsetWithinChar);
244 UpdateMask.setBits(OffsetWithinChar, OffsetWithinChar + WantedBits);
245 BitsThisChar &= UpdateMask;
247 if (*FirstElemToUpdate == *LastElemToUpdate ||
248 Elems[*FirstElemToUpdate]->isNullValue() ||
249 isa<llvm::UndefValue>(Elems[*FirstElemToUpdate])) {
252 OffsetInChars,
true);
254 llvm::Constant *&ToUpdate = Elems[*FirstElemToUpdate];
257 auto *CI = dyn_cast<llvm::ConstantInt>(ToUpdate);
262 assert(CI->getBitWidth() == CharWidth &&
"splitAt failed");
263 assert((!(CI->getValue() & UpdateMask) || AllowOverwrite) &&
264 "unexpectedly overwriting bitfield");
265 BitsThisChar |= (CI->getValue() & ~UpdateMask);
266 ToUpdate = llvm::ConstantInt::get(CGM.
getLLVMContext(), BitsThisChar);
271 if (WantedBits == Bits.getBitWidth())
276 Bits.lshrInPlace(WantedBits);
277 Bits = Bits.trunc(Bits.getBitWidth() - WantedBits);
280 OffsetWithinChar = 0;
290std::optional<size_t> ConstantAggregateBuilder::splitAt(
CharUnits Pos) {
292 return Offsets.size();
295 auto FirstAfterPos = llvm::upper_bound(Offsets, Pos);
296 if (FirstAfterPos == Offsets.begin())
300 size_t LastAtOrBeforePosIndex = FirstAfterPos - Offsets.begin() - 1;
301 if (Offsets[LastAtOrBeforePosIndex] == Pos)
302 return LastAtOrBeforePosIndex;
305 if (Offsets[LastAtOrBeforePosIndex] +
306 getSize(Elems[LastAtOrBeforePosIndex]) <= Pos)
307 return LastAtOrBeforePosIndex + 1;
310 if (!split(LastAtOrBeforePosIndex, Pos))
318bool ConstantAggregateBuilder::split(
size_t Index,
CharUnits Hint) {
319 NaturalLayout =
false;
320 llvm::Constant *
C = Elems[Index];
323 if (
auto *CA = dyn_cast<llvm::ConstantAggregate>(
C)) {
326 replace(Elems, Index, Index + 1,
327 llvm::map_range(llvm::seq(0u, CA->getNumOperands()),
328 [&](
unsigned Op) { return CA->getOperand(Op); }));
329 if (isa<llvm::ArrayType>(CA->getType()) ||
330 isa<llvm::VectorType>(CA->getType())) {
333 llvm::GetElementPtrInst::getTypeAtIndex(CA->getType(), (uint64_t)0);
336 Offsets, Index, Index + 1,
337 llvm::map_range(llvm::seq(0u, CA->getNumOperands()),
338 [&](
unsigned Op) { return Offset + Op * ElemSize; }));
341 auto *ST = cast<llvm::StructType>(CA->getType());
342 const llvm::StructLayout *Layout =
344 replace(Offsets, Index, Index + 1,
346 llvm::seq(0u, CA->getNumOperands()), [&](
unsigned Op) {
347 return Offset + CharUnits::fromQuantity(
348 Layout->getElementOffset(Op));
354 if (
auto *CDS = dyn_cast<llvm::ConstantDataSequential>(
C)) {
358 CharUnits ElemSize = getSize(CDS->getElementType());
359 replace(Elems, Index, Index + 1,
360 llvm::map_range(llvm::seq(0u, CDS->getNumElements()),
362 return CDS->getElementAsConstant(Elem);
364 replace(Offsets, Index, Index + 1,
366 llvm::seq(0u, CDS->getNumElements()),
367 [&](
unsigned Elem) { return Offset + Elem * ElemSize; }));
371 if (isa<llvm::ConstantAggregateZero>(
C)) {
374 assert(Hint > Offset && Hint < Offset + ElemSize &&
"nothing to split");
375 replace(Elems, Index, Index + 1,
376 {getZeroes(Hint - Offset), getZeroes(Offset + ElemSize - Hint)});
377 replace(Offsets, Index, Index + 1, {Offset, Hint});
381 if (isa<llvm::UndefValue>(
C)) {
383 replace(Elems, Index, Index + 1, {});
384 replace(Offsets, Index, Index + 1, {});
395static llvm::Constant *
396EmitArrayConstant(
CodeGenModule &CGM, llvm::ArrayType *DesiredType,
397 llvm::Type *CommonElementType, uint64_t ArrayBound,
399 llvm::Constant *Filler);
401llvm::Constant *ConstantAggregateBuilder::buildFrom(
404 bool NaturalLayout, llvm::Type *DesiredTy,
bool AllowOversized) {
405 ConstantAggregateBuilderUtils Utils(CGM);
408 return llvm::UndefValue::get(DesiredTy);
410 auto Offset = [&](
size_t I) {
return Offsets[I] - StartOffset; };
414 if (llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(DesiredTy)) {
415 assert(!AllowOversized &&
"oversized array emission not supported");
417 bool CanEmitArray =
true;
418 llvm::Type *CommonType = Elems[0]->getType();
419 llvm::Constant *Filler = llvm::Constant::getNullValue(CommonType);
420 CharUnits ElemSize = Utils.getSize(ATy->getElementType());
422 for (
size_t I = 0; I != Elems.size(); ++I) {
424 if (Elems[I]->isNullValue())
428 if (Elems[I]->getType() != CommonType ||
429 Offset(I) % ElemSize != 0) {
430 CanEmitArray =
false;
433 ArrayElements.resize(Offset(I) / ElemSize + 1, Filler);
434 ArrayElements.back() = Elems[I];
438 return EmitArrayConstant(CGM, ATy, CommonType, ATy->getNumElements(),
439 ArrayElements, Filler);
448 CharUnits DesiredSize = Utils.getSize(DesiredTy);
449 if (Size > DesiredSize) {
450 assert(AllowOversized &&
"Elems are oversized");
456 for (llvm::Constant *
C : Elems)
457 Align = std::max(Align, Utils.getAlignment(
C));
465 if (DesiredSize < AlignedSize || DesiredSize.
alignTo(Align) != DesiredSize) {
467 NaturalLayout =
false;
469 }
else if (DesiredSize > AlignedSize) {
472 UnpackedElemStorage.assign(Elems.begin(), Elems.end());
473 UnpackedElemStorage.push_back(Utils.getPadding(DesiredSize - Size));
474 UnpackedElems = UnpackedElemStorage;
481 if (!NaturalLayout) {
483 for (
size_t I = 0; I != Elems.size(); ++I) {
484 CharUnits Align = Utils.getAlignment(Elems[I]);
487 assert(DesiredOffset >= SizeSoFar &&
"elements out of order");
489 if (DesiredOffset != NaturalOffset)
491 if (DesiredOffset != SizeSoFar)
492 PackedElems.push_back(Utils.getPadding(DesiredOffset - SizeSoFar));
493 PackedElems.push_back(Elems[I]);
494 SizeSoFar = DesiredOffset + Utils.getSize(Elems[I]);
499 assert(SizeSoFar <= DesiredSize &&
500 "requested size is too small for contents");
501 if (SizeSoFar < DesiredSize)
502 PackedElems.push_back(Utils.getPadding(DesiredSize - SizeSoFar));
506 llvm::StructType *STy = llvm::ConstantStruct::getTypeForElements(
507 CGM.
getLLVMContext(), Packed ? PackedElems : UnpackedElems, Packed);
511 if (llvm::StructType *DesiredSTy = dyn_cast<llvm::StructType>(DesiredTy)) {
512 if (DesiredSTy->isLayoutIdentical(STy))
516 return llvm::ConstantStruct::get(STy, Packed ? PackedElems : UnpackedElems);
519void ConstantAggregateBuilder::condense(
CharUnits Offset,
520 llvm::Type *DesiredTy) {
523 std::optional<size_t> FirstElemToReplace = splitAt(Offset);
524 if (!FirstElemToReplace)
526 size_t First = *FirstElemToReplace;
528 std::optional<size_t> LastElemToReplace = splitAt(Offset + Size);
529 if (!LastElemToReplace)
531 size_t Last = *LastElemToReplace;
537 if (Length == 1 && Offsets[
First] == Offset &&
538 getSize(Elems[
First]) == Size) {
541 auto *STy = dyn_cast<llvm::StructType>(DesiredTy);
542 if (STy && STy->getNumElements() == 1 &&
543 STy->getElementType(0) == Elems[
First]->getType())
544 Elems[
First] = llvm::ConstantStruct::get(STy, Elems[
First]);
548 llvm::Constant *Replacement = buildFrom(
550 ArrayRef(Offsets).slice(
First, Length), Offset, getSize(DesiredTy),
551 false, DesiredTy,
false);
552 replace(Elems,
First,
Last, {Replacement});
560class ConstStructBuilder {
563 ConstantAggregateBuilder &Builder;
573 ConstantAggregateBuilder &Const,
CharUnits Offset,
578 ConstantAggregateBuilder &Builder,
CharUnits StartOffset)
580 StartOffset(StartOffset) {}
582 bool AppendField(
const FieldDecl *Field, uint64_t FieldOffset,
583 llvm::Constant *InitExpr,
bool AllowOverwrite =
false);
585 bool AppendBytes(
CharUnits FieldOffsetInChars, llvm::Constant *InitCst,
586 bool AllowOverwrite =
false);
588 bool AppendBitField(
const FieldDecl *Field, uint64_t FieldOffset,
589 llvm::Constant *InitExpr,
bool AllowOverwrite =
false);
591 bool Build(
const InitListExpr *ILE,
bool AllowOverwrite);
597bool ConstStructBuilder::AppendField(
598 const FieldDecl *Field, uint64_t FieldOffset, llvm::Constant *InitCst,
599 bool AllowOverwrite) {
604 return AppendBytes(FieldOffsetInChars, InitCst, AllowOverwrite);
607bool ConstStructBuilder::AppendBytes(
CharUnits FieldOffsetInChars,
608 llvm::Constant *InitCst,
609 bool AllowOverwrite) {
610 return Builder.add(InitCst, StartOffset + FieldOffsetInChars, AllowOverwrite);
613bool ConstStructBuilder::AppendBitField(
const FieldDecl *Field,
614 uint64_t FieldOffset, llvm::Constant *
C,
615 bool AllowOverwrite) {
617 llvm::ConstantInt *CI = dyn_cast<llvm::ConstantInt>(
C);
623 llvm::Type *LoadType =
625 llvm::Constant *FoldedConstant = llvm::ConstantFoldLoadFromConst(
627 CI = dyn_cast_if_present<llvm::ConstantInt>(FoldedConstant);
635 llvm::APInt FieldValue = CI->getValue();
641 if (Info.
Size > FieldValue.getBitWidth())
642 FieldValue = FieldValue.zext(Info.
Size);
645 if (Info.
Size < FieldValue.getBitWidth())
646 FieldValue = FieldValue.trunc(Info.
Size);
648 return Builder.addBits(FieldValue,
654 ConstantAggregateBuilder &Const,
658 return ConstStructBuilder::UpdateStruct(
Emitter, Const, Offset, Updater);
660 auto CAT =
Emitter.CGM.getContext().getAsConstantArrayType(
Type);
663 QualType ElemType = CAT->getElementType();
665 llvm::Type *ElemTy =
Emitter.CGM.getTypes().ConvertTypeForMem(ElemType);
667 llvm::Constant *FillC =
nullptr;
669 if (!isa<NoInitExpr>(Filler)) {
670 FillC =
Emitter.tryEmitAbstractForMemory(Filler, ElemType);
676 unsigned NumElementsToUpdate =
677 FillC ? CAT->getZExtSize() : Updater->
getNumInits();
678 for (
unsigned I = 0; I != NumElementsToUpdate; ++I, Offset += ElemSize) {
680 if (I < Updater->getNumInits())
683 if (!
Init && FillC) {
684 if (!
Const.add(FillC, Offset,
true))
686 }
else if (!
Init || isa<NoInitExpr>(
Init)) {
688 }
else if (
const auto *ChildILE = dyn_cast<InitListExpr>(
Init)) {
689 if (!EmitDesignatedInitUpdater(
Emitter, Const, Offset, ElemType,
693 Const.condense(Offset, ElemTy);
695 llvm::Constant *Val =
Emitter.tryEmitPrivateForMemory(
Init, ElemType);
696 if (!
Const.add(Val, Offset,
true))
704bool ConstStructBuilder::Build(
const InitListExpr *ILE,
bool AllowOverwrite) {
708 unsigned FieldNo = -1;
709 unsigned ElementNo = 0;
714 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
715 if (CXXRD->getNumBases())
727 if (
Field->isUnnamedBitField())
733 if (ElementNo < ILE->getNumInits())
735 if (isa_and_nonnull<NoInitExpr>(
Init))
749 if (AllowOverwrite &&
750 (
Field->getType()->isArrayType() ||
Field->getType()->isRecordType())) {
751 if (
auto *SubILE = dyn_cast<InitListExpr>(
Init)) {
754 if (!EmitDesignatedInitUpdater(
Emitter, Builder, StartOffset + Offset,
755 Field->getType(), SubILE))
759 Builder.condense(StartOffset + Offset,
765 llvm::Constant *EltInit =
771 if (!
Field->isBitField()) {
778 if (
Field->hasAttr<NoUniqueAddressAttr>())
779 AllowOverwrite =
true;
782 if (!AppendBitField(Field, Layout.
getFieldOffset(FieldNo), EltInit,
794 :
Decl(
Decl), Offset(Offset), Index(Index) {
801 bool operator<(
const BaseInfo &O)
const {
return Offset < O.Offset; }
814 llvm::Constant *VTableAddressPoint =
818 VTableAddressPoint =
Emitter.tryEmitConstantSignedPointer(
819 VTableAddressPoint, *Authentication);
820 if (!VTableAddressPoint)
823 if (!AppendBytes(Offset, VTableAddressPoint))
830 Bases.reserve(CD->getNumBases());
833 BaseEnd = CD->bases_end();
Base != BaseEnd; ++
Base, ++BaseNo) {
834 assert(!
Base->isVirtual() &&
"should not have virtual bases here");
837 Bases.push_back(BaseInfo(BD, BaseOffset, BaseNo));
839 llvm::stable_sort(Bases);
841 for (
unsigned I = 0, N = Bases.size(); I != N; ++I) {
842 BaseInfo &
Base = Bases[I];
846 VTableClass, Offset +
Base.Offset);
850 unsigned FieldNo = 0;
853 bool AllowOverwrite =
false;
855 FieldEnd = RD->
field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
861 if (
Field->isUnnamedBitField() ||
868 llvm::Constant *EltInit =
869 Emitter.tryEmitPrivateForMemory(FieldValue,
Field->getType());
873 if (!
Field->isBitField()) {
875 if (!AppendField(*Field, Layout.
getFieldOffset(FieldNo) + OffsetBits,
876 EltInit, AllowOverwrite))
880 if (
Field->hasAttr<NoUniqueAddressAttr>())
881 AllowOverwrite =
true;
884 if (!AppendBitField(*Field, Layout.
getFieldOffset(FieldNo) + OffsetBits,
885 EltInit, AllowOverwrite))
893llvm::Constant *ConstStructBuilder::Finalize(
QualType Type) {
906 if (!Builder.Build(ILE,
false))
909 return Builder.Finalize(ValTy);
923 return Builder.Finalize(ValTy);
927 ConstantAggregateBuilder &Const,
930 return ConstStructBuilder(
Emitter, Const, Offset)
931 .Build(Updater,
true);
943 if (llvm::GlobalVariable *Addr =
951 assert(!
E->isFileScope() &&
952 "file-scope compound literal did not have constant initializer!");
956 auto GV =
new llvm::GlobalVariable(
959 llvm::GlobalValue::InternalLinkage,
C,
".compoundliteral",
nullptr,
960 llvm::GlobalVariable::NotThreadLocal,
968static llvm::Constant *
969EmitArrayConstant(
CodeGenModule &CGM, llvm::ArrayType *DesiredType,
970 llvm::Type *CommonElementType, uint64_t ArrayBound,
972 llvm::Constant *Filler) {
974 uint64_t NonzeroLength = ArrayBound;
975 if (Elements.size() < NonzeroLength && Filler->isNullValue())
976 NonzeroLength = Elements.size();
977 if (NonzeroLength == Elements.size()) {
978 while (NonzeroLength > 0 && Elements[NonzeroLength - 1]->isNullValue())
982 if (NonzeroLength == 0)
983 return llvm::ConstantAggregateZero::get(DesiredType);
986 uint64_t TrailingZeroes = ArrayBound - NonzeroLength;
987 if (TrailingZeroes >= 8) {
988 assert(Elements.size() >= NonzeroLength &&
989 "missing initializer for non-zero element");
993 if (CommonElementType && NonzeroLength >= 8) {
994 llvm::Constant *Initial = llvm::ConstantArray::get(
995 llvm::ArrayType::get(CommonElementType, NonzeroLength),
996 ArrayRef(Elements).take_front(NonzeroLength));
998 Elements[0] = Initial;
1000 Elements.resize(NonzeroLength + 1);
1004 CommonElementType ? CommonElementType : DesiredType->getElementType();
1005 FillerType = llvm::ArrayType::get(FillerType, TrailingZeroes);
1006 Elements.back() = llvm::ConstantAggregateZero::get(FillerType);
1007 CommonElementType =
nullptr;
1008 }
else if (Elements.size() != ArrayBound) {
1010 Elements.resize(ArrayBound, Filler);
1011 if (Filler->getType() != CommonElementType)
1012 CommonElementType =
nullptr;
1016 if (CommonElementType)
1017 return llvm::ConstantArray::get(
1018 llvm::ArrayType::get(CommonElementType, ArrayBound), Elements);
1022 Types.reserve(Elements.size());
1023 for (llvm::Constant *Elt : Elements)
1024 Types.push_back(Elt->getType());
1025 llvm::StructType *SType =
1027 return llvm::ConstantStruct::get(SType, Elements);
1036class ConstExprEmitter
1040 llvm::LLVMContext &VMContext;
1043 : CGM(emitter.CGM),
Emitter(emitter), VMContext(CGM.getLLVMContext()) {
1050 llvm::Constant *VisitStmt(
const Stmt *S,
QualType T) {
return nullptr; }
1053 if (llvm::Constant *Result =
Emitter.tryEmitConstantExpr(CE))
1070 return Visit(
GE->getResultExpr(),
T);
1079 return Visit(
E->getInitializer(),
T);
1082 llvm::Constant *ProduceIntToIntCast(
const Expr *
E,
QualType DestType) {
1086 if (llvm::Constant *
C =
Visit(
E, FromType))
1087 if (
auto *CI = dyn_cast<llvm::ConstantInt>(
C)) {
1090 if (DstWidth == SrcWidth)
1093 ? CI->getValue().sextOrTrunc(DstWidth)
1094 : CI->getValue().zextOrTrunc(DstWidth);
1101 if (
const auto *ECE = dyn_cast<ExplicitCastExpr>(
E))
1103 const Expr *subExpr =
E->getSubExpr();
1105 switch (
E->getCastKind()) {
1109 "Destination type is not union type!");
1111 auto field =
E->getTargetUnionField();
1113 auto C =
Emitter.tryEmitPrivateForMemory(subExpr, field->getType());
1114 if (!
C)
return nullptr;
1116 auto destTy = ConvertType(destType);
1117 if (
C->getType() == destTy)
return C;
1124 Types.push_back(
C->getType());
1125 unsigned CurSize = CGM.
getDataLayout().getTypeAllocSize(
C->getType());
1126 unsigned TotalSize = CGM.
getDataLayout().getTypeAllocSize(destTy);
1128 assert(CurSize <= TotalSize &&
"Union size mismatch!");
1129 if (
unsigned NumPadBytes = TotalSize - CurSize) {
1130 llvm::Type *Ty = CGM.
CharTy;
1131 if (NumPadBytes > 1)
1132 Ty = llvm::ArrayType::get(Ty, NumPadBytes);
1134 Elts.push_back(llvm::UndefValue::get(Ty));
1135 Types.push_back(Ty);
1138 llvm::StructType *STy = llvm::StructType::get(VMContext, Types,
false);
1139 return llvm::ConstantStruct::get(STy, Elts);
1142 case CK_AddressSpaceConversion: {
1144 if (!
C)
return nullptr;
1147 llvm::Type *destTy = ConvertType(
E->
getType());
1152 case CK_LValueToRValue: {
1158 dyn_cast<CompoundLiteralExpr>(subExpr->
IgnoreParens()))
1159 return Visit(
E->getInitializer(), destType);
1163 case CK_AtomicToNonAtomic:
1164 case CK_NonAtomicToAtomic:
1166 case CK_ConstructorConversion:
1167 return Visit(subExpr, destType);
1169 case CK_ArrayToPointerDecay:
1170 if (
const auto *S = dyn_cast<StringLiteral>(subExpr))
1173 case CK_NullToPointer:
1174 if (
Visit(subExpr, destType))
1178 case CK_IntToOCLSampler:
1179 llvm_unreachable(
"global sampler variables are not generated");
1181 case CK_IntegralCast:
1182 return ProduceIntToIntCast(subExpr, destType);
1184 case CK_Dependent: llvm_unreachable(
"saw dependent cast!");
1186 case CK_BuiltinFnToFnPtr:
1187 llvm_unreachable(
"builtin functions are handled elsewhere");
1189 case CK_ReinterpretMemberPointer:
1190 case CK_DerivedToBaseMemberPointer:
1191 case CK_BaseToDerivedMemberPointer: {
1193 if (!
C)
return nullptr;
1198 case CK_ObjCObjectLValueCast:
1199 case CK_ARCProduceObject:
1200 case CK_ARCConsumeObject:
1201 case CK_ARCReclaimReturnedObject:
1202 case CK_ARCExtendBlockObject:
1203 case CK_CopyAndAutoreleaseBlockObject:
1211 case CK_LValueBitCast:
1212 case CK_LValueToRValueBitCast:
1213 case CK_NullToMemberPointer:
1214 case CK_UserDefinedConversion:
1215 case CK_CPointerToObjCPointerCast:
1216 case CK_BlockPointerToObjCPointerCast:
1217 case CK_AnyPointerToBlockPointerCast:
1218 case CK_FunctionToPointerDecay:
1219 case CK_BaseToDerived:
1220 case CK_DerivedToBase:
1221 case CK_UncheckedDerivedToBase:
1222 case CK_MemberPointerToBoolean:
1223 case CK_VectorSplat:
1224 case CK_FloatingRealToComplex:
1225 case CK_FloatingComplexToReal:
1226 case CK_FloatingComplexToBoolean:
1227 case CK_FloatingComplexCast:
1228 case CK_FloatingComplexToIntegralComplex:
1229 case CK_IntegralRealToComplex:
1230 case CK_IntegralComplexToReal:
1231 case CK_IntegralComplexToBoolean:
1232 case CK_IntegralComplexCast:
1233 case CK_IntegralComplexToFloatingComplex:
1234 case CK_PointerToIntegral:
1235 case CK_PointerToBoolean:
1236 case CK_BooleanToSignedIntegral:
1237 case CK_IntegralToPointer:
1238 case CK_IntegralToBoolean:
1239 case CK_IntegralToFloating:
1240 case CK_FloatingToIntegral:
1241 case CK_FloatingToBoolean:
1242 case CK_FloatingCast:
1243 case CK_FloatingToFixedPoint:
1244 case CK_FixedPointToFloating:
1245 case CK_FixedPointCast:
1246 case CK_FixedPointToBoolean:
1247 case CK_FixedPointToIntegral:
1248 case CK_IntegralToFixedPoint:
1249 case CK_ZeroToOCLOpaqueType:
1251 case CK_HLSLVectorTruncation:
1252 case CK_HLSLArrayRValue:
1255 llvm_unreachable(
"Invalid CastKind");
1266 return Visit(
E->getSubExpr(),
T);
1277 llvm::APFloat Result =
1279 llvm::RoundingMode RM =
1281 if (RM == llvm::RoundingMode::Dynamic)
1282 RM = llvm::RoundingMode::NearestTiesToEven;
1283 Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
1292 assert(CAT &&
"can't emit array init for non-constant-bound array");
1294 const uint64_t NumElements = CAT->getZExtSize();
1296 if (
const auto *Embed =
1297 dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1298 NumInitElements += Embed->getDataElementCount() - 1;
1299 if (NumInitElements > NumElements) {
1300 NumInitElements = NumElements;
1308 uint64_t NumInitableElts = std::min<uint64_t>(NumInitElements, NumElements);
1310 QualType EltType = CAT->getElementType();
1313 llvm::Constant *fillC =
nullptr;
1315 fillC =
Emitter.tryEmitAbstractForMemory(filler, EltType);
1322 if (fillC && fillC->isNullValue())
1323 Elts.reserve(NumInitableElts + 1);
1325 Elts.reserve(NumElements);
1327 llvm::Type *CommonElementType =
nullptr;
1328 auto Emit = [&](
const Expr *
Init,
unsigned ArrayIndex) {
1329 llvm::Constant *
C =
nullptr;
1333 if (ArrayIndex == 0)
1334 CommonElementType =
C->getType();
1335 else if (
C->getType() != CommonElementType)
1336 CommonElementType =
nullptr;
1341 unsigned ArrayIndex = 0;
1342 QualType DestTy = CAT->getElementType();
1343 for (
unsigned i = 0; i < ILE->
getNumInits(); ++i) {
1345 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1350 for (
unsigned I = EmbedS->getStartingElementPos(),
1351 N = EmbedS->getDataElementCount();
1352 I != EmbedS->getStartingElementPos() + N; ++I) {
1357 C =
Emitter.tryEmitPrivateForMemory(
1367 if ((ArrayIndex - EmbedS->getDataElementCount()) == 0)
1368 CommonElementType =
C->getType();
1369 else if (
C->getType() != CommonElementType)
1370 CommonElementType =
nullptr;
1372 if (!Emit(
Init, ArrayIndex))
1378 llvm::ArrayType *Desired =
1380 return EmitArrayConstant(CGM, Desired, CommonElementType, NumElements, Elts,
1384 llvm::Constant *EmitRecordInitialization(
const InitListExpr *ILE,
1386 return ConstStructBuilder::BuildStruct(
Emitter, ILE,
T);
1399 return EmitArrayInitialization(ILE,
T);
1402 return EmitRecordInitialization(ILE,
T);
1410 auto C =
Visit(
E->getBase(), destType);
1414 ConstantAggregateBuilder
Const(CGM);
1422 bool HasFlexibleArray =
false;
1424 HasFlexibleArray = RT->getDecl()->hasFlexibleArrayMember();
1425 return Const.build(ValTy, HasFlexibleArray);
1430 if (!
E->getConstructor()->isTrivial())
1434 if (
E->getNumArgs()) {
1435 assert(
E->getNumArgs() == 1 &&
"trivial ctor with > 1 argument");
1436 assert(
E->getConstructor()->isCopyOrMoveConstructor() &&
1437 "trivial ctor has argument but isn't a copy/move ctor");
1439 const Expr *Arg =
E->getArg(0);
1441 "argument to copy ctor is of wrong type");
1445 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(Arg))
1446 return Visit(MTE->getSubExpr(), Ty);
1466 assert(CAT &&
"String data not of constant array type!");
1471 return llvm::ConstantDataArray::getString(VMContext, Str,
false);
1475 return Visit(
E->getSubExpr(),
T);
1479 if (llvm::Constant *
C =
Visit(
U->getSubExpr(),
T))
1480 if (
auto *CI = dyn_cast<llvm::ConstantInt>(
C))
1481 return llvm::ConstantInt::get(CGM.
getLLVMContext(), -CI->getValue());
1486 return Visit(
E->getSelectedExpr(),
T);
1497llvm::Constant *ConstantEmitter::validateAndPopAbstract(llvm::Constant *
C,
1498 AbstractState saved) {
1499 Abstract = saved.OldValue;
1501 assert(saved.OldPlaceholdersSize == PlaceholderAddresses.size() &&
1502 "created a placeholder while doing an abstract emission?");
1511 auto state = pushAbstract();
1513 return validateAndPopAbstract(
C, state);
1518 auto state = pushAbstract();
1520 return validateAndPopAbstract(
C, state);
1525 auto state = pushAbstract();
1527 return validateAndPopAbstract(
C, state);
1543 auto state = pushAbstract();
1545 C = validateAndPopAbstract(
C, state);
1548 "internal error: could not emit constant value \"abstractly\"");
1557 bool EnablePtrAuthFunctionTypeDiscrimination) {
1558 auto state = pushAbstract();
1560 tryEmitPrivate(value, destType, EnablePtrAuthFunctionTypeDiscrimination);
1561 C = validateAndPopAbstract(
C, state);
1564 "internal error: could not emit constant value \"abstractly\"");
1571 initializeNonAbstract(
D.getType().getAddressSpace());
1578 initializeNonAbstract(destAddrSpace);
1585 initializeNonAbstract(destAddrSpace);
1587 assert(
C &&
"couldn't emit constant value non-abstractly?");
1592 assert(!Abstract &&
"cannot get current address for abstract constant");
1599 llvm::GlobalValue::PrivateLinkage,
1603 llvm::GlobalVariable::NotThreadLocal,
1606 PlaceholderAddresses.push_back(std::make_pair(
nullptr, global));
1612 llvm::GlobalValue *placeholder) {
1613 assert(!PlaceholderAddresses.empty());
1614 assert(PlaceholderAddresses.back().first ==
nullptr);
1615 assert(PlaceholderAddresses.back().second == placeholder);
1616 PlaceholderAddresses.back().first = signal;
1620 struct ReplacePlaceholders {
1624 llvm::Constant *
Base;
1625 llvm::Type *BaseValueTy =
nullptr;
1628 llvm::DenseMap<llvm::Constant*, llvm::GlobalVariable*> PlaceholderAddresses;
1631 llvm::DenseMap<llvm::GlobalVariable*, llvm::Constant*> Locations;
1639 ReplacePlaceholders(
CodeGenModule &CGM, llvm::Constant *base,
1640 ArrayRef<std::pair<llvm::Constant*,
1641 llvm::GlobalVariable*>> addresses)
1642 : CGM(CGM),
Base(base),
1643 PlaceholderAddresses(addresses.begin(), addresses.end()) {
1646 void replaceInInitializer(llvm::Constant *init) {
1648 BaseValueTy = init->getType();
1651 Indices.push_back(0);
1652 IndexValues.push_back(
nullptr);
1655 findLocations(init);
1658 assert(IndexValues.size() == Indices.size() &&
"mismatch");
1659 assert(Indices.size() == 1 &&
"didn't pop all indices");
1662 assert(Locations.size() == PlaceholderAddresses.size() &&
1663 "missed a placeholder?");
1669 for (
auto &entry : Locations) {
1670 assert(entry.first->getName() ==
"" &&
"not a placeholder!");
1671 entry.first->replaceAllUsesWith(entry.second);
1672 entry.first->eraseFromParent();
1677 void findLocations(llvm::Constant *init) {
1679 if (
auto agg = dyn_cast<llvm::ConstantAggregate>(init)) {
1680 for (
unsigned i = 0, e = agg->getNumOperands(); i != e; ++i) {
1681 Indices.push_back(i);
1682 IndexValues.push_back(
nullptr);
1684 findLocations(agg->getOperand(i));
1686 IndexValues.pop_back();
1694 auto it = PlaceholderAddresses.find(init);
1695 if (it != PlaceholderAddresses.end()) {
1696 setLocation(it->second);
1701 if (
auto expr = dyn_cast<llvm::ConstantExpr>(init)) {
1702 init =
expr->getOperand(0);
1709 void setLocation(llvm::GlobalVariable *placeholder) {
1710 assert(!Locations.contains(placeholder) &&
1711 "already found location for placeholder!");
1716 assert(Indices.size() == IndexValues.size());
1717 for (
size_t i = Indices.size() - 1; i !=
size_t(-1); --i) {
1718 if (IndexValues[i]) {
1720 for (
size_t j = 0; j != i + 1; ++j) {
1721 assert(IndexValues[j] &&
1722 isa<llvm::ConstantInt>(IndexValues[j]) &&
1723 cast<llvm::ConstantInt>(IndexValues[j])->getZExtValue()
1730 IndexValues[i] = llvm::ConstantInt::get(CGM.
Int32Ty, Indices[i]);
1733 llvm::Constant *location = llvm::ConstantExpr::getInBoundsGetElementPtr(
1734 BaseValueTy,
Base, IndexValues);
1736 Locations.insert({placeholder, location});
1742 assert(InitializedNonAbstract &&
1743 "finalizing emitter that was used for abstract emission?");
1744 assert(!Finalized &&
"finalizing emitter multiple times");
1745 assert(global->getInitializer());
1750 if (!PlaceholderAddresses.empty()) {
1751 ReplacePlaceholders(
CGM, global, PlaceholderAddresses)
1752 .replaceInInitializer(global->getInitializer());
1753 PlaceholderAddresses.clear();
1758 assert((!InitializedNonAbstract || Finalized || Failed) &&
1759 "not finalized after being initialized for non-abstract emission");
1760 assert(PlaceholderAddresses.empty() &&
"unhandled placeholders");
1766 type.getQualifiers());
1775 if (!
D.hasLocalStorage()) {
1779 dyn_cast_or_null<CXXConstructExpr>(
D.getInit())) {
1785 InConstantContext =
D.hasConstantInitialization();
1788 const Expr *
E =
D.getInit();
1789 assert(
E &&
"No initializer to emit");
1793 if (llvm::Constant *
C = ConstExprEmitter(*this).Visit(
E, nonMemoryDestType))
1799 if (
APValue *value =
D.evaluateValue())
1842 assert(Schema &&
"applying trivial ptrauth schema");
1845 return UnsignedPointer;
1847 unsigned Key = Schema.
getKey();
1850 llvm::GlobalValue *StorageAddress =
nullptr;
1859 llvm::ConstantInt *Discriminator =
1863 UnsignedPointer, Key, StorageAddress, Discriminator);
1868 return SignedPointer;
1876 QualType destValueType = AT->getValueType();
1881 if (innerSize == outerSize)
1884 assert(innerSize < outerSize &&
"emitted over-large constant for atomic");
1885 llvm::Constant *elts[] = {
1887 llvm::ConstantAggregateZero::get(
1888 llvm::ArrayType::get(
CGM.
Int8Ty, (outerSize - innerSize) / 8))
1890 return llvm::ConstantStruct::getAnon(elts);
1894 if (
C->getType()->isIntegerTy(1) && !destType->
isBitIntType()) {
1896 llvm::Constant *Res = llvm::ConstantFoldCastOperand(
1898 assert(Res &&
"Constant folding must succeed");
1903 ConstantAggregateBuilder Builder(
CGM);
1907 auto *CI = cast<llvm::ConstantInt>(
C);
1908 llvm::Constant *Res = llvm::ConstantFoldCastOperand(
1910 : llvm::Instruction::ZExt,
1916 llvm::APInt
Value = cast<llvm::ConstantInt>(Res)->getValue();
1917 Builder.addBits(
Value, 0,
false);
1918 return Builder.build(DesiredTy,
false);
1928 assert(!destType->
isVoidType() &&
"can't emit a void constant");
1931 if (llvm::Constant *
C = ConstExprEmitter(*this).Visit(
E, destType))
1956struct ConstantLValue {
1957 llvm::Constant *
Value;
1958 bool HasOffsetApplied;
1960 ConstantLValue(llvm::Constant *value,
1961 bool hasOffsetApplied =
false)
1962 :
Value(value), HasOffsetApplied(hasOffsetApplied) {}
1965 : ConstantLValue(address.getPointer()) {}
1969class ConstantLValueEmitter :
public ConstStmtVisitor<ConstantLValueEmitter,
1975 bool EnablePtrAuthFunctionTypeDiscrimination;
1983 bool EnablePtrAuthFunctionTypeDiscrimination =
true)
1984 : CGM(emitter.CGM),
Emitter(emitter),
Value(value), DestType(destType),
1985 EnablePtrAuthFunctionTypeDiscrimination(
1986 EnablePtrAuthFunctionTypeDiscrimination) {}
1988 llvm::Constant *tryEmit();
1991 llvm::Constant *tryEmitAbsolute(llvm::Type *destTy);
1994 ConstantLValue VisitStmt(
const Stmt *S) {
return nullptr; }
2003 ConstantLValue VisitCallExpr(
const CallExpr *
E);
2004 ConstantLValue VisitBlockExpr(
const BlockExpr *
E);
2006 ConstantLValue VisitMaterializeTemporaryExpr(
2009 ConstantLValue emitPointerAuthSignConstant(
const CallExpr *
E);
2010 llvm::Constant *emitPointerAuthPointer(
const Expr *
E);
2011 unsigned emitPointerAuthKey(
const Expr *
E);
2012 std::pair<llvm::Constant *, llvm::ConstantInt *>
2013 emitPointerAuthDiscriminator(
const Expr *
E);
2015 bool hasNonZeroOffset()
const {
2016 return !
Value.getLValueOffset().isZero();
2020 llvm::Constant *getOffset() {
2021 return llvm::ConstantInt::get(CGM.
Int64Ty,
2022 Value.getLValueOffset().getQuantity());
2026 llvm::Constant *applyOffset(llvm::Constant *
C) {
2027 if (!hasNonZeroOffset())
2030 return llvm::ConstantExpr::getGetElementPtr(CGM.
Int8Ty,
C, getOffset());
2036llvm::Constant *ConstantLValueEmitter::tryEmit() {
2047 assert(isa<llvm::IntegerType>(destTy) || isa<llvm::PointerType>(destTy));
2052 return tryEmitAbsolute(destTy);
2056 ConstantLValue result = tryEmitBase(base);
2059 llvm::Constant *value = result.Value;
2060 if (!value)
return nullptr;
2063 if (!result.HasOffsetApplied) {
2064 value = applyOffset(value);
2069 if (isa<llvm::PointerType>(destTy))
2070 return llvm::ConstantExpr::getPointerCast(value, destTy);
2072 return llvm::ConstantExpr::getPtrToInt(value, destTy);
2078ConstantLValueEmitter::tryEmitAbsolute(llvm::Type *destTy) {
2080 auto destPtrTy = cast<llvm::PointerType>(destTy);
2081 if (
Value.isNullPointer()) {
2089 auto intptrTy = CGM.
getDataLayout().getIntPtrType(destPtrTy);
2091 C = llvm::ConstantFoldIntegerCast(getOffset(), intptrTy,
false,
2093 assert(
C &&
"Must have folded, as Offset is a ConstantInt");
2094 C = llvm::ConstantExpr::getIntToPtr(
C, destPtrTy);
2109 auto PtrAuthSign = [&](llvm::Constant *
C) {
2112 if (EnablePtrAuthFunctionTypeDiscrimination)
2116 if (hasNonZeroOffset())
2117 return ConstantLValue(
nullptr);
2121 C, AuthInfo.
getKey(),
nullptr,
2123 return ConstantLValue(
C,
true);
2126 return ConstantLValue(
C);
2129 if (
const auto *FD = dyn_cast<FunctionDecl>(
D))
2132 if (
const auto *VD = dyn_cast<VarDecl>(
D)) {
2134 if (!VD->hasLocalStorage()) {
2135 if (VD->isFileVarDecl() || VD->hasExternalStorage())
2138 if (VD->isLocalVarDecl()) {
2145 if (
const auto *GD = dyn_cast<MSGuidDecl>(
D))
2148 if (
const auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(
D))
2151 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(
D))
2162 return Visit(base.
get<
const Expr*>());
2166ConstantLValueEmitter::VisitConstantExpr(
const ConstantExpr *
E) {
2169 return Visit(
E->getSubExpr());
2175 CompoundLiteralEmitter.setInConstantContext(
Emitter.isInConstantContext());
2176 return tryEmitGlobalCompoundLiteral(CompoundLiteralEmitter,
E);
2180ConstantLValueEmitter::VisitStringLiteral(
const StringLiteral *
E) {
2202ConstantLValueEmitter::VisitObjCBoxedExpr(
const ObjCBoxedExpr *
E) {
2203 assert(
E->isExpressibleAsConstantInitializer() &&
2204 "this boxed expression can't be emitted as a compile-time constant");
2215ConstantLValueEmitter::VisitAddrLabelExpr(
const AddrLabelExpr *
E) {
2216 assert(
Emitter.CGF &&
"Invalid address of label expression outside function");
2217 llvm::Constant *Ptr =
Emitter.CGF->GetAddrOfLabel(
E->getLabel());
2222ConstantLValueEmitter::VisitCallExpr(
const CallExpr *
E) {
2223 unsigned builtin =
E->getBuiltinCallee();
2224 if (builtin == Builtin::BI__builtin_function_start)
2228 if (builtin == Builtin::BI__builtin_ptrauth_sign_constant)
2229 return emitPointerAuthSignConstant(
E);
2231 if (builtin != Builtin::BI__builtin___CFStringMakeConstantString &&
2232 builtin != Builtin::BI__builtin___NSStringMakeConstantString)
2236 if (builtin == Builtin::BI__builtin___NSStringMakeConstantString) {
2245ConstantLValueEmitter::emitPointerAuthSignConstant(
const CallExpr *
E) {
2246 llvm::Constant *UnsignedPointer = emitPointerAuthPointer(
E->getArg(0));
2247 unsigned Key = emitPointerAuthKey(
E->getArg(1));
2248 auto [StorageAddress, OtherDiscriminator] =
2249 emitPointerAuthDiscriminator(
E->getArg(2));
2252 UnsignedPointer, Key, StorageAddress, OtherDiscriminator);
2253 return SignedPointer;
2256llvm::Constant *ConstantLValueEmitter::emitPointerAuthPointer(
const Expr *
E) {
2263 assert(
Result.Val.isLValue());
2264 if (isa<FunctionDecl>(
Result.Val.getLValueBase().get<
const ValueDecl *>()))
2265 assert(
Result.Val.getLValueOffset().isZero());
2270unsigned ConstantLValueEmitter::emitPointerAuthKey(
const Expr *
E) {
2274std::pair<llvm::Constant *, llvm::ConstantInt *>
2275ConstantLValueEmitter::emitPointerAuthDiscriminator(
const Expr *
E) {
2278 if (
const auto *
Call = dyn_cast<CallExpr>(
E)) {
2279 if (
Call->getBuiltinCallee() ==
2280 Builtin::BI__builtin_ptrauth_blend_discriminator) {
2282 Call->getArg(0),
Call->getArg(0)->getType());
2283 auto *Extra = cast<llvm::ConstantInt>(
ConstantEmitter(CGM).emitAbstract(
2284 Call->getArg(1),
Call->getArg(1)->getType()));
2290 if (
Result->getType()->isPointerTy())
2291 return {
Result,
nullptr};
2292 return {
nullptr, cast<llvm::ConstantInt>(
Result)};
2296ConstantLValueEmitter::VisitBlockExpr(
const BlockExpr *
E) {
2297 StringRef functionName;
2299 functionName = CGF->CurFn->getName();
2301 functionName =
"global";
2307ConstantLValueEmitter::VisitCXXTypeidExpr(
const CXXTypeidExpr *
E) {
2309 if (
E->isTypeOperand())
2317ConstantLValueEmitter::VisitMaterializeTemporaryExpr(
2319 assert(
E->getStorageDuration() ==
SD_Static);
2326 bool EnablePtrAuthFunctionTypeDiscrimination) {
2333 return ConstantLValueEmitter(*
this,
Value, DestType,
2334 EnablePtrAuthFunctionTypeDiscrimination)
2340 Value.getFixedPoint().getValue());
2345 Value.getComplexIntReal());
2347 Value.getComplexIntImag());
2350 llvm::StructType *STy =
2351 llvm::StructType::get(
Complex[0]->getType(),
Complex[1]->getType());
2352 return llvm::ConstantStruct::get(STy,
Complex);
2355 const llvm::APFloat &
Init =
Value.getFloat();
2356 if (&
Init.getSemantics() == &llvm::APFloat::IEEEhalf() &&
2360 Init.bitcastToAPInt());
2368 Value.getComplexFloatReal());
2370 Value.getComplexFloatImag());
2373 llvm::StructType *STy =
2374 llvm::StructType::get(
Complex[0]->getType(),
Complex[1]->getType());
2375 return llvm::ConstantStruct::get(STy,
Complex);
2378 unsigned NumElts =
Value.getVectorLength();
2381 for (
unsigned I = 0; I != NumElts; ++I) {
2391 llvm_unreachable(
"unsupported vector element type");
2393 return llvm::ConstantVector::get(Inits);
2400 if (!LHS || !RHS)
return nullptr;
2404 LHS = llvm::ConstantExpr::getPtrToInt(LHS,
CGM.
IntPtrTy);
2405 RHS = llvm::ConstantExpr::getPtrToInt(RHS,
CGM.
IntPtrTy);
2406 llvm::Constant *AddrLabelDiff = llvm::ConstantExpr::getSub(LHS, RHS);
2411 return llvm::ConstantExpr::getTruncOrBitCast(AddrLabelDiff, ResultType);
2415 return ConstStructBuilder::BuildStruct(*
this,
Value, DestType);
2418 unsigned NumElements =
Value.getArraySize();
2419 unsigned NumInitElts =
Value.getArrayInitializedElts();
2422 llvm::Constant *Filler =
nullptr;
2423 if (
Value.hasArrayFiller()) {
2432 if (Filler && Filler->isNullValue())
2433 Elts.reserve(NumInitElts + 1);
2435 Elts.reserve(NumElements);
2437 llvm::Type *CommonElementType =
nullptr;
2438 for (
unsigned I = 0; I < NumInitElts; ++I) {
2441 if (!
C)
return nullptr;
2444 CommonElementType =
C->getType();
2445 else if (
C->getType() != CommonElementType)
2446 CommonElementType =
nullptr;
2450 llvm::ArrayType *Desired =
2455 Desired = llvm::ArrayType::get(Desired->getElementType(), Elts.size());
2457 return EmitArrayConstant(
CGM, Desired, CommonElementType, NumElements, Elts,
2463 llvm_unreachable(
"Unknown APValue kind");
2468 return EmittedCompoundLiterals.lookup(
E);
2473 bool Ok = EmittedCompoundLiterals.insert(std::make_pair(CLE, GV)).second;
2475 assert(Ok &&
"CLE has already been emitted!");
2480 assert(
E->isFileScope() &&
"not a file-scope compound literal expr");
2482 return tryEmitGlobalCompoundLiteral(emitter,
E);
2502 llvm::Type *baseType,
2507 bool asCompleteObject) {
2509 llvm::StructType *structure =
2513 unsigned numElements = structure->getNumElements();
2514 std::vector<llvm::Constant *> elements(numElements);
2516 auto CXXR = dyn_cast<CXXRecordDecl>(record);
2519 for (
const auto &I : CXXR->bases()) {
2520 if (I.isVirtual()) {
2538 llvm::Type *baseType = structure->getElementType(fieldIndex);
2544 for (
const auto *Field : record->
fields()) {
2547 if (!Field->isBitField() &&
2555 if (Field->getIdentifier())
2557 if (
const auto *FieldRD = Field->getType()->getAsRecordDecl())
2558 if (FieldRD->findFirstNamedDataMember())
2564 if (CXXR && asCompleteObject) {
2565 for (
const auto &I : CXXR->vbases()) {
2576 if (elements[fieldIndex])
continue;
2578 llvm::Type *baseType = structure->getElementType(fieldIndex);
2584 for (
unsigned i = 0; i != numElements; ++i) {
2586 elements[i] = llvm::Constant::getNullValue(structure->getElementType(i));
2589 return llvm::ConstantStruct::get(structure, elements);
2594 llvm::Type *baseType,
2600 return llvm::Constant::getNullValue(baseType);
2614 cast<llvm::PointerType>(
getTypes().ConvertTypeForMem(
T)),
T);
2617 return llvm::Constant::getNullValue(
getTypes().ConvertTypeForMem(
T));
2620 llvm::ArrayType *ATy =
2621 cast<llvm::ArrayType>(
getTypes().ConvertTypeForMem(
T));
2625 llvm::Constant *Element =
2629 return llvm::ConstantArray::get(ATy, Array);
2633 return ::EmitNullConstant(*
this, RT->getDecl(),
true);
2636 "Should only see pointers to data members here!");
2643 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)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
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.
uint64_t getFieldOffset(const ValueDecl *FD) const
Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
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.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
const LangOptions & getLangOpts() const
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
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.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
const TargetInfo & getTargetInfo() const
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.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
bool hasOwnVFPtr() const
hasOwnVFPtr - Does this class provide its own virtual-function table pointer, rather than inheriting ...
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.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Represents a base class of a C++ class.
Represents a call to a C++ constructor.
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-...
A use of a default initializer in a constructor or in aggregate initialization.
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.
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
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.
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
virtual llvm::Constant * EmitNullMemberPointer(const MemberPointerType *MPT)
Create a null member pointer of the given type.
virtual llvm::Constant * EmitMemberPointer(const APValue &MP, QualType MPT)
Create a member pointer for the given member pointer constant.
virtual llvm::Constant * getVTableAddressPoint(BaseSubobject Base, const CXXRecordDecl *VTableClass)=0
Get the address point of the vtable for the given base subobject.
virtual llvm::Constant * EmitMemberDataPointer(const MemberPointerType *MPT, CharUnits offset)
Create a member pointer for the given field.
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 llvm::Constant * EmitMemberFunctionPointer(const CXXMethodDecl *MD)
Create a member pointer for the given method.
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.
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
void Error(SourceLocation loc, StringRef error)
Emit a general error that something can't be done.
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()
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.
bool typeRequiresSplitIntoByteArray(QualType ASTTy, llvm::Type *LLVMTy=nullptr)
Check whether the given type needs to be laid out in memory using an opaque byte-array type because i...
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)
llvm::Constant * tryEmitAbstract(const Expr *E, QualType T)
Try to emit the result of the given expression as an abstract constant.
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, LangAS DestAddr, llvm::Type *DestTy, bool IsNonNull=false) const
virtual llvm::Constant * getNullPointer(const CodeGen::CodeGenModule &CGM, llvm::PointerType *T, QualType QT) const
Get target specific null pointer.
CompoundLiteralExpr - [C99 6.5.2.5].
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
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
SourceLocation getBeginLoc() const LLVM_READONLY
bool hasAPValueResult() const
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
Decl - This represents one declaration (or definition), e.g.
Decl * getMostRecentDecl()
Retrieve the most recent declaration that declares the same entity as this declaration (which may be ...
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
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
Represents a member of a struct/union/class.
const Expr * getSubExpr() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Represents a C11 generic selection.
Represents an implicitly-generated value initialization of an object of a given type.
Describes an C or C++ initializer list.
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()
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
A pointer to member type per C++ 8.3.3 - Pointers to members.
ObjCBoxedExpr - used for generalized expression boxing.
ObjCEncodeExpr, used for @encode in Objective-C.
ObjCStringLiteral, used for Objective-C string literals i.e.
ParenExpr - This represents a parenthesized expression, e.g.
const Expr * getSubExpr() const
Pointer-authentication qualifiers.
bool isAddressDiscriminated() const
unsigned getExtraDiscriminator() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
[C99 6.4.2.2] - A predefined identifier such as func.
A (possibly-)qualified type.
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
field_iterator field_begin() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
Encodes a location in the source.
StmtVisitorBase - This class implements a simple visitor for Stmt subclasses.
RetTy Visit(PTR(Stmt) S, ParamTys... P)
Stmt - This represents one statement.
StringLiteral - This represents a string literal expression, e.g.
uint32_t getCodeUnit(size_t i) const
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Expr * getReplacement() const
virtual bool useFP16ConversionIntrinsics() const
Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used to convert to and from __fp...
Symbolic representation of typeid(T) for some type T.
The base class of the type hierarchy.
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isIncompleteArrayType() const
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
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 isMemberDataPointerType() const
bool isBitIntType() 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.
Represents a GCC generic vector type.
QualType getElementType() const
bool isEmptyRecordForLayout(const ASTContext &Context, QualType T)
isEmptyRecordForLayout - Return true iff a structure contains only empty base classes (per isEmptyRec...
bool isEmptyFieldForLayout(const ASTContext &Context, const FieldDecl *FD)
isEmptyFieldForLayout - Return true iff the field is "empty", that is, either a zero-width bit-field ...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
uint32_t Literal
Literals are represented as positive integers.
bool Const(InterpState &S, CodePtr OpPC, const T &Arg)
bool GE(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
@ 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.
LangAS
Defines the address space values used by the address space qualifier of QualType.
const FunctionProtoType * T
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
@ Success
Template argument deduction was successful.
Structure with information about how a bitfield should be accessed.
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
llvm::IntegerType * IntPtrTy
EvalResult is a struct with detailed info about an evaluated expression.