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

1

2

3

4

5

6

7

8

9

10

11

12

21#include "llvm/ADT/StringExtras.h"

22#include "llvm/IR/Intrinsics.h"

23#include "llvm/IR/MDBuilder.h"

24#include "llvm/Support/Path.h"

25

26using namespace clang;

27using namespace CodeGen;

28

31 assert(

32 (D.hasGlobalStorage() ||

34 "VarDecl must have global or local (in the case of OpenCL) storage!");

35 assert(D.getType()->isReferenceType() &&

36 "Should not call EmitDeclInit on a reference!");

37

40

47 DeclPtr, D.getTLSKind());

50 DeclPtr);

51 else

53 return;

54 }

57 return;

64 return;

65 }

66 llvm_unreachable("bad evaluation kind");

67}

68

69

70

73

74

75

76

77

78

80

81

82

83 switch (DtorKind) {

85 return;

86

88 break;

89

93

94 assert(D.getTLSKind() && "should have rejected this");

95 return;

96 }

97

98 llvm::FunctionCallee Func;

99 llvm::Constant *Argument;

100

103

104

105

106

107

109 bool CanRegisterDestructor =

113

114

115

116 bool UsingExternalHelper = !CGM.getCodeGenOpts().CXAAtExit;

117 if (Record && (CanRegisterDestructor || UsingExternalHelper)) {

118 assert(Record->hasTrivialDestructor());

120

123 auto DestAS =

125 auto DestTy = llvm::PointerType::get(

127 auto SrcAS = D.getType().getQualifiers().getAddressSpace();

128 if (DestAS == SrcAS)

130 else

131

132

133 Argument = llvm::ConstantPointerNull::get(DestTy);

134 } else {

136 }

137

138 } else {

143 Argument = llvm::Constant::getNullValue(CGF.Int8PtrTy);

144 }

145

147}

148

149

150

152 llvm::Constant *Addr) {

155}

156

157void CodeGenFunction::EmitInvariantStart(llvm::Constant *Addr, CharUnits Size) {

158

160 return;

161

162

163 llvm::Intrinsic::ID InvStartID = llvm::Intrinsic::invariant_start;

164

165 assert(Addr->getType()->isPointerTy() && "Address must be a pointer");

166 llvm::Type *ObjectPtr[1] = {Addr->getType()};

167 llvm::Function *InvariantStart = CGM.getIntrinsic(InvStartID, ObjectPtr);

168

169

171 llvm::Value *Args[2] = {llvm::ConstantInt::getSigned(Int64Ty, Width), Addr};

172 Builder.CreateCall(InvariantStart, Args);

173}

174

176 llvm::GlobalVariable *GV,

177 bool PerformInit) {

178

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

198 unsigned ActualAddrSpace = GV->getAddressSpace();

199 llvm::Constant *DeclPtr = GV;

200 if (ActualAddrSpace != ExpectedAddrSpace) {

201 llvm::PointerType *PTy =

202 llvm::PointerType::get(getLLVMContext(), ExpectedAddrSpace);

203 DeclPtr = llvm::ConstantExpr::getAddrSpaceCast(DeclPtr, PTy);

204 }

205

207 DeclPtr, GV->getValueType(), getContext().getDeclAlign(&D));

208

211 D.hasAttr()) {

213 &D, DeclAddr, D.getAttr()->getLocation(),

214 PerformInit, this);

215 }

216 bool NeedsDtor =

218 if (PerformInit)

220 if (D.getType().isConstantStorage(getContext(), true, !NeedsDtor))

222 else

224 return;

225 }

226

227 assert(PerformInit && "cannot have constant initializer which needs "

228 "destruction for reference");

231}

232

233

234

236 llvm::FunctionCallee dtor,

237 llvm::Constant *addr) {

238

239 llvm::FunctionType *ty = llvm::FunctionType::get(CGM.VoidTy, false);

241 {

242 llvm::raw_svector_ostream Out(FnName);

244 }

245

249

251

255

257

258 llvm::CallInst *call = CGF.Builder.CreateCall(dtor, addr);

259

260

261 if (auto *dtorFn = dyn_castllvm::Function(

262 dtor.getCallee()->stripPointerCastsAndAliases()))

263 call->setCallingConv(dtorFn->getCallingConv());

264

265 CGF.FinishFunction();

266

267

269 false, false));

273}

274

275

276

278 const VarDecl &D, llvm::FunctionCallee Dtor, llvm::Constant *Addr,

