Skip to content
cccskills
FreePublished on GitHubEnglish overview

Toolchain development

Use this skill to navigate and work on the Carbon compiler toolchain. It explains the compiler phases, code organization, build and test commands, debugging practices, and implementation conventions so you can make and investigate changes consistently.

OriginalShow the original description

Instructions for checking, building, debugging, and understanding the Carbon toolchain.

carbon-language/carbon-lang33,929 stars(GitHub 33,929 + cccskills 0)

Run score Not tested

See how to install

Good for

  • Finding where a toolchain phase is implemented
  • Building or testing the Carbon toolchain
  • Debugging compiler behavior or crashes
  • Updating expected test outputs after a change

Overview

What it does

This skill explains how Carbon’s compiler toolchain is organized and how its processing flows through lexing, parsing, semantic checking, and lowering to LLVM IR. It points to the relevant directories, definition files, and handlers, and describes conventions for making changes. It also covers building and testing with bazelisk, debugging failures, handling diagnostics and errors, and updating expected test output with the provided script.

When it helps

Use it when you are starting work on the Carbon toolchain or need to locate an existing implementation and understand which phase handles it. It can guide you through running tests, investigating a crash, and following the project’s approach to LLVM APIs and existing data structures. It also identifies areas such as the language server and builtin functions that have separate guidance.

Example requests

  • “Find which toolchain phase implements this parsing behavior.”
  • “Run the compiler tests for my change and update the expected output.”
  • “Show me how to investigate the cause of this crash.”

Notes

These guidelines are for Carbon’s toolchain. Use bazelisk for builds and tests, and ./toolchain/autoupdate_testdata.py to update test output. The skill directs work on the language server, diagnostics, and builtin functions to separate skills.

This overview was written by AI (OpenAI Codex) from the public SKILL.md. Check the original below for the exact behavior.

Document check

AI checked the SKILL.md for operations that need care and for setup requirements. The score comes only from actually running the skill (hands-on test).

SafetyAre sending data, deleting files, and running commands disclosed?
AGoodThe listed work covers building, testing, and investigation, not history rewrites or sending.
Easy setupDoes it need few tools or API keys, and are they documented?
BPartly lackingIt names `bazelisk` for builds and tests but gives no installation steps.

Not counted in the score. Rated by AI (OpenAI Codex) as of Oct 26, 2026. Treat it as a guide and read the original before installing.

Disagree? Request a re-evaluation

Tell us which point is wrong and why. No login needed. We will check it against the SKILL.md, redo the evaluation, and show the result here.

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

Files included (1)

  • SKILL.md7.6 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Toolchain development

<!-- Part of the Carbon Language project, under the Apache License v2.0 with LLVM Exceptions. See /LICENSE for license information. SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -->

Toolchain structure

  • Under toolchain/:
    • base/: Base infrastructure and common utilities.
    • check/: Semantic analysis (SemIR generation).
    • lex/: Lexing (Source -> Tokens).
    • lower/: Lowering to LLVM IR.
    • parse/: Parsing (Token -> Parse Tree).
    • sem_ir/: Semantic Intermediate Representation (SemIR) definitions.

Toolchain architecture

  • Documentation: Refer to toolchain/docs for detailed architecture design and patterns.
    • Refer to Toolchain Idioms for a comprehensive list of patterns (for example, ValueStore, formatting .def files, struct reflection) used throughout the implementation.
  • Builtin Functions: Refer to the Builtin functions skill (SKILL.md) for guidelines on registering, mapping, constant evaluating, and lowering compiler builtin primitives (e.g. "int.convert_float").
  • Language server: Refer to the Language server skill (SKILL.md) before working on toolchain/language_server/ or utils/vscode/. Neither follows the patterns described here.
  • Phases: Lex -> Parse -> Check -> Lower.
  • Definitions: Many kinds (tokens, parse nodes, SemIR instructions) are defined in .def files and expanded by way of macros.
  • Handlers:
    • Parser: Handle<StateName> in parse/handle_*.cpp.
    • Checker: HandleParseNode in check/handle_*.cpp.
    • Lowering: HandleInst in lower/handle_*.cpp.
  • Iteration: Prefer iterative algorithms over recursive ones to prevent stack exhaustion on complex codebases.

Essential commands

  • Test everything: bazelisk test //...
  • Test specific target: bazelisk test //toolchain/testing:file_test
  • Test specific file: bazelisk test //toolchain/testing:file_test --test_arg=--file_tests=<path_to_carbon_file>
  • Build toolchain: bazelisk build //toolchain/...

Updating test data

