File: declarations.tex

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (611 lines) | stat: -rw-r--r-- 35,350 bytes parent folder | download
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
\documentclass[../generics]{subfiles}

\begin{document}

\chapter{Declarations}\label{decls}

\IndexDefinition{declaration}
\IndexDefinition{value declaration}
\IndexDefinition{interface type}
\index{extension declaration}
\index{top-level code declaration}
\index{identifier}
\index{expression}
\lettrine{D}{eclarations are the building blocks} of Swift programs. The different kinds of declarations are categorized into a taxonomy. A \emph{value declaration} is a named entity which can be directly referenced from an expression. Every value declaration also has an \emph{interface type}; roughly speaking, this is the type of the expression naming the declaration. Most declarations one encounters are value declarations, for instance structs and functions. There are some important exceptions, however; extensions, described in Chapter~\ref{extensions}, add members to a type but do not themselves have names. A \emph{top-level code declaration} is another kind of declaration that is not a value declaration; it holds the statements and expressions at the top level of a source file.

\IndexDefinition{declared interface type}
\IndexDefinition{type declaration}
\index{metatype type}
A \emph{type declaration} is an important kind of value declaration. A type declaration declares a new type that you can write down in a type annotation; this is the \emph{declared interface type} of the type declaration. Since type declarations are value declarations, they also have an interface type, which is the type of an expression referencing the type declaration. When a type is used as a value, the type of the value is a metatype. A type declaration's interface type is therefore the metatype of its declared interface type.

\index{struct declaration}%
\index{enum declaration}%
\index{class declaration}%
\index{nominal type declaration}%
\index{protocol declaration}%
\IndexDefinition{self interface type}%
\Index{protocol Self type@protocol \texttt{Self} type}%
Struct, enum and class declarations are called \emph{nominal type declarations}. Protocols are also nominal type declarations, but they are special enough it is best to think of them as a separate kind of entity.
The \emph{self interface type} of a nominal type or extension declaration is the type from which the \texttt{self} parameter type of a method is derived. In a struct, enum or class declaration, the self interface type and declared interface type coincide. In a protocol, they differ; the declared interface type is a nominal type, while the self interface type is the protocol \texttt{Self} type (Section~\ref{protocols}).

\index{call expression}
\index{initial value expression}
\index{expression}
In the following, the nominal type declaration \texttt{Fish} is referenced twice, first as a type annotation, and then in an expression:
\begin{Verbatim}
struct Fish {}

let myFish: Fish = Fish()
\end{Verbatim}
This is a very simple piece of code, but there's more going on than seems at first glance. The first occurrence of \texttt{Fish} is the type annotation for the variable declaration \texttt{myFish}, so the interface type of \texttt{myFish} becomes the nominal type \texttt{Fish}. The second occurrence is inside the initial value expression of \texttt{myFish}. The callee of the call expression \texttt{Fish()} is the type expression \texttt{Fish}, whose type is the metatype \texttt{Fish.Type}. A call of a metatype is transformed into a call of the \texttt{init} member, which names a constructor declaration. Constructors are called on an instance of the metatype of a type, and return an instance of the type. So the initial value expression has the type \texttt{Fish}, which matches the interface type of \texttt{myFish}. The constructor has the interface type \verb|(Fish.Type) -> () -> Fish|.

\paragraph{Nesting}
\IndexDefinition{declaration context}
\index{module declaration}
\index{function declaration}
\index{variable declaration}
\index{generic parameter declaration}
\index{closure expression}
\index{source file}
A \emph{declaration context} contains declarations. They overlap with declarations, but neither one implies the other. Module declarations, nominal type declarations, extension declarations and function declarations are also declaration contexts. Variables and generic parameter declarations are declarations, but not declaration contexts. Last but not least, closure expressions and source files are declaration contexts, but not declarations. Table~\ref{taxonomy examples} summarizes the above.
\begin{table}\captionabove{Classifying various entities in our taxonomy}\label{taxonomy examples}
\begin{tabular}{lcccc}
\toprule
\textbf{Entity}&\textbf{Declaration?}&\textbf{Value decl?}&\textbf{Type decl?}&\textbf{Decl context?}\\
\midrule
Module&\checkmark&$\checkmark$&$\checkmark$&\checkmark\\
Source file&$\times$&$\times$&$\times$&\checkmark\\
Nominal type&\checkmark&\checkmark&\checkmark&\checkmark\\
Extension&\checkmark&$\times$&$\times$&\checkmark\\
Generic parameter&\checkmark&\checkmark&\checkmark&$\times$\\
Function&\checkmark&\checkmark&$\times$&\checkmark\\
Variable&\checkmark&\checkmark&$\times$&$\times$\\
Top-level code&$\checkmark$&$\times$&$\times$&\checkmark\\
Closure expression&$\times$&$\times$&$\times$&\checkmark\\
\bottomrule
\end{tabular}
\end{table}

