コマンドラインからGitHub issueの本文やコメントを読み取り専用で確認し、URLや番号から対象リポジトリを指定する手順を案内します。
- issueの本文とコメントを読みたいとき
- URLからissueの内容を確認したいとき
- 別リポジトリのissueを参照したいとき
Carbonコンパイラに組み込み関数を追加する際の登録、型シグネチャ検証、定数評価、LLVMコード生成、テスト方法を案内します。
Instructions for registering, mapping, constant evaluating, and lowering builtin functions in the Carbon toolchain.
実行スコア 未検証
インストール方法を見るCarbonコンパイラに組み込み関数を追加する一連の作業を扱います。関数種別の登録、名前と引数制約の対応付け、コンパイル時だけ評価する関数の指定、定数評価の実装、実行時呼び出しのLLVM IRへの変換、Preludeからのバインディングまでを順に確認できます。整数や浮動小数点数の値を扱う際の範囲チェックや診断の追加、最小Preludeを使って組み込み関数を個別に検証するテストの作り方も説明しています。
Carbonの組み込み関数を新設・変更するコンパイラ開発者向けです。コンパイル時評価と実行時コード生成のどちらに処理を実装するか整理したい場合や、Preludeとの接続、テストの切り分け方を確認したい場合に使えます。
C++、LLVM IR、Carbonのコンパイラ構成を前提とします。
この紹介文は、公開されている SKILL.md をもとに AI(OpenAI Codex)が作成しました。正確な仕様は下の原文を確認してください。
SKILL.md の記述から、注意が要る操作と導入の前提を AI が確認しました。点数は実際に動かした結果(実行検証)だけで付けています。
点数には入れていません。 2026年10月26日 時点で AI(OpenAI Codex)が判定しました。目安なので、入れる前に原文も確認してください。
インストールする前に、エージェントに与えられる指示の中身を確認できます。
Builtin functions are compiler-recognized primitives mapping directly from Carbon code expressions (via standard prelude bindings) to optimized backend execution. This document defines the complete structural workflow, C++ patterns, constant evaluation logic, machine lowering mechanics, library bindings, and validation strategies required to implement builtin functions in the Carbon compiler.
graph TD
Src[Carbon Source Code] -->|Prelude Map| Sem[Semantic Analysis / SemIR]
Sem -->|Signature Constraint| Sig[builtin_function_kind.cpp]
Sem -->|Phase Evaluation| Eval[eval.cpp Constant Interpreter]
Sem -->|Machine Codegen| Lower[handle_call.cpp LLVM Lowering]
Eval -->|Diagnostics| Diag[diagnostics/kind.def]
Lower -->|Native Instructions| LLVM[LLVM IR Generation]
Adding a builtin function involves a 5-step integration:
Register your builtin function name using the X-macro in builtin_function_kind.def:
// toolchain/sem_ir/builtin_function_kind.def
// Converts an integer type to a floating-point type.
CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntConvertFloat)
Inside builtin_function_kind.cpp:
Define Parameter Constraints: If the parameter requires novel
constraints (e.g. "must be a float type"), define a template constraint
struct checking the matching SemIR type instruction (such as FloatType
or FloatLiteralType). Use pre-established semantic helpers:
TypeParam<I, T>: Ensures different parameters resolve to identical
type structures (e.g., generic constraint matching).AnyInt, AnyFloat, AnySizedInt, AnySizedFloat, CharCompatible,
StdInitializerList, NoReturn.Map Literal Name & Register Constraint Signature: Declare a
BuiltinInfo constant inside namespace BuiltinFunctionInfo matching the
macro-defined name:
// toolchain/sem_ir/builtin_function_kind.cpp
constexpr BuiltinInfo IntConvertFloat = {
"int.convert_float", ValidateSignature<auto(AnyInt)->AnyFloat>};
Establish Compile-Time Residency Status: Update
BuiltinFunctionKind::IsCompTimeOnly to determine if a call requires
compile-time evaluation:
true immediately. Runtime
lowering of these is illegal (e.g. IntConvertFloatChecked).AnyLiteralTypes(sem_ir, arg_ids, return_type_id) to enforce that
expressions involving unsized literal values (like IntLiteral or
FloatLiteral) are evaluated exclusively at compile-time (as they lack
runtime representation).Wire the interpreter inside eval.cpp to execute compile-time computations:
Implement Constant Evaluation Logic:
Handle the builtin case inside MakeConstantForBuiltinCall (which
processes the compile-time execution of the call).
Confirm type validation phase is Phase::Concrete to reject incomplete
bindings:
case SemIR::BuiltinFunctionKind::IntConvertFloat: {
if (phase != Phase::Concrete) {
return MakeConstantResult(context, call, phase);
}
return PerformIntToFloatConvert(context, loc_id, arg_ids[0], call.type_id,
/*require_exact=*/false);
}
Extract inputs safely from local value stores (e.g.
context.ints().Get(arg.int_id) or
context.floats().Get(arg.float_id)).
Leverage high-precision LLVM mathematical structures (llvm::APInt,
llvm::APFloat, llvm::APSInt) to handle custom bits and signedness
safely.
Diagnose Invalid Parameters or Exceptions:
Define compile-time diagnostics inside kind.def:
// toolchain/diagnostics/kind.def
CARBON_DIAGNOSTIC_KIND(IntTooLargeForFloatType)
Emplace localized diagnostic formatting messages where they are caught
in eval.cpp:
CARBON_DIAGNOSTIC(IntTooLargeForFloatType, Error,
"integer value {0} too large for floating-point type {1}",
llvm::APSInt, SemIR::TypeId);
context.emitter().Emit(loc_id, IntTooLargeForFloatType, val, dest_type_id);
Return SemIR::ErrorInst::ConstantId to gracefully abort invalid
constant generation rather than crashing the compiler.
Fast-Path Range Limits:
1.0e1000000), executing range limits check against dest_width + 64
(sized) or IntStore::MaxIntWidth (unsized) is mandatory to prevent
out-of-bounds calculations and compile-time memory exhaustion.Inside handle_call.cpp:
Map to Native LLVM Instructions: For runtime-eligible builtins, map the
call inside HandleBuiltinCall to native LLVM IR builder methods:
case SemIR::BuiltinFunctionKind::IntConvertFloat: {
auto* operand = context.GetValue(arg_ids[0]);
auto* dest_type = context.GetTypeOfInst(inst_id);
bool is_signed = IsSignedInt(context, arg_ids[0]);
context.SetLocal(
inst_id, is_signed
? context.builder().CreateSIToFP(operand, dest_type)
: context.builder().CreateUIToFP(operand, dest_type));
return;
}
Assert on Compile-Time-Only Builtins: Throw a hard assertion on lowering-cases for checked validator builtins that should never hit code generation:
case SemIR::BuiltinFunctionKind::IntConvertFloatChecked: {
CARBON_CHECK(builtin_kind.IsCompTimeOnly(
context.sem_ir(), arg_ids,
context.sem_ir().insts().Get(inst_id).type_id()));
CARBON_FATAL("Missing constant value for call to comptime-only function");
}
Map the standard library primitive interfaces to your newly minted named builtins under core/prelude/:
Primitive Mappings: Bind Carbon methods directly to string-literal builtin equivalents:
fn Convert[self: Self]() -> Float(To) = "int.convert_float";
Strict Orphan Rule Compliance: Carbon's orphan rules prohibit implementing interfaces where neither the type nor the interface is locally defined in the backing source module.
FloatLiteral,
IntLiteral) do not have backing Carbon source files. Therefore, an
impl of UnsafeAs (which is defined in as.carbon) between two
literal types must reside inside as.carbon itself.Int(N), Float(N)) must reside in their respective type source files
(such as int.carbon or
float.carbon) where the
backing target type resides to prevent duplicate symbols and structural
recursion loops.Follow the Toolchain tests skill with specialized patterns for builtins:
Create validation splits under toolchain/check/testdata/builtins/:
. characters
in the builtin name with / (directories). For example, a test for the
builtin "char_literal.convert" must be located at
toolchain/check/testdata/builtins/char_literal/convert.carbon.// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/primitives.carbon) or a smaller
prelude, and explicitly declare and call the builtin functions under test
directly (e.g., fn Add(a: f64, b: f64) -> f64 = "float.add";). This
isolates the testing of compiler builtins from the library prelude.+, -, /, <,
etc.) are not available in minimized preludes because the core operators
library isn't imported. To write tests with a minimal footprint, call
primitive builtins directly (e.g. float.negate, float.div) inside your
test code to build expressions.RealId objects
based on spelling variations. Verify compile-time constant conversions using
canonicalized comparison functions (e.g. passing converted results through
Expect(X as f64)) to completely avoid spelling mismatches in expected
outputs.Create testing splits under toolchain/lower/testdata/builtins/:
sitofp i32 %a to float, fptosi float %a to i32).まだレビューはありません。使ってみた感想をお寄せください。
ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。
まだコメントはありません。最初のコメントを書いてみませんか。
コマンドラインからGitHub issueの本文やコメントを読み取り専用で確認し、URLや番号から対象リポジトリを指定する手順を案内します。
AIアシスタントがCarbonのコードベースを扱う際に、専用ツールでファイルを閲覧・検索・編集し、一時ファイルを管理するためのルールを示します。
Bazeliskを使ったCarbonプロジェクトのビルド、テスト、実行、デバッグの基本手順を確認し、対象を絞った検証やASanの利用方法も把握できます。
Carbonツールチェーンのコードを書く際に、言語ごとの整形方法やコメント、命名、ドキュメント、コミットメッセージの基準を確認できます。
Carbonコンパイラのエラーや警告を定義し、書式やソース位置のラベルを整え、テストで網羅性を確かめる方法を案内します。
`gh`でGitHubのIssue、プルリクエスト、リポジトリを読み取り専用で検索・確認し、必要な情報を絞り込む方法を案内します。