Commit Graph
132 Commits
Author SHA1 Message Date
Jon Ross-Perkins f70221c040 Fix deduction crash for function with missing parameters. (#4461)
This is because `var x:! () = ();` modifies the binding index, which
causes `A` to be generic, which causes the params to be used, which
crashes. There may be another issue to fix here so that the invalid
binding doesn't modify the binding index, but at least
`param_patterns_id` should probably be set consistently with
`params_id`.
2024-10-31 17:12:49 +00:00
Geoff RomerandJon Ross-Perkins e20e8bfbea Consolidate caller match in one function call (#4446)
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-10-29 23:31:50 +00:00
Geoff Romer b67d03126e Separate inst kind for out params (#4442) 2024-10-24 15:22:32 +00:00
Geoff Romer 9266f867f9 Model the return slot as an output parameter (#4432)
Also fix `Param` insts to have meaningful names in pretty-printing, to
help clarify relationship with return slot.
2024-10-23 16:53:34 +00:00
Geoff Romer 223c5cb04b Restructure handling of runtime parameters (#4422)
- Generate runtime indices as part of pattern matching, rather than as a
separate postprocessing/rewriting step.
- In contexts where runtime parameters aren't permitted, avoid emitting
insts for them to begin with, rather than trying to detect the problem
and rewrite the IR to remove them later on.
2024-10-21 19:53:38 +00:00
David BlaikieandRichard Smith dfed743de2 Add vtable pointers to class layout (#4407)
A small step to virtual functions - adding vtable pointers to the
layout, but not initializing or otherwise using them at this stage.

A few open design questions I'd love feedback on:

* Is this the right/good enough SemIR representation for now? This patch
adds a `is_dynamic` attribute to `SemIR::Class` and populates/flags it
based on the flag of the base class, or if any virtual function is
declared in the class (or, at least that's my intent). Some other
options include:
* Each `Class` could store a `ClassId` (or `TypeId`?) of the (possibly
indirect, possibly self) base class that is the first one that is
dynamic/has a vtable pointer
* Could make the property narrower, like `has vtable pointer` and have
it `true` only on the type that introduces the vtable - then derived
classes would have to walk their base classes to check if they're the
one that needs to define the vtable pointer or not
* Should the vtable be the first element in the type? If there's a
non-dynamic base type, we could have a layout that's `{<non-dynamic base
type>, vtable ptr, <derived members>}`? Derived types would still be
able to uniquely identify where their vtable pointer is just fine... -
and the vtable pointer is, in a sense, a member of that intermediate
type, so it does seem a bit strange to force it to the front - but I
guess it's probably more efficient in some ways?

Open to any other suggestions/advice/thoughts on the direction, etc.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-10-16 21:26:17 +00:00
Geoff RomerandJon Ross-Perkins 9d942f4633 Generate parameter pattern-match IR from pattern IR (#4388)
Also propagate the pattern IR along with the pattern-match IR, and use
it where appropriate.

Strictly speaking, some parts of the pattern-match IR are allocated
eagerly, while traversing the pattern's parse tree, but they still
aren't actually emitted until we traverse the associated pattern insts.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-10-16 19:15:29 +00:00
Richard Smithandjosh11b b274622228 Improve infrastructure for formatting types in diagnostics. (#4374)
Instead of stringifying types in the caller in some cases, add new types
to represent:

- `InstIdAsType`: an `InstId` diagnostic argument that represents a type
expression that should be included in the diagnostic
- `InstIdAsTypeOfExpr`: an `InstId` diagnostic argument that represents
an expression whose type should be included in the diagnostic

For these cases, we can produce more user-friendly descriptions of a
type than we can with a canonicalized `TypeId`. Add comments to
discourage using `TypeId` diagnostic arguments when one of the above can
be used, and move over existing uses where it's straightforward to do
so.

Move type stringification code to its own files and out of `SemIR::File`
to make `File` smaller and to further discourage the direct use of the
stringification logic.

Also update type printing to include the `` ` `` delimiters surrounding
the type. The intent is that we will eventually want to include other
information when formatting a type, like Clang does when printing a
typedef (`'string' (aka 'std::basic_string<char>')`), and such
formatting requires that the diagnostic machinery produces the `` ` ``s
itself.

There are a couple of cases where we really want to format valid Carbon
type syntax directly into a diagnostic, rather than an `aka` or similar,
because the diagnostic text includes part of the type itself, for
example: ``"consider using `partial {0}`"``. For such cases, a `Raw`
form of the diagnostic argument types is added: `TypeIdAsRawType` and
`InstIdAsRawType`. In principle we could instead use ``"consider using
`partial {0:raw}`"``, but our diagnostic machinery isn't set up for
that.

---------

Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
2024-10-07 22:55:26 +00:00
82937e1a3c Change how to get info for a parameter (#4366)
Updates `SemIR::Function::GetParamFromParamRefId` to return more
information in the form of a new `ParamInfo` struct. This struct has a
method for getting the `NameId` from the name binding instruction. The
callers previously got it from the `Param` instruction, but the plan is
for that instruction to no longer be associated with a name.

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
Co-authored-by: Geoff Romer <gromer@google.com>
2024-10-04 16:30:00 +00:00
David Blaikie eab5dd6112 Reject abstract function definitions (#4350)
Not sure about error recovery options - can/should we drop the
definition as a means of recovery when building the SemIR? I guess
probably not, so I guess this change is about right.

Phrasing of the error message I'm certainly open to.
2024-10-03 22:50:46 +00:00
josh11bandJosh L d6d70bf80d Handle runtime implicit parameters, and self outside of methods (#4361)
Closes #4356, #4359

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
2024-10-03 20:24:28 +00:00
Richard Smith 4ca711c175 When converting an expression to type type, retain the resulting instruction as well as the TypeId. (#4355)
The `TypeId` is lossy, as it represents only the canonical type, and not
the specific computation that produced it.
2024-10-01 01:49:39 +00:00
Geoff RomerandJon Ross-Perkins dc32aa2690 Initial support for binding patterns in SemIR (#4221)
Introduces the `BindingPattern` and `SymbolicBindingPattern` insts, and
a separate stack of pattern blocks that they are emitted into. The
intent is to generate the corresponding pattern-matching insts (like
`BindName`) from them in a separate pass, but that is deferred to future
PRs.

See
[here](https://docs.google.com/document/d/1U_vQH17V893J9aF1LJXUnFYBNSs2MjKl4bJPaWCB2zo/edit?usp=sharing&resourcekey=0-w0xGYZ0An31Kpz-wvzSXwQ)
for the design this is based on, but note that during review we have
chosen to deviate from that design by putting the patterns in separate
blocks, and omitting the "forward references" from a `BindingPattern` to
its corresponding `BindName`. This in turn necessitates having separate
inst kinds for symbolic and non-symbolic binding patterns.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-09-25 19:12:58 +00:00
Jon Ross-PerkinsandRichard Smith e7aebbe581 Update basic diagnostic capitalization/punctuation (#4328)
This is a primarily automated change:

- Search & replace for capitalization
-
`(CARBON_DIAGNOSTIC\((?:\n\s+)?\w+,(?:\n\s+)?\s\w+,(?:\n\s+)?\s")([A-Z])`
    - `$1\L$2`
- Search & replace for period
-
`(CARBON_DIAGNOSTIC\((?:\n\s+)?\w+,(?:\n\s+)?\s\w+,(?:\n\s+)?\s"(?:[^)]|\n)+)\.("[,)])`
    - `$1$2`
- Limited search & replace for `ERROR: ` -> `error: ` in streamed things
- Leaving a TODO for command_line because there's more cleanup that can
be done there
- Modify diagnostic_consumer.cpp
    - ERROR -> error
    - WARNING -> warning

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-09-19 21:32:53 +00:00
Richard Smith 0354efa1fc Rework how we check calls to support deduced implicit parameters (#4302)
Instead of the `call` instruction having a block with one argument per
explicit argument, preceded optionally by `self` and followed optionally
by a return slot, change the `call` to store only the *runtime*
arguments. Store an index on the runtime parameters to make it easier to
determine the correspondence between arguments and parameters in a call.
Compile-time parameters, whether implicit or explicit, are no longer
included in the call argument list. Instead, they're tracked only in the
`specific_id` on the callee.

For calls to generic classes and generic interfaces, it no longer makes
sense to form a `call` instruction, given that the entirety of the
result is determined by the `specific_id`, which is now formed when
checking the call. Instead, the `call` instruction now only models
function calls, and not calls to other kinds of parameterized entity
names, and we create a `class_type` or `interface_type` instead of a
`call` instruction to model these kinds of calls. Notionally the model
here is that we're following the #3720 approach for calls, but for now
we inline the `Call.Op` function when forming SemIR.

We now also track the enclosing specific for a generic class or generic
interface that appears within an enclosing generic. This is necessary in
order for deduction of the inner generic parameters to not get confused
by the outer generic parameters being absent.

In order to not regress diagnostics, the template argument deduction
mechanism has been extended to specify the name of the parameter we're
deducing against when possible, and call arity mismatch errors are now
diagnosed before performing deduction rather than afterwards.
2024-09-13 21:31:43 +00:00
David BlaikieandJon Ross-Perkins b8f61a712e Add KeywordModifierSet helper for conversion to (likely SemIR) enums (#4290)
(based on
https://github.com/carbon-language/carbon-lang/pull/4272#discussion_r1751001345)

Could haggle over the name "ToEnum" probably avoids the debate over
"enumeration" (the type being returned) v "enumerator" (the value being
returned)

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-09-10 22:01:21 +00:00
David BlaikieandJon Ross-Perkins 5806d8385d Add SemIR support for virtual functions (#4272)
I guess this technically would also allow code to pass check that hasn't
before, and that isn't covered by tests (since it's masked by other
failures in the tests that already test this functionality) - should I
add another test/add some code to a valid test case?

Also, this'll miscompile in lowering, since there's no support there yet
- should I do anything about that to make lowering fail in some way? Or
is it acceptable that some things just silently mis-lower? (I could add
a currently-miscompiling test case too, to demonstrate this? (not sure
if the autogenerated tests leave space for comments that would explain
that the currently-tested behavior is incorrect?))

Is the addition to EntityWithParamsBase suitable? of course not all
functions can be virtual, so it's a wasted bit at the moment for all
those cases (though it's free, since it's bitpacked - but as we want to
add more bits in there it might not be a scalable solution)?

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-09-10 18:16:59 +00:00
Jon Ross-PerkinsandRichard Smith bed5fdcbbe Fix indirect import handling for functions. (#4258)
The particular test this focused on is indirect_two_file in
toolchain/check/testdata/function/definition/no_prelude/extern_library.carbon.

This removes `parent_scope_id_for_new_inst` because I think it's
returning unhelpful results. The use was at the root of incorrect
results for the indirect import chain. `name_id_for_new_inst` is
actually wrapping a union, so it's more important.

The merging of `is_extern` and `first_owning_decl_id` in
`handle_function.cpp` feels like it's less correct with the changes
that've been made to `extern`. This ripples in tests, because the error
recovery shifts.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-08-27 20:26:23 +00:00
Jon Ross-Perkins 2d3842fc06 Implement 'extern library' support for functions. (#4220)
Support for types (particularly classes) is left as a TODO.

There's also an issue I'm observing with a "define in impl" test, but
this is probably an issue with resolving the prior declaration which is
imported indirectly. The PR was already feeling big, so I'm choosing to
cut here.

Note, this does not implement the rule "The owning library's API file
must import the `extern` declaration, and must also contain a
declaration."
2024-08-19 22:12:21 +00:00
Jon Ross-Perkins 0feb757de0 Add fields for extern to EntityWithParamsBase (#4206)
This adds fields to `EntityWithParamsBase` to reflect the intention with
`extern library` design. I'm renaming `decl_id` because it shouldn't be
expected to be assigned anymore. import_ref.cpp I'm deliberately keeping
on `first_owning_decl_id` (which will break when importing `extern
library` declarations). Most other cases are for diagnostics, and I'm
using `latest_decl_id` to try and get the closest declaration to the
error. Note I'm partly splitting out this PR to show the test effect,
which apparently we don't test related cases.
2024-08-12 19:50:15 +00:00
Richard Smith 4a21b6af9b Basic support for implementing and using a parameterized interface. (#4203)
The main change here is to form a specific when checking an interface
function against an impl function, instead of just substituting the
`Self` type.
2024-08-09 01:05:03 +00:00
Richard Smith a9e835f3dc Remove caching of return slot usage. (#4163)
The caching isn't buying us much, and is adding complexity and
divergence between the codepaths for generic and non-generic functions.

This means we no longer suppress diagnostics for the second or
subsequent time we call a function with an incomplete return type. If we
want to add that back, it might be worth considering moving the
suppression to `TryToCompleteType` and only diagnosing that a type is
incomplete once, regardless of why we're requiring it to be complete.
2024-07-25 20:29:59 +00:00
Richard Smith 3cb769a053 Rename "generic instance" to "specific" throughout the toolchain. (#4165)
As discussed in toolchain meeting, we want to avoid overloading the
meaning of "instance", and "specific" was the best name we found. It's a
little unorthodox and inventive, but hopefully over time will become as
unsurprising as the term "generic" is.
2024-07-25 16:42:01 +00:00
Jon Ross-Perkins bf89652a4d Move common entity fields to a 'base' struct. (#4161)
I'd considered moving DeclParams uses over, but when handling qualified
names, there's a parse node instead of an instruction. I did try to
unify a couple other uses though, including adding MergeDefinition. I
expect `interface` will use a little more once it's more completely
implemented, but maybe I'm wrong about that.
2024-07-24 23:26:00 +00:00
Richard Smith 07bad72d86 Support for calling non-generic methods in a specific class. (#4156)
Use the specific parameter types for checking, and the specific return
type as the type of the call.
2024-07-24 20:27:01 +00:00
Jon Ross-Perkins db022658c6 Implement syntactic merge checks for parameters. (#4149)
Note this isn't implementing checking through imports. The parse node
there is harder to access through the context, so would require
examining the entity in order to get the import declaration, to get at
the ImportIR. We also don't have a parse tree attached in that case, and
would need to add one to SemIR::File. But I believe we do want to add
that, so it's explicitly a TODO.

Note GetTokenText re-lexes literal values, so there's a bit of potential
overhead there. Not sure if we want a more efficient manner for
comparing in cases like this.
2024-07-23 20:32:24 +00:00
Richard Smith 3cc90f9017 Move GetTypeInInstance from Check to SemIR. (#4144)
In preparation for this function being used by other parts of `SemIR`
and by lowering.
2024-07-17 23:27:14 +00:00
Jon Ross-Perkins 99696b9812 Rename check handlers to HandleParseNode overloads. (#4121)
This is for consistency with #4120. Similar to that, we can use
overloads on the typed NodeId rather than individually named handlers.
There isn't the same caller benefit here though, since the calls from
check.cpp are already boilerplate.
2024-07-12 22:38:06 +00:00
Jon Ross-Perkins a81d67c629 Rename Builtin to BuiltinInst, particularly to get BuiltinInstKind (#4115)
I'm trying to increase the distinction between BuiltinKind and
BuiltinFunctionKind. BuiltinKind is for instructions,
BuiltinFunctionKind is for function definitions. To get to this point,
I'm doing a few changes:

- BuiltinKind -> BuiltinInstKind
    - builtin_kind.* -> builtin_inst_kind.*: filename consistency
- Builtin -> BuiltinInst: mainly for consistency with the above
- Builtin::builtin_kind -> BuiltinInst::builtin_inst_kind: somewhat
repetitive but seems like a consistent edit
- Function::builtin_kind -> Function::builtin_function_kind: seems a
useful distinction

I'm leaving alone things like (and mentioning in case there's a desire
for more renames):

- InstId::BuiltinError, InstId::ForBuiltin: these I think are more
apparent because they're directly associated with Inst.
- GetBuiltinICmpPredicate in lowering: maybe builtin function handling
should be in its own file, but these local names don't feel problematic
to me.
- GetBuiltinType, BuildBuiltinValueRepr, PerformBuiltinIntComparison:
similar to the above, names don't feel too problematic
2024-07-11 18:24:17 +00:00
Richard Smith 7322a1e220 Build a list of dependent constants to recompute in each instance of a generic. (#4110)
For each generic, build a list of instructions describing the
computations we need to do when resolving an instance of the generic:
this is a list of the instance-specific constants and types that the
generic uses. Another way of viewing this list is as a block of Carbon
SemIR code that is evaluated in order to form an instance of the generic
-- this is referenced in the code as the "eval block" for the generic.

For each instruction in the generic whose type or value is a symbolic
constant, replace that type or constant value with a symbolic reference
that says "to find the actual type or value, look at index N in the list
of values for the generic instance".

For an instruction with a symbolic constant value, we can just add that
instruction to our list. For an instruction with a symbolic constant
type, however, we may not have a corresponding instruction computing the
type within the generic and may need to build a new instruction, but
will reuse one where possible. In the case where we build a new
instruction, we use the existing substitution code to build the type
within the eval block.

For now, this transformation is only done in the declaration region of
the generic, not in the definition region. Also, we map back from the
symbolic references to the underlying constant value in a few places
where we will eventually need to do a lookup into a generic instance, in
order to avoid regressing the tests.
2024-07-08 22:29:37 +00:00
Richard Smith fa11050961 Track a list of dependent instructions created within a generic (#4092)
When checking a declaration or definition of a generic, track a list of
created instructions that depend on the generic's parameters in some
way, along with information on how they depend on the parameters. This
will eventually be used to determine what information we need to compute
when creating instances of the generic, but for now we're just building
the list.

Information is tracked separately for the declaration region and the
definition region of the generic, because in general these may be first
provided in separate declarations, and they should be substituted into
at different times.
2024-07-01 20:33:44 +00:00
Richard SmithandJon Ross-Perkins 19c5596fd8 Build Generic objects for generic classes and interfaces. (#4086)
In `ClassType`s and `InterfaceType`s, track a `GenericInstanceId` for
the instance rather than just the argument list.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-06-27 20:22:10 +00:00
Richard Smith e7b0529957 Create a Generic object to represent a generic. (#4081)
Build a `Generic` object for generic functions. This object tracks the
generic parameters that are in scope for the generic entity. Eventually
it will track other information about the generic too.

Add basic SemIR formatting support for generic functions.
2024-06-26 20:13:26 +00:00
Geoff Romer 5a8dfda4f0 Diagnose missing definitions in impl files (#4079) 2024-06-26 18:57:37 +00:00
Richard Smith 9029cac727 Remove inst_id from the public interface of ConstantId. (#4053)
Require mapping from a `ConstantId` to an `InstId` to go through the
`ConstantValueStore`.

This is a preparatory step for an upcoming generics change where
symbolic `ConstantId`s are no longer just a thin wrapper around an
`InstId` but instead are indexes into a table with additional
information about the symbolic constant beyond its `InstId`.
2024-06-14 00:40:53 +00:00
Richard Smith e3c15edb92 Remove return_type_id from Function. (#4051)
Instead of redundantly storing both the `return_type_id` and
`return_storage_id`, where the declared return type is just the type of
the return storage, store only the `return_storage_id`.

Add a convenience property to get the declared return type of the
function.

In addition to avoiding storing redundant information, this is a
preparatory step for an upcoming change for generics support that will
make it more expensive and awkward to store `TypeId`s in places other
than the type of an instruction.
2024-06-13 22:01:21 +00:00
Jon Ross-Perkins 807a3f1370 Add namespace-scoped private keyword support. (#4026)
Adds access to the name lookup table in name scopes. This is so that we
can quickly check access during name lookup without resolving the entity
itself. Does this for names in general, but does not implement handling
for entity-scoped names, only namespace-scoped names (where they're
essentially just not exported).

Excludes `private` names from exports. Although names should be
accessible to `impl` files, that's not implemented here because we'll
probably want to do it by directly copying name lookup tables.
2024-06-06 00:19:56 +00:00
Jon Ross-Perkins d1862e829b Add a macro for introducer tokens. (#4031)
Playing with the macro suggestion on #4028, replace DeclKind with some
templating that asserts the in-use token is an introducer token. This
allows type-safe usage of Lex::TokenKind, reducing the benefit of a
separate enum while improving stdout (since now this will ostream as the
keyword name).
2024-06-05 21:04:53 +00:00
Jon Ross-Perkins 0ffa5bf659 For modifiers, get the TokenKind from DeclKind instead of argument. (#4028) 2024-06-05 16:23:36 +00:00
Jon Ross-Perkins a910eda020 Switch decl_state to an arg for modifier functions (#4027)
With private modifiers, we'll want to start checking modifiers later,
e.g. after a name conflict is detected (and potentially merged). I think
we've agreed to be more explicit about whether the modifier functions
are manipulating state, versus trying to keep the state on the stack a
little longer (moving Pop to the end of these functions).

Removing FileScope from the stack and renaming it to DeclIntroducerStack
to better reflect the usage and behavior. The FileScope mostly reflects
an approach that wasn't ultimately adopted.
2024-06-04 23:12:12 +00:00
Chandler Carruth 8c64f0bfdd Add -Wmissing-prototypes and fix issues it finds. (#4019)
Most of these are places where we failed to include a header file and
simply never got an error about this. The fix is to include the header
file.

Most other cases are functions that should have been marked `static` but
were not. Finding all of these was a main motivation for me enabling the
warning despite how much work it is.

One complicating factor was that we weren't including the `handle.h` for
all the state-based handler functions. While this isn't a tiny amount of
code, it is just declarations and doesn't add any extra dependencies. It
also lets us have the checking for which functions need to be `static`
and which don't. For the `parse` library I had to add the `handle.h`
header as well, I tried to match the design of it in `check`.

I have also had to work around a bug in the warning, but given the value
it seems to be providing, that seems reasonable. I've filed the bug
upstream: https://github.com/llvm/llvm-project/issues/94138

I also had to use some hacks to work around limitations of Bazel rules
that wrap `cc_library` rules and don't expose `copts`. I filed a bug for
`cc_proto_library` specifically:
~https://github.com/bazelbuild/bazel/issues/22610~ 
https://github.com/bazelbuild/bazel/issues/4446
2024-06-04 20:04:45 +00:00
Jon Ross-Perkins d9c62b106d Rename enclosing scope to parent scope (#4020)
Following up on discussion from #3948, doing a general rename of
"enclosing scope" to "parent scope" (and "enclosing scopes" to "ancestor
scopes"). The intent is to improve understandability and collide less
with C++ terminology for "enclosing scope". Note this changes most uses
of "enclosing", but leaves behind a few like "enclosing function" and
"enclosing block".

Note this does create some "parent class" mentions for "adapt" and "var"
(the class they're within), which is maybe unfortunate, but we'd
probably say "base class" if we meant inheritance so perhaps that's
okay. Along the same lines, these are the only `parent_class` uses I see
now, and we do have a few `base_class`.
2024-06-04 19:57:14 +00:00
Jon Ross-Perkins 517a416852 Clean up some misc toolchain braced inits. (#4013)
Following up on #4012 and #4009, clean scattered cases which could be
making better use of designated initializers.
2024-05-31 23:23:57 +00:00
Jon Ross-PerkinsandRichard Smith 5bb318cae6 Switch AddInst struct init style. (#4012)
Trying to conform with #4009. Changes SemIR::LocIdAndInst construction
to root out struct init cases with AddInst and related functions. I'm
using templating of AddInst functions in order to avoid `AddInst(loc_id,
InstName{...})` and instead have `AddInst<InstName>(loc_id, {...})` with
I think similar readability results. There are a couple cases where inst
construction is templated and so designated initializers couldn't be
used, so this may be better for those in particular due to the extra
type enforcement.

This probably doesn't clean up every last case, but I was trying to get
the bulk at once without bleeding over into less related changes.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-05-31 22:49:44 +00:00
Jon Ross-Perkins 7e81c1710e Refactor modifier fetching of enclosing scopes to avoid duplicate calls. (#4010)
Right now, each sequential modifier verification tends to re-fetch the
enclosing scope, doing equivalent verification. Change code to more
explicitly do the fetch once, sharing the result, also making the
enclosing scope available to the caller for other work.

Note, the type store similarly carries an inst store pointer; that's
what I'm basing having the name scope store's inst store pointer on.
2024-05-31 15:36:52 +00:00
Richard Smith 28cefe98df Factor out pushing / popping of names plus parameters. (#4005)
Previously we did some of this in decl_name_stack and some of it in the
callers of decl_name_stack. Factor out a single place to pop a name and
its optional following parameters.

Part of making this behavior consistent is that we now track whether an
implicit parameter list was present or absent rather than mapping an
absent list to `InstBlockId::Empty`. This improves our redeclaration
checking and the precision of some diagnostics.
2024-05-30 16:05:35 +00:00
Jon Ross-Perkins 512583d744 Refactor KeywordModifierSet to provide a class API (#4003)
This is primarily to avoid the use of `!!` in code, trying not to create
too much code as a result (obviously still a net increase). Also
refactoring to its own file to make the enum easier to find.

Note, NodeCategory does similar, I might propose similar there if
everyone's good with the API. However, that's just two, so creating
something like enum_base felt like too much.
2024-05-29 20:52:31 +00:00
Richard SmithandJon Ross-Perkins 28170c7867 Parse parameters in name qualifiers. (#3988)
Parse the name of a declaration as a sequence of `NameQualifier`s --
which have a name, possibly parameters, and a trailing period --
followed by a name and possibly parameters. This prepares us for parsing
declarations of members of generic classes and similar cases, but
actually supporting such member redeclarations is left to a future
change.

We previously required functions to have parameters, but no longer do,
following the direction of #3848. Cases like namespaces that can't
actually have parameters are now diagnosed in check instead of in parse.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-05-29 00:47:29 +00:00
Jon Ross-Perkins 73f8490660 On NameContext, rename enclosing_scope and target_scope_id. (#3948)
I think the new name is more consistent for how `enclosing_scope_id` is
used relative to `name_id` (even removing the clarifying note on
`enclosing_scope_id_for_new_inst`). Suggesting `initial_scope_index` as
a replacing for the old `enclosing_scope`, hoping it's a little clearer.

I'm replacing `target_scope_id` uses in modifier logic because they
seemed to be based on the NameContext use.
2024-05-15 23:28:59 +00:00
Jon Ross-Perkins 76471cf701 Move decl-specific merge logic back to respective handlers. (#3937)
I'd split out the decl-specific handlers so that import_ref.cpp could
also call them. However, with the current model for imports and
constants, we shouldn't use them there. As a consequence, merge them
back into individual files for greater consistency with other helper
functions (and better visibility when making related code changes).
2024-05-07 00:13:04 +00:00