Bug Summary

File:llvm/include/llvm/ADT/IntrusiveRefCntPtr.h
Warning:line 189, 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 -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-12/lib/clang/12.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/build-llvm/lib/ExecutionEngine/Orc -I /build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/llvm/lib/ExecutionEngine/Orc -I /build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/build-llvm/include -I /build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/llvm/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-12/lib/clang/12.0.0/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-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/build-llvm/lib/ExecutionEngine/Orc -fdebug-prefix-map=/build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d=. -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 -o /tmp/scan-build-2020-11-29-190409-37574-1 -x c++ /build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp

/build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/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 static PoolEntryPtr releaseSymbolStringPtr(SymbolStringPtr S) {
33 PoolEntryPtr Result = nullptr;
34 std::swap(Result, S.S);
35 return Result;
36 }
37
38 static SymbolStringPtr retainSymbolStringPtr(PoolEntryPtr P) {
39 return SymbolStringPtr(P);
40 }
41
42 static PoolEntryPtr getRawPoolEntryPtr(const SymbolStringPtr &S) {
43 return S.S;
44 }
45
46 static void retainPoolEntry(PoolEntryPtr P) {
47 SymbolStringPtr S(P);
48 S.S = nullptr;
49 }
50
51 static void releasePoolEntry(PoolEntryPtr P) {
52 SymbolStringPtr S;
53 S.S = P;
54 }
55
56 static InProgressLookupState *extractLookupState(LookupState &LS) {
57 return LS.IPLS.release();
58 }
59
60 static void resetLookupState(LookupState &LS, InProgressLookupState *IPLS) {
61 return LS.reset(IPLS);
62 }
63};
64
65} // namespace orc
66} // namespace llvm
67
68DEFINE_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)); }
69DEFINE_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)); }
70DEFINE_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)); }
71 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)); }
72DEFINE_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)); }
73 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)); }
74DEFINE_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)); }
75DEFINE_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)); }
76DEFINE_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)); }
77 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)); }
78DEFINE_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)); }
79DEFINE_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)); }
80 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)); }
81DEFINE_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)); }
82DEFINE_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)); }
83 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)); }
84DEFINE_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)); }
85DEFINE_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)); }
86DEFINE_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)); }
87
88DEFINE_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)); }
89
90namespace llvm {
91namespace orc {
92
93class CAPIDefinitionGenerator final : public DefinitionGenerator {
94public:
95 CAPIDefinitionGenerator(
96 void *Ctx,
97 LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction TryToGenerate)
98 : Ctx(Ctx), TryToGenerate(TryToGenerate) {}
99
100 Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
101 JITDylibLookupFlags JDLookupFlags,
102 const SymbolLookupSet &LookupSet) override {
103
104 // Take the lookup state.
105 LLVMOrcLookupStateRef LSR = ::wrap(OrcV2CAPIHelper::extractLookupState(LS));
106
107 // Translate the lookup kind.
108 LLVMOrcLookupKind CLookupKind;
109 switch (K) {
110 case LookupKind::Static:
111 CLookupKind = LLVMOrcLookupKindStatic;
112 break;
113 case LookupKind::DLSym:
114 CLookupKind = LLVMOrcLookupKindDLSym;
115 break;
116 }
117
118 // Translate the JITDylibSearchFlags.
119 LLVMOrcJITDylibLookupFlags CJDLookupFlags;
120 switch (JDLookupFlags) {
121 case JITDylibLookupFlags::MatchExportedSymbolsOnly:
122 CJDLookupFlags = LLVMOrcJITDylibLookupFlagsMatchExportedSymbolsOnly;
123 break;
124 case JITDylibLookupFlags::MatchAllSymbols:
125 CJDLookupFlags = LLVMOrcJITDylibLookupFlagsMatchAllSymbols;
126 break;
127 }
128
129 // Translate the lookup set.
130 std::vector<LLVMOrcCLookupSetElement> CLookupSet;
131 CLookupSet.reserve(LookupSet.size());
132 for (auto &KV : LookupSet) {
133 LLVMOrcSymbolLookupFlags SLF;
134 LLVMOrcSymbolStringPoolEntryRef Name =
135 ::wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(KV.first));
136 switch (KV.second) {
137 case SymbolLookupFlags::RequiredSymbol:
138 SLF = LLVMOrcSymbolLookupFlagsRequiredSymbol;
139 break;
140 case SymbolLookupFlags::WeaklyReferencedSymbol:
141 SLF = LLVMOrcSymbolLookupFlagsWeaklyReferencedSymbol;
142 break;
143 }
144 CLookupSet.push_back({Name, SLF});
145 }
146
147 // Run the C TryToGenerate function.
148 auto Err = unwrap(TryToGenerate(::wrap(this), Ctx, &LSR, CLookupKind,
149 ::wrap(&JD), CJDLookupFlags,
150 CLookupSet.data(), CLookupSet.size()));
151
152 // Restore the lookup state.
153 OrcV2CAPIHelper::resetLookupState(LS, ::unwrap(LSR));
154
155 return Err;
156 }
157
158private:
159 void *Ctx;
160 LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction TryToGenerate;
161};
162
163} // end namespace orc
164} // end namespace llvm
165
166void LLVMOrcExecutionSessionSetErrorReporter(
167 LLVMOrcExecutionSessionRef ES, LLVMOrcErrorReporterFunction ReportError,
168 void *Ctx) {
169 unwrap(ES)->setErrorReporter(
170 [=](Error Err) { ReportError(Ctx, wrap(std::move(Err))); });
171}
172
173LLVMOrcSymbolStringPoolRef
174LLVMOrcExecutionSessionGetSymbolStringPool(LLVMOrcExecutionSessionRef ES) {
175 return wrap(unwrap(ES)->getSymbolStringPool().get());
176}
177
178void LLVMOrcSymbolStringPoolClearDeadEntries(LLVMOrcSymbolStringPoolRef SSP) {
179 unwrap(SSP)->clearDeadEntries();
180}
181
182LLVMOrcSymbolStringPoolEntryRef
183LLVMOrcExecutionSessionIntern(LLVMOrcExecutionSessionRef ES, const char *Name) {
184 return wrap(
185 OrcV2CAPIHelper::releaseSymbolStringPtr(unwrap(ES)->intern(Name)));
186}
187
188void LLVMOrcRetainSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S) {
189 OrcV2CAPIHelper::retainPoolEntry(unwrap(S));
190}
191
192void LLVMOrcReleaseSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S) {
193 OrcV2CAPIHelper::releasePoolEntry(unwrap(S));
194}
195
196const char *LLVMOrcSymbolStringPoolEntryStr(LLVMOrcSymbolStringPoolEntryRef S) {
197 return unwrap(S)->getKey().data();
198}
199
200LLVMOrcResourceTrackerRef
201LLVMOrcJITDylibCreateResourceTracker(LLVMOrcJITDylibRef JD) {
202 auto RT = unwrap(JD)->createResourceTracker();
203 // Retain the pointer for the C API client.
204 RT->Retain();
205 return wrap(RT.get());
206}
207
208LLVMOrcResourceTrackerRef
209LLVMOrcJITDylibGetDefaultResourceTracker(LLVMOrcJITDylibRef JD) {
210 auto RT = unwrap(JD)->getDefaultResourceTracker();
211 // Retain the pointer for the C API client.
212 return wrap(RT.get());
213}
214
215void LLVMOrcReleaseResourceTracker(LLVMOrcResourceTrackerRef RT) {
216 ResourceTrackerSP TmpRT(unwrap(RT));
1
Calling constructor for 'IntrusiveRefCntPtr<llvm::orc::ResourceTracker>'
6
Returning from constructor for 'IntrusiveRefCntPtr<llvm::orc::ResourceTracker>'
217 TmpRT->Release();
7
Calling 'ThreadSafeRefCountedBase::Release'
13
Returning; memory was released
218}
14
Calling '~IntrusiveRefCntPtr'
219
220void LLVMOrcResourceTrackerTransferTo(LLVMOrcResourceTrackerRef SrcRT,
221 LLVMOrcResourceTrackerRef DstRT) {
222 ResourceTrackerSP TmpRT(unwrap(SrcRT));
223 TmpRT->transferTo(*unwrap(DstRT));
224}
225
226LLVMErrorRef LLVMOrcResourceTrackerRemove(LLVMOrcResourceTrackerRef RT) {
227 ResourceTrackerSP TmpRT(unwrap(RT));
228 return wrap(TmpRT->remove());
229}
230
231void LLVMOrcDisposeDefinitionGenerator(LLVMOrcDefinitionGeneratorRef DG) {
232 std::unique_ptr<DefinitionGenerator> TmpDG(unwrap(DG));
233}
234
235void LLVMOrcDisposeMaterializationUnit(LLVMOrcMaterializationUnitRef MU) {
236 std::unique_ptr<MaterializationUnit> TmpMU(unwrap(MU));
237}
238
239LLVMOrcMaterializationUnitRef
240LLVMOrcAbsoluteSymbols(LLVMOrcCSymbolMapPairs Syms, size_t NumPairs) {
241 SymbolMap SM;
242 for (size_t I = 0; I != NumPairs; ++I) {
243 JITSymbolFlags Flags;
244
245 if (Syms[I].Sym.Flags.GenericFlags & LLVMJITSymbolGenericFlagsExported)
246 Flags |= JITSymbolFlags::Exported;
247 if (Syms[I].Sym.Flags.GenericFlags & LLVMJITSymbolGenericFlagsWeak)
248 Flags |= JITSymbolFlags::Weak;
249
250 Flags.getTargetFlags() = Syms[I].Sym.Flags.TargetFlags;
251
252 SM[OrcV2CAPIHelper::retainSymbolStringPtr(unwrap(Syms[I].Name))] =
253 JITEvaluatedSymbol(Syms[I].Sym.Address, Flags);
254 }
255
256 return wrap(absoluteSymbols(std::move(SM)).release());
257}
258
259LLVMOrcJITDylibRef
260LLVMOrcExecutionSessionCreateBareJITDylib(LLVMOrcExecutionSessionRef ES,
261 const char *Name) {
262 return wrap(&unwrap(ES)->createBareJITDylib(Name));
263}
264
265LLVMErrorRef
266LLVMOrcExecutionSessionCreateJITDylib(LLVMOrcExecutionSessionRef ES,
267 LLVMOrcJITDylibRef *Result,
268 const char *Name) {
269 auto JD = unwrap(ES)->createJITDylib(Name);
270 if (!JD)
271 return wrap(JD.takeError());
272 *Result = wrap(&*JD);
273 return LLVMErrorSuccess0;
274}
275
276LLVMOrcJITDylibRef
277LLVMOrcExecutionSessionGetJITDylibByName(LLVMOrcExecutionSessionRef ES,
278 const char *Name) {
279 return wrap(unwrap(ES)->getJITDylibByName(Name));
280}
281
282LLVMErrorRef LLVMOrcJITDylibDefine(LLVMOrcJITDylibRef JD,
283 LLVMOrcMaterializationUnitRef MU) {
284 std::unique_ptr<MaterializationUnit> TmpMU(unwrap(MU));
285
286 if (auto Err = unwrap(JD)->define(TmpMU)) {
287 TmpMU.release();
288 return wrap(std::move(Err));
289 }
290 return LLVMErrorSuccess0;
291}
292
293LLVMErrorRef LLVMOrcJITDylibClear(LLVMOrcJITDylibRef JD) {
294 return wrap(unwrap(JD)->clear());
295}
296
297void LLVMOrcJITDylibAddGenerator(LLVMOrcJITDylibRef JD,
298 LLVMOrcDefinitionGeneratorRef DG) {
299 unwrap(JD)->addGenerator(std::unique_ptr<DefinitionGenerator>(unwrap(DG)));
300}
301
302LLVMOrcDefinitionGeneratorRef LLVMOrcCreateCustomCAPIDefinitionGenerator(
303 LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction F, void *Ctx) {
304 auto DG = std::make_unique<CAPIDefinitionGenerator>(Ctx, F);
305 return wrap(DG.release());
306}
307
308LLVMErrorRef LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess(
309 LLVMOrcDefinitionGeneratorRef *Result, char GlobalPrefix,
310 LLVMOrcSymbolPredicate Filter, void *FilterCtx) {
311 assert(Result && "Result can not be null")((Result && "Result can not be null") ? static_cast<
void> (0) : __assert_fail ("Result && \"Result can not be null\""
, "/build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp"
, 311, __PRETTY_FUNCTION__))
;
312 assert((Filter || !FilterCtx) &&(((Filter || !FilterCtx) && "if Filter is null then FilterCtx must also be null"
) ? static_cast<void> (0) : __assert_fail ("(Filter || !FilterCtx) && \"if Filter is null then FilterCtx must also be null\""
, "/build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp"
, 313, __PRETTY_FUNCTION__))
313 "if Filter is null then FilterCtx must also be null")(((Filter || !FilterCtx) && "if Filter is null then FilterCtx must also be null"
) ? static_cast<void> (0) : __assert_fail ("(Filter || !FilterCtx) && \"if Filter is null then FilterCtx must also be null\""
, "/build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp"
, 313, __PRETTY_FUNCTION__))
;
314
315 DynamicLibrarySearchGenerator::SymbolPredicate Pred;
316 if (Filter)
317 Pred = [=](const SymbolStringPtr &Name) -> bool {
318 return Filter(FilterCtx, wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(Name)));
319 };
320
321 auto ProcessSymsGenerator =
322 DynamicLibrarySearchGenerator::GetForCurrentProcess(GlobalPrefix, Pred);
323
324 if (!ProcessSymsGenerator) {
325 *Result = 0;
326 return wrap(ProcessSymsGenerator.takeError());
327 }
328
329 *Result = wrap(ProcessSymsGenerator->release());
330 return LLVMErrorSuccess0;
331}
332
333LLVMOrcThreadSafeContextRef LLVMOrcCreateNewThreadSafeContext(void) {
334 return wrap(new ThreadSafeContext(std::make_unique<LLVMContext>()));
335}
336
337LLVMContextRef
338LLVMOrcThreadSafeContextGetContext(LLVMOrcThreadSafeContextRef TSCtx) {
339 return wrap(unwrap(TSCtx)->getContext());
340}
341
342void LLVMOrcDisposeThreadSafeContext(LLVMOrcThreadSafeContextRef TSCtx) {
343 delete unwrap(TSCtx);
344}
345
346LLVMOrcThreadSafeModuleRef
347LLVMOrcCreateNewThreadSafeModule(LLVMModuleRef M,
348 LLVMOrcThreadSafeContextRef TSCtx) {
349 return wrap(
350 new ThreadSafeModule(std::unique_ptr<Module>(unwrap(M)), *unwrap(TSCtx)));
351}
352
353void LLVMOrcDisposeThreadSafeModule(LLVMOrcThreadSafeModuleRef TSM) {
354 delete unwrap(TSM);
355}
356
357LLVMErrorRef LLVMOrcJITTargetMachineBuilderDetectHost(
358 LLVMOrcJITTargetMachineBuilderRef *Result) {
359 assert(Result && "Result can not be null")((Result && "Result can not be null") ? static_cast<
void> (0) : __assert_fail ("Result && \"Result can not be null\""
, "/build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp"
, 359, __PRETTY_FUNCTION__))
;
360
361 auto JTMB = JITTargetMachineBuilder::detectHost();
362 if (!JTMB) {
363 Result = 0;
364 return wrap(JTMB.takeError());
365 }
366
367 *Result = wrap(new JITTargetMachineBuilder(std::move(*JTMB)));
368 return LLVMErrorSuccess0;
369}
370
371LLVMOrcJITTargetMachineBuilderRef
372LLVMOrcJITTargetMachineBuilderCreateFromTargetMachine(LLVMTargetMachineRef TM) {
373 auto *TemplateTM = unwrap(TM);
374
375 auto JTMB =
376 std::make_unique<JITTargetMachineBuilder>(TemplateTM->getTargetTriple());
377
378 (*JTMB)
379 .setCPU(TemplateTM->getTargetCPU().str())
380 .setRelocationModel(TemplateTM->getRelocationModel())
381 .setCodeModel(TemplateTM->getCodeModel())
382 .setCodeGenOptLevel(TemplateTM->getOptLevel())
383 .setFeatures(TemplateTM->getTargetFeatureString())
384 .setOptions(TemplateTM->Options);
385
386 LLVMDisposeTargetMachine(TM);
387
388 return wrap(JTMB.release());
389}
390
391void LLVMOrcDisposeJITTargetMachineBuilder(
392 LLVMOrcJITTargetMachineBuilderRef JTMB) {
393 delete unwrap(JTMB);
394}
395
396void lLVMOrcDisposeObjectLayer(LLVMOrcObjectLayerRef ObjLayer) {
397 delete unwrap(ObjLayer);
398}
399
400LLVMOrcLLJITBuilderRef LLVMOrcCreateLLJITBuilder(void) {
401 return wrap(new LLJITBuilder());
402}
403
404void LLVMOrcDisposeLLJITBuilder(LLVMOrcLLJITBuilderRef Builder) {
405 delete unwrap(Builder);
406}
407
408void LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(
409 LLVMOrcLLJITBuilderRef Builder, LLVMOrcJITTargetMachineBuilderRef JTMB) {
410 unwrap(Builder)->setJITTargetMachineBuilder(*unwrap(JTMB));
411}
412
413void LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator(
414 LLVMOrcLLJITBuilderRef Builder,
415 LLVMOrcLLJITBuilderObjectLinkingLayerCreatorFunction F, void *Ctx) {
416 unwrap(Builder)->setObjectLinkingLayerCreator(
417 [=](ExecutionSession &ES, const Triple &TT) {
418 auto TTStr = TT.str();
419 return std::unique_ptr<ObjectLayer>(
420 unwrap(F(Ctx, wrap(&ES), TTStr.c_str())));
421 });
422}
423
424LLVMErrorRef LLVMOrcCreateLLJIT(LLVMOrcLLJITRef *Result,
425 LLVMOrcLLJITBuilderRef Builder) {
426 assert(Result && "Result can not be null")((Result && "Result can not be null") ? static_cast<
void> (0) : __assert_fail ("Result && \"Result can not be null\""
, "/build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp"
, 426, __PRETTY_FUNCTION__))
;
427
428 if (!Builder)
429 Builder = LLVMOrcCreateLLJITBuilder();
430
431 auto J = unwrap(Builder)->create();
432 LLVMOrcDisposeLLJITBuilder(Builder);
433
434 if (!J) {
435 Result = 0;
436 return wrap(J.takeError());
437 }
438
439 *Result = wrap(J->release());
440 return LLVMErrorSuccess0;
441}
442
443LLVMErrorRef LLVMOrcDisposeLLJIT(LLVMOrcLLJITRef J) {
444 delete unwrap(J);
445 return LLVMErrorSuccess0;
446}
447
448LLVMOrcExecutionSessionRef LLVMOrcLLJITGetExecutionSession(LLVMOrcLLJITRef J) {
449 return wrap(&unwrap(J)->getExecutionSession());
450}
451
452LLVMOrcJITDylibRef LLVMOrcLLJITGetMainJITDylib(LLVMOrcLLJITRef J) {
453 return wrap(&unwrap(J)->getMainJITDylib());
454}
455
456const char *LLVMOrcLLJITGetTripleString(LLVMOrcLLJITRef J) {
457 return unwrap(J)->getTargetTriple().str().c_str();
458}
459
460char LLVMOrcLLJITGetGlobalPrefix(LLVMOrcLLJITRef J) {
461 return unwrap(J)->getDataLayout().getGlobalPrefix();
462}
463
464LLVMOrcSymbolStringPoolEntryRef
465LLVMOrcLLJITMangleAndIntern(LLVMOrcLLJITRef J, const char *UnmangledName) {
466 return wrap(OrcV2CAPIHelper::releaseSymbolStringPtr(
467 unwrap(J)->mangleAndIntern(UnmangledName)));
468}
469
470LLVMErrorRef LLVMOrcLLJITAddObjectFile(LLVMOrcLLJITRef J, LLVMOrcJITDylibRef JD,
471 LLVMMemoryBufferRef ObjBuffer) {
472 return wrap(unwrap(J)->addObjectFile(
473 *unwrap(JD), std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer))));
474}
475
476LLVMErrorRef LLVMOrcLLJITAddObjectFileWithRT(LLVMOrcLLJITRef J,
477 LLVMOrcResourceTrackerRef RT,
478 LLVMMemoryBufferRef ObjBuffer) {
479 return wrap(unwrap(J)->addObjectFile(
480 ResourceTrackerSP(unwrap(RT)),
481 std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer))));
482}
483
484LLVMErrorRef LLVMOrcLLJITAddLLVMIRModule(LLVMOrcLLJITRef J,
485 LLVMOrcJITDylibRef JD,
486 LLVMOrcThreadSafeModuleRef TSM) {
487 std::unique_ptr<ThreadSafeModule> TmpTSM(unwrap(TSM));
488 return wrap(unwrap(J)->addIRModule(*unwrap(JD), std::move(*TmpTSM)));
489}
490
491LLVMErrorRef LLVMOrcLLJITAddLLVMIRModuleWithRT(LLVMOrcLLJITRef J,
492 LLVMOrcResourceTrackerRef RT,
493 LLVMOrcThreadSafeModuleRef TSM) {
494 std::unique_ptr<ThreadSafeModule> TmpTSM(unwrap(TSM));
495 return wrap(unwrap(J)->addIRModule(ResourceTrackerSP(unwrap(RT)),
496 std::move(*TmpTSM)));
497}
498
499LLVMErrorRef LLVMOrcLLJITLookup(LLVMOrcLLJITRef J,
500 LLVMOrcJITTargetAddress *Result,
501 const char *Name) {
502 assert(Result && "Result can not be null")((Result && "Result can not be null") ? static_cast<
void> (0) : __assert_fail ("Result && \"Result can not be null\""
, "/build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp"
, 502, __PRETTY_FUNCTION__))
;
503
504 auto Sym = unwrap(J)->lookup(Name);
505 if (!Sym) {
506 *Result = 0;
507 return wrap(Sym.takeError());
508 }
509
510 *Result = Sym->getAddress();
511 return LLVMErrorSuccess0;
512}
513
514LLVMOrcObjectLayerRef
515LLVMOrcCreateRTDyldObjectLinkingLayerWithSectionMemoryManager(
516 LLVMOrcExecutionSessionRef ES) {
517 assert(ES && "ES must not be null")((ES && "ES must not be null") ? static_cast<void>
(0) : __assert_fail ("ES && \"ES must not be null\""
, "/build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp"
, 517, __PRETTY_FUNCTION__))
;
518 return wrap(new RTDyldObjectLinkingLayer(
519 *unwrap(ES), [] { return std::make_unique<SectionMemoryManager>(); }));
520}
521
522void LLVMOrcRTDyldObjectLinkingLayerRegisterJITEventListener(
523 LLVMOrcObjectLayerRef RTDyldObjLinkingLayer,
524 LLVMJITEventListenerRef Listener) {
525 assert(RTDyldObjLinkingLayer && "RTDyldObjLinkingLayer must not be null")((RTDyldObjLinkingLayer && "RTDyldObjLinkingLayer must not be null"
) ? static_cast<void> (0) : __assert_fail ("RTDyldObjLinkingLayer && \"RTDyldObjLinkingLayer must not be null\""
, "/build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp"
, 525, __PRETTY_FUNCTION__))
;
526 assert(Listener && "Listener must not be null")((Listener && "Listener must not be null") ? static_cast
<void> (0) : __assert_fail ("Listener && \"Listener must not be null\""
, "/build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp"
, 526, __PRETTY_FUNCTION__))
;
527 reinterpret_cast<RTDyldObjectLinkingLayer *>(unwrap(RTDyldObjLinkingLayer))
528 ->registerJITEventListener(*unwrap(Listener));
529}

