コンテンツにスキップ

LLVM/Clang

出典: フリー教科書『ウィキブックス(Wikibooks)』

Clangとその周辺ツール[編集]

はじめに[編集]

Clangの概要[編集]

Clangは、CC++Objective-CObjective-C++用のLLVMベースのフロントエンドコンパイラです。Clangは高速でモジュール化されており、他のツールやIDEと容易に統合できることが特徴です。GCCやMSVCからの完全な移行を目指すだけでなく、コンパイルパフォーマンス、使いやすさ、エラーメッセージの分かりやすさ、デバッギングサポートなどの面で優れています。

Clang周辺ツールの概要[編集]

Clangには、コンパイル、リファクタリング、コード解析などの用途で使えるさまざまなツールが付属しています。clang-tidyclang-formatclang-queryなどがその一例です。これらのツールを組み合わせることで、Cプロジェクトでの開発を大きく効率化できます。

インストールとビルド[編集]

リポジトリの取得[編集]

Clangとその周辺ツールはLLVMモノリポジトリの一部なので、まずそのリポジトリを取得する必要があります。

git clone --depth=1 -b llvmorg-18.1.6 https://github.com/llvm/llvm-project.git
この例では、TAG:llvmorg-18.1.6 から深さ1でクローニングしています。

CMakeによるビルド[編集]

LLVMプロジェクトはCMakeベースのビルドシステムを採用しています。clangclang-tools-extraをビルドするには、以下のようにします。

cd llvm-project/
cmake -S . -B build/ -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" llvm 
cmake --build build/

基本的な使い方[編集]

コンパイル[編集]

clang++を使えばC++プログラムをコンパイルできます。

clang++ hello.cc -o hello

主要なコンパイルオプション[編集]

Clangには多くのオプションがあり、最適化レベル、警告の制御、標準の指定などができます。

clang++ -O3 -Weverything -std=c++20 -fcolor-diagnostics hello.cc

ネイティブコードの生成、LTOの有効化なども可能です。

clang++ -flto -c file1.cc
clang++ -flto -c file2.cc
clang++ -march=native -Oz -flto file1.o file2.o -o file

静的解析ツール[編集]

Clangには豊富な静的解析ツールが付属しています。

clang-tidy[編集]

clang-tidyはC++の定番の静的解析ツールで、様々なチェックルールが組み込まれています。例:

clang-tidy file.cc -- -std=c++23

特定のチェックのみを実行したり、独自のチェックを追加することもできます。

.clang-tidyファイルは、clang-tidyが使用する設定ファイルです。このファイルを使用することで、プロジェクト固有の設定を行うことができます。以下は、.clang-tidyファイルの一般的な書き方です。

チェックの有効化/無効化
.clang-tidyファイルでは、特定のチェックを有効化または無効化することができます。有効化するチェックは、Checksセクション内にリストとして記述されます。
例えば、すべてのチェックを無効にする場合は次のように記述します。
Checks: '-*'
一方で、個々のチェックを有効化する場合は、次のようにチェック名を指定します。
Checks: 'bugprone-*,clang-analyzer-*'
チェックのオプション設定
.clang-tidyファイルでは、特定のチェックに対するオプションを設定することもできます。これにより、チェックの挙動をカスタマイズすることが可能です。オプションは、CheckOptionsセクション内にチェック名とそのオプションを指定して記述します。
例えば、bugprone-カテゴリのチェックに対して、特定のオプションを設定する場合は次のように記述します。
CheckOptions:
  - key: bugprone-unused-raii
    value: { 'CheckPointer': true, 'CheckSmartPtrOwnership': true }

これらの設定を.clang-tidyファイルに記述することで、プロジェクトごとにカスタマイズされた静的解析設定を行うことができます。

clang-analyzer[編集]

clang-analyzerは、CおよびC++のコードの静的解析を行うための優れたツールです。このツールは、コードの品質やセキュリティ上の問題を検出し、プログラムの安全性と信頼性を向上させるのに役立ちます。

clang-analyzerは、様々な静的解析手法を使用してコードをスキャンし、潜在的な問題を特定します。例えば、メモリリーク、NULLポインタ参照、未定義の動作などの問題を検出することができます。

