mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-07 05:36:04 +00:00
tint/ast: Make DiagnosticControl a plain struct
Introduce DiagnosticDirective, which contains a DiagnosticControl struct (as does DiagnosticAttribute). Bug: tint:1809 Change-Id: I204001266ee472d2ee2827614a306acad53f12ba Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/118060 Reviewed-by: Ben Clayton <bclayton@google.com> Commit-Queue: James Price <jrprice@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
ededebbcf3
commit
98dc5a86cc
@ -264,6 +264,7 @@ libtint_source_set("libtint_syntax_tree_src") {
|
|||||||
"ast/depth_texture.h",
|
"ast/depth_texture.h",
|
||||||
"ast/diagnostic_attribute.h",
|
"ast/diagnostic_attribute.h",
|
||||||
"ast/diagnostic_control.h",
|
"ast/diagnostic_control.h",
|
||||||
|
"ast/diagnostic_directive.h",
|
||||||
"ast/disable_validation_attribute.h",
|
"ast/disable_validation_attribute.h",
|
||||||
"ast/discard_statement.h",
|
"ast/discard_statement.h",
|
||||||
"ast/enable.h",
|
"ast/enable.h",
|
||||||
@ -597,6 +598,8 @@ libtint_source_set("libtint_ast_src") {
|
|||||||
"ast/diagnostic_attribute.h",
|
"ast/diagnostic_attribute.h",
|
||||||
"ast/diagnostic_control.cc",
|
"ast/diagnostic_control.cc",
|
||||||
"ast/diagnostic_control.h",
|
"ast/diagnostic_control.h",
|
||||||
|
"ast/diagnostic_directive.cc",
|
||||||
|
"ast/diagnostic_directive.h",
|
||||||
"ast/disable_validation_attribute.cc",
|
"ast/disable_validation_attribute.cc",
|
||||||
"ast/disable_validation_attribute.h",
|
"ast/disable_validation_attribute.h",
|
||||||
"ast/discard_statement.cc",
|
"ast/discard_statement.cc",
|
||||||
@ -1321,6 +1324,7 @@ if (tint_build_unittests) {
|
|||||||
"ast/continue_statement_test.cc",
|
"ast/continue_statement_test.cc",
|
||||||
"ast/diagnostic_attribute_test.cc",
|
"ast/diagnostic_attribute_test.cc",
|
||||||
"ast/diagnostic_control_test.cc",
|
"ast/diagnostic_control_test.cc",
|
||||||
|
"ast/diagnostic_directive_test.cc",
|
||||||
"ast/discard_statement_test.cc",
|
"ast/discard_statement_test.cc",
|
||||||
"ast/enable_test.cc",
|
"ast/enable_test.cc",
|
||||||
"ast/extension_test.cc",
|
"ast/extension_test.cc",
|
||||||
|
@ -130,6 +130,8 @@ list(APPEND TINT_LIB_SRCS
|
|||||||
ast/diagnostic_attribute.h
|
ast/diagnostic_attribute.h
|
||||||
ast/diagnostic_control.cc
|
ast/diagnostic_control.cc
|
||||||
ast/diagnostic_control.h
|
ast/diagnostic_control.h
|
||||||
|
ast/diagnostic_directive.cc
|
||||||
|
ast/diagnostic_directive.h
|
||||||
ast/disable_validation_attribute.cc
|
ast/disable_validation_attribute.cc
|
||||||
ast/disable_validation_attribute.h
|
ast/disable_validation_attribute.h
|
||||||
ast/discard_statement.cc
|
ast/discard_statement.cc
|
||||||
@ -843,6 +845,7 @@ if(TINT_BUILD_TESTS)
|
|||||||
ast/depth_texture_test.cc
|
ast/depth_texture_test.cc
|
||||||
ast/diagnostic_attribute_test.cc
|
ast/diagnostic_attribute_test.cc
|
||||||
ast/diagnostic_control_test.cc
|
ast/diagnostic_control_test.cc
|
||||||
|
ast/diagnostic_directive_test.cc
|
||||||
ast/discard_statement_test.cc
|
ast/discard_statement_test.cc
|
||||||
ast/enable_test.cc
|
ast/enable_test.cc
|
||||||
ast/external_texture_test.cc
|
ast/external_texture_test.cc
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "src/tint/ast/diagnostic_attribute.h"
|
#include "src/tint/ast/diagnostic_attribute.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "src/tint/program_builder.h"
|
#include "src/tint/program_builder.h"
|
||||||
|
|
||||||
@ -25,8 +26,8 @@ namespace tint::ast {
|
|||||||
DiagnosticAttribute::DiagnosticAttribute(ProgramID pid,
|
DiagnosticAttribute::DiagnosticAttribute(ProgramID pid,
|
||||||
NodeID nid,
|
NodeID nid,
|
||||||
const Source& src,
|
const Source& src,
|
||||||
const ast::DiagnosticControl* dc)
|
ast::DiagnosticControl&& dc)
|
||||||
: Base(pid, nid, src), control(dc) {}
|
: Base(pid, nid, src), control(std::move(dc)) {}
|
||||||
|
|
||||||
DiagnosticAttribute::~DiagnosticAttribute() = default;
|
DiagnosticAttribute::~DiagnosticAttribute() = default;
|
||||||
|
|
||||||
@ -37,8 +38,9 @@ std::string DiagnosticAttribute::Name() const {
|
|||||||
const DiagnosticAttribute* DiagnosticAttribute::Clone(CloneContext* ctx) const {
|
const DiagnosticAttribute* DiagnosticAttribute::Clone(CloneContext* ctx) const {
|
||||||
// Clone arguments outside of create() call to have deterministic ordering
|
// Clone arguments outside of create() call to have deterministic ordering
|
||||||
auto src = ctx->Clone(source);
|
auto src = ctx->Clone(source);
|
||||||
auto dc = ctx->Clone(control);
|
auto rule = ctx->Clone(control.rule_name);
|
||||||
return ctx->dst->create<DiagnosticAttribute>(src, dc);
|
DiagnosticControl dc(control.severity, rule);
|
||||||
|
return ctx->dst->create<DiagnosticAttribute>(src, std::move(dc));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace tint::ast
|
} // namespace tint::ast
|
||||||
|
@ -30,10 +30,7 @@ class DiagnosticAttribute final : public Castable<DiagnosticAttribute, Attribute
|
|||||||
/// @param nid the unique node identifier
|
/// @param nid the unique node identifier
|
||||||
/// @param src the source of this node
|
/// @param src the source of this node
|
||||||
/// @param dc the diagnostic control
|
/// @param dc the diagnostic control
|
||||||
DiagnosticAttribute(ProgramID pid,
|
DiagnosticAttribute(ProgramID pid, NodeID nid, const Source& src, ast::DiagnosticControl&& dc);
|
||||||
NodeID nid,
|
|
||||||
const Source& src,
|
|
||||||
const ast::DiagnosticControl* dc);
|
|
||||||
~DiagnosticAttribute() override;
|
~DiagnosticAttribute() override;
|
||||||
|
|
||||||
/// @returns the WGSL name for the attribute
|
/// @returns the WGSL name for the attribute
|
||||||
@ -44,8 +41,8 @@ class DiagnosticAttribute final : public Castable<DiagnosticAttribute, Attribute
|
|||||||
/// @return the newly cloned node
|
/// @return the newly cloned node
|
||||||
const DiagnosticAttribute* Clone(CloneContext* ctx) const override;
|
const DiagnosticAttribute* Clone(CloneContext* ctx) const override;
|
||||||
|
|
||||||
/// The diagnostic control expression.
|
/// The diagnostic control.
|
||||||
const ast::DiagnosticControl* const control;
|
const ast::DiagnosticControl control;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tint::ast
|
} // namespace tint::ast
|
||||||
|
@ -24,8 +24,8 @@ TEST_F(DiagnosticAttributeTest, Creation) {
|
|||||||
auto* name = Ident("foo");
|
auto* name = Ident("foo");
|
||||||
auto* d = DiagnosticAttribute(DiagnosticSeverity::kWarning, name);
|
auto* d = DiagnosticAttribute(DiagnosticSeverity::kWarning, name);
|
||||||
EXPECT_EQ(d->Name(), "diagnostic");
|
EXPECT_EQ(d->Name(), "diagnostic");
|
||||||
EXPECT_EQ(d->control->severity, DiagnosticSeverity::kWarning);
|
EXPECT_EQ(d->control.severity, DiagnosticSeverity::kWarning);
|
||||||
EXPECT_EQ(d->control->rule_name, name);
|
EXPECT_EQ(d->control.rule_name, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -24,18 +24,13 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/tint/program_builder.h"
|
#include "src/tint/ast/identifier.h"
|
||||||
|
#include "src/tint/ast/templated_identifier.h"
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::DiagnosticControl);
|
|
||||||
|
|
||||||
namespace tint::ast {
|
namespace tint::ast {
|
||||||
|
|
||||||
DiagnosticControl::DiagnosticControl(ProgramID pid,
|
DiagnosticControl::DiagnosticControl(DiagnosticSeverity sev, const Identifier* rule)
|
||||||
NodeID nid,
|
: severity(sev), rule_name(rule) {
|
||||||
const Source& src,
|
|
||||||
DiagnosticSeverity sev,
|
|
||||||
const Identifier* rule)
|
|
||||||
: Base(pid, nid, src), severity(sev), rule_name(rule) {
|
|
||||||
TINT_ASSERT(AST, rule != nullptr);
|
TINT_ASSERT(AST, rule != nullptr);
|
||||||
if (rule) {
|
if (rule) {
|
||||||
// It is invalid for a diagnostic rule name to be templated
|
// It is invalid for a diagnostic rule name to be templated
|
||||||
@ -43,14 +38,6 @@ DiagnosticControl::DiagnosticControl(ProgramID pid,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DiagnosticControl::~DiagnosticControl() = default;
|
|
||||||
|
|
||||||
const DiagnosticControl* DiagnosticControl::Clone(CloneContext* ctx) const {
|
|
||||||
auto src = ctx->Clone(source);
|
|
||||||
auto rule = ctx->Clone(rule_name);
|
|
||||||
return ctx->dst->create<DiagnosticControl>(src, severity, rule);
|
|
||||||
}
|
|
||||||
|
|
||||||
diag::Severity ToSeverity(DiagnosticSeverity sc) {
|
diag::Severity ToSeverity(DiagnosticSeverity sc) {
|
||||||
switch (sc) {
|
switch (sc) {
|
||||||
case DiagnosticSeverity::kError:
|
case DiagnosticSeverity::kError:
|
||||||
|
@ -14,18 +14,13 @@ See:
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/tint/program_builder.h"
|
#include "src/tint/ast/identifier.h"
|
||||||
|
#include "src/tint/ast/templated_identifier.h"
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::DiagnosticControl);
|
|
||||||
|
|
||||||
namespace tint::ast {
|
namespace tint::ast {
|
||||||
|
|
||||||
DiagnosticControl::DiagnosticControl(ProgramID pid,
|
DiagnosticControl::DiagnosticControl(DiagnosticSeverity sev, const Identifier* rule)
|
||||||
NodeID nid,
|
: severity(sev), rule_name(rule) {
|
||||||
const Source& src,
|
|
||||||
DiagnosticSeverity sev,
|
|
||||||
const Identifier* rule)
|
|
||||||
: Base(pid, nid, src), severity(sev), rule_name(rule) {
|
|
||||||
TINT_ASSERT(AST, rule != nullptr);
|
TINT_ASSERT(AST, rule != nullptr);
|
||||||
if (rule) {
|
if (rule) {
|
||||||
// It is invalid for a diagnostic rule name to be templated
|
// It is invalid for a diagnostic rule name to be templated
|
||||||
@ -33,14 +28,6 @@ DiagnosticControl::DiagnosticControl(ProgramID pid,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DiagnosticControl::~DiagnosticControl() = default;
|
|
||||||
|
|
||||||
const DiagnosticControl* DiagnosticControl::Clone(CloneContext* ctx) const {
|
|
||||||
auto src = ctx->Clone(source);
|
|
||||||
auto rule = ctx->Clone(rule_name);
|
|
||||||
return ctx->dst->create<DiagnosticControl>(src, severity, rule);
|
|
||||||
}
|
|
||||||
|
|
||||||
diag::Severity ToSeverity(DiagnosticSeverity sc) {
|
diag::Severity ToSeverity(DiagnosticSeverity sc) {
|
||||||
switch (sc) {
|
switch (sc) {
|
||||||
case DiagnosticSeverity::kError:
|
case DiagnosticSeverity::kError:
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "src/tint/ast/node.h"
|
#include "src/tint/diagnostic/diagnostic.h"
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
namespace tint::ast {
|
namespace tint::ast {
|
||||||
@ -91,26 +91,15 @@ diag::Severity ToSeverity(DiagnosticSeverity sc);
|
|||||||
using DiagnosticRuleSeverities = std::unordered_map<DiagnosticRule, DiagnosticSeverity>;
|
using DiagnosticRuleSeverities = std::unordered_map<DiagnosticRule, DiagnosticSeverity>;
|
||||||
|
|
||||||
/// A diagnostic control used for diagnostic directives and attributes.
|
/// A diagnostic control used for diagnostic directives and attributes.
|
||||||
class DiagnosticControl : public Castable<DiagnosticControl, Node> {
|
struct DiagnosticControl {
|
||||||
public:
|
public:
|
||||||
|
/// Default constructor.
|
||||||
|
DiagnosticControl() {}
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param pid the identifier of the program that owns this node
|
|
||||||
/// @param nid the unique node identifier
|
|
||||||
/// @param src the source of this node
|
|
||||||
/// @param sev the diagnostic severity
|
/// @param sev the diagnostic severity
|
||||||
/// @param rule the diagnostic rule name
|
/// @param rule the diagnostic rule name
|
||||||
DiagnosticControl(ProgramID pid,
|
DiagnosticControl(DiagnosticSeverity sev, const Identifier* rule);
|
||||||
NodeID nid,
|
|
||||||
const Source& src,
|
|
||||||
DiagnosticSeverity sev,
|
|
||||||
const Identifier* rule);
|
|
||||||
|
|
||||||
~DiagnosticControl() override;
|
|
||||||
|
|
||||||
/// Clones this node and all transitive child nodes using the `CloneContext` `ctx`.
|
|
||||||
/// @param ctx the clone context
|
|
||||||
/// @return the newly cloned node
|
|
||||||
const DiagnosticControl* Clone(CloneContext* ctx) const override;
|
|
||||||
|
|
||||||
/// The diagnostic severity control.
|
/// The diagnostic severity control.
|
||||||
DiagnosticSeverity severity;
|
DiagnosticSeverity severity;
|
||||||
|
@ -17,7 +17,7 @@ See:
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "src/tint/ast/node.h"
|
#include "src/tint/diagnostic/diagnostic.h"
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
namespace tint::ast {
|
namespace tint::ast {
|
||||||
@ -39,26 +39,15 @@ diag::Severity ToSeverity(DiagnosticSeverity sc);
|
|||||||
using DiagnosticRuleSeverities = std::unordered_map<DiagnosticRule, DiagnosticSeverity>;
|
using DiagnosticRuleSeverities = std::unordered_map<DiagnosticRule, DiagnosticSeverity>;
|
||||||
|
|
||||||
/// A diagnostic control used for diagnostic directives and attributes.
|
/// A diagnostic control used for diagnostic directives and attributes.
|
||||||
class DiagnosticControl : public Castable<DiagnosticControl, Node> {
|
struct DiagnosticControl {
|
||||||
public:
|
public:
|
||||||
|
/// Default constructor.
|
||||||
|
DiagnosticControl() {}
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param pid the identifier of the program that owns this node
|
|
||||||
/// @param nid the unique node identifier
|
|
||||||
/// @param src the source of this node
|
|
||||||
/// @param sev the diagnostic severity
|
/// @param sev the diagnostic severity
|
||||||
/// @param rule the diagnostic rule name
|
/// @param rule the diagnostic rule name
|
||||||
DiagnosticControl(ProgramID pid,
|
DiagnosticControl(DiagnosticSeverity sev, const Identifier* rule);
|
||||||
NodeID nid,
|
|
||||||
const Source& src,
|
|
||||||
DiagnosticSeverity sev,
|
|
||||||
const Identifier* rule);
|
|
||||||
|
|
||||||
~DiagnosticControl() override;
|
|
||||||
|
|
||||||
/// Clones this node and all transitive child nodes using the `CloneContext` `ctx`.
|
|
||||||
/// @param ctx the clone context
|
|
||||||
/// @return the newly cloned node
|
|
||||||
const DiagnosticControl* Clone(CloneContext* ctx) const override;
|
|
||||||
|
|
||||||
/// The diagnostic severity control.
|
/// The diagnostic severity control.
|
||||||
DiagnosticSeverity severity;
|
DiagnosticSeverity severity;
|
||||||
|
@ -31,26 +31,12 @@ namespace {
|
|||||||
|
|
||||||
using DiagnosticControlTest = TestHelper;
|
using DiagnosticControlTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(DiagnosticControlTest, Creation) {
|
|
||||||
auto* name = Ident("foo");
|
|
||||||
Source source;
|
|
||||||
source.range.begin = Source::Location{20, 2};
|
|
||||||
source.range.end = Source::Location{20, 5};
|
|
||||||
auto* control = create<ast::DiagnosticControl>(source, DiagnosticSeverity::kWarning, name);
|
|
||||||
EXPECT_EQ(control->source.range.begin.line, 20u);
|
|
||||||
EXPECT_EQ(control->source.range.begin.column, 2u);
|
|
||||||
EXPECT_EQ(control->source.range.end.line, 20u);
|
|
||||||
EXPECT_EQ(control->source.range.end.column, 5u);
|
|
||||||
EXPECT_EQ(control->severity, DiagnosticSeverity::kWarning);
|
|
||||||
EXPECT_EQ(control->rule_name, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(DiagnosticControlTest, Assert_RuleNotTemplated) {
|
TEST_F(DiagnosticControlTest, Assert_RuleNotTemplated) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
b.create<ast::DiagnosticControl>(DiagnosticSeverity::kWarning,
|
ast::DiagnosticControl control(DiagnosticSeverity::kWarning,
|
||||||
b.Ident("name", "a", "b", "c"));
|
b.Ident("name", "a", "b", "c"));
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
@ -21,26 +21,12 @@ namespace {
|
|||||||
|
|
||||||
using DiagnosticControlTest = TestHelper;
|
using DiagnosticControlTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(DiagnosticControlTest, Creation) {
|
|
||||||
auto* name = Ident("foo");
|
|
||||||
Source source;
|
|
||||||
source.range.begin = Source::Location{20, 2};
|
|
||||||
source.range.end = Source::Location{20, 5};
|
|
||||||
auto* control = create<ast::DiagnosticControl>(source, DiagnosticSeverity::kWarning, name);
|
|
||||||
EXPECT_EQ(control->source.range.begin.line, 20u);
|
|
||||||
EXPECT_EQ(control->source.range.begin.column, 2u);
|
|
||||||
EXPECT_EQ(control->source.range.end.line, 20u);
|
|
||||||
EXPECT_EQ(control->source.range.end.column, 5u);
|
|
||||||
EXPECT_EQ(control->severity, DiagnosticSeverity::kWarning);
|
|
||||||
EXPECT_EQ(control->rule_name, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(DiagnosticControlTest, Assert_RuleNotTemplated) {
|
TEST_F(DiagnosticControlTest, Assert_RuleNotTemplated) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
b.create<ast::DiagnosticControl>(DiagnosticSeverity::kWarning,
|
ast::DiagnosticControl control(DiagnosticSeverity::kWarning,
|
||||||
b.Ident("name", "a", "b", "c"));
|
b.Ident("name", "a", "b", "c"));
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
39
src/tint/ast/diagnostic_directive.cc
Normal file
39
src/tint/ast/diagnostic_directive.cc
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Copyright 2023 The Tint Authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "src/tint/ast/diagnostic_directive.h"
|
||||||
|
|
||||||
|
#include "src/tint/program_builder.h"
|
||||||
|
|
||||||
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::DiagnosticDirective);
|
||||||
|
|
||||||
|
namespace tint::ast {
|
||||||
|
|
||||||
|
DiagnosticDirective::DiagnosticDirective(ProgramID pid,
|
||||||
|
NodeID nid,
|
||||||
|
const Source& src,
|
||||||
|
DiagnosticControl&& dc)
|
||||||
|
: Base(pid, nid, src), control(std::move(dc)) {}
|
||||||
|
|
||||||
|
DiagnosticDirective::DiagnosticDirective(DiagnosticDirective&&) = default;
|
||||||
|
|
||||||
|
DiagnosticDirective::~DiagnosticDirective() = default;
|
||||||
|
|
||||||
|
const DiagnosticDirective* DiagnosticDirective::Clone(CloneContext* ctx) const {
|
||||||
|
auto src = ctx->Clone(source);
|
||||||
|
auto rule = ctx->Clone(control.rule_name);
|
||||||
|
DiagnosticControl dc(control.severity, rule);
|
||||||
|
return ctx->dst->create<DiagnosticDirective>(src, std::move(dc));
|
||||||
|
}
|
||||||
|
} // namespace tint::ast
|
58
src/tint/ast/diagnostic_directive.h
Normal file
58
src/tint/ast/diagnostic_directive.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
// Copyright 2023 The Tint Authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#ifndef SRC_TINT_AST_DIAGNOSTIC_DIRECTIVE_H_
|
||||||
|
#define SRC_TINT_AST_DIAGNOSTIC_DIRECTIVE_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "src/tint/ast/diagnostic_control.h"
|
||||||
|
#include "src/tint/ast/node.h"
|
||||||
|
|
||||||
|
namespace tint::ast {
|
||||||
|
|
||||||
|
/// A "diagnostic" directive. Example:
|
||||||
|
/// ```
|
||||||
|
/// // Turn off diagnostics for derivative uniformity violations.
|
||||||
|
/// diagnostic(off, derivative_uniformity);
|
||||||
|
/// ```
|
||||||
|
class DiagnosticDirective final : public Castable<DiagnosticDirective, Node> {
|
||||||
|
public:
|
||||||
|
/// Create a extension
|
||||||
|
/// @param pid the identifier of the program that owns this node
|
||||||
|
/// @param nid the unique node identifier
|
||||||
|
/// @param src the source of this node
|
||||||
|
/// @param dc the diagnostic control
|
||||||
|
DiagnosticDirective(ProgramID pid, NodeID nid, const Source& src, DiagnosticControl&& dc);
|
||||||
|
|
||||||
|
/// Move constructor
|
||||||
|
DiagnosticDirective(DiagnosticDirective&&);
|
||||||
|
|
||||||
|
/// Destructor
|
||||||
|
~DiagnosticDirective() override;
|
||||||
|
|
||||||
|
/// Clones this node and all transitive child nodes using the `CloneContext` `ctx`.
|
||||||
|
/// @param ctx the clone context
|
||||||
|
/// @return the newly cloned node
|
||||||
|
const DiagnosticDirective* Clone(CloneContext* ctx) const override;
|
||||||
|
|
||||||
|
/// The diagnostic control.
|
||||||
|
const DiagnosticControl control;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace tint::ast
|
||||||
|
|
||||||
|
#endif // SRC_TINT_AST_DIAGNOSTIC_DIRECTIVE_H_
|
37
src/tint/ast/diagnostic_directive_test.cc
Normal file
37
src/tint/ast/diagnostic_directive_test.cc
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Copyright 2022 The Tint Authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "src/tint/ast/diagnostic_directive.h"
|
||||||
|
|
||||||
|
#include "src/tint/ast/test_helper.h"
|
||||||
|
|
||||||
|
namespace tint::ast {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using DiagnosticDirectiveTest = TestHelper;
|
||||||
|
|
||||||
|
TEST_F(DiagnosticDirectiveTest, Creation) {
|
||||||
|
auto* name = Ident("foo");
|
||||||
|
DiagnosticControl control(ast::DiagnosticSeverity::kWarning, name);
|
||||||
|
auto* diag = create<ast::DiagnosticDirective>(Source{{{10, 5}, {10, 15}}}, std::move(control));
|
||||||
|
EXPECT_EQ(diag->source.range.begin.line, 10u);
|
||||||
|
EXPECT_EQ(diag->source.range.begin.column, 5u);
|
||||||
|
EXPECT_EQ(diag->source.range.end.line, 10u);
|
||||||
|
EXPECT_EQ(diag->source.range.end.column, 15u);
|
||||||
|
EXPECT_EQ(diag->control.severity, ast::DiagnosticSeverity::kWarning);
|
||||||
|
EXPECT_EQ(diag->control.rule_name, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace tint::ast
|
@ -71,9 +71,9 @@ void Module::BinGlobalDeclaration(const tint::ast::Node* decl, diag::List& diags
|
|||||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, var, program_id);
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, var, program_id);
|
||||||
global_variables_.Push(var);
|
global_variables_.Push(var);
|
||||||
},
|
},
|
||||||
[&](const DiagnosticControl* diag_control) {
|
[&](const DiagnosticDirective* diagnostic) {
|
||||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, diag_control, program_id);
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, diagnostic, program_id);
|
||||||
diagnostic_controls_.Push(diag_control);
|
diagnostic_directives_.Push(diagnostic);
|
||||||
},
|
},
|
||||||
[&](const Enable* enable) {
|
[&](const Enable* enable) {
|
||||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, enable, program_id);
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, enable, program_id);
|
||||||
@ -86,11 +86,11 @@ void Module::BinGlobalDeclaration(const tint::ast::Node* decl, diag::List& diags
|
|||||||
[&](Default) { TINT_ICE(AST, diags) << "Unknown global declaration type"; });
|
[&](Default) { TINT_ICE(AST, diags) << "Unknown global declaration type"; });
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::AddDiagnosticControl(const ast::DiagnosticControl* control) {
|
void Module::AddDiagnosticDirective(const ast::DiagnosticDirective* directive) {
|
||||||
TINT_ASSERT(AST, control);
|
TINT_ASSERT(AST, directive);
|
||||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, control, program_id);
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, directive, program_id);
|
||||||
global_declarations_.Push(control);
|
global_declarations_.Push(directive);
|
||||||
diagnostic_controls_.Push(control);
|
diagnostic_directives_.Push(directive);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::AddEnable(const ast::Enable* enable) {
|
void Module::AddEnable(const ast::Enable* enable) {
|
||||||
@ -143,6 +143,7 @@ void Module::Copy(CloneContext* ctx, const Module* src) {
|
|||||||
functions_.Clear();
|
functions_.Clear();
|
||||||
global_variables_.Clear();
|
global_variables_.Clear();
|
||||||
enables_.Clear();
|
enables_.Clear();
|
||||||
|
diagnostic_directives_.Clear();
|
||||||
|
|
||||||
for (auto* decl : global_declarations_) {
|
for (auto* decl : global_declarations_) {
|
||||||
if (TINT_UNLIKELY(!decl)) {
|
if (TINT_UNLIKELY(!decl)) {
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/tint/ast/const_assert.h"
|
#include "src/tint/ast/const_assert.h"
|
||||||
#include "src/tint/ast/diagnostic_control.h"
|
#include "src/tint/ast/diagnostic_directive.h"
|
||||||
#include "src/tint/ast/enable.h"
|
#include "src/tint/ast/enable.h"
|
||||||
#include "src/tint/ast/function.h"
|
#include "src/tint/ast/function.h"
|
||||||
#include "src/tint/ast/type.h"
|
#include "src/tint/ast/type.h"
|
||||||
@ -93,16 +93,16 @@ class Module final : public Castable<Module, Node> {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a global diagnostic control to the module
|
/// Add a diagnostic directive to the module
|
||||||
/// @param control the diagnostic control to add
|
/// @param diagnostic the diagnostic directive to add
|
||||||
void AddDiagnosticControl(const DiagnosticControl* control);
|
void AddDiagnosticDirective(const DiagnosticDirective* diagnostic);
|
||||||
|
|
||||||
/// Add a enable directive to the module
|
/// Add a enable directive to the module
|
||||||
/// @param ext the enable directive to add
|
/// @param ext the enable directive to add
|
||||||
void AddEnable(const Enable* ext);
|
void AddEnable(const Enable* ext);
|
||||||
|
|
||||||
/// @returns the global diagnostic controls for the module
|
/// @returns the diagnostic directives for the module
|
||||||
const auto& DiagnosticControls() const { return diagnostic_controls_; }
|
const auto& DiagnosticDirectives() const { return diagnostic_directives_; }
|
||||||
|
|
||||||
/// @returns the extension set for the module
|
/// @returns the extension set for the module
|
||||||
const auto& Enables() const { return enables_; }
|
const auto& Enables() const { return enables_; }
|
||||||
@ -154,7 +154,7 @@ class Module final : public Castable<Module, Node> {
|
|||||||
utils::Vector<const TypeDecl*, 16> type_decls_;
|
utils::Vector<const TypeDecl*, 16> type_decls_;
|
||||||
FunctionList functions_;
|
FunctionList functions_;
|
||||||
utils::Vector<const Variable*, 32> global_variables_;
|
utils::Vector<const Variable*, 32> global_variables_;
|
||||||
utils::Vector<const DiagnosticControl*, 8> diagnostic_controls_;
|
utils::Vector<const DiagnosticDirective*, 8> diagnostic_directives_;
|
||||||
utils::Vector<const Enable*, 8> enables_;
|
utils::Vector<const Enable*, 8> enables_;
|
||||||
utils::Vector<const ConstAssert*, 8> const_asserts_;
|
utils::Vector<const ConstAssert*, 8> const_asserts_;
|
||||||
};
|
};
|
||||||
|
@ -149,10 +149,10 @@ TEST_F(ModuleTest, Directives) {
|
|||||||
enable_1,
|
enable_1,
|
||||||
enable_2,
|
enable_2,
|
||||||
}));
|
}));
|
||||||
EXPECT_THAT(program.AST().DiagnosticControls(), ::testing::ContainerEq(utils::Vector{
|
EXPECT_THAT(program.AST().DiagnosticDirectives(), ::testing::ContainerEq(utils::Vector{
|
||||||
diagnostic_1,
|
diagnostic_1,
|
||||||
diagnostic_2,
|
diagnostic_2,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#include "src/tint/ast/depth_texture.h"
|
#include "src/tint/ast/depth_texture.h"
|
||||||
#include "src/tint/ast/diagnostic_attribute.h"
|
#include "src/tint/ast/diagnostic_attribute.h"
|
||||||
#include "src/tint/ast/diagnostic_control.h"
|
#include "src/tint/ast/diagnostic_control.h"
|
||||||
|
#include "src/tint/ast/diagnostic_directive.h"
|
||||||
#include "src/tint/ast/disable_validation_attribute.h"
|
#include "src/tint/ast/disable_validation_attribute.h"
|
||||||
#include "src/tint/ast/discard_statement.h"
|
#include "src/tint/ast/discard_statement.h"
|
||||||
#include "src/tint/ast/enable.h"
|
#include "src/tint/ast/enable.h"
|
||||||
@ -3309,7 +3310,7 @@ class ProgramBuilder {
|
|||||||
static_assert(!traits::IsType<traits::PtrElTy<NAME>, ast::TemplatedIdentifier>,
|
static_assert(!traits::IsType<traits::PtrElTy<NAME>, ast::TemplatedIdentifier>,
|
||||||
"it is invalid for a diagnostic rule name to be templated");
|
"it is invalid for a diagnostic rule name to be templated");
|
||||||
return create<ast::DiagnosticAttribute>(
|
return create<ast::DiagnosticAttribute>(
|
||||||
source, DiagnosticControl(source, severity, std::forward<NAME>(rule_name)));
|
source, ast::DiagnosticControl(severity, Ident(std::forward<NAME>(rule_name))));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::DiagnosticAttribute
|
/// Creates an ast::DiagnosticAttribute
|
||||||
@ -3320,57 +3321,35 @@ class ProgramBuilder {
|
|||||||
const ast::DiagnosticAttribute* DiagnosticAttribute(ast::DiagnosticSeverity severity,
|
const ast::DiagnosticAttribute* DiagnosticAttribute(ast::DiagnosticSeverity severity,
|
||||||
NAME&& rule_name) {
|
NAME&& rule_name) {
|
||||||
return create<ast::DiagnosticAttribute>(
|
return create<ast::DiagnosticAttribute>(
|
||||||
source_, DiagnosticControl(source_, severity, std::forward<NAME>(rule_name)));
|
source_, ast::DiagnosticControl(severity, Ident(std::forward<NAME>(rule_name))));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::DiagnosticControl
|
/// Add a diagnostic directive to the module.
|
||||||
/// @param source the source information
|
/// @param source the source information
|
||||||
/// @param severity the diagnostic severity control
|
/// @param severity the diagnostic severity control
|
||||||
/// @param rule_name the diagnostic rule name
|
/// @param rule_name the diagnostic rule name
|
||||||
/// @returns the diagnostic control pointer
|
/// @returns the diagnostic directive pointer
|
||||||
template <typename NAME>
|
template <typename NAME>
|
||||||
const ast::DiagnosticControl* DiagnosticControl(const Source& source,
|
const ast::DiagnosticDirective* DiagnosticDirective(const Source& source,
|
||||||
ast::DiagnosticSeverity severity,
|
ast::DiagnosticSeverity severity,
|
||||||
NAME&& rule_name) {
|
NAME&& rule_name) {
|
||||||
return create<ast::DiagnosticControl>(source, severity,
|
auto* directive = create<ast::DiagnosticDirective>(
|
||||||
Ident(std::forward<NAME>(rule_name)));
|
source, ast::DiagnosticControl(severity, Ident(std::forward<NAME>(rule_name))));
|
||||||
|
AST().AddDiagnosticDirective(directive);
|
||||||
|
return directive;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::DiagnosticControl
|
/// Add a diagnostic directive to the module.
|
||||||
/// @param severity the diagnostic severity control
|
/// @param severity the diagnostic severity control
|
||||||
/// @param rule_name the diagnostic rule name
|
/// @param rule_name the diagnostic rule name
|
||||||
/// @returns the diagnostic control pointer
|
/// @returns the diagnostic directive pointer
|
||||||
template <typename NAME>
|
template <typename NAME>
|
||||||
const ast::DiagnosticControl* DiagnosticControl(ast::DiagnosticSeverity severity,
|
const ast::DiagnosticDirective* DiagnosticDirective(ast::DiagnosticSeverity severity,
|
||||||
NAME&& rule_name) {
|
NAME&& rule_name) {
|
||||||
return create<ast::DiagnosticControl>(source_, severity,
|
auto* directive = create<ast::DiagnosticDirective>(
|
||||||
Ident(std::forward<NAME>(rule_name)));
|
source_, ast::DiagnosticControl(severity, Ident(std::forward<NAME>(rule_name))));
|
||||||
}
|
AST().AddDiagnosticDirective(directive);
|
||||||
|
return directive;
|
||||||
/// Add a global diagnostic control to the module.
|
|
||||||
/// @param source the source information
|
|
||||||
/// @param severity the diagnostic severity control
|
|
||||||
/// @param rule_name the diagnostic rule name
|
|
||||||
/// @returns the diagnostic control pointer
|
|
||||||
template <typename NAME>
|
|
||||||
const ast::DiagnosticControl* DiagnosticDirective(const Source& source,
|
|
||||||
ast::DiagnosticSeverity severity,
|
|
||||||
NAME&& rule_name) {
|
|
||||||
auto* control = DiagnosticControl(source, severity, Ident(std::forward<NAME>(rule_name)));
|
|
||||||
AST().AddDiagnosticControl(control);
|
|
||||||
return control;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add a global diagnostic control to the module.
|
|
||||||
/// @param severity the diagnostic severity control
|
|
||||||
/// @param rule_name the diagnostic rule name
|
|
||||||
/// @returns the diagnostic control pointer
|
|
||||||
template <typename NAME>
|
|
||||||
const ast::DiagnosticControl* DiagnosticDirective(ast::DiagnosticSeverity severity,
|
|
||||||
NAME&& rule_name) {
|
|
||||||
auto* control = DiagnosticControl(source_, severity, Ident(std::forward<NAME>(rule_name)));
|
|
||||||
AST().AddDiagnosticControl(control);
|
|
||||||
return control;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the current builder source to `src`
|
/// Sets the current builder source to `src`
|
||||||
|
@ -383,6 +383,7 @@ Maybe<Void> ParserImpl::diagnostic_directive() {
|
|||||||
return Failure::kNoMatch;
|
return Failure::kNoMatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto source = last_source();
|
||||||
auto control = expect_diagnostic_control();
|
auto control = expect_diagnostic_control();
|
||||||
if (control.errored) {
|
if (control.errored) {
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
@ -392,7 +393,8 @@ Maybe<Void> ParserImpl::diagnostic_directive() {
|
|||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
|
|
||||||
builder_.AST().AddDiagnosticControl(std::move(control.value));
|
auto* directive = create<ast::DiagnosticDirective>(source, std::move(control.value));
|
||||||
|
builder_.AST().AddDiagnosticDirective(directive);
|
||||||
|
|
||||||
return kSuccess;
|
return kSuccess;
|
||||||
});
|
});
|
||||||
@ -3587,7 +3589,7 @@ Maybe<const ast::Attribute*> ParserImpl::attribute() {
|
|||||||
if (control.errored) {
|
if (control.errored) {
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
return create<ast::DiagnosticAttribute>(t.source(), control.value);
|
return create<ast::DiagnosticAttribute>(t.source(), std::move(control.value));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t == "fragment") {
|
if (t == "fragment") {
|
||||||
@ -3756,9 +3758,8 @@ Expect<ast::DiagnosticSeverity> ParserImpl::expect_severity_control_name() {
|
|||||||
|
|
||||||
// diagnostic_control
|
// diagnostic_control
|
||||||
// : PAREN_LEFT severity_control_name COMMA ident_pattern_token COMMA ? PAREN_RIGHT
|
// : PAREN_LEFT severity_control_name COMMA ident_pattern_token COMMA ? PAREN_RIGHT
|
||||||
Expect<const ast::DiagnosticControl*> ParserImpl::expect_diagnostic_control() {
|
Expect<ast::DiagnosticControl> ParserImpl::expect_diagnostic_control() {
|
||||||
auto source = last_source();
|
return expect_paren_block("diagnostic control", [&]() -> Expect<ast::DiagnosticControl> {
|
||||||
return expect_paren_block("diagnostic control", [&]() -> Expect<const ast::DiagnosticControl*> {
|
|
||||||
auto severity_control = expect_severity_control_name();
|
auto severity_control = expect_severity_control_name();
|
||||||
if (severity_control.errored) {
|
if (severity_control.errored) {
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
@ -3774,8 +3775,8 @@ Expect<const ast::DiagnosticControl*> ParserImpl::expect_diagnostic_control() {
|
|||||||
}
|
}
|
||||||
match(Token::Type::kComma);
|
match(Token::Type::kComma);
|
||||||
|
|
||||||
return create<ast::DiagnosticControl>(source, severity_control.value,
|
return ast::DiagnosticControl(severity_control.value,
|
||||||
builder_.Ident(rule_name.source, rule_name.value));
|
builder_.Ident(rule_name.source, rule_name.value));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -717,7 +717,7 @@ class ParserImpl {
|
|||||||
Expect<ast::DiagnosticSeverity> expect_severity_control_name();
|
Expect<ast::DiagnosticSeverity> expect_severity_control_name();
|
||||||
/// Parses a diagnostic_control grammar element.
|
/// Parses a diagnostic_control grammar element.
|
||||||
/// @return the parsed diagnostic control, or nullptr on error.
|
/// @return the parsed diagnostic control, or nullptr on error.
|
||||||
Expect<const ast::DiagnosticControl*> expect_diagnostic_control();
|
Expect<ast::DiagnosticControl> expect_diagnostic_control();
|
||||||
|
|
||||||
/// Splits a peekable token into to parts filling in the peekable fields.
|
/// Splits a peekable token into to parts filling in the peekable fields.
|
||||||
/// @param lhs the token to set in the current position
|
/// @param lhs the token to set in the current position
|
||||||
|
@ -26,8 +26,8 @@ TEST_F(ParserImplTest, DiagnosticAttribute_Valid) {
|
|||||||
EXPECT_TRUE(a.matched);
|
EXPECT_TRUE(a.matched);
|
||||||
auto* d = a.value->As<ast::DiagnosticAttribute>();
|
auto* d = a.value->As<ast::DiagnosticAttribute>();
|
||||||
ASSERT_NE(d, nullptr);
|
ASSERT_NE(d, nullptr);
|
||||||
EXPECT_EQ(d->control->severity, ast::DiagnosticSeverity::kOff);
|
EXPECT_EQ(d->control.severity, ast::DiagnosticSeverity::kOff);
|
||||||
auto* r = d->control->rule_name;
|
auto* r = d->control.rule_name;
|
||||||
ASSERT_NE(r, nullptr);
|
ASSERT_NE(r, nullptr);
|
||||||
EXPECT_EQ(p->builder().Symbols().NameFor(r->symbol), "foo");
|
EXPECT_EQ(p->builder().Symbols().NameFor(r->symbol), "foo");
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,6 @@ TEST_P(DiagnosticControlParserTest, DiagnosticControl_Valid) {
|
|||||||
auto e = p->expect_diagnostic_control();
|
auto e = p->expect_diagnostic_control();
|
||||||
EXPECT_FALSE(e.errored);
|
EXPECT_FALSE(e.errored);
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
ASSERT_NE(e.value, nullptr);
|
|
||||||
ASSERT_TRUE(e->Is<ast::DiagnosticControl>());
|
|
||||||
EXPECT_EQ(e->severity, params.second);
|
EXPECT_EQ(e->severity, params.second);
|
||||||
|
|
||||||
auto* r = e->rule_name;
|
auto* r = e->rule_name;
|
||||||
@ -48,8 +46,6 @@ TEST_F(ParserImplTest, DiagnosticControl_Valid_TrailingComma) {
|
|||||||
auto e = p->expect_diagnostic_control();
|
auto e = p->expect_diagnostic_control();
|
||||||
EXPECT_FALSE(e.errored);
|
EXPECT_FALSE(e.errored);
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
ASSERT_NE(e.value, nullptr);
|
|
||||||
ASSERT_TRUE(e->Is<ast::DiagnosticControl>());
|
|
||||||
EXPECT_EQ(e->severity, ast::DiagnosticSeverity::kError);
|
EXPECT_EQ(e->severity, ast::DiagnosticSeverity::kError);
|
||||||
|
|
||||||
auto* r = e->rule_name;
|
auto* r = e->rule_name;
|
||||||
|
@ -24,13 +24,13 @@ TEST_F(ParserImplTest, DiagnosticDirective_Valid) {
|
|||||||
p->diagnostic_directive();
|
p->diagnostic_directive();
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
auto& ast = p->builder().AST();
|
auto& ast = p->builder().AST();
|
||||||
ASSERT_EQ(ast.DiagnosticControls().Length(), 1u);
|
ASSERT_EQ(ast.DiagnosticDirectives().Length(), 1u);
|
||||||
auto* control = ast.DiagnosticControls()[0];
|
auto* directive = ast.DiagnosticDirectives()[0];
|
||||||
EXPECT_EQ(control->severity, ast::DiagnosticSeverity::kOff);
|
EXPECT_EQ(directive->control.severity, ast::DiagnosticSeverity::kOff);
|
||||||
ASSERT_EQ(ast.GlobalDeclarations().Length(), 1u);
|
ASSERT_EQ(ast.GlobalDeclarations().Length(), 1u);
|
||||||
EXPECT_EQ(ast.GlobalDeclarations()[0], control);
|
EXPECT_EQ(ast.GlobalDeclarations()[0], directive);
|
||||||
|
|
||||||
auto* r = control->rule_name;
|
auto* r = directive->control.rule_name;
|
||||||
ASSERT_NE(r, nullptr);
|
ASSERT_NE(r, nullptr);
|
||||||
EXPECT_EQ(p->builder().Symbols().NameFor(r->symbol), "foo");
|
EXPECT_EQ(p->builder().Symbols().NameFor(r->symbol), "foo");
|
||||||
}
|
}
|
||||||
@ -42,7 +42,7 @@ TEST_F(ParserImplTest, DiagnosticDirective_MissingSemicolon) {
|
|||||||
EXPECT_EQ(p->error(), "1:21: expected ';' for diagnostic directive");
|
EXPECT_EQ(p->error(), "1:21: expected ';' for diagnostic directive");
|
||||||
auto program = p->program();
|
auto program = p->program();
|
||||||
auto& ast = program.AST();
|
auto& ast = program.AST();
|
||||||
EXPECT_EQ(ast.DiagnosticControls().Length(), 0u);
|
EXPECT_EQ(ast.DiagnosticDirectives().Length(), 0u);
|
||||||
EXPECT_EQ(ast.GlobalDeclarations().Length(), 0u);
|
EXPECT_EQ(ast.GlobalDeclarations().Length(), 0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,8 +207,8 @@ class DependencyScanner {
|
|||||||
TraverseExpression(var->initializer);
|
TraverseExpression(var->initializer);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[&](const ast::DiagnosticControl*) {
|
[&](const ast::DiagnosticDirective*) {
|
||||||
// Diagnostic control directives do not affect the dependency graph.
|
// Diagnostic directives do not affect the dependency graph.
|
||||||
},
|
},
|
||||||
[&](const ast::Enable*) {
|
[&](const ast::Enable*) {
|
||||||
// Enable directives do not affect the dependency graph.
|
// Enable directives do not affect the dependency graph.
|
||||||
@ -561,7 +561,7 @@ struct DependencyAnalysis {
|
|||||||
[&](const ast::TypeDecl* td) { return td->name; },
|
[&](const ast::TypeDecl* td) { return td->name; },
|
||||||
[&](const ast::Function* func) { return func->symbol; },
|
[&](const ast::Function* func) { return func->symbol; },
|
||||||
[&](const ast::Variable* var) { return var->symbol; },
|
[&](const ast::Variable* var) { return var->symbol; },
|
||||||
[&](const ast::DiagnosticControl*) { return Symbol(); },
|
[&](const ast::DiagnosticDirective*) { return Symbol(); },
|
||||||
[&](const ast::Enable*) { return Symbol(); },
|
[&](const ast::Enable*) { return Symbol(); },
|
||||||
[&](const ast::ConstAssert*) { return Symbol(); },
|
[&](const ast::ConstAssert*) { return Symbol(); },
|
||||||
[&](Default) {
|
[&](Default) {
|
||||||
@ -672,13 +672,13 @@ struct DependencyAnalysis {
|
|||||||
|
|
||||||
// Make sure all directives go before any other global declarations.
|
// Make sure all directives go before any other global declarations.
|
||||||
for (auto* global : declaration_order_) {
|
for (auto* global : declaration_order_) {
|
||||||
if (global->node->IsAnyOf<ast::DiagnosticControl, ast::Enable>()) {
|
if (global->node->IsAnyOf<ast::DiagnosticDirective, ast::Enable>()) {
|
||||||
sorted_.Add(global->node);
|
sorted_.Add(global->node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto* global : declaration_order_) {
|
for (auto* global : declaration_order_) {
|
||||||
if (global->node->IsAnyOf<ast::DiagnosticControl, ast::Enable>()) {
|
if (global->node->IsAnyOf<ast::DiagnosticDirective, ast::Enable>()) {
|
||||||
// Skip directives here, as they are already added.
|
// Skip directives here, as they are already added.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1095,8 +1095,7 @@ TEST_F(ResolverDependencyGraphOrderedGlobalsTest, DirectiveFirst) {
|
|||||||
auto* var_1 = GlobalVar("SYMBOL1", ty.i32());
|
auto* var_1 = GlobalVar("SYMBOL1", ty.i32());
|
||||||
auto* enable = Enable(ast::Extension::kF16);
|
auto* enable = Enable(ast::Extension::kF16);
|
||||||
auto* var_2 = GlobalVar("SYMBOL2", ty.f32());
|
auto* var_2 = GlobalVar("SYMBOL2", ty.f32());
|
||||||
auto* diagnostic = DiagnosticControl(ast::DiagnosticSeverity::kWarning, "foo");
|
auto* diagnostic = DiagnosticDirective(ast::DiagnosticSeverity::kWarning, "foo");
|
||||||
AST().AddDiagnosticControl(diagnostic);
|
|
||||||
|
|
||||||
EXPECT_THAT(AST().GlobalDeclarations(), ElementsAre(var_1, enable, var_2, diagnostic));
|
EXPECT_THAT(AST().GlobalDeclarations(), ElementsAre(var_1, enable, var_2, diagnostic));
|
||||||
EXPECT_THAT(Build().ordered_globals, ElementsAre(enable, diagnostic, var_1, var_2));
|
EXPECT_THAT(Build().ordered_globals, ElementsAre(enable, diagnostic, var_1, var_2));
|
||||||
|
@ -268,10 +268,10 @@ TEST_F(ResolverDiagnosticControlTest, Conflict_SameNameSameSeverity_Directive) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverDiagnosticControlTest, Conflict_SameNameDifferentSeverity_Directive) {
|
TEST_F(ResolverDiagnosticControlTest, Conflict_SameNameDifferentSeverity_Directive) {
|
||||||
DiagnosticDirective(Source{{12, 34}}, ast::DiagnosticSeverity::kError,
|
DiagnosticDirective(ast::DiagnosticSeverity::kError,
|
||||||
"chromium_unreachable_code");
|
Ident(Source{{12, 34}}, "chromium_unreachable_code"));
|
||||||
DiagnosticDirective(Source{{56, 78}}, ast::DiagnosticSeverity::kOff,
|
DiagnosticDirective(ast::DiagnosticSeverity::kOff,
|
||||||
"chromium_unreachable_code");
|
Ident(Source{{56, 78}}, "chromium_unreachable_code"));
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
R"(56:78 error: conflicting diagnostic directive
|
R"(56:78 error: conflicting diagnostic directive
|
||||||
@ -279,16 +279,16 @@ TEST_F(ResolverDiagnosticControlTest, Conflict_SameNameDifferentSeverity_Directi
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverDiagnosticControlTest, Conflict_SameUnknownNameDifferentSeverity_Directive) {
|
TEST_F(ResolverDiagnosticControlTest, Conflict_SameUnknownNameDifferentSeverity_Directive) {
|
||||||
DiagnosticDirective(Source{{12, 34}}, ast::DiagnosticSeverity::kError,
|
DiagnosticDirective(ast::DiagnosticSeverity::kError,
|
||||||
"chromium_unreachable_codes");
|
Ident(Source{{12, 34}}, "chromium_unreachable_codes"));
|
||||||
DiagnosticDirective(Source{{56, 78}}, ast::DiagnosticSeverity::kOff,
|
DiagnosticDirective(ast::DiagnosticSeverity::kOff,
|
||||||
"chromium_unreachable_codes");
|
Ident(Source{{56, 78}}, "chromium_unreachable_codes"));
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
R"(warning: unrecognized diagnostic rule 'chromium_unreachable_codes'
|
R"(12:34 warning: unrecognized diagnostic rule 'chromium_unreachable_codes'
|
||||||
Did you mean 'chromium_unreachable_code'?
|
Did you mean 'chromium_unreachable_code'?
|
||||||
Possible values: 'chromium_unreachable_code', 'derivative_uniformity'
|
Possible values: 'chromium_unreachable_code', 'derivative_uniformity'
|
||||||
warning: unrecognized diagnostic rule 'chromium_unreachable_codes'
|
56:78 warning: unrecognized diagnostic rule 'chromium_unreachable_codes'
|
||||||
Did you mean 'chromium_unreachable_code'?
|
Did you mean 'chromium_unreachable_code'?
|
||||||
Possible values: 'chromium_unreachable_code', 'derivative_uniformity'
|
Possible values: 'chromium_unreachable_code', 'derivative_uniformity'
|
||||||
56:78 error: conflicting diagnostic directive
|
56:78 error: conflicting diagnostic directive
|
||||||
@ -296,10 +296,8 @@ Possible values: 'chromium_unreachable_code', 'derivative_uniformity'
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverDiagnosticControlTest, Conflict_DifferentUnknownNameDifferentSeverity_Directive) {
|
TEST_F(ResolverDiagnosticControlTest, Conflict_DifferentUnknownNameDifferentSeverity_Directive) {
|
||||||
DiagnosticDirective(Source{{12, 34}}, ast::DiagnosticSeverity::kError,
|
DiagnosticDirective(ast::DiagnosticSeverity::kError, "chromium_unreachable_codes");
|
||||||
"chromium_unreachable_codes");
|
DiagnosticDirective(ast::DiagnosticSeverity::kOff, "chromium_unreachable_codex");
|
||||||
DiagnosticDirective(Source{{56, 78}}, ast::DiagnosticSeverity::kOff,
|
|
||||||
"chromium_unreachable_codex");
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,10 +311,10 @@ TEST_F(ResolverDiagnosticControlTest, Conflict_SameNameSameSeverity_Attribute) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverDiagnosticControlTest, Conflict_SameNameDifferentSeverity_Attribute) {
|
TEST_F(ResolverDiagnosticControlTest, Conflict_SameNameDifferentSeverity_Attribute) {
|
||||||
auto* attr1 = DiagnosticAttribute(Source{{12, 34}}, ast::DiagnosticSeverity::kError,
|
auto* attr1 = DiagnosticAttribute(ast::DiagnosticSeverity::kError,
|
||||||
"chromium_unreachable_code");
|
Ident(Source{{12, 34}}, "chromium_unreachable_code"));
|
||||||
auto* attr2 = DiagnosticAttribute(Source{{56, 78}}, ast::DiagnosticSeverity::kOff,
|
auto* attr2 = DiagnosticAttribute(ast::DiagnosticSeverity::kOff,
|
||||||
"chromium_unreachable_code");
|
Ident(Source{{56, 78}}, "chromium_unreachable_code"));
|
||||||
Func("foo", {}, ty.void_(), {}, utils::Vector{attr1, attr2});
|
Func("foo", {}, ty.void_(), {}, utils::Vector{attr1, attr2});
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
@ -325,17 +323,17 @@ TEST_F(ResolverDiagnosticControlTest, Conflict_SameNameDifferentSeverity_Attribu
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverDiagnosticControlTest, Conflict_SameUnknownNameDifferentSeverity_Attribute) {
|
TEST_F(ResolverDiagnosticControlTest, Conflict_SameUnknownNameDifferentSeverity_Attribute) {
|
||||||
auto* attr1 = DiagnosticAttribute(Source{{12, 34}}, ast::DiagnosticSeverity::kError,
|
auto* attr1 = DiagnosticAttribute(ast::DiagnosticSeverity::kError,
|
||||||
"chromium_unreachable_codes");
|
Ident(Source{{12, 34}}, "chromium_unreachable_codes"));
|
||||||
auto* attr2 = DiagnosticAttribute(Source{{56, 78}}, ast::DiagnosticSeverity::kOff,
|
auto* attr2 = DiagnosticAttribute(ast::DiagnosticSeverity::kOff,
|
||||||
"chromium_unreachable_codes");
|
Ident(Source{{56, 78}}, "chromium_unreachable_codes"));
|
||||||
Func("foo", {}, ty.void_(), {}, utils::Vector{attr1, attr2});
|
Func("foo", {}, ty.void_(), {}, utils::Vector{attr1, attr2});
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
R"(warning: unrecognized diagnostic rule 'chromium_unreachable_codes'
|
R"(12:34 warning: unrecognized diagnostic rule 'chromium_unreachable_codes'
|
||||||
Did you mean 'chromium_unreachable_code'?
|
Did you mean 'chromium_unreachable_code'?
|
||||||
Possible values: 'chromium_unreachable_code', 'derivative_uniformity'
|
Possible values: 'chromium_unreachable_code', 'derivative_uniformity'
|
||||||
warning: unrecognized diagnostic rule 'chromium_unreachable_codes'
|
56:78 warning: unrecognized diagnostic rule 'chromium_unreachable_codes'
|
||||||
Did you mean 'chromium_unreachable_code'?
|
Did you mean 'chromium_unreachable_code'?
|
||||||
Possible values: 'chromium_unreachable_code', 'derivative_uniformity'
|
Possible values: 'chromium_unreachable_code', 'derivative_uniformity'
|
||||||
56:78 error: conflicting diagnostic attribute
|
56:78 error: conflicting diagnostic attribute
|
||||||
@ -343,10 +341,9 @@ Possible values: 'chromium_unreachable_code', 'derivative_uniformity'
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverDiagnosticControlTest, Conflict_DifferentUnknownNameDifferentSeverity_Attribute) {
|
TEST_F(ResolverDiagnosticControlTest, Conflict_DifferentUnknownNameDifferentSeverity_Attribute) {
|
||||||
auto* attr1 = DiagnosticAttribute(Source{{12, 34}}, ast::DiagnosticSeverity::kError,
|
auto* attr1 =
|
||||||
"chromium_unreachable_codes");
|
DiagnosticAttribute(ast::DiagnosticSeverity::kError, "chromium_unreachable_codes");
|
||||||
auto* attr2 = DiagnosticAttribute(Source{{56, 78}}, ast::DiagnosticSeverity::kOff,
|
auto* attr2 = DiagnosticAttribute(ast::DiagnosticSeverity::kOff, "chromium_unreachable_codex");
|
||||||
"chromium_unreachable_codex");
|
|
||||||
Func("foo", {}, ty.void_(), {}, utils::Vector{attr1, attr2});
|
Func("foo", {}, ty.void_(), {}, utils::Vector{attr1, attr2});
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
}
|
}
|
||||||
|
@ -158,11 +158,15 @@ bool Resolver::ResolveInternal() {
|
|||||||
Mark(&builder_->AST());
|
Mark(&builder_->AST());
|
||||||
|
|
||||||
// Process all module-scope declarations in dependency order.
|
// Process all module-scope declarations in dependency order.
|
||||||
|
utils::Vector<const ast::DiagnosticControl*, 4> diagnostic_controls;
|
||||||
for (auto* decl : dependencies_.ordered_globals) {
|
for (auto* decl : dependencies_.ordered_globals) {
|
||||||
Mark(decl);
|
Mark(decl);
|
||||||
if (!Switch<bool>(
|
if (!Switch<bool>(
|
||||||
decl, //
|
decl, //
|
||||||
[&](const ast::DiagnosticControl* dc) { return DiagnosticControl(dc); },
|
[&](const ast::DiagnosticDirective* d) {
|
||||||
|
diagnostic_controls.Push(&d->control);
|
||||||
|
return DiagnosticControl(d->control);
|
||||||
|
},
|
||||||
[&](const ast::Enable* e) { return Enable(e); },
|
[&](const ast::Enable* e) { return Enable(e); },
|
||||||
[&](const ast::TypeDecl* td) { return TypeDecl(td); },
|
[&](const ast::TypeDecl* td) { return TypeDecl(td); },
|
||||||
[&](const ast::Function* func) { return Function(func); },
|
[&](const ast::Function* func) { return Function(func); },
|
||||||
@ -183,7 +187,7 @@ bool Resolver::ResolveInternal() {
|
|||||||
|
|
||||||
SetShadows();
|
SetShadows();
|
||||||
|
|
||||||
if (!validator_.DiagnosticControls(builder_->AST().DiagnosticControls(), "directive")) {
|
if (!validator_.DiagnosticControls(diagnostic_controls, "directive")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -989,7 +993,6 @@ sem::Function* Resolver::Function(const ast::Function* decl) {
|
|||||||
for (auto* attr : decl->attributes) {
|
for (auto* attr : decl->attributes) {
|
||||||
Mark(attr);
|
Mark(attr);
|
||||||
if (auto* dc = attr->As<ast::DiagnosticAttribute>()) {
|
if (auto* dc = attr->As<ast::DiagnosticAttribute>()) {
|
||||||
Mark(dc->control);
|
|
||||||
if (!DiagnosticControl(dc->control)) {
|
if (!DiagnosticControl(dc->control)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -3069,18 +3072,18 @@ sem::Expression* Resolver::UnaryOp(const ast::UnaryOpExpression* unary) {
|
|||||||
return sem;
|
return sem;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Resolver::DiagnosticControl(const ast::DiagnosticControl* control) {
|
bool Resolver::DiagnosticControl(const ast::DiagnosticControl& control) {
|
||||||
Mark(control->rule_name);
|
Mark(control.rule_name);
|
||||||
|
|
||||||
auto rule_name = builder_->Symbols().NameFor(control->rule_name->symbol);
|
auto rule_name = builder_->Symbols().NameFor(control.rule_name->symbol);
|
||||||
auto rule = ast::ParseDiagnosticRule(rule_name);
|
auto rule = ast::ParseDiagnosticRule(rule_name);
|
||||||
if (rule != ast::DiagnosticRule::kUndefined) {
|
if (rule != ast::DiagnosticRule::kUndefined) {
|
||||||
validator_.DiagnosticFilters().Set(rule, control->severity);
|
validator_.DiagnosticFilters().Set(rule, control.severity);
|
||||||
} else {
|
} else {
|
||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
ss << "unrecognized diagnostic rule '" << rule_name << "'\n";
|
ss << "unrecognized diagnostic rule '" << rule_name << "'\n";
|
||||||
utils::SuggestAlternatives(rule_name, ast::kDiagnosticRuleStrings, ss);
|
utils::SuggestAlternatives(rule_name, ast::kDiagnosticRuleStrings, ss);
|
||||||
AddWarning(ss.str(), control->rule_name->source);
|
AddWarning(ss.str(), control.rule_name->source);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -3863,7 +3866,6 @@ SEM* Resolver::StatementScope(const ast::Statement* ast, SEM* sem, F&& callback)
|
|||||||
for (auto* attr : stmt->attributes) {
|
for (auto* attr : stmt->attributes) {
|
||||||
Mark(attr);
|
Mark(attr);
|
||||||
if (auto* dc = attr->template As<ast::DiagnosticAttribute>()) {
|
if (auto* dc = attr->template As<ast::DiagnosticAttribute>()) {
|
||||||
Mark(dc->control);
|
|
||||||
if (!DiagnosticControl(dc->control)) {
|
if (!DiagnosticControl(dc->control)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -263,7 +263,7 @@ class Resolver {
|
|||||||
|
|
||||||
/// @param control the diagnostic control
|
/// @param control the diagnostic control
|
||||||
/// @returns true on success, false on failure
|
/// @returns true on success, false on failure
|
||||||
bool DiagnosticControl(const ast::DiagnosticControl* control);
|
bool DiagnosticControl(const ast::DiagnosticControl& control);
|
||||||
|
|
||||||
/// @param enable the enable declaration
|
/// @param enable the enable declaration
|
||||||
/// @returns the resolved extension
|
/// @returns the resolved extension
|
||||||
|
@ -2433,7 +2433,7 @@ bool Validator::NoDuplicateAttributes(utils::VectorRef<const ast::Attribute*> at
|
|||||||
for (auto* d : attributes) {
|
for (auto* d : attributes) {
|
||||||
if (auto* diag = d->As<ast::DiagnosticAttribute>()) {
|
if (auto* diag = d->As<ast::DiagnosticAttribute>()) {
|
||||||
// Allow duplicate diagnostic attributes, and check for conflicts later.
|
// Allow duplicate diagnostic attributes, and check for conflicts later.
|
||||||
diagnostic_controls.Push(diag->control);
|
diagnostic_controls.Push(&diag->control);
|
||||||
} else {
|
} else {
|
||||||
auto added = seen.Add(&d->TypeInfo(), d->source);
|
auto added = seen.Add(&d->TypeInfo(), d->source);
|
||||||
if (!added && !d->Is<ast::InternalAttribute>()) {
|
if (!added && !d->Is<ast::InternalAttribute>()) {
|
||||||
@ -2457,13 +2457,13 @@ bool Validator::DiagnosticControls(utils::VectorRef<const ast::DiagnosticControl
|
|||||||
{
|
{
|
||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
ss << "conflicting diagnostic " << use;
|
ss << "conflicting diagnostic " << use;
|
||||||
AddError(ss.str(), dc->source);
|
AddError(ss.str(), dc->rule_name->source);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
ss << "severity of '" << symbols_.NameFor(dc->rule_name->symbol) << "' set to '"
|
ss << "severity of '" << symbols_.NameFor(dc->rule_name->symbol) << "' set to '"
|
||||||
<< dc->severity << "' here";
|
<< dc->severity << "' here";
|
||||||
AddNote(ss.str(), (*diag_added.value)->source);
|
AddNote(ss.str(), (*diag_added.value)->rule_name->source);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1311,8 +1311,11 @@ Transform::ApplyResult Renamer::Apply(const Program* src,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[&](const ast::DiagnosticControl* diagnostic) {
|
[&](const ast::DiagnosticAttribute* diagnostic) {
|
||||||
preserved_identifiers.Add(diagnostic->rule_name);
|
preserved_identifiers.Add(diagnostic->control.rule_name);
|
||||||
|
},
|
||||||
|
[&](const ast::DiagnosticDirective* diagnostic) {
|
||||||
|
preserved_identifiers.Add(diagnostic->control.rule_name);
|
||||||
},
|
},
|
||||||
[&](const ast::TypeName* type_name) {
|
[&](const ast::TypeName* type_name) {
|
||||||
if (is_type_short_name(type_name->name->symbol)) {
|
if (is_type_short_name(type_name->name->symbol)) {
|
||||||
|
@ -114,7 +114,9 @@ Transform::ApplyResult SingleEntryPoint::Apply(const Program* src,
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
[&](const ast::Enable* ext) { b.AST().AddEnable(ctx.Clone(ext)); },
|
[&](const ast::Enable* ext) { b.AST().AddEnable(ctx.Clone(ext)); },
|
||||||
[&](const ast::DiagnosticControl* dc) { b.AST().AddDiagnosticControl(ctx.Clone(dc)); },
|
[&](const ast::DiagnosticDirective* d) {
|
||||||
|
b.AST().AddDiagnosticDirective(ctx.Clone(d));
|
||||||
|
},
|
||||||
[&](Default) {
|
[&](Default) {
|
||||||
TINT_UNREACHABLE(Transform, b.Diagnostics())
|
TINT_UNREACHABLE(Transform, b.Diagnostics())
|
||||||
<< "unhandled global declaration: " << decl->TypeInfo().name;
|
<< "unhandled global declaration: " << decl->TypeInfo().name;
|
||||||
|
@ -250,7 +250,7 @@ bool GeneratorImpl::Generate() {
|
|||||||
|
|
||||||
auto* mod = builder_.Sem().Module();
|
auto* mod = builder_.Sem().Module();
|
||||||
for (auto* decl : mod->DependencyOrderedDeclarations()) {
|
for (auto* decl : mod->DependencyOrderedDeclarations()) {
|
||||||
if (decl->IsAnyOf<ast::Alias, ast::ConstAssert, ast::DiagnosticControl>()) {
|
if (decl->IsAnyOf<ast::Alias, ast::ConstAssert, ast::DiagnosticDirective>()) {
|
||||||
continue; // These are not emitted.
|
continue; // These are not emitted.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,7 +310,7 @@ bool GeneratorImpl::Generate() {
|
|||||||
|
|
||||||
auto* mod = builder_.Sem().Module();
|
auto* mod = builder_.Sem().Module();
|
||||||
for (auto* decl : mod->DependencyOrderedDeclarations()) {
|
for (auto* decl : mod->DependencyOrderedDeclarations()) {
|
||||||
if (decl->IsAnyOf<ast::Alias, ast::DiagnosticControl, ast::Enable, ast::ConstAssert>()) {
|
if (decl->IsAnyOf<ast::Alias, ast::DiagnosticDirective, ast::Enable, ast::ConstAssert>()) {
|
||||||
continue; // These are not emitted.
|
continue; // These are not emitted.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,7 +313,7 @@ bool GeneratorImpl::Generate() {
|
|||||||
}
|
}
|
||||||
return EmitFunction(func);
|
return EmitFunction(func);
|
||||||
},
|
},
|
||||||
[&](const ast::DiagnosticControl*) {
|
[&](const ast::DiagnosticDirective*) {
|
||||||
// Do nothing for diagnostic directives in MSL
|
// Do nothing for diagnostic directives in MSL
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
@ -71,9 +71,9 @@ bool GeneratorImpl::Generate() {
|
|||||||
}
|
}
|
||||||
has_directives = true;
|
has_directives = true;
|
||||||
}
|
}
|
||||||
for (auto diagnostic : program_->AST().DiagnosticControls()) {
|
for (auto diagnostic : program_->AST().DiagnosticDirectives()) {
|
||||||
auto out = line();
|
auto out = line();
|
||||||
if (!EmitDiagnosticControl(out, diagnostic)) {
|
if (!EmitDiagnosticControl(out, diagnostic->control)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
out << ";";
|
out << ";";
|
||||||
@ -84,7 +84,7 @@ bool GeneratorImpl::Generate() {
|
|||||||
}
|
}
|
||||||
// Generate global declarations in the order they appear in the module.
|
// Generate global declarations in the order they appear in the module.
|
||||||
for (auto* decl : program_->AST().GlobalDeclarations()) {
|
for (auto* decl : program_->AST().GlobalDeclarations()) {
|
||||||
if (decl->IsAnyOf<ast::DiagnosticControl, ast::Enable>()) {
|
if (decl->IsAnyOf<ast::DiagnosticDirective, ast::Enable>()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!Switch(
|
if (!Switch(
|
||||||
@ -108,9 +108,9 @@ bool GeneratorImpl::Generate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool GeneratorImpl::EmitDiagnosticControl(std::ostream& out,
|
bool GeneratorImpl::EmitDiagnosticControl(std::ostream& out,
|
||||||
const ast::DiagnosticControl* diagnostic) {
|
const ast::DiagnosticControl& diagnostic) {
|
||||||
out << "diagnostic(" << diagnostic->severity << ", "
|
out << "diagnostic(" << diagnostic.severity << ", "
|
||||||
<< program_->Symbols().NameFor(diagnostic->rule_name->symbol) << ")";
|
<< program_->Symbols().NameFor(diagnostic.rule_name->symbol) << ")";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ class GeneratorImpl : public TextGenerator {
|
|||||||
/// @param out the output of the expression stream
|
/// @param out the output of the expression stream
|
||||||
/// @param diagnostic the diagnostic control node
|
/// @param diagnostic the diagnostic control node
|
||||||
/// @returns true if the diagnostic control was emitted
|
/// @returns true if the diagnostic control was emitted
|
||||||
bool EmitDiagnosticControl(std::ostream& out, const ast::DiagnosticControl* diagnostic);
|
bool EmitDiagnosticControl(std::ostream& out, const ast::DiagnosticControl& diagnostic);
|
||||||
/// Handles generating an enable directive
|
/// Handles generating an enable directive
|
||||||
/// @param enable the enable node
|
/// @param enable the enable node
|
||||||
/// @returns true if the enable directive was emitted
|
/// @returns true if the enable directive was emitted
|
||||||
|
Loading…
x
Reference in New Issue
Block a user