Bug Summary

File:llvm/include/llvm/ADT/IntrusiveRefCntPtr.h
Warning:line 219, column 7
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name OrcV2CBindings.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-14~++20220116100644+5f782d25a742/build-llvm/tools/clang/stage2-bins -resource-dir /usr/lib/llvm-14/lib/clang/14.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I lib/ExecutionEngine/Orc -I /build/llvm-toolchain-snapshot-14~++20220116100644+5f782d25a742/llvm/lib/ExecutionEngine/Orc -I include -I /build/llvm-toolchain-snapshot-14~++20220116100644+5f782d25a742/llvm/include -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/llvm-toolchain-snapshot-14~++20220116100644+5f782d25a742/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fmacro-prefix-map=/build/llvm-toolchain-snapshot-14~++20220116100644+5f782d25a742/= -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-14~++20220116100644+5f782d25a742/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-14~++20220116100644+5f782d25a742/= -O3 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-14~++20220116100644+5f782d25a742/build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20220116100644+5f782d25a742/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20220116100644+5f782d25a742/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-01-16-232930-107970-1 -x c++ /build/llvm-toolchain-snapshot-14~++20220116100644+5f782d25a742/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp

/build/llvm-toolchain-snapshot-14~++20220116100644+5f782d25a742/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp

1//===--------------- OrcV2CBindings.cpp - C bindings OrcV2 APIs -----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "llvm-c/LLJIT.h"
10#include "llvm-c/Orc.h"
11#include "llvm-c/OrcEE.h"
12#include "llvm-c/TargetMachine.h"
13
14#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
15#include "llvm/ExecutionEngine/Orc/LLJIT.h"
16#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
17#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
18#include "llvm/ExecutionEngine/SectionMemoryManager.h"
19
20using namespace llvm;
21using namespace llvm::orc;
22
23namespace llvm {
24namespace orc {
25
26class InProgressLookupState;
27
28class OrcV2CAPIHelper {
29public:
30 using PoolEntry = SymbolStringPtr::PoolEntry;
31 using PoolEntryPtr = SymbolStringPtr::PoolEntryPtr;
32
33 // Move from SymbolStringPtr to PoolEntryPtr (no change in ref count).
34 static PoolEntryPtr moveFromSymbolStringPtr(SymbolStringPtr S) {
35 PoolEntryPtr Result = nullptr;
36 std::swap(Result, S.S);
37 return Result;
38 }
39
40 // Move from a PoolEntryPtr to a SymbolStringPtr (no change in ref count).
41 static SymbolStringPtr moveToSymbolStringPtr(PoolEntryPtr P) {
42 SymbolStringPtr S;
43 S.S = P;
44 return S;
45 }
46
47 // Copy a pool entry to a SymbolStringPtr (increments ref count).
48 static SymbolStringPtr copyToSymbolStringPtr(PoolEntryPtr P) {
49 return SymbolStringPtr(P);
50 }
51
52 static PoolEntryPtr getRawPoolEntryPtr(const SymbolStringPtr &S) {
53 return S.S;
54 }
55
56 static void retainPoolEntry(PoolEntryPtr P) {
57 SymbolStringPtr S(P);
58 S.S = nullptr;
59 }
60
61 static void releasePoolEntry(PoolEntryPtr P) {
62 SymbolStringPtr S;
63 S.S = P;
64 }
65
66 static InProgressLookupState *extractLookupState(LookupState &LS) {
67 return LS.IPLS.release();
68 }
69
70 static void resetLookupState(LookupState &LS, InProgressLookupState *IPLS) {
71 return LS.reset(IPLS);
72 }
73};
74
75} // namespace orc
76} // namespace llvm
77
78DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ExecutionSession, LLVMOrcExecutionSessionRef)inline ExecutionSession *unwrap(LLVMOrcExecutionSessionRef P)
{ return reinterpret_cast<ExecutionSession*>(P); } inline
LLVMOrcExecutionSessionRef wrap(const ExecutionSession *P) {
return reinterpret_cast<LLVMOrcExecutionSessionRef>(const_cast
<ExecutionSession*>(P)); }
79DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SymbolStringPool, LLVMOrcSymbolStringPoolRef)inline SymbolStringPool *unwrap(LLVMOrcSymbolStringPoolRef P)
{ return reinterpret_cast<SymbolStringPool*>(P); } inline
LLVMOrcSymbolStringPoolRef wrap(const SymbolStringPool *P) {
return reinterpret_cast<LLVMOrcSymbolStringPoolRef>(const_cast
<SymbolStringPool*>(P)); }
80DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcV2CAPIHelper::PoolEntry,inline OrcV2CAPIHelper::PoolEntry *unwrap(LLVMOrcSymbolStringPoolEntryRef
P) { return reinterpret_cast<OrcV2CAPIHelper::PoolEntry*>
(P); } inline LLVMOrcSymbolStringPoolEntryRef wrap(const OrcV2CAPIHelper
::PoolEntry *P) { return reinterpret_cast<LLVMOrcSymbolStringPoolEntryRef
>(const_cast<OrcV2CAPIHelper::PoolEntry*>(P)); }
81 LLVMOrcSymbolStringPoolEntryRef)inline OrcV2CAPIHelper::PoolEntry *unwrap(LLVMOrcSymbolStringPoolEntryRef
P) { return reinterpret_cast<OrcV2CAPIHelper::PoolEntry*>
(P); } inline LLVMOrcSymbolStringPoolEntryRef wrap(const OrcV2CAPIHelper
::PoolEntry *P) { return reinterpret_cast<LLVMOrcSymbolStringPoolEntryRef
>(const_cast<OrcV2CAPIHelper::PoolEntry*>(P)); }
82DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MaterializationUnit,inline MaterializationUnit *unwrap(LLVMOrcMaterializationUnitRef
P) { return reinterpret_cast<MaterializationUnit*>(P);
} inline LLVMOrcMaterializationUnitRef wrap(const MaterializationUnit
*P) { return reinterpret_cast<LLVMOrcMaterializationUnitRef
>(const_cast<MaterializationUnit*>(P)); }
83 LLVMOrcMaterializationUnitRef)inline MaterializationUnit *unwrap(LLVMOrcMaterializationUnitRef
P) { return reinterpret_cast<MaterializationUnit*>(P);
} inline LLVMOrcMaterializationUnitRef wrap(const MaterializationUnit
*P) { return reinterpret_cast<LLVMOrcMaterializationUnitRef
>(const_cast<MaterializationUnit*>(P)); }
84DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MaterializationResponsibility,inline MaterializationResponsibility *unwrap(LLVMOrcMaterializationResponsibilityRef
P) { return reinterpret_cast<MaterializationResponsibility
*>(P); } inline LLVMOrcMaterializationResponsibilityRef wrap
(const MaterializationResponsibility *P) { return reinterpret_cast
<LLVMOrcMaterializationResponsibilityRef>(const_cast<
MaterializationResponsibility*>(P)); }
85 LLVMOrcMaterializationResponsibilityRef)inline MaterializationResponsibility *unwrap(LLVMOrcMaterializationResponsibilityRef
P) { return reinterpret_cast<MaterializationResponsibility
*>(P); } inline LLVMOrcMaterializationResponsibilityRef wrap
(const MaterializationResponsibility *P) { return reinterpret_cast
<LLVMOrcMaterializationResponsibilityRef>(const_cast<
MaterializationResponsibility*>(P)); }
86DEFINE_SIMPLE_CONVERSION_FUNCTIONS(JITDylib, LLVMOrcJITDylibRef)inline JITDylib *unwrap(LLVMOrcJITDylibRef P) { return reinterpret_cast
<JITDylib*>(P); } inline LLVMOrcJITDylibRef wrap(const JITDylib
*P) { return reinterpret_cast<LLVMOrcJITDylibRef>(const_cast
<JITDylib*>(P)); }
87DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ResourceTracker, LLVMOrcResourceTrackerRef)inline ResourceTracker *unwrap(LLVMOrcResourceTrackerRef P) {
return reinterpret_cast<ResourceTracker*>(P); } inline
LLVMOrcResourceTrackerRef wrap(const ResourceTracker *P) { return
reinterpret_cast<LLVMOrcResourceTrackerRef>(const_cast
<ResourceTracker*>(P)); }
88DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DefinitionGenerator,inline DefinitionGenerator *unwrap(LLVMOrcDefinitionGeneratorRef
P) { return reinterpret_cast<DefinitionGenerator*>(P);
} inline LLVMOrcDefinitionGeneratorRef wrap(const DefinitionGenerator
*P) { return reinterpret_cast<LLVMOrcDefinitionGeneratorRef
>(const_cast<DefinitionGenerator*>(P)); }
89 LLVMOrcDefinitionGeneratorRef)inline DefinitionGenerator *unwrap(LLVMOrcDefinitionGeneratorRef
P) { return reinterpret_cast<DefinitionGenerator*>(P);
} inline LLVMOrcDefinitionGeneratorRef wrap(const DefinitionGenerator
*P) { return reinterpret_cast<LLVMOrcDefinitionGeneratorRef
>(const_cast<DefinitionGenerator*>(P)); }
90DEFINE_SIMPLE_CONVERSION_FUNCTIONS(InProgressLookupState, LLVMOrcLookupStateRef)inline InProgressLookupState *unwrap(LLVMOrcLookupStateRef P)
{ return reinterpret_cast<InProgressLookupState*>(P); }
inline LLVMOrcLookupStateRef wrap(const InProgressLookupState
*P) { return reinterpret_cast<LLVMOrcLookupStateRef>(const_cast
<InProgressLookupState*>(P)); }
91DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ThreadSafeContext,inline ThreadSafeContext *unwrap(LLVMOrcThreadSafeContextRef P
) { return reinterpret_cast<ThreadSafeContext*>(P); } inline
LLVMOrcThreadSafeContextRef wrap(const ThreadSafeContext *P)
{ return reinterpret_cast<LLVMOrcThreadSafeContextRef>
(const_cast<ThreadSafeContext*>(P)); }
92 LLVMOrcThreadSafeContextRef)inline ThreadSafeContext *unwrap(LLVMOrcThreadSafeContextRef P
) { return reinterpret_cast<ThreadSafeContext*>(P); } inline
LLVMOrcThreadSafeContextRef wrap(const ThreadSafeContext *P)
{ return reinterpret_cast<LLVMOrcThreadSafeContextRef>
(const_cast<ThreadSafeContext*>(P)); }
93DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ThreadSafeModule, LLVMOrcThreadSafeModuleRef)inline ThreadSafeModule *unwrap(LLVMOrcThreadSafeModuleRef P)
{ return reinterpret_cast<ThreadSafeModule*>(P); } inline
LLVMOrcThreadSafeModuleRef wrap(const ThreadSafeModule *P) {
return reinterpret_cast<LLVMOrcThreadSafeModuleRef>(const_cast
<ThreadSafeModule*>(P)); }
94DEFINE_SIMPLE_CONVERSION_FUNCTIONS(JITTargetMachineBuilder,inline JITTargetMachineBuilder *unwrap(LLVMOrcJITTargetMachineBuilderRef
P) { return reinterpret_cast<JITTargetMachineBuilder*>
(P); } inline LLVMOrcJITTargetMachineBuilderRef wrap(const JITTargetMachineBuilder
*P) { return reinterpret_cast<LLVMOrcJITTargetMachineBuilderRef
>(const_cast<JITTargetMachineBuilder*>(P)); }
95 LLVMOrcJITTargetMachineBuilderRef)inline JITTargetMachineBuilder *unwrap(LLVMOrcJITTargetMachineBuilderRef
P) { return reinterpret_cast<JITTargetMachineBuilder*>
(P); } inline LLVMOrcJITTargetMachineBuilderRef wrap(const JITTargetMachineBuilder
*P) { return reinterpret_cast<LLVMOrcJITTargetMachineBuilderRef
>(const_cast<JITTargetMachineBuilder*>(P)); }
96DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ObjectLayer, LLVMOrcObjectLayerRef)inline ObjectLayer *unwrap(LLVMOrcObjectLayerRef P) { return reinterpret_cast
<ObjectLayer*>(P); } inline LLVMOrcObjectLayerRef wrap(
const ObjectLayer *P) { return reinterpret_cast<LLVMOrcObjectLayerRef
>(const_cast<ObjectLayer*>(P)); }
97DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRTransformLayer, LLVMOrcIRTransformLayerRef)inline IRTransformLayer *unwrap(LLVMOrcIRTransformLayerRef P)
{ return reinterpret_cast<IRTransformLayer*>(P); } inline
LLVMOrcIRTransformLayerRef wrap(const IRTransformLayer *P) {
return reinterpret_cast<LLVMOrcIRTransformLayerRef>(const_cast
<IRTransformLayer*>(P)); }
98DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ObjectTransformLayer,inline ObjectTransformLayer *unwrap(LLVMOrcObjectTransformLayerRef
P) { return reinterpret_cast<ObjectTransformLayer*>(P)
; } inline LLVMOrcObjectTransformLayerRef wrap(const ObjectTransformLayer
*P) { return reinterpret_cast<LLVMOrcObjectTransformLayerRef
>(const_cast<ObjectTransformLayer*>(P)); }
99 LLVMOrcObjectTransformLayerRef)inline ObjectTransformLayer *unwrap(LLVMOrcObjectTransformLayerRef
P) { return reinterpret_cast<ObjectTransformLayer*>(P)
; } inline LLVMOrcObjectTransformLayerRef wrap(const ObjectTransformLayer
*P) { return reinterpret_cast<LLVMOrcObjectTransformLayerRef
>(const_cast<ObjectTransformLayer*>(P)); }
100DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DumpObjects, LLVMOrcDumpObjectsRef)inline DumpObjects *unwrap(LLVMOrcDumpObjectsRef P) { return reinterpret_cast
<DumpObjects*>(P); } inline LLVMOrcDumpObjectsRef wrap(
const DumpObjects *P) { return reinterpret_cast<LLVMOrcDumpObjectsRef
>(const_cast<DumpObjects*>(P)); }
101DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IndirectStubsManager,inline IndirectStubsManager *unwrap(LLVMOrcIndirectStubsManagerRef
P) { return reinterpret_cast<IndirectStubsManager*>(P)
; } inline LLVMOrcIndirectStubsManagerRef wrap(const IndirectStubsManager
*P) { return reinterpret_cast<LLVMOrcIndirectStubsManagerRef
>(const_cast<IndirectStubsManager*>(P)); }
102 LLVMOrcIndirectStubsManagerRef)inline IndirectStubsManager *unwrap(LLVMOrcIndirectStubsManagerRef
P) { return reinterpret_cast<IndirectStubsManager*>(P)
; } inline LLVMOrcIndirectStubsManagerRef wrap(const IndirectStubsManager
*P) { return reinterpret_cast<LLVMOrcIndirectStubsManagerRef
>(const_cast<IndirectStubsManager*>(P)); }
103DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LazyCallThroughManager,inline LazyCallThroughManager *unwrap(LLVMOrcLazyCallThroughManagerRef
P) { return reinterpret_cast<LazyCallThroughManager*>(
P); } inline LLVMOrcLazyCallThroughManagerRef wrap(const LazyCallThroughManager
*P) { return reinterpret_cast<LLVMOrcLazyCallThroughManagerRef
>(const_cast<LazyCallThroughManager*>(P)); }
104 LLVMOrcLazyCallThroughManagerRef)inline LazyCallThroughManager *unwrap(LLVMOrcLazyCallThroughManagerRef
P) { return reinterpret_cast<LazyCallThroughManager*>(
P); } inline LLVMOrcLazyCallThroughManagerRef wrap(const LazyCallThroughManager
*P) { return reinterpret_cast<LLVMOrcLazyCallThroughManagerRef
>(const_cast<LazyCallThroughManager*>(P)); }
105DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLJITBuilder, LLVMOrcLLJITBuilderRef)inline LLJITBuilder *unwrap(LLVMOrcLLJITBuilderRef P) { return
reinterpret_cast<LLJITBuilder*>(P); } inline LLVMOrcLLJITBuilderRef
wrap(const LLJITBuilder *P) { return reinterpret_cast<LLVMOrcLLJITBuilderRef
>(const_cast<LLJITBuilder*>(P)); }
106DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLJIT, LLVMOrcLLJITRef)inline LLJIT *unwrap(LLVMOrcLLJITRef P) { return reinterpret_cast
<LLJIT*>(P); } inline LLVMOrcLLJITRef wrap(const LLJIT *
P) { return reinterpret_cast<LLVMOrcLLJITRef>(const_cast
<LLJIT*>(P)); }
107DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)inline TargetMachine *unwrap(LLVMTargetMachineRef P) { return
reinterpret_cast<TargetMachine*>(P); } inline LLVMTargetMachineRef
wrap(const TargetMachine *P) { return reinterpret_cast<LLVMTargetMachineRef
>(const_cast<TargetMachine*>(P)); }
108
109namespace llvm {
110namespace orc {
111
112class CAPIDefinitionGenerator final : public DefinitionGenerator {
113public:
114 CAPIDefinitionGenerator(
115 void *Ctx,
116 LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction TryToGenerate)
117 : Ctx(Ctx), TryToGenerate(TryToGenerate) {}
118
119 Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
120 JITDylibLookupFlags JDLookupFlags,
121 const SymbolLookupSet &LookupSet) override {
122
123 // Take the lookup state.
124 LLVMOrcLookupStateRef LSR = ::wrap(OrcV2CAPIHelper::extractLookupState(LS));
125
126 // Translate the lookup kind.
127 LLVMOrcLookupKind CLookupKind;
128 switch (K) {
129 case LookupKind::Static:
130 CLookupKind = LLVMOrcLookupKindStatic;
131 break;
132 case LookupKind::DLSym:
133 CLookupKind = LLVMOrcLookupKindDLSym;
134 break;
135 }
136
137 // Translate the JITDylibSearchFlags.
138 LLVMOrcJITDylibLookupFlags CJDLookupFlags;
139 switch (JDLookupFlags) {
140 case JITDylibLookupFlags::MatchExportedSymbolsOnly:
141 CJDLookupFlags = LLVMOrcJITDylibLookupFlagsMatchExportedSymbolsOnly;
142 break;
143 case JITDylibLookupFlags::MatchAllSymbols:
144 CJDLookupFlags = LLVMOrcJITDylibLookupFlagsMatchAllSymbols;
145 break;
146 }
147
148 // Translate the lookup set.
149 std::vector<LLVMOrcCLookupSetElement> CLookupSet;
150 CLookupSet.reserve(LookupSet.size());
151 for (auto &KV : LookupSet) {
152 LLVMOrcSymbolLookupFlags SLF;
153 LLVMOrcSymbolStringPoolEntryRef Name =
154 ::wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(KV.first));
155 switch (KV.second) {
156 case SymbolLookupFlags::RequiredSymbol:
157 SLF = LLVMOrcSymbolLookupFlagsRequiredSymbol;
158 break;
159 case SymbolLookupFlags::WeaklyReferencedSymbol:
160 SLF = LLVMOrcSymbolLookupFlagsWeaklyReferencedSymbol;
161 break;
162 }
163 CLookupSet.push_back({Name, SLF});
164 }
165
166 // Run the C TryToGenerate function.
167 auto Err = unwrap(TryToGenerate(::wrap(this), Ctx, &LSR, CLookupKind,
168 ::wrap(&JD), CJDLookupFlags,
169 CLookupSet.data(), CLookupSet.size()));
170
171 // Restore the lookup state.
172 OrcV2CAPIHelper::resetLookupState(LS, ::unwrap(LSR));
173
174 return Err;
175 }
176
177private:
178 void *Ctx;
179 LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction TryToGenerate;
180};
181
182} // end namespace orc
183} // end namespace llvm
184
185namespace {
186
187class OrcCAPIMaterializationUnit : public llvm::orc::MaterializationUnit {
188public:
189 OrcCAPIMaterializationUnit(
190 std::string Name, SymbolFlagsMap InitialSymbolFlags,
191 SymbolStringPtr InitSymbol, void *Ctx,
192 LLVMOrcMaterializationUnitMaterializeFunction Materialize,
193 LLVMOrcMaterializationUnitDiscardFunction Discard,
194 LLVMOrcMaterializationUnitDestroyFunction Destroy)
195 : llvm::orc::MaterializationUnit(
196 Interface(std::move(InitialSymbolFlags), std::move(InitSymbol))),
197 Name(std::move(Name)), Ctx(Ctx), Materialize(Materialize),
198 Discard(Discard), Destroy(Destroy) {}
199
200 ~OrcCAPIMaterializationUnit() {
201 if (Ctx)
202 Destroy(Ctx);
203 }
204
205 StringRef getName() const override { return Name; }
206
207 void materialize(std::unique_ptr<MaterializationResponsibility> R) override {
208 void *Tmp = Ctx;
209 Ctx = nullptr;
210 Materialize(Tmp, wrap(R.release()));
211 }
212
213private:
214 void discard(const JITDylib &JD, const SymbolStringPtr &Name) override {
215 Discard(Ctx, wrap(&JD), wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(Name)));
216 }
217
218 std::string Name;
219 void *Ctx = nullptr;
220 LLVMOrcMaterializationUnitMaterializeFunction Materialize = nullptr;
221 LLVMOrcMaterializationUnitDiscardFunction Discard = nullptr;
222 LLVMOrcMaterializationUnitDestroyFunction Destroy = nullptr;
223};
224
225static JITSymbolFlags toJITSymbolFlags(LLVMJITSymbolFlags F) {
226
227 JITSymbolFlags JSF;
228
229 if (F.GenericFlags & LLVMJITSymbolGenericFlagsExported)
230 JSF |= JITSymbolFlags::Exported;
231 if (F.GenericFlags & LLVMJITSymbolGenericFlagsWeak)
232 JSF |= JITSymbolFlags::Weak;
233 if (F.GenericFlags & LLVMJITSymbolGenericFlagsCallable)
234 JSF |= JITSymbolFlags::Callable;
235 if (F.GenericFlags & LLVMJITSymbolGenericFlagsMaterializationSideEffectsOnly)
236 JSF |= JITSymbolFlags::MaterializationSideEffectsOnly;
237
238 JSF.getTargetFlags() = F.TargetFlags;
239
240 return JSF;
241}
242
243static LLVMJITSymbolFlags fromJITSymbolFlags(JITSymbolFlags JSF) {
244 LLVMJITSymbolFlags F = {0, 0};
245 if (JSF & JITSymbolFlags::Exported)
246 F.GenericFlags |= LLVMJITSymbolGenericFlagsExported;
247 if (JSF & JITSymbolFlags::Weak)
248 F.GenericFlags |= LLVMJITSymbolGenericFlagsWeak;
249 if (JSF & JITSymbolFlags::Callable)
250 F.GenericFlags |= LLVMJITSymbolGenericFlagsCallable;
251 if (JSF & JITSymbolFlags::MaterializationSideEffectsOnly)
252 F.GenericFlags |= LLVMJITSymbolGenericFlagsMaterializationSideEffectsOnly;
253
254 F.TargetFlags = JSF.getTargetFlags();
255
256 return F;
257}
258
259static SymbolMap toSymbolMap(LLVMOrcCSymbolMapPairs Syms, size_t NumPairs) {
260 SymbolMap SM;
261 for (size_t I = 0; I != NumPairs; ++I) {
262 JITSymbolFlags Flags = toJITSymbolFlags(Syms[I].Sym.Flags);
263 SM[OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(Syms[I].Name))] =
264 JITEvaluatedSymbol(Syms[I].Sym.Address, Flags);
265 }
266 return SM;
267}
268
269static SymbolDependenceMap
270toSymbolDependenceMap(LLVMOrcCDependenceMapPairs Pairs, size_t NumPairs) {
271 SymbolDependenceMap SDM;
272 for (size_t I = 0; I != NumPairs; ++I) {
273 JITDylib *JD = unwrap(Pairs[I].JD);
274 SymbolNameSet Names;
275
276 for (size_t J = 0; J != Pairs[I].Names.Length; ++J) {
277 auto Sym = Pairs[I].Names.Symbols[J];
278 Names.insert(OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(Sym)));
279 }
280 SDM[JD] = Names;
281 }
282 return SDM;
283}
284
285} // end anonymous namespace
286
287void LLVMOrcExecutionSessionSetErrorReporter(
288 LLVMOrcExecutionSessionRef ES, LLVMOrcErrorReporterFunction ReportError,
289 void *Ctx) {
290 unwrap(ES)->setErrorReporter(
291 [=](Error Err) { ReportError(Ctx, wrap(std::move(Err))); });
292}
293
294LLVMOrcSymbolStringPoolRef
295LLVMOrcExecutionSessionGetSymbolStringPool(LLVMOrcExecutionSessionRef ES) {
296 return wrap(
297 unwrap(ES)->getExecutorProcessControl().getSymbolStringPool().get());
298}
299
300void LLVMOrcSymbolStringPoolClearDeadEntries(LLVMOrcSymbolStringPoolRef SSP) {
301 unwrap(SSP)->clearDeadEntries();
302}
303
304LLVMOrcSymbolStringPoolEntryRef
305LLVMOrcExecutionSessionIntern(LLVMOrcExecutionSessionRef ES, const char *Name) {
306 return wrap(
307 OrcV2CAPIHelper::moveFromSymbolStringPtr(unwrap(ES)->intern(Name)));
308}
309
310void LLVMOrcRetainSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S) {
311 OrcV2CAPIHelper::retainPoolEntry(unwrap(S));
312}
313
314void LLVMOrcReleaseSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S) {
315 OrcV2CAPIHelper::releasePoolEntry(unwrap(S));
316}
317
318const char *LLVMOrcSymbolStringPoolEntryStr(LLVMOrcSymbolStringPoolEntryRef S) {
319 return unwrap(S)->getKey().data();
320}
321
322LLVMOrcResourceTrackerRef
323LLVMOrcJITDylibCreateResourceTracker(LLVMOrcJITDylibRef JD) {
324 auto RT = unwrap(JD)->createResourceTracker();
325 // Retain the pointer for the C API client.
326 RT->Retain();
327 return wrap(RT.get());
328}
329
330LLVMOrcResourceTrackerRef
331LLVMOrcJITDylibGetDefaultResourceTracker(LLVMOrcJITDylibRef JD) {
332 auto RT = unwrap(JD)->getDefaultResourceTracker();
333 // Retain the pointer for the C API client.
334 return wrap(RT.get());
335}
336
337void LLVMOrcReleaseResourceTracker(LLVMOrcResourceTrackerRef RT) {
338 ResourceTrackerSP TmpRT(unwrap(RT));
1
Calling constructor for 'IntrusiveRefCntPtr<llvm::orc::ResourceTracker>'
6
Returning from constructor for 'IntrusiveRefCntPtr<llvm::orc::ResourceTracker>'
339 TmpRT->Release();
7
Calling 'ThreadSafeRefCountedBase::Release'
13
Returning; memory was released
340}
14
Calling '~IntrusiveRefCntPtr'
341
342void LLVMOrcResourceTrackerTransferTo(LLVMOrcResourceTrackerRef SrcRT,
343 LLVMOrcResourceTrackerRef DstRT) {
344 ResourceTrackerSP TmpRT(unwrap(SrcRT));
345 TmpRT->transferTo(*unwrap(DstRT));
346}
347
348LLVMErrorRef LLVMOrcResourceTrackerRemove(LLVMOrcResourceTrackerRef RT) {
349 ResourceTrackerSP TmpRT(unwrap(RT));
350 return wrap(TmpRT->remove());
351}
352
353void LLVMOrcDisposeDefinitionGenerator(LLVMOrcDefinitionGeneratorRef DG) {
354 std::unique_ptr<DefinitionGenerator> TmpDG(unwrap(DG));
355}
356
357void LLVMOrcDisposeMaterializationUnit(LLVMOrcMaterializationUnitRef MU) {
358 std::unique_ptr<MaterializationUnit> TmpMU(unwrap(MU));
359}
360
361LLVMOrcMaterializationUnitRef LLVMOrcCreateCustomMaterializationUnit(
362 const char *Name, void *Ctx, LLVMOrcCSymbolFlagsMapPairs Syms,
363 size_t NumSyms, LLVMOrcSymbolStringPoolEntryRef InitSym,
364 LLVMOrcMaterializationUnitMaterializeFunction Materialize,
365 LLVMOrcMaterializationUnitDiscardFunction Discard,
366 LLVMOrcMaterializationUnitDestroyFunction Destroy) {
367 SymbolFlagsMap SFM;
368 for (size_t I = 0; I != NumSyms; ++I)
369 SFM[OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(Syms[I].Name))] =
370 toJITSymbolFlags(Syms[I].Flags);
371
372 auto IS = OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(InitSym));
373
374 return wrap(new OrcCAPIMaterializationUnit(
375 Name, std::move(SFM), std::move(IS), Ctx, Materialize, Discard, Destroy));
376}
377
378LLVMOrcMaterializationUnitRef
379LLVMOrcAbsoluteSymbols(LLVMOrcCSymbolMapPairs Syms, size_t NumPairs) {
380 SymbolMap SM = toSymbolMap(Syms, NumPairs);
381 return wrap(absoluteSymbols(std::move(SM)).release());
382}
383
384LLVMOrcMaterializationUnitRef LLVMOrcLazyReexports(
385 LLVMOrcLazyCallThroughManagerRef LCTM, LLVMOrcIndirectStubsManagerRef ISM,
386 LLVMOrcJITDylibRef SourceJD, LLVMOrcCSymbolAliasMapPairs CallableAliases,
387 size_t NumPairs) {
388
389 SymbolAliasMap SAM;
390 for (size_t I = 0; I != NumPairs; ++I) {
391 auto pair = CallableAliases[I];
392 JITSymbolFlags Flags = toJITSymbolFlags(pair.Entry.Flags);
393 SymbolStringPtr Name =
394 OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(pair.Entry.Name));
395 SAM[OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(pair.Name))] =
396 SymbolAliasMapEntry(Name, Flags);
397 }
398
399 return wrap(lazyReexports(*unwrap(LCTM), *unwrap(ISM), *unwrap(SourceJD),
400 std::move(SAM))
401 .release());
402}
403
404void LLVMOrcDisposeMaterializationResponsibility(
405 LLVMOrcMaterializationResponsibilityRef MR) {
406 std::unique_ptr<MaterializationResponsibility> TmpMR(unwrap(MR));
407}
408
409LLVMOrcJITDylibRef LLVMOrcMaterializationResponsibilityGetTargetDylib(
410 LLVMOrcMaterializationResponsibilityRef MR) {
411 return wrap(&unwrap(MR)->getTargetJITDylib());
412}
413
414LLVMOrcExecutionSessionRef
415LLVMOrcMaterializationResponsibilityGetExecutionSession(
416 LLVMOrcMaterializationResponsibilityRef MR) {
417 return wrap(&unwrap(MR)->getExecutionSession());
418}
419
420LLVMOrcCSymbolFlagsMapPairs LLVMOrcMaterializationResponsibilityGetSymbols(
421 LLVMOrcMaterializationResponsibilityRef MR, size_t *NumPairs) {
422
423 auto Symbols = unwrap(MR)->getSymbols();
424 LLVMOrcCSymbolFlagsMapPairs Result = static_cast<LLVMOrcCSymbolFlagsMapPairs>(
425 safe_malloc(Symbols.size() * sizeof(LLVMOrcCSymbolFlagsMapPair)));
426 size_t I = 0;
427 for (auto const &pair : Symbols) {
428 auto Name = wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(pair.first));
429 auto Flags = pair.second;
430 Result[I] = {Name, fromJITSymbolFlags(Flags)};
431 I++;
432 }
433 *NumPairs = Symbols.size();
434 return Result;
435}
436
437void LLVMOrcDisposeCSymbolFlagsMap(LLVMOrcCSymbolFlagsMapPairs Pairs) {
438 free(Pairs);
439}
440
441LLVMOrcSymbolStringPoolEntryRef
442LLVMOrcMaterializationResponsibilityGetInitializerSymbol(
443 LLVMOrcMaterializationResponsibilityRef MR) {
444 auto Sym = unwrap(MR)->getInitializerSymbol();
445 return wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(Sym));
446}
447
448LLVMOrcSymbolStringPoolEntryRef *
449LLVMOrcMaterializationResponsibilityGetRequestedSymbols(
450 LLVMOrcMaterializationResponsibilityRef MR, size_t *NumSymbols) {
451
452 auto Symbols = unwrap(MR)->getRequestedSymbols();
453 LLVMOrcSymbolStringPoolEntryRef *Result =
454 static_cast<LLVMOrcSymbolStringPoolEntryRef *>(safe_malloc(
455 Symbols.size() * sizeof(LLVMOrcSymbolStringPoolEntryRef)));
456 size_t I = 0;
457 for (auto &Name : Symbols) {
458 Result[I] = wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(Name));
459 I++;
460 }
461 *NumSymbols = Symbols.size();
462 return Result;
463}
464
465void LLVMOrcDisposeSymbols(LLVMOrcSymbolStringPoolEntryRef *Symbols) {
466 free(Symbols);
467}
468
469LLVMErrorRef LLVMOrcMaterializationResponsibilityNotifyResolved(
470 LLVMOrcMaterializationResponsibilityRef MR, LLVMOrcCSymbolMapPairs Symbols,
471 size_t NumPairs) {
472 SymbolMap SM = toSymbolMap(Symbols, NumPairs);
473 return wrap(unwrap(MR)->notifyResolved(std::move(SM)));
474}
475
476LLVMErrorRef LLVMOrcMaterializationResponsibilityNotifyEmitted(
477 LLVMOrcMaterializationResponsibilityRef MR) {
478 return wrap(unwrap(MR)->notifyEmitted());
479}
480
481LLVMErrorRef LLVMOrcMaterializationResponsibilityDefineMaterializing(
482 LLVMOrcMaterializationResponsibilityRef MR,
483 LLVMOrcCSymbolFlagsMapPairs Syms, size_t NumSyms) {
484 SymbolFlagsMap SFM;
485 for (size_t I = 0; I != NumSyms; ++I)
486 SFM[OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(Syms[I].Name))] =
487 toJITSymbolFlags(Syms[I].Flags);
488
489 return wrap(unwrap(MR)->defineMaterializing(std::move(SFM)));
490}
491
492LLVMErrorRef LLVMOrcMaterializationResponsibilityReplace(
493 LLVMOrcMaterializationResponsibilityRef MR,
494 LLVMOrcMaterializationUnitRef MU) {
495 std::unique_ptr<MaterializationUnit> TmpMU(unwrap(MU));
496 return wrap(unwrap(MR)->replace(std::move(TmpMU)));
497}
498
499LLVMErrorRef LLVMOrcMaterializationResponsibilityDelegate(
500 LLVMOrcMaterializationResponsibilityRef MR,
501 LLVMOrcSymbolStringPoolEntryRef *Symbols, size_t NumSymbols,
502 LLVMOrcMaterializationResponsibilityRef *Result) {
503 SymbolNameSet Syms;
504 for (size_t I = 0; I != NumSymbols; I++) {
505 Syms.insert(OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(Symbols[I])));
506 }
507 auto OtherMR = unwrap(MR)->delegate(Syms);
508
509 if (!OtherMR) {
510 return wrap(OtherMR.takeError());
511 }
512 *Result = wrap(OtherMR->release());
513 return LLVMErrorSuccess0;
514}
515
516void LLVMOrcMaterializationResponsibilityAddDependencies(
517 LLVMOrcMaterializationResponsibilityRef MR,
518 LLVMOrcSymbolStringPoolEntryRef Name,
519 LLVMOrcCDependenceMapPairs Dependencies, size_t NumPairs) {
520
521 SymbolDependenceMap SDM = toSymbolDependenceMap(Dependencies, NumPairs);
522 auto Sym = OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(Name));
523 unwrap(MR)->addDependencies(Sym, SDM);
524}
525
526void LLVMOrcMaterializationResponsibilityAddDependenciesForAll(
527 LLVMOrcMaterializationResponsibilityRef MR,
528 LLVMOrcCDependenceMapPairs Dependencies, size_t NumPairs) {
529
530 SymbolDependenceMap SDM = toSymbolDependenceMap(Dependencies, NumPairs);
531 unwrap(MR)->addDependenciesForAll(SDM);
532}
533
534void LLVMOrcMaterializationResponsibilityFailMaterialization(
535 LLVMOrcMaterializationResponsibilityRef MR) {
536 unwrap(MR)->failMaterialization();
537}
538
539void LLVMOrcIRTransformLayerEmit(LLVMOrcIRTransformLayerRef IRLayer,
540 LLVMOrcMaterializationResponsibilityRef MR,
541 LLVMOrcThreadSafeModuleRef TSM) {
542 std::unique_ptr<ThreadSafeModule> TmpTSM(unwrap(TSM));
543 unwrap(IRLayer)->emit(
544 std::unique_ptr<MaterializationResponsibility>(unwrap(MR)),
545 std::move(*TmpTSM));
546}
547
548LLVMOrcJITDylibRef
549LLVMOrcExecutionSessionCreateBareJITDylib(LLVMOrcExecutionSessionRef ES,
550 const char *Name) {
551 return wrap(&unwrap(ES)->createBareJITDylib(Name));
552}
553
554LLVMErrorRef
555LLVMOrcExecutionSessionCreateJITDylib(LLVMOrcExecutionSessionRef ES,
556 LLVMOrcJITDylibRef *Result,
557 const char *Name) {
558 auto JD = unwrap(ES)->createJITDylib(Name);
559 if (!JD)
560 return wrap(JD.takeError());
561 *Result = wrap(&*JD);
562 return LLVMErrorSuccess0;
563}
564
565LLVMOrcJITDylibRef
566LLVMOrcExecutionSessionGetJITDylibByName(LLVMOrcExecutionSessionRef ES,
567 const char *Name) {
568 return wrap(unwrap(ES)->getJITDylibByName(Name));
569}
570
571LLVMErrorRef LLVMOrcJITDylibDefine(LLVMOrcJITDylibRef JD,
572 LLVMOrcMaterializationUnitRef MU) {
573 std::unique_ptr<MaterializationUnit> TmpMU(unwrap(MU));
574
575 if (auto Err = unwrap(JD)->define(TmpMU)) {
576 TmpMU.release();
577 return wrap(std::move(Err));
578 }
579 return LLVMErrorSuccess0;
580}
581
582LLVMErrorRef LLVMOrcJITDylibClear(LLVMOrcJITDylibRef JD) {
583 return wrap(unwrap(JD)->clear());
584}
585
586void LLVMOrcJITDylibAddGenerator(LLVMOrcJITDylibRef JD,
587 LLVMOrcDefinitionGeneratorRef DG) {
588 unwrap(JD)->addGenerator(std::unique_ptr<DefinitionGenerator>(unwrap(DG)));
589}
590
591LLVMOrcDefinitionGeneratorRef LLVMOrcCreateCustomCAPIDefinitionGenerator(
592 LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction F, void *Ctx) {
593 auto DG = std::make_unique<CAPIDefinitionGenerator>(Ctx, F);
594 return wrap(DG.release());
595}
596
597LLVMErrorRef LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess(
598 LLVMOrcDefinitionGeneratorRef *Result, char GlobalPrefix,
599 LLVMOrcSymbolPredicate Filter, void *FilterCtx) {
600 assert(Result && "Result can not be null")(static_cast <bool> (Result && "Result can not be null"
) ? void (0) : __assert_fail ("Result && \"Result can not be null\""
, "llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp", 600, __extension__
__PRETTY_FUNCTION__))
;
601 assert((Filter || !FilterCtx) &&(static_cast <bool> ((Filter || !FilterCtx) && "if Filter is null then FilterCtx must also be null"
) ? void (0) : __assert_fail ("(Filter || !FilterCtx) && \"if Filter is null then FilterCtx must also be null\""
, "llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp", 602, __extension__
__PRETTY_FUNCTION__))
602 "if Filter is null then FilterCtx must also be null")(static_cast <bool> ((Filter || !FilterCtx) && "if Filter is null then FilterCtx must also be null"
) ? void (0) : __assert_fail ("(Filter || !FilterCtx) && \"if Filter is null then FilterCtx must also be null\""
, "llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp", 602, __extension__
__PRETTY_FUNCTION__))
;
603
604 DynamicLibrarySearchGenerator::SymbolPredicate Pred;
605 if (Filter)
606 Pred = [=](const SymbolStringPtr &Name) -> bool {
607 return Filter(FilterCtx, wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(Name)));
608 };
609
610 auto ProcessSymsGenerator =
611 DynamicLibrarySearchGenerator::GetForCurrentProcess(GlobalPrefix, Pred);
612
613 if (!ProcessSymsGenerator) {
614 *Result = nullptr;
615 return wrap(ProcessSymsGenerator.takeError());
616 }
617
618 *Result = wrap(ProcessSymsGenerator->release());
619 return LLVMErrorSuccess0;
620}
621
622LLVMErrorRef LLVMOrcCreateDynamicLibrarySearchGeneratorForPath(
623 LLVMOrcDefinitionGeneratorRef *Result, const char *FileName,
624 char GlobalPrefix, LLVMOrcSymbolPredicate Filter, void *FilterCtx) {
625 assert(Result && "Result can not be null")(static_cast <bool> (Result && "Result can not be null"
) ? void (0) : __assert_fail ("Result && \"Result can not be null\""
, "llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp", 625, __extension__
__PRETTY_FUNCTION__))
;
626 assert(FileName && "FileName can not be null")(static_cast <bool> (FileName && "FileName can not be null"
) ? void (0) : __assert_fail ("FileName && \"FileName can not be null\""
, "llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp", 626, __extension__
__PRETTY_FUNCTION__))
;
627 assert((Filter || !FilterCtx) &&(static_cast <bool> ((Filter || !FilterCtx) && "if Filter is null then FilterCtx must also be null"
) ? void (0) : __assert_fail ("(Filter || !FilterCtx) && \"if Filter is null then FilterCtx must also be null\""
, "llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp", 628, __extension__
__PRETTY_FUNCTION__))
628 "if Filter is null then FilterCtx must also be null")(static_cast <bool> ((Filter || !FilterCtx) && "if Filter is null then FilterCtx must also be null"
) ? void (0) : __assert_fail ("(Filter || !FilterCtx) && \"if Filter is null then FilterCtx must also be null\""
, "llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp", 628, __extension__
__PRETTY_FUNCTION__))
;
629
630 DynamicLibrarySearchGenerator::SymbolPredicate Pred;
631 if (Filter)
632 Pred = [=](const SymbolStringPtr &Name) -> bool {
633 return Filter(FilterCtx, wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(Name)));
634 };
635
636 auto LibrarySymsGenerator =
637 DynamicLibrarySearchGenerator::Load(FileName, GlobalPrefix, Pred);
638
639 if (!LibrarySymsGenerator) {
640 *Result = nullptr;
641 return wrap(LibrarySymsGenerator.takeError());
642 }
643
644 *Result = wrap(LibrarySymsGenerator->release());
645 return LLVMErrorSuccess0;
646}
647
648LLVMErrorRef LLVMOrcCreateStaticLibrarySearchGeneratorForPath(
649 LLVMOrcDefinitionGeneratorRef *Result, LLVMOrcObjectLayerRef ObjLayer,
650 const char *FileName, const char *TargetTriple) {
651 assert(Result && "Result can not be null")(static_cast <bool> (Result && "Result can not be null"
) ? void (0) : __assert_fail ("Result && \"Result can not be null\""
, "llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp", 651, __extension__
__PRETTY_FUNCTION__))
;
652 assert(FileName && "Filename can not be null")(static_cast <bool> (FileName && "Filename can not be null"
) ? void (0) : __assert_fail ("FileName && \"Filename can not be null\""
, "llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp", 652, __extension__
__PRETTY_FUNCTION__))
;
653 assert(ObjLayer && "ObjectLayer can not be null")(static_cast <bool> (ObjLayer && "ObjectLayer can not be null"
) ? void (0) : __assert_fail ("ObjLayer && \"ObjectLayer can not be null\""
, "llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp", 653, __extension__
__PRETTY_FUNCTION__))
;
654
655 if (TargetTriple) {
656 auto TT = Triple(TargetTriple);
657 auto LibrarySymsGenerator =
658 StaticLibraryDefinitionGenerator::Load(*unwrap(ObjLayer), FileName, TT);
659 if (!LibrarySymsGenerator) {
660 *Result = nullptr;
661 return wrap(LibrarySymsGenerator.takeError());
662 }
663 *Result = wrap(LibrarySymsGenerator->release());
664 return LLVMErrorSuccess0;
665 } else {
666 auto LibrarySymsGenerator =
667 StaticLibraryDefinitionGenerator::Load(*unwrap(ObjLayer), FileName);
668 if (!LibrarySymsGenerator) {
669 *Result = nullptr;
670 return wrap(LibrarySymsGenerator.takeError());
671 }
672 *Result = wrap(LibrarySymsGenerator->release());
673 return LLVMErrorSuccess0;
674 }
675}
676
677LLVMOrcThreadSafeContextRef LLVMOrcCreateNewThreadSafeContext(void) {
678 return wrap(new ThreadSafeContext(std::make_unique<LLVMContext>()));
679}
680
681LLVMContextRef
682LLVMOrcThreadSafeContextGetContext(LLVMOrcThreadSafeContextRef TSCtx) {
683 return wrap(unwrap(TSCtx)->getContext());
684}
685
686void LLVMOrcDisposeThreadSafeContext(LLVMOrcThreadSafeContextRef TSCtx) {
687 delete unwrap(TSCtx);
688}
689
690LLVMErrorRef
691LLVMOrcThreadSafeModuleWithModuleDo(LLVMOrcThreadSafeModuleRef TSM,
692 LLVMOrcGenericIRModuleOperationFunction F,
693 void *Ctx) {
694 return wrap(unwrap(TSM)->withModuleDo(
695 [&](Module &M) { return unwrap(F(Ctx, wrap(&M))); }));
696}
697
698LLVMOrcThreadSafeModuleRef
699LLVMOrcCreateNewThreadSafeModule(LLVMModuleRef M,
700 LLVMOrcThreadSafeContextRef TSCtx) {
701 return wrap(
702 new ThreadSafeModule(std::unique_ptr<Module>(unwrap(M)), *unwrap(TSCtx)));
703}
704
705void LLVMOrcDisposeThreadSafeModule(LLVMOrcThreadSafeModuleRef TSM) {
706 delete unwrap(TSM);
707}
708
709LLVMErrorRef LLVMOrcJITTargetMachineBuilderDetectHost(
710 LLVMOrcJITTargetMachineBuilderRef *Result) {
711 assert(Result && "Result can not be null")(static_cast <bool> (Result && "Result can not be null"
) ? void (0) : __assert_fail ("Result && \"Result can not be null\""
, "llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp", 711, __extension__
__PRETTY_FUNCTION__))
;
712
713 auto JTMB = JITTargetMachineBuilder::detectHost();
714 if (!JTMB) {
715 Result = nullptr;
716 return wrap(JTMB.takeError());
717 }
718
719 *Result = wrap(new JITTargetMachineBuilder(std::move(*JTMB)));
720 return LLVMErrorSuccess0;
721}
722
723LLVMOrcJITTargetMachineBuilderRef
724LLVMOrcJITTargetMachineBuilderCreateFromTargetMachine(LLVMTargetMachineRef TM) {
725 auto *TemplateTM = unwrap(TM);
726
727 auto JTMB =
728 std::make_unique<JITTargetMachineBuilder>(TemplateTM->getTargetTriple());
729
730 (*JTMB)
731 .setCPU(TemplateTM->getTargetCPU().str())
732 .setRelocationModel(TemplateTM->getRelocationModel())
733 .setCodeModel(TemplateTM->getCodeModel())
734 .setCodeGenOptLevel(TemplateTM->getOptLevel())
735 .setFeatures(TemplateTM->getTargetFeatureString())
736 .setOptions(TemplateTM->Options);
737
738 LLVMDisposeTargetMachine(TM);
739
740 return wrap(JTMB.release());
741}
742
743void LLVMOrcDisposeJITTargetMachineBuilder(
744 LLVMOrcJITTargetMachineBuilderRef JTMB) {
745 delete unwrap(JTMB);
746}
747
748char *LLVMOrcJITTargetMachineBuilderGetTargetTriple(
749 LLVMOrcJITTargetMachineBuilderRef JTMB) {
750 auto Tmp = unwrap(JTMB)->getTargetTriple().str();
751 char *TargetTriple = (char *)malloc(Tmp.size() + 1);
752 strcpy(TargetTriple, Tmp.c_str());
753 return TargetTriple;
754}
755
756void LLVMOrcJITTargetMachineBuilderSetTargetTriple(
757 LLVMOrcJITTargetMachineBuilderRef JTMB, const char *TargetTriple) {
758 unwrap(JTMB)->getTargetTriple() = Triple(TargetTriple);
759}
760
761LLVMErrorRef LLVMOrcObjectLayerAddObjectFile(LLVMOrcObjectLayerRef ObjLayer,
762 LLVMOrcJITDylibRef JD,
763 LLVMMemoryBufferRef ObjBuffer) {
764 return wrap(unwrap(ObjLayer)->add(
765 *unwrap(JD), std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer))));
766}
767
768LLVMErrorRef LLVMOrcLLJITAddObjectFileWithRT(LLVMOrcObjectLayerRef ObjLayer,
769 LLVMOrcResourceTrackerRef RT,
770 LLVMMemoryBufferRef ObjBuffer) {
771 return wrap(
772 unwrap(ObjLayer)->add(ResourceTrackerSP(unwrap(RT)),
773 std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer))));
774}
775
776void LLVMOrcObjectLayerEmit(LLVMOrcObjectLayerRef ObjLayer,
777 LLVMOrcMaterializationResponsibilityRef R,
778 LLVMMemoryBufferRef ObjBuffer) {
779 unwrap(ObjLayer)->emit(
780 std::unique_ptr<MaterializationResponsibility>(unwrap(R)),
781 std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer)));
782}
783
784void LLVMOrcDisposeObjectLayer(LLVMOrcObjectLayerRef ObjLayer) {
785 delete unwrap(ObjLayer);
786}
787
788void LLVMOrcIRTransformLayerSetTransform(
789 LLVMOrcIRTransformLayerRef IRTransformLayer,
790 LLVMOrcIRTransformLayerTransformFunction TransformFunction, void *Ctx) {
791 unwrap(IRTransformLayer)
792 ->setTransform(
793 [=](ThreadSafeModule TSM,
794 MaterializationResponsibility &R) -> Expected<ThreadSafeModule> {
795 LLVMOrcThreadSafeModuleRef TSMRef =
796 wrap(new ThreadSafeModule(std::move(TSM)));
797 if (LLVMErrorRef Err = TransformFunction(Ctx, &TSMRef, wrap(&R))) {
798 assert(!TSMRef && "TSMRef was not reset to null on error")(static_cast <bool> (!TSMRef && "TSMRef was not reset to null on error"
) ? void (0) : __assert_fail ("!TSMRef && \"TSMRef was not reset to null on error\""
, "llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp", 798, __extension__
__PRETTY_FUNCTION__))
;
799 return unwrap(Err);
800 }
801 return std::move(*unwrap(TSMRef));
802 });
803}
804
805void LLVMOrcObjectTransformLayerSetTransform(
806 LLVMOrcObjectTransformLayerRef ObjTransformLayer,
807 LLVMOrcObjectTransformLayerTransformFunction TransformFunction, void *Ctx) {
808 unwrap(ObjTransformLayer)
809 ->setTransform([TransformFunction, Ctx](std::unique_ptr<MemoryBuffer> Obj)
810 -> Expected<std::unique_ptr<MemoryBuffer>> {
811 LLVMMemoryBufferRef ObjBuffer = wrap(Obj.release());
812 if (LLVMErrorRef Err = TransformFunction(Ctx, &ObjBuffer)) {
813 assert(!ObjBuffer && "ObjBuffer was not reset to null on error")(static_cast <bool> (!ObjBuffer && "ObjBuffer was not reset to null on error"
) ? void (0) : __assert_fail ("!ObjBuffer && \"ObjBuffer was not reset to null on error\""
, "llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp", 813, __extension__
__PRETTY_FUNCTION__))
;
814 return unwrap(Err);
815 }
816 return std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer));
817 });
818}
819
820LLVMOrcDumpObjectsRef LLVMOrcCreateDumpObjects(const char *DumpDir,
821 const char *IdentifierOverride) {
822 assert(DumpDir && "DumpDir should not be null")(static_cast <bool> (DumpDir && "DumpDir should not be null"
) ? void (0) : __assert_fail ("DumpDir && \"DumpDir should not be null\""
, "llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp", 822, __extension__
__PRETTY_FUNCTION__))
;
823 assert(IdentifierOverride && "IdentifierOverride should not be null")(static_cast <bool> (IdentifierOverride && "IdentifierOverride should not be null"
) ? void (0) : __assert_fail ("IdentifierOverride && \"IdentifierOverride should not be null\""
, "llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp", 823, __extension__
__PRETTY_FUNCTION__))
;
824 return wrap(new DumpObjects(DumpDir, IdentifierOverride));
825}
826
827void LLVMOrcDisposeDumpObjects(LLVMOrcDumpObjectsRef DumpObjects) {
828 delete unwrap(DumpObjects);
829}
830
831LLVMErrorRef LLVMOrcDumpObjects_CallOperator(LLVMOrcDumpObjectsRef DumpObjects,
832 LLVMMemoryBufferRef *ObjBuffer) {
833 std::unique_ptr<MemoryBuffer> OB(unwrap(*ObjBuffer));
834 if (auto Result = (*unwrap(DumpObjects))(std::move(OB))) {
835 *ObjBuffer = wrap(Result->release());
836 return LLVMErrorSuccess0;
837 } else {
838 *ObjBuffer = nullptr;
839 return wrap(Result.takeError());
840 }
841}
842
843LLVMOrcLLJITBuilderRef LLVMOrcCreateLLJITBuilder(void) {
844 return wrap(new LLJITBuilder());
845}
846
847void LLVMOrcDisposeLLJITBuilder(LLVMOrcLLJITBuilderRef Builder) {
848 delete unwrap(Builder);
849}
850
851void LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(
852 LLVMOrcLLJITBuilderRef Builder, LLVMOrcJITTargetMachineBuilderRef JTMB) {
853 unwrap(Builder)->setJITTargetMachineBuilder(std::move(*unwrap(JTMB)));
854 LLVMOrcDisposeJITTargetMachineBuilder(JTMB);
855}
856
857void LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator(
858 LLVMOrcLLJITBuilderRef Builder,
859 LLVMOrcLLJITBuilderObjectLinkingLayerCreatorFunction F, void *Ctx) {
860 unwrap(Builder)->setObjectLinkingLayerCreator(
861 [=](ExecutionSession &ES, const Triple &TT) {
862 auto TTStr = TT.str();
863 return std::unique_ptr<ObjectLayer>(
864 unwrap(F(Ctx, wrap(&ES), TTStr.c_str())));
865 });
866}
867
868LLVMErrorRef LLVMOrcCreateLLJIT(LLVMOrcLLJITRef *Result,
869 LLVMOrcLLJITBuilderRef Builder) {
870 assert(Result && "Result can not be null")(static_cast <bool> (Result && "Result can not be null"
) ? void (0) : __assert_fail ("Result && \"Result can not be null\""
, "llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp", 870, __extension__
__PRETTY_FUNCTION__))
;
871
872 if (!Builder)
873 Builder = LLVMOrcCreateLLJITBuilder();
874
875 auto J = unwrap(Builder)->create();
876 LLVMOrcDisposeLLJITBuilder(Builder);
877
878 if (!J) {
879 Result = nullptr;
880 return wrap(J.takeError());
881 }
882
883 *Result = wrap(J->release());
884 return LLVMErrorSuccess0;
885}
886
887LLVMErrorRef LLVMOrcDisposeLLJIT(LLVMOrcLLJITRef J) {
888 delete unwrap(J);
889 return LLVMErrorSuccess0;
890}
891
892LLVMOrcExecutionSessionRef LLVMOrcLLJITGetExecutionSession(LLVMOrcLLJITRef J) {
893 return wrap(&unwrap(J)->getExecutionSession());
894}
895
896LLVMOrcJITDylibRef LLVMOrcLLJITGetMainJITDylib(LLVMOrcLLJITRef J) {
897 return wrap(&unwrap(J)->getMainJITDylib());
898}
899
900const char *LLVMOrcLLJITGetTripleString(LLVMOrcLLJITRef J) {
901 return unwrap(J)->getTargetTriple().str().c_str();
902}
903
904char LLVMOrcLLJITGetGlobalPrefix(LLVMOrcLLJITRef J) {
905 return unwrap(J)->getDataLayout().getGlobalPrefix();
906}
907
908LLVMOrcSymbolStringPoolEntryRef
909LLVMOrcLLJITMangleAndIntern(LLVMOrcLLJITRef J, const char *UnmangledName) {
910 return wrap(OrcV2CAPIHelper::moveFromSymbolStringPtr(
911 unwrap(J)->mangleAndIntern(UnmangledName)));
912}
913
914LLVMErrorRef LLVMOrcLLJITAddObjectFile(LLVMOrcLLJITRef J, LLVMOrcJITDylibRef JD,
915 LLVMMemoryBufferRef ObjBuffer) {
916 return wrap(unwrap(J)->addObjectFile(
917 *unwrap(JD), std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer))));
918}
919
920LLVMErrorRef LLVMOrcLLJITAddObjectFileWithRT(LLVMOrcLLJITRef J,
921 LLVMOrcResourceTrackerRef RT,
922 LLVMMemoryBufferRef ObjBuffer) {
923 return wrap(unwrap(J)->addObjectFile(
924 ResourceTrackerSP(unwrap(RT)),
925 std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer))));
926}
927
928LLVMErrorRef LLVMOrcLLJITAddLLVMIRModule(LLVMOrcLLJITRef J,
929 LLVMOrcJITDylibRef JD,
930 LLVMOrcThreadSafeModuleRef TSM) {
931 std::unique_ptr<ThreadSafeModule> TmpTSM(unwrap(TSM));
932 return wrap(unwrap(J)->addIRModule(*unwrap(JD), std::move(*TmpTSM)));
933}
934
935LLVMErrorRef LLVMOrcLLJITAddLLVMIRModuleWithRT(LLVMOrcLLJITRef J,
936 LLVMOrcResourceTrackerRef RT,
937 LLVMOrcThreadSafeModuleRef TSM) {
938 std::unique_ptr<ThreadSafeModule> TmpTSM(unwrap(TSM));
939 return wrap(unwrap(J)->addIRModule(ResourceTrackerSP(unwrap(RT)),
940 std::move(*TmpTSM)));
941}
942
943LLVMErrorRef LLVMOrcLLJITLookup(LLVMOrcLLJITRef J,
944 LLVMOrcJITTargetAddress *Result,
945 const char *Name) {
946 assert(Result && "Result can not be null")(static_cast <bool> (Result && "Result can not be null"
) ? void (0) : __assert_fail ("Result && \"Result can not be null\""
, "llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp", 946, __extension__
__PRETTY_FUNCTION__))
;
947
948 auto Sym = unwrap(J)->lookup(Name);
949 if (!Sym) {
950 *Result = 0;
951 return wrap(Sym.takeError());
952 }
953
954 *Result = Sym->getAddress();
955 return LLVMErrorSuccess0;
956}
957
958LLVMOrcObjectLayerRef LLVMOrcLLJITGetObjLinkingLayer(LLVMOrcLLJITRef J) {
959 return wrap(&unwrap(J)->getObjLinkingLayer());
960}
961
962LLVMOrcObjectTransformLayerRef
963LLVMOrcLLJITGetObjTransformLayer(LLVMOrcLLJITRef J) {
964 return wrap(&unwrap(J)->getObjTransformLayer());
965}
966
967LLVMOrcObjectLayerRef
968LLVMOrcCreateRTDyldObjectLinkingLayerWithSectionMemoryManager(
969 LLVMOrcExecutionSessionRef ES) {
970 assert(ES && "ES must not be null")(static_cast <bool> (ES && "ES must not be null"
) ? void (0) : __assert_fail ("ES && \"ES must not be null\""
, "llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp", 970, __extension__
__PRETTY_FUNCTION__))
;
971 return wrap(new RTDyldObjectLinkingLayer(
972 *unwrap(ES), [] { return std::make_unique<SectionMemoryManager>(); }));
973}
974
975void LLVMOrcRTDyldObjectLinkingLayerRegisterJITEventListener(
976 LLVMOrcObjectLayerRef RTDyldObjLinkingLayer,
977 LLVMJITEventListenerRef Listener) {
978 assert(RTDyldObjLinkingLayer && "RTDyldObjLinkingLayer must not be null")(static_cast <bool> (RTDyldObjLinkingLayer && "RTDyldObjLinkingLayer must not be null"
) ? void (0) : __assert_fail ("RTDyldObjLinkingLayer && \"RTDyldObjLinkingLayer must not be null\""
, "llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp", 978, __extension__
__PRETTY_FUNCTION__))
;
979 assert(Listener && "Listener must not be null")(static_cast <bool> (Listener && "Listener must not be null"
) ? void (0) : __assert_fail ("Listener && \"Listener must not be null\""
, "llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp", 979, __extension__
__PRETTY_FUNCTION__))
;
980 reinterpret_cast<RTDyldObjectLinkingLayer *>(unwrap(RTDyldObjLinkingLayer))
981 ->registerJITEventListener(*unwrap(Listener));
982}
983
984LLVMOrcIRTransformLayerRef LLVMOrcLLJITGetIRTransformLayer(LLVMOrcLLJITRef J) {
985 return wrap(&unwrap(J)->getIRTransformLayer());
986}
987
988const char *LLVMOrcLLJITGetDataLayoutStr(LLVMOrcLLJITRef J) {
989 return unwrap(J)->getDataLayout().getStringRepresentation().c_str();
990}
991
992LLVMOrcIndirectStubsManagerRef
993LLVMOrcCreateLocalIndirectStubsManager(const char *TargetTriple) {
994 auto builder = createLocalIndirectStubsManagerBuilder(Triple(TargetTriple));
995 return wrap(builder().release());
996}
997
998void LLVMOrcDisposeIndirectStubsManager(LLVMOrcIndirectStubsManagerRef ISM) {
999 std::unique_ptr<IndirectStubsManager> TmpISM(unwrap(ISM));
1000}
1001
1002LLVMErrorRef LLVMOrcCreateLocalLazyCallThroughManager(
1003 const char *TargetTriple, LLVMOrcExecutionSessionRef ES,
1004 LLVMOrcJITTargetAddress ErrorHandlerAddr,
1005 LLVMOrcLazyCallThroughManagerRef *Result) {
1006 auto LCTM = createLocalLazyCallThroughManager(Triple(TargetTriple),
1007 *unwrap(ES), ErrorHandlerAddr);
1008
1009 if (!LCTM)
1010 return wrap(LCTM.takeError());
1011 *Result = wrap(LCTM->release());
1012 return LLVMErrorSuccess0;
1013}
1014
1015void LLVMOrcDisposeLazyCallThroughManager(
1016 LLVMOrcLazyCallThroughManagerRef LCM) {
1017 std::unique_ptr<LazyCallThroughManager> TmpLCM(unwrap(LCM));
1018}

