# 画面設計書 4-変数ビュー

## 概要

本ドキュメントは、LLDB Curses GUIにおける変数ビューの画面設計を記載する。変数ビューは、現在のスタックフレームのローカル変数とその値を表示するウィンドウであり、変数の展開/折りたたみや値のフォーマット変更が可能である。

### 本画面の処理概要

変数ビューは、デバッグ中のプログラムにおいて現在のスタックフレームに存在するローカル変数を一覧表示し、その値を確認するためのウィンドウである。

**業務上の目的・背景**：デバッグ作業において、変数の値を確認することは最も重要な操作の一つである。変数ビューは、ブレークポイントで停止した際に、現在のスコープ内の全てのローカル変数とその値を一覧表示し、問題の原因究明を支援する。複合型（構造体、クラス、配列等）は展開して詳細を確認でき、値のフォーマット（16進数、2進数、文字等）を変更することも可能。

**画面へのアクセス方法**：メインウィンドウの左下に常時表示される。TABキーでフォーカスを切り替えることでアクティブ化できる。

**主要な操作・処理内容**：
1. 上下矢印キーで変数の選択を変更
2. 右矢印キーで選択した複合型変数を展開
3. 左矢印キーで選択した変数を折りたたみ、または親を選択
4. Page Up/Downでページ単位スクロール
5. `x`/`X`キーで16進数表示（小文字/大文字）
6. `d`キーで符号付き整数表示
7. `u`キーで符号なし整数表示
8. `o`キーで8進数表示
9. `b`キーで2進数表示
10. `c`キーで文字表示
11. `f`キーで浮動小数点表示
12. `s`キーでC文字列表示
13. `p`キーでポインタ表示
14. `D`キーでデフォルトフォーマットに戻す

**画面遷移**：
- この画面からの遷移先：ヘルプダイアログ（hキー）
- この画面への遷移元：メインウィンドウ内のサブウィンドウとして常時表示

**権限による表示制御**：権限による表示制御は存在しない。プロセスが実行中の場合、更新は行われない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 8 | LLDB | 主機能 | FrameVariablesWindowDelegateによるローカル変数表示。現在のスタックフレームの変数と値の表示 |
| 8 | LLDB | 補助機能 | x/X/o/s/u/d/i/A/p/c/b/B/fキーによる値のフォーマット変更 |

## 画面種別

一覧表示（ツリービュー）

## URL/ルーティング

該当なし（CUI/TUIアプリケーション）

## 入出力項目

| 項目名 | 入出力 | 型 | 説明 |
|--------|--------|-----|------|
| キーボード入力 | 入力 | int | 矢印キー、Page Up/Down、フォーマット変更キー（x、d、u等） |
| ExecutionContext | 入力 | ExecutionContext | 現在の実行コンテキスト |
| StackFrame | 入力 | StackFrame | 現在のスタックフレーム |
| VariableList | 入力 | VariableList | フレーム内のローカル変数リスト |

## 表示項目

| 項目名 | 表示位置 | 説明 |
|--------|----------|------|
| タイトルボックス | ウィンドウ上部 | ウィンドウ名（通常 "Variables"） |
| 変数名 | 各行左側 | 変数名（展開可能な場合はツリーマーカー付き） |
| 変数値 | 各行右側 | 変数の値（選択したフォーマットで表示） |
| 型名 | 変数名の後 | 型名（tキーでトグル表示） |
| 選択行表示 | 選択行全体 | ハイライト表示 |

## イベント仕様

### 1-上下矢印キー押下

変数の選択を変更する。

- KEY_UP：前の項目を選択（m_selected_row_idx をデクリメント）
- KEY_DOWN：次の項目を選択（m_selected_row_idx をインクリメント）
- 表示範囲外になった場合は自動スクロール

### 2-左右矢印キー押下

変数の展開/折りたたみを行う。

- KEY_RIGHT：選択した複合型変数を展開（子要素を表示）
- KEY_LEFT：展開中の場合は折りたたみ、折りたたみ済みの場合は親を選択

### 3-Page Up/Downキー押下

ページ単位でスクロールする。

- KEY_PPAGE：表示行数分だけ上にスクロール
- KEY_NPAGE：表示行数分だけ下にスクロール

### 4-フォーマット変更キー押下

選択した変数の表示フォーマットを変更する。

| キー | フォーマット |
|-----|------------|
| x | 16進数（小文字） |
| X | 16進数（大文字） |
| d | 符号付き整数 |
| u | 符号なし整数 |
| o | 8進数 |
| b | 2進数 |
| c | 文字 |
| f | 浮動小数点 |
| s | C文字列 |
| p | ポインタ |
| A | アノテーション付きアドレス |
| i | 命令 |
| B | 16進数バイト（ASCII付き） |
| D | デフォルトフォーマット |
| t | 型名表示のトグル |