このツールは、コードのコンパイル時に静的解析を行うため、実行時に発生する可能性のあるエラーを事前に検出することができます。これにより、バグの早期発見と修正が可能となります。

さらに、clang-analyzerは、統合開発環境(IDE)やビルドシステムと統合することができます。これにより、開発者はコードを書く際に静的解析の結果をリアルタイムで確認することができ、問題を素早く修正することができます。

clang-analyzerは、プロジェクトの品質管理やセキュリティ強化のために不可欠なツールの一つです。その高度な静的解析機能と使いやすさにより、開発者はより信頼性の高いコードを効率的に開発することができます。

clang-check[編集]

clang-checkはAST上で任意のチェックを実行できるツールです。libToolingと組み合わせて使います。

clang-query[編集]

clang-queryはコードに対してクエリを実行し、マッチした構文を検索できます。refactoringの下準備などに役立ちます。

その他のツール[編集]

clang-rename, clang-include-fixer, clang-applyreplacementsなども静的解析に活用できます。

高度な使い方[編集]

Clangは単なるコンパイラ以上の機能を備えています。

libToolingによるコード解析[編集]

libToolingはClangのコード解析機能をプログラムから利用するためのCPPライブラリです。AST traversalやソースコード書き換えなどが可能です。

リファクタリングツール[編集]

clang-applyreplacementsclang-moveなどはリファクタリングに特化したツールです。

clang-format によるコード整形[編集]

clang-formatはコーディングスタイルを統一するためのコード整形ツールです。

clang-reorder-fields によるフィールド順の最適化[編集]

構造体のメンバフィールド順をキャッシュ効率の観点から最適化できます。

clang-repl による対話的コード解析[編集]

REPL形式で対話的にコードを解析し、AST構造を調べられます。

clang-doc によるコードコメントの抽出[編集]

コードコメントをコメントノードのAST表現に変換して、マークアップ文書を生成できます。

clang-extdef-mapping による外部定義のマッピング[編集]

プログラムの外部定義と、それらがどの翻訳単位から来ているかをマッピングできます。

clangプラグイン[編集]

ClangはコンパイルフェーズごとにAST変換を行うプラグインシステムを持っています。独自の解析や最適化を行えます。

ASTの直接操作[編集]

libToolingを使えばASTを直接プログラムから構築・変更できます。

オフロードツール[編集]

clang-offload-bundlerclang-offload-packagerは、GPUなどへのコード分散をサポートします。

これらの機能を生かすことで、高度なツールやワークフローを構築できます。IDEインテグレーションも積極的に行われており、生産性の向上が期待できます。

パフォーマンスとツール連携[編集]

Clangは高速コンパイルを実現するためにいくつかの最適化が施されています。これにより、効率的なコンパイル時間を実現しながらも、生成されるコードの品質やパフォーマンスを犠牲にすることなく、高速な実行形式を生成することが可能です。

LTO, ThinLTO[編集]

Link Time Optimization(LTO)は、リンク時にコード全体にわたる最適化を行うことができる手法です。通常のコンパイルでは、個々のソースファイルが独立して最適化されますが、LTOでは、すべてのコンパイル単位がリンク時に結合され、より高度な最適化が可能になります。

ThinLTOは、LTOの高速でメモリフットプリントは小さな変種です。ThinLTOでは、全体のコンパイル単位を一度に読み込むのではなく、個々のモジュールごとに部分的な最適化を行います。これにより、メモリ使用量を削減し、リンク時間を短縮することができます。

LTOとThinLTOの選択は、プロジェクトの特性や要件によって異なります。大規模なプロジェクトでは、LTOを使用することでさらなる最適化が可能になりますが、リンク時間やメモリ使用量が増加する可能性があります。一方、ThinLTOは、リンク時間やメモリ使用量の制約がある場合に有用です。

LLVMでは、LTOとThinLTOをサポートするためのツールやオプションが提供されており、プロジェクトのニーズに合わせて適切な手法を選択することができます。

IDEインテグレーション[編集]

Visual Studio Code、XCode、KDevelopなどの多くのIDEにClangが統合されています。

コンパイル時間の最適化[編集]

スマートな前方ソース位置キャッシング、ビルドに適したコマンドラインオプションなどを使ってコンパイル時間を最小化できます。