mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Add functions for instantiating builtin types through lookup. (#3857)
Note, my instinct is that `Float(dyn_size)` should be invalid. However, I think the constant evaluation doesn't result in the call being evaluated in eval.cpp when the size is non-constant. I think I could get an error for symbolic phase calls, but that seems a little less interesting already. Long-term maybe we want a way to mark functions as _must_ be evaluated during constant phase? Also, I think there may be a bug with literal value parse node locations, I should be able to point at the position of `arg_ids[0]` but it's missing a line number so I point at `loc` instead.
This commit is contained in:
@@ -302,6 +302,19 @@ static auto PerformAggregateIndex(Context& context, SemIR::Inst inst)
|
||||
return context.constant_values().Get(elements[index_val.getZExtValue()]);
|
||||
}
|
||||
|
||||
// Enforces that the bit width is 64 for a float.
|
||||
static auto ValidateFloatBitWidth(Context& context, SemIRLoc loc,
|
||||
SemIR::InstId inst_id) -> bool {
|
||||
auto inst = context.insts().GetAs<SemIR::IntLiteral>(inst_id);
|
||||
if (context.ints().Get(inst.int_id) == 64) {
|
||||
return true;
|
||||
}
|
||||
|
||||
CARBON_DIAGNOSTIC(CompileTimeFloatBitWidth, Error, "Bit width must be 64.");
|
||||
context.emitter().Emit(loc, CompileTimeFloatBitWidth);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Issues a diagnostic for a compile-time division by zero.
|
||||
static auto DiagnoseDivisionByZero(Context& context, SemIRLoc loc) -> void {
|
||||
CARBON_DIAGNOSTIC(CompileTimeDivisionByZero, Error, "Division by zero.");
|
||||
@@ -497,6 +510,25 @@ static auto PerformBuiltinCall(Context& context, SemIRLoc loc, SemIR::Call call,
|
||||
case SemIR::BuiltinFunctionKind::None:
|
||||
CARBON_FATAL() << "Not a builtin function.";
|
||||
|
||||
case SemIR::BuiltinFunctionKind::IntMakeType32: {
|
||||
return context.constant_values().Get(SemIR::InstId::BuiltinIntType);
|
||||
}
|
||||
|
||||
case SemIR::BuiltinFunctionKind::FloatMakeType: {
|
||||
// TODO: Support a symbolic constant width.
|
||||
if (phase != Phase::Template) {
|
||||
break;
|
||||
}
|
||||
if (!ValidateFloatBitWidth(context, loc, arg_ids[0])) {
|
||||
return SemIR::ConstantId::Error;
|
||||
}
|
||||
return context.constant_values().Get(SemIR::InstId::BuiltinFloatType);
|
||||
}
|
||||
|
||||
case SemIR::BuiltinFunctionKind::BoolMakeType: {
|
||||
return context.constant_values().Get(SemIR::InstId::BuiltinBoolType);
|
||||
}
|
||||
|
||||
// Unary integer -> integer operations.
|
||||
case SemIR::BuiltinFunctionKind::IntNegate:
|
||||
case SemIR::BuiltinFunctionKind::IntComplement: {
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
// 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
|
||||
//
|
||||
// AUTOUPDATE
|
||||
|
||||
// --- types.carbon
|
||||
|
||||
library "types" api;
|
||||
|
||||
fn Bool() -> type = "bool.make_type";
|
||||
|
||||
// --- use_types.carbon
|
||||
|
||||
library "uses_types" api;
|
||||
|
||||
import library "types";
|
||||
|
||||
var b: Bool() = false;
|
||||
|
||||
// CHECK:STDOUT: --- types.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .Bool = %Bool
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Bool: <function> = fn_decl @Bool [template] {
|
||||
// CHECK:STDOUT: %return.var: ref type = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- use_types.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %.1: bool = bool_literal false [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .Bool = %import_ref
|
||||
// CHECK:STDOUT: .b = %b
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %import_ref: <function> = import_ref ir2, inst+2, loc_11 [template = imports.%Bool]
|
||||
// CHECK:STDOUT: %Bool.ref: <function> = name_ref Bool, %import_ref [template = imports.%Bool]
|
||||
// CHECK:STDOUT: %.loc6_12.1: init type = call %Bool.ref() [template = bool]
|
||||
// CHECK:STDOUT: %.loc6_13: type = value_of_initializer %.loc6_12.1 [template = bool]
|
||||
// CHECK:STDOUT: %.loc6_12.2: type = converted %.loc6_12.1, %.loc6_13 [template = bool]
|
||||
// CHECK:STDOUT: %b.var: ref bool = var b
|
||||
// CHECK:STDOUT: %b: ref bool = bind_name b, %b.var
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @__global_init() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc6: bool = bool_literal false [template = constants.%.1]
|
||||
// CHECK:STDOUT: assign file.%b.var, %.loc6
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -0,0 +1,147 @@
|
||||
// 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
|
||||
//
|
||||
// AUTOUPDATE
|
||||
|
||||
// --- types.carbon
|
||||
|
||||
library "types" api;
|
||||
|
||||
fn Float(size: i32) -> type = "float.make_type";
|
||||
|
||||
// --- use_types.carbon
|
||||
|
||||
library "uses_types" api;
|
||||
|
||||
import library "types";
|
||||
|
||||
var f: Float(64) = 0.0;
|
||||
|
||||
fn GetFloat(dyn_size: i32) -> type {
|
||||
return Float(dyn_size);
|
||||
}
|
||||
|
||||
// --- fail_invalid_size.carbon
|
||||
|
||||
library "invalid_size" api;
|
||||
|
||||
import library "types";
|
||||
|
||||
// CHECK:STDERR: fail_invalid_size.carbon:[[@LINE+4]]:20: ERROR: Bit width must be 64.
|
||||
// CHECK:STDERR: var invalid_float: Float(32);
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR:
|
||||
var invalid_float: Float(32);
|
||||
|
||||
var dyn_size: i32 = 64;
|
||||
// CHECK:STDERR: fail_invalid_size.carbon:[[@LINE+3]]:10: ERROR: Cannot evaluate type expression.
|
||||
// CHECK:STDERR: var dyn: Float(dyn_size);
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~
|
||||
var dyn: Float(dyn_size);
|
||||
|
||||
// CHECK:STDOUT: --- types.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .Float = %Float
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Float: <function> = fn_decl @Float [template] {
|
||||
// CHECK:STDOUT: %size.loc4_10.1: i32 = param size
|
||||
// CHECK:STDOUT: @Float.%size: i32 = bind_name size, %size.loc4_10.1
|
||||
// CHECK:STDOUT: %return.var: ref type = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- use_types.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %.1: i32 = int_literal 64 [template]
|
||||
// CHECK:STDOUT: %.2: f64 = real_literal 0e-1 [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .Float = %import_ref
|
||||
// CHECK:STDOUT: .f = %f
|
||||
// CHECK:STDOUT: .GetFloat = %GetFloat
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %import_ref: <function> = import_ref ir2, inst+4, loc_11 [template = imports.%Float]
|
||||
// CHECK:STDOUT: %Float.ref: <function> = name_ref Float, %import_ref [template = imports.%Float]
|
||||
// CHECK:STDOUT: %.loc6_14: i32 = int_literal 64 [template = constants.%.1]
|
||||
// CHECK:STDOUT: %.loc6_13.1: init type = call %Float.ref(%.loc6_14) [template = f64]
|
||||
// CHECK:STDOUT: %.loc6_16: type = value_of_initializer %.loc6_13.1 [template = f64]
|
||||
// CHECK:STDOUT: %.loc6_13.2: type = converted %.loc6_13.1, %.loc6_16 [template = f64]
|
||||
// CHECK:STDOUT: %f.var: ref f64 = var f
|
||||
// CHECK:STDOUT: %f: ref f64 = bind_name f, %f.var
|
||||
// CHECK:STDOUT: %GetFloat: <function> = fn_decl @GetFloat [template] {
|
||||
// CHECK:STDOUT: %dyn_size.loc8_13.1: i32 = param dyn_size
|
||||
// CHECK:STDOUT: @GetFloat.%dyn_size: i32 = bind_name dyn_size, %dyn_size.loc8_13.1
|
||||
// CHECK:STDOUT: %return.var: ref type = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @GetFloat(%dyn_size: i32) -> type {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Float.ref: <function> = name_ref Float, file.%import_ref [template = imports.%Float]
|
||||
// CHECK:STDOUT: %dyn_size.ref: i32 = name_ref dyn_size, %dyn_size
|
||||
// CHECK:STDOUT: %.loc9_15.1: init type = call %Float.ref(%dyn_size.ref)
|
||||
// CHECK:STDOUT: %.loc9_25: type = value_of_initializer %.loc9_15.1
|
||||
// CHECK:STDOUT: %.loc9_15.2: type = converted %.loc9_15.1, %.loc9_25
|
||||
// CHECK:STDOUT: return %.loc9_15.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @__global_init() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc6: f64 = real_literal 0e-1 [template = constants.%.2]
|
||||
// CHECK:STDOUT: assign file.%f.var, %.loc6
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_invalid_size.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %.1: i32 = int_literal 32 [template]
|
||||
// CHECK:STDOUT: %.2: i32 = int_literal 64 [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .Float = %import_ref
|
||||
// CHECK:STDOUT: .invalid_float = %invalid_float
|
||||
// CHECK:STDOUT: .dyn_size = %dyn_size
|
||||
// CHECK:STDOUT: .dyn = %dyn
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %import_ref: <function> = import_ref ir2, inst+4, loc_11 [template = imports.%Float]
|
||||
// CHECK:STDOUT: %Float.ref.loc10: <function> = name_ref Float, %import_ref [template = imports.%Float]
|
||||
// CHECK:STDOUT: %.loc10_26: i32 = int_literal 32 [template = constants.%.1]
|
||||
// CHECK:STDOUT: %.loc10_25.1: init type = call %Float.ref.loc10(%.loc10_26) [template = <error>]
|
||||
// CHECK:STDOUT: %.loc10_28: type = value_of_initializer %.loc10_25.1 [template = <error>]
|
||||
// CHECK:STDOUT: %.loc10_25.2: type = converted %.loc10_25.1, %.loc10_28 [template = <error>]
|
||||
// CHECK:STDOUT: %invalid_float.var: ref <error> = var invalid_float
|
||||
// CHECK:STDOUT: %invalid_float: ref <error> = bind_name invalid_float, %invalid_float.var
|
||||
// CHECK:STDOUT: %dyn_size.var: ref i32 = var dyn_size
|
||||
// CHECK:STDOUT: %dyn_size: ref i32 = bind_name dyn_size, %dyn_size.var
|
||||
// CHECK:STDOUT: %Float.ref.loc16: <function> = name_ref Float, %import_ref [template = imports.%Float]
|
||||
// CHECK:STDOUT: %dyn_size.ref: ref i32 = name_ref dyn_size, %dyn_size
|
||||
// CHECK:STDOUT: %.loc16_16: i32 = bind_value %dyn_size.ref
|
||||
// CHECK:STDOUT: %.loc16_15.1: init type = call %Float.ref.loc16(%.loc16_16)
|
||||
// CHECK:STDOUT: %.loc16_24: type = value_of_initializer %.loc16_15.1
|
||||
// CHECK:STDOUT: %.loc16_15.2: type = converted %.loc16_15.1, %.loc16_24
|
||||
// CHECK:STDOUT: %dyn.var: ref <error> = var dyn
|
||||
// CHECK:STDOUT: %dyn: ref <error> = bind_name dyn, %dyn.var
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @__global_init() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc12: i32 = int_literal 64 [template = constants.%.2]
|
||||
// CHECK:STDOUT: assign file.%dyn_size.var, %.loc12
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -0,0 +1,62 @@
|
||||
// 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
|
||||
//
|
||||
// AUTOUPDATE
|
||||
|
||||
// --- types.carbon
|
||||
|
||||
library "types" api;
|
||||
|
||||
fn Int() -> type = "int.make_type_32";
|
||||
|
||||
// --- use_types.carbon
|
||||
|
||||
library "uses_types" api;
|
||||
|
||||
import library "types";
|
||||
|
||||
var i: Int() = 0;
|
||||
|
||||
// CHECK:STDOUT: --- types.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .Int = %Int
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Int: <function> = fn_decl @Int [template] {
|
||||
// CHECK:STDOUT: %return.var: ref type = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Int() -> type = "int.make_type_32";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- use_types.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %.1: i32 = int_literal 0 [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .Int = %import_ref
|
||||
// CHECK:STDOUT: .i = %i
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %import_ref: <function> = import_ref ir2, inst+2, loc_11 [template = imports.%Int]
|
||||
// CHECK:STDOUT: %Int.ref: <function> = name_ref Int, %import_ref [template = imports.%Int]
|
||||
// CHECK:STDOUT: %.loc6_11.1: init type = call %Int.ref() [template = i32]
|
||||
// CHECK:STDOUT: %.loc6_12: type = value_of_initializer %.loc6_11.1 [template = i32]
|
||||
// CHECK:STDOUT: %.loc6_11.2: type = converted %.loc6_11.1, %.loc6_12 [template = i32]
|
||||
// CHECK:STDOUT: %i.var: ref i32 = var i
|
||||
// CHECK:STDOUT: %i: ref i32 = bind_name i, %i.var
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Int() -> type = "int.make_type_32";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @__global_init() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc6: i32 = int_literal 0 [template = constants.%.1]
|
||||
// CHECK:STDOUT: assign file.%i.var, %.loc6
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -247,6 +247,7 @@ CARBON_DIAGNOSTIC_KIND(BreakOutsideLoop)
|
||||
CARBON_DIAGNOSTIC_KIND(CompileTimeDivisionByZero)
|
||||
CARBON_DIAGNOSTIC_KIND(CompileTimeIntegerOverflow)
|
||||
CARBON_DIAGNOSTIC_KIND(CompileTimeIntegerNegateOverflow)
|
||||
CARBON_DIAGNOSTIC_KIND(CompileTimeFloatBitWidth)
|
||||
CARBON_DIAGNOSTIC_KIND(CompileTimeShiftOutOfRange)
|
||||
CARBON_DIAGNOSTIC_KIND(ContinueOutsideLoop)
|
||||
CARBON_DIAGNOSTIC_KIND(CopyOfUncopyableType)
|
||||
|
||||
@@ -209,6 +209,12 @@ static auto HandleBuiltinCall(FunctionContext& context, SemIR::InstId inst_id,
|
||||
case SemIR::BuiltinFunctionKind::None:
|
||||
CARBON_FATAL() << "No callee in function call.";
|
||||
|
||||
case SemIR::BuiltinFunctionKind::BoolMakeType:
|
||||
case SemIR::BuiltinFunctionKind::FloatMakeType:
|
||||
case SemIR::BuiltinFunctionKind::IntMakeType32:
|
||||
context.SetLocal(inst_id, context.GetTypeAsValue());
|
||||
return;
|
||||
|
||||
case SemIR::BuiltinFunctionKind::IntNegate: {
|
||||
// Lower `-x` as `0 - x`.
|
||||
auto* operand = context.GetValue(arg_ids[0]);
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
// 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
|
||||
//
|
||||
// AUTOUPDATE
|
||||
|
||||
fn Int() -> type = "int.make_type_32";
|
||||
fn Float(size: i32) -> type = "float.make_type";
|
||||
fn Bool() -> type = "bool.make_type";
|
||||
|
||||
fn F() {
|
||||
var i: Int() = 0;
|
||||
var f: Float(64) = 0.0;
|
||||
var b: Bool() = false;
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: ; ModuleID = 'types.carbon'
|
||||
// CHECK:STDOUT: source_filename = "types.carbon"
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: define void @F() {
|
||||
// CHECK:STDOUT: %i = alloca i32, align 4
|
||||
// CHECK:STDOUT: store i32 0, ptr %i, align 4
|
||||
// CHECK:STDOUT: %f = alloca double, align 8
|
||||
// CHECK:STDOUT: store double 0.000000e+00, ptr %f, align 8
|
||||
// CHECK:STDOUT: %b = alloca i1, align 1
|
||||
// CHECK:STDOUT: store i1 false, ptr %b, align 1
|
||||
// CHECK:STDOUT: ret void
|
||||
// CHECK:STDOUT: }
|
||||
@@ -68,6 +68,10 @@ using Bool = BuiltinType<InstId::BuiltinBoolType>;
|
||||
// TODO: This only matches i32 for now. Support iN for all N, and the
|
||||
// Core.BigInt type we use to implement for integer literals.
|
||||
using AnyInt = BuiltinType<InstId::BuiltinIntType>;
|
||||
|
||||
// Constraint that requires the type to be the type type.
|
||||
using Type = BuiltinType<InstId::BuiltinTypeType>;
|
||||
|
||||
} // namespace
|
||||
|
||||
// Validates that this builtin has a signature matching the specified signature.
|
||||
@@ -132,6 +136,19 @@ using IntU = TypeParam<1, AnyInt>;
|
||||
// Not a builtin function.
|
||||
constexpr BuiltinInfo None = {"", nullptr};
|
||||
|
||||
// Returns the `i32` type. Doesn't take a bit size because we need an integer
|
||||
// type as a basis for that.
|
||||
constexpr BuiltinInfo IntMakeType32 = {"int.make_type_32",
|
||||
ValidateSignature<auto()->Type>};
|
||||
|
||||
// Returns float types, such as `f64`. Currently only supports `f64`.
|
||||
constexpr BuiltinInfo FloatMakeType = {"float.make_type",
|
||||
ValidateSignature<auto(IntT)->Type>};
|
||||
|
||||
// Returns the `bool` type.
|
||||
constexpr BuiltinInfo BoolMakeType = {"bool.make_type",
|
||||
ValidateSignature<auto()->Type>};
|
||||
|
||||
// "int.negate": integer negation.
|
||||
constexpr BuiltinInfo IntNegate = {"int.negate",
|
||||
ValidateSignature<auto(IntT)->IntT>};
|
||||
|
||||
@@ -18,6 +18,11 @@
|
||||
|
||||
CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(None)
|
||||
|
||||
// Type factories.
|
||||
CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntMakeType32)
|
||||
CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(FloatMakeType)
|
||||
CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(BoolMakeType)
|
||||
|
||||
// Integer arithmetic.
|
||||
CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntNegate)
|
||||
CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntAdd)
|
||||
|
||||
Reference in New Issue
Block a user