# 機能設計書 82-clang-reorder-fields

## 概要

本ドキュメントは、clang-reorder-fieldsツールの機能設計について記述する。clang-reorder-fieldsは、C/C++の構造体やクラスのフィールド（メンバ変数）の順序を指定された順序に並べ替えるリファクタリングツールである。

### 本機能の処理概要

clang-reorder-fieldsは、構造体やクラスのメンバ変数の宣言順序を変更し、それに伴って初期化リストやコンストラクタの初期化順序も自動的に更新する。メモリレイアウトの最適化やコーディング規約への準拠を目的として使用される。

**業務上の目的・背景**：C/C++では、構造体やクラスのフィールド順序がメモリレイアウトに直接影響する。パディングを減らすためにフィールドを並べ替えたり、論理的なグループ化のために順序を変更したりすることがある。手動での並べ替えは、初期化リストの更新漏れなどのバグを引き起こしやすいため、自動化ツールが必要とされる。

**機能の利用シーン**：
- メモリ効率を向上させるためにフィールドをサイズ順に並べ替える場合
- コーディング規約に従ってフィールドを論理的にグループ化する場合
- アクセス頻度の高いフィールドをキャッシュフレンドリーに配置する場合
- レビュー指摘に基づいてフィールド順序を修正する場合

**主要な処理内容**：
1. 対象の構造体/クラス定義をASTから検索
2. 既存のフィールド順序と新しい順序のマッピングを計算
3. フィールド宣言の並べ替え（コメントを含む）
4. コンストラクタ初期化リストの並べ替え
5. 初期化リスト式（aggregate initialization）の並べ替え
6. 指示付き初期化子（designated initializer）の対応

**関連システム・外部連携**：Clang LibTooling APIを使用。初期化式の依存関係を考慮した警告を出力する機能を持つ。

**権限による制御**：特になし。ファイルシステムへの読み書き権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLIツール | 主画面 | コマンドライン経由での実行 |

## 機能種別

リファクタリング / コード変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| record-name | string | Yes | 対象の構造体/クラス名 | 定義が存在すること |
| fields-order | string list | Yes | 希望するフィールド順序（カンマ区切り） | 全フィールドを含むこと |
| -i | bool | No | ファイルを直接上書きするか | - |
| source files | string list | Yes | 対象ソースファイル | ファイルが存在すること |

### 入力データソース

- ソースファイル（.h, .c, .cpp等）
- compilation database（compile_commands.json）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 修正済みソース | file/-i指定時 or stdout | フィールドが並べ替えられたソースコード |

### 出力先

- -i指定時：入力ファイルを直接上書き
- -i未指定時：標準出力

## 処理フロー

### 処理シーケンス

