Commit Graph
109 Commits
Author SHA1 Message Date
Jon Ross-Perkins 7083b267d4 Switch clang::fallthrough to fallthrough (#3593)
Preferring the C+11 name, [reflecting old
discussion](https://discord.com/channels/655572317891461132/655578254970716160/1171977169556230164)
2024-01-11 22:54:54 +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
Geoff Romer 214d7b991d Handle missing condition in while (#3578) 2024-01-09 19:40:52 +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
josh11b e93b5c61da Suppress clang-tidy error to use auto in tree_test.cpp (#3570) 2024-01-04 22:33:56 +00:00
josh11bandRichard Smith 82179bc903 Add Tree::TryAs to cast to a typed parse node id (#3565)
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-01-04 21:51:19 +00:00
Jon Ross-Perkins 379d776084 Add support for '--config=clang-tidy' (#3559)
This sets things up to use `bazel` to run `clang-tidy` using
https://github.com/erenon/bazel_clang_tidy.

I'm fixing issues outside of explorer, and disabling clang-tidy for
targets in explorer that have legacy issues. I was going to disable
clang-tidy for targets in explorer such as interpreter anyways, because
they're slow to parse, and just extended that to the currently failing
targets.
2024-01-04 18:09:52 +00:00
840cb1bed7 Form a struct value directly in tree extraction. (#3563)
Don't first form a `std::tuple` and then convert it to a struct. Speeds
up compilation of extract.cpp by 15-20%.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Co-authored-by: josh11b <josh11b@users.noreply.github.com>
2024-01-04 01:36:49 +00:00
josh11b 770876bbcb Define Any...DeclId aliases for brevity (#3562) 2024-01-04 00:03:44 +00:00
josh11b e94e0f155a Factor code out of templates to reduce compile time of parse/extract.cpp (#3561)
Unfortunately, it is a relatively small improvement (~5%, though noisy)
in compile time for that file in my testing.
2024-01-03 23:37:13 +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
Jon Ross-Perkins 95746df788 Split out context targets for check and parse. (#3558)
Per request on #3556.

Note, I'm assuming handlers should remain in the same target as the
caller for longer-term performance reasons.
2024-01-03 22:25:38 +00:00
Jon Ross-Perkins c8b30d3eec Split Parse out to its own target. (#3556)
This is mirroring the structure of codegen/codegen.h, lower/lower.h, and
check/check.h. I recently did lex/lex.h, so parse/parse.h is the last.
Now, the directory's main API file is eponymous with the directory.

I could've used a friend function to avoid making the Tree constructor
public, but in other places we make less use of `friend`, just leaving
things public. This felt more consistent, and simple because it only
affects the constructor.
2024-01-03 19:44:05 +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 a602be89e2 Add a MemberName parse node category for member access expressions (#3549)
Use this new category to replace the unconstrained `NodeId` child of
`MemberAccessExpr ` and `PointerMemberAccessExpr`. For now this new
category matches `IdentifierName` and `BaseName`, but later this will be
expanded to support `a.(b.c)` and `p->(b.c)` syntactic forms.

QUESTION: Is it time to make a `node_category.def` x-macro file?
ANSWER: Not yet.
2023-12-28 22:29:30 +00:00
josh11b 83b5db9c1e Make Parse::NodeCategory printable (#3548)
Completes TODO in `parse/extract.cpp`, moving the printing code for
`NodeCategory` out of the implementation of
`Extractable<NodeIdInCategory<T>>`.
2023-12-28 20:04:54 +00:00
josh11b 73cf277bdf Test trace output of Tree::VerifyExtractAs, fix found bugs (#3545)
Tests previously uncovered code. Fix uncovered problems:
* formatting of trace output
* package & import directives need to be classified as declarations
* the problem that meant the previous problem wasn't caught by existing
tests (since `Tree::Verify` didn't check that top-level declarations
match `AnyDeclId`, as required by `Tree::ExtractFile()`).
2023-12-28 00:27:53 +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
josh11b 55d853e17f Fix crash on incomplete constraint (#3542)
Previously would fail with:

```
CHECK failure at toolchain/parse/node_kind.cpp:74: Lex::TokenKind::Error == expected_token_kind || token_kind == expected_token_kind: Created parse node with NodeKind NamedConstraintDecl and has_error 1 for lexical token kind Constraint, but expected token kind Semi
```

Issue found by fuzzing.
2023-12-26 21:48:16 +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
Richard Smith 0a06fceb5f Improve diagnosis of mismatched brackets. (#3282)
Move handling of mismatched brackets out of the main lexing loop into a
separate pass that is only run if there are mismatched brackets This is
done in preparation for using both lookahead and lookbehind to work out
how to match brackets, and to get this code far away from the hot lexing
loop.

Fix bracket insertion location to be immediately after the token that
we're inserting the bracket after, rather than potentially at the end of
a comment. When there are open brackets at the end of the file, say that
there are open brackets, not that there's a closing bracket without a
matching opening bracket.
2023-12-21 08:49:37 +00:00
Richard Smith d87fe8b532 Rename Carbon::StringLiteralId -> Carbon::StringLiteralValueId. (#3522)
We have `StringLiteral`s in multiple other `Carbon` sub-namespaces.
Rename to a more specific name to avoid collisions.

We should likely also rename `Carbon::IntId` -> `Carbon::IntValueId` and
`Carbon::RealId` -> `Carbon::RealValueId`, but this collision is
prioritized because it was blocking work on typed parse nodes which
introduces a `Carbon::Parse::StringLiteralId`.
2023-12-18 23:27:33 +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 add31eb4e3 Refactor NodeKind to take advantage of a parse node only having one token kind. (#3486)
This builds on the series of changes to NodeKinds, aiming to simplify
the NodeKind implementation a little, also making it clearer that
there's a single associated token for each parse node (or, for
placeholders/invalid parses, not validated).

Note that prior to the relevant changes, there were nodes with multiple
tokens. This change is also locking in the approach of one token per
parse node, by refactoring macros to stop supporting multiple.
2023-12-13 21:03:44 +00:00
Jon Ross-Perkins 550559e30e On invalid parse nodes, if the token may vary, allow any token. (#3484)
Note #3486 rewrites the macro behavior, and is already approved: so this
PR is only for the changed enforcement during error. Also, #3493 already
changed several things to allow any token while this PR was awaiting
review, but this still changes enforcement for `For` and `If`.

This was brought up on
[#toolchain](https://discord.com/channels/655572317891461132/655578254970716160/1182066616456970251),
and I think this any-on-error approach gets at least some support. We
could try setting it to the introducer, but it's quite possible we want
it to be something like the token which led to the parse error, rather
than a static token. That leads to a conclusion that, most typically,
we'll expect arbitrary tokens when error conditions may lead to tokens
which aren't the expected token.

A couple related, recent `CARBON_IF_ERROR` crash fixes can be found in
#3404 and #3424. Something like #3404 would've been needed regardless
because `namespace` didn't have `CARBON_IF_ERROR` before, although I
might've missed the underlying issue with declarations because only
`namespace` had a relevant test (that is, if #3404 had added
`CARBON_ANY_TOKEN_ON_ERROR`, I wouldn't have had a crash in #3462).
#3424 would've been avoided with this change because there was a
`CARBON_IF_ERROR`, and it was just too restrictive.
2023-12-13 20:28:48 +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
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 6cc5dc7736 Replace the NodeKind StructFieldUnknown with InvalidParse. (#3482)
StructFieldUnknown was used previously for invalid parses. But we have
added other, more common ways of talking about those; so this is
removing the special-case.
2023-12-12 00:43:04 +00:00
Chandler Carruthandjosh11b 6037b11e90 Teach the parser to not crash on the spaceship <=> operator. (#3494)
This remains structurally valid although we don't use this operator or
have a design for it, this at least fixes a fuzzer-found crash.

---------

Co-authored-by: josh11b <josh11b@users.noreply.github.com>
2023-12-11 22:53:07 +00:00
josh11bandJon Ross-Perkins 6067ca3f49 Change return of SkipPastLikelyEnd to be last consumed token (#3493)
This approach means the parse subtree includes the full token range
consumed.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2023-12-11 22:11:09 +00:00
josh11b 1addf10054 Move add invalid node. Follow up to #3473. (#3491)
I think this matches expectations about how the parse code should be
structured better.
2023-12-11 17:22:17 +00:00
josh11bandJon Ross-Perkins 5f439b842b Parsing impl...as (#3473)
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2023-12-09 04:04:00 +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
josh11b b7d129b88c Add PushState overload to combine Parse::State change with StateStackEntry (#3485)
Shortens a common `PushState` pattern
2023-12-08 23:58:30 +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
Jon Ross-Perkins 50071532fe Refactor state construction and change how the decl loop makes state. (#3467)
Building on #3463. The PushState+PopState to construct a state feels
worth cleanup. The rest is just kind of making it easier to do without
adding another PushState overload.
2023-12-08 17:29:23 +00:00
josh11b 3b0923c81d Add interface support to check (#3474)
Largely copied from the `class` code
2023-12-08 17:13:49 +00:00
2705a32b92 Refactor the decl scope loop to consolidate modifier handling. (#3463)
Building on #3462, trying to make the flow easier to see, also making a
little more use of macros for boilerplate modifier handling.

---------

Co-authored-by: josh11b <josh11b@users.noreply.github.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2023-12-08 17:04:05 +00:00
Geoff RomerandRichard Smith 39750b9925 Parse support for tuple patterns in var and let (#3448)
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2023-12-08 01:16:03 +00:00
Jon Ross-Perkins ef0fa81a58 Upgrade clang-format version (#3471)
This apparently includes a fix for
https://github.com/llvm/llvm-project/issues/47664 (previously
https://bugs.llvm.org/show_bug.cgi?id=48320)

Note this continues with a clang-format version that's different from
the compiler versions we're often using, but the differences in
formatting seem worthwhile.
2023-12-07 19:09:36 +00:00
josh11b 2e29b48d26 Drop GetDeclContext from parse, errors will be diagnosed in check (#3468)
The criteria being enforced is not correct since `final` and `default`
functions in interfaces have definitions.
2023-12-07 16:35:57 +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
josh11b fa07b52b8b Precedence terminology (#3465) 2023-12-06 23:10:33 +00:00
Jon Ross-Perkins 9b194a31c9 Support modifiers on namespace, in theory. (#3462)
In theory because none are allowed. This is to improve consistency in
handle_decl_name_scope's modifier handling, removing the namespace
special-case.

I noticed there's a crash bug on `impl <declaration>` which I'll address
separately.

This builds on #3461.
2023-12-06 22:45:19 +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
josh11b a970b1e587 Require extend before base: BaseType; (#3459) 2023-12-06 20:14:16 +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