LLVM コーディング規約の実践的ガイドライン

はじめに

本ドキュメントはLLVMプロジェクトで採用されているコーディング規約について説明します。大規模なコードベースでは一貫したスタイルが特に重要であり、既存コードの拡張や修正時には既存のスタイルに従うことが基本原則です。

使用言語と標準

LLVMの主要な実装言語はC++です。C++14標準に準拠したコードを基本とし、ベンダー固有の拡張機能は避けます。標準ライブラリやLLVMサポートライブラリを積極的に利用し、カスタムデータ構造の実装は控えるべきです。

機械的なコーディング問題

コードフォーマット

コメントは英語の散文として適切な大文字化と句読点を使用して記述します。実装の詳細ではなく「何を」「なぜ」行うのかを説明することに重点を置きます。

ファイルヘッダー

//===-- llvm/Example.h - Example class definition ----------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file contains the declaration of the Example class.
///
//===----------------------------------------------------------------------===//

Doxygenコメント

/// Calculates the sum of two values.
///
/// \param FirstValue the first operand
/// \param SecondValue the second operand
/// \returns the arithmetic sum of the parameters
int computeSum(int FirstValue, int SecondValue);

エラーメッセージ

明確な診断メッセージはユーザーが問題を特定して修正するのに重要です。エラーメッセージは小文字で始まり、句点で終わらないようにします。

error: invalid section header size: expected 20, got 10

インクルードスタイル

インクルード順序は以下を推奨します:

  1. メインモジュールヘッダー
  2. ローカル/プライベートヘッダー
  3. LLVMプロジェクトヘッダー
  4. システムヘッダー

スペースとインデント

ソースファイルではタブではなくスペースを使用します。行末の空白は避けてください。ラムダ式のフォーマット例:

std::sort(container.begin(), container.end(), [](auto A, auto B) {
  if (A.property < B.property) return true;
  return A.otherProperty < B.otherProperty;
});

スタイルに関する問題

早期リターンの活用

早期リターンやcontinueを使用してコードのネストを浅く保ちます:

Value* processInstruction(Instruction* Inst) {
  if (Inst->isTerminator()) return nullptr;
  if (!Inst->hasOneUse()) return nullptr;
  
  // メイン処理
  return result;
}

命名規則

  • 型名: 大文字始まりのキャメルケース (ExampleClass)
  • 変数名: 大文字始まりのキャメルケース (CounterValue)
  • 関数名: 小文字始まりのキャメルケース (calculateTotal)
  • 列挙型: Kindサフィックス (ValueKind)

アサーションの活用

assert(Index < Elements.size() && "Index out of bounds");

範囲ベースforループ

for (auto& Element : Container) {
  processElement(Element);
}

raw_ostreamの使用

新しいコードではstd::ostreamではなくllvm::raw_ostreamを使用します:

llvm::raw_ostream& output = llvm::outs();
output << "Message: " << value << "\n";

その他の推奨事項

  • 静的コンストラクタの使用を避ける
  • RTTIと例外を使用しない
  • 移植性のあるコードを書く
  • 匿名名前空間は最小限に

タグ: LLVM C++ コーディング規約 プログラミングスタイル コード品質

6月29日 22:51 投稿