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

1

2

3

4

5

6

7

8

9

10

11

12

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

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

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

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

26

27using namespace clang;

29

32 assert(

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

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

38

41

46 if (lv.isObjCStrong())

49 else if (lv.isObjCWeak())

51 DeclPtr);

52 else

54 return;

55 }

58 return;

65 return;

66 }

67 llvm_unreachable("bad evaluation kind");

68}

69

70

71

74

75

76

77

78

79

81

82

83

84 switch (DtorKind) {

86 return;

87

89 break;

90

94

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

96 return;

97 }

98

99 llvm::FunctionCallee Func;

100 llvm::Constant *Argument;

101

104

105

106

107

108

110 bool CanRegisterDestructor =

114

115

116

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

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

119 assert(Record->hasTrivialDestructor());

121

124 auto DestAS =

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

129 if (DestAS == SrcAS)

130 Argument = Addr.getPointer();

131 else

132

133

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

135 } else {

136 Argument = Addr.getPointer();

137 }

138

139 } else {

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

145 }

146

148}

149

150

151

153 llvm::Constant *Addr) {

156}

157

159

160 if (CGM.getCodeGenOpts().OptimizationLevel)

161 return;

162

163

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

165

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

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

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

169

170

171 uint64_t Width = Size.getQuantity();

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

173 Builder.CreateCall(InvariantStart, Args);

174}

175

177 llvm::GlobalVariable *GV,

178 bool PerformInit) {

179

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

199 unsigned ActualAddrSpace = GV->getAddressSpace();

200 llvm::Constant *DeclPtr = GV;

201 if (ActualAddrSpace != ExpectedAddrSpace) {

202 llvm::PointerType *PTy =

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

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

205 }

206

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

209

210 if (T->isReferenceType()) {

212 D.hasAttr()) {

213 (void)CGM.getOpenMPRuntime().emitThreadPrivateVarDefinition(

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

215 PerformInit, this);

216 }

217 bool NeedsDtor =

219 if (PerformInit)

223 else

225 return;

226 }

227

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

229 "destruction for reference");

232}

233

234

235

237 llvm::FunctionCallee dtor,

238 llvm::Constant *addr) {

239

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

242 {

243 llvm::raw_svector_ostream Out(FnName);

244 CGM.getCXXABI().getMangleContext().mangleDynamicAtExitDestructor(&VD, Out);

245 }

246

247 const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();

248 llvm::Function *fn = CGM.CreateGlobalInitOrCleanUpFunction(

250

251 CodeGenFunction CGF(CGM);

252

256

258

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

260

261

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

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

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

265

267

268

270 false, false));

273 return CGM.getFunctionPointer(fn, fnType);

274}

275

276

277

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

280 llvm::FunctionCallee &AtExit) {

282 {

283 llvm::raw_svector_ostream Out(FnName);

284 CGM.getCXXABI().getMangleContext().mangleDynamicAtExitDestructor(&D, Out);

285 }

286

287 const CGFunctionInfo &FI = CGM.getTypes().arrangeLLVMFunctionInfo(

290

291

292 llvm::FunctionType *StubTy =

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

294

295 llvm::Function *DtorStub = CGM.CreateGlobalInitOrCleanUpFunction(

296 StubTy, FnName.str(), FI, D.getLocation());

297

298 CodeGenFunction CGF(CGM);

299

303 Args.push_back(&IPD);

305

308

309

311

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

313

314

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

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

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

318

319

322

324

325 return DtorStub;

326}

327

328

330 llvm::FunctionCallee dtor,

331 llvm::Constant *addr) {

332

335}

336

337

339 llvm::FunctionCallee Dtor,

340 llvm::Constant *Addr) {

341

342 llvm::Function *dtorStub =

344 CGM.AddGlobalDtor(dtorStub);

345}

346

348

349 assert(dtorStub->getType()->isPointerTy() &&

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

351

352 llvm::FunctionType *atexitTy =

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

354

355 llvm::FunctionCallee atexit =

356 CGM.CreateRuntimeFunction(atexitTy, "atexit", llvm::AttributeList(),

357 true);

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

359 atexitFn->setDoesNotThrow();

360

362}

