diff --git a/.agents/skills/code_style/SKILL.md b/.agents/skills/code_style/SKILL.md new file mode 100644 index 000000000000..0c36ba7505c8 --- /dev/null +++ b/.agents/skills/code_style/SKILL.md @@ -0,0 +1,38 @@ +--- +name: Code style +description: + Instructions for code formatting and style guidelines in the Carbon + toolchain. +--- + +# Code style + + + +## License + +- **Licenses**: All Carbon files outside of `third_party/` should have a + license following + [CONTRIBUTING license instructions](/CONTRIBUTING.md#license). + +## Formatting + +- **C++**: Always check `clang-format` on C++ files. +- **Carbon**: The toolchain's `format` command doesn't work well right now. + Instead, try to format Carbon code based on other Carbon files and the C++ + style. +- **Markdown**: Use `pre-commit run prettier --files ` to format + markdown files correctly. + +## Style Guides + +Carbon's toolchain uses LLVM-style C++ with some specific conventions. + +- **Style Guide**: Follow the + [Carbon C++ Project Style Guide](/docs/project/cpp_style_guide.md). +- **Markdown style**: Follow the + [Google developer documentation style guide](https://developers.google.com/style). diff --git a/.agents/skills/toolchain_development/SKILL.md b/.agents/skills/toolchain_development/SKILL.md new file mode 100644 index 000000000000..91d06e1c7869 --- /dev/null +++ b/.agents/skills/toolchain_development/SKILL.md @@ -0,0 +1,130 @@ +--- +name: Toolchain development +description: + Instructions for checking, building, debugging, and understanding the Carbon + toolchain. +--- + +# Toolchain development + + + +## Toolchain structure + +- Under [`toolchain/`](/toolchain/): + - [`base/`](/toolchain/base/): Base infrastructure and common utilities. + - [`check/`](/toolchain/check/): Semantic analysis (SemIR generation). + - [`lex/`](/toolchain/lex/): Lexing (Source -> Tokens). + - [`lower/`](/toolchain/lower/): Lowering to LLVM IR. + - [`parse/`](/toolchain/parse/): Parsing (Token -> Parse Tree). + - [`sem_ir/`](/toolchain/sem_ir/): Semantic Intermediate Representation + (SemIR) definitions. + +## Toolchain architecture + +- **Documentation**: Refer to [`toolchain/docs`](/toolchain/docs) for detailed + architecture design and patterns. + - Refer to [Toolchain Idioms](/toolchain/docs/idioms.md) for a + comprehensive list of patterns (for example, `ValueStore`, formatting + `.def` files, struct reflection) used throughout the implementation. +- **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` 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. + +## Building and testing + +AI assistants should use `bazelisk` instead of `bazel` for build and test +commands, because some AI editors won't see `bazel` aliases. + +### 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=` +- **Build toolchain**: `bazelisk build //toolchain/...` + +### Updating test data + +Carbon tests often use `file_test` (for example, +`//toolchain/testing/file_test`). 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: + +```bash +./toolchain/autoupdate_testdata.py +# Or for a specific file: +./toolchain/autoupdate_testdata.py toolchain/check/testdata/my_test.carbon +``` + +### Pre-commit + +Running `pre-commit` is mandatory. To run it on all files: + +```bash +pre-commit run -a +``` + +To validate a specific list of files: + +```bash +pre-commit run --files +``` + +## Debugging and diagnostics + +- **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`**: Return `ErrorOr` for fallible operations. + - Check with `if (auto result = Function(); result) { Use(*result); }` +- **`llvm::Expected`**: Similar to `ErrorOr`, used when interfacing with + LLVM. + +### Casting (LLVM style) + +- Use `llvm::cast(obj)` (checked, asserts on failure). +- Use `llvm::dyn_cast(obj)` (returns null on failure). +- Use `llvm::isa(obj)` (boolean check). +- **Avoid** `dynamic_cast` and standard RTTI. + +### 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. diff --git a/GEMINI.md b/GEMINI.md index 5aaf6d6cb8b8..a522e07eebf2 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -14,11 +14,7 @@ assistant, **read this first** to avoid common pitfalls. - [General instructions](#general-instructions) - [Project structure](#project-structure) -- [Toolchain architecture](#toolchain-architecture) -- [Building and testing](#building-and-testing) -- [Debugging and diagnostics](#debugging-and-diagnostics) -- [C++ coding patterns](#c-coding-patterns) -- [Common pitfalls](#common-pitfalls) +- [Toolchain development](#toolchain-development) ## General instructions @@ -38,133 +34,13 @@ assistant, **read this first** to avoid common pitfalls. - **[`testing/`](testing/)**: Testing utilities and infrastructure. - **[`toolchain/`](toolchain/)**: The C++ implementation of the compiler (Toolchain). - - [`base/`](toolchain/base/): Base infrastructure and common utilities. - - [`check/`](toolchain/check/): Semantic analysis (SemIR generation). - - [`lex/`](toolchain/lex/): Lexing (Source -> Tokens). - - [`lower/`](toolchain/lower/): Lowering to LLVM IR. - - [`parse/`](toolchain/parse/): Parsing (Token -> Parse Tree). - - [`sem_ir/`](toolchain/sem_ir/): Semantic Intermediate Representation - (SemIR) definitions. -## Toolchain architecture +## Code style -- **Documentation**: Refer to [`toolchain/docs`](toolchain/docs) for detailed - architecture design and patterns. - - Refer to [Toolchain Idioms](toolchain/docs/idioms.md) for a - comprehensive list of patterns (for example, `ValueStore`, formatting - `.def` files, struct reflection) used throughout the implementation. -- **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` 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. +See the "Code style" skill for instructions on formatting, style guides, and +code conventions to follow. -## Building and testing +## Toolchain development -AI assistants should use `bazelisk` instead of `bazel` for build and test -commands, because some AI editors won't see `bazel` aliases. - -### 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=` -- **Build toolchain**: `bazelisk build //toolchain/...` - -### Updating test data - -Carbon tests often use `file_test` (for example, -`//toolchain/testing/file_test`). 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: - -```bash -./toolchain/autoupdate_testdata.py -# Or for a specific file: -./toolchain/autoupdate_testdata.py toolchain/check/testdata/my_test.carbon -``` - -### Pre-commit - -Running `pre-commit` is mandatory. To run it on all files: - -```bash -pre-commit run -a -``` - -To validate a specific list of files: - -```bash -pre-commit run --files -``` - -### Formatting - -- **C++**: Always check `clang-format` on C++ files. -- **Carbon**: The toolchain's `format` command doesn't work well right now. - Instead, try to format Carbon code based on other Carbon files and the C++ - style. -- **Markdown**: Use `pre-commit run prettier --files ` to format - markdown files correctly. - -## Debugging and diagnostics - -- **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. - -## C++ coding patterns - -Carbon's toolchain uses LLVM-style C++ with some specific conventions. - -- **Style Guide**: Follow the - [Carbon C++ Project Style Guide](docs/project/cpp_style_guide.md). -- **Markdown style**: Follow the - [Google developer documentation style guide](https://developers.google.com/style). - -### Error handling - -- **No exceptions**: Do not use C++ exceptions. -- **`ErrorOr`**: Return `ErrorOr` for fallible operations. - - Check with `if (auto result = Function(); result) { Use(*result); }` -- **`llvm::Expected`**: Similar to `ErrorOr`, used when interfacing with - LLVM. - -### Casting (LLVM style) - -- Use `llvm::cast(obj)` (checked, asserts on failure). -- Use `llvm::dyn_cast(obj)` (returns null on failure). -- Use `llvm::isa(obj)` (boolean check). -- **Avoid** `dynamic_cast` and standard RTTI. - -### 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. +See the "Toolchain Development" skill for instructions on architecture, +building, testing, debugging, C++ patterns, and common pitfalls.