1//
2// Copyright (c) 2019 Apple, Inc. All rights reserved.
3//
4// @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5//
6// This file contains Original Code and/or Modifications of Original Code
7// as defined in and that are subject to the Apple Public Source License
8// Version 2.0 (the 'License'). You may not use this file except in
9// compliance with the License. The rights granted to you under the License
10// may not be used to create, or enable the creation or redistribution of,
11// unlawful or unlicensed copies of an Apple operating system, or to
12// circumvent, violate, or enable the circumvention or violation of, any
13// terms of an Apple operating system software license agreement.
14//
15// Please obtain a copy of the License at
16// http://www.opensource.apple.com/apsl/ and read it before using this file.
17//
18// The Original Code and all software distributed under the License are
19// distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20// EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21// INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22// FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23// Please see the License for the specific language governing rights and
24// limitations under the License.
25//
26// @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27//
28
29#ifndef XNU_LIBKERN_LIBKERN_CXX_OS_PTR_H
30#define XNU_LIBKERN_LIBKERN_CXX_OS_PTR_H
31
32//
33// The declarations in this file are a transition tool from raw pointers to
34// the new OSSharedPtr class.
35//
36// Basically, code in headers that wants to be able to vend both a raw pointer
37// and a shared pointer interface should use `OSPtr<T>` instead of `T*`.
38// Then, users that want to opt into using `OSSharedPtr` can define the
39// `IOKIT_ENABLE_SHARED_PTR` macro in their translation unit (.cpp file),
40// and `OSPtr<T>` will suddenly be `OSSharedPtr<T>`.
41//
42// When the `IOKIT_ENABLE_SHARED_PTR` macro is not enabled, however, `OSPtr<T>`
43// will simply be `T*`, so that clients that do not wish to migrate to smart
44// pointers don't need to.
45//
46// Note that defining `IOKIT_ENABLE_SHARED_PTR` requires C++17, because the
47// implementation of `OSSharedPtr` requires that.
48//
49
50#if !defined(PRIVATE) // only ask to opt-in explicitly for third-party developers
51# if defined(IOKIT_ENABLE_SHARED_PTR)
52# if !defined(IOKIT_ENABLE_EXPERIMENTAL_SHARED_PTR_IN_API)
53# error It seems that you have defined IOKIT_ENABLE_SHARED_PTR to \
54 ask IOKit to return shared pointers from many of its API \
55 functions. This is great! However, please note that we may \
56 transition more IOKit APIs to shared pointers in the future, \
57 so if you enable IOKIT_ENABLE_SHARED_PTR right now, your \
58 code may fail to compile with future versions of IOKit \
59 (which would return shared pointers where you expect raw \
60 pointers). If you are OK with that, please define the \
61 IOKIT_ENABLE_EXPERIMENTAL_SHARED_PTR_IN_API macro to \
62 silence this error. If that is not acceptable, please hold \
63 off on enabling shared pointers in IOKit APIs until we have \
64 committed to API stability for it.
65# endif
66# endif
67#endif
68
69#if defined(IOKIT_ENABLE_SHARED_PTR)
70
71#define __returns_nonnull_osptr
72
73#if __cplusplus < 201703L
74#error "Your code must compile with C++17 or later to adopt shared pointers. Use Xcode's 'C++ Language Dialect' setting, or on clang's command-line use -std=gnu++17"
75#endif
76
77#include <libkern/c++/OSSharedPtr.h>
78
79template <typename T>
80using OSPtr = OSSharedPtr<T>;
81
82class OSCollection; // Forward declare only because OSCollection.h needs OSPtr.h
83
84template <typename T>
85using OSTaggedPtr = OSTaggedSharedPtr<T, OSCollection>;
86
87#else
88
89#if __has_attribute(returns_nonnull)
90#define __returns_nonnull_osptr __attribute__((returns_nonnull))
91#else
92#define __returns_nonnull_osptr
93#endif
94
95template <typename T>
96class __attribute__((trivial_abi)) OSSharedPtr;
97
98template <typename T, typename Tag>
99class __attribute__((trivial_abi)) OSTaggedSharedPtr;
100
101// We're not necessarily in C++11 mode, so we need to disable warnings
102// for C++11 extensions
103#pragma clang diagnostic push
104#pragma clang diagnostic ignored "-Wc++11-extensions"
105
106template <typename T>
107using OSPtr = T *;
108
109template <typename T>
110using OSTaggedPtr = T *;
111
112#pragma clang diagnostic pop
113
114#endif
115
116// Allow C++98 code to use nullptr.
117//
118// This isn't the right place to put this, however the old OSPtr.h header
119// had it and some code has now started relying on nullptr being defined.
120#if !__has_feature(cxx_nullptr) && !defined(nullptr)
121# define nullptr NULL
122#endif
123
124#endif // !XNU_LIBKERN_LIBKERN_CXX_OS_PTR_H
125