279 llvm::FunctionCallee &AtExit) {

281 {

282 llvm::raw_svector_ostream Out(FnName);

284 }

285

289

290

291 llvm::FunctionType *StubTy =

292 llvm::FunctionType::get(CGM.IntTy, {CGM.IntTy}, true);

293

296

298

302 Args.push_back(&IPD);

304

306 FI, Args, D.getLocation(), D.getInit()->getExprLoc());

307

308

310

311 llvm::CallInst *call = CGF.Builder.CreateCall(Dtor, Addr);

312

313

314 if (auto *DtorFn = dyn_castllvm::Function(

315 Dtor.getCallee()->stripPointerCastsAndAliases()))

316 call->setCallingConv(DtorFn->getCallingConv());

317

318

319 CGF.Builder.CreateStore(llvm::Constant::getNullValue(CGM.IntTy),

320 CGF.ReturnValue);

321

322 CGF.FinishFunction();

323

324 return DtorStub;

325}

326

327

329 llvm::FunctionCallee dtor,

330 llvm::Constant *addr) {

331

334}

335

336

338 llvm::FunctionCallee Dtor,

339 llvm::Constant *Addr) {

340

341 llvm::Function *dtorStub =

344}

345

347

348 assert(dtorStub->getType() ==

349 llvm::PointerType::get(

350 llvm::FunctionType::get(CGM.VoidTy, false),

351 dtorStub->getType()->getPointerAddressSpace()) &&

352 "Argument to atexit has a wrong type.");

353

354 llvm::FunctionType *atexitTy =

355 llvm::FunctionType::get(IntTy, dtorStub->getType(), false);

356

357 llvm::FunctionCallee atexit =

359 true);

360 if (llvm::Function *atexitFn = dyn_castllvm::Function(atexit.getCallee()))

361 atexitFn->setDoesNotThrow();

362

364}

365

366llvm::Value *

368

369

370

371

372

373

374

375 assert(dtorStub->getType() ==

376 llvm::PointerType::get(

377 llvm::FunctionType::get(CGM.VoidTy, false),

378 dtorStub->getType()->getPointerAddressSpace()) &&

379 "Argument to unatexit has a wrong type.");

380

381 llvm::FunctionType *unatexitTy =

382 llvm::FunctionType::get(IntTy, {dtorStub->getType()}, false);

383

384 llvm::FunctionCallee unatexit =

386

387 castllvm::Function(unatexit.getCallee())->setDoesNotThrow();

388

390}

391

393 llvm::GlobalVariable *DeclPtr,

394 bool PerformInit) {

395

396

397

400 "this initialization requires a guard variable, which "

401 "the kernel does not support");

402

404}

405

407 llvm::BasicBlock *InitBlock,

408 llvm::BasicBlock *NoInitBlock,

409 GuardKind Kind,

412

413

414

415 static const uint64_t InitsPerTLSVar = 1024;

416 static const uint64_t InitsPerLocalVar = 1024 * 1024;

417

418 llvm::MDNode *Weights;

420

421

422

423

424 Weights = nullptr;

425 } else {

427

428

430 NumInits = InitsPerTLSVar;

431 else

432 NumInits = InitsPerLocalVar;

433

434

435

437 Weights = MDHelper.createBranchWeights(1, NumInits - 1);

438 }

439

440 Builder.CreateCondBr(NeedsInit, InitBlock, NoInitBlock, Weights);

441}

442

444 llvm::FunctionType *FTy, const Twine &Name, const CGFunctionInfo &FI,

446 llvm::Function *Fn = llvm::Function::Create(FTy, Linkage, Name, &getModule());

447

449

450 if (const char *Section = getTarget().getStaticInitSectionSpecifier())

451 Fn->setSection(Section);

452 }

453

454 if (Linkage == llvm::GlobalVariable::InternalLinkage)

456

458

460 Fn->setDoesNotThrow();

461

462 if (getLangOpts().Sanitize.has(SanitizerKind::Address) &&

464 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);

465

466 if (getLangOpts().Sanitize.has(SanitizerKind::KernelAddress) &&

468 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);

469

470 if (getLangOpts().Sanitize.has(SanitizerKind::HWAddress) &&

472 Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);

473

474 if (getLangOpts().Sanitize.has(SanitizerKind::KernelHWAddress) &&

476 Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);

477

478 if (getLangOpts().Sanitize.has(SanitizerKind::MemtagStack) &&

480 Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);

481

