# 機能設計書 87-Clangコンパイラ

## 概要

本ドキュメントは、FreeBSDにおけるClangコンパイラ（LLVM/Clang）の機能設計を記述する。ClangはLLVMプロジェクトのC/C++/Objective-Cコンパイラフロントエンドであり、FreeBSDのデフォルトシステムコンパイラとして採用されている。ベースシステム全体のビルドに使用される。

### 本機能の処理概要

**業務上の目的・背景**：Clangはgccに代わるBSDライセンス互換のコンパイラとしてFreeBSD 10.0からデフォルトコンパイラとなった。C11/C17/C23、C++14/C++17/C++20/C++23など最新の言語規格をサポートし、高品質なエラーメッセージ、高速なコンパイル、LLVMバックエンドによる強力な最適化を提供する。FreeBSDのカーネル・ユーザランド・ポーツの全ビルドチェーンの基盤である。

**機能の利用シーン**：FreeBSDベースシステムのビルド（buildworld/buildkernel）、ポーツコレクションのビルド、アプリケーション開発、カーネルモジュールのコンパイル、クロスコンパイル。

**主要な処理内容**：
1. フロントエンド（Clang）: ソースコードの字句解析・構文解析・意味解析、プリプロセッサ処理、LLVM IR生成
2. ミドルエンド（LLVM）: LLVM IR最適化パス（インライン展開、ループ最適化、デッド コード除去等）
3. バックエンド（LLVM）: ターゲットアーキテクチャ向けコード生成（x86_64, aarch64, armv7, powerpc64等）
4. リンカ（LLD）: ELFリンカ。オブジェクトファイルの結合・再配置・実行ファイル生成
5. 関連ツール: llvm-ar（アーカイバ）、llvm-objdump（逆アセンブラ）、llvm-nm（シンボルテーブル）、lldb（デバッガ）

**関連システム・外部連携**：libc（標準Cライブラリ）、libc++（C++標準ライブラリ）、libpthread（スレッドライブラリ）、ld（リンカ）、as（アセンブラ）。

**権限による制御**：一般ユーザで実行可能。出力先ディレクトリへの書き込み権限が必要。

## 関連画面

該当なし（CLIコマンドのため画面は存在しない）

## 機能種別

コンパイル処理 / コード生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| source_file | string | Yes | コンパイル対象ソースファイル(.c/.cc/.cpp等) | 存在すること |
| -o output | string | No | 出力ファイル名 | 書き込み可能なパス |
| -c | flag | No | コンパイルのみ（リンクしない） | - |
| -S | flag | No | アセンブリ出力 | - |
| -E | flag | No | プリプロセスのみ | - |
| -O[0-3/s/z] | string | No | 最適化レベル | 有効な最適化レベル |
| -g | flag | No | デバッグ情報生成 | - |
| -W... | string | No | 警告制御 | 有効な警告フラグ |
| -std=standard | string | No | 言語規格指定(c11/c++17等) | 有効な規格名 |
| -I directory | string | No | インクルードパス追加 | - |
| -L directory | string | No | ライブラリパス追加 | - |
| -l library | string | No | リンクライブラリ指定 | - |
| -target triple | string | No | ターゲットトリプル指定 | 有効なトリプル |

### 入力データソース

C/C++/Objective-Cソースファイル、ヘッダファイル、オブジェクトファイル、ライブラリファイル。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| オブジェクトファイル | binary | .oファイル（ELF形式） |
| 実行ファイル | binary | リンク済みELFバイナリ |
| アセンブリ | text | .sファイル（アセンブリ言語） |
| プリプロセス出力 | text | マクロ展開済みソース |

### 出力先

ファイルシステム上の出力ファイル。

## 処理フロー

### 処理シーケンス

