# 機能設計書 5-Cコード生成

## 概要

本ドキュメントは、NimコンパイラのCコード生成バックエンドの機能設計について記載する。Cコード生成は型付きASTをC言語のソースコードに変換する。

### 本機能の処理概要

Cコード生成バックエンドは、セマンティック解析で型付けされたASTを入力として受け取り、等価なCまたはC++のソースコードを生成する。生成されたCコードは外部Cコンパイラ（GCC、Clang、MSVC等）によってネイティブコードにコンパイルされる。

**業務上の目的・背景**：NimはCへのトランスパイラとして設計されており、既存のCコンパイラインフラを活用することで、高い移植性と最適化されたネイティブコードを生成する。Cコードを中間表現として使用することで、多様なプラットフォームのサポートが可能になる。

**機能の利用シーン**：
- Nimソースコードからネイティブ実行ファイルを生成（`nim c`、`nim compile`）
- C++コードの生成（`nim cpp`）
- Objective-Cコードの生成（`nim objc`）
- 共有ライブラリ（DLL/SO）の生成
- 静的ライブラリの生成

**主要な処理内容**：
1. BModule/BProcの初期化（モジュール/プロシージャ単位の状態管理）
2. 型のCコード表現生成（getTypeDesc）
3. 式のコード生成（genExpr）
4. 文のコード生成（genStmts）
5. プロシージャ定義の生成（genProc）
6. オブジェクト初期化コードの生成
7. ガベージコレクション関連コードの生成
8. ランタイムライブラリとの連携コード生成

**関連システム・外部連携**：
- セマンティック解析（sem.nim）から型付きASTを受け取る
- 外部Cコンパイラ（extccomp.nim）との連携
- ランタイムライブラリ（lib/system.nim等）との連携
- ホットコードリロード（HCR）対応

**権限による制御**：コード生成自体には権限制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| N/A | コマンドラインインターフェース | 参照画面 | コンパイルエラー、nimcacheパス表示 |

## 機能種別

コード変換処理 / コード生成処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| g | BModuleList | Yes | モジュールリスト | 非nil |
| module | PSym | Yes | モジュールシンボル | 非nil |
| n | PNode | Yes | 型付きASTノード | 非nil |
| conf | ConfigRef | Yes | コンパイラ設定 | 非nil |

### 入力データソース

- 型付きAST（PNode）
- 型情報（PType）
- シンボル情報（PSym）
- コンパイラ設定（ConfigRef）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Cソースファイル | File | 生成されたCコード（.c/.cpp/.m） |
| Cヘッダファイル | File | 型定義等のヘッダ（必要に応じて） |
| nimcache | Directory | 中間ファイル格納ディレクトリ |

### 出力先

- nimcacheディレクトリ（デフォルト: `~/.cache/nim/`または`nimcache/`）
- Cソースファイル（`{module}_@m.c`形式）

## 処理フロー

### 処理シーケンス

```
1. BModuleの作成（newModule）
   └─ モジュール単位の状態初期化
2. 型定義の生成（ccgtypes.nim）
   └─ getTypeDesc: Nim型→C型文字列変換
3. プロシージャ処理（genProc）
   ├─ BProcの作成
   ├─ パラメータ処理
   └─ 本体コード生成
4. 式のコード生成（ccgexprs.nim）
   ├─ リテラル生成
   ├─ 変数アクセス
   └─ 演算子/関数呼び出し
5. 文のコード生成（ccgstmts.nim）
   ├─ 代入文
   ├─ 制御構造
   └─ 例外処理
6. モジュール出力（cgenWriteModules）
   └─ Cファイルの書き出し
```

### フローチャート

