Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
193 changes: 20 additions & 173 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,182 +1,29 @@
# LLGo Project AI Assistant Guide
# LLGo Agent Guide

This document provides essential information for AI assistants to help fix bugs and implement features in the LLGo project.
Automated contributors must read and follow the shared [contribution guide](CONTRIBUTING.md). It defines the development environment, testing expectations, platform validation, code quality rules, and pull request record required for every contributor.

## About LLGo
The rules below are additional safeguards for AI agents and other repository automation.

LLGo is a Go compiler based on LLVM designed to better integrate Go with the C ecosystem, including Python and JavaScript. It's a subproject of the XGo project that aims to expand the boundaries of Go/XGo for game development, AI and data science, WebAssembly, and embedded development.
## Scope and working tree safety

## Project Structure
- Keep changes within the requested scope and preserve unrelated edits, untracked files, and active worktrees.
- Inspect the complete diff against upstream before submission. Do not overwrite or discard existing work unless explicitly authorized.
- Use focused edits and tests first. Do not rewrite unrelated files, regenerate unrelated fixtures, or broaden a change merely to make validation pass.
- Diagnose baseline failures instead of hiding them with skips, exclusions, weakened checks, or undocumented environment changes.

- `cmd/llgo` - Main llgo compiler command (usage similar to `go` command)
- `cl/` - Core compiler logic that converts Go packages to LLVM IR
- `ssa/` - LLVM IR file generation using Go SSA semantics
- `internal/build/` - Build process orchestration
- `runtime/` - LLGo runtime library
- `chore/` - Development tools (llgen, llpyg, ssadump, etc.)
- `_demo/` - Example programs demonstrating C/C++ interop (`c/hello`, `c/qsort`) and Python integration (`py/callpy`, `py/numpy`)
- `_cmptest/` - Comparison tests to verify the same program gets the same output with Go and LLGo
## Repository and GitHub safety

## Development Environment
- Treat `xgo-dev/*` as upstream. Do not push branches or tags directly to an `xgo-dev` repository, and do not merge its pull requests.
- Push code to the contributor's fork, then create or update a pull request against `xgo-dev/llgo:main`. Upstream issues may be created when requested.
- Do not publish upstream releases or change upstream repository settings. Inspect remotes and exact refs before any write operation when ownership is unclear.
- Prefer `gh issue view`, `gh pr view`, and `gh pr checks` for GitHub state. Use `gh api` for review threads, inline comments, check-run details, or fields not exposed by higher-level commands; do not scrape the website.
- Use explicit force-with-lease protection when a requested rebase requires rewriting a fork branch. Stop if the remote head changed unexpectedly.