\IndexDefinition{local declaration context}%
\index{subscript declaration}%
\IndexDefinition{initializer declaration context}%
Declarations and declaration contexts are nested within each other. The roots in this hierarchy are module declarations; all other declarations and declaration contexts point at a parent declaration context. Source files are always immediate children of module declarations. A \emph{local context} is any declaration context that is not a module, source file, type declaration or extension. Top-level code declarations, function declarations and closure expressions are three kinds of local contexts we've already seen.

\index{initial value expression}
The three remaining kinds of local context are subscript declarations, enum element declarations and initializer contexts:
\begin{itemize}
\item Subscripts and enum elements are local contexts, because they contain their parameter declarations.
\item Subscript declarations can also be generic, so they need to contain their generic parameters.
\item Initializer contexts represent the initial value expression of a variable that is itself not a child of a local context. This ensures that any declarations appearing in the initial value expression of a variable are always children of a local context.
\end{itemize}

\IndexDefinition{local type declaration}
\IndexDefinition{top-level type declaration}
\IndexDefinition{nested type declaration}
\IndexDefinition{local type declaration}
\IndexDefinition{top-level function declaration}
\IndexDefinition{method declaration}
\IndexDefinition{local function declaration}
\IndexDefinition{global variable declaration}
\IndexDefinition{stored property declaration}
\IndexDefinition{local variable declaration}
There is special terminology for type declarations in different kinds of declaration contexts:
\begin{itemize}
\item A \emph{top-level type} is an immediate child of a source file.
\item A \emph{nested type} or \emph{member type} is an immediate child of a nominal type declaration or an extension.
\item A \emph{local type} is an immediate child of a local context.
\end{itemize}
Similarly, for functions:
\begin{itemize}
\item A \emph{top-level function} or \emph{global function} is an immediate child of a source file.
\item A \emph{method} is an immediate child of a nominal type declaration or an extension.
\item A \emph{local function} is an immediate child of a local context.
\end{itemize}
And finally, for variables:
\begin{itemize}
\item A \emph{global variable} is an immediate child of a source file.
\item A \emph{property} is an immediate child of a nominal type declaration or an extension.
\item A \emph{local variable} is an immediate child of a local context.
\end{itemize}

\paragraph{Computing interface types}
\IndexDefinition{interface type request}
The \Request{interface type request} computes the interface type of a value declaration. The evaluation function switches over the declaration kind and takes different kinds of action, for example:
\begin{itemize}
\item Given a function declaration, this request recursively evaluates itself to get the interface type of each parameter declaration, and constructs a function type from the interface type of each parameter declaration together with the function's return type.
\item For a parameter declaration, this request resolves the type representation written by the user.
\item For a type declaration, it constructs a metatype from the declared interface type of the type declaration.
\end{itemize}
 
\section{Type Declarations}\label{type declarations}

\IndexDefinition{nominal type declaration}%
\IndexDefinition{struct declaration}%
\IndexDefinition{enum declaration}%
\IndexDefinition{class declaration}%
\index{declared interface type}%
\paragraph{Struct, enum and class declarations}
These are the concrete nominal types. The declared interface type of a non-generic nominal type declaration is a nominal type. If the nominal type declaration is generic, the declared interface type is a generic nominal type where the generic arguments are the declaration's generic parameters.

Concrete nominal types can be nested inside of other declaration contexts, with a few limitations described in Section~\ref{nested nominal types}. The declared interface type reflects this nesting. For example, the declared interface type of \texttt{Outer.Inner} is the generic nominal type \texttt{Outer<T>.Inner<U>}:
\begin{Verbatim}
struct Outer<T> {
  struct Inner<U> {}
}
\end{Verbatim}
Structs, enums and classes can conform to protocols; how this is modeled is the topic of Chapter~\ref{conformances}. Classes can also inherit from other classes; Chapter~\ref{classinheritance} describes how inheritance interacts with generics.