```mermaid
flowchart TD
    A[newModule: BModule作成] --> B[型定義生成]
    B --> C[genProc: プロシージャ生成]
    C --> D{ノード種別}
    D -->|式| E[genExpr]
    D -->|文| F[genStmts]
    D -->|リテラル| G[genLiteral]
    E --> H[TLoc: 位置情報]
    F --> H
    G --> H
    H --> I[Rope: コード断片]
    I --> J[cgenWriteModules]
    J --> K[Cソースファイル出力]
    K --> L[extccomp: Cコンパイラ呼び出し]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 名前マングリング | Nimの識別子をC互換の名前に変換 | 全ての識別子 |
| BR-02 | 型マッピング | Nim型をC型にマッピング | 型変換時 |
| BR-03 | GC連携 | GC対象オブジェクトに追跡コード挿入 | refタイプ使用時 |
| BR-04 | C++モード | sfCompileToCppフラグでC++コード生成 | --cpp指定時 |
| BR-05 | 行ディレクティブ | #lineディレクティブでデバッグ情報追加 | optLineDirオプション時 |

### 計算ロジック

- **名前マングリング**: モジュール名 + 識別子名 + 型シグネチャのハッシュ
- **型サイズ計算**: ターゲットプラットフォームのサイズに基づく

## データベース操作仕様

該当なし（Cコード生成はデータベースを使用しない）

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| N/A | N/A | N/A | データベース操作なし |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| errGenerated | 内部エラー | コード生成で予期しない状態 | バグ報告 |
| errCannotOpenFile | ファイルエラー | 出力ファイルが書き込み不可 | パーミッション確認 |

### リトライ仕様

コード生成はリトライを行わない。

## トランザクション仕様

該当なし

## パフォーマンス要件

- Rope（連結文字列）による効率的な文字列構築
- 増分コンパイル対応（シンボルファイル使用時）
- 並列Cコンパイル対応（外部コンパイラ呼び出し時）

## セキュリティ考慮事項

- 生成コードのバッファオーバーフロー対策
- 境界チェックコードの生成（オプション）

## 備考

- cgenモジュールは複数のincludeファイルで構成される
  - ccgtypes.nim: 型のコード生成
  - ccgexprs.nim: 式のコード生成
  - ccgstmts.nim: 文のコード生成
  - ccgliterals.nim: リテラルのコード生成
- TinyCC対応（オプション）
- ホットコードリロード（HCR）対応

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、コード生成で使用されるデータ構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | cgendata.nim | `compiler/cgendata.nim` | BModule、BProc、TLoc型の定義を理解 |

**読解のコツ**:
- `BModule`はモジュール単位のコード生成状態を保持
- `BProc`はプロシージャ単位の状態を保持
- `TLoc`は変数/式の位置情報（メモリ位置、C言語での表現）を保持
- `TLocKind`で位置の種類（locNone、locTemp、locLocalVar等）を表現
- `TStorageLoc`でストレージの種類（OnStack、OnHeap等）を表現

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | cgen.nim | `compiler/cgen.nim` | newModule（63行目）でモジュール初期化を理解 |
| 2-2 | cgen.nim | `compiler/cgen.nim` | genProc（354行目）でプロシージャ生成の概要を理解 |

**主要処理フロー**:
- `newModule`でBModuleを作成し、モジュール毎のコード生成状態を初期化
- `genProc`でプロシージャのCコード生成を開始

#### Step 3: 位置情報（TLoc）を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | cgen.nim | `compiler/cgen.nim` | initLoc（83-85行目）で位置初期化を理解 |
| 3-2 | cgen.nim | `compiler/cgen.nim` | fillLoc（87-100行目）で位置設定を理解 |
| 3-3 | cgen.nim | `compiler/cgen.nim` | rdLoc（371-376行目）で位置読み取りを理解 |

**主要処理フロー**:
- **83-85行目**: `initLoc`でTLocを初期化（種類、ストレージ、フラグ）
- **87-93行目**: `fillLoc`で未初期化の位置を設定
- **371-376行目**: `rdLoc`で間接参照を考慮した位置読み取り

#### Step 4: ropecgマクロを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | cgen.nim | `compiler/cgen.nim` | ropecg（155-243行目）でコード生成マクロを理解 |

**主要処理フロー**:
- `ropecg`マクロはフォーマット文字列を解析してRope構築コードを生成
- `$#`で引数を順番に埋め込み、`$1`〜`$9`で特定の引数を指定
- `#name`でcgsymValueを呼び出してシンボルを参照

#### Step 5: 型のコード生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | ccgtypes.nim | `compiler/ccgtypes.nim` | getTypeDesc関数で型のC表現生成を理解 |

**主要処理フロー**:
- Nim型からC型文字列（`NI`、`NF`、`NU8`等）への変換
- オブジェクト型、タプル型、配列型の構造体生成
- proc型のC関数ポインタ表現

#### Step 6: 式のコード生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 6-1 | ccgexprs.nim | `compiler/ccgexprs.nim` | genExpr関数で式のコード生成を理解 |

