apple/swift
Architecture
The Swift compiler is a multi-stage pipeline that translates Swift source code into machine code (or other artifacts such as .swiftmodule, .swiftinterface, or LLVM IR). Most of the compiler is C++ with LLVM as the backend, but an increasing portion of the optimizer and SIL utilities is implemented in Swift itself (SwiftCompilerSources/).
This page sketches the end-to-end pipeline and the major components. Each component has its own dedicated page under systems/.
End-to-end pipeline
graph TD
Source[".swift source"] --> Driver[Driver<br/>lib/Driver]
Driver --> Frontend[Frontend<br/>lib/Frontend, lib/FrontendTool]
Frontend --> Parse[Parser<br/>lib/Parse, lib/ASTGen]
Parse --> AST[AST<br/>lib/AST]
AST --> Sema[Semantic analysis<br/>lib/Sema]
Sema --> SILGen[SIL generation<br/>lib/SILGen]
SILGen --> SIL[Raw SIL<br/>lib/SIL]
SIL --> SILOpt[SIL optimizer<br/>lib/SILOptimizer + SwiftCompilerSources/Optimizer]
SILOpt --> Canonical[Canonical SIL]
Canonical --> IRGen[IR generation<br/>lib/IRGen]
IRGen --> LLVMIR[LLVM IR]
LLVMIR --> LLVM[LLVM backend]
LLVM --> Object[.o / .dylib / .so]
AST -.serialization.-> Module[.swiftmodule / .swiftinterface]
AST -.PrintAsClang.-> Header[.h header]
AST -.SymbolGraphGen.-> Symbols[symbol graph JSON]The driver supervises the build (file discovery, multi-file compilation, linking). The frontend processes one or more Swift source files. The result is either an object file (in compile mode), a serialized module, a header for Clang clients, or one of several reflective outputs.
Components
Frontend pipeline
| Stage | Code | Output |
|---|---|---|
| Lexing & parsing | lib/Parse/, lib/ASTGen/ (Swift-side) |
AST + source ranges |
| Type-check / Sema | lib/Sema/ (CSGen, CSSimplify, TypeCheckType, GenericSignatureBuilder) |
Type-checked AST |
| Generics | lib/AST/RequirementMachine/, lib/AST/GenericSignature* |
Reduced generic signatures, conformance paths |
| SIL generation | lib/SILGen/ |
Raw SIL |
| SIL optimization | lib/SILOptimizer/, SwiftCompilerSources/Sources/Optimizer/ |
Canonical SIL |
| LLVM IR generation | lib/IRGen/ |
LLVM IR |
Module system
| Concern | Code |
|---|---|
.swiftmodule serialization |
lib/Serialization/ |
Textual .swiftinterface |
lib/Frontend/ModuleInterfaceLoader.cpp, lib/Sema/ |
| C/Objective-C importing | lib/ClangImporter/ |
| Generating C++/ObjC headers | lib/PrintAsClang/ |
| Cross-import overlays | lib/Sema/, lib/Frontend/ |
| Symbol graph | lib/SymbolGraphGen/ |
Tooling and IDE support
| Concern | Code |
|---|---|
| IDE inspection (completion) | lib/IDE/, lib/IDETool/ |
| Refactoring | lib/Refactoring/ |
| Indexing | lib/Index/ |
| SourceKit | tools/SourceKit/ |
| Driver/CLI | lib/Driver/, lib/DriverTool/, tools/driver/ |
| Migrator | lib/Migrator/ |
| Demangling | lib/Demangling/, tools/swift-demangle/ |
Runtime and standard library
| Concern | Code |
|---|---|
Core types (Array, String, generics) |
stdlib/public/core/ |
| Runtime (metadata, casting, ARC) | stdlib/public/runtime/ |
| Concurrency (actors, tasks) | stdlib/public/Concurrency/ |
| Distributed actors | stdlib/public/Distributed/ |
| Observation | stdlib/public/Observation/ |
| Regex / String processing | stdlib/public/RegexBuilder/, stdlib/public/StringProcessing/, stdlib/public/RegexParser/ |
| C++ interop | stdlib/public/Cxx/ |
| Embedded Swift | stdlib/public/EmbeddedPlatform/, stdlib/public/SwiftDirectRuntime/, plus runtime conditionals |
| Reflection / remote inspection | stdlib/public/RemoteInspection/, stdlib/public/SwiftRemoteMirror/ |
The "second" stdlib build (Runtimes/)
The top-level Runtimes/ directory contains a newer, cleaner CMake build of the same standard library and overlays, used for cross-compilation and bring-up of new platforms (see Runtimes and Runtimes/Readme.md). Most stdlib changes happen under stdlib/, but the eventual home of the build is Runtimes/.
Two implementation languages
Historically the compiler was 100% C++. Today, two boundaries exist:
- C++ side —
lib/,include/,tools/,unittests/. Compiled with the host compiler (Clang or MSVC) using LLVM utilities. Contains the AST, Sema, SILGen, SIL, the SIL optimizer's C++ infrastructure, IRGen, the runtime, and the driver/frontend bodies. - Swift side —
SwiftCompilerSources/Sources/{AST,Basic,SIL,Optimizer}. New SIL passes and SIL utility code are written in Swift and called via a bridging layer. C++ owns the data structures; Swift wraps them with safe APIs and consumes them.
When following code, look in both places. A pass might have a Swift entry point in SwiftCompilerSources/Sources/Optimizer/Passes/ plus a C++ registration in lib/SILOptimizer/.
Driver vs frontend
The swift/swiftc binary is dispatched by tools/driver/driver.cpp, which calls into lib/DriverTool/ to figure out whether the user invoked the driver, the frontend (-frontend), the REPL, the package manager subcommand, etc.
- Driver — orchestrates multi-file builds: file discovery, output planning, parallel job scheduling, calling
swift -frontendper primary file, then running the linker. - Frontend — does the actual single-invocation compile (parse → sema → SILGen → SIL opt → IRGen → emit object / module / interface).
For most kinds of compiler hacking you only deal with the frontend.
Request evaluator
Type checking and many lazy AST queries flow through a request-evaluator graph. Each request (e.g., "what is the interface type of this declaration?") is a value-typed function whose result is cached and whose dependencies are tracked. See docs/RequestEvaluator.md. The lib/AST/Evaluator.cpp file implements the evaluator core; requests are defined throughout lib/AST/ and lib/Sema/.
SIL — the Swift Intermediate Language
SIL is Swift's own SSA-form IR, sitting between AST and LLVM IR. It captures Swift-level semantics that LLVM cannot: ownership, generics, dynamic dispatch, exclusivity. It has two phases:
- Raw SIL — output of SILGen, before mandatory passes.
- Canonical SIL — after mandatory passes (definite initialization, mandatory inlining, ARC, ownership lowering). This is the input to IRGen.
The optimizer pipeline runs as a sequence of passes registered in lib/SILOptimizer/PassManager/. New passes are increasingly written in Swift in SwiftCompilerSources/Sources/Optimizer/Passes/. See SIL and the SIL optimizer and docs/SIL/.
How a single file becomes a .o
sequenceDiagram
participant User
participant Driver as swift driver
participant Frontend as swift -frontend
participant Sema
participant SILGen
participant SILOpt
participant IRGen
participant LLVM
User->>Driver: swiftc Hello.swift
Driver->>Driver: plan jobs (compile + link)
Driver->>Frontend: -c Hello.swift -primary-file Hello.swift
Frontend->>Sema: parse + type-check
Sema-->>Frontend: typed AST
Frontend->>SILGen: lower AST to raw SIL
SILGen-->>Frontend: raw SIL
Frontend->>SILOpt: mandatory + perf passes
SILOpt-->>Frontend: canonical SIL
Frontend->>IRGen: lower to LLVM IR
IRGen->>LLVM: emit .bc / .o
LLVM-->>Driver: Hello.o
Driver->>Driver: link Hello.o → executableWhere to read next
- Standard library — what
stdlib/public/core/actually contains. - Runtime — the C++ runtime that supports Swift programs.
- Frontend and driver — the entry-point machinery.
- Sema — type checking and constraint solving.
- SIL and the SIL optimizer — the IR and the optimization pipeline.
- IRGen — lowering SIL to LLVM IR.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.
Previous
Swift project overview
Next
Getting started