\IndexDefinition{protocol declaration}%
\paragraph{Protocol declarations}
The declared interface type of a protocol declaration is the protocol type \texttt{P}. Protocols are the fourth kind of nominal type, but they behave differently in many ways, because they do not have concrete instances. Protocol declarations are described in Chapter~\ref{protocols}.

\IndexDefinition{type alias declaration}%
\IndexDefinition{underlying type}%
\paragraph{Type alias declarations}
Type aliases assign a new name to an underlying type. The declared interface type is a type alias type whose canonical type is the underlying type of the type alias. While type aliases are declaration contexts, the only kind of declaration they contain is their own generic parameter declarations. The special case of type aliases in protocols is discussed in Section~\ref{protocol type alias}.

\IndexDefinition{generic parameter declaration}%
\paragraph{Generic parameter declarations}
Generic parameter declarations declare generic parameter types. They appear inside the generic parameter lists of generic declarations. The declared interface type of a generic parameter declaration is a sugared type that prints as the name of the declaration; the canonical type is the generic parameter type \ttgp{d}{i}, where \texttt{d} is the depth and \texttt{i} is the index. Generic parameter declarations are described in Chapter~\ref{generic declarations}.

\IndexDefinition{associated type declaration}%
\index{bound dependent member type}%
\paragraph{Associated type declarations}
Associated type declarations appear inside protocols. The declared interface type of an associated type \texttt{A} is a bound dependent member type \texttt{Self.[P]A} referencing the declaration of \texttt{A}, with the \texttt{Self} generic parameter of the protocol as the base type. Associated type declarations are described in Section~\ref{protocols}.

\section{Function Declarations}\label{func decls}

\IndexDefinition{function declaration}
\index{generic function type}
\paragraph{Function declarations}
Functions can either appear at the top level, inside of a local context such as another function, or as a member of a type, called a method. If a function is itself generic or nested inside of a generic context, the interface type is a generic function type, otherwise it is a function type.

The interface type of a function is constructed from the interface types of the function's parameter declarations, and the function's return type. If the return type is omitted, it becomes the empty tuple type \texttt{()}. For methods, this function type is then wrapped in another level of function type representing the base of the call which becomes the \texttt{self} parameter of the method.

\index{self interface type}
\IndexDefinition{method self parameter}
The \texttt{self} parameter's type and parameter flags are constructed from the self interface type of the method's type declaration, and various attributes of the method:
\begin{itemize}
\item If the method is \texttt{mutating}, the \texttt{self} parameter becomes \texttt{inout}.
\item If the method returns the dynamic Self type, the \texttt{self} parameter type is wrapped in the dynamic Self type.
\item Finally, if the method is \texttt{static}, the \texttt{self} parameter is wrapped in a metatype.
\end{itemize}

This can be summarized as follows; note that \texttt{(Self)} parameter list means the self interface type of the method's type declaration, together with any additional parameter flags computed via the above:
\begin{quote}
\begin{tabular}{ccll}
\toprule
\textbf{Generic?}&\textbf{Method?}&\textbf{Interface type}\\
\midrule
$\times$&$\times$&\texttt{(Params)\ -> Result}\\
\checkmark&$\times$&\texttt{<Sig> (Params)\ -> Result}\\
$\times$&\checkmark&\texttt{(Self) -> (Params)\ -> Result}\\
\checkmark&\checkmark&\texttt{<Sig> (Self) -> (Params)\ -> Result}\\
\bottomrule
\end{tabular}
\end{quote}

\index{call expression}
The two levels of function type in the interface type of a method mirror the two-level structure of a method call expression \texttt{foo.bar(1, 2)}, shown in Figure~\ref{method call expr}:
\begin{itemize}
\item The self apply expression \texttt{foo.bar} applies the single argument \texttt{foo} to the method's \texttt{self} parameter. The type of the self apply expression is the method's inner function type.
\item The outer call applies the argument list \texttt{(1, 2)} to the inner function type. The type of the outer call expression is the method's return type.
\end{itemize}