482 if (getLangOpts().Sanitize.has(SanitizerKind::Type) &&

484 Fn->addFnAttr(llvm::Attribute::SanitizeType);

485

486 if (getLangOpts().Sanitize.has(SanitizerKind::Thread) &&

488 Fn->addFnAttr(llvm::Attribute::SanitizeThread);

489

490 if (getLangOpts().Sanitize.has(SanitizerKind::NumericalStability) &&

492 Fn->addFnAttr(llvm::Attribute::SanitizeNumericalStability);

493

494 if (getLangOpts().Sanitize.has(SanitizerKind::Memory) &&

496 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);

497

498 if (getLangOpts().Sanitize.has(SanitizerKind::KernelMemory) &&

500 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);

501

502 if (getLangOpts().Sanitize.has(SanitizerKind::SafeStack) &&

504 Fn->addFnAttr(llvm::Attribute::SafeStack);

505

506 if (getLangOpts().Sanitize.has(SanitizerKind::ShadowCallStack) &&

508 Fn->addFnAttr(llvm::Attribute::ShadowCallStack);

509

510 return Fn;

511}

512

513

514

515

516void CodeGenModule::EmitPointerToInitFunc(const VarDecl *D,

517 llvm::GlobalVariable *GV,

518 llvm::Function *InitFunc,

519 InitSegAttr *ISA) {

520 llvm::GlobalVariable *PtrArray = new llvm::GlobalVariable(

521 TheModule, InitFunc->getType(), true,

522 llvm::GlobalValue::PrivateLinkage, InitFunc, "__cxx_init_fn_ptr");

523 PtrArray->setSection(ISA->getSection());

525

526

527 if (llvm::Comdat *C = GV->getComdat())

528 PtrArray->setComdat(C);

529}

530

531void

532CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,

533 llvm::GlobalVariable *Addr,

534 bool PerformInit) {

535

536

537

538

539

540

542 (D->hasAttr() || D->hasAttr() ||

543 D->hasAttr()))

544 return;

545

546

547 auto I = DelayedCXXInitPosition.find(D);

548 if (I != DelayedCXXInitPosition.end() && I->second == ~0U)

549 return;

550

551 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);

553 {

554 llvm::raw_svector_ostream Out(FnName);

556 }

557

558

561

562 auto *ISA = D->getAttr();

564 PerformInit);

565

566 llvm::GlobalVariable *COMDATKey =

567 supportsCOMDAT() && D->isExternallyVisible() ? Addr : nullptr;

568

569 if (D->getTLSKind()) {

570

571

572

573 CXXThreadLocalInits.push_back(Fn);

574 CXXThreadLocalInitVars.push_back(D);

575 } else if (PerformInit && ISA) {

576

577

579 if (ISA->getSection() == ".CRT$XCC")

581 else if (ISA->getSection() == ".CRT$XCL")

583

584 if (Priority != -1)

586 else

587 EmitPointerToInitFunc(D, Addr, Fn, ISA);

588 } else if (auto *IPA = D->getAttr()) {

590 PrioritizedCXXGlobalInits.size());

591 PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));

594 D->hasAttr()) {

595

596

597

598

599

600

601

602

603

604

605

606

607

608

609

610

611

612

613

614

615

616

617

618

619

620

621

622

623

624

625

626

627

628

629

630

631

632

633

634

635

636 I = DelayedCXXInitPosition.find(D);

637 unsigned LexOrder =

638 I == DelayedCXXInitPosition.end() ? CXXGlobalInits.size() : I->second;

640 if (COMDATKey && (getTriple().isOSBinFormatELF() ||

642

643

645 }

646

647

648

649

650 llvm::Comdat *C = Addr->getComdat();

651 if (COMDATKey && C &&

654 Fn->setComdat(C);

655 }

656 } else {

657 I = DelayedCXXInitPosition.find(D);

658 if (I == DelayedCXXInitPosition.end()) {

659 CXXGlobalInits.push_back(Fn);

660 } else if (I->second != ~0U) {

661 assert(I->second < CXXGlobalInits.size() &&

662 CXXGlobalInits[I->second] == nullptr);

663 CXXGlobalInits[I->second] = Fn;

664 }

665 }

666

667

668 DelayedCXXInitPosition[D] = ~0U;

669}

670

671void CodeGenModule::EmitCXXThreadLocalInitFunc() {

673 *this, CXXThreadLocals, CXXThreadLocalInits, CXXThreadLocalInitVars);

674

675 CXXThreadLocalInits.clear();

676 CXXThreadLocalInitVars.clear();

677 CXXThreadLocals.clear();

678}

679

680

681

682

683

684

685

686

687

688

689

690

691

692

693

694

695void CodeGenModule::EmitCXXModuleInitFunc(Module *Primary) {

697 "The function should only be called for C++20 named module interface"

698 " or partition.");

699

700 while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())

701 CXXGlobalInits.pop_back();

702

703

704

705

706

708

709 for (auto I : Primary->Exports)

710 AllImports.insert(I.getPointer());

711

713 AllImports.insert(M);

714

