Commit Graph
63 Commits
Author SHA1 Message Date
Jon Ross-Perkins cda5f66d22 Refactor NodeCategory to provide a class API (#4004)
Mirroring #4003 for NodeCategory.

Note we template a lot more on NodeCategory's enum, so this is a
slightly more awkward delta.

Also, switch from Enum in KeywordModifierSet to RawEnumType for
consistency with EnumBase. The templating on NodeCategory had me
thinking about that more.
2024-05-29 22:47:50 +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 895e90e791 Start including the prelude for testing. (#3861)
- Adds an empty prelude.carbon file
- Imports that file in any non-Core package file
  - Adds --disable-prelude-import to avoid that
- Adds --exclude-dump-file-prefix to be able to hide files from dumping
- Used to hide core files (we can't do this by package name due to lex
dumps, for example)
- Restructures some tests to not rely on `i32`, particularly `alias`
tests (which rely on a name ref) and tests with no prelude.

I'm adding the framework for switching i32 to calling Int32 in the
prelude, but I'm running into a separate error actually switching over.
So that *mostly* works, but isn't quite ready for prime time. However,
maybe the current state of this PR is still useful to review since it
does a lot of the infrastructure work and adds the %Core everywhere?
2024-04-07 17:11:42 +00:00
Jon Ross-Perkins a034f86272 Change struct literal parsing to use placeholders. (#3850)
This is achieving a similar goal as #3849, using placeholders instead of
an ambiguous start node to clarify structure and incrementally simplify
checking. The benefit isn't quite as big here because both paths are
structs, and so checking is more consistent than paren exprs versus
tuples. But I think this removes the only other multi-purpose parse
node.

This uses StructLiteral/StructTypeLiteral naming, reflecting equivalent
SemIR naming. Note, I would lean towards renaming StructLiteral to
StructValueLiteral, but I think consistency in naming takes precedence.
Any renames of StructLiteral might be better in a separate PR.

StructFieldType/StructFieldValue -> StructTypeField/StructField is
trying to making the reading more consistent with
StructTypeLiteral/StructLiteral. SemIR has StructTypeField but not a
value equivalent.
2024-04-03 20:36:49 +00:00
Jon Ross-Perkins b42612bcec Change tuple/paren expr parsing to use placeholders. (#3849)
I've been thinking about this since we decided to add placeholders in
the parse tree. This allows a clearer division of work in check
handling, where we were doing work for ExprOpenParen that's only
necessary for tuples (splitting/renaming handle_paren.cpp accordingly).
2024-04-03 18:31:16 +00:00
Richard Smith f0e940ddfd Initial support for builtin functions. (#3803)
For now, a builtin function is defined by specifying a string literal
initializer in a function declaration:

```carbon
fn MyBuiltin(a: i32) -> i32 = "builtin.name";
```

End-to-end support is included for a sample `"int.add"` builtin
performing integer addition, covering constant evaluation and code
generation.

The implementation here needs substantial refactoring before we'll be
ready to start adding more builtins. That refactoring work will be
coming next. This change is aiming to checkpoint some incremental
progress.
2024-03-21 20:46:34 +00:00
Richard Smith 2584399673 Factor IdKind enum out of node stack. (#3787)
Provide a general mechanism for determining the kind of the args of an
instruction. Use this to simplify instruction profiling a little. The
intent is to also use this mechanism as the basis of a substitution
mechanism, which will be part of a future patch.

Note that this causes us to do three table lookups and two indirect
calls in inst_profile per instruction, instead of one table lookup and
one indirect call. We can revisit this if it shows up in profiles.
2024-03-15 22:42:11 +00:00
Jon Ross-Perkins 86a7c9ff45 Rename parse_node -> node_id (#3760)
This was previously discussed at
https://discord.com/channels/655572317891461132/655578254970716160/1209975051588210729.
I'm initiating this mainly because we typically use "id" suffixes to
indicate an `IdBase` being passed around and the non-id suffix of
`parse_node` suggests at it carrying more data than it actually does.
There used to be more reason for avoiding `node_id` because
`SemIR::InstId` used to be named `NodeId`, but that's no longer
necessary. As a consequence, I'd like to rename `parse_node` to more
precisely reflect its type.

In full, this is doing:

```
parse_node_kind -> node_kind
parse_node -> node_id
ParseNodeCategory -> NodeCategory
ParseNodeKind -> NodeKind
ParseNode -> NodeId
```

This is primarily in check and sem_ir, but with some `parse_node_kind`
references in parse too.

Pluralization is consistent with name forms on both sides, so that
wasn't part of my replacements.
2024-03-09 00:21:29 +00:00
Richard Smith 8e956baca8 Basic support for associated constant declarations (#3737) 2024-03-04 21:23:06 +00:00
Richard Smith 8e8eeb3243 Add diagnostics for extend impl misuse. (#3721)
To make the implementation simpler, make `PopWithParseNodeIf` return
`pair<NodeId, optional<value>>` rather than `optional<pair<NodeId,
value>>`. While wrapping the whole result in `optional` seems more
principled, it's significantly harder to work with.
2024-02-23 22:07:29 +00:00
CJ Johnson 518e361328 Address TODO to change GenericBindingPattern to CompileTimeBindingPattern (#3713) 2024-02-21 22:09:40 +00:00
Jon Ross-Perkins 03347793cc Switch VariableInitializer order to accommodate GlobalInit (#3708)
This undoes parts of #3515 in order to allow PushGlobalInit to be called
when the initializer is called, instead of at the end of the binding
pattern. The current approach is fragile because supported patterns will
become more complex. We also will likely want similar support in `let`,
which puts the initializer first, so this offers a consistent approach
for both.

[Looking
back](https://discord.com/channels/655572317891461132/655578254970716160/1184237511766179840),
this is more or less the second option in that message, but using the
PeekNextIs to avoid vagueness about what's being popped first.

Note I'm putting in PeekNextIs for what I'm hoping will be a pretty
narrow use-case. I could've added depth arguments to the Peek functions,
but that would've rippled through a number of APIs and it's not clear to
me that this has generic utility. I mean, right now it could just be
PeekNextIsVariableInitializer, since it's only optional in that case.
2024-02-21 22:03:32 +00:00
Richard Smith 5ab26072fd Use the DeclNameStack for impl declarations. (#3691)
They don't have names, but using the DeclNameStack anyway keeps our
behavior more consistent, and keeps track of the enclosing name scope
and the prior state of the scope stack for us.

Depends on #3683.
2024-02-06 22:28:31 +00:00
Richard SmithandJon Ross-Perkins 0e053703f8 Build Impl entity to represent an impl declaration. (#3683)
Collect the contents of an `impl` into a scope, and start doing very
basic checking for `impl` declarations and definitions.

This change adds two new `Id` types to the set of type that `NodeStack`
supports -- `ImplId` and `NameScopeId`.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-02-06 18:49:21 +00:00
Richard Smith c35e0fea64 Tidy up and refactor the node stack. (#3685)
Add a type representing a non-discriminated union of IDs. Refactor the
node stack to use it. Plus a few other refactorings aiming to clean up
and simplify the code. The overall goal here is that adding a new kind
of ID, node category, or instruction should only require changing one
place in the node stack rather than a bunch of different changes.

One minor functionality change: crash backtraces now use the correct
type for IDs when dumping the node stack rather than using `InstID`
printing for all but one case.
2024-02-05 22:07:38 +00:00
josh11bandJon Ross-Perkins 03bf22e55e Parse tree for impl that is better for check stage (#3678)
Use two different nodes for "<type> followed by `as`" and "<type>
omitted before `as`, use `self`", so it is easier to determine which
case. Later the second case will push the type id for `self` onto the
node stack, making the two paths more similar.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-02-01 22:23:21 +00:00
Richard Smith 9e7a17b1a1 Scaffolding for checking impls. (#3672)
Consume the components of the `impl` declaration, and set up scopes for
the child elements. We don't yet build a representation for the impl
itself.

Also, add an interface type value. This is necessary so that we have a
value for the expression on the right-hand side of `as` in an `impl`.
2024-01-31 22:18:29 +00:00
Chandler Carruth bf02d1f4b0 Remove headers marked as unused by ClangD. (#3661)
This required adding a few headers that were found transitively before,
but not too many. This is sadly a fairly manual process of opening every
file in my IDE, but I think I got everything in `//common` and
`//toolchain`.

There are a few cases where technically we don't need `foo.h` to be
included into `foo.cpp`, but I've forced those to stay with a pragma.

I've tried to catch the places where we can cut deps in Bazel as well,
but not sure I got all of those.

I had been noticing these in other PRs and it seemed better to isolate
the change.
2024-01-29 16:15:35 +00:00
josh11bandRichard Smith afd7115c0e Support determining IdKind from NodeCategory, in addition to NodeKind (#3648)
The categories `Expr`, `MemberName`, `Decl`, `Statement`, and `Modifier`
are usable since they are associated with a consistent `IdKind`. The
mapping to `IdKind` for NodeKinds that have those categories are no
longer listed explicitly, ensuring that the `NodeCategory` mapping is
the source of truth.

Also: fixes the category of the `FunctionDefinitionStart` and
`ArrayExprStart` node kinds.

Note: I've added [a section on defining constexpr constants to the
Toolchain architecture
doc](https://docs.google.com/document/d/1RRYMm42osyqhI2LyjrjockYCutQ5dOf8Abu50kTrkX0/edit?resourcekey=0-kHyqOESbOHmzZphUbtLrTw&tab=t.0#heading=h.f7682a2tpvxr).

FUTURE:

* We should switch `TuplePattern` to put an `InstId` on the `NodeStack`
instead of an `InstBlockId`, so we can handle the pattern category.
* We should make a category for names to replace uses of the `NameId`
`IdKind`.
* We should make use of these new APIs more, and propagate more-precise
types through the codebase.

QUESTION: Should I use a different approach for determining the number
of members of the `NodeKind` enum?

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-01-27 01:04:01 +00:00
josh11b f5c34d62dd Abbreviate "address" -> "addr" (#3580)
As [requested in
Discord](https://discord.com/channels/655572317891461132/655578254970716160/1184904724483416064)
and is now documented in [the toolchain architecture
doc](https://docs.google.com/document/d/1RRYMm42osyqhI2LyjrjockYCutQ5dOf8Abu50kTrkX0/edit?resourcekey=0-kHyqOESbOHmzZphUbtLrTw&tab=t.0#heading=h.pph7i5m5un7q).
2024-01-09 22:37:48 +00:00
Jon Ross-Perkins a196b9840f Run clang-tidy on headers (#3572)
This patches bazel_clang_tidy handling of headers. I found an equivalent
change at https://github.com/erenon/bazel_clang_tidy/pull/13, but that
was [already
rejected](https://github.com/erenon/bazel_clang_tidy/pull/13#issuecomment-1047007424).
Per the criticism, this will result in redundant processing of headers.

The project instead uses `HeaderFilterRegex: ".*"`, but that results in
two problems:

1. When running with `-k`, errors are repeated when a header is included
more than once, which is common.
2. clang-tidy including errors from headers that are included from other
modules (e.g., abseil-cpp); filtering correctly is difficult.

Given the trade-offs and options (including forking), I thought patching
was preferable so long as it remains narrow.
2024-01-05 23:01:47 +00:00
Geoff RomerandRichard Smith 927d633762 Simplify handling of VariableInitializer (#3515)
Also stop supporting `var` with initializer inside `for`.

Resolves TODO in `handle_variable.cpp`

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-01-05 17:58:22 +00:00
Richard Smith a6508fcf05 Basic support for generic bindings. (#3555)
This change adds a `BindSymbolicName` instruction for generic bindings,
paralleling the existing `BindName`. A mechanism is also added to allow
both kinds of binding to be accessed uniformly, for convenience in the
case where the two different kinds of binding are treated the same.

Generic bindings of type `type` are allowed to be used as types,
although no operations are provided for such types. For now lowering
treats these types as empty structs, which seems like a reasonable
lowering for non-monomorphized unconstrained types.
2024-01-05 03:39:45 +00:00
josh11bandRichard Smith b0da52a3d7 Use typed parse node ids in SemIR instruction types (#3560)
This involves a number of supporting changes:
* The `parse_node;` member of instruction types may now have any type
derived from `Parse::NodeId` and is no longer required to have that
exact type.
* `Parse::Node::Invalid` is now a singleton object of a separate type
that is convertible to `Parse::NodeId` and its descendants. This
replaces the `Invalid` member of its descendants, and avoids having to
write long `NodeIdOneOf<...>` types when initializing variables to
invalid.
* `IndexBase` now allows `==` and `!=` comparisons between its derived
classes and types that are convertible to those types.
* A number of functions in the check stage have been changed to preserve
more type information instead of using `Parse::NodeId`.
* `NodeIdForKind<K>` (also known as `KId`) now has a `Kind` member so it
may be used to declare `NodeIdOneOf<T, U>` types without #including
`parse/typed_nodes.h`.
* `NodeIdForKind<K>` (also known as `KId`) may be implicitly converted
to `NodeIdOneOf<T, U>` if `T::Kind == K` or `U::Kind == K` (executing a
TODO).

Many of the `parse_node` members were not converted since they would
have required more extensive changes. They have been marked with "TODO"
comments.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-01-03 23:13:30 +00:00
josh11bandChandler Carruth 48c986f52d Start using typed parse node ids in the check stage (#3547)
Goal is to increase type safety, though more work needs to be done (see
added TODOs).

Note that, after this change, check handlers corresponding to deleted
parse node kinds will no longer compile.

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2023-12-29 01:28:09 +00:00
josh11b 29104e212a Do TODO to rename QualifiedDecl -> QualifiedName (#3543)
Renaming since the parse node does not represent a declaration.
2023-12-26 23:12:28 +00:00
2e97f27b8d Typed wrappers around parse tree nodes (#3534)
These are intended to allow the structure of a parse tree node to be
described more precisely in code, to support these use cases:

- Automated checking that the parse tree conforms to the expected
structure. (Added to `Tree::Verify`.)
- Easier reading and understanding of the structure of the parse tree by
toolchain developers. (See `parse/typed_nodes.h`.)
- Easier navigation of the parse tree, for example for tooling uses and
for use when forming diagnostics.

On this last point, an object representing the file may be inspecting
using `Tree::ExtractFile`, as in:
```
auto file = tree->ExtractFile();
for (AnyDeclId decl_id : file.decls) {
  // `decl_id` is convertible to a `NodeId`.
  if (std::optional<FunctionDecl> fn_decl =
      tree->ExtractAs<FunctionDecl>(decl_id)) {
    // fn_decl->params is a `TuplePatternId` (which extends `NodeId`)
    // that is guaranteed to reference a `TuplePattern`.
    std::optional<TuplePattern> params = tree->Extract(fn_decl->params);
    // `params` has a value unless there was an error in that node.
  } else if (auto class_def = tree->ExtractAs<ClassDefinition>(decl_id)) {
    // ...
  }
}
```

The `Extract...` functions collect the child nodes into the typed parse
node's fields (internally using a `Tree::SiblingIterator`) for easy
access. However, this is not as fast as directly observing the tree
structure using the postorder strategy being used by the check stage.

These functions rely on using struct reflection on the typed parse node
definitions from `parse/typed_nodes.h` to get the expected structure of
child nodes and then populate them.

Note that validating these in `Tree::Verify` adds significant cost to
it, and is currently included in the parsing stage. Without this change,
a 10 mloc test case of lex & parse takes 4.129 s ± 0.041 s. With this
change, it takes 5.768 s ± 0.036 s.

This builds upon and completes #3393.

Co-authored-by: Richard Smith <richard@metafoo.co.uk>

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2023-12-22 22:14:11 +00:00
josh11bandJon Ross-Perkins e95acbf666 Update comment to reflect #3481 (#3523)
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2023-12-18 23:40:19 +00:00
Richard Smith 0a1abe9f64 Clean up some uses of the node stack. (#3512)
Also minor cleanups for the stack itself.
2023-12-14 20:57:03 +00:00
Richard Smith fbb4ecf319 Remove SelfParam, add an AddrPattern instead. (#3506)
This is intended to make the representation of a `self` pattern be more
similar to other patterns.
2023-12-14 20:53:51 +00:00
Jon Ross-Perkins e343ea593c Add macro for postfix operators. (#3504)
Per request on #3481, for consistency with prefix/infix.
2023-12-13 23:54:27 +00:00
Jon Ross-Perkins 7c7afc9e32 Split out infix and prefix operators to separate node kinds. (#3481)
This leaves a single state for each in the expr loop. I was trying to
think through ways to have per-token states, but they felt sort of
bulky.

Note this is more verbose: but I think the long-term is going to be that
when we start wanting to add handlers, we're going to need to switch to
different names based on the token found. As a consequence, the parse
state logic will end up diverging a little, and we'll just want to align
towards boilerplate handlers.

Short-term, this opens up a path for saying that each parse node
corresponds to precisely one token in success states, and separates out
what were becoming big handler functions in check.
2023-12-13 19:52:20 +00:00
Jon Ross-Perkins c4864aa2ff Split out and/or operator handling from infix. (#3480)
This is also doing the parse node split, allowing lower reliance in
formatter on the tokenized buffer (something that I may be touching more
due to import handling).
2023-12-09 01:03:32 +00:00
Geoff RomerandRichard Smith 6e65a30b5d Rename ParamList to TuplePattern (#3479)
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2023-12-08 23:35:47 +00:00
Geoff Romer 5897e57c21 Clarify naming around paren expressions (#3444)
(Split out of #3410)

Consistently use `ParenExpr` solely for parenthesized single
expressions, and use more syntax-oriented terminology for states and
nodes that might represent either a `ParenExpr` or a tuple literal.
2023-12-08 21:46:28 +00:00
josh11b 3b0923c81d Add interface support to check (#3474)
Largely copied from the `class` code
2023-12-08 17:13:49 +00:00
Richard Smith fe6f7b4330 Rename Name -> IdentifierName given that we have several other kinds of parse nodes that represent names. (#3453)
Factor out common checking handling for the different kinds of
unqualified names
2023-12-07 01:48:14 +00:00
Jon Ross-Perkins d73729179a Switch modifiers to use distinct parse nodes. (#3461)
This is supporting a direction that all parse nodes should correspond to
a single token, allowing for reduced tokenized buffer access during
checking (it's still necessary for diagnostics, and some literals).

One of the justifications for a unified parse node was implementation
LOC: note this is slightly smaller, using macros to reduce some
duplication. While this does add more switching in HandleDeclScopeLoop,
that's offset by less explicit switching in the check handlers. Also, I
think the duplication in HandleDeclScopeLoop can be reduced by shifting
the flow there, which I'll do in a separate PR.
2023-12-06 22:14:53 +00:00
josh11bandJon Ross-Perkins fada410559 Support declaration modifier keywords (#3412)
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2023-12-05 22:45:57 +00:00
Richard Smith 7dffa0c7ec Support for base: T;, .base, x.base. (#3450)
No support for `extend base` yet, in an effort to minimize collisions
with #3412.
2023-12-04 22:45:59 +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
Geoff Romer b8d4e2f41b Binding pattern naming cleanup (#3410)
- Rename `PatternBinding` to `BindingPattern`.
- Use `BindingPattern` rather than `Pattern` in the names of
binding-pattern-specific parse states.
2023-12-01 21:36:51 +00:00
Richard Smith 332a368cee Rename Parse::Node -> Parse::NodeId. (#3432)
As discussed [on
discord](https://discord.com/channels/655572317891461132/655578254970716160/1178878128714678282)
and today's toolchain discussion.
2023-11-29 18:53:12 +00:00
Jon Ross-Perkins a204689893 Use more specific node kinds for literals. (#3419)
Sounding out the approach, to make it clearer what a literal node
corresponds to.
2023-11-22 01:27:28 +00:00
Richard SmithandJon Ross-Perkins 2715e2276e Parsing and basic checking for abstract class and base class. (#3385)
For now, we require the same introducer to be used each time a class is
declared, but see #3384.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2023-11-13 20:38:21 +00:00
josh11bandJon Ross-Perkins c53b248800 Abbreviate "parameter" -> "param" (#3392)
Part of switching to the [abbreviations we've decided to
use](https://docs.google.com/document/d/1RRYMm42osyqhI2LyjrjockYCutQ5dOf8Abu50kTrkX0/edit?resourcekey=0-kHyqOESbOHmzZphUbtLrTw#heading=h.pph7i5m5un7q).

I will rename files in a follow-up PR.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2023-11-13 19:06:54 +00:00
Richard Smith afd6d85610 Support for returned var and return var. (#3374)
Implement toolchain support for `returned var` and `return var`.

- Modeled `returned` in the parse tree as a `ReturnedSpecifier`
appearing after the `VariableIntroducer`.
- Modeled `return var` in the parse tree as a `ReturnVarSpecifier`
appearing after the `ReturnStatementStart`.
- Factored out the implementation of `return` statement and `returned
var` handling in check into a new `return.{h,cpp}`. The parse nodes
themselves are still handled in `handle_*.cpp`. This allows easy code
reuse between `return` and `returned var`.
2023-11-10 19:52:30 +00:00
josh11b 5020fdb3be Use abbreviation "decl" instead of "declaration" (#3382)
Part of switching to the [abbreviations we've decided to
use](https://docs.google.com/document/d/1RRYMm42osyqhI2LyjrjockYCutQ5dOf8Abu50kTrkX0/edit?resourcekey=0-kHyqOESbOHmzZphUbtLrTw#heading=h.pph7i5m5un7q).

I will rename files in a follow-up PR.
2023-11-10 10:43:25 +00:00
josh11b 11ca083855 Use abbreviation "expr" instead of "expression" (#3375)
Part of switching to the [abbreviations we've decided to
use](https://docs.google.com/document/d/1RRYMm42osyqhI2LyjrjockYCutQ5dOf8Abu50kTrkX0/edit?resourcekey=0-kHyqOESbOHmzZphUbtLrTw#heading=h.pph7i5m5un7q).

I will rename files in a follow-up PR.
2023-11-10 01:32:32 +00:00
Richard Smith 71aa4a45be Distinguish between name IDs and string IDs in the type system. (#3341)
Add a `NameId` that is effectively just a wrapper around a `StringId`,
with
some additional predefined values for names that don't correspond to
strings, such as the name of `self` or the function's return slot.
2023-11-09 16:51:36 +00:00