clang: lib/CodeGen/CGExprConstant.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

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"

34#include

35using namespace clang;

36using namespace CodeGen;

37

38

39

40

41

42namespace {

43class ConstExprEmitter;

44

46 llvm::Type *Ty = CGM.CharTy;

48 Ty = llvm::ArrayType::get(Ty, PadSize.getQuantity());

50 return llvm::Constant::getNullValue(Ty);

51 }

52 return llvm::UndefValue::get(Ty);

53}

54

55struct ConstantAggregateBuilderUtils {

57

58 ConstantAggregateBuilderUtils(CodeGenModule &CGM) : CGM(CGM) {}

59

60 CharUnits getAlignment(const llvm::Constant *C) const {

63 }

64

65 CharUnits getSize(llvm::Type *Ty) const {

67 }

68

69 CharUnits getSize(const llvm::Constant *C) const {

70 return getSize(C->getType());

71 }

72

73 llvm::Constant *getPadding(CharUnits PadSize) const {

74 return ::getPadding(CGM, PadSize);

75 }

76

77 llvm::Constant *getZeroes(CharUnits ZeroSize) const {

78 llvm::Type *Ty = llvm::ArrayType::get(CGM.CharTy, ZeroSize.getQuantity());

79 return llvm::ConstantAggregateZero::get(Ty);

80 }

81};

82

83

84

85class ConstantAggregateBuilder : private ConstantAggregateBuilderUtils {

86

87

88

89

90

91

92

93

96

97

98

99

101

102

103

104 bool NaturalLayout = true;

105

106 bool split(size_t Index, CharUnits Hint);

107 std::optional<size_t> splitAt(CharUnits Pos);

108

109 static llvm::Constant *buildFrom(CodeGenModule &CGM,

113 bool NaturalLayout, llvm::Type *DesiredTy,

114 bool AllowOversized);

115

116public:

118 : ConstantAggregateBuilderUtils(CGM) {}

119

120

121

122

123

124

125 bool add(llvm::Constant *C, CharUnits Offset, bool AllowOverwrite);

126

127

128 bool addBits(llvm::APInt Bits, uint64_t OffsetInBits, bool AllowOverwrite);

129

130

131

132 void condense(CharUnits Offset, llvm::Type *DesiredTy);

133

134

135

136

137

138

139 llvm::Constant *build(llvm::Type *DesiredTy, bool AllowOversized) const {

140 return buildFrom(CGM, Elems, Offsets, CharUnits::Zero(), Size,

141 NaturalLayout, DesiredTy, AllowOversized);

142 }

143};

144

145template<typename Container, typename Range = std::initializer_list<

146 typename Container::value_type>>

147static void replace(Container &C, size_t BeginOff, size_t EndOff, Range Vals) {

148 assert(BeginOff <= EndOff && "invalid replacement range");

149 llvm::replace(C, C.begin() + BeginOff, C.begin() + EndOff, Vals);

150}

151

152bool ConstantAggregateBuilder::add(llvm::Constant *C, CharUnits Offset,

153 bool AllowOverwrite) {

154

155 if (Offset >= Size) {

158 if (AlignedSize > Offset || Offset.alignTo(Align) != Offset)

159 NaturalLayout = false;

160 else if (AlignedSize < Offset) {

161 Elems.push_back(getPadding(Offset - Size));

162 Offsets.push_back(Size);

163 }

164 Elems.push_back(C);

165 Offsets.push_back(Offset);

166 Size = Offset + getSize(C);

167 return true;

168 }

169

170

171 std::optional<size_t> FirstElemToReplace = splitAt(Offset);

172 if (!FirstElemToReplace)

173 return false;

174

176 std::optional<size_t> LastElemToReplace = splitAt(Offset + CSize);

177 if (!LastElemToReplace)

178 return false;

179

180 assert((FirstElemToReplace == LastElemToReplace || AllowOverwrite) &&

181 "unexpectedly overwriting field");

182

183 replace(Elems, *FirstElemToReplace, *LastElemToReplace, {C});

184 replace(Offsets, *FirstElemToReplace, *LastElemToReplace, {Offset});

185 Size = std::max(Size, Offset + CSize);

186 NaturalLayout = false;

187 return true;

188}

189

190bool ConstantAggregateBuilder::addBits(llvm::APInt Bits, uint64_t OffsetInBits,

191 bool AllowOverwrite) {

194

195

196

197 unsigned OffsetWithinChar = OffsetInBits % CharWidth;

198

199

200

203 ; ++OffsetInChars) {

204

205 unsigned WantedBits =

206 std::min((uint64_t)Bits.getBitWidth(), CharWidth - OffsetWithinChar);

207

208

209

210 llvm::APInt BitsThisChar = Bits;

211 if (BitsThisChar.getBitWidth() < CharWidth)

212 BitsThisChar = BitsThisChar.zext(CharWidth);

214

215

216 int Shift = Bits.getBitWidth() - CharWidth + OffsetWithinChar;

217 if (Shift > 0)

218 BitsThisChar.lshrInPlace(Shift);

219 else if (Shift < 0)

220 BitsThisChar = BitsThisChar.shl(-Shift);

221 } else {

222 BitsThisChar = BitsThisChar.shl(OffsetWithinChar);

223 }

224 if (BitsThisChar.getBitWidth() > CharWidth)

225 BitsThisChar = BitsThisChar.trunc(CharWidth);

226

227 if (WantedBits == CharWidth) {

228

229 add(llvm::ConstantInt::get(CGM.getLLVMContext(), BitsThisChar),

230 OffsetInChars, AllowOverwrite);

231 } else {

232

233

234

235 std::optional<size_t> FirstElemToUpdate = splitAt(OffsetInChars);

236 if (!FirstElemToUpdate)

237 return false;

238 std::optional<size_t> LastElemToUpdate =

240 if (!LastElemToUpdate)

241 return false;

242 assert(*LastElemToUpdate - *FirstElemToUpdate < 2 &&

243 "should have at most one element covering one byte");

244

245

246 llvm::APInt UpdateMask(CharWidth, 0);

248 UpdateMask.setBits(CharWidth - OffsetWithinChar - WantedBits,

249 CharWidth - OffsetWithinChar);

250 else

251 UpdateMask.setBits(OffsetWithinChar, OffsetWithinChar + WantedBits);

252 BitsThisChar &= UpdateMask;

253

254 if (*FirstElemToUpdate == *LastElemToUpdate ||

255 Elems[*FirstElemToUpdate]->isNullValue() ||

256 isallvm::UndefValue(Elems[*FirstElemToUpdate])) {

257

258 add(llvm::ConstantInt::get(CGM.getLLVMContext(), BitsThisChar),

259 OffsetInChars, true);

260 } else {

261 llvm::Constant *&ToUpdate = Elems[*FirstElemToUpdate];

262

263

264 auto *CI = dyn_castllvm::ConstantInt(ToUpdate);

265 if (!CI)

266 return false;

267

268

269 assert(CI->getBitWidth() == CharWidth && "splitAt failed");

270 assert((!(CI->getValue() & UpdateMask) || AllowOverwrite) &&

271 "unexpectedly overwriting bitfield");

272 BitsThisChar |= (CI->getValue() & ~UpdateMask);

273 ToUpdate = llvm::ConstantInt::get(CGM.getLLVMContext(), BitsThisChar);

274 }

275 }

276

277

278 if (WantedBits == Bits.getBitWidth())

279 break;

280

281

283 Bits.lshrInPlace(WantedBits);

284 Bits = Bits.trunc(Bits.getBitWidth() - WantedBits);

285

286

287 OffsetWithinChar = 0;

288 }

289

290 return true;

291}

292

293

294

295

296

297std::optional<size_t> ConstantAggregateBuilder::splitAt(CharUnits Pos) {

298 if (Pos >= Size)

299 return Offsets.size();

300

301 while (true) {

302 auto FirstAfterPos = llvm::upper_bound(Offsets, Pos);

303 if (FirstAfterPos == Offsets.begin())

304 return 0;

305

306

307 size_t LastAtOrBeforePosIndex = FirstAfterPos - Offsets.begin() - 1;

308 if (Offsets[LastAtOrBeforePosIndex] == Pos)

309 return LastAtOrBeforePosIndex;

310

311

312 if (Offsets[LastAtOrBeforePosIndex] +

313 getSize(Elems[LastAtOrBeforePosIndex]) <= Pos)

314 return LastAtOrBeforePosIndex + 1;

315

316

317 if (!split(LastAtOrBeforePosIndex, Pos))

318 return std::nullopt;

319 }

320}

321

322

323

324