715

717 assert((SubM->isGlobalModule() || SubM->isPrivateModule()) &&

718 "The sub modules of C++20 module unit should only be global module "

719 "fragments or private module framents.");

720 assert(SubM->Exports.empty() &&

721 "The global mdoule fragments and the private module fragments are "

722 "not allowed to export import modules.");

724 AllImports.insert(M);

725 }

726

728 for (Module *M : AllImports) {

729

731 continue;

732

733

735 continue;

736 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);

738 {

739 llvm::raw_svector_ostream Out(FnName);

740 cast(getCXXABI().getMangleContext())

741 .mangleModuleInitializer(M, Out);

742 }

744 "We should only have one use of the initializer call");

745 llvm::Function *Fn = llvm::Function::Create(

746 FTy, llvm::Function::ExternalLinkage, FnName.str(), &getModule());

747 ModuleInits.push_back(Fn);

748 }

749

750

751

752 if (!PrioritizedCXXGlobalInits.empty()) {

754 llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(),

755 PrioritizedCXXGlobalInits.end());

757 I = PrioritizedCXXGlobalInits.begin(),

758 E = PrioritizedCXXGlobalInits.end();

759 I != E;) {

761 std::upper_bound(I + 1, E, *I, GlobalInitPriorityCmp());

762

763 for (; I < PrioE; ++I)

764 ModuleInits.push_back(I->second);

765 }

766 }

767

768

769 for (auto *F : CXXGlobalInits)

770 ModuleInits.push_back(F);

771

772 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);

774

775

776

777

778

779 llvm::Function *Fn;

780 {

782 llvm::raw_svector_ostream Out(InitFnName);

783 cast(getCXXABI().getMangleContext())

784 .mangleModuleInitializer(Primary, Out);

786 FTy, llvm::Twine(InitFnName), FI, SourceLocation(), false,

787 llvm::GlobalVariable::ExternalLinkage);

788

789

790

792 if (!ModuleInits.empty()) {

793

794 llvm::GlobalVariable *Guard = new llvm::GlobalVariable(

796 llvm::GlobalVariable::InternalLinkage,

797 llvm::ConstantInt::get(Int8Ty, 0), InitFnName.str() + "__in_chrg");

799 Guard->setAlignment(GuardAlign.getAsAlign());

801 }

803 GuardAddr);

804 }

805

806

807

808

809

811

812

813

816 Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);

817 }

818

823 Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);

824 else

825 Fn->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL);

826 Fn->addFnAttr("device-init");

827 }

828

829

830 AllImports.clear();

831 PrioritizedCXXGlobalInits.clear();

832 CXXGlobalInits.clear();

833 ModuleInits.clear();

834}

835

838

841

842 for (size_t i = 0; i < FileName.size(); ++i) {

843

844

847 }

848

850}

851

853 assert(Priority <= 65535 && "Priority should always be <= 65535.");

854

855

856

857 std::string PrioritySuffix = llvm::utostr(Priority);

858 PrioritySuffix = std::string(6 - PrioritySuffix.size(), '0') + PrioritySuffix;

859

860 return PrioritySuffix;

861}

862

863void

864CodeGenModule::EmitCXXGlobalInitFunc() {

865 while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())

866 CXXGlobalInits.pop_back();

867

868

870 if (CXX20ModuleInits)

871 for (Module *M : ImportedModules) {

872

874 continue;

875

876

878 continue;

879 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);

881 {

882 llvm::raw_svector_ostream Out(FnName);

883 cast(getCXXABI().getMangleContext())

884 .mangleModuleInitializer(M, Out);

885 }

887 "We should only have one use of the initializer call");

888 llvm::Function *Fn = llvm::Function::Create(

889 FTy, llvm::Function::ExternalLinkage, FnName.str(), &getModule());

890 ModuleInits.push_back(Fn);

891 }

892

893 if (ModuleInits.empty() && CXXGlobalInits.empty() &&

894 PrioritizedCXXGlobalInits.empty())

895 return;

896

897 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);

899

900

901 if (!PrioritizedCXXGlobalInits.empty()) {

903 llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(),

904 PrioritizedCXXGlobalInits.end());

905

906

907

909 I = PrioritizedCXXGlobalInits.begin(),

910 E = PrioritizedCXXGlobalInits.end(); I != E; ) {

912 PrioE = std::upper_bound(I + 1, E, *I, GlobalInitPriorityCmp());

913

914 LocalCXXGlobalInits.clear();

915

916 unsigned int Priority = I->first.priority;

919

920

921 if (!ModuleInits.empty()) {

922 for (auto *F : ModuleInits)

923 LocalCXXGlobalInits.push_back(F);

924 ModuleInits.clear();

925 }

926

927 for (; I < PrioE; ++I)

928 LocalCXXGlobalInits.push_back(I->second);

929

932 }

