mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 22:02:23 +01:00
This change deliberately breaks away from the line/column ordering, and instead focuses on a last byte offset corresponding to the final token processed as part of producing the message. Where that's equal, this maintains stable ordering in order to reflect the order that diagnostics were produced. The intent of this approach is that lex, parse, and check diagnostics are interleaved based on where they are produced, but that subexpressions still have diagnostics emitted prior to containing expressions. In particular, the prior line/column sort essentially sorted on the _start_ of where a diagnostic was associated, and this is closer to sorting based on the _end_. As a consequence, something like `F(1 2)` will have the error for `1 2` emitted _before_ a diagnostic for `F(1 2)` not matching parameters, instead of _after_. In check, we track the last handled node. This provides a last_byte_offset _separate_ from where a diagnostic is associated. The intent is that this creates an ordering of diagnostics which may be associated with earlier code, to cause the diagnostics to be emitted later. An example consequence of this is the change in ordering of modifier diagnostics: we are diagnosing those from the same place, but they have the same last_byte_offset, so we print them out in the order produced. I've added similar tracking to parse, but cannot identify any test which is affected by it (note the separate commit, I thought about this late). I'm not sure whether we have good out-of-order errors we could produce for this. A significant number of tests have reordered diagnostics as a consequence of this change, so this change does not add further testing.
63 lines
2.2 KiB
C++
63 lines
2.2 KiB
C++
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
#include "toolchain/parse/parse.h"
|
|
|
|
#include "common/check.h"
|
|
#include "toolchain/base/pretty_stack_trace_function.h"
|
|
#include "toolchain/parse/context.h"
|
|
#include "toolchain/parse/handle.h"
|
|
#include "toolchain/parse/node_kind.h"
|
|
|
|
namespace Carbon::Parse {
|
|
|
|
auto HandleInvalid(Context& context) -> void {
|
|
CARBON_FATAL("The Invalid state shouldn't be on the stack: {0}",
|
|
context.PopState());
|
|
}
|
|
|
|
auto Parse(Lex::TokenizedBuffer& tokens, DiagnosticConsumer& consumer,
|
|
llvm::raw_ostream* vlog_stream) -> Tree {
|
|
// Delegate to the parser.
|
|
Tree tree(tokens);
|
|
Context context(&tree, &tokens, &consumer, vlog_stream);
|
|
PrettyStackTraceFunction context_dumper(
|
|
[&](llvm::raw_ostream& output) { context.PrintForStackDump(output); });
|
|
|
|
context.AddLeafNode(NodeKind::FileStart,
|
|
context.ConsumeChecked(Lex::TokenKind::FileStart));
|
|
|
|
context.PushState(State::DeclScopeLoop);
|
|
|
|
while (!context.state_stack().empty()) {
|
|
switch (context.state_stack().back().state) {
|
|
#define CARBON_PARSE_STATE(Name) \
|
|
case State::Name: \
|
|
Handle##Name(context); \
|
|
break;
|
|
#include "toolchain/parse/state.def"
|
|
}
|
|
}
|
|
|
|
context.AddLeafNode(NodeKind::FileEnd, *context.position());
|
|
|
|
// Mark the tree as potentially having errors if there were errors coming in
|
|
// from the tokenized buffer or we diagnosed new errors.
|
|
tree.set_has_errors(tokens.has_errors() || context.has_errors());
|
|
|
|
if (auto verify = tree.Verify(); !verify.ok()) {
|
|
// TODO: This is temporarily printing to stderr directly during development.
|
|
// If we can, restrict this to a subtree with the error and add it to the
|
|
// stack trace (such as with PrettyStackTraceFunction). Otherwise, switch
|
|
// back to vlog_stream prior to broader distribution so that end users are
|
|
// hopefully comfortable copy-pasting stderr when there are bugs in tree
|
|
// construction.
|
|
tree.Print(llvm::errs());
|
|
CARBON_FATAL("Invalid tree returned by Parse(): {0}", verify.error());
|
|
}
|
|
return tree;
|
|
}
|
|
|
|
} // namespace Carbon::Parse
|