325bool ConstantAggregateBuilder::split(size_t Index, CharUnits Hint) {

326 NaturalLayout = false;

327 llvm::Constant *C = Elems[Index];

328 CharUnits Offset = Offsets[Index];

329

330 if (auto *CA = dyn_castllvm::ConstantAggregate(C)) {

331

332

333 replace(Elems, Index, Index + 1,

334 llvm::map_range(llvm::seq(0u, CA->getNumOperands()),

335 [&](unsigned Op) { return CA->getOperand(Op); }));

336 if (isallvm::ArrayType(CA->getType()) ||

337 isallvm::VectorType(CA->getType())) {

338

339 llvm::Type *ElemTy =

340 llvm::GetElementPtrInst::getTypeAtIndex(CA->getType(), (uint64_t)0);

341 CharUnits ElemSize = getSize(ElemTy);

342 replace(

343 Offsets, Index, Index + 1,

344 llvm::map_range(llvm::seq(0u, CA->getNumOperands()),

345 [&](unsigned Op) { return Offset + Op * ElemSize; }));

346 } else {

347

348 auto *ST = castllvm::StructType(CA->getType());

349 const llvm::StructLayout *Layout =

351 replace(Offsets, Index, Index + 1,

352 llvm::map_range(

353 llvm::seq(0u, CA->getNumOperands()), [&](unsigned Op) {

354 return Offset + CharUnits::fromQuantity(

355 Layout->getElementOffset(Op));

356 }));

357 }

358 return true;

359 }

360

361 if (auto *CDS = dyn_castllvm::ConstantDataSequential(C)) {

362

363

364

365 CharUnits ElemSize = getSize(CDS->getElementType());

366 replace(Elems, Index, Index + 1,

367 llvm::map_range(llvm::seq(0u, CDS->getNumElements()),

368 [&](unsigned Elem) {

369 return CDS->getElementAsConstant(Elem);

370 }));

371 replace(Offsets, Index, Index + 1,

372 llvm::map_range(

373 llvm::seq(0u, CDS->getNumElements()),

374 [&](unsigned Elem) { return Offset + Elem * ElemSize; }));

375 return true;

376 }

377

378 if (isallvm::ConstantAggregateZero(C)) {

379

381 assert(Hint > Offset && Hint < Offset + ElemSize && "nothing to split");

382 replace(Elems, Index, Index + 1,

383 {getZeroes(Hint - Offset), getZeroes(Offset + ElemSize - Hint)});

384 replace(Offsets, Index, Index + 1, {Offset, Hint});

385 return true;

386 }

387

388 if (isallvm::UndefValue(C)) {

389

390 replace(Elems, Index, Index + 1, {});

391 replace(Offsets, Index, Index + 1, {});

392 return true;

393 }

394

395

396

397

398

399 return false;

400}

401

402static llvm::Constant *

403EmitArrayConstant(CodeGenModule &CGM, llvm::ArrayType *DesiredType,

404 llvm::Type *CommonElementType, uint64_t ArrayBound,

406 llvm::Constant *Filler);

407

408llvm::Constant *ConstantAggregateBuilder::buildFrom(

411 bool NaturalLayout, llvm::Type *DesiredTy, bool AllowOversized) {

412 ConstantAggregateBuilderUtils Utils(CGM);

413

414 if (Elems.empty())

415 return llvm::UndefValue::get(DesiredTy);

416

417 auto Offset = [&](size_t I) { return Offsets[I] - StartOffset; };

418

419

420

421 if (llvm::ArrayType *ATy = dyn_castllvm::ArrayType(DesiredTy)) {

422 assert(!AllowOversized && "oversized array emission not supported");

423

424 bool CanEmitArray = true;

425 llvm::Type *CommonType = Elems[0]->getType();

426 llvm::Constant *Filler = llvm::Constant::getNullValue(CommonType);

427 CharUnits ElemSize = Utils.getSize(ATy->getElementType());

429 for (size_t I = 0; I != Elems.size(); ++I) {

430

431 if (Elems[I]->isNullValue())

432 continue;

433

434

435 if (Elems[I]->getType() != CommonType ||

436 Offset(I) % ElemSize != 0) {

437 CanEmitArray = false;

438 break;

439 }

440 ArrayElements.resize(Offset(I) / ElemSize + 1, Filler);

441 ArrayElements.back() = Elems[I];

442 }

443

444 if (CanEmitArray) {

445 return EmitArrayConstant(CGM, ATy, CommonType, ATy->getNumElements(),

446 ArrayElements, Filler);

447 }

448

449

450 }

451

452

453

454

455 CharUnits DesiredSize = Utils.getSize(DesiredTy);

456 if (Size > DesiredSize) {

457 assert(AllowOversized && "Elems are oversized");

458 DesiredSize = Size;

459 }

460

461

463 for (llvm::Constant *C : Elems)

464 Align = std::max(Align, Utils.getAlignment(C));

465

466

468

469 bool Packed = false;

472 if (DesiredSize < AlignedSize || DesiredSize.alignTo(Align) != DesiredSize) {

473

474 NaturalLayout = false;

475 Packed = true;

476 } else if (DesiredSize > AlignedSize) {

477

478

479 UnpackedElemStorage.assign(Elems.begin(), Elems.end());

480 UnpackedElemStorage.push_back(Utils.getPadding(DesiredSize - Size));

481 UnpackedElems = UnpackedElemStorage;

482 }

483

484

485

486

488 if (!NaturalLayout) {

490 for (size_t I = 0; I != Elems.size(); ++I) {

491 CharUnits Align = Utils.getAlignment(Elems[I]);

493 CharUnits DesiredOffset = Offset(I);

494 assert(DesiredOffset >= SizeSoFar && "elements out of order");

495

496 if (DesiredOffset != NaturalOffset)

497 Packed = true;

498 if (DesiredOffset != SizeSoFar)

499 PackedElems.push_back(Utils.getPadding(DesiredOffset - SizeSoFar));

500 PackedElems.push_back(Elems[I]);

501 SizeSoFar = DesiredOffset + Utils.getSize(Elems[I]);

502 }

503

504

505 if (Packed) {

506 assert(SizeSoFar <= DesiredSize &&

507 "requested size is too small for contents");

508 if (SizeSoFar < DesiredSize)

509 PackedElems.push_back(Utils.getPadding(DesiredSize - SizeSoFar));

510 }

511 }

512

513 llvm::StructType *STy = llvm::ConstantStruct::getTypeForElements(

514 CGM.getLLVMContext(), Packed ? PackedElems : UnpackedElems, Packed);

515

516

517

518 if (llvm::StructType *DesiredSTy = dyn_castllvm::StructType(DesiredTy)) {

519 if (DesiredSTy->isLayoutIdentical(STy))

520 STy = DesiredSTy;

521 }

522

523 return llvm::ConstantStruct::get(STy, Packed ? PackedElems : UnpackedElems);

524}

525

526void ConstantAggregateBuilder::condense(CharUnits Offset,

527 llvm::Type *DesiredTy) {

529

530 std::optional<size_t> FirstElemToReplace = splitAt(Offset);

531 if (!FirstElemToReplace)

532 return;

533 size_t First = *FirstElemToReplace;

534

535 std::optional<size_t> LastElemToReplace = splitAt(Offset + Size);

536 if (!LastElemToReplace)

537 return;

538 size_t Last = *LastElemToReplace;

539

541 if (Length == 0)

542 return;

543

544 if (Length == 1 && Offsets[First] == Offset &&

545 getSize(Elems[First]) == Size) {

546

547

548 auto *STy = dyn_castllvm::StructType(DesiredTy);

549 if (STy && STy->getNumElements() == 1 &&

550 STy->getElementType(0) == Elems[First]->getType())

551 Elems[First] = llvm::ConstantStruct::get(STy, Elems[First]);

552 return;

553 }

554

555 llvm::Constant *Replacement = buildFrom(

557 ArrayRef(Offsets).slice(First, Length), Offset, getSize(DesiredTy),

558 false, DesiredTy, false);

559 replace(Elems, First, Last, {Replacement});

560 replace(Offsets, First, Last, {Offset});

561}

562

563

564

565

566

567class ConstStructBuilder {

570 ConstantAggregateBuilder &Builder;

572

573public:

580 ConstantAggregateBuilder &Const, CharUnits Offset,

582

583private:

585 ConstantAggregateBuilder &Builder, CharUnits StartOffset)

587 StartOffset(StartOffset) {}

588

589 bool AppendField(const FieldDecl *Field, uint64_t FieldOffset,

590 llvm::Constant *InitExpr, bool AllowOverwrite = false);

591

592 bool AppendBytes(CharUnits FieldOffsetInChars, llvm::Constant *InitCst,

593 bool AllowOverwrite = false);

594

595 bool AppendBitField(const FieldDecl *Field, uint64_t FieldOffset,

596 llvm::Constant *InitExpr, bool AllowOverwrite = false);

597

598 bool Build(const InitListExpr *ILE, bool AllowOverwrite);

