/
ASTContext.h
1056 lines (871 loc) · 39.8 KB
/
ASTContext.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
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//===--- ASTContext.h - AST Context Object ----------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2020 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 defines the ASTContext interface.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_AST_ASTCONTEXT_H
#define SWIFT_AST_ASTCONTEXT_H
#include "swift/AST/Evaluator.h"
#include "swift/AST/GenericSignature.h"
#include "swift/AST/Identifier.h"
#include "swift/AST/SearchPathOptions.h"
#include "swift/AST/Type.h"
#include "swift/AST/Types.h"
#include "swift/AST/TypeAlignments.h"
#include "swift/Basic/LangOptions.h"
#include "swift/Basic/Located.h"
#include "swift/Basic/Malloc.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/DataTypes.h"
#include <functional>
#include <memory>
#include <utility>
#include <vector>
namespace clang {
class Decl;
class MacroInfo;
class Module;
class ObjCInterfaceDecl;
}
namespace llvm {
class LLVMContext;
}
namespace swift {
class AbstractFunctionDecl;
class ASTContext;
enum class Associativity : unsigned char;
class AvailabilityContext;
class BoundGenericType;
class ClangModuleLoader;
class ClangNode;
class ConcreteDeclRef;
class ConstructorDecl;
class Decl;
class DeclContext;
class DefaultArgumentInitializer;
class DerivativeAttr;
class DifferentiableAttr;
class ExtensionDecl;
class ForeignRepresentationInfo;
class FuncDecl;
class GenericContext;
class InFlightDiagnostic;
class IterableDeclContext;
class LazyContextData;
class LazyIterableDeclContextData;
class LazyMemberLoader;
class ModuleDependencies;
class PatternBindingDecl;
class PatternBindingInitializer;
class SourceFile;
class SourceLoc;
class Type;
class TypeVariableType;
class TupleType;
class FunctionType;
class GenericSignatureBuilder;
class ArchetypeType;
class Identifier;
class InheritedNameSet;
class ModuleDecl;
class ModuleDependenciesCache;
class ModuleLoader;
class NominalTypeDecl;
class NormalProtocolConformance;
class OpaqueTypeDecl;
class InheritedProtocolConformance;
class SelfProtocolConformance;
class SpecializedProtocolConformance;
enum class ProtocolConformanceState;
class Pattern;
enum PointerTypeKind : unsigned;
class PrecedenceGroupDecl;
class TupleTypeElt;
class EnumElementDecl;
class ProtocolDecl;
class SubstitutableType;
class SourceManager;
class ValueDecl;
class DiagnosticEngine;
class TypeCheckerDebugConsumer;
struct RawComment;
class DocComment;
class SILBoxType;
class SILTransform;
class TypeAliasDecl;
class VarDecl;
class UnifiedStatsReporter;
class IndexSubset;
struct SILAutoDiffDerivativeFunctionKey;
struct InterfaceSubContextDelegate;
enum class KnownProtocolKind : uint8_t;
namespace namelookup {
class ImportCache;
}
namespace syntax {
class SyntaxArena;
}
/// The arena in which a particular ASTContext allocation will go.
enum class AllocationArena {
/// The permanent arena, which is tied to the lifetime of
/// the ASTContext.
///
/// All global declarations and types need to be allocated into this arena.
/// At present, everything that is not a type involving a type variable is
/// allocated in this arena.
Permanent,
/// The constraint solver's temporary arena, which is tied to the
/// lifetime of a particular instance of the constraint solver.
///
/// Any type involving a type variable is allocated in this arena.
ConstraintSolver
};
/// Lists the set of "known" Foundation entities that are used in the
/// compiler.
///
/// While the names of Foundation types aren't likely to change in
/// Objective-C, their mapping into Swift can. Therefore, when
/// referring to names of Foundation entities in Swift, use this enum
/// and \c ASTContext::getSwiftName or \c ASTContext::getSwiftId.
enum class KnownFoundationEntity {
#define FOUNDATION_ENTITY(Name) Name,
#include "swift/AST/KnownFoundationEntities.def"
};
/// Retrieve the Foundation entity kind for the given Objective-C
/// entity name.
Optional<KnownFoundationEntity> getKnownFoundationEntity(StringRef name);
/// Introduces a new constraint checker arena, whose lifetime is
/// tied to the lifetime of this RAII object.
class ConstraintCheckerArenaRAII {
ASTContext &Self;
void *Data;
public:
/// Introduces a new constraint checker arena, supplanting any
/// existing constraint checker arena.
///
/// \param self The ASTContext into which this constraint checker arena
/// will be installed.
///
/// \param allocator The allocator used for allocating any data that
/// goes into the constraint checker arena.
ConstraintCheckerArenaRAII(ASTContext &self,
llvm::BumpPtrAllocator &allocator);
ConstraintCheckerArenaRAII(const ConstraintCheckerArenaRAII &) = delete;
ConstraintCheckerArenaRAII(ConstraintCheckerArenaRAII &&) = delete;
ConstraintCheckerArenaRAII &
operator=(const ConstraintCheckerArenaRAII &) = delete;
ConstraintCheckerArenaRAII &
operator=(ConstraintCheckerArenaRAII &&) = delete;
~ConstraintCheckerArenaRAII();
};
class SILLayout; // From SIL
/// ASTContext - This object creates and owns the AST objects.
/// However, this class does more than just maintain context within an AST.
/// It is the closest thing to thread-local or compile-local storage in this
/// code base. Why? SourceKit uses this code with multiple threads per Unix
/// process. Each thread processes a different source file. Each thread has its
/// own instance of ASTContext, and that instance persists for the duration of
/// the thread, throughout all phases of the compilation. (The name "ASTContext"
/// is a bit of a misnomer here.) Why not use thread-local storage? This code
/// may use DispatchQueues and pthread-style TLS won't work with code that uses
/// DispatchQueues. Summary: if you think you need a global or static variable,
/// you probably need to put it here instead.
class ASTContext final {
ASTContext(const ASTContext&) = delete;
void operator=(const ASTContext&) = delete;
ASTContext(LangOptions &langOpts, TypeCheckerOptions &typeckOpts,
SearchPathOptions &SearchPathOpts, SourceManager &SourceMgr,
DiagnosticEngine &Diags);
public:
// Members that should only be used by ASTContext.cpp.
struct Implementation;
Implementation &getImpl() const;
friend ConstraintCheckerArenaRAII;
void operator delete(void *Data) throw();
static ASTContext *get(LangOptions &langOpts, TypeCheckerOptions &typeckOpts,
SearchPathOptions &SearchPathOpts,
SourceManager &SourceMgr, DiagnosticEngine &Diags);
~ASTContext();
/// Optional table of counters to report, nullptr when not collecting.
///
/// This must be initialized early so that Allocate() doesn't try to access
/// it before being set to null.
UnifiedStatsReporter *Stats = nullptr;
/// The language options used for translation.
const LangOptions &LangOpts;
/// The type checker options.
const TypeCheckerOptions &TypeCheckerOpts;
/// The search path options used by this AST context.
SearchPathOptions &SearchPathOpts;
/// The source manager object.
SourceManager &SourceMgr;
/// Diags - The diagnostics engine.
DiagnosticEngine &Diags;
/// The request-evaluator that is used to process various requests.
Evaluator evaluator;
/// The set of top-level modules we have loaded.
/// This map is used for iteration, therefore it's a MapVector and not a
/// DenseMap.
llvm::MapVector<Identifier, ModuleDecl*> LoadedModules;
/// The builtin module.
ModuleDecl * const TheBuiltinModule;
/// The standard library module.
mutable ModuleDecl *TheStdlibModule = nullptr;
/// The name of the standard library module "Swift".
Identifier StdlibModuleName;
/// The name of the SwiftShims module "SwiftShims".
Identifier SwiftShimsModuleName;
// Define the set of known identifiers.
#define IDENTIFIER_WITH_NAME(Name, IdStr) Identifier Id_##Name;
#include "swift/AST/KnownIdentifiers.def"
/// A consumer of type checker debug output.
std::unique_ptr<TypeCheckerDebugConsumer> TypeCheckerDebug;
/// Cache for names of canonical GenericTypeParamTypes.
mutable llvm::DenseMap<unsigned, Identifier>
CanonicalGenericTypeParamTypeNames;
/// Cache of remapped types (useful for diagnostics).
llvm::StringMap<Type> RemappedTypes;
/// The # of times we have performed typo correction.
unsigned NumTypoCorrections = 0;
/// The next auto-closure discriminator. This needs to be preserved
/// across invocations of both the parser and the type-checker.
unsigned NextAutoClosureDiscriminator = 0;
/// Cached mapping from types to their associated tangent spaces.
llvm::DenseMap<Type, Optional<TangentSpace>> AutoDiffTangentSpaces;
/// A cache of derivative function types per configuration.
llvm::DenseMap<SILAutoDiffDerivativeFunctionKey, CanSILFunctionType>
SILAutoDiffDerivativeFunctions;
/// Cache of `@differentiable` attributes keyed by parameter indices. Used to
/// diagnose duplicate `@differentiable` attributes for the same key.
llvm::DenseMap<std::pair<Decl *, IndexSubset *>, DifferentiableAttr *>
DifferentiableAttrs;
/// Cache of `@derivative` attributes keyed by parameter indices and
/// derivative function kind. Used to diagnose duplicate `@derivative`
/// attributes for the same key.
// TODO(TF-1042): remove `DerivativeAttrs` from `ASTContext`. Serialize
// derivative function configurations per original `AbstractFunctionDecl`.
llvm::DenseMap<
std::tuple<Decl *, IndexSubset *, AutoDiffDerivativeFunctionKind>,
llvm::SmallPtrSet<DerivativeAttr *, 1>>
DerivativeAttrs;
private:
/// The current generation number, which reflects the number of
/// times that external modules have been loaded.
///
/// Various places in the AST, such as the set of extensions associated with
/// a nominal type, keep track of the generation number they saw and will
/// automatically update when they are out of date.
unsigned CurrentGeneration = 0;
friend class Pattern;
/// Mapping from patterns that store interface types that will be lazily
/// resolved to contextual types, to the declaration context in which the
/// pattern resides.
llvm::DenseMap<const Pattern *, DeclContext *>
DelayedPatternContexts;
/// Cache of module names that fail the 'canImport' test in this context.
llvm::SmallPtrSet<Identifier, 8> FailedModuleImportNames;
/// Retrieve the allocator for the given arena.
llvm::BumpPtrAllocator &
getAllocator(AllocationArena arena = AllocationArena::Permanent) const;
public:
/// Allocate - Allocate memory from the ASTContext bump pointer.
void *Allocate(unsigned long bytes, unsigned alignment,
AllocationArena arena = AllocationArena::Permanent) const {
if (bytes == 0)
return nullptr;
if (LangOpts.UseMalloc)
return AlignedAlloc(bytes, alignment);
if (arena == AllocationArena::Permanent && Stats)
Stats->getFrontendCounters().NumASTBytesAllocated += bytes;
return getAllocator(arena).Allocate(bytes, alignment);
}
template <typename T>
T *Allocate(AllocationArena arena = AllocationArena::Permanent) const {
T *res = (T *) Allocate(sizeof(T), alignof(T), arena);
new (res) T();
return res;
}
template <typename T>
MutableArrayRef<T> AllocateUninitialized(unsigned NumElts,
AllocationArena Arena = AllocationArena::Permanent) const {
T *Data = (T *) Allocate(sizeof(T) * NumElts, alignof(T), Arena);
return { Data, NumElts };
}
template <typename T>
MutableArrayRef<T> Allocate(unsigned numElts,
AllocationArena arena = AllocationArena::Permanent) const {
T *res = (T *) Allocate(sizeof(T) * numElts, alignof(T), arena);
for (unsigned i = 0; i != numElts; ++i)
new (res+i) T();
return {res, numElts};
}
/// Allocate a copy of the specified object.
template <typename T>
typename std::remove_reference<T>::type *AllocateObjectCopy(T &&t,
AllocationArena arena = AllocationArena::Permanent) const {
// This function cannot be named AllocateCopy because it would always win
// overload resolution over the AllocateCopy(ArrayRef<T>).
using TNoRef = typename std::remove_reference<T>::type;
TNoRef *res = (TNoRef *) Allocate(sizeof(TNoRef), alignof(TNoRef), arena);
new (res) TNoRef(std::forward<T>(t));
return res;
}
template <typename T, typename It>
T *AllocateCopy(It start, It end,
AllocationArena arena = AllocationArena::Permanent) const {
T *res = (T*)Allocate(sizeof(T)*(end-start), alignof(T), arena);
for (unsigned i = 0; start != end; ++start, ++i)
new (res+i) T(*start);
return res;
}
template<typename T, size_t N>
MutableArrayRef<T> AllocateCopy(T (&array)[N],
AllocationArena arena = AllocationArena::Permanent) const {
return MutableArrayRef<T>(AllocateCopy<T>(array, array+N, arena), N);
}
template<typename T>
MutableArrayRef<T> AllocateCopy(ArrayRef<T> array,
AllocationArena arena = AllocationArena::Permanent) const {
return MutableArrayRef<T>(AllocateCopy<T>(array.begin(),array.end(), arena),
array.size());
}
template<typename T>
ArrayRef<T> AllocateCopy(const SmallVectorImpl<T> &vec,
AllocationArena arena = AllocationArena::Permanent) const {
return AllocateCopy(ArrayRef<T>(vec), arena);
}
template<typename T>
MutableArrayRef<T>
AllocateCopy(SmallVectorImpl<T> &vec,
AllocationArena arena = AllocationArena::Permanent) const {
return AllocateCopy(MutableArrayRef<T>(vec), arena);
}
StringRef AllocateCopy(StringRef Str,
AllocationArena arena = AllocationArena::Permanent) const {
ArrayRef<char> Result =
AllocateCopy(llvm::makeArrayRef(Str.data(), Str.size()), arena);
return StringRef(Result.data(), Result.size());
}
template<typename T, typename Vector, typename Set>
MutableArrayRef<T>
AllocateCopy(llvm::SetVector<T, Vector, Set> setVector,
AllocationArena arena = AllocationArena::Permanent) const {
return MutableArrayRef<T>(AllocateCopy<T>(setVector.begin(),
setVector.end(),
arena),
setVector.size());
}
/// Retrive the syntax node memory manager for this context.
llvm::IntrusiveRefCntPtr<syntax::SyntaxArena> getSyntaxArena() const;
/// Set a new stats reporter.
void setStatsReporter(UnifiedStatsReporter *stats);
public:
/// getIdentifier - Return the uniqued and AST-Context-owned version of the
/// specified string.
Identifier getIdentifier(StringRef Str) const;
/// Decide how to interpret two precedence groups.
Associativity associateInfixOperators(PrecedenceGroupDecl *left,
PrecedenceGroupDecl *right) const;
/// Retrieve the declaration of Swift.Error.
ProtocolDecl *getErrorDecl() const;
CanType getExceptionType() const;
#define KNOWN_STDLIB_TYPE_DECL(NAME, DECL_CLASS, NUM_GENERIC_PARAMS) \
/** Retrieve the declaration of Swift.NAME. */ \
DECL_CLASS *get##NAME##Decl() const;
#include "swift/AST/KnownStdlibTypes.def"
/// Retrieve the declaration of Swift.Optional<T>.Some.
EnumElementDecl *getOptionalSomeDecl() const;
/// Retrieve the declaration of Swift.Optional<T>.None.
EnumElementDecl *getOptionalNoneDecl() const;
/// Retrieve the declaration of the "pointee" property of a pointer type.
VarDecl *getPointerPointeePropertyDecl(PointerTypeKind ptrKind) const;
/// Retrieve the type Swift.AnyObject.
CanType getAnyObjectType() const;
/// Retrieve the type Swift.Never.
CanType getNeverType() const;
#define KNOWN_OBJC_TYPE_DECL(MODULE, NAME, DECL_CLASS) \
/** Retrieve the declaration of MODULE.NAME. */ \
DECL_CLASS *get##NAME##Decl() const; \
\
/** Retrieve the type of MODULE.NAME. */ \
Type get##NAME##Type() const;
#include "swift/AST/KnownObjCTypes.def"
// Declare accessors for the known declarations.
#define FUNC_DECL(Name, Id) \
FuncDecl *get##Name() const;
#include "swift/AST/KnownDecls.def"
/// Get the '+' function on two RangeReplaceableCollection.
FuncDecl *getPlusFunctionOnRangeReplaceableCollection() const;
/// Get the '+' function on two String.
FuncDecl *getPlusFunctionOnString() const;
/// Get Sequence.makeIterator().
FuncDecl *getSequenceMakeIterator() const;
/// Check whether the standard library provides all the correct
/// intrinsic support for Optional<T>.
///
/// If this is true, the four methods above all promise to return
/// non-null.
bool hasOptionalIntrinsics() const;
/// Check whether the standard library provides all the correct
/// intrinsic support for UnsafeMutablePointer<T> function arguments.
///
/// If this is true, the methods getConvert*ToPointerArgument
/// all promise to return non-null.
bool hasPointerArgumentIntrinsics() const;
/// Check whether the standard library provides all the correct
/// intrinsic support for array literals.
///
/// If this is true, the method getAllocateUninitializedArray
/// promises to return non-null.
bool hasArrayLiteralIntrinsics() const;
/// Retrieve the declaration of Swift.Bool.init(_builtinBooleanLiteral:)
ConcreteDeclRef getBoolBuiltinInitDecl() const;
/// Retrieve the witness for init(_builtinIntegerLiteral:).
ConcreteDeclRef getIntBuiltinInitDecl(NominalTypeDecl *intDecl) const;
/// Retrieve the witness for init(_builtinFloatLiteral:).
ConcreteDeclRef getFloatBuiltinInitDecl(NominalTypeDecl *floatDecl) const;
/// Retrieve the witness for (_builtinStringLiteral:utf8CodeUnitCount:isASCII:).
ConcreteDeclRef getStringBuiltinInitDecl(NominalTypeDecl *stringDecl) const;
ConcreteDeclRef getBuiltinInitDecl(NominalTypeDecl *decl,
KnownProtocolKind builtinProtocol,
llvm::function_ref<DeclName (ASTContext &ctx)> initName) const;
/// Retrieve the declaration of Swift.<(Int, Int) -> Bool.
FuncDecl *getLessThanIntDecl() const;
/// Retrieve the declaration of Swift.==(Int, Int) -> Bool.
FuncDecl *getEqualIntDecl() const;
/// Retrieve the declaration of Swift._hashValue<H>(for: H) -> Int.
FuncDecl *getHashValueForDecl() const;
/// Retrieve the declaration of Array.append(element:)
FuncDecl *getArrayAppendElementDecl() const;
/// Retrieve the declaration of
/// Array.reserveCapacityForAppend(newElementsCount: Int)
FuncDecl *getArrayReserveCapacityDecl() const;
// Retrieve the declaration of Swift._stdlib_isOSVersionAtLeast.
FuncDecl *getIsOSVersionAtLeastDecl() const;
/// Look for the declaration with the given name within the
/// Swift module.
void lookupInSwiftModule(StringRef name,
SmallVectorImpl<ValueDecl *> &results) const;
/// Retrieve a specific, known protocol.
ProtocolDecl *getProtocol(KnownProtocolKind kind) const;
/// Determine whether the given nominal type is one of the standard
/// library or Cocoa framework types that is known to be bridged by another
/// module's overlay, for layering or implementation detail reasons.
bool isTypeBridgedInExternalModule(NominalTypeDecl *nominal) const;
/// True if the given type is an Objective-C class that serves as the bridged
/// object type for many Swift value types, meaning that the conversion from
/// an object to a value is a conditional cast.
bool isObjCClassWithMultipleSwiftBridgedTypes(Type t);
/// Get the Objective-C type that a Swift type bridges to, if any.
///
/// \param dc The context in which bridging is occurring.
/// \param type The Swift for which we are querying bridging behavior.
/// \param bridgedValueType The specific value type that is bridged,
/// which will usually by the same as \c type.
Type getBridgedToObjC(const DeclContext *dc, Type type,
Type *bridgedValueType = nullptr) const;
/// Get the Clang type corresponding to a Swift function type.
///
/// \param params The function parameters.
/// \param resultTy The Swift result type.
/// \param incompleteExtInfo Used to convey escaping and throwing
/// information, in case it is needed.
/// \param trueRep The actual calling convention, which must be C-compatible.
/// The calling convention in \p incompleteExtInfo is ignored.
const clang::Type *
getClangFunctionType(ArrayRef<AnyFunctionType::Param> params, Type resultTy,
const FunctionType::ExtInfo incompleteExtInfo,
FunctionTypeRepresentation trueRep);
/// Get the Swift declaration that a Clang declaration was exported from,
/// if applicable.
const Decl *getSwiftDeclForExportedClangDecl(const clang::Decl *decl);
/// Determine whether the given Swift type is representable in a
/// given foreign language.
ForeignRepresentationInfo
getForeignRepresentationInfo(NominalTypeDecl *nominal,
ForeignLanguage language,
const DeclContext *dc);
/// Add a cleanup function to be called when the ASTContext is deallocated.
void addCleanup(std::function<void(void)> cleanup);
/// Add a cleanup to run the given object's destructor when the ASTContext is
/// deallocated.
template<typename T>
void addDestructorCleanup(T &object) {
addCleanup([&object]{ object.~T(); });
}
/// Get the runtime availability of the class metadata update callback
/// mechanism for the target platform.
AvailabilityContext getObjCMetadataUpdateCallbackAvailability();
/// Get the runtime availability of the objc_getClass() hook for the target
/// platform.
AvailabilityContext getObjCGetClassHookAvailability();
/// Get the runtime availability of features introduced in the Swift 5.0
/// compiler for the target platform.
AvailabilityContext getSwift50Availability();
/// Get the runtime availability of the opaque types language feature for the
/// target platform.
AvailabilityContext getOpaqueTypeAvailability();
/// Get the runtime availability of the objc_loadClassref() entry point for
/// the target platform.
AvailabilityContext getObjCClassStubsAvailability();
/// Get the runtime availability of features introduced in the Swift 5.1
/// compiler for the target platform.
AvailabilityContext getSwift51Availability();
/// Get the runtime availability of
/// swift_getTypeByMangledNameInContextInMetadataState.
AvailabilityContext getTypesInAbstractMetadataStateAvailability();
/// Get the runtime availability of support for prespecialized generic
/// metadata.
AvailabilityContext getPrespecializedGenericMetadataAvailability();
/// Get the runtime availability of features introduced in the Swift 5.2
/// compiler for the target platform.
AvailabilityContext getSwift52Availability();
/// Get the runtime availability of features introduced in the Swift 5.3
/// compiler for the target platform.
AvailabilityContext getSwift53Availability();
/// Get the runtime availability of features that have been introduced in the
/// Swift compiler for future versions of the target platform.
AvailabilityContext getSwiftFutureAvailability();
//===--------------------------------------------------------------------===//
// Diagnostics Helper functions
//===--------------------------------------------------------------------===//
bool hadError() const;
//===--------------------------------------------------------------------===//
// Type manipulation routines.
//===--------------------------------------------------------------------===//
// Builtin type and simple types that are used frequently.
const CanType TheErrorType; /// This is the ErrorType singleton.
const CanType TheUnresolvedType; /// This is the UnresolvedType singleton.
const CanType TheEmptyTupleType; /// This is '()', aka Void
const CanType TheAnyType; /// This is 'Any', the empty protocol composition
const CanType TheNativeObjectType; /// Builtin.NativeObject
const CanType TheBridgeObjectType; /// Builtin.BridgeObject
const CanType TheRawPointerType; /// Builtin.RawPointer
const CanType TheUnsafeValueBufferType; /// Builtin.UnsafeValueBuffer
const CanType TheSILTokenType; /// Builtin.SILToken
const CanType TheIntegerLiteralType; /// Builtin.IntegerLiteralType
const CanType TheIEEE32Type; /// 32-bit IEEE floating point
const CanType TheIEEE64Type; /// 64-bit IEEE floating point
// Target specific types.
const CanType TheIEEE16Type; /// 16-bit IEEE floating point
const CanType TheIEEE80Type; /// 80-bit IEEE floating point
const CanType TheIEEE128Type; /// 128-bit IEEE floating point
const CanType ThePPC128Type; /// 128-bit PowerPC 2xDouble
/// Adds a search path to SearchPathOpts, unless it is already present.
///
/// Does any proper bookkeeping to keep all module loaders up to date as well.
void addSearchPath(StringRef searchPath, bool isFramework, bool isSystem);
/// Adds a module loader to this AST context.
///
/// \param loader The new module loader, which will be added after any
/// existing module loaders.
/// \param isClang \c true if this module loader is responsible for loading
/// Clang modules, which are special-cased in some parts of the
/// compiler.
/// \param isDWARF \c true if this module loader can load Clang modules
/// from DWARF.
void addModuleLoader(std::unique_ptr<ModuleLoader> loader,
bool isClang = false, bool isDWARF = false);
/// Retrieve the module dependencies for the module with the given name.
///
/// \param isUnderlyingClangModule When true, only look for a Clang module
/// with the given name, ignoring any Swift modules.
Optional<ModuleDependencies> getModuleDependencies(
StringRef moduleName,
bool isUnderlyingClangModule,
ModuleDependenciesCache &cache,
InterfaceSubContextDelegate &delegate);
/// Load extensions to the given nominal type from the external
/// module loaders.
///
/// \param nominal The nominal type whose extensions should be loaded.
///
/// \param previousGeneration The previous generation number. The AST already
/// contains extensions loaded from any generation up to and including this
/// one.
void loadExtensions(NominalTypeDecl *nominal, unsigned previousGeneration);
/// Load the methods within the given class that produce
/// Objective-C class or instance methods with the given selector.
///
/// \param classDecl The class in which we are searching for @objc methods.
/// The search only considers this class and its extensions; not any
/// superclasses.
///
/// \param selector The selector to search for.
///
/// \param isInstanceMethod Whether we are looking for an instance method
/// (vs. a class method).
///
/// \param swiftOnly If true, only loads methods from imported Swift modules,
/// skipping the Clang importer.
///
/// \param previousGeneration The previous generation with which this
/// callback was invoked. The list of methods will already contain all of
/// the results from generations up and including \c previousGeneration.
///
/// \param methods The list of @objc methods in this class that have this
/// selector and are instance/class methods as requested. This list will be
/// extended with any methods found in subsequent generations.
void loadObjCMethods(ClassDecl *classDecl, ObjCSelector selector,
bool isInstanceMethod, bool swiftOnly,
unsigned previousGeneration,
llvm::TinyPtrVector<AbstractFunctionDecl *> &methods);
/// Load derivative function configurations for the given
/// AbstractFunctionDecl.
///
/// \param originalAFD The declaration whose derivative function
/// configurations should be loaded.
///
/// \param previousGeneration The previous generation number. The AST already
/// contains derivative function configurations loaded from any generation up
/// to and including this one.
void loadDerivativeFunctionConfigurations(
AbstractFunctionDecl *originalAFD, unsigned previousGeneration,
llvm::SetVector<AutoDiffConfig> &results);
/// Retrieve the Clang module loader for this ASTContext.
///
/// If there is no Clang module loader, returns a null pointer.
/// The loader is owned by the AST context.
ClangModuleLoader *getClangModuleLoader() const;
/// Retrieve the DWARF module loader for this ASTContext.
///
/// If there is no Clang module loader, returns a null pointer.
/// The loader is owned by the AST context.
ClangModuleLoader *getDWARFModuleLoader() const;
namelookup::ImportCache &getImportCache() const;
/// Asks every module loader to verify the ASTs it has loaded.
///
/// Does nothing in non-asserts (NDEBUG) builds.
void verifyAllLoadedModules() const;
/// Check whether the module with a given name can be imported without
/// importing it.
///
/// Note that even if this check succeeds, errors may still occur if the
/// module is loaded in full.
bool canImportModule(Located<Identifier> ModulePath);
/// \returns a module with a given name that was already loaded. If the
/// module was not loaded, returns nullptr.
ModuleDecl *getLoadedModule(
ArrayRef<Located<Identifier>> ModulePath) const;
ModuleDecl *getLoadedModule(Identifier ModuleName) const;
/// Attempts to load a module into this ASTContext.
///
/// If a module by this name has already been loaded, the existing module will
/// be returned.
///
/// \returns The requested module, or NULL if the module cannot be found.
ModuleDecl *getModule(ArrayRef<Located<Identifier>> ModulePath);
ModuleDecl *getModuleByName(StringRef ModuleName);
/// Returns the standard library module, or null if the library isn't present.
///
/// If \p loadIfAbsent is true, the ASTContext will attempt to load the module
/// if it hasn't been set yet.
ModuleDecl *getStdlibModule(bool loadIfAbsent = false);
ModuleDecl *getStdlibModule() const {
return const_cast<ASTContext *>(this)->getStdlibModule(false);
}
/// Retrieve the current generation number, which reflects the
/// number of times a module import has caused mass invalidation of
/// lookup tables.
///
/// Various places in the AST keep track of the generation numbers at which
/// their own information is valid, such as the list of extensions associated
/// with a nominal type.
unsigned getCurrentGeneration() const { return CurrentGeneration; }
/// Increase the generation number, implying that various lookup
/// tables have been significantly altered by the introduction of a new
/// module import.
///
/// \returns the previous generation number.
unsigned bumpGeneration() { return CurrentGeneration++; }
/// Produce a "normal" conformance for a nominal type.
NormalProtocolConformance *
getConformance(Type conformingType,
ProtocolDecl *protocol,
SourceLoc loc,
DeclContext *dc,
ProtocolConformanceState state);
/// Produce a self-conformance for the given protocol.
SelfProtocolConformance *
getSelfConformance(ProtocolDecl *protocol);
/// A callback used to produce a diagnostic for an ill-formed protocol
/// conformance that was type-checked before we're actually walking the
/// conformance itself, along with a bit indicating whether this diagnostic
/// produces an error.
struct DelayedConformanceDiag {
ValueDecl *Requirement;
std::function<void()> Callback;
bool IsError;
};
/// Check whether current context has any errors associated with
/// ill-formed protocol conformances which haven't been produced yet.
bool hasDelayedConformanceErrors() const;
/// Add a delayed diagnostic produced while type-checking a
/// particular protocol conformance.
void addDelayedConformanceDiag(NormalProtocolConformance *conformance,
DelayedConformanceDiag fn);
/// Retrieve the delayed-conformance diagnostic callbacks for the
/// given normal protocol conformance.
std::vector<DelayedConformanceDiag>
takeDelayedConformanceDiags(NormalProtocolConformance *conformance);
/// Add delayed missing witnesses for the given normal protocol conformance.
void addDelayedMissingWitnesses(NormalProtocolConformance *conformance,
ArrayRef<ValueDecl*> witnesses);
/// Retrieve the delayed missing witnesses for the given normal protocol
/// conformance.
std::vector<ValueDecl*>
takeDelayedMissingWitnesses(NormalProtocolConformance *conformance);
/// Produce a specialized conformance, which takes a generic
/// conformance and substitutions written in terms of the generic
/// conformance's signature.
///
/// \param type The type for which we are retrieving the conformance.
///
/// \param generic The generic conformance.
///
/// \param substitutions The set of substitutions required to produce the
/// specialized conformance from the generic conformance.
ProtocolConformance *
getSpecializedConformance(Type type,
ProtocolConformance *generic,
SubstitutionMap substitutions);
/// Produce an inherited conformance, for subclasses of a type
/// that already conforms to a protocol.
///
/// \param type The type for which we are retrieving the conformance.
///
/// \param inherited The inherited conformance.
InheritedProtocolConformance *
getInheritedConformance(Type type, ProtocolConformance *inherited);
/// Get the lazy data for the given declaration.
///
/// \param lazyLoader If non-null, the lazy loader to use when creating the
/// lazy data. The pointer must either be null or be consistent
/// across all calls for the same \p func.
LazyContextData *getOrCreateLazyContextData(const DeclContext *decl,
LazyMemberLoader *lazyLoader);
/// Get the lazy iterable context for the given iterable declaration context.
///
/// \param lazyLoader If non-null, the lazy loader to use when creating the
/// iterable context data. The pointer must either be null or be consistent
/// across all calls for the same \p idc.
LazyIterableDeclContextData *getOrCreateLazyIterableContextData(
const IterableDeclContext *idc,
LazyMemberLoader *lazyLoader);
/// Access the side cache for property wrapper backing property types,
/// used because TypeChecker::typeCheckBinding() needs somewhere to stash
/// the backing property type.
Type getSideCachedPropertyWrapperBackingPropertyType(VarDecl *var) const;
void setSideCachedPropertyWrapperBackingPropertyType(VarDecl *var,
Type type);
/// Returns memory usage of this ASTContext.
size_t getTotalMemory() const;
/// Returns memory used exclusively by constraint solver.
size_t getSolverMemory() const;
/// Retrieve the Swift name for the given Foundation entity, where
/// "NS" prefix stripping will apply under omit-needless-words.
StringRef getSwiftName(KnownFoundationEntity kind);
/// Retrieve the Swift identifier for the given Foundation entity, where
/// "NS" prefix stripping will apply under omit-needless-words.
Identifier getSwiftId(KnownFoundationEntity kind) {
return getIdentifier(getSwiftName(kind));
}
/// Populate \p names with visible top level module names.
/// This guarantees that resulted \p names doesn't have duplicated names.
void getVisibleTopLevelModuleNames(SmallVectorImpl<Identifier> &names) const;
/// Whether to perform typo correction given the pre-configured correction limit.
/// Increments \c NumTypoCorrections then checks this against the limit in
/// the language options.
bool shouldPerformTypoCorrection();
private:
/// Register the given generic signature builder to be used as the canonical
/// generic signature builder for the given signature, if we don't already
/// have one.
void registerGenericSignatureBuilder(GenericSignature sig,
GenericSignatureBuilder &&builder);
friend class GenericSignatureBuilder;
private:
friend class IntrinsicInfo;
/// Retrieve an LLVMContext that is used for scratch space for intrinsic lookup.
llvm::LLVMContext &getIntrinsicScratchContext() const;
public:
/// Retrieve or create the stored generic signature builder for the given
/// canonical generic signature and module.
GenericSignatureBuilder *getOrCreateGenericSignatureBuilder(
CanGenericSignature sig);
/// Retrieve a generic signature with a single unconstrained type parameter,
/// like `<T>`.
CanGenericSignature getSingleGenericParameterSignature() const;
/// Retrieve a generic signature with a single type parameter conforming
/// to the given opened archetype.
CanGenericSignature getOpenedArchetypeSignature(CanType existential,
ModuleDecl *mod);
GenericSignature getOverrideGenericSignature(const ValueDecl *base,
const ValueDecl *derived);
enum class OverrideGenericSignatureReqCheck {
/// Base method's generic requirements are satisifed by derived method
BaseReqSatisfiedByDerived,
/// Derived method's generic requirements are satisifed by base method
DerivedReqSatisfiedByBase
};