933 PrioritizedCXXGlobalInits.clear();

934 }

935

936 if (getCXXABI().useSinitAndSterm() && ModuleInits.empty() &&

937 CXXGlobalInits.empty())

938 return;

939

940 for (auto *F : CXXGlobalInits)

941 ModuleInits.push_back(F);

942 CXXGlobalInits.clear();

943

944

945

946

947

948 llvm::Function *Fn;

949 if (CXX20ModuleInits && getContext().getCurrentNamedModule() &&

950 getContext().getCurrentNamedModule()->isModuleImplementation()) {

952 llvm::raw_svector_ostream Out(InitFnName);

953 cast(getCXXABI().getMangleContext())

954 .mangleModuleInitializer(getContext().getCurrentNamedModule(), Out);

956 FTy, llvm::Twine(InitFnName), FI, SourceLocation(), false,

957 llvm::GlobalVariable::ExternalLinkage);

958 } else

960 FTy,

962 FI);

963

966

967

968

969

970

971

972

973

974

977 Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);

978 }

979

984 Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);

985 else

986 Fn->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL);

987 Fn->addFnAttr("device-init");

988 }

989

990 ModuleInits.clear();

991}

992

993void CodeGenModule::EmitCXXGlobalCleanUpFunc() {

994 if (CXXGlobalDtorsOrStermFinalizers.empty() &&

995 PrioritizedCXXStermFinalizers.empty())

996 return;

997

998 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);

1000

1001

1002 if (!PrioritizedCXXStermFinalizers.empty()) {

1004 llvm::array_pod_sort(PrioritizedCXXStermFinalizers.begin(),

1005 PrioritizedCXXStermFinalizers.end());

1006

1007

1008

1010 I = PrioritizedCXXStermFinalizers.begin(),

1011 E = PrioritizedCXXStermFinalizers.end();

1012 I != E;) {

1014 std::upper_bound(I + 1, E, *I, StermFinalizerPriorityCmp());

1015

1016 LocalCXXStermFinalizers.clear();

1017

1018 unsigned int Priority = I->first.priority;

1021

1022 for (; I < PrioE; ++I) {

1023 llvm::FunctionCallee DtorFn = I->second;

1024 LocalCXXStermFinalizers.emplace_back(DtorFn.getFunctionType(),

1025 DtorFn.getCallee(), nullptr);

1026 }

1027

1029 Fn, LocalCXXStermFinalizers);

1031 }

1032 PrioritizedCXXStermFinalizers.clear();

1033 }

1034

1035 if (CXXGlobalDtorsOrStermFinalizers.empty())

1036 return;

1037

1038

1039 llvm::Function *Fn =

1041

1043 Fn, CXXGlobalDtorsOrStermFinalizers);

1045 CXXGlobalDtorsOrStermFinalizers.clear();

1046}

1047

1048

1051 llvm::GlobalVariable *Addr,

1052 bool PerformInit) {

1053

1054 if (D->hasAttr())

1055 DebugInfo = nullptr;

1056

1058

1062

1064

1065

1066

1067

1068

1069

1070

1071

1072 if (Addr->hasWeakLinkage() || Addr->hasLinkOnceLinkage() ||

1076 } else {

1078 }

1079

1082

1084}

1085

1086void

1090 {

1094

1096

1097 llvm::BasicBlock *ExitBlock = nullptr;

1099

1100

1103 "guard.uninitialized");

1109

1110

1111

1112 Builder.CreateStore(llvm::ConstantInt::get(GuardVal->getType(),1), Guard);

1113

1114

1118 CGM.getDataLayout().getTypeAllocSize(GuardVal->getType())));

1119 }

1120

1121 RunCleanupsScope Scope(*this);

1122

1123

1124

1128 }

1129

1130 for (unsigned i = 0, e = Decls.size(); i != e; ++i)

1131 if (Decls[i])

1133

1138 Builder.CreateCall(llvm::FunctionCallee(ResInitFn), {});

1139 }

1140 }

1141

1142 Scope.ForceCleanup();

1143

1144 if (ExitBlock) {

1145 Builder.CreateBr(ExitBlock);

1147 }

1148 }

1149

1151}

1152

1154 llvm::Function *Fn,

1155 ArrayRef<std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH,

1156 llvm::Constant *>>

