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 79 template <typename T> 80 using OSPtr = OSSharedPtr<T>; 81 82 class OSCollection; // Forward declare only because OSCollection.h needs OSPtr.h 83 84 template <typename T> 85 using 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 95 template <typename T> 96 class __attribute__((trivial_abi)) OSSharedPtr; 97 98 template <typename T, typename Tag> 99 class __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 106 template <typename T> 107 using OSPtr = T *; 108 109 template <typename T> 110 using 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