599 bool Build(const APValue &Val, const RecordDecl *RD, bool IsPrimaryBase,

601 bool DoZeroInitPadding(const ASTRecordLayout &Layout, unsigned FieldNo,

602 const FieldDecl &Field, bool AllowOverwrite,

603 CharUnits &SizeSoFar, bool &ZeroFieldSize);

604 bool DoZeroInitPadding(const ASTRecordLayout &Layout, bool AllowOverwrite,

607};

608

609bool ConstStructBuilder::AppendField(

610 const FieldDecl *Field, uint64_t FieldOffset, llvm::Constant *InitCst,

611 bool AllowOverwrite) {

613

615

616 return AppendBytes(FieldOffsetInChars, InitCst, AllowOverwrite);

617}

618

619bool ConstStructBuilder::AppendBytes(CharUnits FieldOffsetInChars,

620 llvm::Constant *InitCst,

621 bool AllowOverwrite) {

622 return Builder.add(InitCst, StartOffset + FieldOffsetInChars, AllowOverwrite);

623}

624

625bool ConstStructBuilder::AppendBitField(const FieldDecl *Field,

626 uint64_t FieldOffset, llvm::Constant *C,

627 bool AllowOverwrite) {

628

629 llvm::ConstantInt *CI = dyn_castllvm::ConstantInt(C);

630 if (!CI) {

631

632

633

634

635 llvm::Type *LoadType =

637 llvm::Constant *FoldedConstant = llvm::ConstantFoldLoadFromConst(

638 C, LoadType, llvm::APInt::getZero(32), CGM.getDataLayout());

639 CI = dyn_cast_if_presentllvm::ConstantInt(FoldedConstant);

640 if (!CI)

641 return false;

642 }

643

647 llvm::APInt FieldValue = CI->getValue();

648

649

650

651

652

653 if (Info.Size > FieldValue.getBitWidth())

654 FieldValue = FieldValue.zext(Info.Size);

655

656

657 if (Info.Size < FieldValue.getBitWidth())

658 FieldValue = FieldValue.trunc(Info.Size);

659

660 return Builder.addBits(FieldValue,

662 AllowOverwrite);

663}

664

666 ConstantAggregateBuilder &Const,

670 return ConstStructBuilder::UpdateStruct(Emitter, Const, Offset, Updater);

671

672 auto CAT = Emitter.CGM.getContext().getAsConstantArrayType(Type);

673 if (!CAT)

674 return false;

675 QualType ElemType = CAT->getElementType();

676 CharUnits ElemSize = Emitter.CGM.getContext().getTypeSizeInChars(ElemType);

677 llvm::Type *ElemTy = Emitter.CGM.getTypes().ConvertTypeForMem(ElemType);

678

679 llvm::Constant *FillC = nullptr;

681 if (!isa(Filler)) {

682 FillC = Emitter.tryEmitAbstractForMemory(Filler, ElemType);

683 if (!FillC)

684 return false;

685 }

686 }

687

688 unsigned NumElementsToUpdate =

689 FillC ? CAT->getZExtSize() : Updater->getNumInits();

690 for (unsigned I = 0; I != NumElementsToUpdate; ++I, Offset += ElemSize) {

692 if (I < Updater->getNumInits())

694

695 if (Init && FillC) {

696 if (Const.add(FillC, Offset, true))

697 return false;

698 } else if (Init || isa(Init)) {

699 continue;

700 } else if (const auto *ChildILE = dyn_cast(Init)) {

701 if (!EmitDesignatedInitUpdater(Emitter, Const, Offset, ElemType,

702 ChildILE))

703 return false;

704

705 Const.condense(Offset, ElemTy);

706 } else {

707 llvm::Constant *Val = Emitter.tryEmitPrivateForMemory(Init, ElemType);

708 if (Const.add(Val, Offset, true))

709 return false;

710 }

711 }

712

713 return true;

714}

715

716bool ConstStructBuilder::Build(const InitListExpr *ILE, bool AllowOverwrite) {

719

720 unsigned FieldNo = -1;

721 unsigned ElementNo = 0;

722

723

724

725

726 if (auto *CXXRD = dyn_cast(RD))

727 if (CXXRD->getNumBases())

728 return false;

729

731 bool ZeroFieldSize = false;

733

735 ++FieldNo;

736

737

740 continue;

741

742

743 if (Field->isUnnamedBitField())

744 continue;

745

746

747

749 if (ElementNo < ILE->getNumInits())

751 if (isa_and_nonnull(Init)) {

752 if (ZeroInitPadding &&

753 !DoZeroInitPadding(Layout, FieldNo, *Field, AllowOverwrite, SizeSoFar,

754 ZeroFieldSize))

755 return false;

756 continue;

757 }

758

759

760

763 return false;

764 continue;

765 }

766

767 if (ZeroInitPadding &&

768 !DoZeroInitPadding(Layout, FieldNo, *Field, AllowOverwrite, SizeSoFar,

769 ZeroFieldSize))

770 return false;

771

772

773

774

775 if (AllowOverwrite &&

776 (Field->getType()->isArrayType() || Field->getType()->isRecordType())) {

777 if (auto *SubILE = dyn_cast(Init)) {

780 if (!EmitDesignatedInitUpdater(Emitter, Builder, StartOffset + Offset,

781 Field->getType(), SubILE))

782 return false;

783

784

785 Builder.condense(StartOffset + Offset,

787 continue;

788 }

789 }

790

791 llvm::Constant *EltInit =

793 : Emitter.emitNullForMemory(Field->getType());

794 if (!EltInit)

795 return false;

796

797 if (ZeroInitPadding && ZeroFieldSize)

799 CGM.getDataLayout().getTypeAllocSize(EltInit->getType()));

800

801 if (Field->isBitField()) {

802

803 if (!AppendField(Field, Layout.getFieldOffset(FieldNo), EltInit,

804 AllowOverwrite))

805 return false;

806

807

808 if (Field->hasAttr())

809 AllowOverwrite = true;

810 } else {

811

812 if (!AppendBitField(Field, Layout.getFieldOffset(FieldNo), EltInit,

813 AllowOverwrite))

814 return false;

815 }

816 }

817

818 if (ZeroInitPadding && !DoZeroInitPadding(Layout, AllowOverwrite, SizeSoFar))

819 return false;

820

821 return true;

822}

823

824namespace {

825struct BaseInfo {

827 : Decl(Decl), Offset(Offset), Index(Index) {

828 }

829

832 unsigned Index;

833

834 bool operator<(const BaseInfo &O) const { return Offset < O.Offset; }

835};

836}

837

838bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD,

839 bool IsPrimaryBase,

843

844 if (const CXXRecordDecl *CD = dyn_cast(RD)) {

845

847 llvm::Constant *VTableAddressPoint =

849 VTableClass);

851 VTableAddressPoint = Emitter.tryEmitConstantSignedPointer(

852 VTableAddressPoint, *Authentication);

853 if (!VTableAddressPoint)

854 return false;

855 }

856 if (!AppendBytes(Offset, VTableAddressPoint))

857 return false;

858 }

859

860

861

863 Bases.reserve(CD->getNumBases());

864 unsigned BaseNo = 0;

866 BaseEnd = CD->bases_end(); Base != BaseEnd; ++Base, ++BaseNo) {

867 assert(Base->isVirtual() && "should not have virtual bases here");

870 Bases.push_back(BaseInfo(BD, BaseOffset, BaseNo));

871 }

872 llvm::stable_sort(Bases);

873

874 for (unsigned I = 0, N = Bases.size(); I != N; ++I) {

875 BaseInfo &Base = Bases[I];

876

879 VTableClass, Offset + Base.Offset);

880 }

881 }

882

883 unsigned FieldNo = 0;

886 bool ZeroFieldSize = false;

888

889 bool AllowOverwrite = false;

891 FieldEnd = RD->field_end(); Field != FieldEnd; ++Field, ++FieldNo) {

892

894 continue;

895

896

897 if (Field->isUnnamedBitField() ||

899 continue;

900

901

902 const APValue &FieldValue =

904 llvm::Constant *EltInit =

905 Emitter.tryEmitPrivateForMemory(FieldValue, Field->getType());

906 if (!EltInit)

907 return false;

908

909 if (ZeroInitPadding) {

910 if (!DoZeroInitPadding(Layout, FieldNo, **Field, AllowOverwrite,

911 SizeSoFar, ZeroFieldSize))

912 return false;

913 if (ZeroFieldSize)

915 CGM.getDataLayout().getTypeAllocSize(EltInit->getType()));

916 }

917

918 if (Field->isBitField()) {

919

920 if (!AppendField(*Field, Layout.getFieldOffset(FieldNo) + OffsetBits,

921 EltInit, AllowOverwrite))

922 return false;

923

924

925 if (Field->hasAttr())

926 AllowOverwrite = true;

927 } else {

928

929 if (!AppendBitField(*Field, Layout.getFieldOffset(FieldNo) + OffsetBits,

930 EltInit, AllowOverwrite))

931 return false;

932 }

933 }

934 if (ZeroInitPadding && !DoZeroInitPadding(Layout, AllowOverwrite, SizeSoFar))

935 return false;

936

937 return true;

938}

939

940bool ConstStructBuilder::DoZeroInitPadding(

942 bool AllowOverwrite, CharUnits &SizeSoFar, bool &ZeroFieldSize) {

945 if (SizeSoFar < StartOffset)

946 if (!AppendBytes(SizeSoFar, getPadding(CGM, StartOffset - SizeSoFar),

947 AllowOverwrite))

948 return false;

949

950 if (Field.isBitField()) {

952 SizeSoFar = StartOffset + FieldSize;

953 ZeroFieldSize = FieldSize.isZero();

954 } else {

958 uint64_t EndBitOffset = StartBitOffset + Info.Size;

961 SizeSoFar++;

962 }

963 ZeroFieldSize = Info.Size == 0;

964 }

965 return true;

966}

967

968bool ConstStructBuilder::DoZeroInitPadding(const ASTRecordLayout &Layout,

969 bool AllowOverwrite,

972 if (SizeSoFar < TotalSize)

973 if (!AppendBytes(SizeSoFar, getPadding(CGM, TotalSize - SizeSoFar),

974 AllowOverwrite))

975 return false;

976 SizeSoFar = TotalSize;

977 return true;

978}

979

980llvm::Constant *ConstStructBuilder::Finalize(QualType Type) {

981 Type = Type.getNonReferenceType();

985}

986

992

993 if (!Builder.Build(ILE, false))

994 return nullptr;

995

996 return Builder.Finalize(ValTy);

997}

998

1002 ConstantAggregateBuilder Const(Emitter.CGM);

