-
Notifications
You must be signed in to change notification settings - Fork 10.4k
/
Copy pathSILGen.h
637 lines (512 loc) · 26.4 KB
/
SILGen.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
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
//===--- SILGen.h - Implements Lowering of ASTs -> SIL ----------*- 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
//
//===----------------------------------------------------------------------===//
#ifndef SILGEN_H
#define SILGEN_H
#include "ASTVisitor.h"
#include "Cleanup.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/AnyFunctionRef.h"
#include "swift/AST/DiagnosticEngine.h"
#include "swift/SIL/SILDebugScope.h"
#include "swift/SIL/SILFunction.h"
#include "swift/SIL/SILModule.h"
#include "swift/SIL/TypeLowering.h"
#include "llvm/ADT/DenseMap.h"
#include <deque>
namespace swift {
class SILBasicBlock;
class ForeignAsyncConvention;
class SymbolSource;
namespace Lowering {
class TypeConverter;
class SILGenFunction;
class CalleeTypeInfo;
/// An enum to indicate whether a protocol method requirement is satisfied by
/// a free function, as for an operator requirement.
enum IsFreeFunctionWitness_t : bool {
IsNotFreeFunctionWitness = false,
IsFreeFunctionWitness = true,
};
/// An ASTVisitor for generating SIL from top-level declarations in a module.
class LLVM_LIBRARY_VISIBILITY SILGenModule : public ASTVisitor<SILGenModule> {
public:
/// The Module being constructed.
SILModule &M;
/// The type converter for the module.
TypeConverter &Types;
/// The Swift module we are visiting.
ModuleDecl *SwiftModule;
/// Mapping from SILDeclRefs to emitted SILFunctions.
llvm::DenseMap<SILDeclRef, SILFunction*> emittedFunctions;
/// Mapping from ProtocolConformances to emitted SILWitnessTables.
llvm::DenseMap<NormalProtocolConformance*, SILWitnessTable*> emittedWitnessTables;
/// Mapping from SILDeclRefs to where the given function will be inserted
/// when it's emitted. Used for non-externally visible symbols.
llvm::DenseMap<SILDeclRef, SILDeclRef> delayedFunctions;
/// Queue of delayed SILFunctions that need to be forced.
std::deque<SILDeclRef> pendingForcedFunctions;
/// Delayed SILFunctions that need to be forced.
llvm::DenseSet<SILDeclRef> forcedFunctions;
/// Mapping global VarDecls to their onceToken and onceFunc, respectively.
llvm::DenseMap<VarDecl *, std::pair<SILGlobalVariable *,
SILFunction *>> delayedGlobals;
/// Bookkeeping to ensure that useConformancesFrom{ObjectiveC,}Type() is
/// only called once for each unique type, as an optimization.
llvm::DenseSet<TypeBase *> usedConformancesFromTypes;
llvm::DenseSet<TypeBase *> usedConformancesFromObjectiveCTypes;
/// Queue of delayed conformances that need to be emitted.
std::deque<NormalProtocolConformance *> pendingConformances;
/// Set of delayed conformances that have already been forced.
llvm::DenseSet<NormalProtocolConformance *> forcedConformances;
size_t anonymousSymbolCounter = 0;
std::optional<SILDeclRef> StringToNSStringFn;
std::optional<SILDeclRef> NSStringToStringFn;
std::optional<SILDeclRef> ArrayToNSArrayFn;
std::optional<SILDeclRef> NSArrayToArrayFn;
std::optional<SILDeclRef> DictionaryToNSDictionaryFn;
std::optional<SILDeclRef> NSDictionaryToDictionaryFn;
std::optional<SILDeclRef> SetToNSSetFn;
std::optional<SILDeclRef> NSSetToSetFn;
std::optional<SILDeclRef> BoolToObjCBoolFn;
std::optional<SILDeclRef> ObjCBoolToBoolFn;
std::optional<SILDeclRef> BoolToDarwinBooleanFn;
std::optional<SILDeclRef> DarwinBooleanToBoolFn;
std::optional<SILDeclRef> NSErrorToErrorFn;
std::optional<SILDeclRef> ErrorToNSErrorFn;
std::optional<SILDeclRef> BoolToWindowsBoolFn;
std::optional<SILDeclRef> WindowsBoolToBoolFn;
std::optional<ProtocolDecl *> PointerProtocol;
std::optional<ProtocolDecl *> ObjectiveCBridgeable;
std::optional<FuncDecl *> BridgeToObjectiveCRequirement;
std::optional<FuncDecl *> UnconditionallyBridgeFromObjectiveCRequirement;
std::optional<AssociatedTypeDecl *> BridgedObjectiveCType;
std::optional<ProtocolDecl *> BridgedStoredNSError;
std::optional<VarDecl *> NSErrorRequirement;
std::optional<ProtocolConformance *> NSErrorConformanceToError;
public:
SILGenModule(SILModule &M, ModuleDecl *SM);
~SILGenModule();
SILGenModule(SILGenModule const &) = delete;
void operator=(SILGenModule const &) = delete;
ASTContext &getASTContext() { return M.getASTContext(); }
/// Main entry point.
void emitSourceFile(SourceFile *sf);
/// Lazy entry point for Feature::LazyImmediate.
void emitSymbolSource(SymbolSource Source);
llvm::StringMap<std::pair<std::string, /*isWinner=*/bool>> FileIDsByFilePath;
static DeclName getMagicFunctionName(SILDeclRef ref);
static DeclName getMagicFunctionName(DeclContext *dc);
/// Get the function for a SILDeclRef, or return nullptr if it hasn't been
/// emitted yet.
SILFunction *getEmittedFunction(SILDeclRef constant,
ForDefinition_t forDefinition);
/// Get the function for a SILDeclRef, creating it if necessary.
SILFunction *getFunction(SILDeclRef constant,
ForDefinition_t forDefinition);
/// Get the dynamic dispatch thunk for a SILDeclRef.
SILFunction *getDynamicThunk(SILDeclRef constant,
CanSILFunctionType constantTy);
/// Emit a vtable thunk for a derived method if its natural abstraction level
/// diverges from the overridden base method. If no thunking is needed,
/// returns a static reference to the derived method.
std::optional<SILVTable::Entry>
emitVTableMethod(ClassDecl *theClass, SILDeclRef derived, SILDeclRef base);
/// True if a function has been emitted for a given SILDeclRef.
bool hasFunction(SILDeclRef constant);
/// Get or create the declaration of a reabstraction thunk with the
/// given signature.
SILFunction *getOrCreateReabstractionThunk(
CanSILFunctionType thunkType,
CanSILFunctionType fromType,
CanSILFunctionType toType,
CanType dynamicSelfType,
CanType fromGlobalActor);
/// Get or create the declaration of a completion handler block
/// implementation function for an ObjC API that was imported
/// as `async` in Swift.
SILFunction *getOrCreateForeignAsyncCompletionHandlerImplFunction(
CanSILFunctionType blockType, CanType blockStorageType,
CanType continuationType, AbstractionPattern origFormalType,
CanGenericSignature sig, CalleeTypeInfo &calleeInfo);
/// Determine whether the given class has any instance variables that
/// need to be destroyed.
bool hasNonTrivialIVars(ClassDecl *cd);
/// Given an original function and a user-specified custom derivative
/// function, get or create a derivative thunk with the expected derivative
/// function type computed from the original function.
///
/// To achieve the expected derivative type, the thunk may perform
/// self-reordering, reabstraction, or both.
///
/// Self-reordering is done for canonicalizing the types of derivative
/// functions for instance methods wrt `self`. We want users to define
/// derivatives with the following AST function types:
///
/// JVP:
/// - Takes `Self` as first parameter.
/// - Returns differential taking `Self.Tan` as first parameter.
///
/// (Self) -> (T, ...) -> (R, (Self.Tan, T.Tan, ...) -> R.Tan)
///
/// VJP:
/// - Takes `Self` as first parameter.
/// - Returns pullback returning `Self.Tan` as first result.
///
/// (Self) -> (T, ...) -> (R, (R.Tan) -> (Self.Tan, T.Tan, ...))
///
/// However, the curried `Self` parameter in the AST JVP/VJP function types
/// becomes the *last* parameter in the flattened parameter list of their
/// lowered SIL function types.
///
/// JVP:
/// - Takes `Self` as *last* parameter.
/// - Returns differential taking `Self.Tan` as *first* parameter.
///
/// $(T, ..., Self) -> (R, (Self.Tan, T.Tan, ...) -> R.Tan)
///
/// VJP:
/// - Takes `Self` as *last* parameter.
/// - Returns pullback returning `Self.Tan` as *first* result.
///
/// $(T, ..., Self) -> (R, (R.Tan) -> (Self.Tan, T.Tan, ...))
///
/// This leads to a parameter ordering inconsistency, and would require the
/// differentiation transform to handle "wrt `self` instance method
/// derivatives" specially. However, canonicalization during SILGen makes the
/// parameter ordering uniform for "instance method derivatives wrt self" and
/// simplifies the transform rules.
///
/// If `self` must be reordered, reorder it so that it appears as:
/// - The last parameter in the returned differential.
/// - The last result in the returned pullback.
SILFunction *getOrCreateCustomDerivativeThunk(
AbstractFunctionDecl *originalAFD, SILFunction *originalFn,
SILFunction *customDerivativeFn, const AutoDiffConfig &config,
AutoDiffDerivativeFunctionKind kind);
/// Get or create a derivative function vtable entry thunk for the given
/// SILDeclRef and derivative function type.
SILFunction *getOrCreateDerivativeVTableThunk(
SILDeclRef derivativeFnRef, CanSILFunctionType derivativeFnTy);
/// Determine whether we need to emit an ivar destroyer for the given class.
/// An ivar destroyer is needed if a superclass of this class may define a
/// failing designated initializer.
bool requiresIVarDestroyer(ClassDecl *cd);
//===--------------------------------------------------------------------===//
// Visitors for top-level forms
//===--------------------------------------------------------------------===//
/// Returns true if SILGen should be skipped for the given decl.
bool shouldSkipDecl(Decl *d);
void visit(Decl *D);
// These are either not allowed at global scope or don't require
// code emission.
void visitImportDecl(ImportDecl *d) {}
void visitEnumCaseDecl(EnumCaseDecl *d) {}
void visitEnumElementDecl(EnumElementDecl *d) {}
void visitOperatorDecl(OperatorDecl *d) {}
void visitPrecedenceGroupDecl(PrecedenceGroupDecl *d) {}
void visitTypeAliasDecl(TypeAliasDecl *d) {}
void visitOpaqueTypeDecl(OpaqueTypeDecl *d) {}
void visitGenericTypeParamDecl(GenericTypeParamDecl *d) {}
void visitAssociatedTypeDecl(AssociatedTypeDecl *d) {}
void visitConstructorDecl(ConstructorDecl *d) {}
void visitDestructorDecl(DestructorDecl *d) {}
void visitModuleDecl(ModuleDecl *d) { }
void visitMissingMemberDecl(MissingMemberDecl *d) {}
// Emitted as part of its storage.
void visitAccessorDecl(AccessorDecl *ad) {}
void visitFuncDecl(FuncDecl *fd);
void visitPatternBindingDecl(PatternBindingDecl *vd);
void visitTopLevelCodeDecl(TopLevelCodeDecl *td) {}
void visitNominalTypeDecl(NominalTypeDecl *ntd);
void visitExtensionDecl(ExtensionDecl *ed);
void visitVarDecl(VarDecl *vd);
void visitSubscriptDecl(SubscriptDecl *sd);
void visitMissingDecl(MissingDecl *d);
void visitMacroDecl(MacroDecl *d);
void visitMacroExpansionDecl(MacroExpansionDecl *d);
// Same as AbstractStorageDecl::visitEmittedAccessors, but skips over skipped
// (unavailable) decls.
void visitEmittedAccessors(AbstractStorageDecl *D,
llvm::function_ref<void(AccessorDecl *)>);
void emitEntryPoint(SourceFile *SF);
void emitEntryPoint(SourceFile *SF, SILFunction *TopLevel);
void emitAbstractFuncDecl(AbstractFunctionDecl *AFD);
/// Generates code for the given FuncDecl and adds the
/// SILFunction to the current SILModule under the name SILDeclRef(decl). For
/// curried functions, curried entry point Functions are also generated and
/// added to the current SILModule.
void emitFunction(FuncDecl *fd);
/// Emits the function definition for a given SILDeclRef.
void emitFunctionDefinition(SILDeclRef constant, SILFunction *f);
/// Emit a function now, if it's externally usable or has been referenced in
/// the current TU, or remember how to emit it later if not.
void emitOrDelayFunction(SILDeclRef constant);
/// Generates code for the given closure expression and adds the
/// SILFunction to the current SILModule under the name SILDeclRef(ce).
SILFunction *emitClosure(AbstractClosureExpr *ce,
const FunctionTypeInfo &closureInfo);
/// Generates code for the given ConstructorDecl and adds
/// the SILFunction to the current SILModule under the name SILDeclRef(decl).
void emitConstructor(ConstructorDecl *decl);
/// Generates code for the given class's destructor and adds
/// the SILFunction to the current SILModule under the name
/// SILDeclRef(cd, Destructor).
///
/// TODO: Rename to emitClassDestructor.
void emitDestructor(ClassDecl *cd, DestructorDecl *dd);
/// Generates code for the given move only nominal type's destructor and adds
/// the SILFunction to the current SILModule under the name SILDeclRef(nd,
/// dd).
void emitMoveOnlyDestructor(NominalTypeDecl *nd, DestructorDecl *dd);
/// Emits the default argument generator with the given expression.
void emitDefaultArgGenerator(SILDeclRef constant, ParamDecl *param);
/// Emits the stored property initializer for the given pattern.
void emitStoredPropertyInitialization(PatternBindingDecl *pd, unsigned i);
/// Emits the backing initializer for a property with an attached wrapper.
void emitPropertyWrapperBackingInitializer(VarDecl *var);
/// Emits argument generators, including default argument generators and
/// property wrapper argument generators, for the given parameter list.
void emitArgumentGenerators(SILDeclRef::Loc decl, ParameterList *paramList);
/// Emits a thunk from a foreign function to the native Swift convention.
void emitForeignToNativeThunk(SILDeclRef thunk);
/// Emits a thunk from a Swift function to the native Swift convention.
void emitNativeToForeignThunk(SILDeclRef thunk);
/// Emits the distributed actor thunk for the decl if there is one associated
/// with it.
void emitDistributedThunkForDecl(AbstractFunctionDecl * afd);
/// Returns true if the given declaration must be referenced through a
/// back deployment thunk in a context with the given resilience expansion.
bool requiresBackDeploymentThunk(ValueDecl *decl,
ResilienceExpansion expansion);
/// Emits a thunk that calls either the original function if it is available
/// or otherwise calls a fallback variant of the function that was emitted
/// into the client module.
void emitBackDeploymentThunk(SILDeclRef thunk);
void preEmitFunction(SILDeclRef constant, SILFunction *F, SILLocation L);
void postEmitFunction(SILDeclRef constant, SILFunction *F);
/// Add a global variable to the SILModule.
void addGlobalVariable(VarDecl *global);
/// Emit the ObjC-compatible entry point for a method.
void emitObjCMethodThunk(FuncDecl *method);
/// Emit the ObjC-compatible getter and setter for a property.
void emitObjCPropertyMethodThunks(AbstractStorageDecl *prop);
/// Emit the ObjC-compatible entry point for a constructor.
void emitObjCConstructorThunk(ConstructorDecl *constructor);
/// Emit the ObjC-compatible entry point for a destructor (i.e., -dealloc).
void emitObjCDestructorThunk(DestructorDecl *destructor);
/// Get or emit the witness table for a protocol conformance.
SILWitnessTable *getWitnessTable(NormalProtocolConformance *conformance);
/// Emit a protocol witness entry point.
SILFunction *
emitProtocolWitness(ProtocolConformanceRef conformance, SILLinkage linkage,
SerializedKind_t serializedKind, SILDeclRef requirement,
SILDeclRef witnessRef, IsFreeFunctionWitness_t isFree,
Witness witness);
/// Emit the default witness table for a resilient protocol.
void emitDefaultWitnessTable(ProtocolDecl *protocol);
/// Emit the self-conformance witness table for a protocol.
void emitSelfConformanceWitnessTable(ProtocolDecl *protocol);
/// Emit the lazy initializer function for a global pattern binding
/// declaration.
SILFunction *emitLazyGlobalInitializer(StringRef funcName,
PatternBindingDecl *binding,
unsigned pbdEntry);
/// Emit the accessor for a global variable or stored static property.
///
/// This ensures the lazy initializer has been run before returning the
/// address of the variable.
void emitGlobalAccessor(VarDecl *global,
SILGlobalVariable *onceToken,
SILFunction *onceFunc);
/// True if the given function requires an entry point for ObjC method
/// dispatch.
bool requiresObjCMethodEntryPoint(FuncDecl *method);
/// True if the given constructor requires an entry point for ObjC method
/// dispatch.
bool requiresObjCMethodEntryPoint(ConstructorDecl *constructor);
/// Emit a global initialization.
void emitGlobalInitialization(PatternBindingDecl *initializer, unsigned elt);
/// Is the self method of the given nonmutating method passed indirectly?
bool isNonMutatingSelfIndirect(SILDeclRef method);
SILDeclRef getFuncDeclRef(FuncDecl *funcDecl, ResilienceExpansion expansion);
bool canStorageUseStoredKeyPathComponent(AbstractStorageDecl *decl,
ResilienceExpansion expansion);
KeyPathPatternComponent emitKeyPathComponentForDecl(
SILLocation loc, GenericEnvironment *genericEnv,
ResilienceExpansion expansion, unsigned &baseOperand,
bool &needsGenericContext, SubstitutionMap subs, ValueDecl *decl,
ArrayRef<ProtocolConformanceRef> indexHashables, CanType baseTy,
DeclContext *useDC, bool forPropertyDescriptor, bool isApplied = false);
/// Emit all differentiability witnesses for the given function, visiting its
/// `@differentiable` and `@derivative` attributes.
void emitDifferentiabilityWitnessesForFunction(SILDeclRef constant,
SILFunction *F);
/// Emit the differentiability witness for the given original function
/// declaration and SIL function, autodiff configuration, and JVP and VJP
/// functions (null if undefined).
void emitDifferentiabilityWitness(AbstractFunctionDecl *originalAFD,
SILFunction *originalFunction,
DifferentiabilityKind diffKind,
const AutoDiffConfig &config,
SILFunction *jvp, SILFunction *vjp,
const DeclAttribute *diffAttr);
/// Emit a deinit table for a noncopyable type.
void emitNonCopyableTypeDeinitTable(NominalTypeDecl *decl);
/// Known functions for bridging.
SILDeclRef getStringToNSStringFn();
SILDeclRef getNSStringToStringFn();
SILDeclRef getArrayToNSArrayFn();
SILDeclRef getNSArrayToArrayFn();
SILDeclRef getDictionaryToNSDictionaryFn();
SILDeclRef getNSDictionaryToDictionaryFn();
SILDeclRef getSetToNSSetFn();
SILDeclRef getNSSetToSetFn();
SILDeclRef getBoolToObjCBoolFn();
SILDeclRef getObjCBoolToBoolFn();
SILDeclRef getBoolToDarwinBooleanFn();
SILDeclRef getDarwinBooleanToBoolFn();
SILDeclRef getBoolToWindowsBoolFn();
SILDeclRef getWindowsBoolToBoolFn();
SILDeclRef getNSErrorToErrorFn();
SILDeclRef getErrorToNSErrorFn();
#define FUNC_DECL(NAME, ID) \
FuncDecl *get##NAME(SILLocation loc);
#include "swift/AST/KnownDecls.def"
#define KNOWN_SDK_FUNC_DECL(MODULE, NAME, ID) \
FuncDecl *get##NAME(SILLocation loc);
#include "swift/AST/KnownSDKDecls.def"
/// Retrieve the _ObjectiveCBridgeable protocol definition.
ProtocolDecl *getObjectiveCBridgeable(SILLocation loc);
/// Retrieve the _ObjectiveCBridgeable._bridgeToObjectiveC requirement.
FuncDecl *getBridgeToObjectiveCRequirement(SILLocation loc);
/// Retrieve the
/// _ObjectiveCBridgeable._unconditionallyBridgeFromObjectiveC
/// requirement.
FuncDecl *getUnconditionallyBridgeFromObjectiveCRequirement(SILLocation loc);
/// Retrieve the _ObjectiveCBridgeable._ObjectiveCType requirement.
AssociatedTypeDecl *getBridgedObjectiveCTypeRequirement(SILLocation loc);
/// Find the conformance of the given Swift type to the
/// _ObjectiveCBridgeable protocol.
ProtocolConformance *getConformanceToObjectiveCBridgeable(SILLocation loc,
Type type);
/// Retrieve the _BridgedStoredNSError protocol definition.
ProtocolDecl *getBridgedStoredNSError(SILLocation loc);
/// Retrieve the _BridgedStoredNSError._nsError requirement.
VarDecl *getNSErrorRequirement(SILLocation loc);
/// Find the conformance of the given Swift type to the
/// _BridgedStoredNSError protocol.
ProtocolConformanceRef getConformanceToBridgedStoredNSError(SILLocation loc,
Type type);
/// Retrieve the conformance of NSError to the Error protocol.
ProtocolConformance *getNSErrorConformanceToError();
/// Retrieve the _Concurrency._asyncLetStart intrinsic.
FuncDecl *getAsyncLetStart();
/// Retrieve the _Concurrency._asyncLetGet intrinsic.
FuncDecl *getAsyncLetGet();
/// Retrieve the _Concurrency._asyncLetGetThrowing intrinsic.
FuncDecl *getAsyncLetGetThrowing();
/// Retrieve the _Concurrency._asyncLetFinish intrinsic.
FuncDecl *getFinishAsyncLet();
/// Retrieve the _Concurrency._taskFutureGet intrinsic.
FuncDecl *getTaskFutureGet();
/// Retrieve the _Concurrency._taskFutureGetThrowing intrinsic.
FuncDecl *getTaskFutureGetThrowing();
/// Retrieve the _Concurrency._resumeUnsafeContinuation intrinsic.
FuncDecl *getResumeUnsafeContinuation();
/// Retrieve the _Concurrency._resumeUnsafeThrowingContinuation intrinsic.
FuncDecl *getResumeUnsafeThrowingContinuation();
/// Retrieve the _Concurrency._resumeUnsafeThrowingContinuationWithError intrinsic.
FuncDecl *getResumeUnsafeThrowingContinuationWithError();
/// Retrieve the _Concurrency._runTaskForBridgedAsyncMethod intrinsic.
FuncDecl *getRunTaskForBridgedAsyncMethod();
/// Retrieve the _Concurrency._checkExpectedExecutor intrinsic.
FuncDecl *getCheckExpectedExecutor();
/// Retrieve the _Concurrency._createCheckedContinuation intrinsic.
FuncDecl *getCreateCheckedContinuation();
/// Retrieve the _Concurrency._createCheckedThrowingContinuation intrinsic.
FuncDecl *getCreateCheckedThrowingContinuation();
/// Retrieve the _Concurrency._resumeCheckedContinuation intrinsic.
FuncDecl *getResumeCheckedContinuation();
/// Retrieve the _Concurrency._resumeCheckedThrowingContinuation intrinsic.
FuncDecl *getResumeCheckedThrowingContinuation();
/// Retrieve the _Concurrency._resumeCheckedThrowingContinuationWithError intrinsic.
FuncDecl *getResumeCheckedThrowingContinuationWithError();
/// Retrieve the _Concurrency._asyncMainDrainQueue intrinsic.
FuncDecl *getAsyncMainDrainQueue();
/// Retrieve the _Concurrency._swiftJobRun intrinsic.
FuncDecl *getSwiftJobRun();
/// Retrieve the _Concurrency._deinitOnExecutor intrinsic.
FuncDecl *getDeinitOnExecutor();
// Retrieve the _SwiftConcurrencyShims.exit intrinsic.
FuncDecl *getExit();
SILFunction *getKeyPathProjectionCoroutine(bool isReadAccess,
KeyPathTypeKind typeKind);
/// Report a diagnostic.
template<typename...T, typename...U>
InFlightDiagnostic diagnose(SourceLoc loc, Diag<T...> diag,
U &&...args) {
return M.getASTContext().Diags.diagnose(loc, diag, std::forward<U>(args)...);
}
template<typename...T, typename...U>
InFlightDiagnostic diagnose(SILLocation loc, Diag<T...> diag,
U &&...args) {
return M.getASTContext().Diags.diagnose(loc.getSourceLoc(),
diag, std::forward<U>(args)...);
}
/// Get or create SILGlobalVariable for a given global VarDecl.
SILGlobalVariable *getSILGlobalVariable(VarDecl *gDecl,
ForDefinition_t forDef);
/// Emit all lazy conformances referenced from this function body.
void emitLazyConformancesForFunction(SILFunction *F);
/// Emit all lazy conformances referenced from this type's signature and
/// stored properties (or in the case of enums, associated values).
void emitLazyConformancesForType(NominalTypeDecl *NTD);
/// Mark a protocol conformance as used, so we know we need to emit it if
/// it's in our TU.
void useConformance(ProtocolConformanceRef conformance);
/// Mark protocol conformances from the given type as used.
void useConformancesFromType(CanType type);
/// Mark protocol conformances from the given set of substitutions as used.
void useConformancesFromSubstitutions(SubstitutionMap subs);
/// Mark _ObjectiveCBridgeable conformances as used for any imported types
/// mentioned by the given type.
void useConformancesFromObjectiveCType(CanType type);
/// Make a note of a member reference expression, which allows us
/// to ensure that the conformance above is emitted wherever it
/// needs to be.
void noteMemberRefExpr(MemberRefExpr *e);
/// Map the substitutions for the original declaration to substitutions for
/// the overridden declaration.
static SubstitutionMap mapSubstitutionsForWitnessOverride(
AbstractFunctionDecl *original,
AbstractFunctionDecl *overridden,
SubstitutionMap subs);
/// Emit a property descriptor for the given storage decl if it needs one.
void tryEmitPropertyDescriptor(AbstractStorageDecl *decl);
/// Replace local archetypes captured from outer AST contexts with primary
/// archetypes.
void recontextualizeCapturedLocalArchetypes(
SILFunction *F, GenericSignatureWithCapturedEnvironments sig);
private:
/// The most recent declaration we considered for emission.
SILDeclRef lastEmittedFunction;
/// Emit the deallocator for a class that uses the objc allocator.
void emitObjCAllocatorDestructor(ClassDecl *cd, DestructorDecl *dd);
/// Emit the actual body of deallocator.
/// If deinit is isolated, function should be an isolated deallocator, an
/// actual deallocator is just a thunk that switches executors. If deinit is
/// isolated, function should be the deallocator itself.
void emitDeallocatorImpl(SILDeclRef constant, SILFunction *f);
};
} // end namespace Lowering
} // end namespace swift
#endif