forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathTypeChecker.h
1793 lines (1522 loc) · 70.7 KB
/
TypeChecker.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
//===--- TypeChecker.h - Type Checking Class --------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines the TypeChecking class.
//
//===----------------------------------------------------------------------===//
#ifndef TYPECHECKING_H
#define TYPECHECKING_H
#include "swift/Sema/TypeCheckRequest.h"
#include "swift/AST/AST.h"
#include "swift/AST/AnyFunctionRef.h"
#include "swift/AST/Availability.h"
#include "swift/AST/DiagnosticsSema.h"
#include "swift/AST/KnownProtocols.h"
#include "swift/AST/LazyResolver.h"
#include "swift/AST/TypeRefinementContext.h"
#include "swift/Parse/Lexer.h"
#include "swift/Basic/Fallthrough.h"
#include "swift/Basic/OptionSet.h"
#include "swift/Config.h"
#include "llvm/ADT/SetVector.h"
#include <functional>
namespace swift {
class ArchetypeBuilder;
class GenericTypeResolver;
class NominalTypeDecl;
class TopLevelContext;
class TypeChecker;
namespace constraints {
enum class ConstraintKind : char;
class ConstraintSystem;
class Solution;
}
/// \brief A mapping from substitutable types to the protocol-conformance
/// mappings for those types.
typedef llvm::DenseMap<SubstitutableType *,
SmallVector<ProtocolConformance *, 2>> ConformanceMap;
/// The result of name lookup.
class LookupResult {
public:
struct Result {
/// The declaration we found.
ValueDecl *Decl;
/// The base declaration through which we found the declaration.
ValueDecl *Base;
operator ValueDecl*() const { return Decl; }
ValueDecl *operator->() const { return Decl; }
};
private:
/// The set of results found.
SmallVector<Result, 4> Results;
public:
typedef SmallVectorImpl<Result>::iterator iterator;
iterator begin() { return Results.begin(); }
iterator end() { return Results.end(); }
unsigned size() const { return Results.size(); }
bool empty() const { return Results.empty(); }
const Result& operator[](unsigned index) const { return Results[index]; }
Result front() const { return Results.front(); }
Result back() const { return Results.back(); }
/// Add a result to the set of results.
void add(Result result) { Results.push_back(result); }
void clear() { Results.clear(); }
/// Determine whether the result set is nonempty.
explicit operator bool() const {
return !Results.empty();
}
TypeDecl *getSingleTypeResult() const {
if (size() != 1)
return nullptr;
return dyn_cast<TypeDecl>(front().Decl);
}
/// Filter out any results that aren't accepted by the given predicate.
void filter(const std::function<bool(Result)> &pred);
};
/// The result of name lookup for types.
class LookupTypeResult {
/// The set of results found.
SmallVector<std::pair<TypeDecl *, Type>, 4> Results;
friend class TypeChecker;
public:
typedef SmallVectorImpl<std::pair<TypeDecl *, Type>>::iterator iterator;
iterator begin() { return Results.begin(); }
iterator end() { return Results.end(); }
unsigned size() const { return Results.size(); }
std::pair<TypeDecl *, Type> operator[](unsigned index) const {
return Results[index];
}
std::pair<TypeDecl *, Type> front() const { return Results.front(); }
std::pair<TypeDecl *, Type> back() const { return Results.back(); }
/// Add a result to the set of results.
void addResult(std::pair<TypeDecl *, Type> result) {
Results.push_back(result);
}
/// \brief Determine whether this result set is ambiguous.
bool isAmbiguous() const {
return Results.size() > 1;
}
/// Determine whether the result set is nonempty.
explicit operator bool() const {
return !Results.empty();
}
};
/// This specifies the purpose of the contextual type, when specified to
/// typeCheckExpression. This is used for diagnostic generation to produce more
/// specified error messages when the conversion fails.
///
enum ContextualTypePurpose {
CTP_Unused, ///< No contextual type is specified.
CTP_Initialization, ///< Pattern binding initialization.
CTP_ReturnStmt, ///< Value specified to a 'return' statement.
CTP_ThrowStmt, ///< Value specified to a 'throw' statement.
CTP_EnumCaseRawValue, ///< Raw value specified for "case X = 42" in enum.
CTP_DefaultParameter, ///< Default value in parameter 'foo(a : Int = 42)'.
CTP_CalleeResult, ///< Constraint is placed on the result of a callee.
CTP_CallArgument, ///< Call to function or operator requires type.
CTP_ClosureResult, ///< Closure result expects a specific type.
CTP_ArrayElement, ///< ArrayExpr wants elements to have a specific type.
CTP_DictionaryKey, ///< DictionaryExpr keys should have a specific type.
CTP_DictionaryValue, ///< DictionaryExpr values should have a specific type.
CTP_CoerceOperand, ///< CoerceExpr operand coerced to specific type.
CTP_AssignSource, ///< AssignExpr source operand coerced to result type.
CTP_CannotFail, ///< Conversion can never fail. abort() if it does.
};
/// Flags that can be used to control name lookup.
enum class TypeCheckExprFlags {
/// Whether we know that the result of the expression is discarded. This
/// disables constraints forcing an lvalue result to be loadable.
IsDiscarded = 0x01,
/// Whether the client wants to disable the structural syntactic restrictions
/// that we force for style or other reasons.
DisableStructuralChecks = 0x02,
/// Set if the client wants diagnostics suppressed.
SuppressDiagnostics = 0x04,
/// If set, the client wants a best-effort solution to the constraint system,
/// but can tolerate a solution where all of the constraints are solved, but
/// not all type variables have been determined. In this case, the constraint
/// system is not applied to the expression AST, but the ConstraintSystem is
/// left in-tact.
AllowUnresolvedTypeVariables = 0x08,
/// If set, the 'convertType' specified to typeCheckExpression should not
/// produce a conversion constraint, but it should be used to guide the
/// solution in terms of performance optimizations of the solver, and in terms
/// of guiding diagnostics.
ConvertTypeIsOnlyAHint = 0x10,
/// If set, this expression isn't embedded in a larger expression or
/// statement. This should only be used for syntactic restrictions, and should
/// not affect type checking itself.
IsExprStmt = 0x20,
/// If set, this expression is being re-type checked as part of diagnostics,
/// and so we should not visit bodies of non-single expression closures.
SkipMultiStmtClosures = 0x40,
};
typedef OptionSet<TypeCheckExprFlags> TypeCheckExprOptions;
inline TypeCheckExprOptions operator|(TypeCheckExprFlags flag1,
TypeCheckExprFlags flag2) {
return TypeCheckExprOptions(flag1) | flag2;
}
/// Flags that can be used to control name lookup.
enum class NameLookupFlags {
/// Whether we know that this lookup is always a private dependency.
KnownPrivate = 0x01,
/// Whether name lookup should be able to find protocol members.
ProtocolMembers = 0x02,
/// Whether to perform 'dynamic' name lookup that finds @objc
/// members of any class or protocol.
DynamicLookup = 0x04,
/// Whether we're only looking for types.
OnlyTypes = 0x08,
};
/// A set of options that control name lookup.
typedef OptionSet<NameLookupFlags> NameLookupOptions;
inline NameLookupOptions operator|(NameLookupFlags flag1,
NameLookupFlags flag2) {
return NameLookupOptions(flag1) | flag2;
}
/// Default options for member name lookup.
const NameLookupOptions defaultMemberLookupOptions
= NameLookupFlags::DynamicLookup | NameLookupFlags::ProtocolMembers;
/// Default options for constructor lookup.
const NameLookupOptions defaultConstructorLookupOptions
= NameLookupFlags::ProtocolMembers;
/// Default options for member type lookup.
const NameLookupOptions defaultMemberTypeLookupOptions
= NameLookupFlags::ProtocolMembers;
/// Default options for unqualified name lookup.
const NameLookupOptions defaultUnqualifiedLookupOptions
= NameLookupFlags::ProtocolMembers;
/// Describes the result of comparing two entities, of which one may be better
/// or worse than the other, or they are unordered.
enum class Comparison {
/// Neither entity is better than the other.
Unordered,
/// The first entity is better than the second.
Better,
/// The first entity is worse than the second.
Worse
};
/// Specify how we handle the binding of underconstrained (free) type variables
/// within a solution to a constraint system.
enum class FreeTypeVariableBinding {
/// Disallow any binding of such free type variables.
Disallow,
/// Allow the free type variables to persist in the solution.
Allow,
/// Bind the type variables to fresh generic parameters.
GenericParameters,
/// Bind the type variables to UnresolvedType to represent the ambiguity.
UnresolvedType
};
/// An abstract interface that can interact with the type checker during
/// the type checking of a particular expression.
class ExprTypeCheckListener {
public:
virtual ~ExprTypeCheckListener();
/// Callback invoked once the constraint system has been constructed.
///
/// \param cs The constraint system that has been constructed.
///
/// \param expr The pre-checked expression from which the constraint system
/// was generated.
///
/// \returns true if an error occurred that is not itself part of the
/// constraint system, or false otherwise.
virtual bool builtConstraints(constraints::ConstraintSystem &cs, Expr *expr);
/// Callback invokes once the chosen solution has been applied to the
/// expression.
///
/// The callback may further alter the expression, returning either a
/// new expression (to replace the result) or a null pointer to indicate
/// failure.
virtual Expr *appliedSolution(constraints::Solution &solution,
Expr *expr);
};
/// Flags that describe the context of type checking a pattern or
/// type.
enum TypeResolutionFlags : unsigned {
/// Whether to allow unspecified types within a pattern.
TR_AllowUnspecifiedTypes = 0x01,
/// Whether the pattern is variadic.
TR_Variadic = 0x02,
/// Whether the given type can override the type of a typed pattern.
TR_OverrideType = 0x04,
/// Whether to allow unbound generic types.
TR_AllowUnboundGenerics = 0x08,
/// Whether we are validating the type for SIL.
TR_SILType = 0x10,
/// Whether we are in the input type of a function, or under one level of
/// tuple type. This is not set for multi-level tuple arguments.
TR_FunctionInput = 0x20,
/// Whether this is the immediate input type to a function type,
TR_ImmediateFunctionInput = 0x40,
/// Whether we are in the result type of a function type.
TR_FunctionResult = 0x80,
/// Whether we are in the result type of a function body that is
/// known to produce dynamic Self.
TR_DynamicSelfResult = 0x100,
/// Whether this is a resolution based on a non-inferred type pattern.
TR_FromNonInferredPattern = 0x200,
/// Whether we are the variable type in a for/in statement.
TR_EnumerationVariable = 0x400,
/// Whether we are looking only in the generic signature of the context
/// we're searching, rather than the entire context.
TR_GenericSignature = 0x800,
/// Whether this type is the referent of a global type alias.
TR_GlobalTypeAlias = 0x1000,
/// Whether this type is the value carried in an enum case.
TR_EnumCase = 0x2000,
/// Whether this type is being used in an expression or local declaration.
///
/// This affects what sort of dependencies are recorded when resolving the
/// type.
TR_InExpression = 0x4000,
/// Whether this type resolution is guaranteed not to affect downstream files.
TR_KnownNonCascadingDependency = 0x8000,
/// Whether we should allow references to unavailable types.
TR_AllowUnavailable = 0x10000,
/// Whether this is the payload subpattern of an enum pattern.
TR_EnumPatternPayload = 0x20000,
/// Whether we are binding an extension declaration, which limits
/// the lookup.
TR_ExtensionBinding = 0x40000,
/// Whether we are in the inheritance clause of a nominal type declaration
/// or extension.
TR_InheritanceClause = 0x80000,
/// Whether we should resolve only the structure of the resulting
/// type rather than its complete semantic properties.
TR_ResolveStructure = 0x100000,
/// Whether this is the type of an editor placeholder.
TR_EditorPlaceholder = 0x200000,
};
/// Option set describing how type resolution should work.
typedef OptionSet<TypeResolutionFlags> TypeResolutionOptions;
inline TypeResolutionOptions operator|(TypeResolutionFlags lhs,
TypeResolutionFlags rhs) {
return TypeResolutionOptions(lhs) | rhs;
}
/// Strip the contextual options from the given type resolution options.
static inline TypeResolutionOptions
withoutContext(TypeResolutionOptions options) {
options -= TR_ImmediateFunctionInput;
options -= TR_FunctionInput;
options -= TR_FunctionResult;
options -= TR_EnumCase;
return options;
}
/// Describes the reason why are we trying to apply @objc to a declaration.
///
/// Should only affect diagnostics. If you change this enum, also change
/// the OBJC_ATTR_SELECT macro in DiagnosticsSema.def.
enum class ObjCReason {
DoNotDiagnose,
ExplicitlyDynamic,
ExplicitlyObjC,
ExplicitlyIBOutlet,
ExplicitlyNSManaged,
MemberOfObjCProtocol,
ImplicitlyObjC,
OverridesObjC
};
/// Return the %select discriminator for the OBJC_ATTR_SELECT macro used to
/// complain about the correct attribute during @objc inference.
static inline unsigned getObjCDiagnosticAttrKind(ObjCReason Reason) {
assert(Reason != ObjCReason::DoNotDiagnose);
return static_cast<unsigned>(Reason) - 1;
}
/// Flags that control protocol conformance checking.
enum class ConformanceCheckFlags {
/// Whether we're performing the check from within an expression.
InExpression = 0x01,
/// Whether we will be using the conformance in the AST.
///
/// This implies that the conformance will have to be complete.
Used = 0x02
};
/// Options that control protocol conformance checking.
typedef OptionSet<ConformanceCheckFlags> ConformanceCheckOptions;
inline ConformanceCheckOptions operator|(ConformanceCheckFlags lhs,
ConformanceCheckFlags rhs) {
return ConformanceCheckOptions(lhs) | rhs;
}
/// The Swift type checker, which takes a parsed AST and performs name binding,
/// type checking, and semantic analysis to produce a type-annotated AST.
class TypeChecker final : public LazyResolver {
public:
ASTContext &Context;
DiagnosticEngine &Diags;
/// \brief The list of implicitly-defined functions created by the
/// type checker.
std::vector<AbstractFunctionDecl *> implicitlyDefinedFunctions;
/// \brief The list of function definitions we've encountered.
std::vector<AbstractFunctionDecl *> definedFunctions;
/// The list of protocol conformances that were "used" and will need to be
/// completed before type checking is considered complete.
llvm::SetVector<NormalProtocolConformance *> UsedConformances;
/// The list of nominal type declarations that have been validated
/// during type checking.
llvm::SetVector<NominalTypeDecl *> ValidatedTypes;
/// Caches whether a particular type is accessible from a particular file
/// unit.
///
/// This can't use CanTypes because typealiases may have more limited types
/// than their underlying types.
llvm::DenseMap<Type, Accessibility> TypeAccessibilityCache;
// We delay validation of C and Objective-C type-bridging functions in the
// standard library until we encounter a declaration that requires one. This
// flag is set to 'true' once the bridge functions have been checked.
bool HasCheckedBridgeFunctions = false;
/// A list of closures for the most recently type-checked function, which we
/// will need to compute captures for.
std::vector<AnyFunctionRef> ClosuresWithUncomputedCaptures;
/// Describes an attempt to capture a local function.
struct LocalFunctionCapture {
FuncDecl *LocalFunction;
SourceLoc CaptureLoc;
};
/// Local functions that have been captured before their definitions.
///
/// We need this to guard against functions that would transitively capture
/// variables before their definition, e.g.:
///
/// func outer() {
/// func first() {
/// second()
/// }
/// second()
/// var x
/// func second() {
/// use(x)
/// }
/// }
llvm::SmallDenseMap<AnyFunctionRef, SmallVector<AnyFunctionRef, 4>, 4>
ForwardCapturedFuncs;
/// A set of local functions from which C function pointers are derived.
///
/// This is used to diagnose the use of local functions with captured context
/// as C function pointers when the function's captures have not yet been
/// computed.
llvm::DenseMap<AnyFunctionRef, std::vector<Expr*>> LocalCFunctionPointers;
private:
Type IntLiteralType;
Type FloatLiteralType;
Type BooleanLiteralType;
Type UnicodeScalarType;
Type ExtendedGraphemeClusterType;
Type StringLiteralType;
Type ArrayLiteralType;
Type DictionaryLiteralType;
Type ColorLiteralType;
Type ImageLiteralType;
Type FileReferenceLiteralType;
Type StringType;
Type Int8Type;
Type UInt8Type;
Type NSObjectType;
Type NSErrorType;
Type ExceptionType;
/// The \c Swift.UnsafeMutablePointer<T> declaration.
Optional<NominalTypeDecl *> ArrayDecl;
/// A set of types that can be trivially mapped to Objective-C types.
llvm::DenseSet<CanType> ObjCMappedTypes;
/// A set of types that can be mapped to C integer types.
llvm::DenseSet<CanType> CIntegerTypes;
/// The set of expressions currently being analyzed for failures.
llvm::DenseMap<Expr*, Expr*> DiagnosedExprs;
/// A set of types that are representable in Objective-C, but require
/// non-trivial bridging.
///
/// The value of the map is a flag indicating whether the bridged
/// type can be optional.
llvm::DenseMap<CanType, bool> ObjCRepresentableTypes;
Module *StdlibModule = nullptr;
/// The index of the next response metavariable to bind to a REPL result.
unsigned NextResponseVariableIndex = 0;
/// If true, the time it takes to type-check each function will be dumped
/// to llvm::errs().
bool DebugTimeFunctionBodies = false;
/// Indicate that the type checker is checking code that will be
/// immediately executed. This will suppress certain warnings
/// when executing scripts.
bool InImmediateMode = false;
/// A helper to construct and typecheck call to super.init().
///
/// \returns NULL if the constructed expression does not typecheck.
Expr* constructCallToSuperInit(ConstructorDecl *ctor, ClassDecl *ClDecl);
public:
TypeChecker(ASTContext &Ctx) : TypeChecker(Ctx, Ctx.Diags) { }
TypeChecker(ASTContext &Ctx, DiagnosticEngine &Diags);
~TypeChecker();
LangOptions &getLangOpts() const { return Context.LangOpts; }
/// Dump the time it takes to type-check each function to llvm::errs().
void enableDebugTimeFunctionBodies() {
DebugTimeFunctionBodies = true;
}
bool getInImmediateMode() {
return InImmediateMode;
}
void setInImmediateMode(bool InImmediateMode) {
this->InImmediateMode = InImmediateMode;
}
template<typename ...ArgTypes>
InFlightDiagnostic diagnose(ArgTypes &&...Args) {
return Diags.diagnose(std::forward<ArgTypes>(Args)...);
}
Type getArraySliceType(SourceLoc loc, Type elementType);
Type getDictionaryType(SourceLoc loc, Type keyType, Type valueType);
Type getOptionalType(SourceLoc loc, Type elementType);
Type getImplicitlyUnwrappedOptionalType(SourceLoc loc, Type elementType);
Type getStringType(DeclContext *dc);
Type getInt8Type(DeclContext *dc);
Type getUInt8Type(DeclContext *dc);
Type getNSObjectType(DeclContext *dc);
Type getNSErrorType(DeclContext *dc);
Type getExceptionType(DeclContext *dc, SourceLoc loc);
/// \brief Try to resolve an IdentTypeRepr, returning either the referenced
/// Type or an ErrorType in case of error.
Type resolveIdentifierType(DeclContext *DC,
IdentTypeRepr *IdType,
TypeResolutionOptions options,
bool diagnoseErrors,
GenericTypeResolver *resolver,
UnsatisfiedDependency *unsatisfiedDependency);
/// Bind an UnresolvedDeclRefExpr by performing name lookup and
/// returning the resultant expression. Context is the DeclContext used
/// for the lookup.
Expr *resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE, DeclContext *Context);
/// \brief Validate the given type.
///
/// Type validation performs name binding, checking of generic arguments,
/// and so on to determine whether the given type is well-formed and can
/// be used as a type.
///
/// \param Loc The type (with source location information) to validate.
/// If the type has already been validated, returns immediately.
///
/// \param DC The context that the type appears in.
///
/// \param options Options that alter type resolution.
///
/// \param resolver A resolver for generic types. If none is supplied, this
/// routine will create a \c PartialGenericTypeToArchetypeResolver to use.
///
/// \returns true if type validation failed, or false otherwise.
bool validateType(TypeLoc &Loc, DeclContext *DC,
TypeResolutionOptions options = None,
GenericTypeResolver *resolver = nullptr,
UnsatisfiedDependency *unsatisfiedDependency = nullptr);
/// Check for unsupported protocol types in the given declaration.
void checkUnsupportedProtocolType(Decl *decl);
/// Check for unsupported protocol types in the given statement.
void checkUnsupportedProtocolType(Stmt *stmt);
/// Expose TypeChecker's handling of GenericParamList to SIL parsing.
/// We pass in a vector of nested GenericParamLists and a vector of
/// ArchetypeBuilders with the innermost GenericParamList in the beginning
/// of the vector.
bool handleSILGenericParams(SmallVectorImpl<ArchetypeBuilder *> &builders,
SmallVectorImpl<GenericParamList *> &gps,
DeclContext *DC);
/// \brief Resolves a TypeRepr to a type.
///
/// Performs name binding, checking of generic arguments, and so on in order
/// to create a well-formed type.
///
/// \param TyR The type representation to check.
///
/// \param DC The context that the type appears in.
///
/// \param options Options that alter type resolution.
///
/// \param resolver A resolver for generic types. If none is supplied, this
/// routine will create a \c PartialGenericTypeToArchetypeResolver to use.
///
/// \param unsatisfiedDependency When non-null, used to check whether
/// dependencies have been satisfied appropriately.
///
/// \returns a well-formed type or an ErrorType in case of an error.
Type resolveType(TypeRepr *TyR, DeclContext *DC,
TypeResolutionOptions options,
GenericTypeResolver *resolver = nullptr,
UnsatisfiedDependency *unsatisfiedDependency = nullptr);
void validateDecl(ValueDecl *D, bool resolveTypeParams = false);
/// Resolves the accessibility of the given declaration.
void validateAccessibility(ValueDecl *D);
/// Validate the given extension declaration, ensuring that it
/// properly extends the nominal type it names.
void validateExtension(ExtensionDecl *ext);
/// \brief Force all members of an external decl, and also add its
/// conformances.
void forceExternalDeclMembers(NominalTypeDecl *NTD);
/// Resolve a reference to the given type declaration within a particular
/// context.
///
/// This routine aids unqualified name lookup for types by performing the
/// resolution necessary to rectify the declaration found by name lookup with
/// the declaration context from which name lookup started.
///
/// \param typeDecl The type declaration found by name lookup.
/// \param fromDC The declaration context in which the name lookup occurred.
/// \param isSpecialized Whether this type is immediately specialized.
/// \param resolver The resolver for generic types.
///
/// \returns the resolved type, or emits a diagnostic and returns null if the
/// type cannot be resolved.
Type resolveTypeInContext(TypeDecl *typeDecl, DeclContext *fromDC,
TypeResolutionOptions options,
bool isSpecialized,
GenericTypeResolver *resolver = nullptr,
UnsatisfiedDependency *unsatisfiedDependency
= nullptr);
/// \brief Apply generic arguments to the given type.
///
/// \param type The unbound generic type to which to apply arguments.
/// \param loc The source location for diagnostic reporting.
/// \param dc The context where the arguments are applied.
/// \param genericArgs The list of generic arguments to apply to the type.
/// \param isGenericSignature True if we are looking only in the generic
/// signature of the context.
/// \param resolver The generic type resolver.
///
/// \returns A BoundGenericType bound to the given arguments, or null on
/// error.
Type applyGenericArguments(Type type,
SourceLoc loc,
DeclContext *dc,
MutableArrayRef<TypeLoc> genericArgs,
bool isGenericSignature,
GenericTypeResolver *resolver);
/// \brief Substitute the given base type into the type of the given member,
/// producing the effective type that the member will have.
///
/// \param module The module in which the substitution will be performed.
/// \param member The member whose type projection is being computed.
/// \param baseTy The base type that will be substituted for the 'Self' of the
/// member.
/// \param isTypeReference Whether this is a reference to a type declaration
/// within a type context.
Type substMemberTypeWithBase(Module *module, const ValueDecl *member,
Type baseTy, bool isTypeReference);
/// \brief Retrieve the superclass type of the given type, or a null type if
/// the type has no supertype.
Type getSuperClassOf(Type type);
/// \brief Determine whether one type is a subtype of another.
///
/// \param t1 The potential subtype.
/// \param t2 The potential supertype.
/// \param dc The context of the check.
///
/// \returns true if \c t1 is a subtype of \c t2.
bool isSubtypeOf(Type t1, Type t2, DeclContext *dc);
/// \brief Determine whether one type is implicitly convertible to another.
///
/// \param t1 The potential source type of the conversion.
///
/// \param t2 The potential destination type of the conversion.
///
/// \param dc The context of the conversion.
///
/// \returns true if \c t1 can be implicitly converted to \c t2.
bool isConvertibleTo(Type t1, Type t2, DeclContext *dc);
/// \brief Determine whether one type is explicitly convertible to another,
/// i.e. using an 'as' expression.
///
/// \param t1 The potential source type of the conversion.
///
/// \param t2 The potential destination type of the conversion.
///
/// \param dc The context of the conversion.
///
/// \returns true if \c t1 can be explicitly converted to \c t2.
bool isExplicitlyConvertibleTo(Type t1, Type t2, DeclContext *dc);
/// \brief Return true if performing a checked cast from one type to another
/// with the "as!" operator could possibly succeed.
///
/// \param t1 The potential source type of the cast.
///
/// \param t2 The potential destination type of the cast.
///
/// \param dc The context of the cast.
///
/// \returns true if a checked cast from \c t1 to \c t2 may succeed, and
/// false if it will certainly fail, e.g. because the types are unrelated.
bool checkedCastMaySucceed(Type t1, Type t2, DeclContext *dc);
/// \brief Determine whether a constraint of the given kind can be satisfied
/// by the two types.
///
/// \param t1 The first type of the constraint.
///
/// \param t2 The second type of the constraint.
///
/// \param dc The context of the conversion.
///
/// \returns true if \c t1 and \c t2 satisfy the constraint.
bool typesSatisfyConstraint(Type t1, Type t2,
constraints::ConstraintKind kind,
DeclContext *dc);
/// \brief Determine whether one type would be a valid substitution for an
/// archetype.
///
/// \param type The potential type.
///
/// \param archetype The archetype for which type may (or may not) be
/// substituted.
///
/// \param dc The context of the check.
///
/// \returns true if \c t1 is a valid substitution for \c t2.
bool isSubstitutableFor(Type type, ArchetypeType *archetype, DeclContext *dc);
/// If the inputs to an apply expression use a consistent "sugar" type
/// (that is, a typealias or shorthand syntax) equivalent to the result type
/// of the function, set the result type of the expression to that sugar type.
Expr *substituteInputSugarTypeForResult(ApplyExpr *E);
bool typeCheckAbstractFunctionBodyUntil(AbstractFunctionDecl *AFD,
SourceLoc EndTypeCheckLoc);
bool typeCheckAbstractFunctionBody(AbstractFunctionDecl *AFD);
bool typeCheckFunctionBodyUntil(FuncDecl *FD, SourceLoc EndTypeCheckLoc);
bool typeCheckConstructorBodyUntil(ConstructorDecl *CD,
SourceLoc EndTypeCheckLoc);
bool typeCheckDestructorBodyUntil(DestructorDecl *DD,
SourceLoc EndTypeCheckLoc);
void typeCheckClosureBody(ClosureExpr *closure);
void typeCheckTopLevelCodeDecl(TopLevelCodeDecl *TLCD);
void processREPLTopLevel(SourceFile &SF, TopLevelContext &TLC,
unsigned StartElem);
Identifier getNextResponseVariableName(DeclContext *DC);
void typeCheckDecl(Decl *D, bool isFirstPass);
void checkDeclAttributesEarly(Decl *D);
void checkDeclAttributes(Decl *D);
void checkTypeModifyingDeclAttributes(VarDecl *var);
void checkAutoClosureAttr(ParamDecl *D, AutoClosureAttr *attr);
void checkNoEscapeAttr(ParamDecl *D, NoEscapeAttr *attr);
void checkOwnershipAttr(VarDecl *D, OwnershipAttr *attr);
void computeAccessibility(ValueDecl *D);
void computeDefaultAccessibility(ExtensionDecl *D);
virtual void resolveAccessibility(ValueDecl *VD) override {
validateAccessibility(VD);
}
virtual void resolveDeclSignature(ValueDecl *VD) override {
validateDecl(VD, true);
}
virtual void resolveExtension(ExtensionDecl *ext) override {
validateExtension(ext);
checkInheritanceClause(ext);
}
virtual void resolveImplicitConstructors(NominalTypeDecl *nominal) override {
addImplicitConstructors(nominal);
}
virtual void
resolveExternalDeclImplicitMembers(NominalTypeDecl *nominal) override {
handleExternalDecl(nominal);
}
/// Determine attributes for the given function and curry level, with a level
/// of 0 indicating the innermost function.
AnyFunctionType::ExtInfo
applyFunctionTypeAttributes(AbstractFunctionDecl *func, unsigned i);
/// Determine whether the given (potentially constrained) protocol extension
/// is usable for the given type.
bool isProtocolExtensionUsable(DeclContext *dc, Type type,
ExtensionDecl *protocolExtension) override;
/// Validate the signature of a generic function.
///
/// \param func The generic function.
///
/// \returns true if an error occurred, or false otherwise.
bool validateGenericFuncSignature(AbstractFunctionDecl *func);
/// Revert the signature of a generic function to its pre-type-checked state,
/// so that it can be type checked again when we have resolved its generic
/// parameters.
void revertGenericFuncSignature(AbstractFunctionDecl *func);
/// Revert the dependent types within the given generic parameter list.
void revertGenericParamList(GenericParamList *genericParams);
/// Validate the given generic parameters to produce a generic
/// signature.
///
/// \param genericParams The generic parameters to validate.
///
/// \param dc The declaration context in which to perform the validation.
///
/// \param outerSignature The generic signature of the outer
/// context, if not available as part of the \c dc argument (used
/// for SIL parsing).
///
/// \param inferRequirements When non-empty, callback that will be invoked
/// to perform any additional requirement inference that contributes to the
/// generic signature. Returns true if an error occurred.
///
/// \param invalid Will be set true if an error occurs during validation.
///
/// \returns the generic signature that captures the generic
/// parameters and inferred requirements.
GenericSignature *validateGenericSignature(
GenericParamList *genericParams,
DeclContext *dc,
GenericSignature *outerSignature,
std::function<bool(ArchetypeBuilder &)> inferRequirements,
bool &invalid);
/// Validate the signature of a generic type.
///
/// \param nominal The generic type.
///
/// \returns true if an error occurred, or false otherwise.
bool validateGenericTypeSignature(NominalTypeDecl *nominal);
/// Check the generic parameters in the given generic parameter list (and its
/// parent generic parameter lists) according to the given resolver.
bool checkGenericParamList(ArchetypeBuilder *builder,
GenericParamList *genericParams,
DeclContext *parentDC,
bool adoptArchetypes = true,
GenericTypeResolver *resolver = nullptr);
/// Check the given set of generic arguments against the requirements in a
/// generic signature.
///
/// \param dc The context in which the generic arguments should be checked.
/// \param loc The location at which any diagnostics should be emitted.
/// \param noteLoc The location at which any notes will be printed.
/// \param owner The type that owns the generic signature.
/// \param genericSig The actual generic signature.
/// \param genericArgs The generic arguments.
///
/// \returns true if an error occurred, false otherwise.
bool checkGenericArguments(DeclContext *dc, SourceLoc loc,
SourceLoc noteLoc,
Type owner,
GenericSignature *genericSig,
ArrayRef<Type> genericArgs);
/// Given a type that was produced within the given generic declaration
/// context, produce the corresponding interface type.
///
/// \param dc The declaration context in which the type was produced.
///
/// \param type The type, which involves archetypes but not dependent types.
///
/// \returns the type after mapping all archetypes to their corresponding
/// dependent types.
Type getInterfaceTypeFromInternalType(DeclContext *dc, Type type);
/// Resolve the superclass of the given class.
void resolveSuperclass(ClassDecl *classDecl) override;
/// Resolve the raw type of the given enum.
void resolveRawType(EnumDecl *enumDecl) override;
/// Resolve the inherited protocols of a given protocol.
void resolveInheritedProtocols(ProtocolDecl *protocol) override;
/// Resolve the types in the inheritance clause of the given
/// declaration context, which will be a nominal type declaration or
/// extension declaration.
void resolveInheritanceClause(
llvm::PointerUnion<TypeDecl *, ExtensionDecl *> decl) override;
/// Check the inheritance clause of the given declaration.
void checkInheritanceClause(Decl *decl,
GenericTypeResolver *resolver = nullptr);
/// Retrieve the set of inherited protocols for this protocol type.
ArrayRef<ProtocolDecl *> getDirectConformsTo(ProtocolDecl *proto);
/// \brief Add any implicitly-defined constructors required for the given
/// struct or class.
void addImplicitConstructors(NominalTypeDecl *typeDecl);
/// \brief Add an implicitly-defined destructor, if there is no
/// user-provided destructor.
void addImplicitDestructor(ClassDecl *CD);
/// \brief Add the RawOptionSet (todo:, Equatable, and Hashable) methods to an
/// imported NS_OPTIONS struct.
void addImplicitStructConformances(StructDecl *ED);
/// \brief Add the RawRepresentable, Equatable, and Hashable methods to an
/// enum with a raw type.
void addImplicitEnumConformances(EnumDecl *ED);