1004

1006 const CXXRecordDecl *CD = dyn_cast(RD);

1007 if (!Builder.Build(Val, RD, false, CD, CharUnits::Zero()))

1008 return nullptr;

1009

1010 return Builder.Finalize(ValTy);

1011}

1012

1014 ConstantAggregateBuilder &Const,

1017 return ConstStructBuilder(Emitter, Const, Offset)

1018 .Build(Updater, true);

1019}

1020

1021

1022

1023

1024

1030 if (llvm::GlobalVariable *Addr =

1032 return ConstantAddress(Addr, Addr->getValueType(), Align);

1033

1036 addressSpace, E->getType());

1037 if (C) {

1038 assert(E->isFileScope() &&

1039 "file-scope compound literal did not have constant initializer!");

1041 }

1042

1043 auto GV = new llvm::GlobalVariable(

1046 llvm::GlobalValue::InternalLinkage, C, ".compoundliteral", nullptr,

1047 llvm::GlobalVariable::NotThreadLocal,

1050 GV->setAlignment(Align.getAsAlign());

1053}

1054

1055static llvm::Constant *

1056EmitArrayConstant(CodeGenModule &CGM, llvm::ArrayType *DesiredType,

1057 llvm::Type *CommonElementType, uint64_t ArrayBound,

1059 llvm::Constant *Filler) {

1060

1061 uint64_t NonzeroLength = ArrayBound;

1062 if (Elements.size() < NonzeroLength && Filler->isNullValue())

1063 NonzeroLength = Elements.size();

1064 if (NonzeroLength == Elements.size()) {

1065 while (NonzeroLength > 0 && Elements[NonzeroLength - 1]->isNullValue())

1066 --NonzeroLength;

1067 }

1068

1069 if (NonzeroLength == 0)

1070 return llvm::ConstantAggregateZero::get(DesiredType);

1071

1072

1073 uint64_t TrailingZeroes = ArrayBound - NonzeroLength;

1074 if (TrailingZeroes >= 8) {

1075 assert(Elements.size() >= NonzeroLength &&

1076 "missing initializer for non-zero element");

1077

1078

1079

1080 if (CommonElementType && NonzeroLength >= 8) {

1081 llvm::Constant *Initial = llvm::ConstantArray::get(

1082 llvm::ArrayType::get(CommonElementType, NonzeroLength),

1083 ArrayRef(Elements).take_front(NonzeroLength));

1084 Elements.resize(2);

1085 Elements[0] = Initial;

1086 } else {

1087 Elements.resize(NonzeroLength + 1);

1088 }

1089

1090 auto *FillerType =

1091 CommonElementType ? CommonElementType : DesiredType->getElementType();

1092 FillerType = llvm::ArrayType::get(FillerType, TrailingZeroes);

1093 Elements.back() = llvm::ConstantAggregateZero::get(FillerType);

1094 CommonElementType = nullptr;

1095 } else if (Elements.size() != ArrayBound) {

1096

1097 Elements.resize(ArrayBound, Filler);

1098 if (Filler->getType() != CommonElementType)

1099 CommonElementType = nullptr;

1100 }

1101

1102

1103 if (CommonElementType)

1104 return llvm::ConstantArray::get(

1105 llvm::ArrayType::get(CommonElementType, ArrayBound), Elements);

1106

1107

1109 Types.reserve(Elements.size());

1110 for (llvm::Constant *Elt : Elements)

1111 Types.push_back(Elt->getType());

1112 llvm::StructType *SType =

1113 llvm::StructType::get(CGM.getLLVMContext(), Types, true);

1114 return llvm::ConstantStruct::get(SType, Elements);

1115}

1116

1117

1118

1119

1120

1121

1122

1123class ConstExprEmitter

1124 : public ConstStmtVisitor<ConstExprEmitter, llvm::Constant *, QualType> {

1127 llvm::LLVMContext &VMContext;

1128public:

1130 : CGM(emitter.CGM), Emitter(emitter), VMContext(CGM.getLLVMContext()) {

1131 }

1132

1133

1134

1135

1136

1137 llvm::Constant *VisitStmt(const Stmt *S, QualType T) { return nullptr; }

1138

1140 if (llvm::Constant *Result = Emitter.tryEmitConstantExpr(CE))

1143 }

1144

1147 }

1148

1149 llvm::Constant *

1153 }

1154

1157 return Visit(GE->getResultExpr(), T);

1158 }

1159

1162 }

1163

1166 return Visit(E->getInitializer(), T);

1167 }

1168

1169 llvm::Constant *ProduceIntToIntCast(const Expr *E, QualType DestType) {

1171

1173 if (llvm::Constant *C = Visit(E, FromType))

1174 if (auto *CI = dyn_castllvm::ConstantInt(C)) {

1177 if (DstWidth == SrcWidth)

1178 return CI;

1180 ? CI->getValue().sextOrTrunc(DstWidth)

1181 : CI->getValue().zextOrTrunc(DstWidth);

1182 return llvm::ConstantInt::get(CGM.getLLVMContext(), A);

1183 }

1184 return nullptr;

1185 }

1186

1187 llvm::Constant *VisitCastExpr(const CastExpr *E, QualType destType) {

1188 if (const auto *ECE = dyn_cast(E))

1190 const Expr *subExpr = E->getSubExpr();

1191

1192 switch (E->getCastKind()) {

1193 case CK_ToUnion: {

1194

1196 "Destination type is not union type!");

1197

1198 auto field = E->getTargetUnionField();

1199

1200 auto C = Emitter.tryEmitPrivateForMemory(subExpr, field->getType());

1201 if (C) return nullptr;

1202

1203 auto destTy = ConvertType(destType);

1204 if (C->getType() == destTy) return C;

1205

1206

1207

1210 Elts.push_back(C);

1211 Types.push_back(C->getType());

1212 unsigned CurSize = CGM.getDataLayout().getTypeAllocSize(C->getType());

1213 unsigned TotalSize = CGM.getDataLayout().getTypeAllocSize(destTy);

1214

1215 assert(CurSize <= TotalSize && "Union size mismatch!");

1216 if (unsigned NumPadBytes = TotalSize - CurSize) {

1217 llvm::Constant *Padding =

1219 Elts.push_back(Padding);

1220 Types.push_back(Padding->getType());

1221 }

1222

1223 llvm::StructType *STy = llvm::StructType::get(VMContext, Types, false);

1224 return llvm::ConstantStruct::get(STy, Elts);

1225 }

1226

1227 case CK_AddressSpaceConversion: {

1228 auto C = Emitter.tryEmitPrivate(subExpr, subExpr->getType());

1229 if (C) return nullptr;

1232 llvm::Type *destTy = ConvertType(E->getType());

1234 destAS, destTy);

1235 }

1236

1237 case CK_LValueToRValue: {

1238

1239

1240

1241

1242 if (const auto *E =

1243 dyn_cast(subExpr->IgnoreParens()))

1244 return Visit(E->getInitializer(), destType);

1245 return nullptr;

1246 }

1247

1248 case CK_AtomicToNonAtomic:

1249 case CK_NonAtomicToAtomic:

1250 case CK_NoOp:

1251 case CK_ConstructorConversion:

1252 return Visit(subExpr, destType);

1253

1254 case CK_ArrayToPointerDecay:

1255 if (const auto *S = dyn_cast(subExpr))

1257 return nullptr;

1258 case CK_NullToPointer:

1259 if (Visit(subExpr, destType))

1261 return nullptr;

1262

1263 case CK_IntToOCLSampler:

1264 llvm_unreachable("global sampler variables are not generated");

1265

1266 case CK_IntegralCast:

1267 return ProduceIntToIntCast(subExpr, destType);

1268

1269 case CK_Dependent: llvm_unreachable("saw dependent cast!");

1270

1271 case CK_BuiltinFnToFnPtr:

1272 llvm_unreachable("builtin functions are handled elsewhere");

1273

1274 case CK_ReinterpretMemberPointer:

1275 case CK_DerivedToBaseMemberPointer:

1276 case CK_BaseToDerivedMemberPointer: {

1277 auto C = Emitter.tryEmitPrivate(subExpr, subExpr->getType());

1278 if (C) return nullptr;

1280 }

1281

1282

1283 case CK_ObjCObjectLValueCast:

1284 case CK_ARCProduceObject:

1285 case CK_ARCConsumeObject:

1286 case CK_ARCReclaimReturnedObject:

1287 case CK_ARCExtendBlockObject:

1288 case CK_CopyAndAutoreleaseBlockObject:

1289 return nullptr;

1290

1291

1292

1293 case CK_BitCast:

1294 case CK_ToVoid:

1295 case CK_Dynamic:

1296 case CK_LValueBitCast:

1297 case CK_LValueToRValueBitCast:

1298 case CK_NullToMemberPointer:

1299 case CK_UserDefinedConversion:

1300 case CK_CPointerToObjCPointerCast:

1301 case CK_BlockPointerToObjCPointerCast:

1302 case CK_AnyPointerToBlockPointerCast:

1303 case CK_FunctionToPointerDecay:

1304 case CK_BaseToDerived:

1305 case CK_DerivedToBase:

1306 case CK_UncheckedDerivedToBase:

1307 case CK_MemberPointerToBoolean:

1308 case CK_VectorSplat:

1309 case CK_FloatingRealToComplex:

1310 case CK_FloatingComplexToReal:

1311 case CK_FloatingComplexToBoolean:

