本技能介绍如何使用命令行`gh`只读查看GitHub issue正文和评论,支持通过编号或URL定位,也可指定其他仓库,并说明如何提取大量评论。
- 查看issue正文和评论
- 通过URL读取issue
- 查看其他仓库的issue
本技能介绍如何为Carbon编译器添加内置函数,包括类型注册、签名验证、常量求值、运行时LLVM IR生成、Prelude绑定,以及使用最小Prelude编写针对性测试。
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编译器结构为前提。
本介绍由 AI(OpenAI Codex)根据公开的 SKILL.md 撰写。准确的规格请查看下方原文。
AI 根据 SKILL.md 的内容检查了需要注意的操作和使用前提。评分只依据实际运行的结果(实测对比)。
不计入评分。 由 AI(OpenAI Codex)于 2026年10月26日 评估。仅供参考,安装前请同时查看原文。
安装前可以查看交给 AI 代理的指令内容。
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).还没有评价。欢迎分享你的使用感受。
无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。
还没有评论。来写第一条吧。
本技能介绍如何使用命令行`gh`只读查看GitHub issue正文和评论,支持通过编号或URL定位,也可指定其他仓库,并说明如何提取大量评论。
本技能为在 Carbon 代码库中工作的 AI 助手规定文件查看、搜索和编辑工具,并说明临时文件的存放与清理规则,以及何时可以编写和运行自定义程序。
了解如何在 Carbon 项目中通过 Bazelisk 构建、测试和运行程序,包括指定目标、启用 ASan,以及系统依赖变更后重建缓存。
了解 Carbon 工具链对 Bazel、C++、Carbon、Markdown 和 Python 文件的格式规范,并查看注释、文档、命名、设计及提交说明的写作要求。
本技能介绍如何在Carbon工具链中添加或修改错误和警告,包括注册诊断类型、用带类型的参数构造消息、为源码位置添加标签和上下文,以及检查措辞规范和测试覆盖。
使用 `gh` 只读搜索和查看 GitHub 的议题、拉取请求、仓库与代码,并了解如何查询 REST 和 GraphQL API、翻页获取结果及筛选或整理输出。