\begin{figure}\captionabove{Two levels of function application in a method call \texttt{foo.bar(1, 2)}}\label{method call expr}
\begin{center}
\begin{tikzpicture}[%
  grow via three points={one child at (0.5,-0.7) and
  two children at (0.5,-0.7) and (0.5,-1.4)},
  edge from parent path={[->] (\tikzparentnode.south) |- (\tikzchildnode.west)}]
  \node  [class] {\vphantom{p}call expression: \texttt{Result}}
    child { node [class] {\vphantom{p}self apply expression: \texttt{(Int, Int) -> ()}}
      child { node  [class] {\vphantom{p}declaration reference expression: \texttt{Foo.bar}}}
      child { node  [class] {\vphantom{p}declaration reference expression: \texttt{foo}}}}
    child [missing] {}
    child [missing] {}
    child { node [class] {\vphantom{p}argument list}
      child { node  [class] {\vphantom{p}integer literal expression: \texttt{1}}}
      child { node  [class] {\vphantom{p}integer literal expression: \texttt{2}}}}
    child [missing] {}
    child [missing] {}
    child [missing] {};
\end{tikzpicture}
\end{center}
\end{figure}

\IndexDefinition{constructor declaration}
\paragraph{Constructor declarations}
Constructor declarations always appear as members of other types, and are named \texttt{init}. The interface type of a constructor takes a metatype and returns an instance of the constructed type, possibly wrapped in an \texttt{Optional}.

\begin{quote}
\begin{tabular}{cl}
\toprule
\textbf{Generic?}&\textbf{Interface type}\\
\midrule
$\times$&\texttt{(Self.Type) -> (Params)\ -> Self}\\
\checkmark&\texttt{<Sig> (Self.Type) -> (Params)\ -> Self}\\
\bottomrule
\end{tabular}
\end{quote}

\IndexDefinition{initializer interface type}
Class constructors also have a \emph{initializer interface type}, used when a subclass initializer delegates to an initializer in the superclass. The initializer interface type is the same as the interface type, except it takes a self value instead of a self metatype.

\begin{quote}
\begin{tabular}{cl}
\toprule
\textbf{Generic?}&\textbf{Initializer interface type}\\
\midrule
$\times$&\texttt{(Self) -> (Params)\ -> Self}\\
\checkmark&\texttt{<Sig> (Self) -> (Params)\ -> Self}\\
\bottomrule
\end{tabular}
\end{quote}

\IndexDefinition{destructor declaration}
\paragraph{Destructor declarations}
Destructor declarations cannot have a generic parameter list, a \texttt{where} clause, or a parameter list. Formally they take no parameters and return \texttt{()}.

\begin{quote}
\begin{tabular}{cl}
\toprule
\textbf{Generic?}&\textbf{Interface type}\\
\midrule
$\times$&\texttt{(Self) -> ()\ -> ()}\\
\checkmark&\texttt{<Sig> (Self) -> ()\ -> ()}\\
\bottomrule
\end{tabular}
\end{quote}

\section{Storage Declarations}
\IndexDefinition{storage declaration}
\index{l-value type}
Storage declarations represent the declaration of an l-value. Storage declarations can have zero or more associated accessor declarations. The accessor declarations are siblings of the storage declaration in the declaration context hierarchy.

\IndexDefinition{variable declaration}
\paragraph{Variable declarations} The interface type of a variable is the stored value type, possibly wrapped in a reference storage type if the variable is declared as \texttt{weak} or \texttt{unowned}. The \emph{value interface type} of a variable is the storage type without any wrapping.

For historical reasons, the interface type of a property (a variable appearing inside of a type) does not include the \texttt{Self} clause, the way that method declarations do.

\IndexDefinition{pattern binding declaration}
\IndexDefinition{pattern binding entry}
\IndexDefinition{pattern}
\IndexDefinition{initial value expression}
Variable declarations are always created alongside a \emph{pattern binding declaration} which represents the various ways in which variables can be bound to values in Swift. A pattern binding declaration consists of one or more \emph{pattern binding entries}. Each pattern binding entry has a \emph{pattern} and an optional \emph{initial value expression}. A pattern declares zero or more variables.

