-
Notifications
You must be signed in to change notification settings - Fork 10.4k
/
Copy pathGenClass.h
239 lines (196 loc) · 9.57 KB
/
GenClass.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
//===--- GenClass.h - Swift IR generation for classes -----------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file provides the private interface to the class-emission code.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_IRGEN_GENCLASS_H
#define SWIFT_IRGEN_GENCLASS_H
#include "swift/AST/Types.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/ArrayRef.h"
namespace llvm {
class Constant;
class Value;
class Function;
class MDString;
}
namespace swift {
class ClassDecl;
class ExtensionDecl;
class ProtocolDecl;
struct SILDeclRef;
class SILType;
class VarDecl;
namespace irgen {
class ConstantStructBuilder;
class FunctionPointer;
class HeapLayout;
class IRGenFunction;
class IRGenModule;
class MemberAccessStrategy;
class OwnedAddress;
class Address;
class Size;
class StructLayout;
class TypeInfo;
enum class ClassDeallocationKind : unsigned char;
enum class FieldAccess : uint8_t;
/// Return the lowered type for the class's 'self' type within its context.
SILType getSelfType(const ClassDecl *base);
OwnedAddress projectPhysicalClassMemberAddress(
IRGenFunction &IGF, llvm::Value *base,
SILType baseType, SILType fieldType, VarDecl *field);
/// Return a strategy for accessing the given stored class property.
///
/// This API is used by RemoteAST.
MemberAccessStrategy
getPhysicalClassMemberAccessStrategy(IRGenModule &IGM,
SILType baseType, VarDecl *field);
enum ForMetaClass_t : bool {
ForClass = false,
ForMetaClass = true
};
enum HasUpdateCallback_t : bool {
DoesNotHaveUpdateCallback = false,
HasUpdateCallback = true
};
/// Creates a layout for the class \p classType with allocated tail elements
/// \p tailTypes.
///
/// The caller is responsible for deleting the returned StructLayout.
StructLayout *getClassLayoutWithTailElems(IRGenModule &IGM, SILType classType,
llvm::ArrayRef<SILType> tailTypes);
ClassDecl *getRootClassForMetaclass(IRGenModule &IGM, ClassDecl *theClass);
ClassDecl *getSuperclassDeclForMetadata(IRGenModule &IGM, ClassDecl *theClass);
CanType getSuperclassForMetadata(IRGenModule &IGM, ClassDecl *theClass);
CanType getSuperclassForMetadata(IRGenModule &IGM, CanType theClass,
bool useArchetypes = true);
enum class ClassMetadataStrategy {
/// Does the given class have resilient ancestry, or is the class itself
/// generic?
Resilient,
/// Does the class require at in-place initialization because of
/// non-fixed size properties or generic ancestry? The class does not
/// export a static symbol visible to Objective-C code.
Singleton,
/// A more restricted case of the above. Does the class require at in-place
/// initialization because of non-fixed size properties, while exporting a
/// static symbol visible to Objective-C code? The Objective-C runtime is
/// able to initialize the metadata by calling the update callback stored
/// in rodata. This strategy can only be used if the class availability
/// restricts its use to newer Objective-C runtimes that support this
/// feature.
Update,
/// An even more restricted case of the above. The class requires in-place
/// initialization on newer Objective-C runtimes, but the metadata is
/// statically valid on older runtimes because field offsets were computed
/// assuming type layouts loaded from a legacy type info YAML file.
FixedOrUpdate,
/// The class metadata is completely static and only Objective-C runtime
/// realization (and possibly field offset sliding) must be performed.
Fixed
};
std::pair<Size,Size>
emitClassPrivateDataFields(IRGenModule &IGM,
ConstantStructBuilder &builder,
ClassDecl *cls);
llvm::Constant *emitClassPrivateData(IRGenModule &IGM, ClassDecl *theClass);
llvm::Constant *emitSpecializedGenericClassPrivateData(IRGenModule &IGM,
ClassDecl *theClass,
CanType theType);
void emitGenericClassPrivateDataTemplate(IRGenModule &IGM,
ClassDecl *theClass,
llvm::SmallVectorImpl<llvm::Constant*> &fields,
Size &metaclassOffset,
Size &classRODataOffset,
Size &metaclassRODataOffset,
Size &totalSize);
llvm::Constant *emitCategoryData(IRGenModule &IGM, ExtensionDecl *ext);
llvm::Constant *emitObjCProtocolData(IRGenModule &IGM, ProtocolDecl *ext);
/// Emit a projection from a class instance to the first tail allocated
/// element.
Address emitTailProjection(IRGenFunction &IGF, llvm::Value *Base,
SILType ClassType, SILType TailType);
using TailArraysRef = llvm::ArrayRef<std::pair<SILType, llvm::Value *>>;
/// Adds the size for tail allocated arrays to \p size and returns the new
/// size value. Also updades the alignment mask to represent the alignment of
/// the largest element.
std::pair<llvm::Value *, llvm::Value *>
appendSizeForTailAllocatedArrays(IRGenFunction &IGF,
llvm::Value *size, llvm::Value *alignMask,
TailArraysRef TailArrays);
/// Emit an allocation of a class.
/// The \p StackAllocSize is an in- and out-parameter. The passed value
/// specifies the maximum object size for stack allocation. A negative value
/// means that no stack allocation is possible.
/// The returned \p StackAllocSize value is the actual size if the object is
/// allocated on the stack or -1, if the object is allocated on the heap.
llvm::Value *emitClassAllocation(IRGenFunction &IGF, SILType selfType,
bool objc, bool isBare, int &StackAllocSize, TailArraysRef TailArrays);
/// Emit an allocation of a class using a metadata value.
llvm::Value *emitClassAllocationDynamic(IRGenFunction &IGF,
llvm::Value *metadata,
SILType selfType,
bool objc,
int &StackAllocSize,
TailArraysRef TailArrays);
/// Emit class deallocation.
void emitClassDeallocation(IRGenFunction &IGF,
SILType selfType,
llvm::Value *selfValue);
/// Emit class deallocation.
void emitPartialClassDeallocation(IRGenFunction &IGF,
SILType selfType,
llvm::Value *selfValue,
llvm::Value *metadataValue);
/// Emit the constant fragile offset of the given property inside an instance
/// of the class.
llvm::Constant *tryEmitConstantClassFragilePhysicalMemberOffset(
IRGenModule &IGM, SILType baseType, VarDecl *field);
FieldAccess getClassFieldAccess(IRGenModule &IGM,
SILType baseType,
VarDecl *field);
Size getClassFieldOffset(IRGenModule &IGM,
SILType baseType,
VarDecl *field);
/// Load the instance size and alignment mask from a reference to
/// class type metadata of the given type.
std::pair<llvm::Value *, llvm::Value *>
emitClassResilientInstanceSizeAndAlignMask(IRGenFunction &IGF,
ClassDecl *theClass,
llvm::Value *metadata);
/// For VFE, returns a type identifier for the given base method on a class.
llvm::MDString *typeIdForMethod(IRGenModule &IGM, SILDeclRef method);
/// Given a metadata pointer, emit the callee for the given method.
FunctionPointer emitVirtualMethodValue(IRGenFunction &IGF,
llvm::Value *metadata,
SILDeclRef method,
CanSILFunctionType methodType);
/// Given an instance pointer (or, for a static method, a class
/// pointer), emit the callee for the given method.
FunctionPointer emitVirtualMethodValue(IRGenFunction &IGF, llvm::Value *base,
SILType baseType, SILDeclRef method,
CanSILFunctionType methodType,
bool useSuperVTable);
/// Is the given class known to have Swift-compatible metadata?
bool hasKnownSwiftMetadata(IRGenModule &IGM, ClassDecl *theClass);
inline bool isKnownNotTaggedPointer(IRGenModule &IGM, ClassDecl *theClass) {
// For now, assume any class type defined in Clang might be tagged.
return hasKnownSwiftMetadata(IGM, theClass);
}
/// Is the given class-like type known to have Swift-compatible
/// metadata?
bool hasKnownSwiftMetadata(IRGenModule &IGM, CanType theType);
} // end namespace irgen
} // end namespace swift
#endif