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:
Jon Ross-Perkins
2024-04-04 23:47:06 +00:00
committed by GitHub
parent f44643f080
commit 6889aff49a
9 changed files with 360 additions and 0 deletions
+32
View File
@@ -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: {