\begin{example}
A pattern binding declaration with a single entry, where the pattern declares a single variable:
\begin{Verbatim}
let x = 123
\end{Verbatim}
Same as the above, except with a more complex pattern which declares a variable storing the first element of a tuple while discarding the second element:
\begin{Verbatim}
let (x, _) = (123, "hello")
\end{Verbatim}
A pattern binding declaration with a single entry, where the pattern declares two variables \texttt{x} and \texttt{y}:
\begin{Verbatim}
let (x, y) = (123, "hello")
\end{Verbatim}
A pattern binding declaration with two entries, where the first pattern declares \texttt{x} and the second declares \texttt{y}:
\begin{Verbatim}
let x = 123, y = "hello"
\end{Verbatim}
A pattern binding declaration with a single entry that does not declare any variables:
\begin{Verbatim}
let _ = ignored()
\end{Verbatim}
And finally, two pattern binding declarations, where each one pattern binding declaration has a single entry declaring a single variable:
\begin{Verbatim}
let x = 123
let y = "hello"
\end{Verbatim}
\end{example}
\begin{example}
When a pattern binding declaration appears outside of a local context, each entry must declare at least one variable, so we reject both of the following:
\begin{Verbatim}
let _ = 123

struct S {
  let _ = "hello"
}
\end{Verbatim}
\end{example}
\index{typed pattern}
\index{tuple pattern}
\begin{example}
A funny quirk of the pattern grammar is that typed patterns and tuple patterns do not compose in the way one might think. If ``\texttt{let x:~Int}'' is a typed pattern declaring a variable \texttt{x} type with annotation \texttt{Int}, and ``\texttt{let (x, y)}'' is a tuple pattern declaring two variables \texttt{x} and \texttt{y}, you might expect ``\texttt{let~(x:~Int,~y:~String)}'' to declare two variables \texttt{x} and \texttt{y} with type annotations \texttt{Int} and \texttt{String} respectively; what actually happens is you get a tuple pattern declaring two variables named \texttt{Int} and \texttt{String} that binds a two-element tuple with \emph{labels} \texttt{x} and \texttt{y}:
\begin{Verbatim}
let (x: Int, y: String) = (x: 123, y: "hello")
print(Int)  // huh? prints 123
print(String)  // weird! prints "hello"
\end{Verbatim}
\end{example}

\IndexDefinition{parameter declaration}%
\IndexDefinition{value ownership kind}%
\index{autoclosure function type}%
\paragraph{Parameter declarations} Functions, enum elements and subscripts can have parameter lists; each parameter is represented by a parameter declaration. The interface type of a declaration with a parameter list is built by first computing the interface type of each parameter. Among other things, the parameter declaration stores the value ownership kind, the variadic flag, and the \texttt{@autoclosure} attribute. This is in fact the same exact information encoded in the parameter list of a function type.

\index{argument label}%
\IndexDefinition{default argument expression}%
\index{closure expression}%
Closure expressions also have parameter lists and thus parent parameter declarations. Parameter declarations of named declarations can have argument labels and default argument expressions, which are not encoded in a function type. These phenomena are only visible when directly calling a named declaration and not a closure value.

\IndexDefinition{subscript declaration}%
\paragraph{Subscript declarations} Subscripts always appear as members of types, with a special declaration name. The interface type of a subscript is a function type taking the index parameters and returning the storage type. The value interface type of a subscript is just the storage type. For historical reasons, the interface type of a subscript does not include the \texttt{Self} clause, the way that method declarations do.
\begin{quote}
\begin{tabular}{clll}
\toprule
\textbf{Generic?}&\textbf{Interface type}\\
\midrule
$\times$&\texttt{(Indices...)\ -> Value}\\
$\checkmark$&\texttt{<Sig...>\ (Indices...)\ -> Value}\\
\bottomrule
\end{tabular}
\end{quote}

\IndexDefinition{accessor declaration}
\paragraph{Accessor declarations}

The interface type of an accessor depends the accessor kind. For example, getters return the value, and setters take the new value as a parameter. Property accessors do not take any other parameters; subscript accessors also take the subscript's index parameters. There is a lot more to say about accessors and storage declarations, but unfortunately, you'll have to wait for the next book.

\section{Source Code Reference}\label{declarationssourceref}

