본문으로 건너뛰기
cccskills
무료GitHub에 공개한국어 소개

Builtin functions

Carbon 컴파일러에 내장 함수를 추가하는 절차를 안내합니다. 함수 등록과 시그니처 검증부터 상수 평가, 런타임 호출의 LLVM IR 생성, Prelude 연결, 최소 Prelude를 이용한 개별 테스트까지 다룹니다.

원문원문 설명 보기

Instructions for registering, mapping, constant evaluating, and lowering builtin functions in the Carbon toolchain.

carbon-language/carbon-lang스타 33,929(GitHub 33,929 + cccskills 0)

실행 점수 미검증

설치 방법 보기

이럴 때 유용합니다

  • 내장 함수 등록
  • 상수 평가 구현
  • LLVM IR 생성 추가
  • 내장 함수 테스트 작성

한국어 소개

할 수 있는 일

이 스킬은 Carbon 컴파일러에 내장 함수를 추가하는 절차를 설명합니다. 함수 종류 등록, 이름과 매개변수 제약의 연결, 컴파일 시에만 실행되는 함수의 지정, 상수 평가 구현, 런타임 호출을 LLVM IR로 낮추기, Prelude에 바인딩 추가하기를 다룹니다. 정수와 부동 소수점 값을 처리할 때의 범위 검사와 진단, 최소 Prelude를 사용해 내장 함수를 개별적으로 검증하는 테스트 작성 방법도 안내합니다.

이럴 때 유용합니다

Carbon 내장 함수를 새로 만들거나 수정할 때 활용할 수 있습니다. 컴파일 시 평가와 런타임 코드 생성을 각각 어디에 구현할지 정리하거나, Prelude 연결과 분리된 테스트 방법을 확인할 때 유용합니다.

사용 예시

  • “내장 함수를 등록하고 상수 평가를 구현하는 방법을 알려 주세요.”
  • “이 내장 함수를 LLVM IR로 낮추는 코드를 어디에 추가해야 하나요?”
  • “Prelude에 의존하지 않고 내장 함수를 검증하는 테스트를 작성해 주세요.”

주의 사항

C++, LLVM IR, Carbon 컴파일러 구조에 대한 이해를 전제로 합니다.

이 소개문은 공개된 SKILL.md를 바탕으로 AI(OpenAI Codex)가 작성했습니다. 정확한 사양은 아래 원문을 확인하세요.

문서 점검

AI가 SKILL.md의 내용에서 주의가 필요한 작업과 도입 전제를 확인했습니다. 점수는 실제로 실행한 결과(실행 검증)만으로 매깁니다.

안전성전송·삭제·명령 실행 등을 명시하고 있는가
A양호자료는 컴파일러 구현과 테스트를 다루며 외부 전송이나 삭제 작업은 언급하지 않습니다.
도입의 용이성필요한 도구나 API 키가 적고 적혀 있는가
B일부 부족C++, LLVM IR, Carbon 컴파일러에 대한 지식을 전제로 하지만 환경 설치 절차는 없습니다.

점수에는 넣지 않았습니다. 2026년 10월 26일 기준으로 AI(OpenAI Codex)가 판정했습니다. 참고용이므로 설치 전에 원문도 확인해 주세요.

평가가 다르다고 생각되면 재검토를 요청하기

어느 항목이 왜 다르다고 생각하는지 적어 주세요. 로그인은 필요 없습니다. SKILL.md와 대조해 평가를 다시 만들고 이곳에 반영합니다.

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

포함된 파일(1)

  • SKILL.md11.3 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Builtin Functions in the Carbon Toolchain

<!-- Part of the Carbon Language project, under the Apache License v2.0 with LLVM Exceptions. See /LICENSE for license information. SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -->

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.


Technical Flow & Lifecycle

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:

  1. Define the Builtin Kind: Register the enum in builtin_function_kind.def.
  2. Signature & Compile-Time Registry: Declare the mapping name, parameter constraints, and compile-time evaluation residency in builtin_function_kind.cpp.
  3. Compile-Time Interpreter Support: Wire constant evaluation hooks and bounds/exception diagnostics in eval.cpp.
  4. LLVM IR Lowering Support: Connect target machine generation in handle_call.cpp.
  5. Prelude Library Mapping: Bind primitive interfaces to named builtins under core/prelude/.

Detailed Step-by-Step Implementation Guide

Step 1: Kind Definition & Registration

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)

Step 2: Signature Validation & Compile-Time Residence

Inside builtin_function_kind.cpp:

  1. 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.
  2. 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>};
    
  3. Establish Compile-Time Residency Status: Update BuiltinFunctionKind::IsCompTimeOnly to determine if a call requires compile-time evaluation:

    • Checked/Diagnostics Primitives: Return true immediately. Runtime lowering of these is illegal (e.g. IntConvertFloatChecked).
    • Runtime Primitives: Return 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).

Step 3: Constant Evaluation Support

