apple/swift
Frontend and driver
Active contributors: jrose-apple, DougGregor, akyrtzi
Purpose
The driver is the user-facing swift / swiftc binary that orchestrates a build: discovering source files, planning compile / link jobs, parallelizing them, and invoking the frontend per file. The frontend (swift -frontend) is the per-invocation compiler that actually parses, type-checks, and lowers a single primary file (or a whole module) to an output artifact.
Directory layout
tools/driver/
└── driver.cpp # main entry point (5 lines)
lib/DriverTool/ # subcommand dispatch (driver vs frontend vs ...)
├── DriverTool.cpp
├── modulewrap_main.cpp
├── swift_api_digester_main.cpp
├── swift_api_extract_main.cpp
└── swift_symbolgraph_extract_main.cpp
lib/Driver/ # the C++ driver (legacy / fallback)
├── Driver.cpp
├── Compilation.cpp
├── Job.cpp
├── DarwinToolChains.cpp
├── UnixToolChains.cpp
├── WindowsToolChains.cpp
└── WebAssemblyToolChains.cpp
lib/Frontend/ # frontend orchestration
├── CompilerInvocation.cpp
├── Frontend.cpp
├── FrontendOptions.cpp
├── ModuleInterfaceLoader.cpp
└── ParseableInterfaceModuleLoader.cpp
lib/FrontendTool/ # frontend body (the actual compile)
└── FrontendTool.cpp # the dispatch from -frontend args to outputsThe default user-facing driver is actually the Swift-implemented swift-driver which lives in a sibling repo. The C++ lib/Driver/ here is a fallback used for some legacy paths and for bootstrapping.
Key abstractions
| Type | File | Description |
|---|---|---|
swift::mainEntry |
lib/DriverTool/DriverTool.cpp |
Decides which subcommand was requested. |
swift::Driver |
lib/Driver/Driver.cpp |
Top-level driver: parses args, plans jobs. |
swift::driver::Compilation |
lib/Driver/Compilation.cpp |
Owns the planned set of Jobs and runs them. |
swift::driver::Job |
lib/Driver/Job.cpp |
One subprocess invocation (compile, link, etc.). |
swift::driver::ToolChain |
lib/Driver/ToolChain.cpp |
Per-platform compiler/linker selection. |
swift::CompilerInvocation |
include/swift/Frontend/Frontend.h |
Parsed swift -frontend flags. |
swift::CompilerInstance |
include/swift/Frontend/Frontend.h |
Live state: ASTContext, source manager, modules. |
swift::FrontendOptions |
include/swift/Frontend/FrontendOptions.h |
Frontend-specific options enum. |
swift::performFrontend |
lib/FrontendTool/FrontendTool.cpp |
The frontend's main loop: dispatches to per-action handlers. |
How it works
sequenceDiagram
participant Bin as swift / swiftc binary
participant DT as DriverTool
participant Driver as lib/Driver
participant Frontend as lib/FrontendTool
Bin->>DT: mainEntry(argc, argv)
DT->>DT: pick mode by argv[0] / first arg
alt user invoked driver
DT->>Driver: Driver::buildCompilation(args)
Driver->>Driver: discover inputs, plan jobs
loop per primary file
Driver->>Frontend: spawn `swift -frontend ...`
Frontend-->>Driver: .o or .swiftmodule
end
Driver->>Driver: link
else user passed -frontend
DT->>Frontend: performFrontend(args)
Frontend-->>Bin: exit code
endDriver vs swift-driver
Two implementations exist:
- C++
lib/Driver/-- in this repo, written years ago. Used as a fallback and for some legacy paths (e.g.,swift-frontend -emit-stub). EachToolChainderived class (DarwinToolChains.cpp,UnixToolChains.cpp,WindowsToolChains.cpp,WebAssemblyToolChains.cpp) describes how to invoke the linker, the assembler, and any post-processing tools for that platform. - swift-driver -- a separate Swift-implemented driver in swiftlang/swift-driver. Shipping toolchains use it by default. It links against the same options definitions in
lib/Option/.
The frontend's main loop
swift::performFrontend (in lib/FrontendTool/FrontendTool.cpp) is a giant switch on the requested action (-emit-object, -emit-sil, -emit-ir, -typecheck, -emit-module, -emit-symbol-graph, ...). For each primary file:
- Build a
CompilerInstance(loads the standard library, sets up theASTContext). - Parse and type-check the primary file.
- If the action wants SIL: run SILGen, then the optimizer.
- If the action wants IR or an object: run IRGen.
- Emit the artifact.
-emit-sib (Swift Intermediate Bitcode) and -emit-module are short-circuit paths that stop at SIL or AST serialization respectively.
Integration points
- The driver consumes the central options database in
lib/Option/Options.td(TableGen). The same.tdis used bylib/DriverTool/,swift-driver, and frontend option parsing. - The driver invokes Clang for
-x cinputs and the linker (ld64,lld,link.exe) perToolChain. - The frontend depends on essentially every other compiler library (
AST,Sema,SILGen,SILOptimizer,IRGen,Serialization,Frontend,ClangImporter,Index,IDE,Migrator, ...).
Entry points for modification
- Adding a new compile action (e.g.,
-emit-foo): editlib/Frontend/FrontendOptions.cppto recognize the option, add a case inperformFrontendinlib/FrontendTool/FrontendTool.cpp, and wire it throughCompilerInvocation. - Adding a driver flag: add to
lib/Option/Options.td, then handle it inDriver.cppand pass through to the frontend. - Adding a new
ToolChain: subclassswift::driver::ToolChaininlib/Driver/, register inDriver::buildToolChain.
Related pages
- Parser -- what runs first inside the frontend.
- Sema -- what runs second.
- Serialization and module loading --
-emit-moduleand.swiftinterface. - SwiftCompilerSources -- bridging into Swift-side passes.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.
Previous
Systems
Next
Parser