### 5-hキー押下

ヘルプダイアログを表示する。

## データベース更新仕様

該当なし（データベースは使用しない）

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|---------|
| MSG-001 | 情報 | "Frame variable window keyboard shortcuts:" | ヘルプダイアログ表示時 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| プロセスが実行中 | 変数の更新を行わない（現在の表示を維持） |
| フレームがない | 空のリストを表示 |
| 変数取得失敗 | 該当変数をスキップ |

## 備考

- FrameVariablesWindowDelegateクラスで実装
- ValueObjectListDelegateを継承してツリー表示機能を利用
- 動的型を使用しない（eDynamicDontRunTarget）
- 合成値（SyntheticValue）がある場合はそれを優先表示
- スタックフレームが変わった場合のみ変数リストを更新

---

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

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

### 推奨読解順序

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

ValueObjectListDelegateの基本構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | IOHandlerCursesGUI.cpp | `lldb/source/Core/IOHandlerCursesGUI.cpp` | 5540-5620行：ValueObjectListDelegateクラス定義、キーヘルプ配列 |
| 1-2 | IOHandlerCursesGUI.cpp | `lldb/source/Core/IOHandlerCursesGUI.cpp` | 5560-5595行：WindowDelegateDraw基本実装 |

**読解のコツ**: ValueObjectListDelegateはツリー表示のための汎用基底クラス。Rowクラスでツリー構造を管理。

#### Step 2: フレーム変数デリゲートを理解する

FrameVariablesWindowDelegateクラスの実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | IOHandlerCursesGUI.cpp | `lldb/source/Core/IOHandlerCursesGUI.cpp` | 5902-5967行：FrameVariablesWindowDelegateクラス定義 |
| 2-2 | IOHandlerCursesGUI.cpp | `lldb/source/Core/IOHandlerCursesGUI.cpp` | 5913-5962行：WindowDelegateDraw実装 |

**主要処理フロー**:
1. **5914-5915行**: ExecutionContextから現在のProcess/Frameを取得
2. **5920-5928行**: プロセス状態をチェック（実行中は更新しない）
3. **5932-5954行**: フレームブロックが変わった場合、VariableListから変数を取得
4. **5940-5950行**: 各変数のValueObjectを生成、SyntheticValueがあれば優先
5. **5961行**: 基底クラスのWindowDelegateDrawを呼び出して描画

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

```
FrameVariablesWindowDelegate::WindowDelegateDraw() [描画]
    │
    ├─ Debugger::GetCommandInterpreter().GetExecutionContext()
    │      └─ Process/Frame 状態取得
    │
    ├─ Frame::GetFrameBlock()
    │      └─ 現在のブロック取得
    │
    ├─ Frame::GetVariableList()
    │      └─ ローカル変数リスト取得
    │
    ├─ Frame::GetValueObjectForFrameVariable()
    │      └─ 各変数のValueObject生成
    │
    ├─ ValueObject::GetSyntheticValue()
    │      └─ 合成値がある場合は取得
    │
    ├─ SetValues()
    │      └─ ValueObjectListDelegate::m_rows に設定
    │
    └─ ValueObjectListDelegate::WindowDelegateDraw()
           └─ ツリー形式で描画
```

### データフロー図

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

ExecutionContext ──────────▶ FrameVariablesWindowDelegate   ─▶ 変数リスト表示
(Process/Thread/Frame)       ::WindowDelegateDraw()

Frame ──────────────────────▶ GetVariableList()             ─▶ VariableList

VariableList ───────────────▶ GetValueObjectForFrameVariable() ─▶ ValueObject

ValueObject ────────────────▶ DisplayRows()                 ─▶ ツリー表示

キーボード入力 ────────────▶ WindowDelegateHandleChar()    ┌─▶ 選択変更
(矢印/x/d/u等)                                               ├─▶ 展開/折りたたみ
                                                             └─▶ フォーマット変更
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| IOHandlerCursesGUI.cpp | `lldb/source/Core/IOHandlerCursesGUI.cpp` | ソース | FrameVariablesWindowDelegate、ValueObjectListDelegateの実装 |
| ValueObject.h | `lldb/include/lldb/ValueObject/ValueObject.h` | ヘッダ | 値オブジェクトクラス |
| VariableList.h | `lldb/include/lldb/Symbol/VariableList.h` | ヘッダ | 変数リストクラス |
| StackFrame.h | `lldb/include/lldb/Target/StackFrame.h` | ヘッダ | スタックフレームクラス |