1312 case CK_FloatingComplexCast:

1313 case CK_FloatingComplexToIntegralComplex:

1314 case CK_IntegralRealToComplex:

1315 case CK_IntegralComplexToReal:

1316 case CK_IntegralComplexToBoolean:

1317 case CK_IntegralComplexCast:

1318 case CK_IntegralComplexToFloatingComplex:

1319 case CK_PointerToIntegral:

1320 case CK_PointerToBoolean:

1321 case CK_BooleanToSignedIntegral:

1322 case CK_IntegralToPointer:

1323 case CK_IntegralToBoolean:

1324 case CK_IntegralToFloating:

1325 case CK_FloatingToIntegral:

1326 case CK_FloatingToBoolean:

1327 case CK_FloatingCast:

1328 case CK_FloatingToFixedPoint:

1329 case CK_FixedPointToFloating:

1330 case CK_FixedPointCast:

1331 case CK_FixedPointToBoolean:

1332 case CK_FixedPointToIntegral:

1333 case CK_IntegralToFixedPoint:

1334 case CK_ZeroToOCLOpaqueType:

1335 case CK_MatrixCast:

1336 case CK_HLSLVectorTruncation:

1337 case CK_HLSLArrayRValue:

1338 return nullptr;

1339 }

1340 llvm_unreachable("Invalid CastKind");

1341 }

1342

1343 llvm::Constant *VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *DIE,

1345

1346

1348 }

1349

1351 return Visit(E->getSubExpr(), T);

1352 }

1353

1356 }

1357

1360 if (!Ctx.hasSameType(SrcType, DestType)) {

1362 llvm::APFloat Result =

1364 llvm::RoundingMode RM =

1366 if (RM == llvm::RoundingMode::Dynamic)

1367 RM = llvm::RoundingMode::NearestTiesToEven;

1368 Result.convertFromAPInt(Value, Value.isSigned(), RM);

1370 }

1371 }

1373 }

1374

1377 assert(CAT && "can't emit array init for non-constant-bound array");

1379 const uint64_t NumElements = CAT->getZExtSize();

1380 for (const auto *Init : ILE->inits()) {

1381 if (const auto *Embed =

1382 dyn_cast(Init->IgnoreParenImpCasts())) {

1383 NumInitElements += Embed->getDataElementCount() - 1;

1384 if (NumInitElements > NumElements) {

1385 NumInitElements = NumElements;

1386 break;

1387 }

1388 }

1389 }

1390

1391

1392

1393 uint64_t NumInitableElts = std::min<uint64_t>(NumInitElements, NumElements);

1394

1395 QualType EltType = CAT->getElementType();

1396

1397

1398 llvm::Constant *fillC = nullptr;

1400 fillC = Emitter.tryEmitAbstractForMemory(filler, EltType);

1401 if (!fillC)

1402 return nullptr;

1403 }

1404

1405

1407 if (fillC && fillC->isNullValue())

1408 Elts.reserve(NumInitableElts + 1);

1409 else

1410 Elts.reserve(NumElements);

1411

1412 llvm::Type *CommonElementType = nullptr;

1413 auto Emit = [&](const Expr *Init, unsigned ArrayIndex) {

1414 llvm::Constant *C = nullptr;

1415 C = Emitter.tryEmitPrivateForMemory(Init, EltType);

1416 if (C)

1417 return false;

1418 if (ArrayIndex == 0)

1419 CommonElementType = C->getType();

1420 else if (C->getType() != CommonElementType)

1421 CommonElementType = nullptr;

1422 Elts.push_back(C);

1423 return true;

1424 };

1425

1426 unsigned ArrayIndex = 0;

1427 QualType DestTy = CAT->getElementType();

1428 for (unsigned i = 0; i < ILE->getNumInits(); ++i) {

1430 if (auto *EmbedS = dyn_cast(Init->IgnoreParenImpCasts())) {

1431 StringLiteral *SL = EmbedS->getDataStringLiteral();

1434 llvm::Constant *C;

1435 for (unsigned I = EmbedS->getStartingElementPos(),

1436 N = EmbedS->getDataElementCount();

1437 I != EmbedS->getStartingElementPos() + N; ++I) {

1441 } else {

1442 C = Emitter.tryEmitPrivateForMemory(

1443 withDestType(CGM.getContext(), Init, EmbedS->getType(), DestTy,

1445 EltType);

1446 }

1447 if (C)

1448 return nullptr;

1449 Elts.push_back(C);

1450 ArrayIndex++;

1451 }

1452 if ((ArrayIndex - EmbedS->getDataElementCount()) == 0)

1453 CommonElementType = C->getType();

1454 else if (C->getType() != CommonElementType)

1455 CommonElementType = nullptr;

1456 } else {

1457 if (!Emit(Init, ArrayIndex))

1458 return nullptr;

1459 ArrayIndex++;

1460 }

1461 }

1462

1463 llvm::ArrayType *Desired =

1465 return EmitArrayConstant(CGM, Desired, CommonElementType, NumElements, Elts,

1466 fillC);

1467 }

1468

1469 llvm::Constant *EmitRecordInitialization(const InitListExpr *ILE,

1471 return ConstStructBuilder::BuildStruct(Emitter, ILE, T);

1472 }

1473

1477 }

1478

1482

1484 return EmitArrayInitialization(ILE, T);

1485

1487 return EmitRecordInitialization(ILE, T);

1488

1489 return nullptr;

1490 }

1491

1492 llvm::Constant *

1495 auto C = Visit(E->getBase(), destType);

1496 if (C)

1497 return nullptr;

1498

1499 ConstantAggregateBuilder Const(CGM);

1501

1503 E->getUpdater()))

1504 return nullptr;

1505

1507 bool HasFlexibleArray = false;

1509 HasFlexibleArray = RT->getDecl()->hasFlexibleArrayMember();

1510 return Const.build(ValTy, HasFlexibleArray);

1511 }

1512

1513 llvm::Constant *VisitCXXConstructExpr(const CXXConstructExpr *E,

1515 if (E->getConstructor()->isTrivial())

1516 return nullptr;

1517

1518

1519 if (E->getNumArgs()) {

1520 assert(E->getNumArgs() == 1 && "trivial ctor with > 1 argument");

1521 assert(E->getConstructor()->isCopyOrMoveConstructor() &&

1522 "trivial ctor has argument but isn't a copy/move ctor");

1523

1524 const Expr *Arg = E->getArg(0);

1526 "argument to copy ctor is of wrong type");

1527

1528

1529

1530 if (const auto *MTE = dyn_cast(Arg))

1531 return Visit(MTE->getSubExpr(), Ty);

1532

1533 return nullptr;

1534 }

1535

1537 }

1538

1540

1542 }

1543

1545

1546

1547

1548 std::string Str;

1551 assert(CAT && "String data not of constant array type!");

1552

1553

1554

1556 return llvm::ConstantDataArray::getString(VMContext, Str, false);

1557 }

1558

1560 return Visit(E->getSubExpr(), T);

1561 }

1562

1564 if (llvm::Constant *C = Visit(U->getSubExpr(), T))

1565 if (auto *CI = dyn_castllvm::ConstantInt(C))

1566 return llvm::ConstantInt::get(CGM.getLLVMContext(), -CI->getValue());

1567 return nullptr;

1568 }

1569

1571 return Visit(E->getSelectedExpr(), T);

1572 }

1573

1574

1575 llvm::Type *ConvertType(QualType T) {

1577 }

1578};

1579

1580}

1581

1582llvm::Constant *ConstantEmitter::validateAndPopAbstract(llvm::Constant *C,

1583 AbstractState saved) {

1584 Abstract = saved.OldValue;

1585

1586 assert(saved.OldPlaceholdersSize == PlaceholderAddresses.size() &&

1587 "created a placeholder while doing an abstract emission?");

1588

1589

1590

1591 return C;

1592}

1593

1594llvm::Constant *

1596 auto state = pushAbstract();

1598 return validateAndPopAbstract(C, state);

1599}

1600

1601llvm::Constant *

1603 auto state = pushAbstract();

1605 return validateAndPopAbstract(C, state);

1606}

1607

1608llvm::Constant *

1610 auto state = pushAbstract();

1612 return validateAndPopAbstract(C, state);

1613}

1614

1617 return nullptr;

1618

1622

1624}

1625

1626llvm::Constant *

1628 auto state = pushAbstract();

1630 C = validateAndPopAbstract(C, state);

1631 if (C) {

1633 "internal error: could not emit constant value \"abstractly\"");

1635 }

1636 return C;

1637}

1638

1639llvm::Constant *

1642 bool EnablePtrAuthFunctionTypeDiscrimination) {

1643 auto state = pushAbstract();

1644 auto C =

1645 tryEmitPrivate(value, destType, EnablePtrAuthFunctionTypeDiscrimination);

1646 C = validateAndPopAbstract(C, state);

1647 if (C) {

1649 "internal error: could not emit constant value \"abstractly\"");

1651 }

1652 return C;

1653}

1654

1656 initializeNonAbstract(D.getType().getAddressSpace());

1658}

1659

1661 LangAS destAddrSpace,

1663 initializeNonAbstract(destAddrSpace);

1665}

1666

1668 LangAS destAddrSpace,

1670 initializeNonAbstract(destAddrSpace);

1672 assert(C && "couldn't emit constant value non-abstractly?");

1673 return C;

1674}

1675