363

364llvm::Value *

366

367

368

369

370

371

372

373 assert(dtorStub->getType()->isPointerTy() &&

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

375

376 llvm::FunctionType *unatexitTy =

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

378

379 llvm::FunctionCallee unatexit =

380 CGM.CreateRuntimeFunction(unatexitTy, "unatexit", llvm::AttributeList());

381

383

385}

386

388 llvm::GlobalVariable *DeclPtr,

389 bool PerformInit) {

390

391

392

393 if (CGM.getCodeGenOpts().ForbidGuardVariables)

395 "this initialization requires a guard variable, which "

396 "the kernel does not support");

397

398 CGM.getCXXABI().EmitGuardedInit(*this, D, DeclPtr, PerformInit);

399}

400

402 llvm::BasicBlock *InitBlock,

403 llvm::BasicBlock *NoInitBlock,

407

408

409

410 static const uint64_t InitsPerTLSVar = 1024;

411 static const uint64_t InitsPerLocalVar = 1024 * 1024;

412

413 llvm::MDNode *Weights;

415

416

417

418

419 Weights = nullptr;

420 } else {

421 uint64_t NumInits;

422

423

425 NumInits = InitsPerTLSVar;

426 else

427 NumInits = InitsPerLocalVar;

428

429

430

431 llvm::MDBuilder MDHelper(CGM.getLLVMContext());

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

433 }

434

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

436}

437

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

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

442

444

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

446 Fn->setSection(Section);

447 }

448

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

451 else {

455 }

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

560 FTy, FnName.str(), getTypes().arrangeNullaryFunction(), D->getLocation());

561

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

564 PerformInit);

565

566 llvm::GlobalVariable *COMDATKey =

568

570

571

572

573 CXXThreadLocalInits.push_back(Fn);

574 CXXThreadLocalInitVars.push_back(D);

575 } else if (PerformInit && ISA) {

576

577

578 int Priority = -1;

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

580 Priority = 200;

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

582 Priority = 400;

583

584 if (Priority != -1)

586 else

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

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

589 OrderGlobalInitsOrStermFinalizers Key(IPA->getPriority(),

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

707 llvm::SmallSetVector<Module *, 8> AllImports;

708

709 for (auto I : Primary->Exports)

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

711

712 AllImports.insert_range(Primary->Imports);

713

714

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

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

718 "fragments or private module framents.");

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

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

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

722 AllImports.insert_range(SubM->Imports);

723 }

724

725 SmallVector<llvm::Function *, 8> ModuleInits;

726 for (Module *M : AllImports) {

727

728 if (M->isHeaderLikeModule())

729 continue;

730

731

732 if (!M->isNamedModuleInterfaceHasInit())

733 continue;

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

735 SmallString<256> FnName;

736 {

737 llvm::raw_svector_ostream Out(FnName);

739 .mangleModuleInitializer(M, Out);

740 }

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

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

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

745 ModuleInits.push_back(Fn);

746 }

747

748

749

750 if (!PrioritizedCXXGlobalInits.empty()) {

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

752 PrioritizedCXXGlobalInits.end());

753 for (SmallVectorImpl::iterator

754 I = PrioritizedCXXGlobalInits.begin(),

755 E = PrioritizedCXXGlobalInits.end();

756 I != E;) {

757 SmallVectorImpl::iterator PrioE =

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

759

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

761 ModuleInits.push_back(I->second);

762 }

763 }

764

765

766 for (auto *F : CXXGlobalInits)

767 ModuleInits.push_back(F);

768

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

771

772

773

774

775

776 llvm::Function *Fn;

777 {

778 SmallString<256> InitFnName;

779 llvm::raw_svector_ostream Out(InitFnName);

781 .mangleModuleInitializer(Primary, Out);

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

784 llvm::GlobalVariable::ExternalLinkage);

785

786

787

789 if (!ModuleInits.empty()) {

790

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

793 llvm::GlobalVariable::InternalLinkage,

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

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

797 GuardAddr = ConstantAddress(Guard, Int8Ty, GuardAlign);

798 }

799 CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, ModuleInits,

