This includes being able to define a class that was previously
forward-declared, and being able to define a member function out-of-line
that was previously declared inside a class.
No support for fields or methods yet, and a class definition doesn't yet
cause the class to be treated as a complete type.
---------
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Track the callee expression in full, instead of only tracking the
callee's FunctionId. This results in the `name_reference` denoting the
function actually being used.
Lowering now propagates a `llvm::Function*` as the value associated with
expressions of type `<function>`.
We were not creating `NameReference` node for names produced by member
access into a namespace, such as the second name in
`Namespace.Function`, which caused lowering of calls to such names to
fail. This is now fixed, but the resulting `NameReference` node only
refers to the name and the lookup result, not to the `Namespace.`
qualifier. We'll need to decide how to fit a third operand into that
node (perhaps we can stop storing the `name_id`, since it can be derived
from the lookup result) but for now the qualifier is not tracked.
Bug found by fuzzing. Problem was untyped SemIR nodes had an invalid
type id, which was retrieved by `HandlePrefixOperator` and then passed
to `context.GetUnqualifiedType`, ultimately performing an invalid access
in `semantics_ir_->GetNode`.
We prefer to make a placeholder type for functions and namespaces to
remove the need for checking for the untyped case everywhere. Eventually
functions will have their own types, but this approach will be needed
for namespaces (and perhaps other non-first-class entities like unbound
methods and interface members) long term.
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This is shorter, more closely connected to code using the typed node
types, and avoids using the ambiguous word `Node` in places referring to
typed `SemIR` nodes.
Replace `SemIR::Node::GetAsFoo` and `SemIR::Node::Foo::Make` with
`SemIR::Foo` class that represents a particular kind of node, with named
fields.
Rename `SemIR::IntegerLiteral` and `SemIR::RealLiteral` to
`IntegerValue` / `RealValue` to better reflect their purpose and avoid a
name collision with the corresponding `SemIR` node kinds.
Remove `NodeKind::Invalid` and the `SemIR::Node` default constructor
entirely, as they were not used for anything.
Also add `name_reference_untyped` for references to non-first-class
names without types, which currently covers namespaces and functions.
This improves the fidelity of the SemIR representation, and fixes some
issues where we would use the wrong location for nodes and diagnostics
downstream of a name reference.
We're still missing a representation for dotted name expressions, such
as `Namespace.Function`, and we don't use the `untyped` node as an
operand of any other node yet.
Combine the initialization, implicit conversion, and value category
conversion functions into a single function.
This substantially reduces the duplication between these steps, and
ensures that we support the same set of conversions in all these
contexts. This also fixes some issues where we would not use the proper
value representation for tuples and structs after performing implicit
conversions.
This implements initializing expression semantics for structs and
tuples, following #2006 and discussions since.
Tuple and (and analogously, struct) literals are treated as having a
mixed expression category that is later resolved based on how the
literal is used, as either a tuple initializer or a tuple value, at
which point we create a `TupleInit` or `TupleValue` that represents the
formation of the tuple initializer or tuple value from the tuple
literal.
There's quite a lot of TODOs here, and the SemIR representation is still
not quite right, but this seems like a good place to checkpoint some
incremental progress.
Continuing along with #3070. Note this is just a file rename, with BUILD
edits; every file previously in semantics/ should show as moved (except
maybe BUILDs, which split).