```
1. コマンドライン引数の解析
   └─ record-name, fields-order, 対象ファイルを取得

2. RefactoringToolの初期化
   └─ コンパイルデータベースとソースファイルリストを設定

3. ReorderFieldsActionの実行
   └─ ASTConsumerを生成してAST解析を開始

4. 対象レコード（構造体/クラス）の検索
   └─ findDefinitionでrecord-nameに一致する定義を検索

5. 安全性チェック（isSafeToRewrite）
   └─ 複数フィールドを1行で宣言していないか
   └─ マクロによる複数フィールド定義がないか
   └─ プリプロセッサディレクティブが含まれていないか

6. フィールド順序マッピングの計算
   └─ getNewFieldsOrderで新しいインデックスを計算

7. 順序の妥当性チェック
   └─ flexible array memberが末尾に残ることを確認

8. フィールド宣言の並べ替え
   └─ reorderFieldsInDefinitionでソースレベルの置換を生成

9. コンストラクタ初期化リストの並べ替え
   └─ reorderFieldsInConstructorで各コンストラクタを処理

10. 初期化リスト式の並べ替え
    └─ reorderFieldsInInitListExprで集約初期化を処理

11. 変更の適用
    └─ -i時：ファイル上書き / それ以外：標準出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[コマンドライン解析]
    B --> C[RefactoringTool初期化]
    C --> D[AST解析開始]
    D --> E{record-nameの定義を検索}
    E -->|見つからない| F[エラー: 定義が見つからない]
    E -->|複数見つかる| G[エラー: 名前が曖昧]
    E -->|1つ見つかる| H{安全性チェック}
    H -->|失敗| I[処理中止]
    H -->|成功| J[フィールド順序マッピング計算]
    J --> K{フィールド数一致?}
    K -->|No| L[エラー: フィールド数不一致]
    K -->|Yes| M{flexible array member確認}
    M -->|末尾でない| N[エラー: FAM must be last]
    M -->|OK| O[フィールド宣言を並べ替え]
    O --> P[コンストラクタ初期化リスト並べ替え]
    P --> Q[InitListExpr並べ替え]
    Q --> R{-iオプション?}
    R -->|Yes| S[ファイル上書き]
    R -->|No| T[標準出力]
    S --> U[終了]
    T --> U
    F --> U
    G --> U
    I --> U
    L --> U
    N --> U
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 全フィールド指定 | fields-orderには全てのフィールドを指定する必要がある | 常時 |
| BR-02 | FAM末尾制約 | flexible array memberは末尾に残らなければならない | FAMを持つ構造体 |
| BR-03 | アクセス指定子保持 | 異なるアクセス指定子を持つフィールド間での並べ替えは不可 | C++クラス |
| BR-04 | 初期化依存警告 | 初期化式で他のフィールドを参照する場合、並べ替えにより未初期化アクセスが発生する可能性を警告 | 常時 |

### 計算ロジック

新しいフィールド位置の計算：
```
NewFieldsPositions[NewFieldsOrder[I]] = I
```
これにより、元のフィールドインデックスから新しい位置へのマッピングと、その逆のマッピングの両方を持つ。

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

該当なし（ファイルベースの操作のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 定義未発見 | record-nameの定義が見つからない | 正しいレコード名を指定 |
| - | 曖昧な名前 | 同名の定義が複数存在 | 完全修飾名を使用 |
| - | フィールド数不一致 | fields-orderの数がフィールド数と異なる | 全フィールドを指定 |
| - | フィールド未発見 | fields-orderに存在しないフィールド名 | 正しいフィールド名を指定 |
| - | FAM制約違反 | flexible array memberが末尾でなくなる | FAMを末尾に維持 |
| - | 複数フィールド宣言 | 1行に複数のフィールドが宣言されている | 1行1フィールドに分割 |

### リトライ仕様

リトライは行わない。エラー時は即座に終了。

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

該当なし。ただし、-iオプション使用時はRewriterが全ての変更をまとめて適用する。

## パフォーマンス要件

特に規定なし。通常のソースファイルサイズでは即座に完了すること。

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

- ファイルシステムへの書き込み権限が必要
- -iオプション使用時は元ファイルが上書きされるため、バックアップを推奨

## 備考

- C++20以降の指示付き初期化子（designated initializers）をサポート
- ゼロ初期化（`= {}`）は対象外として処理をスキップ
- プリプロセッサディレクティブを含むフィールド定義は処理不可
- コメントはフィールドと一緒に移動される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ReorderFieldsAction.h | `clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.h` | ReorderFieldsActionクラスの公開インターフェース |
| 1-2 | Designator.h | `clang-tools-extra/clang-reorder-fields/Designator.h` | 指示付き初期化子のためのDesignator構造体 |

**読解のコツ**: ReorderFieldsActionは3つの重要なメンバを持つ：RecordName（対象名）、DesiredFieldsOrder（希望順序）、Replacements（置換マップ）。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ClangReorderFields.cpp | `clang-tools-extra/clang-reorder-fields/tool/ClangReorderFields.cpp` | main関数とコマンドライン処理 |

**主要処理フロー**:
1. **52-58行目**: CommonOptionsParserでコマンドライン解析
2. **63行目**: RefactoringTool初期化
3. **65-66行目**: ReorderFieldsAction作成
4. **70-71行目**: -i時はrunAndSave、それ以外はrun
5. **73-88行目**: 結果の出力処理

#### Step 3: コア処理ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ReorderFieldsAction.cpp | `clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp` | 全ての並べ替えロジック |

**主要処理フロー**:
- **40-55行目**: findDefinition - 対象レコードの検索
- **57-81行目**: declaresMultipleFieldsInStatement/Macro - 安全性チェック
- **112-134行目**: isSafeToRewrite - 総合安全性判定
- **139-165行目**: getNewFieldsOrder - 新しい順序の計算
- **380-410行目**: reorderFieldsInDefinition - フィールド宣言の並べ替え
- **417-470行目**: reorderFieldsInConstructor - コンストラクタ初期化リストの並べ替え
- **524-655行目**: reorderFieldsInInitListExpr - 初期化リスト式の並べ替え
- **673-713行目**: HandleTranslationUnit - メイン処理の統合

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

```
main (ClangReorderFields.cpp)
    │
    ├─ CommonOptionsParser::create
    │
    ├─ RefactoringTool::run / runAndSave
    │      │
    │      └─ ReorderFieldsAction::newASTConsumer
    │             │
    │             └─ ReorderingConsumer::HandleTranslationUnit
    │                    │
    │                    ├─ findDefinition
    │                    │
    │                    ├─ isSafeToRewrite
    │                    │      ├─ declaresMultipleFieldsInStatement
    │                    │      ├─ declaresMultipleFieldsInMacro
    │                    │      └─ containsPreprocessorDirectives
    │                    │
    │                    ├─ getNewFieldsOrder
    │                    │
    │                    ├─ isOrderValid
    │                    │
    │                    ├─ ReorderedStruct構築
    │                    │
    │                    ├─ reorderFieldsInDefinition
    │                    │
    │                    ├─ reorderFieldsInConstructor (各コンストラクタ)
    │                    │      └─ findMembersUsedInInitExpr (依存チェック)
    │                    │
    │                    └─ reorderFieldsInInitListExpr (各初期化リスト)
    │
    └─ applyAllReplacements / Rewrite.getEditBuffer