For detailed dependency requirements and installation instructions, see the [Dependencies](README.md#dependencies) and [How to install](README.md#how-to-install) sections in the README.
## Validation and reporting

## Testing & Validation

The following commands and workflows are essential when fixing bugs or implementing features in the LLGo project:

### Run all tests
```bash
go test ./...
```

**Note:** Some tests may fail if optional dependencies (like Python) are not properly configured. The test suite includes comprehensive tests for:
- Compiler functionality
- SSA generation
- C interop
- Python integration (requires Python development headers)

### Write and run tests for your changes

When adding new functionality or fixing bugs, create appropriate test cases:

```bash
# Add your test to the relevant package's *_test.go file
# Then run tests for that package
go test ./path/to/package

# Or run all tests
go test ./...
```

**Important:** The `LLGO_ROOT` environment variable must be set to the repository root when running llgo commands during development.

### Update out.ll files after modifying compiler IR generation

**CRITICAL:** When you modify the compiler's IR generation logic (especially in `ssa/` or `cl/` packages), you MUST update all out.ll test files under the `cl/` directory.

#### Understanding out.ll files

The `out.ll` files under the `cl/` directory are comparison IR files that serve as reference outputs for the test suite:
- They are generated by `llgen` from the corresponding `in.go` files in the same directory
- They reflect the current compiler's LLVM IR representation of the Go source code
- They are used by tests to verify that the compiler generates correct and consistent IR output

#### Required steps after modifying IR generation logic

1. **Reinstall the tools** to apply your compiler changes:
```bash
go install -v ./chore/gentests
go install -v ./chore/llgen
```

2. **Regenerate out.ll files**:

**For batch updates (recommended)** - Use `gentests` to regenerate all test files:
```bash
gentests
```
This will automatically regenerate all out.ll files in these directories:
- `cl/_testlibc`
- `cl/_testlibgo`
- `cl/_testrt`
- `cl/_testgo`
- `cl/_testpy`
- `cl/_testdata`

**For individual test inspection** - Use `llgen` to regenerate specific test directories:
```bash
llgen cl/_testgo/interface
llgen cl/_testrt/tpmethod
```

3. **Verify the changes** make sense by reviewing the diff in the out.ll files

4. **Commit the updated out.ll files** along with your compiler changes

#### Why this matters

This process ensures that:
- The test suite reflects the current compiler behavior
- Changes to IR generation are properly documented and reviewed
- Future regressions can be detected by comparing against the reference output

## Code Quality

Before submitting any code updates, you must run the following formatting and validation commands:

### Format code
```bash
go fmt ./...
```

**Important:** Always run `go fmt ./...` before committing code changes. This ensures consistent code formatting across the project.

### Run static analysis
```bash
go vet ./...
```

**Note:** Currently reports some issues related to lock passing by value in `ssa/type_cvt.go` and a possible unsafe.Pointer misuse in `cl/builtin_test.go`. These are known issues.


## Common Development Tasks

### Build the entire project
```bash
go build -v ./...
```

### Build llgo command specifically
```bash
go build -o llgo ./cmd/llgo
```

### Check llgo version
```bash
llgo version
```

### Install llgo for system-wide use
```bash
./install.sh
```

### Build development tools
```bash
go install -v ./cmd/...
go install -v ./chore/...
```

## Key Modules for Understanding

- `ssa` - Generates LLVM IR using Go SSA semantics
- `cl` - Core compiler converting Go to LLVM IR
- `internal/build` - Orchestrates the compilation process

## Debugging

### Disable Garbage Collection
For testing purposes, you can disable GC:
```bash
LLGO_ROOT=/path/to/llgo llgo run -tags nogc .
```

## LLGO_ROOT Environment Variable

**CRITICAL:** Always set `LLGO_ROOT` to the repository root when running llgo during development:

```bash
export LLGO_ROOT=/path/to/llgo
# or
LLGO_ROOT=/path/to/llgo llgo run .
```

## Important Notes

1. **Testing Requirement:** All bug fixes and features MUST include tests
2. **Demo Directory:** Examples in `_demo` are prefixed with `_` to prevent standard `go` command from trying to compile them
3. **Defer in Loops:** LLGo now supports `defer` within loops, matching Go's semantics of executing defers in LIFO order for every iteration. Be mindful of loop-heavy defer usage as it allocates per iteration.
4. **C Ecosystem Integration:** LLGo uses `go:linkname` directive to link external symbols through ABI
5. **Python Integration:** Third-party Python libraries require separate installation of library files
- Follow [CONTRIBUTING.md](CONTRIBUTING.md#testing-and-validation) for the affected package, nested runtime module, GOROOT cases, and target-specific validation.
- Report the exact commands and platforms exercised. Distinguish execution from build-only checks and state every omitted test with its reason; omission is not a pass.
- Do not claim repository-wide success from a focused test. When a required check cannot run locally, leave it to CI and say so explicitly.
- For generated IR, use the repository's `// LITTEST` and `chore/litgen` workflow described in the contribution guide; do not hand-edit or bulk-regenerate unrelated expectations.

`AGENTS.md` links to this file so supported agents receive the same automation-specific rules.
121 changes: 121 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Contributing to LLGo

LLGo is an LLVM-based Go compiler with C, Python, JavaScript, WebAssembly, and embedded integrations. This guide covers the repository-specific workflow for code contributors. See the [README](README.md) for installation and usage.

## Contribution workflow

- Fork the repository, create a focused branch, and open a pull request against `xgo-dev/llgo:main`.
- Keep changes scoped and avoid rewriting unrelated files. Diagnose baseline failures instead of hiding them with skips, exclusions, or weakened checks.
- Describe the behavior change, compatibility implications, tests run, platforms exercised, and any validation gaps in the pull request.
- Use an issue to discuss substantial proposals or behavior changes before investing in a large implementation.

## Project structure

- `cmd/llgo` - Main compiler command
- `cl/` - Go package to LLVM IR compilation
- `ssa/` - LLVM IR generation with Go SSA semantics
- `internal/build/` - Build orchestration
- `runtime/` - LLGo runtime library
- `chore/` - Development tools (litgen, llpyg, ssadump, etc.)
- `_demo/` - C/C++, Python, and other integration examples
- `_cmptest/` - Go/LLGo output comparison tests

## Development environment

For detailed dependency requirements and installation instructions, see the [Dependencies](README.md#dependencies) and [How to install](README.md#how-to-install) sections in the README.

CI uses LLVM 19 and pinned Go patch releases; check [`.github/workflows/llgo.yml`](.github/workflows/llgo.yml) and [`.github/workflows/goroot.yml`](.github/workflows/goroot.yml) for exact versions. Native development supports macOS and Linux; use WSL2 or Linux containers on Windows.

## Testing and validation

Behavior changes require focused regression tests; documentation-only and mechanical changes do not need artificial tests. Start with the affected package, then broaden validation:

```bash
go test ./path/to/package
go test ./...
```

The nested `runtime` Go module is not covered by root-level `go test`, `go build`, or `go vet`; run the corresponding command there when it is affected, for example `(cd runtime && go test ./...)`.

Install the [documented dependencies](README.md#dependencies), including development libraries for Python and other integrations. If one is unavailable, report the exact omitted tests and reason; omission is not a pass.

Prefer the development wrapper for LLGo execution tests; it builds the current checkout and selects its runtime tree:

```bash
./dev/llgo.sh test ./path/to/package
```

After focused tests pass, `./dev/local_ci.sh` runs the main local checks when dependencies are available. See [`dev/README.md`](dev/README.md) for details.

### Coverage

- The Codecov patch check must pass; new deterministic logic and error paths should normally be covered.
- From the module containing the target package, check focused coverage with `go test -coverprofile=coverage.out ./path/to/package` and `go tool cover -func=coverage.out`.
- Linux and macOS coverage is combined; validate host-specific changes on the matching host when possible.
- [`.github/codecov.yml`](.github/codecov.yml) lists paths excluded from coverage. Add an exclusion only for generated, tooling, fixture, or otherwise non-meaningful code; never exclude production logic merely to make a PR pass, and explain every ignore change in the PR.

### Update IR test expectations

When `ssa/` or `cl/` changes generated IR, refresh only the affected expectations and review every generated diff:

```bash
go run ./chore/litgen path/to/LITTEST/in.go
```

Do not regenerate unrelated output. Supported scopes and the marker format are documented in [`dev/README.md`](dev/README.md#6-refresh-ir-checks).

### Compatibility and target validation

- Go compatibility covers source and observable behavior, not gc's internal ABI. Run standard-library tests with both `go test ./test/std/...` and `./dev/llgo.sh test ./test/std/...`.
- Run official Go cases with `bash ./dev/test_goroot.sh -- -directive-mode ci`; see [`test/goroot/README.md`](test/goroot/README.md) for filtering, multiple toolchains, full coverage, and sharding.
- Run native tests on the matching host. Use `dev/docker.sh` for Linux amd64/arm64 validation, `dev/test_wasm.sh` for Wasm, and `dev/test_embed.sh` for embedded build plus emulator smoke.
- Cross-compilation is not execution validation. Do not weaken failures to make a change pass, and state any target that could not be run.
- Changes to runtime ABI, archive/link metadata, target selection, or generated IR need focused multi-target tests. Use `// LITTEST` checks where IR shape matters and describe compatibility implications in the pull request.

The host matrix, CI coverage, dependencies, and target-specific follow-up commands are in [`dev/README.md`](dev/README.md#platform-and-target-validation).

### Performance, size, and validation record

- For compiler, runtime, linker, ABI, or hot-path changes, run focused benchmarks and inspect the paired Linux/macOS results. Repeat material differences because small changes may be runner noise. See [`benchmark/baseline/README.md`](benchmark/baseline/README.md).
- For changes that may affect binary layout or size, use `llgo build -size` as described in [`doc/size-report.md`](doc/size-report.md).
- In the pull request, record commands and targets, distinguish execution from build-only checks, and identify gaps. Required Linux/macOS checks must pass; a `continue-on-error` lane is not authoritative.

## Code quality

### Format code

```bash
gofmt -w path/to/changed.go
```

Format every changed Go file before committing, but do not rewrite unrelated files.

For changed shell scripts, run `bash -n path/to/changed.sh` and `shellcheck path/to/changed.sh` when ShellCheck is available.

### Run static analysis

Run `go vet ./path/to/package` for affected packages. Repository-wide vet currently reports lock-copy diagnostics in `ssa/type_cvt.go` and possible `unsafe.Pointer` misuse in `cl/builtin_test.go`; do not claim a clean run, suppress new diagnostics, or silently expand this baseline.

## Common development tasks

Use `./dev/llgo.sh version` to build the current checkout with the development configuration and check the resulting command. Installation and tool-building commands are maintained in the [README](README.md#how-to-install).

## Debugging

### Disable garbage collection

The `nogc` build tag is a targeted diagnostic mode that changes runtime semantics; it does not replace validation with the default GC configuration:

```bash
./dev/llgo.sh run -tags nogc .
```

See [Garbage Collection](README.md#garbage-collection-gc) and [`doc/defer-tls-gc.md`](doc/defer-tls-gc.md) for the supported modes and runtime design.

### `LLGO_ROOT`

Do not set `LLGO_ROOT` unconditionally. Development wrappers derive it for the current checkout, and an installed `llgo` does not necessarily require it. Set it explicitly only to select a non-standard source/runtime tree.

## Important notes

Examples live under `_demo/`, whose underscore keeps ordinary `go` package discovery from including them. C and C++ integration uses LLGo directives and target ABIs, including `go:linkname` where appropriate; follow [`doc/How-to-support-a-C&C++-Library.md`](doc/How-to-support-a-C&C++-Library.md) instead of assuming every binding uses the same mechanism.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ llgo - A Go compiler based on LLVM

LLGo is a Go compiler based on LLVM in order to better integrate Go with the C ecosystem including Python and JavaScript. It's a subproject of [the XGo project](https://github.com/goplus/gop).

See [CONTRIBUTING.md](CONTRIBUTING.md) for the development, testing, and pull request workflow.

LLGo aims to expand the boundaries of Go/XGo, providing limitless possibilities such as:

* Game development
Expand Down Expand Up @@ -422,8 +424,6 @@ cd llgo
* [pydump](_xtool/pydump): It's the first program compiled by `llgo` (NOT `go`) in a production environment. It outputs symbol information (functions, variables, and constants) from a Python library in JSON format, preparing for the generation of corresponding packages in `llgo`.
* [pysigfetch](https://github.com/goplus/hdq/tree/main/chore/pysigfetch): It generates symbol information by extracting information from Python's documentation site. This tool is not part of the `llgo` project, but we depend on it.
* [llpyg](chore/llpyg): It is used to automatically convert Python libraries into Go packages that `llgo` can import. It depends on `pydump` and `pysigfetch` to accomplish the task.
* [llgen](chore/llgen): It is used to compile Go packages into LLVM IR files (*.ll).
* [gentests](chore/gentests): It refreshes the built-in golden test data under `cl/_test*`, including `out.ll` and `expect.txt`. Directories that use source-embedded `// LITTEST` checks are skipped for `out.ll` regeneration.
* [litgen](chore/litgen): It generates and refreshes source-embedded `// LITTEST` FileCheck directives from the current LLVM IR for marked Go source files.
* [ssadump](chore/ssadump): It is a Go SSA builder and interpreter.

Expand Down
Loading
Loading