1157 DtorsOrStermFinalizers) {

1158 {

1162

1164

1165

1166 for (unsigned i = 0, e = DtorsOrStermFinalizers.size(); i != e; ++i) {

1167 llvm::FunctionType *CalleeTy;

1168 llvm::Value *Callee;

1169 llvm::Constant *Arg;

1170 std::tie(CalleeTy, Callee, Arg) = DtorsOrStermFinalizers[e - i - 1];

1171

1172 llvm::CallInst *CI = nullptr;

1173 if (Arg == nullptr) {

1174 assert(

1176 "Arg could not be nullptr unless using sinit and sterm functions.");

1177 CI = Builder.CreateCall(CalleeTy, Callee);

1178 } else

1179 CI = Builder.CreateCall(CalleeTy, Callee, Arg);

1180

1181

1182 if (llvm::Function *F = dyn_castllvm::Function(Callee))

1183 CI->setCallingConv(F->getCallingConv());

1184 }

1185 }

1186

1188}

1189

1190

1191

1192

1195 bool useEHCleanupForArray, const VarDecl *VD) {

1199 args.push_back(&Dst);

1200

1205 FTy, "__cxx_global_array_dtor", FI, VD->getLocation());

1206

1208

1211

1213

1214 emitDestroy(addr, type, destroyer, useEHCleanupForArray);

1215

1217

1218 return fn;

1219}

static std::string getPrioritySuffix(unsigned int Priority)

static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D, ConstantAddress DeclPtr)

static SmallString< 128 > getTransformedFileName(llvm::Module &M)

static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D, ConstantAddress Addr)

Emit code to cause the destruction of the given variable with static storage duration.

static void EmitDeclInvariant(CodeGenFunction &CGF, const VarDecl &D, llvm::Constant *Addr)

Emit code to cause the variable at the given address to be considered as constant from this point onw...

Defines the clang::LangOptions interface.

llvm::MachO::Record Record

const LangOptions & getLangOpts() const

CharUnits getTypeSizeInChars(QualType T) const

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

QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const

Return a normal function type with a typed argument list.

unsigned getTargetAddressSpace(LangAS AS) const

Represents a C++ destructor within a class.

Represents a C++ struct/union/class.

CharUnits - This is an opaque type for sizes expressed in character units.

llvm::Align getAsAlign() const

getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...

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.

Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...

static AggValueSlot forLValue(const LValue &LV, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)

static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)

Apply TemporaryLocation if it is valid.

static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)

Set the IRBuilder to not attach debug locations.

llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)

llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")

llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")

virtual bool HasThisReturn(GlobalDecl GD) const

Returns true if the given constructor or destructor is one of the kinds that the ABI says returns 'th...

virtual bool useSinitAndSterm() const

virtual void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, llvm::GlobalVariable *DeclPtr, bool PerformInit)=0

Emits the guarded initializer and destructor setup for the given variable, given that it couldn't be ...

virtual void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D, llvm::FunctionCallee Dtor, llvm::Constant *Addr)=0

Emit code to force the execution of a destructor during global teardown.

virtual bool canCallMismatchedFunctionType() const

Returns true if the target allows calling a function through a pointer with a different signature tha...

virtual void EmitThreadLocalInitFuncs(CodeGenModule &CGM, ArrayRef< const VarDecl * > CXXThreadLocals, ArrayRef< llvm::Function * > CXXThreadLocalInits, ArrayRef< const VarDecl * > CXXThreadLocalInitVars)=0

Emits ABI-required functions necessary to initialize thread_local variables in this translation unit.

MangleContext & getMangleContext()

Gets the mangle context.

CGFunctionInfo - Class to encapsulate the information about a function definition.

bool needsResourceBindingInitFn()

llvm::Function * createResourceBindingInitFn()

void annotateHLSLResource(const VarDecl *D, llvm::GlobalVariable *GV)

virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest)=0

virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest, bool threadlocal=false)=0

virtual llvm::Function * emitThreadPrivateVarDefinition(const VarDecl *VD, Address VDAddr, SourceLocation Loc, bool PerformInit, CodeGenFunction *CGF=nullptr)

Emit a code for initialization of threadprivate variable.

CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...

void GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef< llvm::Function * > CXXThreadLocals, ConstantAddress Guard=ConstantAddress::invalid())

GenerateCXXGlobalInitFunc - Generates code for initializing global variables.

void FinishFunction(SourceLocation EndLoc=SourceLocation())

FinishFunction - Complete IR generation of the current function.

static TypeEvaluationKind getEvaluationKind(QualType T)

getEvaluationKind - Return the TypeEvaluationKind of QualType T.

llvm::Constant * createAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr)

llvm::Value * EmitObjCAutoreleasePoolPush()

llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)

createBasicBlock - Create an LLVM basic block.

const LangOptions & getLangOpts() const

void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)