```

### データフロー図

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

record-name ────┐
                │
fields-order ───┼───▶ findDefinition ───▶ RecordDecl
                │           │
source files ───┘           ▼
                      isSafeToRewrite
                            │
                            ▼
                      getNewFieldsOrder ───▶ NewFieldsOrder[]
                            │
                            ▼
                      ReorderedStruct構築
                            │
                  ┌─────────┼─────────┐
                  ▼         ▼         ▼
           reorder      reorder    reorder
           Fields       Fields     Fields
           InDef        InCtor     InInit
                  │         │         │
                  └────┬────┴────┬────┘
                       ▼
                  Replacements Map
                       │
                       ▼
              ┌────────┴────────┐
              ▼                 ▼
         -i: ファイル上書き   stdout出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ClangReorderFields.cpp | `clang-tools-extra/clang-reorder-fields/tool/ClangReorderFields.cpp` | ソース | mainエントリーポイント |
| ReorderFieldsAction.h | `clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.h` | ヘッダ | 公開API定義 |
| ReorderFieldsAction.cpp | `clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp` | ソース | コア処理実装 |
| Designator.h | `clang-tools-extra/clang-reorder-fields/Designator.h` | ヘッダ | 指示付き初期化子対応 |
| Designator.cpp | `clang-tools-extra/clang-reorder-fields/Designator.cpp` | ソース | 指示付き初期化子処理 |
| CMakeLists.txt | `clang-tools-extra/clang-reorder-fields/CMakeLists.txt` | ビルド | ビルド設定 |
