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///   StrongCopy##Name##ValueInst
59/// LOADABLE_REF_STORAGE
60///   Ref*ToNameInst
61///   Name*ToRefInst
62/// NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE
63///   Load##Name##Inst
64///   Store##Name##Inst
65/// ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE
66///   StrongCopy##Name##ValueInst
67///   StrongRetain##Name##Inst
68///   Name##RetainInst
69///   Name##ReleaseInst
70///
71/// After helper macro expansion:
72///
73/// UNCHECKED_REF_STORAGE
74///   Ref*ToNameInst
75///   Name*ToRefInst
76///   Name##RetainValueInst
77///   Name##ReleaseValueInst
78/// ALWAYS_LOADABLE_CHECKED_REF_STORAGE
79///   Ref*ToNameInst
80///   Name*ToRefInst
81///   StrongCopy##Name##ValueInst
82///   StrongRetain##Name##Inst
83///   Name##RetainInst
84///   Name##ReleaseInst
85/// SOMETIMES_LOADABLE_CHECKED_REF_STORAGE
86///   Ref*ToNameInst
87///   Name*ToRefInst
88///   Load##Name##Inst
89///   Store##Name##Inst
90///   StrongCopy##Name##ValueInst
91///   StrongRetain##Name##Inst
92///   Name##RetainInst
93///   Name##ReleaseInst
94/// NEVER_LOADABLE_CHECKED_REF_STORAGE
95///   Load##Name##Inst
96///   Store##Name##Inst
97///
98/// Finally, a note about IRGen: TypeInfos need to be created per reference
99/// storage type, and SOMETIMES_LOADABLE_CHECKED_REF_STORAGE needs *two*
100/// TypeInfos to be created. One for the loadable scenario, and one for the
101/// address-only scenario.
102///
103/// TODO: We should change Copy##Name##ValueInst to be defined on
104/// LOADABLE_REF_STORAGE. It just will require us to go through, refactor, and
105/// fix up this code.
106
107
108#ifndef REF_STORAGE
109#define REF_STORAGE(Name, name, NAME)
110#endif
111
112#ifdef ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE
113  #if defined(ALWAYS_LOADABLE_CHECKED_REF_STORAGE) || \
114      defined(SOMETIMES_LOADABLE_CHECKED_REF_STORAGE)
115    #error Overlapping meta-programming macros
116  #endif
117  #define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \
118    ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME)
119  #define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \
120    ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME)
121#endif
122
123#ifdef NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE
124  #if defined(NEVER_LOADABLE_CHECKED_REF_STORAGE) || \
125      defined(SOMETIMES_LOADABLE_CHECKED_REF_STORAGE)
126    #error Overlapping meta-programming macros
127  #endif
128  #define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \
129     NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME)
130  #define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \
131     NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME)
132#endif
133
134#ifdef LOADABLE_REF_STORAGE
135  #if defined(ALWAYS_LOADABLE_CHECKED_REF_STORAGE) || \
136      defined(SOMETIMES_LOADABLE_CHECKED_REF_STORAGE) || \
137      defined(UNCHECKED_REF_STORAGE)
138    #error Overlapping meta-programming macros
139  #endif
140  #define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \
141    LOADABLE_REF_STORAGE(Name, name, NAME)
142  #define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \
143    LOADABLE_REF_STORAGE(Name, name, NAME)
144  #define UNCHECKED_REF_STORAGE(Name, name, NAME) \
145    LOADABLE_REF_STORAGE(Name, name, NAME)
146#endif
147
148#ifdef CHECKED_REF_STORAGE
149  #if defined(SOMETIMES_LOADABLE_CHECKED_REF_STORAGE) || \
150      defined(ALWAYS_LOADABLE_CHECKED_REF_STORAGE) || \
151      defined(NEVER_LOADABLE_CHECKED_REF_STORAGE)
152    #error Overlapping meta-programming macros
153  #endif
154  #define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \
155    CHECKED_REF_STORAGE(Name, name, NAME)
156  #define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \
157    CHECKED_REF_STORAGE(Name, name, NAME)
158  #define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \
159    CHECKED_REF_STORAGE(Name, name, NAME)
160#endif
161
162#ifndef NEVER_LOADABLE_CHECKED_REF_STORAGE
163#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \
164  REF_STORAGE(Name, name, NAME)
165#endif
166
167#ifndef SOMETIMES_LOADABLE_CHECKED_REF_STORAGE
168#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \
169  REF_STORAGE(Name, name, NAME)
170#endif
171
172#ifndef ALWAYS_LOADABLE_CHECKED_REF_STORAGE
173#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \
174  REF_STORAGE(Name, name, NAME)
175#endif
176
177#ifndef UNCHECKED_REF_STORAGE
178#define UNCHECKED_REF_STORAGE(Name, name, NAME) \
179  REF_STORAGE(Name, name, NAME)
180#endif
181
182#ifndef REF_STORAGE_RANGE
183#define REF_STORAGE_RANGE(First, Last)
184#endif
185
186// NOTE: You will need to update ReferenceOwnership in ModuleFormat.h.
187NEVER_LOADABLE_CHECKED_REF_STORAGE(Weak, weak, WEAK)
188SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Unowned, unowned, UNOWNED)
189UNCHECKED_REF_STORAGE(Unmanaged, unmanaged, UNMANAGED)
190REF_STORAGE_RANGE(Weak, Unmanaged)
191
192#undef REF_STORAGE
193#undef NEVER_LOADABLE_CHECKED_REF_STORAGE
194#undef ALWAYS_LOADABLE_CHECKED_REF_STORAGE
195#undef SOMETIMES_LOADABLE_CHECKED_REF_STORAGE
196#undef UNCHECKED_REF_STORAGE
197#undef REF_STORAGE_RANGE
198
199#undef ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE
200#undef NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE
201#undef LOADABLE_REF_STORAGE
202#undef CHECKED_REF_STORAGE
203