1677 assert(!Abstract && "cannot get current address for abstract constant");

1678

1679

1680

1681

1682

1684 llvm::GlobalValue::PrivateLinkage,

1685 nullptr,

1686 "",

1687 nullptr,

1688 llvm::GlobalVariable::NotThreadLocal,

1690

1691 PlaceholderAddresses.push_back(std::make_pair(nullptr, global));

1692

1693 return global;

1694}

1695

1697 llvm::GlobalValue *placeholder) {

1698 assert(!PlaceholderAddresses.empty());

1699 assert(PlaceholderAddresses.back().first == nullptr);

1700 assert(PlaceholderAddresses.back().second == placeholder);

1701 PlaceholderAddresses.back().first = signal;

1702}

1703

1704namespace {

1705 struct ReplacePlaceholders {

1707

1708

1709 llvm::Constant *Base;

1710 llvm::Type *BaseValueTy = nullptr;

1711

1712

1713 llvm::DenseMap<llvm::Constant*, llvm::GlobalVariable*> PlaceholderAddresses;

1714

1715

1716 llvm::DenseMap<llvm::GlobalVariable*, llvm::Constant*> Locations;

1717

1718

1719

1720

1723

1724 ReplacePlaceholders(CodeGenModule &CGM, llvm::Constant *base,

1725 ArrayRef<std::pair<llvm::Constant*,

1726 llvm::GlobalVariable*>> addresses)

1727 : CGM(CGM), Base(base),

1728 PlaceholderAddresses(addresses.begin(), addresses.end()) {

1729 }

1730

1731 void replaceInInitializer(llvm::Constant *init) {

1732

1733 BaseValueTy = init->getType();

1734

1735

1736 Indices.push_back(0);

1737 IndexValues.push_back(nullptr);

1738

1739

1740 findLocations(init);

1741

1742

1743 assert(IndexValues.size() == Indices.size() && "mismatch");

1744 assert(Indices.size() == 1 && "didn't pop all indices");

1745

1746

1747 assert(Locations.size() == PlaceholderAddresses.size() &&

1748 "missed a placeholder?");

1749

1750

1751

1752

1753

1754 for (auto &entry : Locations) {

1755 assert(entry.first->getName() == "" && "not a placeholder!");

1756 entry.first->replaceAllUsesWith(entry.second);

1757 entry.first->eraseFromParent();

1758 }

1759 }

1760

1761 private:

1762 void findLocations(llvm::Constant *init) {

1763

1764 if (auto agg = dyn_castllvm::ConstantAggregate(init)) {

1765 for (unsigned i = 0, e = agg->getNumOperands(); i != e; ++i) {

1766 Indices.push_back(i);

1767 IndexValues.push_back(nullptr);

1768

1769 findLocations(agg->getOperand(i));

1770

1771 IndexValues.pop_back();

1772 Indices.pop_back();

1773 }

1774 return;

1775 }

1776

1777

1778 while (true) {

1779 auto it = PlaceholderAddresses.find(init);

1780 if (it != PlaceholderAddresses.end()) {

1781 setLocation(it->second);

1782 break;

1783 }

1784

1785

1786 if (auto expr = dyn_castllvm::ConstantExpr(init)) {

1787 init = expr->getOperand(0);

1788 } else {

1789 break;

1790 }

1791 }

1792 }

1793

1794 void setLocation(llvm::GlobalVariable *placeholder) {

1795 assert(!Locations.contains(placeholder) &&

1796 "already found location for placeholder!");

1797

1798

1799

1800

1801 assert(Indices.size() == IndexValues.size());

1802 for (size_t i = Indices.size() - 1; i != size_t(-1); --i) {

1803 if (IndexValues[i]) {

1804#ifndef NDEBUG

1805 for (size_t j = 0; j != i + 1; ++j) {

1806 assert(IndexValues[j] &&

1807 isallvm::ConstantInt(IndexValues[j]) &&

1808 castllvm::ConstantInt(IndexValues[j])->getZExtValue()

1809 == Indices[j]);

1810 }

1811#endif

1812 break;

1813 }

1814

1815 IndexValues[i] = llvm::ConstantInt::get(CGM.Int32Ty, Indices[i]);

1816 }

1817

1818 llvm::Constant *location = llvm::ConstantExpr::getInBoundsGetElementPtr(

1819 BaseValueTy, Base, IndexValues);

1820

1821 Locations.insert({placeholder, location});

1822 }

1823 };

1824}

1825

1827 assert(InitializedNonAbstract &&

1828 "finalizing emitter that was used for abstract emission?");

1829 assert(!Finalized && "finalizing emitter multiple times");

1830 assert(global->getInitializer());

1831

1832

1833 Finalized = true;

1834

1835 if (!PlaceholderAddresses.empty()) {

1836 ReplacePlaceholders(CGM, global, PlaceholderAddresses)

1837 .replaceInInitializer(global->getInitializer());

1838 PlaceholderAddresses.clear();

1839 }

1840}

1841

1843 assert((!InitializedNonAbstract || Finalized || Failed) &&

1844 "not finalized after being initialized for non-abstract emission");

1845 assert(PlaceholderAddresses.empty() && "unhandled placeholders");

1846}

1847

1851 type.getQualifiers());

1852 }

1853 return type;

1854}

1855

1857

1858

1859

1860 if (D.hasLocalStorage()) {

1864 dyn_cast_or_null(D.getInit())) {

1868 }

1869 }

1870 InConstantContext = D.hasConstantInitialization();

1871

1872 QualType destType = D.getType();

1873 const Expr *E = D.getInit();

1874 assert(E && "No initializer to emit");

1875

1878 if (llvm::Constant *C = ConstExprEmitter(*this).Visit(E, nonMemoryDestType))

1880 }

1881

1882

1883

1884 if (APValue *value = D.evaluateValue())

1886

1887 return nullptr;

1888}

1889

1890llvm::Constant *

1895}

1896

1897llvm::Constant *

1903}

1904

1910}

1911

1917}

1918

1919

1920

1921

1922

1923

1924llvm::Constant *

1927 assert(Schema && "applying trivial ptrauth schema");

1928

1930 return UnsignedPointer;

1931

1932 unsigned Key = Schema.getKey();

1933

1934

1935 llvm::GlobalValue *StorageAddress = nullptr;

1937

1939 return nullptr;

1940

1942 }

1943

1944 llvm::ConstantInt *Discriminator =

1946

1948 UnsignedPointer, Key, StorageAddress, Discriminator);

1949

1952

1953 return SignedPointer;

1954}

1955

1957 llvm::Constant *C,

1959

1961 QualType destValueType = AT->getValueType();

1963

1966 if (innerSize == outerSize)

1967 return C;

1968

1969 assert(innerSize < outerSize && "emitted over-large constant for atomic");

1970 llvm::Constant *elts[] = {

1971 C,

1972 llvm::ConstantAggregateZero::get(

1973 llvm::ArrayType::get(CGM.Int8Ty, (outerSize - innerSize) / 8))

1974 };

1975 return llvm::ConstantStruct::getAnon(elts);

1976 }

1977

1978

1979 if (C->getType()->isIntegerTy(1) && !destType->isBitIntType()) {

1981 llvm::Constant *Res = llvm::ConstantFoldCastOperand(

1983 assert(Res && "Constant folding must succeed");

1984 return Res;

1985 }

1986

1988 ConstantAggregateBuilder Builder(CGM);

1990

1991

1992 auto *CI = castllvm::ConstantInt(C);

1993 llvm::Constant *Res = llvm::ConstantFoldCastOperand(

1995 : llvm::Instruction::ZExt,

1998

1999

2001 llvm::APInt Value = castllvm::ConstantInt(Res)->getValue();

2002 Builder.addBits(Value, 0, false);

2003 return Builder.build(DesiredTy, false);

2004 }

2005 return Res;

2006 }

2007

2008 return C;

2009}

2010

2013 assert(!destType->isVoidType() && "can't emit a void constant");

2014

2016 if (llvm::Constant *C = ConstExprEmitter(*this).Visit(E, destType))

2017 return C;

2018

2020

2022

2025 else

2027

2030

2031 return nullptr;

2032}

2033

2036}

2037