Carbon tests often use file_test (for example, //toolchain/testing/file_test). For detailed guidelines on authoring tests, including file splits, naming conventions (fail_, todo_), and generating minimal output with SemIR dumps, please refer to the Toolchain tests skill.

If you change compiler behavior, you likely need to update expected test outputs. Do not manually edit thousands of lines of expected output. Use the script:

./toolchain/autoupdate_testdata.py
# Or for a specific file:
./toolchain/autoupdate_testdata.py toolchain/check/testdata/my_test.carbon

Debugging and diagnostics

  • Compiler Diagnostics: Refer to the Diagnostics skill (SKILL.md) for strict rules on declaring, formatting, emitting, testing, and styling compiler diagnostic messages (errors, warnings, notes).
  • Printing to stderr: Use llvm::errs() << "debug info\n";.
    • Avoid std::cout (it may interfere with tool output).
  • SemIR Stringification:
    • SemIR objects often have a Print method or operator<<.
    • inst.Print(llvm::errs())
  • Debugging Crashes:
    • Bazel sandboxing can hide artifacts. Use --sandbox_debug if needed, but often running the binary directly from bazel-bin/ is easier for debugging.

Error handling

  • No exceptions: Do not use C++ exceptions.
  • ErrorOr<T>: Return ErrorOr<T> for fallible operations.
    • Check with if (auto result = Function(); result) { Use(*result); }
  • llvm::Expected<T>: Similar to ErrorOr, used when interfacing with LLVM.

Context-Aware Diagnostics

When declaring and emitting errors, ensure semantic wording matches the exact context:

  • Semantic Precision: Do not reference "types" when raising errors for unsized expressions like IntLiteral or FloatLiteral. For example, use RealLiteralTooLargeForUnsizedInt instead of a diagnostic referencing an "integer type".
  • Wording Consistency: Before declaring a new diagnostic in kind.def, search for existing diagnostics in the targeted implementation files (for example, other uses of MaxIntWidth) to align message structures and parameter expectations.

Casting (LLVM style)

  • Use llvm::cast<T>(obj) (checked, asserts on failure).
  • Use llvm::dyn_cast<T>(obj) (returns null on failure).
  • Use llvm::isa<T>(obj) (boolean check).
  • Avoid dynamic_cast and standard RTTI.

Leverage LLVM APIs

Before implementing custom algorithms for mathematical, logical, or bitwise operations, inspect target LLVM ADT class APIs:

  • Builtin APIs: Verify if LLVM classes (such as APInt, APFloat, or APSInt) already offer native equivalents (for example, .pow(), ilogb(), .changeSign(), convertFromAPInt()). Avoid duplicate, naive, or inefficient custom loops.

Data structures

  • Prefer APIs in common/ and toolchain/base/ over LLVM ADTs. For example, use Map instead of llvm::DenseMap.
  • If no Carbon API exists, prefer LLVM ADTs over standard library ones (for example llvm::SmallVector, llvm::StringRef).
  • StringRef is a view; be careful with lifetimes.

Common pitfalls

  1. Legacy explorer references: The explorer prototype has been moved. Ignore references to it in proposals or old docs; focus on toolchain.
  2. Manually updating test files: Always check if autoupdate_testdata.py can do it for you.
  3. Using std::string unnecessarily: Prefer llvm::StringRef for arguments.
  4. Header includes: Use specific include orders (often enforced by clang-format).
  5. Parse node order: Semantics processes parse nodes in post-order; ensure your parser transitions support this.
  6. Builtin implementation gaps: If adding a primitive builtin function, make sure you address all phases of the lifecycle: macro definition registration, signature validation, compile-time constant evaluation (interpreter), LLVM IR lowering, and prelude modular implementation bindings (avoiding orphan rules). Refer to the Builtin functions skill (SKILL.md) for details.
  7. Premature helper abstraction: Avoid extracting tiny helper functions that are called from exactly one place and do not significantly modularize complex code. Prefer inlining directly to keep the implementation compact, readable, and localized.
  8. Redundant bounds calculations: Avoid repeating calculations of complex boundary estimations (such as lower and upper bound estimations). Refactor the logic to calculate unified values once, preserving compactness.
  9. Trusting stale clangd diagnostics: In-editor diagnostics are only as good as compile_commands.json. If it predates a newly added file, clangd falls back to a default command and reports nonsense, such as missing standard headers or "no member named None". Regenerate it with ./scripts/create_compdb.py, which only takes a few seconds.

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Use this skill to read GitHub issue details and comments from the command line with `gh`. It covers issues referenced by number or URL, including issues in other repositories, and keeps access read-only so issue state is not changed.

  • Reading an issue and its full comment history
  • Opening an issue referenced by URL
  • Viewing an issue from another repository
carbon-language/carbon-lang33.9KUpdated Oct 26, 2026

Agent tools

FreeSummary

Use this skill to guide an AI assistant working in the Carbon repository on viewing, searching, and editing files with specialized environment tools. It also sets rules for temporary files and when custom programs may be used.

  • Choosing approved tools to view, search, or edit files
  • Checking where temporary analysis and test files belong
  • Deciding when a custom transformation program is allowed
carbon-language/carbon-lang33.9KUpdated Oct 26, 2026

Bazel usage

FreeSummary

Follow the Carbon project's Bazel workflow through Bazelisk, a version-managing launcher. Learn commands for building targets, running tests and binaries, enabling AddressSanitizer, and refreshing cached state after system dependency changes.

  • Building a Carbon target
  • Running focused project tests
  • Launching a Bazel-built binary
carbon-language/carbon-lang33.9KUpdated Oct 26, 2026

Use this skill to implement builtin functions in the Carbon compiler, from registering a function name and checking its signature to evaluating constant calls and generating LLVM IR for runtime calls. It also covers prelude bindings and focused tests.

  • Registering a new Carbon builtin function
  • Adding compile-time evaluation behavior
  • Lowering runtime builtins to LLVM IR
carbon-language/carbon-lang33.9KUpdated Oct 26, 2026

Code style

FreeSummary

Apply Carbon toolchain conventions for formatting Bazel, C++, Carbon, Markdown, and Python files. The skill also covers clear comments and documentation, accurate names, design choices, and concise commit descriptions.

  • Formatting a changed source file
  • Writing or revising code comments
  • Choosing names that match their meaning
carbon-language/carbon-lang33.9KUpdated Oct 26, 2026

Diagnostics

FreeSummary

Use this skill to add or revise diagnostics in the Carbon toolchain. It explains how to register message kinds, format typed arguments, attach source labels and context, and verify that diagnostics follow the project’s wording and test coverage rules.

  • Adding an error or warning to the Carbon compiler
  • Attaching source locations and explanatory labels
  • Checking diagnostic wording and formatting conventions
carbon-language/carbon-lang33.9KUpdated Oct 26, 2026

See all skills by carbon-language

Report a problem with this skill