EmitBlock - Emit the given block.

llvm::Type * ConvertTypeForMem(QualType T)

llvm::Function * createTLSAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr, llvm::FunctionCallee &AtExit)

void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)

void registerGlobalDtorWithLLVM(const VarDecl &D, llvm::FunctionCallee fn, llvm::Constant *addr)

Registers the dtor using 'llvm.global_dtors' for platforms that do not support an 'atexit()' function...

Destroyer * getDestroyer(QualType::DestructionKind destructionKind)

void emitDestroy(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)

llvm::Function * generateDestroyHelper(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray, const VarDecl *VD)

void GenerateCXXGlobalCleanUpFunc(llvm::Function *Fn, ArrayRef< std::tuple< llvm::FunctionType *, llvm::WeakTrackingVH, llvm::Constant * > > DtorsOrStermFinalizers)

GenerateCXXGlobalCleanUpFunc - Generates code for cleaning up global variables.

void EmitCXXGuardedInit(const VarDecl &D, llvm::GlobalVariable *DeclPtr, bool PerformInit)

Emit code in this function to perform a guarded variable initialization.

void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::GlobalVariable *GV, bool PerformInit)

EmitCXXGlobalVarDeclInit - Create the initializer for a C++ variable with global storage.

void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit)

EmitComplexExprIntoLValue - Emit the given expression of complex type and place its result into the s...

void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())

Emit code for the start of a function.

void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::FunctionCallee fn, llvm::Constant *addr)

Call atexit() with a function that passes the given argument to the given function.

llvm::Value * unregisterGlobalDtorWithUnAtExit(llvm::Constant *dtorStub)

Call unatexit() with function dtorStub.

RValue EmitReferenceBindingToExpr(const Expr *E)

Emits a reference binding to the passed in expression.

void EmitAggExpr(const Expr *E, AggValueSlot AS)

EmitAggExpr - Emit the computation of the specified expression of aggregate type.

llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")

ASTContext & getContext() const

bool needsEHCleanup(QualType::DestructionKind kind)

Determines whether an EH cleanup is required to destroy a type with the given destruction kind.

llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")

void EmitInvariantStart(llvm::Constant *Addr, CharUnits Size)

CodeGenTypes & getTypes() const

void GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, const VarDecl *D, llvm::GlobalVariable *Addr, bool PerformInit)

LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)

void EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr)

llvm::LLVMContext & getLLVMContext()

llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)

EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...

void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)

EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...

void EmitCXXGuardedInitBranch(llvm::Value *NeedsInit, llvm::BasicBlock *InitBlock, llvm::BasicBlock *NoInitBlock, GuardKind Kind, const VarDecl *D)

Emit a branch to select whether or not to perform guarded initialization.

This class organizes the cross-function state that is used while generating LLVM code.

void SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, const CGFunctionInfo &FI)

Set the attributes on the LLVM function for the given decl and function info.

CGHLSLRuntime & getHLSLRuntime()

Return a reference to the configured HLSL runtime.

llvm::Module & getModule() const

llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)

Create or return a runtime function declaration with the specified type and name.

llvm::FunctionCallee getAddrAndTypeOfCXXStructor(GlobalDecl GD, const CGFunctionInfo *FnInfo=nullptr, llvm::FunctionType *FnType=nullptr, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)

llvm::Constant * getFunctionPointer(GlobalDecl GD, llvm::Type *Ty=nullptr)

Return the ABI-correct function pointer value for a reference to the given function.

bool isInNoSanitizeList(SanitizerMask Kind, llvm::Function *Fn, SourceLocation Loc) const

const LangOptions & getLangOpts() const

CodeGenTypes & getTypes()

const TargetInfo & getTarget() const

void addUsedGlobal(llvm::GlobalValue *GV)

Add a global to a list to be added to the llvm.used metadata.

const llvm::DataLayout & getDataLayout() const

void Error(SourceLocation loc, StringRef error)

Emit a general error that something can't be done.

CGCXXABI & getCXXABI() const

CGOpenMPRuntime & getOpenMPRuntime()

Return a reference to the configured OpenMP runtime.

const llvm::Triple & getTriple() const

void AddGlobalDtor(llvm::Function *Dtor, int Priority=65535, bool IsDtorAttrFunc=false)

AddGlobalDtor - Add a function to the list that will be called when the module is unloaded.

ASTContext & getContext() const

bool supportsCOMDAT() const

const TargetCodeGenInfo & getTargetCodeGenInfo()

const CodeGenOptions & getCodeGenOpts() const

llvm::LLVMContext & getLLVMContext()

llvm::GlobalValue * GetGlobalValue(StringRef Ref)