/build/llvm-toolchain-snapshot-14~++20220116100644+5f782d25a742/llvm/include/llvm/ADT/IntrusiveRefCntPtr.h

1//==- llvm/ADT/IntrusiveRefCntPtr.h - Smart Refcounting Pointer --*- C++ -*-==//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the RefCountedBase, ThreadSafeRefCountedBase, and
10// IntrusiveRefCntPtr classes.
11//
12// IntrusiveRefCntPtr is a smart pointer to an object which maintains a
13// reference count. (ThreadSafe)RefCountedBase is a mixin class that adds a
14// refcount member variable and methods for updating the refcount. An object
15// that inherits from (ThreadSafe)RefCountedBase deletes itself when its
16// refcount hits zero.
17//
18// For example:
19//
20// class MyClass : public RefCountedBase<MyClass> {};
21//
22// void foo() {
23// // Constructing an IntrusiveRefCntPtr increases the pointee's refcount by
24// // 1 (from 0 in this case).
25// IntrusiveRefCntPtr<MyClass> Ptr1(new MyClass());
26//
27// // Copying an IntrusiveRefCntPtr increases the pointee's refcount by 1.
28// IntrusiveRefCntPtr<MyClass> Ptr2(Ptr1);
29//
30// // Constructing an IntrusiveRefCntPtr has no effect on the object's
31// // refcount. After a move, the moved-from pointer is null.
32// IntrusiveRefCntPtr<MyClass> Ptr3(std::move(Ptr1));
33// assert(Ptr1 == nullptr);
34//
35// // Clearing an IntrusiveRefCntPtr decreases the pointee's refcount by 1.
36// Ptr2.reset();
37//
38// // The object deletes itself when we return from the function, because
39// // Ptr3's destructor decrements its refcount to 0.
40// }
41//
42// You can use IntrusiveRefCntPtr with isa<T>(), dyn_cast<T>(), etc.:
43//
44// IntrusiveRefCntPtr<MyClass> Ptr(new MyClass());
45// OtherClass *Other = dyn_cast<OtherClass>(Ptr); // Ptr.get() not required
46//
47// IntrusiveRefCntPtr works with any class that
48//
49// - inherits from (ThreadSafe)RefCountedBase,
50// - has Retain() and Release() methods, or
51// - specializes IntrusiveRefCntPtrInfo.
52//
53//===----------------------------------------------------------------------===//
54
55#ifndef LLVM_ADT_INTRUSIVEREFCNTPTR_H
56#define LLVM_ADT_INTRUSIVEREFCNTPTR_H
57
58#include <atomic>
59#include <cassert>
60#include <cstddef>
61#include <memory>
62
63namespace llvm {
64
65/// A CRTP mixin class that adds reference counting to a type.
66///
67/// The lifetime of an object which inherits from RefCountedBase is managed by
68/// calls to Release() and Retain(), which increment and decrement the object's
69/// refcount, respectively. When a Release() call decrements the refcount to 0,
70/// the object deletes itself.
71template <class Derived> class RefCountedBase {
72 mutable unsigned RefCount = 0;
73
74protected:
75 RefCountedBase() = default;
76 RefCountedBase(const RefCountedBase &) {}
77 RefCountedBase &operator=(const RefCountedBase &) = delete;
78
79#ifndef NDEBUG
80 ~RefCountedBase() {
81 assert(RefCount == 0 &&(static_cast <bool> (RefCount == 0 && "Destruction occured when there are still references to this."
) ? void (0) : __assert_fail ("RefCount == 0 && \"Destruction occured when there are still references to this.\""
, "llvm/include/llvm/ADT/IntrusiveRefCntPtr.h", 82, __extension__
__PRETTY_FUNCTION__))
82 "Destruction occured when there are still references to this.")(static_cast <bool> (RefCount == 0 && "Destruction occured when there are still references to this."
) ? void (0) : __assert_fail ("RefCount == 0 && \"Destruction occured when there are still references to this.\""
, "llvm/include/llvm/ADT/IntrusiveRefCntPtr.h", 82, __extension__
__PRETTY_FUNCTION__))
;
83 }
84#else
85 // Default the destructor in release builds, A trivial destructor may enable
86 // better codegen.
87 ~RefCountedBase() = default;
88#endif
89
90public:
91 void Retain() const { ++RefCount; }
92
93 void Release() const {
94 assert(RefCount > 0 && "Reference count is already zero.")(static_cast <bool> (RefCount > 0 && "Reference count is already zero."
) ? void (0) : __assert_fail ("RefCount > 0 && \"Reference count is already zero.\""
, "llvm/include/llvm/ADT/IntrusiveRefCntPtr.h", 94, __extension__
__PRETTY_FUNCTION__))
;
95 if (--RefCount == 0)
96 delete static_cast<const Derived *>(this);
97 }
98};
99
100/// A thread-safe version of \c RefCountedBase.
101template <class Derived> class ThreadSafeRefCountedBase {
102 mutable std::atomic<int> RefCount{0};
103
104protected:
105 ThreadSafeRefCountedBase() = default;
106 ThreadSafeRefCountedBase(const ThreadSafeRefCountedBase &) {}
107 ThreadSafeRefCountedBase &
108 operator=(const ThreadSafeRefCountedBase &) = delete;
109
110#ifndef NDEBUG
111 ~ThreadSafeRefCountedBase() {
112 assert(RefCount == 0 &&(static_cast <bool> (RefCount == 0 && "Destruction occured when there are still references to this."
) ? void (0) : __assert_fail ("RefCount == 0 && \"Destruction occured when there are still references to this.\""
, "llvm/include/llvm/ADT/IntrusiveRefCntPtr.h", 113, __extension__
__PRETTY_FUNCTION__))
113 "Destruction occured when there are still references to this.")(static_cast <bool> (RefCount == 0 && "Destruction occured when there are still references to this."
) ? void (0) : __assert_fail ("RefCount == 0 && \"Destruction occured when there are still references to this.\""
, "llvm/include/llvm/ADT/IntrusiveRefCntPtr.h", 113, __extension__
__PRETTY_FUNCTION__))
;
114 }
115#else
116 // Default the destructor in release builds, A trivial destructor may enable
117 // better codegen.
118 ~ThreadSafeRefCountedBase() = default;
119#endif
120
121public:
122 void Retain() const { RefCount.fetch_add(1, std::memory_order_relaxed); }
123
124 void Release() const {
125 int NewRefCount = RefCount.fetch_sub(1, std::memory_order_acq_rel) - 1;
126 assert(NewRefCount >= 0 && "Reference count was already zero.")(static_cast <bool> (NewRefCount >= 0 && "Reference count was already zero."
) ? void (0) : __assert_fail ("NewRefCount >= 0 && \"Reference count was already zero.\""
, "llvm/include/llvm/ADT/IntrusiveRefCntPtr.h", 126, __extension__
__PRETTY_FUNCTION__))
;
8
Assuming 'NewRefCount' is >= 0
9
'?' condition is true
127 if (NewRefCount == 0)
10
Assuming 'NewRefCount' is equal to 0
11
Taking true branch
128 delete static_cast<const Derived *>(this);
12
Memory is released
129 }
130};
131
132/// Class you can specialize to provide custom retain/release functionality for
133/// a type.
134///
135/// Usually specializing this class is not necessary, as IntrusiveRefCntPtr
136/// works with any type which defines Retain() and Release() functions -- you
137/// can define those functions yourself if RefCountedBase doesn't work for you.
138///
139/// One case when you might want to specialize this type is if you have
140/// - Foo.h defines type Foo and includes Bar.h, and
141/// - Bar.h uses IntrusiveRefCntPtr<Foo> in inline functions.
142///
143/// Because Foo.h includes Bar.h, Bar.h can't include Foo.h in order to pull in
144/// the declaration of Foo. Without the declaration of Foo, normally Bar.h
145/// wouldn't be able to use IntrusiveRefCntPtr<Foo>, which wants to call
146/// T::Retain and T::Release.
147///
148/// To resolve this, Bar.h could include a third header, FooFwd.h, which
149/// forward-declares Foo and specializes IntrusiveRefCntPtrInfo<Foo>. Then
150/// Bar.h could use IntrusiveRefCntPtr<Foo>, although it still couldn't call any
151/// functions on Foo itself, because Foo would be an incomplete type.
152template <typename T> struct IntrusiveRefCntPtrInfo {
153 static void retain(T *obj) { obj->Retain(); }
154 static void release(T *obj) { obj->Release(); }
155};
156
157/// A smart pointer to a reference-counted object that inherits from
158/// RefCountedBase or ThreadSafeRefCountedBase.
159///
160/// This class increments its pointee's reference count when it is created, and
161/// decrements its refcount when it's destroyed (or is changed to point to a
162/// different object).
163template <typename T> class IntrusiveRefCntPtr {
164 T *Obj = nullptr;
165
166public:
167 using element_type = T;
168
169 explicit IntrusiveRefCntPtr() = default;
170 IntrusiveRefCntPtr(T *obj) : Obj(obj) { retain(); }
2
Calling 'IntrusiveRefCntPtr::retain'
5
Returning from 'IntrusiveRefCntPtr::retain'
171 IntrusiveRefCntPtr(const IntrusiveRefCntPtr &S) : Obj(S.Obj) { retain(); }
172 IntrusiveRefCntPtr(IntrusiveRefCntPtr &&S) : Obj(S.Obj) { S.Obj = nullptr; }
173
174 template <class X,
175 std::enable_if_t<std::is_convertible<X *, T *>::value, bool> = true>
176 IntrusiveRefCntPtr(IntrusiveRefCntPtr<X> S) : Obj(S.get()) {
177 S.Obj = nullptr;
178 }
179
180 template <class X,
181 std::enable_if_t<std::is_convertible<X *, T *>::value, bool> = true>
182 IntrusiveRefCntPtr(std::unique_ptr<X> S) : Obj(S.release()) {
183 retain();
184 }
185
186 ~IntrusiveRefCntPtr() { release(); }
15
Calling 'IntrusiveRefCntPtr::release'
187
188 IntrusiveRefCntPtr &operator=(IntrusiveRefCntPtr S) {
189 swap(S);
190 return *this;
191 }
192
193 T &operator*() const { return *Obj; }
194 T *operator->() const { return Obj; }
195 T *get() const { return Obj; }
196 explicit operator bool() const { return Obj; }
197
198 void swap(IntrusiveRefCntPtr &other) {
199 T *tmp = other.Obj;
200 other.Obj = Obj;
201 Obj = tmp;
202 }
203
204 void reset() {
205 release();
206 Obj = nullptr;
207 }
208
209 void resetWithoutRelease() { Obj = nullptr; }
210
211private:
212 void retain() {
213 if (Obj)
3
Assuming field 'Obj' is non-null
4
Taking true branch
214 IntrusiveRefCntPtrInfo<T>::retain(Obj);
215 }
216
217 void release() {
218 if (Obj
15.1
Field 'Obj' is non-null
15.1
Field 'Obj' is non-null
)
16
Taking true branch
219 IntrusiveRefCntPtrInfo<T>::release(Obj);
17
Use of memory after it is freed
220 }
221
222 template <typename X> friend class IntrusiveRefCntPtr;
223};
224
225template <class T, class U>
226inline bool operator==(const IntrusiveRefCntPtr<T> &A,
227 const IntrusiveRefCntPtr<U> &B) {
228 return A.get() == B.get();
229}
230
231template <class T, class U>
232inline bool operator!=(const IntrusiveRefCntPtr<T> &A,
233 const IntrusiveRefCntPtr<U> &B) {
234 return A.get() != B.get();
235}
236
237template <class T, class U>
238inline bool operator==(const IntrusiveRefCntPtr<T> &A, U *B) {
239 return A.get() == B;
240}
241
242template <class T, class U>
243inline bool operator!=(const IntrusiveRefCntPtr<T> &A, U *B) {
244 return A.get() != B;
245}
246
247template <class T, class U>
248inline bool operator==(T *A, const IntrusiveRefCntPtr<U> &B) {
249 return A == B.get();
250}
251
252template <class T, class U>
253inline bool operator!=(T *A, const IntrusiveRefCntPtr<U> &B) {
254 return A != B.get();
255}
256
257template <class T>
258bool operator==(std::nullptr_t, const IntrusiveRefCntPtr<T> &B) {
259 return !B;
260}
261
262template <class T>
263bool operator==(const IntrusiveRefCntPtr<T> &A, std::nullptr_t B) {
264 return B == A;
265}
266
267template <class T>
268bool operator!=(std::nullptr_t A, const IntrusiveRefCntPtr<T> &B) {
269 return !(A == B);
270}
271
272template <class T>
273bool operator!=(const IntrusiveRefCntPtr<T> &A, std::nullptr_t B) {
274 return !(A == B);
275}
276
277// Make IntrusiveRefCntPtr work with dyn_cast, isa, and the other idioms from
278// Casting.h.
279template <typename From> struct simplify_type;
280
281template <class T> struct simplify_type<IntrusiveRefCntPtr<T>> {
282 using SimpleType = T *;
283
284 static SimpleType getSimplifiedValue(IntrusiveRefCntPtr<T> &Val) {
285 return Val.get();
286 }
287};
288
289template <class T> struct simplify_type<const IntrusiveRefCntPtr<T>> {
290 using SimpleType = /*const*/ T *;
291
292 static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T> &Val) {
293 return Val.get();
294 }
295};
296
297/// Factory function for creating intrusive ref counted pointers.
298template <typename T, typename... Args>
299IntrusiveRefCntPtr<T> makeIntrusiveRefCnt(Args &&...A) {
300 return IntrusiveRefCntPtr<T>(new T(std::forward<Args>(A)...));
301}
302
303} // end namespace llvm
304
305#endif // LLVM_ADT_INTRUSIVEREFCNTPTR_H