2038namespace {

2039

2040

2041struct ConstantLValue {

2042 llvm::Constant *Value;

2043 bool HasOffsetApplied;

2044

2045 ConstantLValue(llvm::Constant *value,

2046 bool hasOffsetApplied = false)

2047 : Value(value), HasOffsetApplied(hasOffsetApplied) {}

2048

2050 : ConstantLValue(address.getPointer()) {}

2051};

2052

2053

2054class ConstantLValueEmitter : public ConstStmtVisitor<ConstantLValueEmitter,

2055 ConstantLValue> {

2060 bool EnablePtrAuthFunctionTypeDiscrimination;

2061

2062

2064

2065public:

2068 bool EnablePtrAuthFunctionTypeDiscrimination = true)

2069 : CGM(emitter.CGM), Emitter(emitter), Value(value), DestType(destType),

2070 EnablePtrAuthFunctionTypeDiscrimination(

2071 EnablePtrAuthFunctionTypeDiscrimination) {}

2072

2073 llvm::Constant *tryEmit();

2074

2075private:

2076 llvm::Constant *tryEmitAbsolute(llvm::Type *destTy);

2078

2079 ConstantLValue VisitStmt(const Stmt *S) { return nullptr; }

2080 ConstantLValue VisitConstantExpr(const ConstantExpr *E);

2082 ConstantLValue VisitStringLiteral(const StringLiteral *E);

2083 ConstantLValue VisitObjCBoxedExpr(const ObjCBoxedExpr *E);

2084 ConstantLValue VisitObjCEncodeExpr(const ObjCEncodeExpr *E);

2086 ConstantLValue VisitPredefinedExpr(const PredefinedExpr *E);

2087 ConstantLValue VisitAddrLabelExpr(const AddrLabelExpr *E);

2088 ConstantLValue VisitCallExpr(const CallExpr *E);

2089 ConstantLValue VisitBlockExpr(const BlockExpr *E);

2090 ConstantLValue VisitCXXTypeidExpr(const CXXTypeidExpr *E);

2091 ConstantLValue VisitMaterializeTemporaryExpr(

2093

2094 ConstantLValue emitPointerAuthSignConstant(const CallExpr *E);

2095 llvm::Constant *emitPointerAuthPointer(const Expr *E);

2096 unsigned emitPointerAuthKey(const Expr *E);

2097 std::pair<llvm::Constant *, llvm::ConstantInt *>

2098 emitPointerAuthDiscriminator(const Expr *E);

2099

2100 bool hasNonZeroOffset() const {

2101 return Value.getLValueOffset().isZero();

2102 }

2103

2104

2105 llvm::Constant *getOffset() {

2106 return llvm::ConstantInt::get(CGM.Int64Ty,

2107 Value.getLValueOffset().getQuantity());

2108 }

2109

2110

2111 llvm::Constant *applyOffset(llvm::Constant *C) {

2112 if (!hasNonZeroOffset())

2113 return C;

2114

2115 return llvm::ConstantExpr::getGetElementPtr(CGM.Int8Ty, C, getOffset());

2116 }

2117};

2118

2119}

2120

2121llvm::Constant *ConstantLValueEmitter::tryEmit() {

2123

2124

2125

2126

2127

2128

2129

2130

2132 assert(isallvm::IntegerType(destTy) || isallvm::PointerType(destTy));

2133

2134

2135

2136 if (!base) {

2137 return tryEmitAbsolute(destTy);

2138 }

2139

2140

2141 ConstantLValue result = tryEmitBase(base);

2142

2143

2144 llvm::Constant *value = result.Value;

2145 if (!value) return nullptr;

2146

2147

2148 if (!result.HasOffsetApplied) {

2149 value = applyOffset(value);

2150 }

2151

2152

2153

2154 if (isallvm::PointerType(destTy))

2155 return llvm::ConstantExpr::getPointerCast(value, destTy);

2156

2157 return llvm::ConstantExpr::getPtrToInt(value, destTy);

2158}

2159

2160

2161

2162llvm::Constant *

2163ConstantLValueEmitter::tryEmitAbsolute(llvm::Type *destTy) {

2164

2165 auto destPtrTy = castllvm::PointerType(destTy);

2166 if (Value.isNullPointer()) {

2167

2169 }

2170

2171

2172

2173

2174 auto intptrTy = CGM.getDataLayout().getIntPtrType(destPtrTy);

2175 llvm::Constant *C;

2176 C = llvm::ConstantFoldIntegerCast(getOffset(), intptrTy, false,

2178 assert(C && "Must have folded, as Offset is a ConstantInt");

2179 C = llvm::ConstantExpr::getIntToPtr(C, destPtrTy);

2180 return C;

2181}

2182

2183ConstantLValue

2185

2187

2188

2190

2191 if (D->hasAttr())

2193

2194 auto PtrAuthSign = [&](llvm::Constant *C) {

2196

2197 if (EnablePtrAuthFunctionTypeDiscrimination)

2199

2200 if (AuthInfo) {

2201 if (hasNonZeroOffset())

2202 return ConstantLValue(nullptr);

2203

2204 C = applyOffset(C);

2206 C, AuthInfo.getKey(), nullptr,

2207 cast_or_nullllvm::ConstantInt(AuthInfo.getDiscriminator()));

2208 return ConstantLValue(C, true);

2209 }

2210

2211 return ConstantLValue(C);

2212 };

2213

2214 if (const auto *FD = dyn_cast(D))

2216

2217 if (const auto *VD = dyn_cast(D)) {

2218

2219 if (!VD->hasLocalStorage()) {

2220 if (VD->isFileVarDecl() || VD->hasExternalStorage())

2222

2223 if (VD->isLocalVarDecl()) {

2226 }

2227 }

2228 }

2229

2230 if (const auto *GD = dyn_cast(D))

2232

2233 if (const auto *GCD = dyn_cast(D))

2235

2236 if (const auto *TPO = dyn_cast(D))

2238

2239 return nullptr;

2240 }

2241

2242

2245

2246

2247 return Visit(base.get<const Expr*>());

2248}

2249

2250ConstantLValue

2251ConstantLValueEmitter::VisitConstantExpr(const ConstantExpr *E) {

2252 if (llvm::Constant *Result = Emitter.tryEmitConstantExpr(E))

2254 return Visit(E->getSubExpr());

2255}

2256

2257ConstantLValue

2258ConstantLValueEmitter::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {

2260 CompoundLiteralEmitter.setInConstantContext(Emitter.isInConstantContext());

2261 return tryEmitGlobalCompoundLiteral(CompoundLiteralEmitter, E);

2262}

2263

2264ConstantLValue

2265ConstantLValueEmitter::VisitStringLiteral(const StringLiteral *E) {

2267}

2268

2269ConstantLValue

2270ConstantLValueEmitter::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {

2272}

2273

2279}

2280

2281ConstantLValue

2282ConstantLValueEmitter::VisitObjCStringLiteral(const ObjCStringLiteral *E) {

2284}

2285

2286ConstantLValue

2287ConstantLValueEmitter::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) {

2288 assert(E->isExpressibleAsConstantInitializer() &&

2289 "this boxed expression can't be emitted as a compile-time constant");

2290 const auto *SL = cast(E->getSubExpr()->IgnoreParenCasts());

2292}

2293

2294ConstantLValue

2295ConstantLValueEmitter::VisitPredefinedExpr(const PredefinedExpr *E) {

2297}

2298

2299ConstantLValue

2300ConstantLValueEmitter::VisitAddrLabelExpr(const AddrLabelExpr *E) {

2301 assert(Emitter.CGF && "Invalid address of label expression outside function");

2302 llvm::Constant *Ptr = Emitter.CGF->GetAddrOfLabel(E->getLabel());

2303 return Ptr;

2304}

2305

2306ConstantLValue

2307ConstantLValueEmitter::VisitCallExpr(const CallExpr *E) {

2308 unsigned builtin = E->getBuiltinCallee();

2309 if (builtin == Builtin::BI__builtin_function_start)

2312

2313 if (builtin == Builtin::BI__builtin_ptrauth_sign_constant)

2314 return emitPointerAuthSignConstant(E);

2315

2316 if (builtin != Builtin::BI__builtin___CFStringMakeConstantString &&

2317 builtin != Builtin::BI__builtin___NSStringMakeConstantString)

2318 return nullptr;

2319

2321 if (builtin == Builtin::BI__builtin___NSStringMakeConstantString) {

2323 } else {

2324

2326 }

2327}

2328

2329ConstantLValue

2330ConstantLValueEmitter::emitPointerAuthSignConstant(const CallExpr *E) {

2331 llvm::Constant *UnsignedPointer = emitPointerAuthPointer(E->getArg(0));

2332 unsigned Key = emitPointerAuthKey(E->getArg(1));

2333 auto [StorageAddress, OtherDiscriminator] =

2334 emitPointerAuthDiscriminator(E->getArg(2));

2335

2337 UnsignedPointer, Key, StorageAddress, OtherDiscriminator);

2338 return SignedPointer;

2339}

2340

2341llvm::Constant *ConstantLValueEmitter::emitPointerAuthPointer(const Expr *E) {

2344 assert(Succeeded);

2345 (void)Succeeded;

2346

2347

2348 assert(Result.Val.isLValue());

2349 if (isa(Result.Val.getLValueBase().get<const ValueDecl *>()))

2350 assert(Result.Val.getLValueOffset().isZero());

2353}

2354

2355unsigned ConstantLValueEmitter::emitPointerAuthKey(const Expr *E) {

2357}

2358

2359std::pair<llvm::Constant *, llvm::ConstantInt *>

2360ConstantLValueEmitter::emitPointerAuthDiscriminator(const Expr *E) {

2362

2363 if (const auto *Call = dyn_cast(E)) {

2364 if (Call->getBuiltinCallee() ==

2365 Builtin::BI__builtin_ptrauth_blend_discriminator) {

2367 Call->getArg(0), Call->getArg(0)->getType());

2368 auto *Extra = castllvm::ConstantInt(ConstantEmitter(CGM).emitAbstract(

2369 Call->getArg(1), Call->getArg(1)->getType()));

2370 return {Pointer, Extra};

2371 }

2372 }

2373

2375 if (Result->getType()->isPointerTy())

2376 return {Result, nullptr};

2377 return {nullptr, castllvm::ConstantInt(Result)};

2378}

2379

2380ConstantLValue

2381ConstantLValueEmitter::VisitBlockExpr(const BlockExpr *E) {

2382 StringRef functionName;

2383 if (auto CGF = Emitter.CGF)

2384 functionName = CGF->CurFn->getName();

2385 else

2386 functionName = "global";

2387

2389}