```
1. ドライバ初期化
   └─ clang-driver.cpp: LLVMDriver初期化、コマンドライン解析
2. プリプロセス
   └─ マクロ展開、ヘッダファイルインクルード、条件コンパイル
3. 字句解析・構文解析
   └─ トークン化、AST（抽象構文木）構築
4. 意味解析
   └─ 型チェック、オーバーロード解決、テンプレートインスタンス化
5. LLVM IR生成
   └─ ASTからLLVM中間表現への変換
6. 最適化
   └─ LLVM最適化パイプライン実行（-O0〜-O3に応じた最適化レベル）
7. コード生成
   └─ ターゲットアーキテクチャ向けマシンコード生成
8. アセンブル
   └─ オブジェクトファイル(.o)生成
9. リンク（-cなしの場合）
   └─ LLD/ldによるオブジェクトファイル結合・実行ファイル生成
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[ドライバ: コマンドライン解析]
    B --> C{-Eオプション?}
    C -->|Yes| D[プリプロセスのみ]
    C -->|No| E[プリプロセス]
    E --> F[字句解析・構文解析 → AST]
    F --> G[意味解析]
    G --> H{-fsyntax-only?}
    H -->|Yes| I[構文チェックのみ]
    H -->|No| J[LLVM IR生成]
    J --> K{-Sオプション?}
    K -->|Yes| L[アセンブリ出力]
    K -->|No| M[最適化パス]
    M --> N[コード生成 → .o]
    N --> O{-cオプション?}
    O -->|Yes| P[オブジェクト出力]
    O -->|No| Q[リンク → 実行ファイル]
    D --> R[終了]
    I --> R
    L --> R
    P --> R
    Q --> R
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-87-01 | デフォルト最適化 | デフォルトは-O0（最適化なし） | オプション未指定時 |
| BR-87-02 | ターゲット自動検出 | ホストシステムのアーキテクチャを自動検出 | -target未指定時 |
| BR-87-03 | FreeBSDターゲット | FreeBSD向けにデフォルトのシステムインクルードパス・ライブラリパスを設定 | FreeBSD上で実行時 |
| BR-87-04 | CC互換 | cc/c++/cpp等のシンボリックリンクから呼出可能 | argv[0]による動作切替 |

### 計算ロジック

LLVM最適化パイプラインは-Oレベルに応じて適用される最適化パスの組み合わせが変わる。-O0: 最適化なし、-O1: 基本最適化、-O2: 標準最適化、-O3: 積極的最適化、-Os: サイズ最適化、-Oz: 最小サイズ最適化。

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | コンパイルエラー | ソースコードの構文/型エラー | ソース位置・詳細メッセージ・Fix-It提案を表示 |
| 1 | リンクエラー | 未定義シンボル・重複定義 | エラーメッセージ表示 |
| 1 | ファイル不存在 | 指定ソースファイルが見つからない | エラーメッセージ表示 |
| - | 警告 | 潜在的問題の検出 | 警告メッセージ表示（-Werrorで致命的化可） |

### リトライ仕様

リトライは行わない。

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

コンパイルは個別ソースファイル単位で実行。コンパイルエラー時は不完全な出力ファイルは生成されない。

## パフォーマンス要件

- プリコンパイルヘッダ（-include-pch）によるコンパイル高速化
- モジュール（-fmodules）によるヘッダ解析の重複排除
- LTOサポートによるリンク時最適化

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

- -fstack-protectorによるスタックバッファオーバーフロー検出
- -fsanitize=addressによるAddress Sanitizer
- Position Independent Executable (-pie) デフォルト有効
- RELRO/BIND_NOW等のリンカセキュリティ機能

## 備考

- FreeBSDのClangはcontrib/llvm-project/から取り込み
- clang-driver.cppはLLVMDriverの薄いラッパー（19行、clang_mainを呼出すのみ）
- usr.bin/clang/配下にclang以外のLLVMツール群（lld, lldb, llvm-ar等）のビルド設定が配置
- CC.shスクリプトによるコンパイララッパーも提供

---

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

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

### 推奨読解順序

#### Step 1: FreeBSD固有のエントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | clang-driver.cpp | `usr.bin/clang/clang/clang-driver.cpp` | LLVMDriverラッパー。clang_main()への委譲 |
| 1-2 | Makefile | `usr.bin/clang/clang/Makefile` | FreeBSD向けClangビルド設定 |
| 1-3 | CC.sh | `usr.bin/clang/clang/CC.sh` | コンパイララッパースクリプト |

**読解のコツ**: FreeBSDのClangビルドはusr.bin/clang/配下のMakefileとcontrib/llvm-project/のソースを組み合わせる。clang-driver.cppは最小限のラッパー（15-18行目でInitLLVM + clang_main呼出のみ）。

#### Step 2: LLVMツール群の構成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | clang.prog.mk | `usr.bin/clang/clang.prog.mk` | LLVM共通ビルド設定 |

**主要処理フロー**:
1. **9行目（clang-driver.cpp）**: llvm/Support/LLVMDriver.hインクルード
2. **13行目**: clang_main()関数宣言
3. **15-18行目**: main()でInitLLVM後にclang_mainへ委譲

#### Step 3: LLVMプロジェクトのソースを参照する（参考）

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | - | `contrib/llvm-project/clang/` | Clangフロントエンド本体（参考） |
| 3-2 | - | `contrib/llvm-project/llvm/` | LLVM中間表現・最適化・コード生成（参考） |
| 3-3 | - | `contrib/llvm-project/lld/` | LLDリンカ（参考） |

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

```
clang-driver.cpp main()
    |
    +-- llvm::InitLLVM()        # LLVM初期化
    +-- clang_main()            # Clangフロントエンドメイン
            |
            +-- [プリプロセス]
            |       +-- マクロ展開
            |       +-- #include処理
            |
            +-- [フロントエンド]
            |       +-- Lexer: 字句解析
            |       +-- Parser: 構文解析 → AST
            |       +-- Sema: 意味解析
            |
            +-- [IRGen]
            |       +-- AST → LLVM IR変換
            |
            +-- [最適化]
            |       +-- LLVM Pass Manager
            |       +-- 各種最適化パス
            |
            +-- [バックエンド]
            |       +-- 命令選択
            |       +-- レジスタ割り当て
            |       +-- コード生成 → .o
            |
            +-- [リンク]（-cなし時）
                    +-- LLD / system ld