800 GuardAddr);

801 }

802

803

804

805

806

808

809

810

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

814 }

815

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

821 else

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

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

824 }

825

826

827 AllImports.clear();

828 PrioritizedCXXGlobalInits.clear();

829 CXXGlobalInits.clear();

830 ModuleInits.clear();

831}

832

835

838

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

840

841

844 }

845

847}

848

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

851

852

853

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

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

856

857 return PrioritySuffix;

858}

859

860void

861CodeGenModule::EmitCXXGlobalInitFunc() {

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

863 CXXGlobalInits.pop_back();

864

865

866 SmallVector<llvm::Function *, 8> ModuleInits;

867 if (CXX20ModuleInits)

868 for (Module *M : ImportedModules) {

869

870 if (M->isHeaderLikeModule())

871 continue;

872

873

874 if (!M->isNamedModuleInterfaceHasInit())

875 continue;

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

877 SmallString<256> FnName;

878 {

879 llvm::raw_svector_ostream Out(FnName);

881 .mangleModuleInitializer(M, Out);

882 }

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

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

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

887 ModuleInits.push_back(Fn);

888 }

889

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

891 PrioritizedCXXGlobalInits.empty())

892 return;

893

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

896

897

898 if (!PrioritizedCXXGlobalInits.empty()) {

899 SmallVector<llvm::Function *, 8> LocalCXXGlobalInits;

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

901 PrioritizedCXXGlobalInits.end());

902

903

904

905 for (SmallVectorImpl::iterator

906 I = PrioritizedCXXGlobalInits.begin(),

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

908 SmallVectorImpl::iterator

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

910

911 LocalCXXGlobalInits.clear();

912

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

916

917

918 if (!ModuleInits.empty()) {

919 for (auto *F : ModuleInits)

920 LocalCXXGlobalInits.push_back(F);

921 ModuleInits.clear();

922 }

923

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

925 LocalCXXGlobalInits.push_back(I->second);

926

927 CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, LocalCXXGlobalInits);

929 }

930 PrioritizedCXXGlobalInits.clear();

931 }

932

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

934 CXXGlobalInits.empty())

935 return;

936

937 for (auto *F : CXXGlobalInits)

938 ModuleInits.push_back(F);

939 CXXGlobalInits.clear();

940

941

942

943

944

945 llvm::Function *Fn;

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

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

948 SmallString<256> InitFnName;

949 llvm::raw_svector_ostream Out(InitFnName);

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

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

954 llvm::GlobalVariable::ExternalLinkage);

955 } else

957 FTy,

959 FI);

960

961 CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, ModuleInits);

963

964

965

966

967

968

969

970

971

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

975 }

976

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

982 else

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

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

985 }

986

987 ModuleInits.clear();

988}

989

990void CodeGenModule::EmitCXXGlobalCleanUpFunc() {

991 if (CXXGlobalDtorsOrStermFinalizers.empty() &&

992 PrioritizedCXXStermFinalizers.empty())

993 return;

994

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

997

998

999 if (!PrioritizedCXXStermFinalizers.empty()) {

1000 SmallVector<CXXGlobalDtorsOrStermFinalizer_t, 8> LocalCXXStermFinalizers;

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

1002 PrioritizedCXXStermFinalizers.end());

1003

1004

1005

1006 for (SmallVectorImpl::iterator

1007 I = PrioritizedCXXStermFinalizers.begin(),

1008 E = PrioritizedCXXStermFinalizers.end();

1009 I != E;) {

1010 SmallVectorImpl::iterator PrioE =

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

1012

1013 LocalCXXStermFinalizers.clear();

1014

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

1018

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

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

1021 LocalCXXStermFinalizers.emplace_back(DtorFn.getFunctionType(),

1022 DtorFn.getCallee(), nullptr);

1023 }

1024

1025 CodeGenFunction(*this).GenerateCXXGlobalCleanUpFunc(

1026 Fn, LocalCXXStermFinalizers);

1028 }

1029 PrioritizedCXXStermFinalizers.clear();

1030 }

1031

1032 if (CXXGlobalDtorsOrStermFinalizers.empty())

1033 return;

1034

