Commit Graph
18 Commits
Author SHA1 Message Date
Jon Ross-Perkins 295c8eb97f Change Namespace formatting to use the scope's name. (#3782)
This change only affects the generated IR, but I think it's cleaning up
an existing issue with namespace name printing.
2024-03-14 21:12:26 +00:00
Richard Smith 5665660677 Remove special-case formatting for class and interface LHS. (#3744)
These now have a type_id, so we can use the normal formatting.
2024-03-06 23:32:33 +00:00
Richard Smith 064123d93f If a SemIR instruction has a braced block and a constant value, print the constant value first. (#3734) 2024-02-29 23:51:32 +00:00
Richard Smith 67d5446b03 Add Self to the name scope for a class. (#3736)
Rather than just adding `Self` to the lexical scope, add it to the
class's name scope so that it is visible in later lexical scopes for the
same class -- in particular, for out-of-line definitions of members.
Also switch some tests in `check/testdata/class` over to making
idiomatic use of `Self` both inside a class and out-of-line, now that it
works more consistently.

Note that this does not permit using `Class.Self`, but only because we
don't yet support keyword names after `.` at all. If that changed, one
could use `Class.Self` to redundantly refer to `Class`. Whether we allow
that is left to a future decision.
2024-02-29 21:33:47 +00:00
Richard Smith 5543602a50 Make namespace formatting more consistent with other declaration block instructions. (#3732)
List names vertically rather than horizontally.
2024-02-28 22:20:37 +00:00
Richard Smith 5f4e6c768a Format the decl block for a declaration as a trailing block. (#3731)
Previously we used the default inst block formatting, which writes out a
parenthesized list of references, which would always be 'unexpected
instref's because nothing else prints the instructions in the decl
block.

In addition, track the decl block for function declarations like we do
for other kinds of declaration. This means that the parameter
declarations for a function are now properly rendered into the formatted
IR. Note that this adds a lot of verbosity to `function_decl`, but it
does accurately reflect the IR, and we'll probably want this information
to be printed once we start supporting more complex generic function
declarations.

This removes almost all the 'unexpected instref's in our formatted
output. There are remaining cases when a declarative scope contains
multiple blocks, where we only track one of those blocks. That happens
when there is control flow within declarative scopes, and for error
recovery when a class or interface or similar is defined more than once.

As requested in #3730.
2024-02-28 21:28:59 +00:00
Jon Ross-Perkins 364ea5d3f2 Assign a constant to ClassDecl/InterfaceDecl for name references. (#3722)
By adding a constant to ClassDecl/InterfaceDecl, we're able to remove
name reference special-casing. Use TryEvalInst on the Decl to generate
the Type. For ClassDecl, then use the generated constant for
self_type_id.
2024-02-24 00:00:18 +00:00
Gıyaseddin Tanrıkulu bdff7ccf28 Add GlobalInit to blocks to emit initialization instructions for globals (#3687)
`GlobalInit` block is now static block within a `SemIR` which will be
used to emit initialization instructions for variables in the `Package`
scope.

inst_block_stack now has additional methods to handle `GlobalInit` block
separately, this block can be popped without being finalized allowing to
accumulate between all instances of variables.

At the end of the `check` phase, if this block is not empty , the
function `__global_init` will be added with this block being inserted
into it.

This block is pushed to `inst_block_scope` at the end `BindName`,
allowing instruction to be emitted into it, then popped at the semicolon
(VariableDecl).

This significantly changes the `SemIR` output, that's why this commit
updates a lot of the test cases.
2024-02-09 16:21:57 +00:00
Jon Ross-Perkins 91f0c23124 Provide diagnostic locations for imported namespaces. (#3640)
Building on #3636 which handles the general import case, add special
casing for namespaces. Namespaces can be combined cross-IR, so it's a
little more complex.

The implementation adds import_id to the Namespace instruction as a
reference to find the original using the normal structure. This is
achieved by moving the name_id to NameScope to free up space.

---

I considered a few alternatives...

I considered adding import_id to NameScope, but:

1. It's more consistent with things such as Function or Class that
provide name_id on the info object rather than the instruction.
2. I thought it more likely that there would be more NameScope cases
that might want a name_id rather than the import_id, since ImportRef
will typically be used.

I considered putting the import source (cross-ref IR id + inst id) on
the NameScope versus a separate ImportRef, which seems like the
strongest argument towards the NameScope approach because it removes an
instruction. That just felt inconsistent though, and the overhead of
instruction-per-imported-namespace should be low (theoretically few
namespaces should be used). Plus I feel a bit odd adding two
generally-unused ids to NameScope.

A specialized Namespace structure could also have been created to store
the import_id, but that would add an indirection to the NameScope.
2024-01-24 18:00:32 +00:00
Richard Smith b138c90c9e Use constant evaluation to determine the identity of types. (#3617)
Remove the type canonicalization mechanism and instead rely on constant
canonicalization to deduplicate types.

Rename the `Canonicalize*Type` functions to reflect that they're no
longer performing canonicalization. Switch code that creates types due
to semantic checking, rather than due to source syntax, to directly
create type constants through evaluation rather than creating an
instruction and evaluating it to produce a separate constant
representation.

The mapping from `const (const T)` that was previously performed by type
canonicalization is now implemented in expression evaluation instead.

The value `<error>` is now treated as a constant value, with a special
property that an instruction involving `<error>` that could possibly be
constant evaluates to `<error>`. This helps avoid producing follow-on
errors when an error occurs as a subexpression of an expression, such as
a type, that is intended to be constant.
2024-01-19 00:47:37 +00:00
Richard Smith 29c294880d Deduplicate and canonicalize all constants. (#3611)
Rather than producing multiple constants with the same value, fold all
instances of a given constant to the same constant instruction.

A future PR will use this to replace the current type canonicalization
system.
2024-01-18 21:42:19 +00:00
Richard Smith b7c21a7fa7 Add constant evaluation for namespace expressions. (#3612) 2024-01-17 21:12:25 +00:00
Richard Smith d712bf12a6 Remove parse nodes from constants. (#3599)
These instructions are intended to be shared across all uses and so
don't have a meaningful location. So far, only type constants are
shared.
2024-01-13 04:52:25 +00:00
Richard SmithandChandler Carruth a3154356f0 Distinguish between template constants and symbolic constants. (#3595)
This is accomplished by tracking an extra bit on the ID we store in the
constant values table, and propagating that from subexpressions to the
enclosing expression. This extra bit is not yet computed correctly for
types; that will be addressed in later PRs.

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2024-01-12 02:56:22 +00:00
Richard Smith 7553d864e1 Very basic support for constant evaluation of expressions. (#3581)
Form a side table with constant values for each instruction. Evaluation
is only supported for a few very simple kinds of instruction for now.
This is not observable outside of the SemIR output, because nothing
depends on expressions having a constant value phase yet.
2024-01-11 23:12:58 +00:00
Jon Ross-PerkinsandRichard Smith cad4605dad Add imports of enclosing scopes. (#3575)
Namespaces are copied, which means also adding their name to the
underlying instruction. It happened not to be done previously; the name
was only in name lookup.

Since the only import supported right now is the default import,
functionality is limited; in the future I'll need to deal with namespace
vs package conflicts.

Tests of namespace imports are under "namespace" -- I figured this would
be best for scaling as more instructions get support.

This also improves some debugging-related output that I was trying to
use while trying to build the support.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-01-10 17:36:50 +00:00
Jacob Schneider 6419568142 Fully underline parse nodes in diagnostics. (#3442)
Another incremental change to diagnostic formatting. I simply recurse
over all the tokens in the subtree of a parse node and construct a
`DiagnosticLocation` that covers all of the tokens.

I believe it's nicer for the user to be directed at the entire chunk of
source where the error is occurring rather then just pointing at the
bracketing/terminator tokens, but let me know if you all agree.
2023-12-13 18:43:19 +00:00
Jon Ross-Perkins 30155dbb72 Add support for 'package' in expressions. (#3445)
This creates a namespace for `package` scope.

It looks like names of class_decls in namespaces lead to an unexpected
instref. This is already true, as best as I can tell. I'm not sure if
there's a preferred approach to address that, so I've left a TODO for
now.
2023-12-04 21:05:41 +00:00