tint/dependency_graph: Handle diagnostic controls

Bug: 1809
Change-Id: I376d0758a09463b37e2d71040cc8add5897ef8bb
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/117564
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
James Price 2023-01-24 21:01:36 +00:00
parent 15bf15d55f
commit 098e3d8f90
2 changed files with 24 additions and 18 deletions

View File

@ -31,6 +31,7 @@
#include "src/tint/ast/continue_statement.h"
#include "src/tint/ast/depth_multisampled_texture.h"
#include "src/tint/ast/depth_texture.h"
#include "src/tint/ast/diagnostic_attribute.h"
#include "src/tint/ast/discard_statement.h"
#include "src/tint/ast/external_texture.h"
#include "src/tint/ast/f16.h"
@ -204,8 +205,11 @@ class DependencyScanner {
TraverseExpression(var->initializer);
}
},
[&](const ast::DiagnosticControl*) {
// Diagnostic control directives do not affect the dependency graph.
},
[&](const ast::Enable*) {
// Enable directives do not effect the dependency graph.
// Enable directives do not affect the dependency graph.
},
[&](const ast::ConstAssert* assertion) { TraverseExpression(assertion->condition); },
[&](Default) { UnhandledNode(diagnostics_, global->node); });
@ -454,9 +458,9 @@ class DependencyScanner {
return;
}
if (attr->IsAnyOf<ast::BuiltinAttribute, ast::InternalAttribute, ast::InterpolateAttribute,
ast::InvariantAttribute, ast::StageAttribute, ast::StrideAttribute,
ast::StructMemberOffsetAttribute>()) {
if (attr->IsAnyOf<ast::BuiltinAttribute, ast::DiagnosticAttribute, ast::InternalAttribute,
ast::InterpolateAttribute, ast::InvariantAttribute, ast::StageAttribute,
ast::StrideAttribute, ast::StructMemberOffsetAttribute>()) {
return;
}
@ -555,6 +559,7 @@ struct DependencyAnalysis {
[&](const ast::TypeDecl* td) { return td->name; },
[&](const ast::Function* func) { return func->symbol; },
[&](const ast::Variable* var) { return var->symbol; },
[&](const ast::DiagnosticControl*) { return Symbol(); },
[&](const ast::Enable*) { return Symbol(); },
[&](const ast::ConstAssert*) { return Symbol(); },
[&](Default) {
@ -663,16 +668,16 @@ struct DependencyAnalysis {
return; // This code assumes there are no undeclared identifiers.
}
// Make sure all 'enable' directives go before any other global declarations.
// Make sure all directives go before any other global declarations.
for (auto* global : declaration_order_) {
if (auto* enable = global->node->As<ast::Enable>()) {
sorted_.Add(enable);
if (global->node->IsAnyOf<ast::DiagnosticControl, ast::Enable>()) {
sorted_.Add(global->node);
}
}
for (auto* global : declaration_order_) {
if (global->node->Is<ast::Enable>()) {
// Skip 'enable' directives here, as they are already added.
if (global->node->IsAnyOf<ast::DiagnosticControl, ast::Enable>()) {
// Skip directives here, as they are already added.
continue;
}
utils::UniqueVector<const Global*, 8> stack;

View File

@ -1088,18 +1088,19 @@ INSTANTIATE_TEST_SUITE_P(Functions,
testing::Combine(testing::ValuesIn(kFuncDeclKinds),
testing::ValuesIn(kFuncUseKinds)));
TEST_F(ResolverDependencyGraphOrderedGlobalsTest, EnableFirst) {
// Test that enable nodes always go before any other global declaration.
// Although all enable directives in a valid WGSL program must go before any other global
// declaration, a transform may produce such a AST tree that has some declarations before enable
// nodes. DependencyGraph should deal with these cases.
TEST_F(ResolverDependencyGraphOrderedGlobalsTest, DirectiveFirst) {
// Test that directive nodes always go before any other global declaration.
// Although all directives in a valid WGSL program must go before any other global declaration,
// a transform may produce such a AST tree that has some declarations before directive nodes.
// DependencyGraph should deal with these cases.
auto* var_1 = GlobalVar("SYMBOL1", ty.i32());
auto* enable_1 = Enable(ast::Extension::kF16);
auto* enable = Enable(ast::Extension::kF16);
auto* var_2 = GlobalVar("SYMBOL2", ty.f32());
auto* enable_2 = Enable(ast::Extension::kF16);
auto* diagnostic = DiagnosticControl(ast::DiagnosticSeverity::kWarning, Expr("foo"));
AST().AddDiagnosticControl(diagnostic);
EXPECT_THAT(AST().GlobalDeclarations(), ElementsAre(var_1, enable_1, var_2, enable_2));
EXPECT_THAT(Build().ordered_globals, ElementsAre(enable_1, enable_2, var_1, var_2));
EXPECT_THAT(AST().GlobalDeclarations(), ElementsAre(var_1, enable, var_2, diagnostic));
EXPECT_THAT(Build().ordered_globals, ElementsAre(enable, diagnostic, var_1, var_2));
}
} // namespace ordered_globals