1035

1036 llvm::Function *Fn =

1038

1039 CodeGenFunction(*this).GenerateCXXGlobalCleanUpFunc(

1040 Fn, CXXGlobalDtorsOrStermFinalizers);

1042 CXXGlobalDtorsOrStermFinalizers.clear();

1043}

1044

1045

1048 llvm::GlobalVariable *Addr,

1049 bool PerformInit) {

1050

1051 if (D->hasAttr())

1052 DebugInfo = nullptr;

1053

1055

1059

1061

1062

1063

1064

1065

1066

1067

1068

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

1073 } else {

1075 }

1076

1078}

1079

1080void

1084 {

1088

1090

1091 llvm::BasicBlock *ExitBlock = nullptr;

1093

1094

1095 llvm::Value *GuardVal = Builder.CreateLoad(Guard);

1096 llvm::Value *Uninit = Builder.CreateIsNull(GuardVal,

1097 "guard.uninitialized");

1103

1104

1105

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

1107

1108

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

1113 }

1114

1116

1117

1118

1122 }

1123

1124 for (llvm::Function *Decl : Decls)

1127

1128 Scope.ForceCleanup();

1129

1130 if (ExitBlock) {

1131 Builder.CreateBr(ExitBlock);

1133 }

1134 }

1135

1137}

1138

1140 llvm::Function *Fn,

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

1142 llvm::Constant *>>

1143 DtorsOrStermFinalizers) {

1144 {

1148

1150

1151

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

1153 llvm::FunctionType *CalleeTy;

1154 llvm::Value *Callee;

1155 llvm::Constant *Arg;

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

1157

1158 llvm::CallBase *CI = nullptr;

1159 if (Arg == nullptr) {

1160 assert(

1161 CGM.getCXXABI().useSinitAndSterm() &&

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

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

1164 } else {

1165

1166

1167

1168 assert(Arg->getType()->isPointerTy());

1169 assert(CalleeTy->getParamType(0)->isPointerTy());

1170 unsigned ActualAddrSpace = Arg->getType()->getPointerAddressSpace();

1171 unsigned ExpectedAddrSpace =

1172 CalleeTy->getParamType(0)->getPointerAddressSpace();

1173 if (ActualAddrSpace != ExpectedAddrSpace) {

1174 llvm::PointerType *PTy =

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

1176 Arg = llvm::ConstantExpr::getAddrSpaceCast(Arg, PTy);

1177 }

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

1179 }

1180

1181

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

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

1184

1185 if (CGM.shouldEmitConvergenceTokens() && CI->isConvergent())

1186 CI = addConvergenceControlToken(CI);

1187 }

1188 }

1189

1191}

1192

1193

1194

1195

1198 bool useEHCleanupForArray, const VarDecl *VD) {

1202 args.push_back(&Dst);

1203

1205 CGM.getTypes().arrangeBuiltinFunctionDeclaration(getContext().VoidTy, args);

1206 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);

1207 llvm::Function *fn = CGM.CreateGlobalInitOrCleanUpFunction(

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

1209

1211

1214

1216

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

1218

1220

1221 return fn;

1222}

static std::string getPrioritySuffix(unsigned int Priority)

Definition CGDeclCXX.cpp:849

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

Definition CGDeclCXX.cpp:30

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

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

Definition CGDeclCXX.cpp:72

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

Definition CGDeclCXX.cpp:152

Defines the clang::LangOptions interface.

static SmallString< 128 > getTransformedFileName(mlir::ModuleOp mlirModule)

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)

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.

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

Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.

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

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

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

Definition CGDeclCXX.cpp:387

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

Create a stub function, suitable for being passed to atexit, which passes the given address to the gi...

Definition CGDeclCXX.cpp:236

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

emitDestroy - Immediately perform the destruction of the given object.

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

Create a stub function, suitable for being passed to __pt_atexit_np, which passes the given address t...

Definition CGDeclCXX.cpp:278

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 registerGlobalDtorWithAtExit(const VarDecl &D, llvm::FunctionCallee fn, llvm::Constant *addr)

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

Definition CGDeclCXX.cpp:329

void EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr)

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

