Add getting constant ID information from Inspector

This also involves a reorganization of the code into its own
subdirectory.

BUG=tint:253

Change-Id: If05018da2662e923e659b485576704f3a6bcd062
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/30340
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
Ryan Harrison 2020-10-16 02:26:54 +00:00 committed by Commit Bot service account
parent 95dc655bf8
commit 8904253837
11 changed files with 564 additions and 97 deletions

View File

@ -373,8 +373,12 @@ source_set("libtint_core_src") {
"src/ast/workgroup_decoration.h", "src/ast/workgroup_decoration.h",
"src/context.cc", "src/context.cc",
"src/context.h", "src/context.h",
"src/inspector.cc", "src/inspector/entry_point.cc",
"src/inspector.h", "src/inspector/entry_point.h",
"src/inspector/inspector.cc",
"src/inspector/inspector.h",
"src/inspector/scalar.cc",
"src/inspector/scalar.h",
"src/reader/reader.cc", "src/reader/reader.cc",
"src/reader/reader.h", "src/reader/reader.h",
"src/scope_stack.h", "src/scope_stack.h",
@ -757,7 +761,7 @@ source_set("tint_unittests_core_src") {
"src/ast/variable_decl_statement_test.cc", "src/ast/variable_decl_statement_test.cc",
"src/ast/variable_test.cc", "src/ast/variable_test.cc",
"src/ast/workgroup_decoration_test.cc", "src/ast/workgroup_decoration_test.cc",
"src/inspector_test.cc", "src/inspector/inspector_test.cc",
"src/scope_stack_test.cc", "src/scope_stack_test.cc",
"src/transform/bound_array_accessors_transform_test.cc", "src/transform/bound_array_accessors_transform_test.cc",
"src/transform/vertex_pulling_transform_test.cc", "src/transform/vertex_pulling_transform_test.cc",

View File

@ -20,6 +20,7 @@
#include "src/ast/pipeline_stage.h" #include "src/ast/pipeline_stage.h"
#include "src/context.h" #include "src/context.h"
#include "src/inspector/inspector.h"
#include "src/reader/reader.h" #include "src/reader/reader.h"
#include "src/transform/bound_array_accessors_transform.h" #include "src/transform/bound_array_accessors_transform.h"
#include "src/transform/manager.h" #include "src/transform/manager.h"

View File

@ -194,8 +194,12 @@ set(TINT_LIB_SRCS
ast/workgroup_decoration.h ast/workgroup_decoration.h
context.cc context.cc
context.h context.h
inspector.cc inspector/entry_point.cc
inspector.h inspector/entry_point.h
inspector/inspector.cc
inspector/inspector.h
inspector/scalar.cc
inspector/scalar.h
reader/reader.cc reader/reader.cc
reader/reader.h reader/reader.h
scope_stack.h scope_stack.h
@ -367,7 +371,7 @@ set(TINT_TEST_SRCS
ast/variable_decl_statement_test.cc ast/variable_decl_statement_test.cc
ast/variable_test.cc ast/variable_test.cc
ast/workgroup_decoration_test.cc ast/workgroup_decoration_test.cc
inspector_test.cc inspector/inspector_test.cc
scope_stack_test.cc scope_stack_test.cc
transform/bound_array_accessors_transform_test.cc transform/bound_array_accessors_transform_test.cc
transform/vertex_pulling_transform_test.cc transform/vertex_pulling_transform_test.cc

View File

@ -1,59 +0,0 @@
// Copyright 2020 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/inspector.h"
#include <algorithm>
#include "src/ast/function.h"
namespace tint {
namespace inspector {
EntryPoint::EntryPoint() = default;
EntryPoint::EntryPoint(EntryPoint&) = default;
EntryPoint::EntryPoint(EntryPoint&&) = default;
EntryPoint::~EntryPoint() = default;
Inspector::Inspector(const ast::Module& module) : module_(module) {}
Inspector::~Inspector() = default;
std::vector<EntryPoint> Inspector::GetEntryPoints() {
std::vector<EntryPoint> result;
for (const auto& func : module_.functions()) {
if (func->IsEntryPoint()) {
EntryPoint entry_point;
entry_point.name = func->name();
entry_point.stage = func->pipeline_stage();
std::tie(entry_point.workgroup_size_x, entry_point.workgroup_size_y,
entry_point.workgroup_size_z) = func->workgroup_size();
for (auto* var : func->referenced_module_variables()) {
if (var->storage_class() == ast::StorageClass::kInput) {
entry_point.input_variables.push_back(var->name());
} else {
entry_point.output_variables.push_back(var->name());
}
}
result.push_back(std::move(entry_point));
}
}
return result;
}
} // namespace inspector
} // namespace tint

View File

@ -0,0 +1,26 @@
// Copyright 2020 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/inspector/entry_point.h"
namespace tint {
namespace inspector {
EntryPoint::EntryPoint() = default;
EntryPoint::EntryPoint(EntryPoint&) = default;
EntryPoint::EntryPoint(EntryPoint&&) = default;
EntryPoint::~EntryPoint() = default;
} // namespace inspector
} // namespace tint

View File

@ -12,22 +12,19 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef SRC_INSPECTOR_H_ #ifndef SRC_INSPECTOR_ENTRY_POINT_H_
#define SRC_INSPECTOR_H_ #define SRC_INSPECTOR_ENTRY_POINT_H_
#include <memory>
#include <string>
#include <tuple> #include <tuple>
#include <vector> #include <vector>
#include "src/ast/module.h"
#include "src/ast/pipeline_stage.h" #include "src/ast/pipeline_stage.h"
namespace tint { namespace tint {
namespace inspector { namespace inspector {
/// Container of reflection data for an entry point in the shader. /// Container of reflection data for an entry point in the shader.
struct EntryPoint { typedef struct EntryPoint {
/// Constructors /// Constructors
EntryPoint(); EntryPoint();
/// Copy Constructor /// Copy Constructor
@ -56,30 +53,9 @@ struct EntryPoint {
return std::tuple<uint32_t, uint32_t, uint32_t>( return std::tuple<uint32_t, uint32_t, uint32_t>(
workgroup_size_x, workgroup_size_y, workgroup_size_z); workgroup_size_x, workgroup_size_y, workgroup_size_z);
} }
}; } EntryPoint;
/// Extracts information from a module
class Inspector {
public:
/// Constructor
/// @param module Shader module to extract information from.
explicit Inspector(const ast::Module& module);
~Inspector();
/// @returns error messages from the Inspector
const std::string& error() { return error_; }
/// @returns true if an error was encountered
bool has_error() const { return !error_.empty(); }
/// @returns vector of entry point information
std::vector<EntryPoint> GetEntryPoints();
private:
const ast::Module& module_;
std::string error_;
};
} // namespace inspector } // namespace inspector
} // namespace tint } // namespace tint
#endif // SRC_INSPECTOR_H_ #endif // SRC_INSPECTOR_ENTRY_POINT_H_

138
src/inspector/inspector.cc Normal file
View File

@ -0,0 +1,138 @@
// Copyright 2020 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/inspector/inspector.h"
#include <algorithm>
#include <map>
#include "src/ast/bool_literal.h"
#include "src/ast/constructor_expression.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/float_literal.h"
#include "src/ast/function.h"
#include "src/ast/null_literal.h"
#include "src/ast/scalar_constructor_expression.h"
#include "src/ast/sint_literal.h"
#include "src/ast/uint_literal.h"
namespace tint {
namespace inspector {
Inspector::Inspector(const ast::Module& module) : module_(module) {}
Inspector::~Inspector() = default;
std::vector<EntryPoint> Inspector::GetEntryPoints() {
std::vector<EntryPoint> result;
for (const auto& func : module_.functions()) {
if (!func->IsEntryPoint()) {
continue;
}
EntryPoint entry_point;
entry_point.name = func->name();
entry_point.stage = func->pipeline_stage();
std::tie(entry_point.workgroup_size_x, entry_point.workgroup_size_y,
entry_point.workgroup_size_z) = func->workgroup_size();
for (auto* var : func->referenced_module_variables()) {
if (var->storage_class() == ast::StorageClass::kInput) {
entry_point.input_variables.push_back(var->name());
} else {
entry_point.output_variables.push_back(var->name());
}
}
result.push_back(std::move(entry_point));
}
return result;
}
std::map<uint32_t, Scalar> Inspector::GetConstantIDs() {
std::map<uint32_t, Scalar> result;
for (auto& var : module_.global_variables()) {
if (!var->IsDecorated()) {
continue;
}
auto* decorated = var->AsDecorated();
if (!decorated->HasConstantIdDecoration()) {
continue;
}
// If there are conflicting defintions for a constant id, that is invalid
// WGSL, so the validator should catch it. Thus here the inspector just
// assumes all definitians of the constant id are the same, so only needs
// to find the first reference to constant id.
uint32_t constant_id = decorated->constant_id();
if (result.find(constant_id) != result.end()) {
continue;
}
if (!var->has_constructor()) {
result[constant_id] = Scalar();
continue;
}
auto* expression = var->constructor();
if (!expression->IsConstructor()) {
// This is invalid WGSL, but handling gracefully.
result[constant_id] = Scalar();
continue;
}
auto* constructor = expression->AsConstructor();
if (!constructor->IsScalarConstructor()) {
// This is invalid WGSL, but handling gracefully.
result[constant_id] = Scalar();
continue;
}
auto* literal = constructor->AsScalarConstructor()->literal();
if (!literal) {
// This is invalid WGSL, but handling gracefully.
result[constant_id] = Scalar();
continue;
}
if (literal->IsBool()) {
result[constant_id] = Scalar(literal->AsBool()->IsTrue());
continue;
}
if (literal->IsUint()) {
result[constant_id] = Scalar(literal->AsUint()->value());
continue;
}
if (literal->IsSint()) {
result[constant_id] = Scalar(literal->AsSint()->value());
continue;
}
if (literal->IsFloat()) {
result[constant_id] = Scalar(literal->AsFloat()->value());
continue;
}
result[constant_id] = Scalar();
}
return result;
}
} // namespace inspector
} // namespace tint

59
src/inspector/inspector.h Normal file
View File

@ -0,0 +1,59 @@
// Copyright 2020 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_INSPECTOR_INSPECTOR_H_
#define SRC_INSPECTOR_INSPECTOR_H_
#include <map>
#include <memory>
#include <string>
#include <tuple>
#include <vector>
#include "src/ast/module.h"
#include "src/ast/pipeline_stage.h"
#include "src/inspector/entry_point.h"
#include "src/inspector/scalar.h"
namespace tint {
namespace inspector {
/// Extracts information from a module
class Inspector {
public:
/// Constructor
/// @param module Shader module to extract information from.
explicit Inspector(const ast::Module& module);
~Inspector();
/// @returns error messages from the Inspector
const std::string& error() { return error_; }
/// @returns true if an error was encountered
bool has_error() const { return !error_.empty(); }
/// @returns vector of entry point information
std::vector<EntryPoint> GetEntryPoints();
/// @returns map of const_id to initial value
std::map<uint32_t, Scalar> GetConstantIDs();
private:
const ast::Module& module_;
std::string error_;
};
} // namespace inspector
} // namespace tint
#endif // SRC_INSPECTOR_INSPECTOR_H_

View File

@ -12,23 +12,39 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/inspector.h" #include "src/inspector/inspector.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "src/ast/assignment_statement.h" #include "src/ast/assignment_statement.h"
#include "src/ast/bool_literal.h"
#include "src/ast/call_expression.h" #include "src/ast/call_expression.h"
#include "src/ast/call_statement.h" #include "src/ast/call_statement.h"
#include "src/ast/constant_id_decoration.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/float_literal.h"
#include "src/ast/function.h" #include "src/ast/function.h"
#include "src/ast/identifier_expression.h" #include "src/ast/identifier_expression.h"
#include "src/ast/null_literal.h"
#include "src/ast/pipeline_stage.h" #include "src/ast/pipeline_stage.h"
#include "src/ast/return_statement.h" #include "src/ast/return_statement.h"
#include "src/ast/scalar_constructor_expression.h"
#include "src/ast/sint_literal.h"
#include "src/ast/stage_decoration.h" #include "src/ast/stage_decoration.h"
#include "src/ast/type/bool_type.h"
#include "src/ast/type/f32_type.h"
#include "src/ast/type/i32_type.h"
#include "src/ast/type/type.h"
#include "src/ast/type/u32_type.h" #include "src/ast/type/u32_type.h"
#include "src/ast/type/void_type.h" #include "src/ast/type/void_type.h"
#include "src/ast/uint_literal.h"
#include "src/ast/variable_decl_statement.h"
#include "src/ast/variable_decoration.h"
#include "src/ast/workgroup_decoration.h" #include "src/ast/workgroup_decoration.h"
#include "src/context.h" #include "src/context.h"
#include "src/type_determiner.h" #include "src/type_determiner.h"
#include "tint/tint.h"
namespace tint { namespace tint {
namespace inspector { namespace inspector {
namespace { namespace {
@ -140,6 +156,59 @@ class InspectorHelper {
return func; return func;
} }
/// Add a Constant ID to the global variables.
/// @param name name of the variable to add
/// @param id id number for the constant id
/// @param type type of the variable
/// @param val value to initialize the variable with, if NULL no initializer
/// will be added.
template <class T>
void CreateConstantID(std::string name,
uint32_t id,
ast::type::Type* type,
T* val) {
auto dvar = std::make_unique<ast::DecoratedVariable>(
std::make_unique<ast::Variable>(name, ast::StorageClass::kNone, type));
dvar->set_is_const(true);
ast::VariableDecorationList decos;
decos.push_back(std::make_unique<ast::ConstantIdDecoration>(id));
dvar->set_decorations(std::move(decos));
if (val) {
dvar->set_constructor(std::make_unique<ast::ScalarConstructorExpression>(
MakeLiteral<T>(type, val)));
}
mod()->AddGlobalVariable(std::move(dvar));
}
template <class T>
std::unique_ptr<ast::Literal> MakeLiteral(ast::type::Type*, T*) {
return nullptr;
}
template <>
std::unique_ptr<ast::Literal> MakeLiteral<bool>(ast::type::Type* type,
bool* val) {
return std::make_unique<ast::BoolLiteral>(type, *val);
}
template <>
std::unique_ptr<ast::Literal> MakeLiteral<uint32_t>(ast::type::Type* type,
uint32_t* val) {
return std::make_unique<ast::UintLiteral>(type, *val);
}
template <>
std::unique_ptr<ast::Literal> MakeLiteral<int32_t>(ast::type::Type* type,
int32_t* val) {
return std::make_unique<ast::SintLiteral>(type, *val);
}
template <>
std::unique_ptr<ast::Literal> MakeLiteral<float>(ast::type::Type* type,
float* val) {
return std::make_unique<ast::FloatLiteral>(type, *val);
}
bool ContainsString(const std::vector<std::string>& vec, bool ContainsString(const std::vector<std::string>& vec,
const std::string& str) { const std::string& str) {
for (auto& s : vec) { for (auto& s : vec) {
@ -154,8 +223,11 @@ class InspectorHelper {
TypeDeterminer* td() { return td_.get(); } TypeDeterminer* td() { return td_.get(); }
Inspector* inspector() { return inspector_.get(); } Inspector* inspector() { return inspector_.get(); }
ast::type::VoidType* void_type() { return &void_type_; } ast::type::BoolType* bool_type() { return &bool_type_; }
ast::type::F32Type* f32_type() { return &f32_type_; }
ast::type::I32Type* i32_type() { return &i32_type_; }
ast::type::U32Type* u32_type() { return &u32_type_; } ast::type::U32Type* u32_type() { return &u32_type_; }
ast::type::VoidType* void_type() { return &void_type_; }
private: private:
Context ctx_; Context ctx_;
@ -163,8 +235,11 @@ class InspectorHelper {
std::unique_ptr<TypeDeterminer> td_; std::unique_ptr<TypeDeterminer> td_;
std::unique_ptr<Inspector> inspector_; std::unique_ptr<Inspector> inspector_;
ast::type::VoidType void_type_; ast::type::BoolType bool_type_;
ast::type::F32Type f32_type_;
ast::type::I32Type i32_type_;
ast::type::U32Type u32_type_; ast::type::U32Type u32_type_;
ast::type::VoidType void_type_;
}; };
class InspectorTest : public InspectorHelper, public testing::Test {}; class InspectorTest : public InspectorHelper, public testing::Test {};
@ -494,6 +569,94 @@ TEST_F(InspectorGetEntryPointTest, MultipleEntryPointsSharedInOutVariables) {
EXPECT_EQ("out2_var", result[1].output_variables[0]); EXPECT_EQ("out2_var", result[1].output_variables[0]);
} }
TEST_F(InspectorGetEntryPointTest, BoolConstantIDs) {
bool val_true = true;
bool val_false = false;
CreateConstantID<bool>("foo", 1, bool_type(), nullptr);
CreateConstantID<bool>("bar", 20, bool_type(), &val_true);
CreateConstantID<bool>("baz", 300, bool_type(), &val_false);
auto result = inspector()->GetConstantIDs();
ASSERT_EQ(3u, result.size());
ASSERT_TRUE(result.find(1) != result.end());
EXPECT_TRUE(result[1].IsNull());
ASSERT_TRUE(result.find(20) != result.end());
EXPECT_TRUE(result[20].IsBool());
EXPECT_TRUE(result[20].AsBool());
ASSERT_TRUE(result.find(300) != result.end());
EXPECT_TRUE(result[300].IsBool());
EXPECT_FALSE(result[300].AsBool());
}
TEST_F(InspectorGetEntryPointTest, U32ConstantIDs) {
uint32_t val = 42;
CreateConstantID<uint32_t>("foo", 1, u32_type(), nullptr);
CreateConstantID<uint32_t>("bar", 20, u32_type(), &val);
auto result = inspector()->GetConstantIDs();
ASSERT_EQ(2u, result.size());
ASSERT_TRUE(result.find(1) != result.end());
EXPECT_TRUE(result[1].IsNull());
ASSERT_TRUE(result.find(20) != result.end());
EXPECT_TRUE(result[20].IsU32());
EXPECT_EQ(42u, result[20].AsU32());
}
TEST_F(InspectorGetEntryPointTest, I32ConstantIDs) {
int32_t val_neg = -42;
int32_t val_pos = 42;
CreateConstantID<int32_t>("foo", 1, i32_type(), nullptr);
CreateConstantID<int32_t>("bar", 20, i32_type(), &val_neg);
CreateConstantID<int32_t>("baz", 300, i32_type(), &val_pos);
auto result = inspector()->GetConstantIDs();
ASSERT_EQ(3u, result.size());
ASSERT_TRUE(result.find(1) != result.end());
EXPECT_TRUE(result[1].IsNull());
ASSERT_TRUE(result.find(20) != result.end());
EXPECT_TRUE(result[20].IsI32());
EXPECT_EQ(-42, result[20].AsI32());
ASSERT_TRUE(result.find(300) != result.end());
EXPECT_TRUE(result[300].IsI32());
EXPECT_EQ(42, result[300].AsI32());
}
TEST_F(InspectorGetEntryPointTest, FloatConstantIDs) {
float val_zero = 0.0f;
float val_neg = -10.0f;
float val_pos = 15.0f;
CreateConstantID<float>("foo", 1, f32_type(), nullptr);
CreateConstantID<float>("bar", 20, f32_type(), &val_zero);
CreateConstantID<float>("baz", 300, f32_type(), &val_neg);
CreateConstantID<float>("x", 4000, f32_type(), &val_pos);
auto result = inspector()->GetConstantIDs();
ASSERT_EQ(4u, result.size());
ASSERT_TRUE(result.find(1) != result.end());
EXPECT_TRUE(result[1].IsNull());
ASSERT_TRUE(result.find(20) != result.end());
EXPECT_TRUE(result[20].IsFloat());
EXPECT_FLOAT_EQ(0.0, result[20].AsFloat());
ASSERT_TRUE(result.find(300) != result.end());
EXPECT_TRUE(result[300].IsFloat());
EXPECT_FLOAT_EQ(-10.0, result[300].AsFloat());
ASSERT_TRUE(result.find(4000) != result.end());
EXPECT_TRUE(result[4000].IsFloat());
EXPECT_FLOAT_EQ(15.0, result[4000].AsFloat());
}
} // namespace } // namespace
} // namespace inspector } // namespace inspector
} // namespace tint } // namespace tint

75
src/inspector/scalar.cc Normal file
View File

@ -0,0 +1,75 @@
// Copyright 2020 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/inspector/scalar.h"
namespace tint {
namespace inspector {
Scalar::Scalar() : type_(kNull) {}
Scalar::Scalar(bool val) : type_(kBool) {
value_.b = val;
}
Scalar::Scalar(uint32_t val) : type_(kU32) {
value_.u = val;
}
Scalar::Scalar(int32_t val) : type_(kI32) {
value_.i = val;
}
Scalar::Scalar(float val) : type_(kFloat) {
value_.f = val;
}
bool Scalar::IsNull() const {
return type_ == kNull;
}
bool Scalar::IsBool() const {
return type_ == kBool;
}
bool Scalar::IsU32() const {
return type_ == kU32;
}
bool Scalar::IsI32() const {
return type_ == kI32;
}
bool Scalar::IsFloat() const {
return type_ == kFloat;
}
bool Scalar::AsBool() const {
return value_.b;
}
uint32_t Scalar::AsU32() const {
return value_.u;
}
int32_t Scalar::AsI32() const {
return value_.i;
}
float Scalar::AsFloat() const {
return value_.f;
}
} // namespace inspector
} // namespace tint

80
src/inspector/scalar.h Normal file
View File

@ -0,0 +1,80 @@
// Copyright 2020 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_INSPECTOR_SCALAR_H_
#define SRC_INSPECTOR_SCALAR_H_
#include <cstdint>
namespace tint {
namespace inspector {
/// Contains a literal scalar value
class Scalar {
public:
/// Null Constructor
Scalar();
/// @param val literal scalar value to contain
explicit Scalar(bool val);
/// @param val literal scalar value to contain
explicit Scalar(uint32_t val);
/// @param val literal scalar value to contain
explicit Scalar(int32_t val);
/// @param val literal scalar value to contain
explicit Scalar(float val);
/// @returns true if this is a null
bool IsNull() const;
/// @returns true if this is a bool
bool IsBool() const;
/// @returns true if this is a unsigned integer.
bool IsU32() const;
/// @returns true if this is a signed integer.
bool IsI32() const;
/// @returns true if this is a float.
bool IsFloat() const;
/// @returns scalar value if bool, otherwise undefined behaviour.
bool AsBool() const;
/// @returns scalar value if unsigned integer, otherwise undefined behaviour.
uint32_t AsU32() const;
/// @returns scalar value if signed integer, otherwise undefined behaviour.
int32_t AsI32() const;
/// @returns scalar value if float, otherwise undefined behaviour.
float AsFloat() const;
private:
typedef enum {
kNull,
kBool,
kU32,
kI32,
kFloat,
} Type;
typedef union {
bool b;
uint32_t u;
int32_t i;
float f;
} Value;
Type type_;
Value value_;
};
} // namespace inspector
} // namespace tint
#endif // SRC_INSPECTOR_SCALAR_H_