|
| 1 | +//===--- ReferenceStorage.def - Non-default reference storage ---*- C++ -*-===// |
| 2 | +// |
| 3 | +// This source file is part of the Swift.org open source project |
| 4 | +// |
| 5 | +// Copyright (c) 2018 Apple Inc. and the Swift project authors |
| 6 | +// Licensed under Apache License v2.0 with Runtime Library Exception |
| 7 | +// |
| 8 | +// See https://swift.org/LICENSE.txt for license information |
| 9 | +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
| 10 | +// |
| 11 | +//===----------------------------------------------------------------------===// |
| 12 | +// |
| 13 | +// This file defines non-default reference storage kind macros used for |
| 14 | +// macro-metaprogramming. |
| 15 | +// |
| 16 | +//===----------------------------------------------------------------------===// |
| 17 | + |
| 18 | +/// There are two fundamental reference storage types: checked and unchecked. |
| 19 | +/// Checked storage types have runtime enforced correctness. |
| 20 | +/// Unchecked storage types have no runtime enforced correctness. |
| 21 | +/// |
| 22 | +/// Checked reference storage types are also subcategorized by loadability. |
| 23 | +/// * Always loadable: The compiler may move the reference or use registers. |
| 24 | +/// * Never loadable: The runtime (etc) tracks the address of the reference. |
| 25 | +/// * Sometimes loadable: If the reference is a native object, then it is |
| 26 | +/// always loadable. Otherwise fall back to never loadable semantics, a.k.a. |
| 27 | +/// "address only". |
| 28 | +/// |
| 29 | +/// Unchecked reference storage types are always loadable. |
| 30 | +/// |
| 31 | +/// The primary macros therefore are: |
| 32 | +/// * ALWAYS_LOADABLE_CHECKED_REF_STORAGE |
| 33 | +/// * SOMETIMES_LOADABLE_CHECKED_REF_STORAGE |
| 34 | +/// * NEVER_LOADABLE_CHECKED_REF_STORAGE |
| 35 | +/// * UNCHECKED_REF_STORAGE |
| 36 | +/// |
| 37 | +/// Helper macros include: |
| 38 | +/// * CHECKED_REF_STORAGE -- Any checked reference storage type. Specifically |
| 39 | +/// "always", "sometimes", and "never" -- but not "unchecked". |
| 40 | +/// * LOADABLE_REF_STORAGE -- Any loadable reference storage type. Specifically |
| 41 | +/// "always", "sometimes", and "unchecked" -- but not "never". |
| 42 | +/// * ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE -- self describing. |
| 43 | +/// * NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE -- self describing. |
| 44 | +/// |
| 45 | +/// SUBSYSTEMS NOTES |
| 46 | +/// |
| 47 | +/// In general, reference storage types are barely visible in the user facing |
| 48 | +/// type system and therefore AST clients above SIL can get away with |
| 49 | +/// just REF_STORAGE, or CHECKED_REF_STORAGE with UNCHECKED_REF_STORAGE. |
| 50 | +/// |
| 51 | +/// When it comes to SIL aware AST clients, loadability matters. The best way |
| 52 | +/// to understand how the helper macros are used is to look at SILNodes.def. |
| 53 | +/// What follows is a short -- possibly not up to date -- summary: |
| 54 | +/// |
| 55 | +/// UNCHECKED_REF_STORAGE |
| 56 | +/// Name##RetainValueInst |
| 57 | +/// Name##ReleaseValueInst |
| 58 | +/// LOADABLE_REF_STORAGE |
| 59 | +/// Ref*ToNameInst |
| 60 | +/// Name*ToRefInst |
| 61 | +/// NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE |
| 62 | +/// Load##Name##Inst |
| 63 | +/// Store##Name##Inst |
| 64 | +/// ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE |
| 65 | +/// Copy##Name##ValueInst |
| 66 | +/// StrongRetain##Name##Inst |
| 67 | +/// Name##RetainInst |
| 68 | +/// Name##ReleaseInst |
| 69 | +/// |
| 70 | +/// After helper macro expansion: |
| 71 | +/// |
| 72 | +/// UNCHECKED_REF_STORAGE |
| 73 | +/// Ref*ToNameInst |
| 74 | +/// Name*ToRefInst |
| 75 | +/// Name##RetainValueInst |
| 76 | +/// Name##ReleaseValueInst |
| 77 | +/// ALWAYS_LOADABLE_CHECKED_REF_STORAGE |
| 78 | +/// Ref*ToNameInst |
| 79 | +/// Name*ToRefInst |
| 80 | +/// Copy##Name##ValueInst |
| 81 | +/// StrongRetain##Name##Inst |
| 82 | +/// Name##RetainInst |
| 83 | +/// Name##ReleaseInst |
| 84 | +/// SOMETIMES_LOADABLE_CHECKED_REF_STORAGE |
| 85 | +/// Ref*ToNameInst |
| 86 | +/// Name*ToRefInst |
| 87 | +/// Load##Name##Inst |
| 88 | +/// Store##Name##Inst |
| 89 | +/// Copy##Name##ValueInst |
| 90 | +/// StrongRetain##Name##Inst |
| 91 | +/// Name##RetainInst |
| 92 | +/// Name##ReleaseInst |
| 93 | +/// NEVER_LOADABLE_CHECKED_REF_STORAGE |
| 94 | +/// Load##Name##Inst |
| 95 | +/// Store##Name##Inst |
| 96 | +/// |
| 97 | +/// Finally, a note about IRGen: TypeInfos need to be created per reference |
| 98 | +/// storage type, and SOMETIMES_LOADABLE_CHECKED_REF_STORAGE needs *two* |
| 99 | +/// TypeInfos to be created. One for the loadable scenario, and one for the |
| 100 | +/// address-only scenario. |
| 101 | + |
| 102 | + |
| 103 | +#ifndef REF_STORAGE |
| 104 | +#define REF_STORAGE(Name, name, NAME) |
| 105 | +#endif |
| 106 | + |
| 107 | +#ifdef ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE |
| 108 | + #if defined(ALWAYS_LOADABLE_CHECKED_REF_STORAGE) || \ |
| 109 | + defined(SOMETIMES_LOADABLE_CHECKED_REF_STORAGE) |
| 110 | + #error Overlapping meta-programming macros |
| 111 | + #endif |
| 112 | + #define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \ |
| 113 | + ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) |
| 114 | + #define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \ |
| 115 | + ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) |
| 116 | +#endif |
| 117 | + |
| 118 | +#ifdef NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE |
| 119 | + #if defined(NEVER_LOADABLE_CHECKED_REF_STORAGE) || \ |
| 120 | + defined(SOMETIMES_LOADABLE_CHECKED_REF_STORAGE) |
| 121 | + #error Overlapping meta-programming macros |
| 122 | + #endif |
| 123 | + #define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \ |
| 124 | + NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) |
| 125 | + #define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \ |
| 126 | + NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) |
| 127 | +#endif |
| 128 | + |
| 129 | +#ifdef LOADABLE_REF_STORAGE |
| 130 | + #if defined(ALWAYS_LOADABLE_CHECKED_REF_STORAGE) || \ |
| 131 | + defined(SOMETIMES_LOADABLE_CHECKED_REF_STORAGE) || \ |
| 132 | + defined(UNCHECKED_REF_STORAGE) |
| 133 | + #error Overlapping meta-programming macros |
| 134 | + #endif |
| 135 | + #define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \ |
| 136 | + LOADABLE_REF_STORAGE(Name, name, NAME) |
| 137 | + #define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \ |
| 138 | + LOADABLE_REF_STORAGE(Name, name, NAME) |
| 139 | + #define UNCHECKED_REF_STORAGE(Name, name, NAME) \ |
| 140 | + LOADABLE_REF_STORAGE(Name, name, NAME) |
| 141 | +#endif |
| 142 | + |
| 143 | +#ifdef CHECKED_REF_STORAGE |
| 144 | + #if defined(SOMETIMES_LOADABLE_CHECKED_REF_STORAGE) || \ |
| 145 | + defined(ALWAYS_LOADABLE_CHECKED_REF_STORAGE) || \ |
| 146 | + defined(NEVER_LOADABLE_CHECKED_REF_STORAGE) |
| 147 | + #error Overlapping meta-programming macros |
| 148 | + #endif |
| 149 | + #define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \ |
| 150 | + CHECKED_REF_STORAGE(Name, name, NAME) |
| 151 | + #define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \ |
| 152 | + CHECKED_REF_STORAGE(Name, name, NAME) |
| 153 | + #define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \ |
| 154 | + CHECKED_REF_STORAGE(Name, name, NAME) |
| 155 | +#endif |
| 156 | + |
| 157 | +#ifndef NEVER_LOADABLE_CHECKED_REF_STORAGE |
| 158 | +#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \ |
| 159 | + REF_STORAGE(Name, name, NAME) |
| 160 | +#endif |
| 161 | + |
| 162 | +#ifndef SOMETIMES_LOADABLE_CHECKED_REF_STORAGE |
| 163 | +#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \ |
| 164 | + REF_STORAGE(Name, name, NAME) |
| 165 | +#endif |
| 166 | + |
| 167 | +#ifndef ALWAYS_LOADABLE_CHECKED_REF_STORAGE |
| 168 | +#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \ |
| 169 | + REF_STORAGE(Name, name, NAME) |
| 170 | +#endif |
| 171 | + |
| 172 | +#ifndef UNCHECKED_REF_STORAGE |
| 173 | +#define UNCHECKED_REF_STORAGE(Name, name, NAME) \ |
| 174 | + REF_STORAGE(Name, name, NAME) |
| 175 | +#endif |
| 176 | + |
| 177 | +#ifndef REF_STORAGE_RANGE |
| 178 | +#define REF_STORAGE_RANGE(First, Last) |
| 179 | +#endif |
| 180 | + |
| 181 | +// NOTE: You will need to update ReferenceOwnership in ModuleFormat.h. |
| 182 | +NEVER_LOADABLE_CHECKED_REF_STORAGE(Weak, weak, WEAK) |
| 183 | +SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Unowned, unowned, UNOWNED) |
| 184 | +UNCHECKED_REF_STORAGE(Unmanaged, unmanaged, UNMANAGED) |
| 185 | +REF_STORAGE_RANGE(Weak, Unmanaged) |
| 186 | + |
| 187 | +#undef REF_STORAGE |
| 188 | +#undef NEVER_LOADABLE_CHECKED_REF_STORAGE |
| 189 | +#undef ALWAYS_LOADABLE_CHECKED_REF_STORAGE |
| 190 | +#undef SOMETIMES_LOADABLE_CHECKED_REF_STORAGE |
| 191 | +#undef UNCHECKED_REF_STORAGE |
| 192 | +#undef REF_STORAGE_RANGE |
| 193 | + |
| 194 | +#undef ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE |
| 195 | +#undef NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE |
| 196 | +#undef LOADABLE_REF_STORAGE |
| 197 | +#undef CHECKED_REF_STORAGE |
0 commit comments