mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 17:51:05 +01:00
Refactor checking flow to allow for ordering based on import/package. (#3379)
As I was working on this, I noticed `import` and `library` syntax needs to be fixed for how it imports the current package, and for `Main` libraries. This mostly reflects the current state in its testing. Otherwise, this should handle most of the errors I could think of: dependency cycles, redundant imports, etc. It does not actually deal with the nuances of cross-IR references. --------- Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This commit is contained in:
co-authored by
Richard Smith
parent
09b5ab14d8
commit
d024403dc4
+32
-17
@@ -432,10 +432,6 @@ class Driver::CompilationUnit {
|
||||
|
||||
// Parses tokens. Returns true on success.
|
||||
auto RunParse() -> bool {
|
||||
// Can be called when the file fails to load, so ensure there's source.
|
||||
if (!source_) {
|
||||
return false;
|
||||
}
|
||||
CARBON_CHECK(tokens_);
|
||||
|
||||
LogCall("Parse::Tree::Parse", [&] {
|
||||
@@ -449,18 +445,19 @@ class Driver::CompilationUnit {
|
||||
return !parse_tree_->has_errors();
|
||||
}
|
||||
|
||||
// Check the parse tree and produce SemIR. Returns true on success.
|
||||
auto RunCheck(const SemIR::File& builtins) -> bool {
|
||||
// Can be called when the file fails to load, so ensure there's source.
|
||||
if (!source_) {
|
||||
return false;
|
||||
}
|
||||
// Returns information needed to check this unit.
|
||||
auto GetCheckUnit() -> Check::Unit {
|
||||
CARBON_CHECK(parse_tree_);
|
||||
return {.value_stores = &value_stores_,
|
||||
.tokens = &*tokens_,
|
||||
.parse_tree = &*parse_tree_,
|
||||
.consumer = consumer_,
|
||||
.sem_ir = &sem_ir_};
|
||||
}
|
||||
|
||||
LogCall("Check::CheckParseTree", [&] {
|
||||
sem_ir_ = Check::CheckParseTree(value_stores_, builtins, *tokens_,
|
||||
*parse_tree_, *consumer_, vlog_stream_);
|
||||
});
|
||||
// Runs post-check logic. Returns true if checking succeeded for the IR.
|
||||
auto PostCheck() -> bool {
|
||||
CARBON_CHECK(sem_ir_);
|
||||
|
||||
// We've finished all steps that can produce diagnostics. Emit the
|
||||
// diagnostics now, so that the developer sees them sooner and doesn't need
|
||||
@@ -575,6 +572,8 @@ class Driver::CompilationUnit {
|
||||
value_stores_.OutputYaml(input_file_name_));
|
||||
}
|
||||
|
||||
auto has_source() -> bool { return source_.has_value(); }
|
||||
|
||||
private:
|
||||
// Wraps a call with log statements to indicate start and end.
|
||||
auto LogCall(llvm::StringLiteral label, llvm::function_ref<void()> fn)
|
||||
@@ -641,10 +640,15 @@ auto Driver::Compile(const CompileOptions& options) -> bool {
|
||||
if (options.phase == CompileOptions::Phase::Lex) {
|
||||
return success_before_lower;
|
||||
}
|
||||
// Parse and check phases examine `has_source` because they want to proceed if
|
||||
// lex failed, but not if source doesn't exist. Later steps are skipped if
|
||||
// anything failed, so don't need this.
|
||||
|
||||
// Parse.
|
||||
for (auto& unit : units) {
|
||||
success_before_lower &= unit->RunParse();
|
||||
if (unit->has_source()) {
|
||||
success_before_lower &= unit->RunParse();
|
||||
}
|
||||
}
|
||||
if (options.phase == CompileOptions::Phase::Parse) {
|
||||
return success_before_lower;
|
||||
@@ -653,9 +657,20 @@ auto Driver::Compile(const CompileOptions& options) -> bool {
|
||||
// Check.
|
||||
SharedValueStores builtin_value_stores;
|
||||
auto builtins = Check::MakeBuiltins(builtin_value_stores);
|
||||
// TODO: Organize units to compile in dependency order.
|
||||
llvm::SmallVector<Check::Unit> check_units;
|
||||
for (auto& unit : units) {
|
||||
success_before_lower &= unit->RunCheck(builtins);
|
||||
if (unit->has_source()) {
|
||||
check_units.push_back(unit->GetCheckUnit());
|
||||
}
|
||||
}
|
||||
CARBON_VLOG() << "*** Check::CheckParseTrees ***\n";
|
||||
Check::CheckParseTrees(builtins, llvm::MutableArrayRef(check_units),
|
||||
vlog_stream_);
|
||||
CARBON_VLOG() << "*** Check::CheckParseTrees done ***\n";
|
||||
for (auto& unit : units) {
|
||||
if (unit->has_source()) {
|
||||
success_before_lower &= unit->PostCheck();
|
||||
}
|
||||
}
|
||||
if (options.phase == CompileOptions::Phase::Check) {
|
||||
return success_before_lower;
|
||||
|
||||
Reference in New Issue
Block a user