void GenKernelArgMetadata(llvm::Function *FN, const FunctionDecl *FD=nullptr, CodeGenFunction *CGF=nullptr)

OpenCL v1.2 s5.6.4.6 allows the compiler to store kernel argument information in the program executab...

llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})

CGObjCRuntime & getObjCRuntime()

Return a reference to the configured Objective-C runtime.

void AddGlobalCtor(llvm::Function *Ctor, int Priority=65535, unsigned LexOrder=~0U, llvm::Constant *AssociatedData=nullptr)

AddGlobalCtor - Add a function to the list that will be called before main() runs.

llvm::Function * CreateGlobalInitOrCleanUpFunction(llvm::FunctionType *ty, const Twine &name, const CGFunctionInfo &FI, SourceLocation Loc=SourceLocation(), bool TLS=false, llvm::GlobalVariable::LinkageTypes Linkage=llvm::GlobalVariable::InternalLinkage)

const CGFunctionInfo & arrangeLLVMFunctionInfo(CanQualType returnType, FnInfoOpts opts, ArrayRef< CanQualType > argTypes, FunctionType::ExtInfo info, ArrayRef< FunctionProtoType::ExtParameterInfo > paramInfos, RequiredArgs args)

"Arrange" the LLVM information for a call or type with the given signature.

llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)

GetFunctionType - Get the LLVM function type for.

const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)

A builtin function is a freestanding function using the default C conventions.

unsigned getTargetAddressSpace(QualType T) const

const CGFunctionInfo & arrangeNullaryFunction()

A nullary function is a freestanding function of type 'void ()'.

A specialization of Address that requires the address to be an LLVM Constant.

ConstantAddress withElementType(llvm::Type *ElemTy) const

static ConstantAddress invalid()

llvm::Constant * getPointer() const

FunctionArgList - Type for representing both the decl and type of parameters to a function.

LValue - This represents an lvalue references.

bool isObjCStrong() const

RValue - This trivial value class is used to represent the result of an expression that is evaluated.

llvm::Value * getScalarVal() const

getScalarVal() - Return the Value* of this scalar value.

virtual LangAS getAddrSpaceOfCxaAtexitPtrParam() const

Get address space of pointer parameter for __cxa_atexit.

SourceLocation getLocation() const

SourceLocation getBeginLoc() const LLVM_READONLY

SourceLocation getBeginLoc() const LLVM_READONLY

This represents one expression.

SourceLocation getExprLoc() const LLVM_READONLY

getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...

A class which abstracts out some details necessary for making a call.

GlobalDecl - represents a global declaration.

virtual void mangleDynamicAtExitDestructor(const VarDecl *D, raw_ostream &)=0

virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &)=0

Describes a module or submodule.

SmallVector< ExportDecl, 2 > Exports

The set of export declarations.

bool isNamedModuleInterfaceHasInit() const

bool isInterfaceOrPartition() const

llvm::SmallSetVector< Module *, 2 > Imports

The set of modules imported by this module, and on which this module depends.

llvm::iterator_range< submodule_iterator > submodules()

bool isHeaderLikeModule() const

Is this module have similar semantics as headers.

A (possibly-)qualified type.

@ DK_objc_strong_lifetime

Scope - A scope is a transient data structure that is used while parsing the program.

Encodes a location in the source.

The base class of the type hierarchy.

CXXRecordDecl * getAsCXXRecordDecl() const

Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...

bool isReferenceType() const

Represents a variable declaration or definition.

const Expr * getInit() const

@ TLS_Dynamic

TLS with a dynamic initializer.

const internal::VariadicAllOfMatcher< Type > type

Matches Types in the clang AST.

The JSON file list parser is used to communicate input to InstallAPI.

bool isTemplateInstantiation(TemplateSpecializationKind Kind)

Determine whether this template specialization kind refers to an instantiation of an entity (as oppos...

bool isUniqueGVALinkage(GVALinkage L)

Do we know that this will be the only definition of this symbol (excluding inlining-only definitions)...

Linkage

Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.

@ Dtor_Complete

Complete object dtor.

LLVM_READONLY bool isPreprocessingNumberBody(unsigned char c)

Return true if this is the body character of a C preprocessing number, which is [a-zA-Z0-9_.

const FunctionProtoType * T

@ Other

Other implicit parameter.

llvm::PointerType * VoidPtrTy

llvm::IntegerType * Int64Ty

llvm::IntegerType * Int8Ty

i8, i16, i32, and i64

llvm::CallingConv::ID getRuntimeCC() const

llvm::IntegerType * IntTy

int

llvm::PointerType * Int8PtrTy

Extra information about a function prototype.