Factory.ai

Open-Source Wikis

/

Swift

/

How to contribute

/

Patterns and conventions

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-format is enforced. Run utils/git-clang-format-all.zsh before sending a PR.
  • 2-space indentation, no tabs.
  • Public types in include/swift/<Subsystem>/, implementation in lib/<Subsystem>/.
  • Headers use #pragma once + namespace swift.

Idioms

  • StringRef and ArrayRef everywhere -- avoid passing std::string or std::vector by value.
  • Pointer-likeness -- Decl *, Type (a small wrapper around a pointer), SILValue are 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 provides classof() for these.
  • Source locations -- pass SourceLoc and SourceRange from swift::SourceManager. They're 4-byte tokens, not strings.
  • Diagnostics -- never print directly. Use Context.Diags.diagnose(loc, diag::id, args...). Diagnostic IDs live in include/swift/AST/Diagnostics*.def.

Diagnostics

Adding a diagnostic looks like:

  1. Add an entry to include/swift/AST/DiagnosticsSema.def (or DiagnosticsParse.def, DiagnosticsSIL.def, etc.):
    ERROR(my_new_error, none, "cannot convert value of type %0 to %1", (Type, Type))
  2. Emit it: ctx.Diags.diagnose(loc, diag::my_new_error, fromType, toType);
  3. Add an expected-error line to a regression test under test/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 BridgedXxx types as opaque pointers + small POD structs.
  • Swift side wraps BridgedXxx in 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

Stdlib gotchas

  • The stdlib is compiled with -parse-stdlib, which means the Swift module is not available; Builtin is. Use Bool, Int, etc. from Bool.swift, Integers.swift.gyb, etc.
  • Many types use gyb templates (Tuple.swift.gyb, FixedPoint.swift.gyb) to expand combinatorial overloads.
  • @frozen means the struct's layout is locked for ABI; adding a stored property is a binary-incompatible change.
  • _checkValidIndex and similar _ calls are removed in -Ounchecked builds.

SwiftCompilerSources style

  • Files in SwiftCompilerSources/Sources/ are normal Swift, but they import AST, SIL, OptimizerBridging modules that wrap C++ types.
  • Errors are not exceptional -- functions return Optional or use precondition.
  • Heavy use of @inline(__always) and value-typed wrappers because the bridging layer is thin.
  • See SwiftCompilerSources/README.md for 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.rst in docs/ABI/ before changing manglers.
  • lib/Demangling/ and stdlib/public/Demangling/ are mirrored -- changes must be applied in both.

Testing requirement

PRs without tests are rarely merged. Use:

  • test/Sema/ for type checker
  • test/SILOptimizer/ for new SIL passes
  • test/stdlib/ for standard library
  • unittests/ for C++ unit-level changes (e.g., a SILBuilder helper)

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.

Patterns and conventions – Swift wiki | Factory