Key source files:
\begin{itemize}
\item \SourceFile{include/swift/AST/Decl.h}
\item \SourceFile{include/swift/AST/DeclContext.h}
\item \SourceFile{lib/AST/Decl.cpp}
\item \SourceFile{lib/AST/DeclContext.cpp}
\end{itemize}
Other source files:
\begin{itemize}
\item \SourceFile{include/swift/AST/DeclNodes.def}
\item \SourceFile{include/swift/AST/ASTVisitor.h}
\item \SourceFile{include/swift/AST/ASTWalker.h}
\end{itemize}

\IndexSource{declaration}
\apiref{Decl}{class}
Base class of declarations. Figure~\ref{declhierarchy} shows various subclasses, which correspond to the different kinds of declarations defined previously in this chapter.
\begin{figure}\captionabove{The \texttt{Decl} class hierarchy}\label{declhierarchy}
\begin{center}
\begin{tikzpicture}[%
  grow via three points={one child at (0.5,-0.7) and
  two children at (0.5,-0.7) and (0.5,-1.4)},
  edge from parent path={[->] (\tikzparentnode.south) |- (\tikzchildnode.west)}]
  \node  [class] {\texttt{\vphantom{p}Decl}}
    child { node [class] {\texttt{\vphantom{p}ValueDecl}}
      child { node  [class] {\texttt{\vphantom{p}TypeDecl}}
        child { node  [class] {\texttt{\vphantom{p}NominalTypeDecl}}
          child { node  [class] {\texttt{\vphantom{p}StructDecl}}}
          child { node  [class] {\texttt{\vphantom{p}EnumDecl}}}
          child { node  [class] {\texttt{\vphantom{p}ClassDecl}}}
          child { node  [class] {\texttt{\vphantom{p}ProtocolDecl}}}
        }
        child [missing] {}
        child [missing] {}
        child [missing] {}
        child [missing] {}
        child { node  [class] {\texttt{\vphantom{p}TypeAliasDecl}}}
        child { node  [class] {\texttt{\vphantom{p}AbstractTypeParamDecl}}
          child { node  [class] {\texttt{\vphantom{p}GenericTypeParamDecl}}}
          child { node  [class] {\texttt{\vphantom{p}AssociatedTypeDecl}}}
        }
      }
      child [missing] {}
      child [missing] {}
      child [missing] {}
      child [missing] {}
      child [missing] {}
      child [missing] {}
      child [missing] {}
      child [missing] {}
      child [missing] {}
      child { node  [class] {\texttt{\vphantom{p}AbstractFunctionDecl}}
        child { node [class] {\texttt{\vphantom{p}FuncDecl}}
             child { node  [class] {\texttt{\vphantom{p}AccessorDecl}}}
        }
        child [missing] {}
        child { node  [class] {\texttt{\vphantom{p}ConstructorDecl}}}
        child { node  [class] {\texttt{\vphantom{p}DestructorDecl}}}
      }
      child [missing] {}
      child [missing] {}
      child [missing] {}
      child [missing] {}
      child { node  [class] {\texttt{\vphantom{p}AbstractStorageDecl}}
        child { node  [class] {\texttt{\vphantom{p}VarDecl}}
            child { node  [class] {\texttt{\vphantom{p}ParamDecl}}}
        }
        child [missing] {}
        child { node  [class] {\texttt{\vphantom{p}SubscriptDecl}}}
      }
      child [missing] {}
      child [missing] {}
      child [missing] {}
    }
    child [missing] {}
    child [missing] {}
    child [missing] {}
    child [missing] {}
    child [missing] {}
    child [missing] {}
    child [missing] {}
    child [missing] {}
    child [missing] {}
    child [missing] {}
    child [missing] {}
    child [missing] {}
    child [missing] {}
    child [missing] {}
    child [missing] {}
    child [missing] {}
    child [missing] {}
    child [missing] {}
    child [missing] {}
    child { node  [class] {\texttt{\vphantom{p}ExtensionDecl}}};
\end{tikzpicture}
\end{center}
\end{figure}

