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