```

### データフロー図

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

ソースファイル(.c/.cpp) ──> プリプロセス ──> 展開済みソース
                             Clang Lexer/Parser ──> AST
                             Clang Sema ──> 型付きAST
                             Clang CodeGen ──> LLVM IR
                             LLVM Optimizer ──> 最適化IR
                             LLVM Backend ──> マシンコード
                             Assembler ──> .oファイル
                             LLD/ld ──> 実行ファイル
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| clang-driver.cpp | `usr.bin/clang/clang/clang-driver.cpp` | ソース | Clangエントリーポイント（LLVMDriverラッパー） |
| Makefile | `usr.bin/clang/clang/Makefile` | ビルド設定 | FreeBSD向けClangビルド |
| CC.sh | `usr.bin/clang/clang/CC.sh` | スクリプト | コンパイララッパー |
| clang.prog.mk | `usr.bin/clang/clang.prog.mk` | ビルド設定 | LLVM共通ビルド設定 |
| llvm-project/ | `contrib/llvm-project/` | ソース群 | LLVMプロジェクト本体 |
| lld/ | `usr.bin/clang/lld/` | ビルド設定 | LLDリンカビルド設定 |
| lldb/ | `usr.bin/clang/lldb/` | ビルド設定 | LLDBデバッガビルド設定 |
| llvm-ar/ | `usr.bin/clang/llvm-ar/` | ビルド設定 | LLVMアーカイバビルド設定 |
