-
Notifications
You must be signed in to change notification settings - Fork 10.4k
/
Copy pathASTContext.h
953 lines (793 loc) · 36.5 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
//===--- ASTContext.h - AST Context Object ----------------------*- 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 defines the ASTContext interface.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_AST_ASTCONTEXT_H
#define SWIFT_AST_ASTCONTEXT_H
#include "llvm/Support/DataTypes.h"
#include "swift/AST/ClangModuleLoader.h"
#include "swift/AST/Identifier.h"
#include "swift/AST/SearchPathOptions.h"
#include "swift/AST/SubstitutionList.h"
#include "swift/AST/Type.h"
#include "swift/AST/TypeAlignments.h"
#include "swift/Basic/LangOptions.h"
#include "swift/Basic/Malloc.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Support/Allocator.h"
#include <functional>
#include <memory>
#include <utility>
#include <vector>
namespace clang {
class Decl;
class MacroInfo;
class Module;
class ObjCInterfaceDecl;
}
namespace swift {
class ASTContext;
enum class Associativity : unsigned char;
class BoundGenericType;
class ClangNode;
class Decl;
class DeclContext;
class DefaultArgumentInitializer;
class ExtensionDecl;
class ForeignRepresentationInfo;
class FuncDecl;
class GenericContext;
class InFlightDiagnostic;
class IterableDeclContext;
class LazyContextData;
class LazyGenericContextData;
class LazyIterableDeclContextData;
class LazyMemberLoader;
class LazyResolver;
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 ModuleLoader;
class NominalTypeDecl;
class NormalProtocolConformance;
class InheritedProtocolConformance;
class SpecializedProtocolConformance;
enum class ProtocolConformanceState;
class Pattern;
enum PointerTypeKind : unsigned;
class PrecedenceGroupDecl;
class TupleTypeElt;
class EnumElementDecl;
enum OptionalTypeKind : unsigned;
class ProtocolDecl;
class SubstitutableType;
class SourceManager;
class ValueDecl;
class DiagnosticEngine;
class Substitution;
class TypeCheckerDebugConsumer;
struct RawComment;
class DocComment;
class SILBoxType;
class TypeAliasDecl;
class VarDecl;
class UnifiedStatsReporter;
enum class KnownProtocolKind : uint8_t;
/// \brief The arena in which a particular ASTContext allocation will go.
enum class AllocationArena {
/// \brief 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,
/// \brief 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);
/// \brief Introduces a new constraint checker arena, whose lifetime is
/// tied to the lifetime of this RAII object.
class ConstraintCheckerArenaRAII {
ASTContext &Self;
void *Data;
public:
/// \brief 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
/// \brief Describes either a nominal type declaration or an extension
/// declaration.
typedef llvm::PointerUnion<NominalTypeDecl *, ExtensionDecl *>
TypeOrExtensionDecl;
/// 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 {
ASTContext(const ASTContext&) = delete;
void operator=(const ASTContext&) = delete;
public:
// Members that should only be used by ASTContext.cpp.
struct Implementation;
Implementation &Impl;
friend ConstraintCheckerArenaRAII;
public:
ASTContext(LangOptions &langOpts, SearchPathOptions &SearchPathOpts,
SourceManager &SourceMgr, DiagnosticEngine &Diags);
~ASTContext();
/// \brief The language options used for translation.
LangOptions &LangOpts;
/// \brief The search path options used by this AST context.
SearchPathOptions &SearchPathOpts;
/// \brief The source manager object.
SourceManager &SourceMgr;
/// Diags - The diagnostics engine.
DiagnosticEngine &Diags;
/// 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"
/// \brief The list of external definitions imported by this context.
llvm::SetVector<Decl *> ExternalDefinitions;
/// FIXME: HACK HACK HACK
/// This state should be tracked somewhere else.
unsigned LastCheckedExternalDefinition = 0;
/// 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;
/// Optional table of counters to report, nullptr when not collecting.
UnifiedStatsReporter *Stats = nullptr;
private:
/// \brief 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;
public:
/// \brief Retrieve the allocator for the given arena.
llvm::BumpPtrAllocator &
getAllocator(AllocationArena arena = AllocationArena::Permanent) const;
/// 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);
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());
}
/// Retrieve the lazy resolver for this context.
LazyResolver *getLazyResolver() const;
/// Set the lazy resolver for this context.
void setLazyResolver(LazyResolver *resolver);
/// 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 or ImplicitlyUnwrappedOptional.
EnumDecl *getOptionalDecl(OptionalTypeKind kind) const;
/// 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 Swift.ImplicitlyUnwrappedOptional<T>.Some.
EnumElementDecl *getImplicitlyUnwrappedOptionalSomeDecl() const;
/// Retrieve the declaration of Swift.ImplicitlyUnwrappedOptional<T>.None.
EnumElementDecl *getImplicitlyUnwrappedOptionalNoneDecl() const;
EnumElementDecl *getOptionalSomeDecl(OptionalTypeKind kind) const;
EnumElementDecl *getOptionalNoneDecl(OptionalTypeKind kind) 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;
/// Retrieve the declaration of Swift.Void.
TypeAliasDecl *getVoidDecl() const;
/// Retrieve the declaration of ObjectiveC.ObjCBool.
StructDecl *getObjCBoolDecl() const;
/// Retrieve the declaration of Foundation.NSError.
ClassDecl *getNSErrorDecl() const;
/// Retrieve the declaration of Foundation.NSNumber.
ClassDecl *getNSNumberDecl() const;
/// Retrieve the declaration of Foundation.NSValue.
ClassDecl *getNSValueDecl() const;
// Declare accessors for the known declarations.
#define FUNC_DECL(Name, Id) \
FuncDecl *get##Name(LazyResolver *resolver) const;
#include "swift/AST/KnownDecls.def"
/// Get the '+' function on two RangeReplaceableCollection.
FuncDecl *getPlusFunctionOnRangeReplaceableCollection() const;
/// Get the '+' function on two String.
FuncDecl *getPlusFunctionOnString() 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(LazyResolver *resolver) 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(LazyResolver *resolver) 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(LazyResolver *resolver) const;
/// Retrieve the declaration of Swift._getBool.
FuncDecl *getGetBoolDecl(LazyResolver *resolver) const;
/// Retrieve the declaration of Swift.==(Int, Int) -> Bool.
FuncDecl *getEqualIntDecl() const;
/// Retrieve the declaration of
/// Swift._combineHashValues(Int, Int) -> Int.
FuncDecl *getCombineHashValuesDecl() const;
/// Retrieve the declaration of Swift._mixInt(Int) -> Int.
FuncDecl *getMixIntDecl() 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._unimplementedInitializer.
FuncDecl *getUnimplementedInitializerDecl(LazyResolver *resolver) const;
/// Retrieve the declaration of Swift._undefined.
FuncDecl *getUndefinedDecl(LazyResolver *resolver) const;
// Retrieve the declaration of Swift._stdlib_isOSVersionAtLeast.
FuncDecl *getIsOSVersionAtLeastDecl(LazyResolver *resolver) 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;
/// Determine whether the given Swift type is representable in a
/// given foreign language.
ForeignRepresentationInfo
getForeignRepresentationInfo(NominalTypeDecl *nominal,
ForeignLanguage language,
const DeclContext *dc);
/// Add a declaration to a list of declarations that need to be emitted
/// as part of the current module or source file, but are otherwise not
/// nested within it.
void addExternalDecl(Decl *decl);
/// 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(); });
}
//===--------------------------------------------------------------------===//
// 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 TheUnknownObjectType; /// Builtin.UnknownObject
const CanType TheRawPointerType; /// Builtin.RawPointer
const CanType TheUnsafeValueBufferType; /// Builtin.UnsafeValueBuffer
const CanType TheSILTokenType; /// Builtin.SILToken
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);
/// \brief 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.
void addModuleLoader(std::unique_ptr<ModuleLoader> loader,
bool isClang = false);
/// \brief 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);
/// \brief 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 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,
unsigned previousGeneration,
llvm::TinyPtrVector<AbstractFunctionDecl *> &methods);
/// \brief 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;
/// Asks every module loader to verify the ASTs it has loaded.
///
/// Does nothing in non-asserts (NDEBUG) builds.
void verifyAllLoadedModules() const;
/// \brief 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(std::pair<Identifier, SourceLoc> ModulePath);
/// \returns a module with a given name that was already loaded. If the
/// module was not loaded, returns nullptr.
ModuleDecl *getLoadedModule(
ArrayRef<std::pair<Identifier, SourceLoc>> ModulePath) const;
ModuleDecl *getLoadedModule(Identifier ModuleName) const;
/// \brief 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<std::pair<Identifier, SourceLoc>> 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);
}
/// \brief 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; }
/// \brief 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++; }
/// \brief Produce a "normal" conformance for a nominal type.
NormalProtocolConformance *
getConformance(Type conformingType,
ProtocolDecl *protocol,
SourceLoc loc,
DeclContext *dc,
ProtocolConformanceState state);
/// Produce a new normal conformance for a property behavior.
NormalProtocolConformance *
getBehaviorConformance(Type conformingType,
ProtocolDecl *protocol,
SourceLoc loc,
AbstractStorageDecl *storage,
ProtocolConformanceState state);
/// 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;
};
/// 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);
/// \brief 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. This list is
/// copied so passing a temporary is permitted.
ProtocolConformance *
getSpecializedConformance(Type type,
ProtocolConformance *generic,
SubstitutionList substitutions,
bool alreadyCheckedCollapsed = false);
/// \brief 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. The keys must
/// be generic parameters, not archetypes, so for example passing in
/// TypeBase::getContextSubstitutionMap() is OK.
ProtocolConformance *
getSpecializedConformance(Type type,
ProtocolConformance *generic,
const SubstitutionMap &substitutions);
/// \brief 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);
/// Record compiler-known protocol information in the AST.
void recordKnownProtocols(ModuleDecl *Stdlib);
/// 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 function data for the given generic context.
///
/// \param lazyLoader If non-null, the lazy loader to use when creating the
/// function data. The pointer must either be null or be consistent
/// across all calls for the same \p func.
LazyGenericContextData *getOrCreateLazyGenericContextData(
const GenericContext *dc,
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);
/// \brief Returns memory usage of this ASTContext.
size_t getTotalMemory() const;
/// \brief Returns memory used exclusively by constraint solver.
size_t getSolverMemory() const;
/// Complain if @objc or dynamic is used without importing Foundation.
void diagnoseAttrsRequiringFoundation(SourceFile &SF);
/// Note that the given method produces an Objective-C method.
void recordObjCMethod(AbstractFunctionDecl *method);
/// Diagnose any Objective-C method overrides that aren't reflected
/// as overrides in Swift.
bool diagnoseUnintendedObjCMethodOverrides(SourceFile &sf);
/// Note that there is a conflict between different definitions that
/// produce the same Objective-C method.
void recordObjCMethodConflict(ClassDecl *classDecl, ObjCSelector selector,
bool isInstance);
/// Diagnose all conflicts between members that have the same
/// Objective-C selector in the same class.
///
/// \param sf The source file for which we are diagnosing conflicts.
///
/// \returns true if there were any conflicts diagnosed.
bool diagnoseObjCMethodConflicts(SourceFile &sf);
/// Note that an optional @objc requirement has gone unsatisfied by
/// a conformance to its protocol.
///
/// \param dc The declaration context in which the conformance occurs.
/// \param req The optional requirement.
void recordObjCUnsatisfiedOptReq(DeclContext *dc, AbstractFunctionDecl *req);
/// Diagnose any unsatisfied @objc optional requirements of
/// protocols that conflict with methods.
bool diagnoseObjCUnsatisfiedOptReqConflicts(SourceFile &sf);
/// 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));
}
/// Collect visible clang modules from the ClangModuleLoader. These modules are
/// not necessarily loaded.
void getVisibleTopLevelClangModules(SmallVectorImpl<clang::Module*> &Modules) const;
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;
public:
/// Retrieve or create the stored generic signature builder for the given
/// canonical generic signature and module.
GenericSignatureBuilder *getOrCreateGenericSignatureBuilder(
CanGenericSignature sig);
/// Retrieve or create the canonical generic environment of a canonical
/// generic signature builder.
GenericEnvironment *getOrCreateCanonicalGenericEnvironment(
GenericSignatureBuilder *builder,
GenericSignature *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 existential type.
CanGenericSignature getExistentialSignature(CanType existential,
ModuleDecl *mod);
/// Whether our effective Swift version is in the Swift 3 family.
bool isSwiftVersion3() const { return LangOpts.isSwiftVersion3(); }
/// Whether our effective Swift version is at least 'major'.
///
/// This is usually the check you want; for example, when introducing
/// a new language feature which is only visible in Swift 5, you would
/// check for isSwiftVersionAtLeast(5).
bool isSwiftVersionAtLeast(unsigned major) const {
return LangOpts.isSwiftVersionAtLeast(major);
}
private:
friend Decl;
Optional<RawComment> getRawComment(const Decl *D);
void setRawComment(const Decl *D, RawComment RC);
Optional<StringRef> getBriefComment(const Decl *D);
void setBriefComment(const Decl *D, StringRef Comment);
friend TypeBase;
friend ArchetypeType;
/// Provide context-level uniquing for SIL lowered type layouts and boxes.
friend SILLayout;
friend SILBoxType;
};
/// Retrieve information about the given Objective-C method for
/// diagnostic purposes, to be used with OBJC_DIAG_SELECT in
/// DiagnosticsSema.def.
std::pair<unsigned, DeclName> getObjCMethodDiagInfo(
AbstractFunctionDecl *method);
/// Attach Fix-Its to the given diagnostic that updates the name of the
/// given declaration to the desired target name.
///
/// \returns false if the name could not be fixed.
bool fixDeclarationName(InFlightDiagnostic &diag, ValueDecl *decl,
DeclName targetName);
/// Fix the Objective-C name of the given declaration to match the provided
/// Objective-C selector.
///
/// \param ignoreImpliedName When true, ignore the implied name of the
/// given declaration, because it no longer applies.
///
/// For properties, the selector should be a zero-parameter selector of the
/// given property's name.
bool fixDeclarationObjCName(InFlightDiagnostic &diag, ValueDecl *decl,
Optional<ObjCSelector> targetNameOpt,
bool ignoreImpliedName = false);
} // end namespace swift
#endif