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 -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 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/build-llvm/lib/ExecutionEngine/Orc -resource-dir /usr/lib/llvm-13/lib/clang/13.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/build-llvm/lib/ExecutionEngine/Orc -I /build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc -I /build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/build-llvm/include -I /build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/include -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-13/lib/clang/13.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 -O2 -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-13~++20210506100649+6304c0836a4d/build-llvm/lib/ExecutionEngine/Orc -fdebug-prefix-map=/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d=. -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -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-2021-05-07-005843-9350-1 -x c++ /build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp

/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/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/RTDyldObjectLinkingLayer.h"
17#include "llvm/ExecutionEngine/SectionMemoryManager.h"
18
19using namespace llvm;
20using namespace llvm::orc;
21
22namespace llvm {
23namespace orc {
24
25class InProgressLookupState;
26
27class OrcV2CAPIHelper {
28public:
29 using PoolEntry = SymbolStringPtr::PoolEntry;
30 using PoolEntryPtr = SymbolStringPtr::PoolEntryPtr;
31
32 // Move from SymbolStringPtr to PoolEntryPtr (no change in ref count).
33 static PoolEntryPtr moveFromSymbolStringPtr(SymbolStringPtr S) {
34 PoolEntryPtr Result = nullptr;
35 std::swap(Result, S.S);
36 return Result;
37 }
38
39 // Move from a PoolEntryPtr to a SymbolStringPtr (no change in ref count).
40 static SymbolStringPtr moveToSymbolStringPtr(PoolEntryPtr P) {
41 SymbolStringPtr S;
42 S.S = P;
43 return S;
44 }
45
46 // Copy a pool entry to a SymbolStringPtr (increments ref count).
47 static SymbolStringPtr copyToSymbolStringPtr(PoolEntryPtr P) {
48 return SymbolStringPtr(P);
49 }
50
51 static PoolEntryPtr getRawPoolEntryPtr(const SymbolStringPtr &S) {
52 return S.S;
53 }
54
55 static void retainPoolEntry(PoolEntryPtr P) {
56 SymbolStringPtr S(P);
57 S.S = nullptr;
58 }
59
60 static void releasePoolEntry(PoolEntryPtr P) {
61 SymbolStringPtr S;
62 S.S = P;
63 }
64
65 static InProgressLookupState *extractLookupState(LookupState &LS) {
66 return LS.IPLS.release();
67 }
68
69 static void resetLookupState(LookupState &LS, InProgressLookupState *IPLS) {
70 return LS.reset(IPLS);
71 }
72};
73
74} // namespace orc
75} // namespace llvm
76
77DEFINE_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)); }
78DEFINE_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)); }
79DEFINE_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)); }
80 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)); }
81DEFINE_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)); }
82 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)); }
83DEFINE_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)); }
84 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)); }
85DEFINE_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)); }
86DEFINE_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)); }
87DEFINE_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)); }
88 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)); }
89DEFINE_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)); }
90DEFINE_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)); }
91 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)); }
92DEFINE_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)); }
93DEFINE_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)); }
94 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)); }
95DEFINE_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)); }
96DEFINE_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)); }
97DEFINE_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)); }
98
99DEFINE_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)); }
100
101namespace llvm {
102namespace orc {
103
104class CAPIDefinitionGenerator final : public DefinitionGenerator {
105public:
106 CAPIDefinitionGenerator(
107 void *Ctx,
108 LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction TryToGenerate)
109 : Ctx(Ctx), TryToGenerate(TryToGenerate) {}
110
111 Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
112 JITDylibLookupFlags JDLookupFlags,
113 const SymbolLookupSet &LookupSet) override {
114
115 // Take the lookup state.
116 LLVMOrcLookupStateRef LSR = ::wrap(OrcV2CAPIHelper::extractLookupState(LS));
117
118 // Translate the lookup kind.
119 LLVMOrcLookupKind CLookupKind;
120 switch (K) {
121 case LookupKind::Static:
122 CLookupKind = LLVMOrcLookupKindStatic;
123 break;
124 case LookupKind::DLSym:
125 CLookupKind = LLVMOrcLookupKindDLSym;
126 break;
127 }
128
129 // Translate the JITDylibSearchFlags.
130 LLVMOrcJITDylibLookupFlags CJDLookupFlags;
131 switch (JDLookupFlags) {
132 case JITDylibLookupFlags::MatchExportedSymbolsOnly:
133 CJDLookupFlags = LLVMOrcJITDylibLookupFlagsMatchExportedSymbolsOnly;
134 break;
135 case JITDylibLookupFlags::MatchAllSymbols:
136 CJDLookupFlags = LLVMOrcJITDylibLookupFlagsMatchAllSymbols;
137 break;
138 }
139
140 // Translate the lookup set.
141 std::vector<LLVMOrcCLookupSetElement> CLookupSet;
142 CLookupSet.reserve(LookupSet.size());
143 for (auto &KV : LookupSet) {
144 LLVMOrcSymbolLookupFlags SLF;
145 LLVMOrcSymbolStringPoolEntryRef Name =
146 ::wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(KV.first));
147 switch (KV.second) {
148 case SymbolLookupFlags::RequiredSymbol:
149 SLF = LLVMOrcSymbolLookupFlagsRequiredSymbol;
150 break;
151 case SymbolLookupFlags::WeaklyReferencedSymbol:
152 SLF = LLVMOrcSymbolLookupFlagsWeaklyReferencedSymbol;
153 break;
154 }
155 CLookupSet.push_back({Name, SLF});
156 }
157
158 // Run the C TryToGenerate function.
159 auto Err = unwrap(TryToGenerate(::wrap(this), Ctx, &LSR, CLookupKind,
160 ::wrap(&JD), CJDLookupFlags,
161 CLookupSet.data(), CLookupSet.size()));
162
163 // Restore the lookup state.
164 OrcV2CAPIHelper::resetLookupState(LS, ::unwrap(LSR));
165
166 return Err;
167 }
168
169private:
170 void *Ctx;
171 LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction TryToGenerate;
172};
173
174} // end namespace orc
175} // end namespace llvm
176
177namespace {
178
179class OrcCAPIMaterializationUnit : public llvm::orc::MaterializationUnit {
180public:
181 OrcCAPIMaterializationUnit(
182 std::string Name, SymbolFlagsMap InitialSymbolFlags,
183 SymbolStringPtr InitSymbol, void *Ctx,
184 LLVMOrcMaterializationUnitMaterializeFunction Materialize,
185 LLVMOrcMaterializationUnitDiscardFunction Discard,
186 LLVMOrcMaterializationUnitDestroyFunction Destroy)
187 : llvm::orc::MaterializationUnit(std::move(InitialSymbolFlags),
188 std::move(InitSymbol)),
189 Name(std::move(Name)), Ctx(Ctx), Materialize(Materialize),
190 Discard(Discard), Destroy(Destroy) {}
191
192 ~OrcCAPIMaterializationUnit() {
193 if (Ctx)
194 Destroy(Ctx);
195 }
196
197 StringRef getName() const override { return Name; }
198
199 void materialize(std::unique_ptr<MaterializationResponsibility> R) override {
200 void *Tmp = Ctx;
201 Ctx = nullptr;
202 Materialize(Tmp, wrap(R.release()));
203 }
204
205private:
206 void discard(const JITDylib &JD, const SymbolStringPtr &Name) override {
207 Discard(Ctx, wrap(&JD), wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(Name)));
208 }
209
210 std::string Name;
211 void *Ctx = nullptr;
212 LLVMOrcMaterializationUnitMaterializeFunction Materialize = nullptr;
213 LLVMOrcMaterializationUnitDiscardFunction Discard = nullptr;
214 LLVMOrcMaterializationUnitDestroyFunction Destroy = nullptr;
215};
216
217static JITSymbolFlags toJITSymbolFlags(LLVMJITSymbolFlags F) {
218
219 JITSymbolFlags JSF;
220
221 if (F.GenericFlags & LLVMJITSymbolGenericFlagsExported)
222 JSF |= JITSymbolFlags::Exported;
223 if (F.GenericFlags & LLVMJITSymbolGenericFlagsWeak)
224 JSF |= JITSymbolFlags::Weak;
225 if (F.GenericFlags & LLVMJITSymbolGenericFlagsCallable)
226 JSF |= JITSymbolFlags::Callable;
227 if (F.GenericFlags & LLVMJITSymbolGenericFlagsMaterializationSideEffectsOnly)
228 JSF |= JITSymbolFlags::MaterializationSideEffectsOnly;
229
230 JSF.getTargetFlags() = F.TargetFlags;
231
232 return JSF;
233}
234
235} // end anonymous namespace
236
237void LLVMOrcExecutionSessionSetErrorReporter(
238 LLVMOrcExecutionSessionRef ES, LLVMOrcErrorReporterFunction ReportError,
239 void *Ctx) {
240 unwrap(ES)->setErrorReporter(
241 [=](Error Err) { ReportError(Ctx, wrap(std::move(Err))); });
242}
243
244LLVMOrcSymbolStringPoolRef
245LLVMOrcExecutionSessionGetSymbolStringPool(LLVMOrcExecutionSessionRef ES) {
246 return wrap(unwrap(ES)->getSymbolStringPool().get());
247}
248
249void LLVMOrcSymbolStringPoolClearDeadEntries(LLVMOrcSymbolStringPoolRef SSP) {
250 unwrap(SSP)->clearDeadEntries();
251}
252
253LLVMOrcSymbolStringPoolEntryRef
254LLVMOrcExecutionSessionIntern(LLVMOrcExecutionSessionRef ES, const char *Name) {
255 return wrap(
256 OrcV2CAPIHelper::moveFromSymbolStringPtr(unwrap(ES)->intern(Name)));
257}
258
259void LLVMOrcRetainSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S) {
260 OrcV2CAPIHelper::retainPoolEntry(unwrap(S));
261}
262
263void LLVMOrcReleaseSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S) {
264 OrcV2CAPIHelper::releasePoolEntry(unwrap(S));
265}
266
267const char *LLVMOrcSymbolStringPoolEntryStr(LLVMOrcSymbolStringPoolEntryRef S) {
268 return unwrap(S)->getKey().data();
269}
270
271LLVMOrcResourceTrackerRef
272LLVMOrcJITDylibCreateResourceTracker(LLVMOrcJITDylibRef JD) {
273 auto RT = unwrap(JD)->createResourceTracker();
274 // Retain the pointer for the C API client.
275 RT->Retain();
276 return wrap(RT.get());
277}
278
279LLVMOrcResourceTrackerRef
280LLVMOrcJITDylibGetDefaultResourceTracker(LLVMOrcJITDylibRef JD) {
281 auto RT = unwrap(JD)->getDefaultResourceTracker();
282 // Retain the pointer for the C API client.
283 return wrap(RT.get());
284}
285
286void LLVMOrcReleaseResourceTracker(LLVMOrcResourceTrackerRef RT) {
287 ResourceTrackerSP TmpRT(unwrap(RT));
1
Calling constructor for 'IntrusiveRefCntPtr<llvm::orc::ResourceTracker>'
6
Returning from constructor for 'IntrusiveRefCntPtr<llvm::orc::ResourceTracker>'
288 TmpRT->Release();
7
Calling 'ThreadSafeRefCountedBase::Release'
13
Returning; memory was released
289}
14
Calling '~IntrusiveRefCntPtr'
290
291void LLVMOrcResourceTrackerTransferTo(LLVMOrcResourceTrackerRef SrcRT,
292 LLVMOrcResourceTrackerRef DstRT) {
293 ResourceTrackerSP TmpRT(unwrap(SrcRT));
294 TmpRT->transferTo(*unwrap(DstRT));
295}
296
297LLVMErrorRef LLVMOrcResourceTrackerRemove(LLVMOrcResourceTrackerRef RT) {
298 ResourceTrackerSP TmpRT(unwrap(RT));
299 return wrap(TmpRT->remove());
300}
301
302void LLVMOrcDisposeDefinitionGenerator(LLVMOrcDefinitionGeneratorRef DG) {
303 std::unique_ptr<DefinitionGenerator> TmpDG(unwrap(DG));
304}
305
306void LLVMOrcDisposeMaterializationUnit(LLVMOrcMaterializationUnitRef MU) {
307 std::unique_ptr<MaterializationUnit> TmpMU(unwrap(MU));
308}
309
310LLVMOrcMaterializationUnitRef LLVMOrcCreateCustomMaterializationUnit(
311 const char *Name, void *Ctx, LLVMOrcCSymbolFlagsMapPairs Syms,
312 size_t NumSyms, LLVMOrcSymbolStringPoolEntryRef InitSym,
313 LLVMOrcMaterializationUnitMaterializeFunction Materialize,
314 LLVMOrcMaterializationUnitDiscardFunction Discard,
315 LLVMOrcMaterializationUnitDestroyFunction Destroy) {
316 SymbolFlagsMap SFM;
317 for (size_t I = 0; I != NumSyms; ++I)
318 SFM[OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(Syms[I].Name))] =
319 toJITSymbolFlags(Syms[I].Flags);
320
321 auto IS = OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(InitSym));
322
323 return wrap(new OrcCAPIMaterializationUnit(
324 Name, std::move(SFM), std::move(IS), Ctx, Materialize, Discard, Destroy));
325}
326
327LLVMOrcMaterializationUnitRef
328LLVMOrcAbsoluteSymbols(LLVMOrcCSymbolMapPairs Syms, size_t NumPairs) {
329 SymbolMap SM;
330 for (size_t I = 0; I != NumPairs; ++I) {
331 JITSymbolFlags Flags = toJITSymbolFlags(Syms[I].Sym.Flags);
332 SM[OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(Syms[I].Name))] =
333 JITEvaluatedSymbol(Syms[I].Sym.Address, Flags);
334 }
335
336 return wrap(absoluteSymbols(std::move(SM)).release());
337}
338
339LLVMOrcJITDylibRef
340LLVMOrcExecutionSessionCreateBareJITDylib(LLVMOrcExecutionSessionRef ES,
341 const char *Name) {
342 return wrap(&unwrap(ES)->createBareJITDylib(Name));
343}
344
345LLVMErrorRef
346LLVMOrcExecutionSessionCreateJITDylib(LLVMOrcExecutionSessionRef ES,
347 LLVMOrcJITDylibRef *Result,
348 const char *Name) {
349 auto JD = unwrap(ES)->createJITDylib(Name);
350 if (!JD)
351 return wrap(JD.takeError());
352 *Result = wrap(&*JD);
353 return LLVMErrorSuccess0;
354}
355
356LLVMOrcJITDylibRef
357LLVMOrcExecutionSessionGetJITDylibByName(LLVMOrcExecutionSessionRef ES,
358 const char *Name) {
359 return wrap(unwrap(ES)->getJITDylibByName(Name));
360}
361
362LLVMErrorRef LLVMOrcJITDylibDefine(LLVMOrcJITDylibRef JD,
363 LLVMOrcMaterializationUnitRef MU) {
364 std::unique_ptr<MaterializationUnit> TmpMU(unwrap(MU));
365
366 if (auto Err = unwrap(JD)->define(TmpMU)) {
367 TmpMU.release();
368 return wrap(std::move(Err));
369 }
370 return LLVMErrorSuccess0;
371}
372
373LLVMErrorRef LLVMOrcJITDylibClear(LLVMOrcJITDylibRef JD) {
374 return wrap(unwrap(JD)->clear());
375}
376
377void LLVMOrcJITDylibAddGenerator(LLVMOrcJITDylibRef JD,
378 LLVMOrcDefinitionGeneratorRef DG) {
379 unwrap(JD)->addGenerator(std::unique_ptr<DefinitionGenerator>(unwrap(DG)));
380}
381
382LLVMOrcDefinitionGeneratorRef LLVMOrcCreateCustomCAPIDefinitionGenerator(
383 LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction F, void *Ctx) {
384 auto DG = std::make_unique<CAPIDefinitionGenerator>(Ctx, F);
385 return wrap(DG.release());
386}
387
388LLVMErrorRef LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess(
389 LLVMOrcDefinitionGeneratorRef *Result, char GlobalPrefix,
390 LLVMOrcSymbolPredicate Filter, void *FilterCtx) {
391 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\""
, "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp"
, 391, __extension__ __PRETTY_FUNCTION__))
;
392 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\""
, "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp"
, 393, __extension__ __PRETTY_FUNCTION__))
393 "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\""
, "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp"
, 393, __extension__ __PRETTY_FUNCTION__))
;
394
395 DynamicLibrarySearchGenerator::SymbolPredicate Pred;
396 if (Filter)
397 Pred = [=](const SymbolStringPtr &Name) -> bool {
398 return Filter(FilterCtx, wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(Name)));
399 };
400
401 auto ProcessSymsGenerator =
402 DynamicLibrarySearchGenerator::GetForCurrentProcess(GlobalPrefix, Pred);
403
404 if (!ProcessSymsGenerator) {
405 *Result = 0;
406 return wrap(ProcessSymsGenerator.takeError());
407 }
408
409 *Result = wrap(ProcessSymsGenerator->release());
410 return LLVMErrorSuccess0;
411}
412
413LLVMOrcThreadSafeContextRef LLVMOrcCreateNewThreadSafeContext(void) {
414 return wrap(new ThreadSafeContext(std::make_unique<LLVMContext>()));
415}
416
417LLVMContextRef
418LLVMOrcThreadSafeContextGetContext(LLVMOrcThreadSafeContextRef TSCtx) {
419 return wrap(unwrap(TSCtx)->getContext());
420}
421
422void LLVMOrcDisposeThreadSafeContext(LLVMOrcThreadSafeContextRef TSCtx) {
423 delete unwrap(TSCtx);
424}
425
426LLVMOrcThreadSafeModuleRef
427LLVMOrcCreateNewThreadSafeModule(LLVMModuleRef M,
428 LLVMOrcThreadSafeContextRef TSCtx) {
429 return wrap(
430 new ThreadSafeModule(std::unique_ptr<Module>(unwrap(M)), *unwrap(TSCtx)));
431}
432
433void LLVMOrcDisposeThreadSafeModule(LLVMOrcThreadSafeModuleRef TSM) {
434 delete unwrap(TSM);
435}
436
437LLVMErrorRef LLVMOrcJITTargetMachineBuilderDetectHost(
438 LLVMOrcJITTargetMachineBuilderRef *Result) {
439 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\""
, "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp"
, 439, __extension__ __PRETTY_FUNCTION__))
;
440
441 auto JTMB = JITTargetMachineBuilder::detectHost();
442 if (!JTMB) {
443 Result = 0;
444 return wrap(JTMB.takeError());
445 }
446
447 *Result = wrap(new JITTargetMachineBuilder(std::move(*JTMB)));
448 return LLVMErrorSuccess0;
449}
450
451LLVMOrcJITTargetMachineBuilderRef
452LLVMOrcJITTargetMachineBuilderCreateFromTargetMachine(LLVMTargetMachineRef TM) {
453 auto *TemplateTM = unwrap(TM);
454
455 auto JTMB =
456 std::make_unique<JITTargetMachineBuilder>(TemplateTM->getTargetTriple());
457
458 (*JTMB)
459 .setCPU(TemplateTM->getTargetCPU().str())
460 .setRelocationModel(TemplateTM->getRelocationModel())
461 .setCodeModel(TemplateTM->getCodeModel())
462 .setCodeGenOptLevel(TemplateTM->getOptLevel())
463 .setFeatures(TemplateTM->getTargetFeatureString())
464 .setOptions(TemplateTM->Options);
465
466 LLVMDisposeTargetMachine(TM);
467
468 return wrap(JTMB.release());
469}
470
471void LLVMOrcDisposeJITTargetMachineBuilder(
472 LLVMOrcJITTargetMachineBuilderRef JTMB) {
473 delete unwrap(JTMB);
474}
475
476char *LLVMOrcJITTargetMachineBuilderGetTargetTriple(
477 LLVMOrcJITTargetMachineBuilderRef JTMB) {
478 auto Tmp = unwrap(JTMB)->getTargetTriple().str();
479 char *TargetTriple = (char *)malloc(Tmp.size() + 1);
480 strcpy(TargetTriple, Tmp.c_str());
481 return TargetTriple;
482}
483
484void LLVMOrcJITTargetMachineBuilderSetTargetTriple(
485 LLVMOrcJITTargetMachineBuilderRef JTMB, const char *TargetTriple) {
486 unwrap(JTMB)->getTargetTriple() = Triple(TargetTriple);
487}
488
489void LLVMOrcJITTargetMachineBuilderDisposeTargetTriple(
490 LLVMOrcJITTargetMachineBuilderRef JTMB, char *TargetTriple) {
491 free(TargetTriple);
492}
493
494LLVMErrorRef LLVMOrcObjectLayerAddObjectFile(LLVMOrcObjectLayerRef ObjLayer,
495 LLVMOrcJITDylibRef JD,
496 LLVMMemoryBufferRef ObjBuffer) {
497 return wrap(unwrap(ObjLayer)->add(
498 *unwrap(JD), std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer))));
499}
500
501LLVMErrorRef LLVMOrcLLJITAddObjectFileWithRT(LLVMOrcObjectLayerRef ObjLayer,
502 LLVMOrcResourceTrackerRef RT,
503 LLVMMemoryBufferRef ObjBuffer) {
504 return wrap(
505 unwrap(ObjLayer)->add(ResourceTrackerSP(unwrap(RT)),
506 std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer))));
507}
508
509void LLVMOrcObjectLayerEmit(LLVMOrcObjectLayerRef ObjLayer,
510 LLVMOrcMaterializationResponsibilityRef R,
511 LLVMMemoryBufferRef ObjBuffer) {
512 unwrap(ObjLayer)->emit(
513 std::unique_ptr<MaterializationResponsibility>(unwrap(R)),
514 std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer)));
515}
516
517void LLVMOrcDisposeObjectLayer(LLVMOrcObjectLayerRef ObjLayer) {
518 delete unwrap(ObjLayer);
519}
520
521LLVMOrcLLJITBuilderRef LLVMOrcCreateLLJITBuilder(void) {
522 return wrap(new LLJITBuilder());
523}
524
525void LLVMOrcDisposeLLJITBuilder(LLVMOrcLLJITBuilderRef Builder) {
526 delete unwrap(Builder);
527}
528
529void LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(
530 LLVMOrcLLJITBuilderRef Builder, LLVMOrcJITTargetMachineBuilderRef JTMB) {
531 unwrap(Builder)->setJITTargetMachineBuilder(std::move(*unwrap(JTMB)));
532 LLVMOrcDisposeJITTargetMachineBuilder(JTMB);
533}
534
535void LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator(
536 LLVMOrcLLJITBuilderRef Builder,
537 LLVMOrcLLJITBuilderObjectLinkingLayerCreatorFunction F, void *Ctx) {
538 unwrap(Builder)->setObjectLinkingLayerCreator(
539 [=](ExecutionSession &ES, const Triple &TT) {
540 auto TTStr = TT.str();
541 return std::unique_ptr<ObjectLayer>(
542 unwrap(F(Ctx, wrap(&ES), TTStr.c_str())));
543 });
544}
545
546LLVMErrorRef LLVMOrcCreateLLJIT(LLVMOrcLLJITRef *Result,
547 LLVMOrcLLJITBuilderRef Builder) {
548 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\""
, "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp"
, 548, __extension__ __PRETTY_FUNCTION__))
;
549
550 if (!Builder)
551 Builder = LLVMOrcCreateLLJITBuilder();
552
553 auto J = unwrap(Builder)->create();
554 LLVMOrcDisposeLLJITBuilder(Builder);
555
556 if (!J) {
557 Result = 0;
558 return wrap(J.takeError());
559 }
560
561 *Result = wrap(J->release());
562 return LLVMErrorSuccess0;
563}
564
565LLVMErrorRef LLVMOrcDisposeLLJIT(LLVMOrcLLJITRef J) {
566 delete unwrap(J);
567 return LLVMErrorSuccess0;
568}
569
570LLVMOrcExecutionSessionRef LLVMOrcLLJITGetExecutionSession(LLVMOrcLLJITRef J) {
571 return wrap(&unwrap(J)->getExecutionSession());
572}
573
574LLVMOrcJITDylibRef LLVMOrcLLJITGetMainJITDylib(LLVMOrcLLJITRef J) {
575 return wrap(&unwrap(J)->getMainJITDylib());
576}
577
578const char *LLVMOrcLLJITGetTripleString(LLVMOrcLLJITRef J) {
579 return unwrap(J)->getTargetTriple().str().c_str();
580}
581
582char LLVMOrcLLJITGetGlobalPrefix(LLVMOrcLLJITRef J) {
583 return unwrap(J)->getDataLayout().getGlobalPrefix();
584}
585
586LLVMOrcSymbolStringPoolEntryRef
587LLVMOrcLLJITMangleAndIntern(LLVMOrcLLJITRef J, const char *UnmangledName) {
588 return wrap(OrcV2CAPIHelper::moveFromSymbolStringPtr(
589 unwrap(J)->mangleAndIntern(UnmangledName)));
590}
591
592LLVMErrorRef LLVMOrcLLJITAddObjectFile(LLVMOrcLLJITRef J, LLVMOrcJITDylibRef JD,
593 LLVMMemoryBufferRef ObjBuffer) {
594 return wrap(unwrap(J)->addObjectFile(
595 *unwrap(JD), std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer))));
596}
597
598LLVMErrorRef LLVMOrcLLJITAddObjectFileWithRT(LLVMOrcLLJITRef J,
599 LLVMOrcResourceTrackerRef RT,
600 LLVMMemoryBufferRef ObjBuffer) {
601 return wrap(unwrap(J)->addObjectFile(
602 ResourceTrackerSP(unwrap(RT)),
603 std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer))));
604}
605
606LLVMErrorRef LLVMOrcLLJITAddLLVMIRModule(LLVMOrcLLJITRef J,
607 LLVMOrcJITDylibRef JD,
608 LLVMOrcThreadSafeModuleRef TSM) {
609 std::unique_ptr<ThreadSafeModule> TmpTSM(unwrap(TSM));
610 return wrap(unwrap(J)->addIRModule(*unwrap(JD), std::move(*TmpTSM)));
611}
612
613LLVMErrorRef LLVMOrcLLJITAddLLVMIRModuleWithRT(LLVMOrcLLJITRef J,
614 LLVMOrcResourceTrackerRef RT,
615 LLVMOrcThreadSafeModuleRef TSM) {
616 std::unique_ptr<ThreadSafeModule> TmpTSM(unwrap(TSM));
617 return wrap(unwrap(J)->addIRModule(ResourceTrackerSP(unwrap(RT)),
618 std::move(*TmpTSM)));
619}
620
621LLVMErrorRef LLVMOrcLLJITLookup(LLVMOrcLLJITRef J,
622 LLVMOrcJITTargetAddress *Result,
623 const char *Name) {
624 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\""
, "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp"
, 624, __extension__ __PRETTY_FUNCTION__))
;
625
626 auto Sym = unwrap(J)->lookup(Name);
627 if (!Sym) {
628 *Result = 0;
629 return wrap(Sym.takeError());
630 }
631
632 *Result = Sym->getAddress();
633 return LLVMErrorSuccess0;
634}
635
636LLVMOrcObjectLayerRef LLVMOrcLLJITGetObjLinkingLayer(LLVMOrcLLJITRef J) {
637 return wrap(&unwrap(J)->getObjLinkingLayer());
638}
639
640LLVMOrcObjectLayerRef
641LLVMOrcCreateRTDyldObjectLinkingLayerWithSectionMemoryManager(
642 LLVMOrcExecutionSessionRef ES) {
643 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\""
, "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp"
, 643, __extension__ __PRETTY_FUNCTION__))
;
644 return wrap(new RTDyldObjectLinkingLayer(
645 *unwrap(ES), [] { return std::make_unique<SectionMemoryManager>(); }));
646}
647
648void LLVMOrcRTDyldObjectLinkingLayerRegisterJITEventListener(
649 LLVMOrcObjectLayerRef RTDyldObjLinkingLayer,
650 LLVMJITEventListenerRef Listener) {
651 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\""
, "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp"
, 651, __extension__ __PRETTY_FUNCTION__))
;
652 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\""
, "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp"
, 652, __extension__ __PRETTY_FUNCTION__))
;
653 reinterpret_cast<RTDyldObjectLinkingLayer *>(unwrap(RTDyldObjLinkingLayer))
654 ->registerJITEventListener(*unwrap(Listener));
655}

/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/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.\""
, "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/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.\""
, "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/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.\""
, "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/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.\""
, "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/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.\""
, "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/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.\""
, "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/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