Wire the interpreter inside eval.cpp to execute compile-time computations:

  1. 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.

  2. 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.

  3. Fast-Path Range Limits:

    • Before evaluating expensive math operations on giant exponents (e.g. 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.

Step 4: Machine Code Generation (LLVM Lowering)

Inside handle_call.cpp:

  1. 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;
    }
    
  2. 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");
    }
    

Step 5: Standard Library Prelude Integration

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.

    • Literal Conversions: Literal types (like 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.
    • Sized Conversions: Implementations targeting sized primitives (e.g. 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.

High-Fidelity Validation & Test Authoring

Follow the Toolchain tests skill with specialized patterns for builtins:

1. Checker Builtin File Splits

Create validation splits under toolchain/check/testdata/builtins/:

  • Test Naming Convention: All tests under toolchain/check/testdata/builtins/ must be named after the builtin they are testing, replacing . 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.
  • Minimal Prelude & Direct Call Isolation: Builtin tests must not test the prelude library or operators. They must use the minimal primitive prelude (// 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.
  • Min-Prelude Limitations: Standard operators (like +, -, /, <, 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.
  • Canonicalized Float Comparison: In SemIR, real literal representations with identical mathematical values can result in mismatched 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.
  • Locals Bypass: If validating generic implicit conversions, compile-time arguments cannot take local runtime variable parameters. Validate compile-time conversions by passing literal constants directly, and sized variable implicit conversions at runtime.

2. Machine Codegen Lowering Splits

Create testing splits under toolchain/lower/testdata/builtins/:

  • Emplace a simple carbon binding to the tested builtin.
  • Confirm matching LLVM metadata target definitions are mapped precisely (e.g., matching sitofp i32 %a to float, fptosi float %a to i32).

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Accessing GitHub issues

무료요약 있음

명령줄의 `gh`로 GitHub 이슈 본문과 댓글을 읽기 전용으로 확인하는 방법을 안내합니다. 번호나 URL로 이슈를 찾고 다른 저장소를 지정하는 방법, 댓글이 많은 경우 JSON과 `jq`로 내용을 추출하는 방법을 다룹니다.

  • 이슈 본문과 댓글 읽기
  • URL로 이슈 내용 확인
  • 다른 저장소의 이슈 조회
carbon-language/carbon-lang3.4만2026년 10월 26일 업데이트

Agent tools

무료요약 있음

Carbon 저장소에서 일하는 AI 도우미가 전용 환경 도구로 파일을 읽고 검색하고 편집하는 규칙을 안내합니다. 임시 파일을 둘 위치와 삭제 시점, 사용자 지정 프로그램을 허용하는 경우도 설명합니다.

  • 정해진 도구로 Carbon 파일 검색
  • 파일 변경에 맞는 전용 도구 선택
  • 임시 파일 위치와 삭제 규칙 확인
carbon-language/carbon-lang3.4만2026년 10월 26일 업데이트

Bazel usage

무료요약 있음

Carbon 프로젝트에서 Bazelisk로 빌드, 테스트, 실행하는 기본 절차를 안내합니다. 대상을 지정한 검증, ASan 활성화, 시스템 의존성 변경 후 캐시 재생성도 다룹니다.

  • Carbon 코드 빌드
  • 변경 사항과 관련된 테스트 실행
  • Bazel로 빌드한 프로그램 실행
carbon-language/carbon-lang3.4만2026년 10월 26일 업데이트

Code style

무료요약 있음

Carbon 툴체인의 Bazel, C++, Carbon, Markdown, Python 파일 서식 기준을 안내합니다. 주석, 문서, 이름, 설계 원칙과 변경 내용을 설명하는 커밋 메시지 작성법도 다룹니다.

  • Carbon 코드와 관련 파일 서식 정리
  • 주석과 문서 검토
  • 이름이 실제 의미에 맞는지 확인
carbon-language/carbon-lang3.4만2026년 10월 26일 업데이트

Diagnostics

무료요약 있음

Carbon 도구 체인에서 오류와 경고 진단을 추가하거나 수정하는 방법을 안내합니다. 진단 종류 등록, 형식이 지정된 인수로 메시지 구성, 소스 위치에 라벨과 문맥 연결, 문구 규칙 및 테스트 범위 확인을 다룹니다.

  • 진단 메시지 추가
  • 소스 위치에 라벨 지정
  • 진단 문구 통일
carbon-language/carbon-lang3.4만2026년 10월 26일 업데이트

GitHub CLI usage

무료요약 있음

`gh`로 GitHub 이슈, 풀 리퀘스트, 저장소와 코드를 읽기 전용으로 검색하고 확인하는 방법을 안내합니다. REST·GraphQL API 조회, 페이지별 결과 수집, 출력 필터링과 형식 지정도 다룹니다.

  • 이슈의 내용과 상태 확인
  • 풀 리퀘스트의 변경 사항과 검사 상태 확인
  • GitHub 코드나 저장소 검색
carbon-language/carbon-lang3.4만2026년 10월 26일 업데이트

carbon-language의 스킬 모두 보기

이 스킬의 문제 신고