26#include "llvm/ADT/STLExtras.h"
27#include "llvm/ADT/Sequence.h"
28#include "llvm/Analysis/ConstantFolding.h"
29#include "llvm/IR/Constants.h"
30#include "llvm/IR/DataLayout.h"
31#include "llvm/IR/Function.h"
32#include "llvm/IR/GlobalVariable.h"
35using namespace CodeGen;
42class ConstExprEmitter;
44struct ConstantAggregateBuilderUtils {
47 ConstantAggregateBuilderUtils(
CodeGenModule &CGM) : CGM(CGM) {}
49 CharUnits getAlignment(
const llvm::Constant *
C)
const {
58 CharUnits getSize(
const llvm::Constant *
C)
const {
59 return getSize(
C->getType());
62 llvm::Constant *getPadding(
CharUnits PadSize)
const {
63 llvm::Type *Ty = CGM.
CharTy;
65 Ty = llvm::ArrayType::get(Ty, PadSize.
getQuantity());
66 return llvm::UndefValue::get(Ty);
69 llvm::Constant *getZeroes(
CharUnits ZeroSize)
const {
71 return llvm::ConstantAggregateZero::get(Ty);
77class ConstantAggregateBuilder :
private ConstantAggregateBuilderUtils {
96 bool NaturalLayout =
true;
99 std::optional<size_t> splitAt(
CharUnits Pos);
105 bool NaturalLayout, llvm::Type *DesiredTy,
106 bool AllowOversized);
110 : ConstantAggregateBuilderUtils(CGM) {}
117 bool add(llvm::Constant *
C,
CharUnits Offset,
bool AllowOverwrite);
120 bool addBits(llvm::APInt Bits, uint64_t OffsetInBits,
bool AllowOverwrite);
124 void condense(
CharUnits Offset, llvm::Type *DesiredTy);
131 llvm::Constant *build(llvm::Type *DesiredTy,
bool AllowOversized)
const {
133 NaturalLayout, DesiredTy, AllowOversized);
137template<
typename Container,
typename Range = std::initializer_list<
138 typename Container::value_type>>
139static void replace(Container &
C,
size_t BeginOff,
size_t EndOff, Range Vals) {
140 assert(BeginOff <= EndOff &&
"invalid replacement range");
141 llvm::replace(
C,
C.begin() + BeginOff,
C.begin() + EndOff, Vals);
144bool ConstantAggregateBuilder::add(llvm::Constant *
C,
CharUnits Offset,
145 bool AllowOverwrite) {
147 if (Offset >= Size) {
150 if (AlignedSize > Offset || Offset.alignTo(Align) != Offset)
151 NaturalLayout =
false;
152 else if (AlignedSize < Offset) {
153 Elems.push_back(getPadding(Offset - Size));
154 Offsets.push_back(Size);
157 Offsets.push_back(Offset);
158 Size = Offset + getSize(
C);
163 std::optional<size_t> FirstElemToReplace = splitAt(Offset);
164 if (!FirstElemToReplace)
168 std::optional<size_t> LastElemToReplace = splitAt(Offset + CSize);
169 if (!LastElemToReplace)
172 assert((FirstElemToReplace == LastElemToReplace || AllowOverwrite) &&
173 "unexpectedly overwriting field");
175 replace(Elems, *FirstElemToReplace, *LastElemToReplace, {
C});
176 replace(Offsets, *FirstElemToReplace, *LastElemToReplace, {Offset});
177 Size = std::max(Size, Offset + CSize);
178 NaturalLayout =
false;
182bool ConstantAggregateBuilder::addBits(llvm::APInt Bits, uint64_t OffsetInBits,
183 bool AllowOverwrite) {
189 unsigned OffsetWithinChar = OffsetInBits % CharWidth;
197 unsigned WantedBits =
198 std::min((uint64_t)Bits.getBitWidth(), CharWidth - OffsetWithinChar);
202 llvm::APInt BitsThisChar = Bits;
203 if (BitsThisChar.getBitWidth() < CharWidth)
204 BitsThisChar = BitsThisChar.zext(CharWidth);
208 int Shift = Bits.getBitWidth() - CharWidth + OffsetWithinChar;
210 BitsThisChar.lshrInPlace(Shift);
212 BitsThisChar = BitsThisChar.shl(-Shift);
214 BitsThisChar = BitsThisChar.shl(OffsetWithinChar);
216 if (BitsThisChar.getBitWidth() > CharWidth)
217 BitsThisChar = BitsThisChar.trunc(CharWidth);
219 if (WantedBits == CharWidth) {
222 OffsetInChars, AllowOverwrite);
227 std::optional<size_t> FirstElemToUpdate = splitAt(OffsetInChars);
228 if (!FirstElemToUpdate)
230 std::optional<size_t> LastElemToUpdate =
232 if (!LastElemToUpdate)
234 assert(*LastElemToUpdate - *FirstElemToUpdate < 2 &&
235 "should have at most one element covering one byte");
238 llvm::APInt UpdateMask(CharWidth, 0);
240 UpdateMask.setBits(CharWidth - OffsetWithinChar - WantedBits,
241 CharWidth - OffsetWithinChar);
243 UpdateMask.setBits(OffsetWithinChar, OffsetWithinChar + WantedBits);
244 BitsThisChar &= UpdateMask;
246 if (*FirstElemToUpdate == *LastElemToUpdate ||
247 Elems[*FirstElemToUpdate]->isNullValue() ||
248 isa<llvm::UndefValue>(Elems[*FirstElemToUpdate])) {
251 OffsetInChars,
true);
253 llvm::Constant *&ToUpdate = Elems[*FirstElemToUpdate];
256 auto *CI = dyn_cast<llvm::ConstantInt>(ToUpdate);
261 assert(CI->getBitWidth() == CharWidth &&
"splitAt failed");
262 assert((!(CI->getValue() & UpdateMask) || AllowOverwrite) &&
263 "unexpectedly overwriting bitfield");
264 BitsThisChar |= (CI->getValue() & ~UpdateMask);
265 ToUpdate = llvm::ConstantInt::get(CGM.
getLLVMContext(), BitsThisChar);
270 if (WantedBits == Bits.getBitWidth())
275 Bits.lshrInPlace(WantedBits);
276 Bits = Bits.trunc(Bits.getBitWidth() - WantedBits);
279 OffsetWithinChar = 0;
289std::optional<size_t> ConstantAggregateBuilder::splitAt(
CharUnits Pos) {
291 return Offsets.size();
294 auto FirstAfterPos = llvm::upper_bound(Offsets, Pos);
295 if (FirstAfterPos == Offsets.begin())
299 size_t LastAtOrBeforePosIndex = FirstAfterPos - Offsets.begin() - 1;
300 if (Offsets[LastAtOrBeforePosIndex] == Pos)
301 return LastAtOrBeforePosIndex;
304 if (Offsets[LastAtOrBeforePosIndex] +
305 getSize(Elems[LastAtOrBeforePosIndex]) <= Pos)
306 return LastAtOrBeforePosIndex + 1;
309 if (!split(LastAtOrBeforePosIndex, Pos))
317bool ConstantAggregateBuilder::split(
size_t Index,
CharUnits Hint) {
318 NaturalLayout =
false;
319 llvm::Constant *
C = Elems[Index];
322 if (
auto *CA = dyn_cast<llvm::ConstantAggregate>(
C)) {
325 replace(Elems, Index, Index + 1,
326 llvm::map_range(llvm::seq(0u, CA->getNumOperands()),
327 [&](
unsigned Op) { return CA->getOperand(Op); }));
328 if (isa<llvm::ArrayType>(CA->getType()) ||
329 isa<llvm::VectorType>(CA->getType())) {
332 llvm::GetElementPtrInst::getTypeAtIndex(CA->getType(), (uint64_t)0);
335 Offsets, Index, Index + 1,
336 llvm::map_range(llvm::seq(0u, CA->getNumOperands()),
337 [&](
unsigned Op) { return Offset + Op * ElemSize; }));
340 auto *ST = cast<llvm::StructType>(CA->getType());
341 const llvm::StructLayout *Layout =
343 replace(Offsets, Index, Index + 1,
345 llvm::seq(0u, CA->getNumOperands()), [&](
unsigned Op) {
346 return Offset + CharUnits::fromQuantity(
347 Layout->getElementOffset(Op));
353 if (
auto *CDS = dyn_cast<llvm::ConstantDataSequential>(
C)) {
357 CharUnits ElemSize = getSize(CDS->getElementType());
358 replace(Elems, Index, Index + 1,
359 llvm::map_range(llvm::seq(0u, CDS->getNumElements()),
361 return CDS->getElementAsConstant(Elem);
363 replace(Offsets, Index, Index + 1,
365 llvm::seq(0u, CDS->getNumElements()),
366 [&](
unsigned Elem) { return Offset + Elem * ElemSize; }));
370 if (isa<llvm::ConstantAggregateZero>(
C)) {
373 assert(Hint > Offset && Hint < Offset + ElemSize &&
"nothing to split");
374 replace(Elems, Index, Index + 1,
375 {getZeroes(Hint - Offset), getZeroes(Offset + ElemSize - Hint)});
376 replace(Offsets, Index, Index + 1, {Offset, Hint});
380 if (isa<llvm::UndefValue>(
C)) {
382 replace(Elems, Index, Index + 1, {});
383 replace(Offsets, Index, Index + 1, {});
394static llvm::Constant *
395EmitArrayConstant(
CodeGenModule &CGM, llvm::ArrayType *DesiredType,
396 llvm::Type *CommonElementType,
unsigned ArrayBound,
398 llvm::Constant *Filler);
400llvm::Constant *ConstantAggregateBuilder::buildFrom(
403 bool NaturalLayout, llvm::Type *DesiredTy,
bool AllowOversized) {
404 ConstantAggregateBuilderUtils Utils(CGM);
407 return llvm::UndefValue::get(DesiredTy);
409 auto Offset = [&](
size_t I) {
return Offsets[I] - StartOffset; };
413 if (llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(DesiredTy)) {
414 assert(!AllowOversized &&
"oversized array emission not supported");
416 bool CanEmitArray =
true;
417 llvm::Type *CommonType = Elems[0]->getType();
418 llvm::Constant *Filler = llvm::Constant::getNullValue(CommonType);
419 CharUnits ElemSize = Utils.getSize(ATy->getElementType());
421 for (
size_t I = 0; I != Elems.size(); ++I) {
423 if (Elems[I]->isNullValue())
427 if (Elems[I]->getType() != CommonType ||
428 Offset(I) % ElemSize != 0) {
429 CanEmitArray =
false;
432 ArrayElements.resize(Offset(I) / ElemSize + 1, Filler);
433 ArrayElements.back() = Elems[I];
437 return EmitArrayConstant(CGM, ATy, CommonType, ATy->getNumElements(),
438 ArrayElements, Filler);
447 CharUnits DesiredSize = Utils.getSize(DesiredTy);
448 if (Size > DesiredSize) {
449 assert(AllowOversized &&
"Elems are oversized");
455 for (llvm::Constant *
C : Elems)
456 Align = std::max(Align, Utils.getAlignment(
C));
464 if (DesiredSize < AlignedSize || DesiredSize.
alignTo(Align) != DesiredSize) {
466 NaturalLayout =
false;
468 }
else if (DesiredSize > AlignedSize) {
471 UnpackedElemStorage.assign(Elems.begin(), Elems.end());
472 UnpackedElemStorage.push_back(Utils.getPadding(DesiredSize - Size));
473 UnpackedElems = UnpackedElemStorage;
480 if (!NaturalLayout) {
482 for (
size_t I = 0; I != Elems.size(); ++I) {
483 CharUnits Align = Utils.getAlignment(Elems[I]);
486 assert(DesiredOffset >= SizeSoFar &&
"elements out of order");
488 if (DesiredOffset != NaturalOffset)
490 if (DesiredOffset != SizeSoFar)
491 PackedElems.push_back(Utils.getPadding(DesiredOffset - SizeSoFar));
492 PackedElems.push_back(Elems[I]);
493 SizeSoFar = DesiredOffset + Utils.getSize(Elems[I]);
498 assert(SizeSoFar <= DesiredSize &&
499 "requested size is too small for contents");
500 if (SizeSoFar < DesiredSize)
501 PackedElems.push_back(Utils.getPadding(DesiredSize - SizeSoFar));
505 llvm::StructType *STy = llvm::ConstantStruct::getTypeForElements(
506 CGM.
getLLVMContext(), Packed ? PackedElems : UnpackedElems, Packed);
510 if (llvm::StructType *DesiredSTy = dyn_cast<llvm::StructType>(DesiredTy)) {
511 if (DesiredSTy->isLayoutIdentical(STy))
515 return llvm::ConstantStruct::get(STy, Packed ? PackedElems : UnpackedElems);
518void ConstantAggregateBuilder::condense(
CharUnits Offset,
519 llvm::Type *DesiredTy) {
522 std::optional<size_t> FirstElemToReplace = splitAt(Offset);
523 if (!FirstElemToReplace)
525 size_t First = *FirstElemToReplace;
527 std::optional<size_t> LastElemToReplace = splitAt(Offset + Size);
528 if (!LastElemToReplace)
530 size_t Last = *LastElemToReplace;
536 if (Length == 1 && Offsets[
First] == Offset &&
537 getSize(Elems[
First]) == Size) {
540 auto *STy = dyn_cast<llvm::StructType>(DesiredTy);
541 if (STy && STy->getNumElements() == 1 &&
542 STy->getElementType(0) == Elems[
First]->getType())
543 Elems[
First] = llvm::ConstantStruct::get(STy, Elems[
First]);
547 llvm::Constant *Replacement = buildFrom(
549 ArrayRef(Offsets).slice(
First, Length), Offset, getSize(DesiredTy),
550 false, DesiredTy,
false);
551 replace(Elems,
First,
Last, {Replacement});
559class ConstStructBuilder {
562 ConstantAggregateBuilder &Builder;
571 ConstantAggregateBuilder &Const,
CharUnits Offset,
576 ConstantAggregateBuilder &Builder,
CharUnits StartOffset)
578 StartOffset(StartOffset) {}
580 bool AppendField(
const FieldDecl *Field, uint64_t FieldOffset,
581 llvm::Constant *InitExpr,
bool AllowOverwrite =
false);
583 bool AppendBytes(
CharUnits FieldOffsetInChars, llvm::Constant *InitCst,
584 bool AllowOverwrite =
false);
586 bool AppendBitField(
const FieldDecl *Field, uint64_t FieldOffset,
587 llvm::ConstantInt *InitExpr,
bool AllowOverwrite =
false);
595bool ConstStructBuilder::AppendField(
596 const FieldDecl *Field, uint64_t FieldOffset, llvm::Constant *InitCst,
597 bool AllowOverwrite) {
602 return AppendBytes(FieldOffsetInChars, InitCst, AllowOverwrite);
605bool ConstStructBuilder::AppendBytes(
CharUnits FieldOffsetInChars,
606 llvm::Constant *InitCst,
607 bool AllowOverwrite) {
608 return Builder.add(InitCst, StartOffset + FieldOffsetInChars, AllowOverwrite);
611bool ConstStructBuilder::AppendBitField(
612 const FieldDecl *Field, uint64_t FieldOffset, llvm::ConstantInt *CI,
613 bool AllowOverwrite) {
617 llvm::APInt FieldValue = CI->getValue();
623 if (Info.
Size > FieldValue.getBitWidth())
624 FieldValue = FieldValue.zext(Info.
Size);
627 if (Info.
Size < FieldValue.getBitWidth())
628 FieldValue = FieldValue.trunc(Info.
Size);
630 return Builder.addBits(FieldValue,
636 ConstantAggregateBuilder &Const,
640 return ConstStructBuilder::UpdateStruct(
Emitter, Const, Offset, Updater);
642 auto CAT =
Emitter.CGM.getContext().getAsConstantArrayType(
Type);
645 QualType ElemType = CAT->getElementType();
647 llvm::Type *ElemTy =
Emitter.CGM.getTypes().ConvertTypeForMem(ElemType);
649 llvm::Constant *FillC =
nullptr;
651 if (!isa<NoInitExpr>(Filler)) {
652 FillC =
Emitter.tryEmitAbstractForMemory(Filler, ElemType);
658 unsigned NumElementsToUpdate =
659 FillC ? CAT->getSize().getZExtValue() : Updater->
getNumInits();
660 for (
unsigned I = 0; I != NumElementsToUpdate; ++I, Offset += ElemSize) {
662 if (I < Updater->getNumInits())
665 if (!
Init && FillC) {
666 if (!
Const.add(FillC, Offset,
true))
668 }
else if (!
Init || isa<NoInitExpr>(
Init)) {
671 if (!EmitDesignatedInitUpdater(
Emitter, Const, Offset, ElemType,
675 Const.condense(Offset, ElemTy);
677 llvm::Constant *Val =
Emitter.tryEmitPrivateForMemory(
Init, ElemType);
678 if (!
Const.add(Val, Offset,
true))
686bool ConstStructBuilder::Build(
InitListExpr *ILE,
bool AllowOverwrite) {
690 unsigned FieldNo = -1;
691 unsigned ElementNo = 0;
696 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
697 if (CXXRD->getNumBases())
709 if (
Field->isUnnamedBitfield())
715 if (ElementNo < ILE->getNumInits())
731 if (AllowOverwrite &&
732 (
Field->getType()->isArrayType() ||
Field->getType()->isRecordType())) {
733 if (
auto *SubILE = dyn_cast<InitListExpr>(
Init)) {
736 if (!EmitDesignatedInitUpdater(
Emitter, Builder, StartOffset + Offset,
737 Field->getType(), SubILE))
741 Builder.condense(StartOffset + Offset,
747 llvm::Constant *EltInit =
753 if (!
Field->isBitField()) {
760 if (
Field->hasAttr<NoUniqueAddressAttr>())
761 AllowOverwrite =
true;
764 if (
auto *CI = dyn_cast<llvm::ConstantInt>(EltInit)) {
782 :
Decl(
Decl), Offset(Offset), Index(Index) {
789 bool operator<(
const BaseInfo &O)
const {
return Offset < O.Offset; }
802 llvm::Constant *VTableAddressPoint =
805 if (!AppendBytes(Offset, VTableAddressPoint))
812 Bases.reserve(CD->getNumBases());
815 BaseEnd = CD->bases_end();
Base != BaseEnd; ++
Base, ++BaseNo) {
816 assert(!
Base->isVirtual() &&
"should not have virtual bases here");
819 Bases.push_back(BaseInfo(BD, BaseOffset, BaseNo));
821 llvm::stable_sort(Bases);
823 for (
unsigned I = 0, N = Bases.size(); I != N; ++I) {
824 BaseInfo &
Base = Bases[I];
828 VTableClass, Offset +
Base.Offset);
832 unsigned FieldNo = 0;
835 bool AllowOverwrite =
false;
837 FieldEnd = RD->
field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
849 llvm::Constant *EltInit =
850 Emitter.tryEmitPrivateForMemory(FieldValue,
Field->getType());
854 if (!
Field->isBitField()) {
856 if (!AppendField(*Field, Layout.
getFieldOffset(FieldNo) + OffsetBits,
857 EltInit, AllowOverwrite))
861 if (
Field->hasAttr<NoUniqueAddressAttr>())
862 AllowOverwrite =
true;
865 if (!AppendBitField(*Field, Layout.
getFieldOffset(FieldNo) + OffsetBits,
866 cast<llvm::ConstantInt>(EltInit), AllowOverwrite))
874llvm::Constant *ConstStructBuilder::Finalize(
QualType Type) {
887 if (!Builder.Build(ILE,
false))
890 return Builder.Finalize(ValTy);
904 return Builder.Finalize(ValTy);
908 ConstantAggregateBuilder &Const,
910 return ConstStructBuilder(
Emitter, Const, Offset)
911 .Build(Updater,
true);
923 if (llvm::GlobalVariable *Addr =
932 "file-scope compound literal did not have constant initializer!");
936 auto GV =
new llvm::GlobalVariable(
939 llvm::GlobalValue::InternalLinkage,
C,
".compoundliteral",
nullptr,
940 llvm::GlobalVariable::NotThreadLocal,
948static llvm::Constant *
949EmitArrayConstant(
CodeGenModule &CGM, llvm::ArrayType *DesiredType,
950 llvm::Type *CommonElementType,
unsigned ArrayBound,
952 llvm::Constant *Filler) {
954 unsigned NonzeroLength = ArrayBound;
955 if (Elements.size() < NonzeroLength && Filler->isNullValue())
956 NonzeroLength = Elements.size();
957 if (NonzeroLength == Elements.size()) {
958 while (NonzeroLength > 0 && Elements[NonzeroLength - 1]->isNullValue())
962 if (NonzeroLength == 0)
963 return llvm::ConstantAggregateZero::get(DesiredType);
966 unsigned TrailingZeroes = ArrayBound - NonzeroLength;
967 if (TrailingZeroes >= 8) {
968 assert(Elements.size() >= NonzeroLength &&
969 "missing initializer for non-zero element");
973 if (CommonElementType && NonzeroLength >= 8) {
974 llvm::Constant *Initial = llvm::ConstantArray::get(
975 llvm::ArrayType::get(CommonElementType, NonzeroLength),
976 ArrayRef(Elements).take_front(NonzeroLength));
978 Elements[0] = Initial;
980 Elements.resize(NonzeroLength + 1);
984 CommonElementType ? CommonElementType : DesiredType->getElementType();
985 FillerType = llvm::ArrayType::get(FillerType, TrailingZeroes);
986 Elements.back() = llvm::ConstantAggregateZero::get(FillerType);
987 CommonElementType =
nullptr;
988 }
else if (Elements.size() != ArrayBound) {
990 Elements.resize(ArrayBound, Filler);
991 if (Filler->getType() != CommonElementType)
992 CommonElementType =
nullptr;
996 if (CommonElementType)
997 return llvm::ConstantArray::get(
998 llvm::ArrayType::get(CommonElementType, ArrayBound), Elements);
1002 Types.reserve(Elements.size());
1003 for (llvm::Constant *Elt : Elements)
1004 Types.push_back(Elt->getType());
1005 llvm::StructType *SType =
1007 return llvm::ConstantStruct::get(SType, Elements);
1016class ConstExprEmitter :
1017 public StmtVisitor<ConstExprEmitter, llvm::Constant*, QualType> {
1020 llvm::LLVMContext &VMContext;
1023 : CGM(emitter.CGM),
Emitter(emitter), VMContext(CGM.getLLVMContext()) {
1035 if (llvm::Constant *Result =
Emitter.tryEmitConstantExpr(CE))
1052 return Visit(
GE->getResultExpr(), T);
1064 if (
const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
1072 "Destination type is not union type!");
1076 auto C =
Emitter.tryEmitPrivateForMemory(subExpr, field->getType());
1077 if (!
C)
return nullptr;
1079 auto destTy = ConvertType(destType);
1080 if (
C->getType() == destTy)
return C;
1087 Types.push_back(
C->getType());
1088 unsigned CurSize = CGM.
getDataLayout().getTypeAllocSize(
C->getType());
1089 unsigned TotalSize = CGM.
getDataLayout().getTypeAllocSize(destTy);
1091 assert(CurSize <= TotalSize &&
"Union size mismatch!");
1092 if (
unsigned NumPadBytes = TotalSize - CurSize) {
1093 llvm::Type *Ty = CGM.
CharTy;
1094 if (NumPadBytes > 1)
1095 Ty = llvm::ArrayType::get(Ty, NumPadBytes);
1097 Elts.push_back(llvm::UndefValue::get(Ty));
1098 Types.push_back(Ty);
1101 llvm::StructType *STy = llvm::StructType::get(VMContext, Types,
false);
1102 return llvm::ConstantStruct::get(STy, Elts);
1105 case CK_AddressSpaceConversion: {
1107 if (!
C)
return nullptr;
1110 llvm::Type *destTy = ConvertType(E->
getType());
1115 case CK_LValueToRValue: {
1120 if (
auto *E = dyn_cast<CompoundLiteralExpr>(subExpr->
IgnoreParens()))
1121 return Visit(E->getInitializer(), destType);
1125 case CK_AtomicToNonAtomic:
1126 case CK_NonAtomicToAtomic:
1128 case CK_ConstructorConversion:
1129 return Visit(subExpr, destType);
1131 case CK_ArrayToPointerDecay:
1132 if (
const auto *S = dyn_cast<StringLiteral>(subExpr))
1135 case CK_NullToPointer:
1136 if (
Visit(subExpr, destType))
1140 case CK_IntToOCLSampler:
1141 llvm_unreachable(
"global sampler variables are not generated");
1143 case CK_IntegralCast: {
1147 if (llvm::Constant *
C =
Visit(subExpr, FromType))
1148 if (
auto *CI = dyn_cast<llvm::ConstantInt>(
C)) {
1151 if (DstWidth == SrcWidth)
1154 ? CI->getValue().sextOrTrunc(DstWidth)
1155 : CI->getValue().zextOrTrunc(DstWidth);
1161 case CK_Dependent: llvm_unreachable(
"saw dependent cast!");
1163 case CK_BuiltinFnToFnPtr:
1164 llvm_unreachable(
"builtin functions are handled elsewhere");
1166 case CK_ReinterpretMemberPointer:
1167 case CK_DerivedToBaseMemberPointer:
1168 case CK_BaseToDerivedMemberPointer: {
1170 if (!
C)
return nullptr;
1175 case CK_ObjCObjectLValueCast:
1176 case CK_ARCProduceObject:
1177 case CK_ARCConsumeObject:
1178 case CK_ARCReclaimReturnedObject:
1179 case CK_ARCExtendBlockObject:
1180 case CK_CopyAndAutoreleaseBlockObject:
1188 case CK_LValueBitCast:
1189 case CK_LValueToRValueBitCast:
1190 case CK_NullToMemberPointer:
1191 case CK_UserDefinedConversion:
1192 case CK_CPointerToObjCPointerCast:
1193 case CK_BlockPointerToObjCPointerCast:
1194 case CK_AnyPointerToBlockPointerCast:
1195 case CK_FunctionToPointerDecay:
1196 case CK_BaseToDerived:
1197 case CK_DerivedToBase:
1198 case CK_UncheckedDerivedToBase:
1199 case CK_MemberPointerToBoolean:
1200 case CK_VectorSplat:
1201 case CK_FloatingRealToComplex:
1202 case CK_FloatingComplexToReal:
1203 case CK_FloatingComplexToBoolean:
1204 case CK_FloatingComplexCast:
1205 case CK_FloatingComplexToIntegralComplex:
1206 case CK_IntegralRealToComplex:
1207 case CK_IntegralComplexToReal:
1208 case CK_IntegralComplexToBoolean:
1209 case CK_IntegralComplexCast:
1210 case CK_IntegralComplexToFloatingComplex:
1211 case CK_PointerToIntegral:
1212 case CK_PointerToBoolean:
1213 case CK_BooleanToSignedIntegral:
1214 case CK_IntegralToPointer:
1215 case CK_IntegralToBoolean:
1216 case CK_IntegralToFloating:
1217 case CK_FloatingToIntegral:
1218 case CK_FloatingToBoolean:
1219 case CK_FloatingCast:
1220 case CK_FloatingToFixedPoint:
1221 case CK_FixedPointToFloating:
1222 case CK_FixedPointCast:
1223 case CK_FixedPointToBoolean:
1224 case CK_FixedPointToIntegral:
1225 case CK_IntegralToFixedPoint:
1226 case CK_ZeroToOCLOpaqueType:
1228 case CK_HLSLVectorTruncation:
1231 llvm_unreachable(
"Invalid CastKind");
1250 assert(CAT &&
"can't emit array init for non-constant-bound array");
1252 unsigned NumElements = CAT->getSize().getZExtValue();
1256 unsigned NumInitableElts = std::min(NumInitElements, NumElements);
1258 QualType EltType = CAT->getElementType();
1261 llvm::Constant *fillC =
nullptr;
1263 fillC =
Emitter.tryEmitAbstractForMemory(filler, EltType);
1270 if (fillC && fillC->isNullValue())
1271 Elts.reserve(NumInitableElts + 1);
1273 Elts.reserve(NumElements);
1275 llvm::Type *CommonElementType =
nullptr;
1276 for (
unsigned i = 0; i < NumInitableElts; ++i) {
1278 llvm::Constant *
C =
Emitter.tryEmitPrivateForMemory(
Init, EltType);
1282 CommonElementType =
C->getType();
1283 else if (
C->getType() != CommonElementType)
1284 CommonElementType =
nullptr;
1288 llvm::ArrayType *Desired =
1290 return EmitArrayConstant(CGM, Desired, CommonElementType, NumElements, Elts,
1295 return ConstStructBuilder::BuildStruct(
Emitter, ILE, T);
1308 return EmitArrayInitialization(ILE, T);
1311 return EmitRecordInitialization(ILE, T);
1322 ConstantAggregateBuilder
Const(CGM);
1330 bool HasFlexibleArray =
false;
1332 HasFlexibleArray = RT->getDecl()->hasFlexibleArrayMember();
1333 return Const.build(ValTy, HasFlexibleArray);
1342 assert(E->
getNumArgs() == 1 &&
"trivial ctor with > 1 argument");
1344 "trivial ctor has argument but isn't a copy/move ctor");
1348 "argument to copy ctor is of wrong type");
1352 if (
auto *MTE = dyn_cast<MaterializeTemporaryExpr>(Arg))
1353 return Visit(MTE->getSubExpr(), Ty);
1373 assert(CAT &&
"String data not of constant array type!");
1377 Str.resize(CAT->
getSize().getZExtValue(),
'\0');
1378 return llvm::ConstantDataArray::getString(VMContext, Str,
false);
1386 if (llvm::Constant *
C =
Visit(
U->getSubExpr(), T))
1387 if (
auto *CI = dyn_cast<llvm::ConstantInt>(
C))
1388 return llvm::ConstantInt::get(CGM.
getLLVMContext(), -CI->getValue());
1397 llvm::Type *ConvertType(
QualType T) {
1404llvm::Constant *ConstantEmitter::validateAndPopAbstract(llvm::Constant *
C,
1405 AbstractState saved) {
1406 Abstract = saved.OldValue;
1408 assert(saved.OldPlaceholdersSize == PlaceholderAddresses.size() &&
1409 "created a placeholder while doing an abstract emission?");
1418 auto state = pushAbstract();
1420 return validateAndPopAbstract(
C, state);
1425 auto state = pushAbstract();
1427 return validateAndPopAbstract(
C, state);
1432 auto state = pushAbstract();
1434 return validateAndPopAbstract(
C, state);
1450 auto state = pushAbstract();
1452 C = validateAndPopAbstract(
C, state);
1455 "internal error: could not emit constant value \"abstractly\"");
1464 auto state = pushAbstract();
1466 C = validateAndPopAbstract(
C, state);
1469 "internal error: could not emit constant value \"abstractly\"");
1483 initializeNonAbstract(destAddrSpace);
1490 initializeNonAbstract(destAddrSpace);
1492 assert(
C &&
"couldn't emit constant value non-abstractly?");
1497 assert(!Abstract &&
"cannot get current address for abstract constant");
1504 llvm::GlobalValue::PrivateLinkage,
1508 llvm::GlobalVariable::NotThreadLocal,
1511 PlaceholderAddresses.push_back(std::make_pair(
nullptr, global));
1517 llvm::GlobalValue *placeholder) {
1518 assert(!PlaceholderAddresses.empty());
1519 assert(PlaceholderAddresses.back().first ==
nullptr);
1520 assert(PlaceholderAddresses.back().second == placeholder);
1521 PlaceholderAddresses.back().first = signal;
1525 struct ReplacePlaceholders {
1529 llvm::Constant *
Base;
1530 llvm::Type *BaseValueTy =
nullptr;
1533 llvm::DenseMap<llvm::Constant*, llvm::GlobalVariable*> PlaceholderAddresses;
1536 llvm::DenseMap<llvm::GlobalVariable*, llvm::Constant*> Locations;
1544 ReplacePlaceholders(
CodeGenModule &CGM, llvm::Constant *base,
1545 ArrayRef<std::pair<llvm::Constant*,
1546 llvm::GlobalVariable*>> addresses)
1547 : CGM(CGM),
Base(base),
1548 PlaceholderAddresses(addresses.begin(), addresses.end()) {
1551 void replaceInInitializer(llvm::Constant *init) {
1553 BaseValueTy = init->getType();
1556 Indices.push_back(0);
1557 IndexValues.push_back(
nullptr);
1560 findLocations(init);
1563 assert(IndexValues.size() == Indices.size() &&
"mismatch");
1564 assert(Indices.size() == 1 &&
"didn't pop all indices");
1567 assert(Locations.size() == PlaceholderAddresses.size() &&
1568 "missed a placeholder?");
1574 for (
auto &entry : Locations) {
1575 assert(entry.first->getParent() ==
nullptr &&
"not a placeholder!");
1576 entry.first->replaceAllUsesWith(entry.second);
1577 entry.first->eraseFromParent();
1582 void findLocations(llvm::Constant *init) {
1584 if (
auto agg = dyn_cast<llvm::ConstantAggregate>(init)) {
1585 for (
unsigned i = 0, e = agg->getNumOperands(); i != e; ++i) {
1586 Indices.push_back(i);
1587 IndexValues.push_back(
nullptr);
1589 findLocations(agg->getOperand(i));
1591 IndexValues.pop_back();
1599 auto it = PlaceholderAddresses.find(init);
1600 if (it != PlaceholderAddresses.end()) {
1601 setLocation(it->second);
1606 if (
auto expr = dyn_cast<llvm::ConstantExpr>(init)) {
1607 init =
expr->getOperand(0);
1614 void setLocation(llvm::GlobalVariable *placeholder) {
1615 assert(!Locations.contains(placeholder) &&
1616 "already found location for placeholder!");
1621 assert(Indices.size() == IndexValues.size());
1622 for (
size_t i = Indices.size() - 1; i !=
size_t(-1); --i) {
1623 if (IndexValues[i]) {
1625 for (
size_t j = 0; j != i + 1; ++j) {
1626 assert(IndexValues[j] &&
1627 isa<llvm::ConstantInt>(IndexValues[j]) &&
1628 cast<llvm::ConstantInt>(IndexValues[j])->getZExtValue()
1635 IndexValues[i] = llvm::ConstantInt::get(CGM.
Int32Ty, Indices[i]);
1638 llvm::Constant *location = llvm::ConstantExpr::getInBoundsGetElementPtr(
1639 BaseValueTy,
Base, IndexValues);
1641 Locations.insert({placeholder, location});
1647 assert(InitializedNonAbstract &&
1648 "finalizing emitter that was used for abstract emission?");
1649 assert(!Finalized &&
"finalizing emitter multiple times");
1650 assert(global->getInitializer());
1655 if (!PlaceholderAddresses.empty()) {
1656 ReplacePlaceholders(
CGM, global, PlaceholderAddresses)
1657 .replaceInInitializer(global->getInitializer());
1658 PlaceholderAddresses.clear();
1663 assert((!InitializedNonAbstract || Finalized || Failed) &&
1664 "not finalized after being initialized for non-abstract emission");
1665 assert(PlaceholderAddresses.empty() &&
"unhandled placeholders");
1671 type.getQualifiers());
1684 dyn_cast_or_null<CXXConstructExpr>(D.
getInit())) {
1694 assert(E &&
"No initializer to emit");
1698 if (llvm::Constant *
C = ConstExprEmitter(*this).Visit(
const_cast<Expr *
>(E),
1745 QualType destValueType = AT->getValueType();
1750 if (innerSize == outerSize)
1753 assert(innerSize < outerSize &&
"emitted over-large constant for atomic");
1754 llvm::Constant *elts[] = {
1756 llvm::ConstantAggregateZero::get(
1757 llvm::ArrayType::get(
CGM.
Int8Ty, (outerSize - innerSize) / 8))
1759 return llvm::ConstantStruct::getAnon(elts);
1763 if (
C->getType()->isIntegerTy(1) && !destType->
isBitIntType()) {
1765 llvm::Constant *Res = llvm::ConstantFoldCastOperand(
1767 assert(Res &&
"Constant folding must succeed");
1776 assert(!destType->
isVoidType() &&
"can't emit a void constant");
1779 if (llvm::Constant *
C =
1780 ConstExprEmitter(*this).Visit(
const_cast<Expr *
>(E), destType))
1805struct ConstantLValue {
1806 llvm::Constant *
Value;
1807 bool HasOffsetApplied;
1809 ConstantLValue(llvm::Constant *value,
1810 bool hasOffsetApplied =
false)
1811 :
Value(value), HasOffsetApplied(hasOffsetApplied) {}
1814 : ConstantLValue(address.getPointer()) {}
1818class ConstantLValueEmitter :
public ConstStmtVisitor<ConstantLValueEmitter,
1831 : CGM(emitter.CGM),
Emitter(emitter),
Value(value), DestType(destType) {}
1833 llvm::Constant *tryEmit();
1836 llvm::Constant *tryEmitAbsolute(llvm::Type *destTy);
1839 ConstantLValue VisitStmt(
const Stmt *S) {
return nullptr; }
1840 ConstantLValue VisitConstantExpr(
const ConstantExpr *E);
1848 ConstantLValue VisitCallExpr(
const CallExpr *E);
1849 ConstantLValue VisitBlockExpr(
const BlockExpr *E);
1851 ConstantLValue VisitMaterializeTemporaryExpr(
1854 bool hasNonZeroOffset()
const {
1855 return !
Value.getLValueOffset().isZero();
1859 llvm::Constant *getOffset() {
1860 return llvm::ConstantInt::get(CGM.
Int64Ty,
1861 Value.getLValueOffset().getQuantity());
1865 llvm::Constant *applyOffset(llvm::Constant *
C) {
1866 if (!hasNonZeroOffset())
1869 return llvm::ConstantExpr::getGetElementPtr(CGM.
Int8Ty,
C, getOffset());
1875llvm::Constant *ConstantLValueEmitter::tryEmit() {
1886 assert(isa<llvm::IntegerType>(destTy) || isa<llvm::PointerType>(destTy));
1891 return tryEmitAbsolute(destTy);
1895 ConstantLValue result = tryEmitBase(base);
1898 llvm::Constant *value = result.Value;
1899 if (!value)
return nullptr;
1902 if (!result.HasOffsetApplied) {
1903 value = applyOffset(value);
1908 if (isa<llvm::PointerType>(destTy))
1909 return llvm::ConstantExpr::getPointerCast(value, destTy);
1911 return llvm::ConstantExpr::getPtrToInt(value, destTy);
1917ConstantLValueEmitter::tryEmitAbsolute(llvm::Type *destTy) {
1919 auto destPtrTy = cast<llvm::PointerType>(destTy);
1920 if (
Value.isNullPointer()) {
1928 auto intptrTy = CGM.
getDataLayout().getIntPtrType(destPtrTy);
1930 C = llvm::ConstantFoldIntegerCast(getOffset(), intptrTy,
false,
1932 assert(
C &&
"Must have folded, as Offset is a ConstantInt");
1933 C = llvm::ConstantExpr::getIntToPtr(
C, destPtrTy);
1943 D = cast<ValueDecl>(D->getMostRecentDecl());
1945 if (D->hasAttr<WeakRefAttr>())
1948 if (
auto FD = dyn_cast<FunctionDecl>(D))
1951 if (
auto VD = dyn_cast<VarDecl>(D)) {
1953 if (!VD->hasLocalStorage()) {
1954 if (VD->isFileVarDecl() || VD->hasExternalStorage())
1957 if (VD->isLocalVarDecl()) {
1964 if (
auto *GD = dyn_cast<MSGuidDecl>(D))
1967 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D))
1970 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(D))
1981 return Visit(base.
get<
const Expr*>());
1985ConstantLValueEmitter::VisitConstantExpr(
const ConstantExpr *E) {
1986 if (llvm::Constant *
Result =
Emitter.tryEmitConstantExpr(E))
1994 CompoundLiteralEmitter.setInConstantContext(
Emitter.isInConstantContext());
1995 return tryEmitGlobalCompoundLiteral(CompoundLiteralEmitter, E);
1999ConstantLValueEmitter::VisitStringLiteral(
const StringLiteral *E) {
2004ConstantLValueEmitter::VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
2021ConstantLValueEmitter::VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
2023 "this boxed expression can't be emitted as a compile-time constant");
2029ConstantLValueEmitter::VisitPredefinedExpr(
const PredefinedExpr *E) {
2034ConstantLValueEmitter::VisitAddrLabelExpr(
const AddrLabelExpr *E) {
2035 assert(
Emitter.CGF &&
"Invalid address of label expression outside function");
2041ConstantLValueEmitter::VisitCallExpr(
const CallExpr *E) {
2043 if (builtin == Builtin::BI__builtin_function_start)
2046 if (builtin != Builtin::BI__builtin___CFStringMakeConstantString &&
2047 builtin != Builtin::BI__builtin___NSStringMakeConstantString)
2051 if (builtin == Builtin::BI__builtin___NSStringMakeConstantString) {
2060ConstantLValueEmitter::VisitBlockExpr(
const BlockExpr *E) {
2061 StringRef functionName;
2063 functionName = CGF->CurFn->
getName();
2065 functionName =
"global";
2071ConstantLValueEmitter::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
2081ConstantLValueEmitter::VisitMaterializeTemporaryExpr(
2096 return ConstantLValueEmitter(*
this,
Value, DestType).tryEmit();
2101 Value.getFixedPoint().getValue());
2106 Value.getComplexIntReal());
2108 Value.getComplexIntImag());
2111 llvm::StructType *STy =
2112 llvm::StructType::get(
Complex[0]->getType(),
Complex[1]->getType());
2113 return llvm::ConstantStruct::get(STy,
Complex);
2116 const llvm::APFloat &
Init =
Value.getFloat();
2117 if (&
Init.getSemantics() == &llvm::APFloat::IEEEhalf() &&
2121 Init.bitcastToAPInt());
2129 Value.getComplexFloatReal());
2131 Value.getComplexFloatImag());
2134 llvm::StructType *STy =
2135 llvm::StructType::get(
Complex[0]->getType(),
Complex[1]->getType());
2136 return llvm::ConstantStruct::get(STy,
Complex);
2139 unsigned NumElts =
Value.getVectorLength();
2142 for (
unsigned I = 0; I != NumElts; ++I) {
2152 llvm_unreachable(
"unsupported vector element type");
2154 return llvm::ConstantVector::get(Inits);
2161 if (!LHS || !RHS)
return nullptr;
2165 LHS = llvm::ConstantExpr::getPtrToInt(LHS,
CGM.
IntPtrTy);
2166 RHS = llvm::ConstantExpr::getPtrToInt(RHS,
CGM.
IntPtrTy);
2167 llvm::Constant *AddrLabelDiff = llvm::ConstantExpr::getSub(LHS, RHS);
2172 return llvm::ConstantExpr::getTruncOrBitCast(AddrLabelDiff, ResultType);
2176 return ConstStructBuilder::BuildStruct(*
this,
Value, DestType);
2179 unsigned NumElements =
Value.getArraySize();
2180 unsigned NumInitElts =
Value.getArrayInitializedElts();
2183 llvm::Constant *Filler =
nullptr;
2184 if (
Value.hasArrayFiller()) {
2193 if (Filler && Filler->isNullValue())
2194 Elts.reserve(NumInitElts + 1);
2196 Elts.reserve(NumElements);
2198 llvm::Type *CommonElementType =
nullptr;
2199 for (
unsigned I = 0; I < NumInitElts; ++I) {
2202 if (!
C)
return nullptr;
2205 CommonElementType =
C->getType();
2206 else if (
C->getType() != CommonElementType)
2207 CommonElementType =
nullptr;
2211 llvm::ArrayType *Desired =
2216 Desired = llvm::ArrayType::get(Desired->getElementType(), Elts.size());
2218 return EmitArrayConstant(
CGM, Desired, CommonElementType, NumElements, Elts,
2224 llvm_unreachable(
"Unknown APValue kind");
2229 return EmittedCompoundLiterals.lookup(E);
2234 bool Ok = EmittedCompoundLiterals.insert(std::make_pair(CLE, GV)).second;
2236 assert(Ok &&
"CLE has already been emitted!");
2241 assert(E->
isFileScope() &&
"not a file-scope compound literal expr");
2243 return tryEmitGlobalCompoundLiteral(emitter, E);
2263 llvm::Type *baseType,
2268 bool asCompleteObject) {
2270 llvm::StructType *structure =
2274 unsigned numElements = structure->getNumElements();
2275 std::vector<llvm::Constant *> elements(numElements);
2277 auto CXXR = dyn_cast<CXXRecordDecl>(record);
2280 for (
const auto &I : CXXR->bases()) {
2281 if (I.isVirtual()) {
2297 llvm::Type *baseType = structure->getElementType(fieldIndex);
2303 for (
const auto *Field : record->
fields()) {
2306 if (!Field->isBitField() && !Field->isZeroSize(CGM.
getContext())) {
2313 if (Field->getIdentifier())
2315 if (
const auto *FieldRD = Field->getType()->getAsRecordDecl())
2316 if (FieldRD->findFirstNamedDataMember())
2322 if (CXXR && asCompleteObject) {
2323 for (
const auto &I : CXXR->vbases()) {
2334 if (elements[fieldIndex])
continue;
2336 llvm::Type *baseType = structure->getElementType(fieldIndex);
2342 for (
unsigned i = 0; i != numElements; ++i) {
2344 elements[i] = llvm::Constant::getNullValue(structure->getElementType(i));
2347 return llvm::ConstantStruct::get(structure, elements);
2352 llvm::Type *baseType,
2358 return llvm::Constant::getNullValue(baseType);
2372 cast<llvm::PointerType>(
getTypes().ConvertTypeForMem(T)), T);
2374 if (
getTypes().isZeroInitializable(T))
2375 return llvm::Constant::getNullValue(
getTypes().ConvertTypeForMem(T));
2378 llvm::ArrayType *ATy =
2379 cast<llvm::ArrayType>(
getTypes().ConvertTypeForMem(T));
2383 llvm::Constant *Element =
2385 unsigned NumElements = CAT->
getSize().getZExtValue();
2387 return llvm::ConstantArray::get(ATy, Array);
2391 return ::EmitNullConstant(*
this, RT->getDecl(),
true);
2394 "Should only see pointers to data members here!");
2401 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
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,...
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.
LabelDecl * getLabel() const
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.
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.
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.
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
QualType getTypeOperand(ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
bool isTypeOperand() const
Expr * getExprOperand() const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
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.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
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.
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
llvm::StringRef getName() const
Return the IR name of the pointer value.
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 * getVTableAddressPointForConstExpr(BaseSubobject Base, const CXXRecordDecl *VTableClass)=0
Get the address point of the vtable for the given base subobject while building a constexpr.
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.
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 * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
llvm::Constant * GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty=nullptr, bool ForVTable=false, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
Return the address of the given function.
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.
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.
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.
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.
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
llvm::Type * ConvertTypeForMem(QualType T, bool ForBitField=false)
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)
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)
virtual llvm::Value * performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, llvm::Value *V, LangAS SrcAddr, LangAS DestAddr, llvm::Type *DestTy, bool IsNonNull=false) const
Perform address space cast of an expression of pointer type.
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].
const Expr * getInitializer() const
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Represents the canonical version of C arrays with a specified constant size.
const llvm::APInt & getSize() const
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.
InitListExpr * getUpdater() const
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...
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...
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
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
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.
ObjCBoxedExpr - used for generalized expression boxing.
bool isExpressibleAsConstantInitializer() const
ObjCEncodeExpr, used for @encode in Objective-C.
QualType getEncodedType() const
ObjCStringLiteral, used for Objective-C string literals i.e.
StringLiteral * getString()
Expr * getSelectedExpr() const
ParenExpr - This represents a parethesized expression, e.g.
const Expr * getSubExpr() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
[C99 6.4.2.2] - A predefined identifier such as func.
StringLiteral * getFunctionName()
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)
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Stmt - This represents one statement.
StringLiteral - This represents a string literal expression, e.g.
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 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
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
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.
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.
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.