90 lines
3.0 KiB
C++
90 lines
3.0 KiB
C++
// Copyright 2021 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/sem/info.h"
|
|
|
|
#include "src/tint/sem/function.h"
|
|
#include "src/tint/sem/module.h"
|
|
#include "src/tint/sem/statement.h"
|
|
#include "src/tint/sem/value_expression.h"
|
|
|
|
namespace tint::sem {
|
|
|
|
Info::Info() = default;
|
|
|
|
Info::Info(Info&&) = default;
|
|
|
|
Info::~Info() = default;
|
|
|
|
Info& Info::operator=(Info&&) = default;
|
|
|
|
ast::DiagnosticSeverity Info::DiagnosticSeverity(const ast::Node* ast_node,
|
|
ast::DiagnosticRule rule) const {
|
|
// Get the diagnostic severity modification for a node.
|
|
auto check = [&](auto* node) {
|
|
auto& severities = node->DiagnosticSeverities();
|
|
auto itr = severities.find(rule);
|
|
if (itr != severities.end()) {
|
|
return itr->second;
|
|
}
|
|
return ast::DiagnosticSeverity::kUndefined;
|
|
};
|
|
|
|
// Get the diagnostic severity modification for a function.
|
|
auto check_func = [&](const sem::Function* func) {
|
|
auto severity = check(func);
|
|
if (severity != ast::DiagnosticSeverity::kUndefined) {
|
|
return severity;
|
|
}
|
|
|
|
// No severity set on the function, so check the module instead.
|
|
return check(module_);
|
|
};
|
|
|
|
// Get the diagnostic severity modification for a statement.
|
|
auto check_stmt = [&](const sem::Statement* stmt) {
|
|
// Walk up the statement hierarchy, checking for diagnostic severity modifications.
|
|
while (true) {
|
|
auto severity = check(stmt);
|
|
if (severity != ast::DiagnosticSeverity::kUndefined) {
|
|
return severity;
|
|
}
|
|
if (!stmt->Parent()) {
|
|
break;
|
|
}
|
|
stmt = stmt->Parent();
|
|
}
|
|
|
|
// No severity set on the statement, so check the function instead.
|
|
return check_func(stmt->Function());
|
|
};
|
|
|
|
// Query the diagnostic severity from the semantic node that corresponds to the AST node.
|
|
auto* sem = Get(ast_node);
|
|
TINT_ASSERT(Resolver, sem != nullptr);
|
|
auto severity = Switch(
|
|
sem, //
|
|
[&](const sem::ValueExpression* expr) { return check_stmt(expr->Stmt()); },
|
|
[&](const sem::Statement* stmt) { return check_stmt(stmt); },
|
|
[&](const sem::Function* func) { return check_func(func); },
|
|
[&](Default) {
|
|
// Use the global severity set on the module.
|
|
return check(module_);
|
|
});
|
|
TINT_ASSERT(Resolver, severity != ast::DiagnosticSeverity::kUndefined);
|
|
return severity;
|
|
}
|
|
|
|
} // namespace tint::sem
|