createBasicBlock - Create an LLVM basic block.

const LangOptions & getLangOpts() const

RValue EmitReferenceBindingToExpr(const Expr *E)

Emits a reference binding to the passed in expression.

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

Destroyer * getDestroyer(QualType::DestructionKind destructionKind)

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

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

Definition CGDeclCXX.cpp:176

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 GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef< llvm::Function * > CXXThreadLocals, ConstantAddress Guard=ConstantAddress::invalid())

GenerateCXXGlobalInitFunc - Generates code for initializing global variables.

Definition CGDeclCXX.cpp:1081

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

Emit the code necessary to initialize the given global variable.

Definition CGDeclCXX.cpp:1046

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.

Definition CGDeclCXX.cpp:401

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

Definition CGDeclCXX.cpp:158

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

Call unatexit() with function dtorStub.

Definition CGDeclCXX.cpp:365

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

ASTContext & getContext() const

void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty)

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

Definition CGDeclCXX.cpp:338

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="")

llvm::Type * ConvertTypeForMem(QualType T)

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

GenerateCXXGlobalCleanUpFunc - Generates code for cleaning up global variables.

Definition CGDeclCXX.cpp:1139

llvm::Value * EmitObjCAutoreleasePoolPush()

Produce the code to do a objc_autoreleasepool_push.

CodeGenTypes & getTypes() const

static TypeEvaluationKind getEvaluationKind(QualType T)

getEvaluationKind - Return the TypeEvaluationKind of QualType T.

void EmitAggExpr(const Expr *E, AggValueSlot AS)

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

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

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

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

void FinishFunction(SourceLocation EndLoc=SourceLocation())

FinishFunction - Complete IR generation of the current function.

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

generateDestroyHelper - Generates a helper function which, when invoked, destroys the given object.

Definition CGDeclCXX.cpp:1196

Address ReturnValue

ReturnValue - The temporary alloca to hold the return value.

llvm::LLVMContext & getLLVMContext()

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 EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)

EmitBlock - Emit the given block.

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.

llvm::Module & getModule() const

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

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.

CGCXXABI & getCXXABI() const

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

CGObjCRuntime & getObjCRuntime()

Return a reference to the configured Objective-C runtime.

void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, llvm::Function *F, bool IsThunk)

Set the LLVM function attributes (sext, zext, etc).

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.

void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)

Set the LLVM function attributes which only apply to a function definition.

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)

Definition CGDeclCXX.cpp:438

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.

static ConstantAddress invalid()

llvm::Constant * getPointer() const

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

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 void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const

setTargetAttributes - Provides a convenient hook to handle extra target-specific attributes for the g...

virtual LangAS getAddrSpaceOfCxaAtexitPtrParam() const

Get address space of pointer parameter for __cxa_atexit.

SourceLocation getLocation() const

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 mangleDynamicInitializer(const VarDecl *D, raw_ostream &)=0

SmallVector< ExportDecl, 2 > Exports

The set of export declarations.

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

A (possibly-)qualified type.

@ DK_objc_strong_lifetime

Qualifiers getQualifiers() const

Retrieve the set of qualifiers applied to this type.

bool isConstantStorage(const ASTContext &Ctx, bool ExcludeCtor, bool ExcludeDtor)

LangAS getAddressSpace() const

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.

TLSKind getTLSKind() const

bool hasGlobalStorage() const

Returns true for all variables that do not have local storage.

QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const

Would the destruction of this variable have any effect, and if so, what kind?

const Expr * getInit() const

bool hasLocalStorage() const

Returns true if a variable with function scope is a non-static local variable.

@ TLS_Dynamic

TLS with a dynamic initializer.

bool isLocalVarDecl() const

Returns true for local variable declarations other than parameters.

TemplateSpecializationKind getTemplateSpecializationKind() const

If this variable is an instantiation of a variable template or a static data member of a class templa...

@ Decl

The l-value was an access to a declared entity or something equivalently strong, like the address of ...

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.

@ Module

Module linkage, which indicates that the entity can be referred to from other translation units withi...

const FunctionProtoType * T

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

U cast(CodeGen::Address addr)

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