\IndexSource{synthesized declaration}
Instances are always allocated in the permanent arena of the \texttt{ASTContext}, either when the declaration is parsed or synthesized. The top-level \verb|isa<>|, \verb|cast<>| and \verb|dyn_cast<>| template functions support dynamic casting from \texttt{Decl *} to any of its subclasses.
\begin{itemize}
\item \texttt{getDeclContext()} returns the parent \texttt{DeclContext} of this declaration.
\item \texttt{getInnermostDeclContext()} if this declaration is also a declaration context, returns the declaration as a \texttt{DeclContext}, otherwise returns the parent \texttt{DeclContext}.
\item \texttt{getASTContext()} returns the singleton AST context from a declaration.
\end{itemize}

\index{visitor pattern}
\IndexSource{declaration kind}
\index{exhaustive switch}
\index{statement}
\index{expression}
\index{type representation}
\paragraph{Visitors}
If you need to exhaustively handle each kind of declaration, the simplest way is to switch over the kind, which is an instance of the \texttt{DeclKind} enum, like this:
\begin{Verbatim}
Decl *decl = ...;
switch (decl->getKind()) {
case DeclKind::Struct: {
  auto *structDecl = decl->castTo<StructDecl>();
  ...
}
case DeclKind::Enum:
  ...
case DeclKind::Class:
  ...
}
\end{Verbatim}
However, just as with types, is can be more convenient to use the visitor pattern. You can subclass \texttt{ASTVisitor} and override various \texttt{visit\emph{Kind}Decl()} methods, then hand the declaration to the visitor's \texttt{visit()} method, which performs the switch and dynamic cast dance above:
\begin{Verbatim}
class MyVisitor: public ASTVisitor<MyVisitor> {
public:
  void visitStructDecl(StructType *decl) {
    ...
  }
};

MyVisitor visitor;

Decl *decl = ...;
visitor.visit(decl);
\end{Verbatim}
The \texttt{ASTVisitor} also defines various methods corresponding to abstract base classes in the \texttt{Decl} hierarchy, so for example you can override \texttt{visitNominalTypeDecl()} to handle all nominal type declarations at once. The \texttt{ASTVisitor} is more general than just visiting declarations; it also supports visiting statements, expressions, and type representations.

A more elaborate form is implemented by the \texttt{ASTWalker}. While the visitor visits a single declaration, the walker traverses nested declarations, statements and expressions for you in a pre-order walk.

\IndexSource{value declaration}
\apiref{ValueDecl}{class}
Base class of named declarations.

\IndexSource{interface type}
\begin{itemize}
\item \texttt{getDeclName()} returns the declaration's name.
\item \texttt{getInterfaceType()} returns the declaration's interface type.
\end{itemize}

\IndexSource{type declaration}
\IndexSource{declared interface type}
\apiref{TypeDecl}{class}
Base class of type declarations.
\begin{itemize}
\item \texttt{getDeclaredInterfaceType()} returns the type of an instance of this declaration.
\end{itemize}

\IndexSource{nominal type declaration}
\IndexSource{struct declaration}
\IndexSource{enum declaration}
\IndexSource{class declaration}
\IndexSource{nominal type declaration}
\IndexSource{self interface type}
\apiref{NominalTypeDecl}{class}
Base class of nominal type declarations. Also a \texttt{DeclContext}.
\begin{itemize}
\item \texttt{getSelfInterfaceType()} returns the type of the \texttt{self} value inside the body of this declaration. Different from the declared interface type for protocols, where the declared interface type is a nominal but the declared self type is the generic parameter \texttt{Self}.
\item \texttt{getDeclaredType()} returns the type of an instance of this declaration, without generic arguments. If the declaration is generic, this is an unbound generic type. If this declaration is not generic, this is a nominal type. This is occasionally used in diagnostics instead of the declared interface type, when the generic parameter types are irrelevant.
\end{itemize}

\IndexSource{type alias declaration}
\IndexSource{underlying type}
\apiref{TypeAliasDecl}{class}
A type alias declaration. Also a \texttt{DeclContext}.
\begin{itemize}
\item \texttt{getDeclaredInterfaceType()} returns the underlying type of the type alias declaration, wrapped in type alias type sugar.
\item \texttt{getUnderlyingType()} returns the underlying type of the type alias declaration, without wrapping it in type alias type sugar.
\end{itemize}

