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