# 機能設計書 58-llvm-undname

## 概要

本ドキュメントは、LLVMプロジェクトにおけるllvm-undnameツールの機能設計を記述する。llvm-undnameは、Microsoft Visual C++のマングル名をデマングルして人間が読める形式に変換するツールである。

### 本機能の処理概要

llvm-undnameは、Windows環境でMicrosoft Visual C++コンパイラが生成するマングル名（名前修飾）を解除し、元のC/C++の関数名やクラス名を復元するコマンドラインツールである。Windowsの標準ツールであるundname.exeと互換性があり、クロスプラットフォームで動作する。

**業務上の目的・背景**：Microsoft Visual C++は独自のマングリング規則を使用しており、Itanium C++ ABIとは異なる。Windowsのバイナリ解析やデバッグにおいて、MSVCのマングル名を解読する必要があるが、標準のundname.exeはWindowsでのみ動作する。llvm-undnameは、Linux/macOS上でもWindowsバイナリのシンボルを解読可能にする。

**機能の利用シーン**：
- Windows PEファイルのシンボル解析
- dumpbin/nmの出力解読
- クロスプラットフォーム開発でのデバッグ
- Windows DLLのリバースエンジニアリング

**主要な処理内容**：
1. マングル名の入力（引数または標準入力）
2. Microsoftマングル名のデマングル処理
3. オプションに応じた出力フィルタリング
4. デマングル結果の出力

**関連システム・外部連携**：
- LLVMのDemangle ライブラリとの連携

**権限による制御**：本ツールはファイルシステムへのアクセスを必要としない（標準入出力のみ）。

## 関連画面

本ツールはCLI（コマンドラインインターフェース）ツールであり、GUI画面は存在しない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| N/A | コマンドライン | 主画面 | マングル名の入力、デマングル結果の表示 |

## 機能種別

文字列変換 / デマングル処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| symbols | list<string> | No | デマングルするシンボル名（複数可） | - |
| --backrefs | bool | No | バックリファレンスをダンプ（デバッグ用） | - |
| --no-access-specifier | bool | No | アクセス指定子を省略 | - |
| --no-calling-convention | bool | No | 呼び出し規約を省略 | - |
| --no-return-type | bool | No | 戻り値型を省略 | - |
| --no-member-type | bool | No | メンバ型を省略 | - |
| --no-variable-type | bool | No | 変数型を省略 | - |
| --raw-file | string | No | ファイルから入力（ファザーデータ用） | - |
| --warn-trailing | bool | No | 末尾の余分な文字を警告 | - |

### 入力データソース

- コマンドライン引数
- 標準入力（シンボル名未指定時）
- ファイル（--raw-file指定時）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| DemangledName | text | デマングルされたシンボル名 |
| WarningMessage | text | 末尾文字警告（--warn-trailing時） |

### 出力先

- 標準出力：デマングル結果
- 標準エラー出力：エラー/警告

## 処理フロー

### 処理シーケンス