\IndexSource{function declaration}
\IndexSource{method self parameter}
\apiref{AbstractFunctionDecl}{class}
Base class of function-like declarations. Also a \texttt{DeclContext}.
\begin{itemize}
\item \texttt{getImplicitSelfDecl()} returns the implicit \texttt{self} parameter, if there is one.
\item \texttt{getParameters()} returns the function's parameter list.
\item \texttt{getMethodInterfaceType()} returns the type of a method without the \texttt{Self} clause.
\item \texttt{getResultInterfaceType()} returns the return type of this function or method.
\end{itemize}

\apiref{ParameterList}{class}
The parameter list of \texttt{AbstractFunctionDecl}, \texttt{EnumElementDecl} or \texttt{SubscriptDecl}.
\begin{itemize}
\item \texttt{size()} returns the number of parameters.
\item \texttt{get()} returns the \texttt{ParamDecl} at the given index.
\end{itemize}

\IndexSource{constructor declaration}
\apiref{ConstructorDecl}{class}
Constructor declarations.
\begin{itemize}
\item \texttt{getInitializerInterfaceType()} returns the initializer interface type, used when type checking \texttt{super.init()} delegation.
\end{itemize}

\IndexSource{storage declaration}
\apiref{AbstractStorageDecl}{class}
Base class for storage declarations.
\begin{itemize}
\item \texttt{getValueInterfaceType()} returns the type of the stored value, without \texttt{weak} or \texttt{unowned} storage qualifiers.
\end{itemize}

\IndexSource{declaration context}
\apiref{DeclContext}{class}
Base class for declaration contexts. The top-level \verb|isa<>|, \verb|cast<>| and \verb|dyn_cast<>| template functions also support dynamic casting from a \texttt{DeclContext *} to any of its subclasses.

\IndexSource{closure expression}
\IndexSource{source file}
\IndexSource{file unit}
There are a handful of subclasses which are not also subclasses of \texttt{Decl *}:
\begin{itemize}
\item \texttt{ClosureExpr}.
\item \texttt{FileUnit} and its various subclasses, such as \texttt{SourceFile}.
\item A few other less interesting ones you can find in the source.
\end{itemize}

Utilities for understanding the nesting of declaration contexts:
\begin{itemize}
\item \texttt{getAsDecl()} if declaration context is also a declaration, returns the declaration, otherwise returns \texttt{nullptr}.
\item \texttt{getParent()} returns the parent declaration context.
\item \texttt{isModuleScopeContext()} returns true if this is a \texttt{ModuleDecl} or \texttt{FileUnit}.
\item \texttt{isTypeContext()} returns true if this is a nominal type declaration or an extension.
\item \texttt{isLocalContext()} returns true if this is not a module scope context or type context.
\item \texttt{getParentModule()} returns the module declaration at the root of the hierarchy.
\item \texttt{getModuleScopeContext()} returns the innermost parent which is a \texttt{ModuleDecl} or \texttt{FileUnit}.
\item \texttt{getParentSourceFile()} returns the innermost parent which is a source file, or \texttt{nullptr} if this declaration context was not parsed from source.
\item \texttt{getInnermostDeclarationDeclContext()} returns the innermost parent which is also a declaration, or \texttt{nullptr}.
\item \texttt{getInnermostDeclarationTypeContext()} returns the innermost parent which is also a nominal type or extension, or \texttt{nullptr}.
\end{itemize}
Operations on type contexts:
\begin{itemize}
\item \texttt{getSelfNominalDecl()} returns the nominal type declaration if this is a type context, or \texttt{nullptr}.
\item \texttt{getSelfStructDecl()} as above but result is a \texttt{StructDecl *} or \texttt{nullptr}.
\item \texttt{getSelfEnumDecl()} as above but result is a \texttt{EnumDecl *} or \texttt{nullptr}.
\item \texttt{getSelfClassDecl()} as above but result is a \texttt{ClassDecl *} or \texttt{nullptr}.
\item \texttt{getSelfProtocolDecl()} as above but result is a \texttt{ProtocolDecl *} or \texttt{nullptr}.
\item \texttt{getDeclaredInterfaceType()} delegates to the method on \texttt{NominalTypeDecl} or \texttt{ExtensionDecl} as appropriate.
\item \texttt{getSelfInterfaceType()} is similar.
\end{itemize}
Generics-related methods on \texttt{DeclContext} are described in Section~\ref{genericdeclsourceref}.

\end{document}