/build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/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
62namespace llvm {
63
64/// A CRTP mixin class that adds reference counting to a type.
65///
66/// The lifetime of an object which inherits from RefCountedBase is managed by
67/// calls to Release() and Retain(), which increment and decrement the object's
68/// refcount, respectively. When a Release() call decrements the refcount to 0,
69/// the object deletes itself.
70template <class Derived> class RefCountedBase {
71 mutable unsigned RefCount = 0;
72
73public:
74 RefCountedBase() = default;
75 RefCountedBase(const RefCountedBase &) {}
76
77 void Retain() const { ++RefCount; }
78
79 void Release() const {
80 assert(RefCount > 0 && "Reference count is already zero.")((RefCount > 0 && "Reference count is already zero."
) ? static_cast<void> (0) : __assert_fail ("RefCount > 0 && \"Reference count is already zero.\""
, "/build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/llvm/include/llvm/ADT/IntrusiveRefCntPtr.h"
, 80, __PRETTY_FUNCTION__))
;
81 if (--RefCount == 0)
82 delete static_cast<const Derived *>(this);
83 }
84};
85
86/// A thread-safe version of \c RefCountedBase.
87template <class Derived> class ThreadSafeRefCountedBase {
88 mutable std::atomic<int> RefCount;
89
90protected:
91 ThreadSafeRefCountedBase() : RefCount(0) {}
92
93public:
94 void Retain() const { RefCount.fetch_add(1, std::memory_order_relaxed); }
95
96 void Release() const {
97 int NewRefCount = RefCount.fetch_sub(1, std::memory_order_acq_rel) - 1;
98 assert(NewRefCount >= 0 && "Reference count was already zero.")((NewRefCount >= 0 && "Reference count was already zero."
) ? static_cast<void> (0) : __assert_fail ("NewRefCount >= 0 && \"Reference count was already zero.\""
, "/build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/llvm/include/llvm/ADT/IntrusiveRefCntPtr.h"
, 98, __PRETTY_FUNCTION__))
;
8
Assuming 'NewRefCount' is >= 0
9
'?' condition is true
99 if (NewRefCount == 0)
10
Assuming 'NewRefCount' is equal to 0
11
Taking true branch
100 delete static_cast<const Derived *>(this);
12
Memory is released
101 }
102};
103
104/// Class you can specialize to provide custom retain/release functionality for
105/// a type.
106///
107/// Usually specializing this class is not necessary, as IntrusiveRefCntPtr
108/// works with any type which defines Retain() and Release() functions -- you
109/// can define those functions yourself if RefCountedBase doesn't work for you.
110///
111/// One case when you might want to specialize this type is if you have
112/// - Foo.h defines type Foo and includes Bar.h, and
113/// - Bar.h uses IntrusiveRefCntPtr<Foo> in inline functions.
114///
115/// Because Foo.h includes Bar.h, Bar.h can't include Foo.h in order to pull in
116/// the declaration of Foo. Without the declaration of Foo, normally Bar.h
117/// wouldn't be able to use IntrusiveRefCntPtr<Foo>, which wants to call
118/// T::Retain and T::Release.
119///
120/// To resolve this, Bar.h could include a third header, FooFwd.h, which
121/// forward-declares Foo and specializes IntrusiveRefCntPtrInfo<Foo>. Then
122/// Bar.h could use IntrusiveRefCntPtr<Foo>, although it still couldn't call any
123/// functions on Foo itself, because Foo would be an incomplete type.
124template <typename T> struct IntrusiveRefCntPtrInfo {
125 static void retain(T *obj) { obj->Retain(); }
126 static void release(T *obj) { obj->Release(); }
127};
128
129/// A smart pointer to a reference-counted object that inherits from
130/// RefCountedBase or ThreadSafeRefCountedBase.
131///
132/// This class increments its pointee's reference count when it is created, and
133/// decrements its refcount when it's destroyed (or is changed to point to a
134/// different object).
135template <typename T> class IntrusiveRefCntPtr {
136 T *Obj = nullptr;
137
138public:
139 using element_type = T;
140
141 explicit IntrusiveRefCntPtr() = default;
142 IntrusiveRefCntPtr(T *obj) : Obj(obj) { retain(); }
2
Calling 'IntrusiveRefCntPtr::retain'
5
Returning from 'IntrusiveRefCntPtr::retain'
143 IntrusiveRefCntPtr(const IntrusiveRefCntPtr &S) : Obj(S.Obj) { retain(); }
144 IntrusiveRefCntPtr(IntrusiveRefCntPtr &&S) : Obj(S.Obj) { S.Obj = nullptr; }
145
146 template <class X>
147 IntrusiveRefCntPtr(IntrusiveRefCntPtr<X> &&S) : Obj(S.get()) {
148 S.Obj = nullptr;
149 }
150
151 template <class X>
152 IntrusiveRefCntPtr(const IntrusiveRefCntPtr<X> &S) : Obj(S.get()) {
153 retain();
154 }
155
156 ~IntrusiveRefCntPtr() { release(); }
15
Calling 'IntrusiveRefCntPtr::release'
157
158 IntrusiveRefCntPtr &operator=(IntrusiveRefCntPtr S) {
159 swap(S);
160 return *this;
161 }
162
163 T &operator*() const { return *Obj; }
164 T *operator->() const { return Obj; }
165 T *get() const { return Obj; }
166 explicit operator bool() const { return Obj; }
167
168 void swap(IntrusiveRefCntPtr &other) {
169 T *tmp = other.Obj;
170 other.Obj = Obj;
171 Obj = tmp;
172 }
173
174 void reset() {
175 release();
176 Obj = nullptr;
177 }
178
179 void resetWithoutRelease() { Obj = nullptr; }
180
181private:
182 void retain() {
183 if (Obj)
3
Assuming field 'Obj' is non-null
4
Taking true branch
184 IntrusiveRefCntPtrInfo<T>::retain(Obj);
185 }
186
187 void release() {
188 if (Obj
15.1
Field 'Obj' is non-null
15.1
Field 'Obj' is non-null
)
16
Taking true branch
189 IntrusiveRefCntPtrInfo<T>::release(Obj);
17
Use of memory after it is freed
190 }
191
192 template <typename X> friend class IntrusiveRefCntPtr;
193};
194
195template <class T, class U>
196inline bool operator==(const IntrusiveRefCntPtr<T> &A,
197 const IntrusiveRefCntPtr<U> &B) {
198 return A.get() == B.get();
199}
200
201template <class T, class U>
202inline bool operator!=(const IntrusiveRefCntPtr<T> &A,
203 const IntrusiveRefCntPtr<U> &B) {
204 return A.get() != B.get();
205}
206
207template <class T, class U>
208inline bool operator==(const IntrusiveRefCntPtr<T> &A, U *B) {
209 return A.get() == B;
210}
211
212template <class T, class U>
213inline bool operator!=(const IntrusiveRefCntPtr<T> &A, U *B) {
214 return A.get() != B;
215}
216
217template <class T, class U>
218inline bool operator==(T *A, const IntrusiveRefCntPtr<U> &B) {
219 return A == B.get();
220}
221
222template <class T, class U>
223inline bool operator!=(T *A, const IntrusiveRefCntPtr<U> &B) {
224 return A != B.get();
225}
226
227template <class T>
228bool operator==(std::nullptr_t A, const IntrusiveRefCntPtr<T> &B) {
229 return !B;
230}
231
232template <class T>
233bool operator==(const IntrusiveRefCntPtr<T> &A, std::nullptr_t B) {
234 return B == A;
235}
236
237template <class T>
238bool operator!=(std::nullptr_t A, const IntrusiveRefCntPtr<T> &B) {
239 return !(A == B);
240}
241
242template <class T>
243bool operator!=(const IntrusiveRefCntPtr<T> &A, std::nullptr_t B) {
244 return !(A == B);
245}
246
247// Make IntrusiveRefCntPtr work with dyn_cast, isa, and the other idioms from
248// Casting.h.
249template <typename From> struct simplify_type;
250
251template <class T> struct simplify_type<IntrusiveRefCntPtr<T>> {
252 using SimpleType = T *;
253
254 static SimpleType getSimplifiedValue(IntrusiveRefCntPtr<T> &Val) {
255 return Val.get();
256 }
257};
258
259template <class T> struct simplify_type<const IntrusiveRefCntPtr<T>> {
260 using SimpleType = /*const*/ T *;
261
262 static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T> &Val) {
263 return Val.get();
264 }
265};
266
267} // end namespace llvm
268
269#endif // LLVM_ADT_INTRUSIVEREFCNTPTR_H