apple/swift
Patterns and conventions
Coding conventions for the two languages that live in this repo.
C++ side
The compiler and runtime are LLVM-style C++. Conventions are largely LLVM's, with Swift-specific extensions.
Style
.clang-formatis enforced. Runutils/git-clang-format-all.zshbefore sending a PR.- 2-space indentation, no tabs.
- Public types in
include/swift/<Subsystem>/, implementation inlib/<Subsystem>/. - Headers use
#pragma once+ namespaceswift.
Idioms
StringRefandArrayRefeverywhere -- avoid passingstd::stringorstd::vectorby value.- Pointer-likeness --
Decl *,Type(a small wrapper around a pointer),SILValueare all cheap-to-copy handles. Don't pass them by reference. - Casting -- use
dyn_cast,cast,isa(LLVM RTTI), not C++dynamic_cast. Each Swift hierarchy providesclassof()for these. - Source locations -- pass
SourceLocandSourceRangefromswift::SourceManager. They're 4-byte tokens, not strings. - Diagnostics -- never print directly. Use
Context.Diags.diagnose(loc, diag::id, args...). Diagnostic IDs live ininclude/swift/AST/Diagnostics*.def.
Diagnostics
Adding a diagnostic looks like:
- Add an entry to
include/swift/AST/DiagnosticsSema.def(orDiagnosticsParse.def,DiagnosticsSIL.def, etc.):ERROR(my_new_error, none, "cannot convert value of type %0 to %1", (Type, Type)) - Emit it:
ctx.Diags.diagnose(loc, diag::my_new_error, fromType, toType); - Add an
expected-errorline to a regression test undertest/Sema/.
Bridging C++ and Swift
include/swift/Bridging/ contains the FFI layer that lets Swift code in SwiftCompilerSources/ call into the C++ AST/SIL data structures. Patterns:
- C++ side defines
BridgedXxxtypes as opaque pointers + small POD structs. - Swift side wraps
BridgedXxxin safe Swift types (Function,Instruction,Type). - Public Swift API is in
SwiftCompilerSources/Sources/{AST,SIL,Optimizer}/Sources/. - Avoid leaking C++ exceptions across the bridge -- the runtime is
-fno-exceptions.
Swift side
Swift code lives in two main places: standard library (stdlib/) and Swift-implemented compiler (SwiftCompilerSources/).
Stdlib style
- See
docs/StdlibAPIGuidelines.rstanddocs/StandardLibraryProgrammersManual.md. - All public stdlib API requires Swift Evolution review.
- Internal helpers use
_prefix (e.g.,_precondition,_internalInvariant). @_alwaysEmitIntoClientis used to ship new APIs that should be inlined into clients on older runtimes; seedocs/LibraryEvolution.rst.@inlinableand@usableFromInline-- understand resilience implications before using.
Stdlib gotchas
- The stdlib is compiled with
-parse-stdlib, which means theSwiftmodule is not available;Builtinis. UseBool,Int, etc. fromBool.swift,Integers.swift.gyb, etc. - Many types use
gybtemplates (Tuple.swift.gyb,FixedPoint.swift.gyb) to expand combinatorial overloads. @frozenmeans the struct's layout is locked for ABI; adding a stored property is a binary-incompatible change._checkValidIndexand similar_calls are removed in-Ouncheckedbuilds.
SwiftCompilerSources style
- Files in
SwiftCompilerSources/Sources/are normal Swift, but they importAST,SIL,OptimizerBridgingmodules that wrap C++ types. - Errors are not exceptional -- functions return
Optionalor useprecondition. - Heavy use of
@inline(__always)and value-typed wrappers because the bridging layer is thin. - See
SwiftCompilerSources/README.mdfor build instructions.
Common cross-cutting concerns
Source compatibility
For any change that affects user code, consider:
- Is there a Swift Evolution proposal? If yes, gate behind
-enable-experimental-feature. - Does it require a new diagnostic? Add one with
// expected-warning {{...}}tests. - Does it break source? Use the language-mode flag (
-language-version 6) to gate.
ABI stability
If your change touches the runtime, the standard library's frozen API, or any mangling code, you may be breaking ABI:
- Read
docs/LibraryEvolution.rst. - Consult
Mangling.rstindocs/ABI/before changing manglers. lib/Demangling/andstdlib/public/Demangling/are mirrored -- changes must be applied in both.
Testing requirement
PRs without tests are rarely merged. Use:
test/Sema/for type checkertest/SILOptimizer/for new SIL passestest/stdlib/for standard libraryunittests/for C++ unit-level changes (e.g., aSILBuilderhelper)
See Testing for the test runners.
Localization
Diagnostics support localization via lib/Localization/. The default English text comes from the .def files; translations live in localization/. Adding a diagnostic doesn't require translating it -- the build will pick up the English fallback.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.
Previous
Debugging
Next
Tooling