2390

2391ConstantLValue

2392ConstantLValueEmitter::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {

2394 if (E->isTypeOperand())

2396 else

2397 T = E->getExprOperand()->getType();

2399}

2400

2401ConstantLValue

2402ConstantLValueEmitter::VisitMaterializeTemporaryExpr(

2404 assert(E->getStorageDuration() == SD_Static);

2407}

2408

2409llvm::Constant *

2411 bool EnablePtrAuthFunctionTypeDiscrimination) {

2415

2418 return ConstantLValueEmitter(*this, Value, DestType,

2419 EnablePtrAuthFunctionTypeDiscrimination)

2420 .tryEmit();

2425 Value.getFixedPoint().getValue());

2427 llvm::Constant *Complex[2];

2428

2430 Value.getComplexIntReal());

2432 Value.getComplexIntImag());

2433

2434

2435 llvm::StructType *STy =

2436 llvm::StructType::get(Complex[0]->getType(), Complex[1]->getType());

2437 return llvm::ConstantStruct::get(STy, Complex);

2438 }

2440 const llvm::APFloat &Init = Value.getFloat();

2441 if (&Init.getSemantics() == &llvm::APFloat::IEEEhalf() &&

2445 Init.bitcastToAPInt());

2446 else

2448 }

2450 llvm::Constant *Complex[2];

2451

2453 Value.getComplexFloatReal());

2455 Value.getComplexFloatImag());

2456

2457

2458 llvm::StructType *STy =

2459 llvm::StructType::get(Complex[0]->getType(), Complex[1]->getType());

2460 return llvm::ConstantStruct::get(STy, Complex);

2461 }

2463 unsigned NumElts = Value.getVectorLength();

2465

2466 for (unsigned I = 0; I != NumElts; ++I) {

2468 if (Elt.isInt())

2475 else

2476 llvm_unreachable("unsupported vector element type");

2477 }

2478 return llvm::ConstantVector::get(Inits);

2479 }

2485 if (!LHS || !RHS) return nullptr;

2486

2487

2489 LHS = llvm::ConstantExpr::getPtrToInt(LHS, CGM.IntPtrTy);

2490 RHS = llvm::ConstantExpr::getPtrToInt(RHS, CGM.IntPtrTy);

2491 llvm::Constant *AddrLabelDiff = llvm::ConstantExpr::getSub(LHS, RHS);

2492

2493

2494

2495

2496 return llvm::ConstantExpr::getTruncOrBitCast(AddrLabelDiff, ResultType);

2497 }

2500 return ConstStructBuilder::BuildStruct(*this, Value, DestType);

2503 unsigned NumElements = Value.getArraySize();

2504 unsigned NumInitElts = Value.getArrayInitializedElts();

2505

2506

2507 llvm::Constant *Filler = nullptr;

2508 if (Value.hasArrayFiller()) {

2511 if (!Filler)

2512 return nullptr;

2513 }

2514

2515

2517 if (Filler && Filler->isNullValue())

2518 Elts.reserve(NumInitElts + 1);

2519 else

2520 Elts.reserve(NumElements);

2521

2522 llvm::Type *CommonElementType = nullptr;

2523 for (unsigned I = 0; I < NumInitElts; ++I) {

2526 if (C) return nullptr;

2527

2528 if (I == 0)

2529 CommonElementType = C->getType();

2530 else if (C->getType() != CommonElementType)

2531 CommonElementType = nullptr;

2532 Elts.push_back(C);

2533 }

2534

2535 llvm::ArrayType *Desired =

2537

2538

2540 Desired = llvm::ArrayType::get(Desired->getElementType(), Elts.size());

2541

2542 return EmitArrayConstant(CGM, Desired, CommonElementType, NumElements, Elts,

2543 Filler);

2544 }

2547 }

2548 llvm_unreachable("Unknown APValue kind");

2549}

2550

2553 return EmittedCompoundLiterals.lookup(E);

2554}

2555

2558 bool Ok = EmittedCompoundLiterals.insert(std::make_pair(CLE, GV)).second;

2559 (void)Ok;

2560 assert(Ok && "CLE has already been emitted!");

2561}

2562

2565 assert(E->isFileScope() && "not a file-scope compound literal expr");

2567 return tryEmitGlobalCompoundLiteral(emitter, E);

2568}

2569

2570llvm::Constant *

2572

2575

2576

2577 if (const CXXMethodDecl *method = dyn_cast(decl))

2579

2580

2584}

2585

2587 llvm::Type *baseType,

2589

2592 bool asCompleteObject) {

2594 llvm::StructType *structure =

2595 (asCompleteObject ? layout.getLLVMType()

2597

2598 unsigned numElements = structure->getNumElements();

2599 std::vector<llvm::Constant *> elements(numElements);

2600

2601 auto CXXR = dyn_cast(record);

2602

2603 if (CXXR) {

2604 for (const auto &I : CXXR->bases()) {

2605 if (I.isVirtual()) {

2606

2607

2608 continue;

2609 }

2610

2612 cast(I.getType()->castAs<RecordType>()->getDecl());

2613

2614

2620 continue;

2621

2623 llvm::Type *baseType = structure->getElementType(fieldIndex);

2625 }

2626 }

2627

2628

2629 for (const auto *Field : record->fields()) {

2630

2631

2632 if (!Field->isBitField() &&

2635 elements[fieldIndex] = CGM.EmitNullConstant(Field->getType());

2636 }

2637

2638

2639 if (record->isUnion()) {

2640 if (Field->getIdentifier())

2641 break;

2642 if (const auto *FieldRD = Field->getType()->getAsRecordDecl())

2643 if (FieldRD->findFirstNamedDataMember())

2644 break;

2645 }

2646 }

2647

2648

2649 if (CXXR && asCompleteObject) {

2650 for (const auto &I : CXXR->vbases()) {

2652 cast(I.getType()->castAs<RecordType>()->getDecl());

2653

2654

2656 continue;

2657

2659

2660

2661 if (elements[fieldIndex]) continue;

2662

2663 llvm::Type *baseType = structure->getElementType(fieldIndex);

2665 }

2666 }

2667

2668

2669 for (unsigned i = 0; i != numElements; ++i) {

2670 if (!elements[i])

2671 elements[i] = llvm::Constant::getNullValue(structure->getElementType(i));

2672 }

2673

2674 return llvm::ConstantStruct::get(structure, elements);

2675}

2676

2677

2679 llvm::Type *baseType,

2682

2683

2685 return llvm::Constant::getNullValue(baseType);

2686

2687

2688 return EmitNullConstant(CGM, base, false);

2689}

2690

2694}

2695

2699 castllvm::PointerType(getTypes().ConvertTypeForMem(T)), T);

2700

2701 if (getTypes().isZeroInitializable(T))

2702 return llvm::Constant::getNullValue(getTypes().ConvertTypeForMem(T));

2703

2705 llvm::ArrayType *ATy =

2706 castllvm::ArrayType(getTypes().ConvertTypeForMem(T));

2707

2709

2710 llvm::Constant *Element =

2712 unsigned NumElements = CAT->getZExtSize();

2714 return llvm::ConstantArray::get(ATy, Array);

2715 }

2716

2718 return ::EmitNullConstant(*this, RT->getDecl(), true);

2719

2721 "Should only see pointers to data members here!");

2722

2724}

2725

2726llvm::Constant *

2728 return ::EmitNullConstant(*this, Record, false);

2729}

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.

CharUnits getTypeSizeInChars(QualType T) const

Return the size of the specified (complete) type T, in characters.

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 ...

CharUnits getSize() const

getSize - Get the record size in characters.

uint64_t getFieldOffset(unsigned FieldNo) const

getFieldOffset - Get the offset of the given field index, in bits.

CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const

getBaseClassOffset - Get the offset, in chars, for the given base class.

const CXXRecordDecl * getPrimaryBase() const

getPrimaryBase - Get the primary base for this record.

CharUnits getNonVirtualSize() const

getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...

AddrLabelExpr - The GNU address of label extension, representing &&label.

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()

bool shouldZeroInitPadding() const

CGObjCRuntime & getObjCRuntime()

Return a reference to the configured Objective-C runtime.

ConstantAddress GetAddrOfGlobalTemporary(const MaterializeTemporaryExpr *E, const Expr *Inner)

Returns a pointer to a global variable representing a temporary with static or thread storage duratio...

llvm::Constant * EmitNullConstant(QualType T)

Return the result of value-initializing the given type, i.e.

llvm::Constant * getConstantSignedPointer(llvm::Constant *Pointer, const PointerAuthSchema &Schema, llvm::Constant *StorageAddress, GlobalDecl SchemaDecl, QualType SchemaType)

Sign a constant pointer using the given scheme, producing a constant with the same IR type.

ConstantAddress GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *)

Return a pointer to a constant array for the given ObjCEncodeExpr node.

llvm::Type * ConvertType(QualType T)

ConvertType - Convert type T into a llvm::Type.

llvm::Type * convertTypeForLoadStore(QualType T, llvm::Type *LLVMTy=nullptr)

Given that T is a scalar type, return the IR type that should be used for load and store operations.

const CGRecordLayout & getCGRecordLayout(const RecordDecl *)

getCGRecordLayout - Return record layout info for the given record decl.

llvm::Type * ConvertTypeForMem(QualType T)

ConvertTypeForMem - Convert type T into a llvm::Type.

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.

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'.

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.