```
1. 初期化処理
   └─ InitLLVMによるコマンドライン引数パース
2. 入力ソース判定
   ├─ --raw-file: ファイルから読み込み
   ├─ 引数あり: 各引数をデマングル
   └─ 引数なし: 標準入力から行単位で読み込み
3. 各シンボルのデマングル
   └─ microsoftDemangle()呼び出し
4. 結果出力
   └─ 成功時: デマングル結果
   └─ 失敗時: エラーメッセージ
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[InitLLVM・引数パース]
    B --> C{--raw-file指定?}
    C -->|Yes| D[ファイル読み込み]
    C -->|No| E{シンボル引数あり?}
    D --> F[msDemangle実行]
    E -->|Yes| G[各シンボルをmsDemangle]
    E -->|No| H[標準入力から読み込み]
    H --> I[行ごとにmsDemangle]
    F --> J{成功?}
    G --> J
    I --> J
    J -->|Yes| K[結果出力]
    J -->|No| L[エラー出力]
    K --> M{--warn-trailing && 末尾あり?}
    M -->|Yes| N[警告出力]
    M -->|No| O[終了]
    N --> O
    L --> O
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 空行・コメントスキップ | 空行、#、;で始まる行は無視 | 標準入力時 |
| BR-02 | エコー制御 | リダイレクト入力時は入力行をエコー | 標準入力がユーザー入力でない場合 |
| BR-03 | 末尾文字警告 | デマングルで消費されなかった文字を警告 | --warn-trailing時 |
| BR-04 | フラグ組み合わせ | 複数のno-*オプションを組み合わせ可能 | 常時 |

### 計算ロジック

デマングルアルゴリズム：
- microsoftDemangle()関数を使用
- MSDemangleFlagsで出力フィルタリングを制御
- NReadで消費文字数を取得（末尾警告用）

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

本ツールはデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | 入力エラー | --raw-fileのファイルが開けない | ファイルパスを確認 |
| 1 | デマングル失敗 | 無効なマングル名 | 正しいMSVCマングル名を使用 |

### リトライ仕様

リトライ処理は実装されていない。

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

該当なし。

## パフォーマンス要件

即座に応答することが期待される。

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

- ファイル読み取りは--raw-file使用時のみ
- メモリ安全性はDemangleライブラリに依存

## 備考

- Windows undname.exeと互換性がある
- Microsoftマングル名専用（Itanium ABIには非対応）

---

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

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

### 推奨読解順序

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

デマングル処理に使用されるフラグを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Demangle.h | `llvm/include/llvm/Demangle/Demangle.h` | MSDemangleFlags列挙型 |

**読解のコツ**: MSDemangleFlagsはビットフラグで、複数のオプションをORで組み合わせる。

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

処理の起点となるmain関数を読み解く。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | llvm-undname.cpp | `llvm/tools/llvm-undname/llvm-undname.cpp` | main関数 |

**主要処理フロー**:
1. **96-100行目**: InitLLVMとコマンドライン引数パース
2. **102-111行目**: --raw-fileオプション処理
3. **113-146行目**: シンボル処理（引数または標準入力）

#### Step 3: デマングル処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | llvm-undname.cpp | `llvm/tools/llvm-undname/llvm-undname.cpp` | msDemangle関数（65-94行目） |

**主要処理フロー**:
- **66-79行目**: MSDemangleFlagsの設定
- **81-82行目**: microsoftDemangle()呼び出し
- **83-88行目**: 成功時の出力と末尾警告
- **89-91行目**: 失敗時のエラー出力

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

```
main()
    │
    ├─ InitLLVM()
    ├─ cl::ParseCommandLineOptions()
    │
    ├─ [--raw-file指定時]
    │      └─ MemoryBuffer::getFileOrSTDIN()
    │             └─ msDemangle()
    │
    ├─ [シンボル引数あり]
    │      └─ msDemangle() [x N]
    │
    └─ [標準入力]
           └─ std::getline() ループ
                  └─ msDemangle()
                         └─ microsoftDemangle()
```

### データフロー図

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

コマンドライン  ───▶ main()
引数                   │
        または         │
標準入力        ───▶ std::getline()
        または         │
--raw-file      ───▶ MemoryBuffer
                       │
                       ▼
                  msDemangle()
                       │
                       ├─ MSDemangleFlags設定
                       │
                       └─ microsoftDemangle()
                              │
                              ▼
                       デマングル結果 ───▶ 標準出力
                              │
                              └─ [失敗時] ───▶ 標準エラー
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| llvm-undname.cpp | `llvm/tools/llvm-undname/llvm-undname.cpp` | ソース | メインエントリーポイント |
| CMakeLists.txt | `llvm/tools/llvm-undname/CMakeLists.txt` | ビルド設定 | ビルド構成の定義 |
| Demangle.h | `llvm/include/llvm/Demangle/Demangle.h` | ヘッダー | デマングルAPI定義 |
| MicrosoftDemangle.cpp | `llvm/lib/Demangle/MicrosoftDemangle.cpp` | ソース | Microsoftデマングル実装 |