**主要処理フロー**:
- ノード種別に応じた式のC表現生成
- 演算子のインライン展開
- 関数呼び出しの生成

#### Step 7: 文のコード生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 7-1 | ccgstmts.nim | `compiler/ccgstmts.nim` | genStmts関数で文のコード生成を理解 |

**主要処理フロー**:
- 代入文、制御構造、ループのC表現生成
- 例外処理のsetjmp/longjmpベースの実装

#### Step 8: オブジェクト初期化を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 8-1 | cgen.nim | `compiler/cgen.nim` | genObjectInit（459-508行目）でオブジェクト初期化を理解 |

**主要処理フロー**:
- **462行目**: `analyseObjectWithTypeField`で型フィールドの有無を判定
- **474-476行目**: `m_type`フィールドに型情報を設定
- **500-508行目**: 例外型の`name`フィールドを設定

### プログラム呼び出し階層図

```
newModule
    └─ BModule初期化

genProc (プロシージャ生成)
    │
    ├─ BProc作成
    │
    ├─ genParams (パラメータ処理)
    │
    └─ genStmts (本体生成)
           │
           ├─ genStmt (個別文)
           │      ├─ genAsgn (代入)
           │      ├─ genIf (if文)
           │      ├─ genWhile (while文)
           │      ├─ genFor (for文)
           │      └─ genTry (try文)
           │
           └─ genExpr (式生成)
                  ├─ genLiteral (リテラル)
                  ├─ genSym (シンボル)
                  ├─ genCall (呼び出し)
                  └─ genOp (演算)

cgenWriteModules
    └─ 各モジュールのCファイル出力
           ├─ 型定義セクション
           ├─ 変数定義セクション
           ├─ プロシージャセクション
           └─ 初期化セクション
```

### データフロー図

```
[入力]                          [処理]                              [出力]

型付きAST ────────────────────▶ genProc/genStmts ────────────────▶ BProc.s (コード断片)
(PNode)                          (コード生成)
       │
       ▼
型情報 ───────────────────────▶ getTypeDesc ─────────────────────▶ C型文字列
(PType)                          (型変換)
       │
       ▼
位置情報 ─────────────────────▶ TLoc操作 ────────────────────────▶ C変数アクセス
(TLoc)                           (位置管理)
       │
       ▼
コード断片 ───────────────────▶ cgenWriteModules ────────────────▶ Cソースファイル
(Rope)                           (ファイル出力)
       │
       ▼
Cソースファイル ──────────────▶ extccomp ────────────────────────▶ 実行ファイル
                                (外部コンパイラ)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| cgen.nim | `compiler/cgen.nim` | ソース | Cコード生成メインモジュール |
| cgendata.nim | `compiler/cgendata.nim` | ソース | BModule、BProc、TLoc等の定義 |
| ccgtypes.nim | `compiler/ccgtypes.nim` | ソース | 型のCコード生成（includeされる） |
| ccgexprs.nim | `compiler/ccgexprs.nim` | ソース | 式のCコード生成（includeされる） |
| ccgstmts.nim | `compiler/ccgstmts.nim` | ソース | 文のCコード生成（includeされる） |
| ccgliterals.nim | `compiler/ccgliterals.nim` | ソース | リテラルのCコード生成（includeされる） |
| ccgutils.nim | `compiler/ccgutils.nim` | ソース | コード生成ユーティリティ |
| ccgreset.nim | `compiler/ccgreset.nim` | ソース | リセット処理（includeされる） |
| cbuilderbase.nim | `compiler/cbuilderbase.nim` | ソース | Cコードビルダー基盤 |
| cbuilderexprs.nim | `compiler/cbuilderexprs.nim` | ソース | 式ビルダー（includeされる） |
| cbuilderdecls.nim | `compiler/cbuilderdecls.nim` | ソース | 宣言ビルダー（includeされる） |
| cbuilderstmts.nim | `compiler/cbuilderstmts.nim` | ソース | 文ビルダー（includeされる） |
| extccomp.nim | `compiler/extccomp.nim` | ソース | 外部Cコンパイラ連携 |
| ropes.nim | `compiler/ropes.nim` | ソース | 効率的な文字列連結 |
| mangleutils.nim | `compiler/mangleutils.nim` | ソース | 名前マングリングユーティリティ |
