diff --git a/BUILD.gn b/BUILD.gn index 67cd7b81c8..98337098da 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -265,6 +265,8 @@ source_set("libtint_core_src") { "src/ast/float_literal.h", "src/ast/function.cc", "src/ast/function.h", + "src/ast/function_decoration.cc", + "src/ast/function_decoration.h", "src/ast/identifier_expression.cc", "src/ast/identifier_expression.h", "src/ast/if_statement.cc", diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 33cd00633f..f821429b03 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -86,6 +86,8 @@ set(TINT_LIB_SRCS ast/float_literal.h ast/function.cc ast/function.h + ast/function_decoration.cc + ast/function_decoration.h ast/identifier_expression.cc ast/identifier_expression.h ast/if_statement.cc diff --git a/src/ast/function.cc b/src/ast/function.cc index 23a15833b9..0e52bf9489 100644 --- a/src/ast/function.cc +++ b/src/ast/function.cc @@ -191,6 +191,11 @@ void Function::to_str(std::ostream& out, size_t indent) const { out << "Function " << name_ << " -> " << return_type_->type_name() << std::endl; + for (const auto& deco : decorations()) { + make_indent(out, indent); + deco->to_str(out); + } + make_indent(out, indent); out << "("; diff --git a/src/ast/function.h b/src/ast/function.h index 31897cfd48..b292464fb2 100644 --- a/src/ast/function.h +++ b/src/ast/function.h @@ -25,6 +25,7 @@ #include "src/ast/block_statement.h" #include "src/ast/builtin_decoration.h" #include "src/ast/expression.h" +#include "src/ast/function_decoration.h" #include "src/ast/location_decoration.h" #include "src/ast/node.h" #include "src/ast/set_decoration.h" @@ -81,6 +82,14 @@ class Function : public Node { /// @returns the function params const VariableList& params() const { return params_; } + /// Adds a decoration to the function + /// @param deco the decoration to set + void add_decoration(std::unique_ptr deco) { + decorations_.push_back(std::move(deco)); + } + /// @returns the decorations attached to this function + const FunctionDecorationList& decorations() const { return decorations_; } + /// Adds the given variable to the list of referenced module variables if it /// is not already included. /// @param var the module variable to add @@ -157,6 +166,7 @@ class Function : public Node { std::unique_ptr body_; std::vector referenced_module_vars_; std::vector ancestor_entry_points_; + FunctionDecorationList decorations_; }; /// A list of unique functions diff --git a/src/ast/function_decoration.cc b/src/ast/function_decoration.cc new file mode 100644 index 0000000000..a44729735b --- /dev/null +++ b/src/ast/function_decoration.cc @@ -0,0 +1,25 @@ +// 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/ast/function_decoration.h" + +namespace tint { +namespace ast { + +FunctionDecoration::FunctionDecoration() = default; + +FunctionDecoration::~FunctionDecoration() = default; + +} // namespace ast +} // namespace tint diff --git a/src/ast/function_decoration.h b/src/ast/function_decoration.h new file mode 100644 index 0000000000..4b75f305cd --- /dev/null +++ b/src/ast/function_decoration.h @@ -0,0 +1,44 @@ +// 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_AST_FUNCTION_DECORATION_H_ +#define SRC_AST_FUNCTION_DECORATION_H_ + +#include +#include +#include + +namespace tint { +namespace ast { + +/// A decoration attached to a function +class FunctionDecoration { + public: + virtual ~FunctionDecoration(); + + /// Outputs the function decoration to the given stream + /// @param out the stream to output too + virtual void to_str(std::ostream& out) const = 0; + + protected: + FunctionDecoration(); +}; + +/// A list of unique function decorations +using FunctionDecorationList = std::vector>; + +} // namespace ast +} // namespace tint + +#endif // SRC_AST_FUNCTION_DECORATION_H_ diff --git a/src/ast/function_test.cc b/src/ast/function_test.cc index f374363ca2..a75a619bcb 100644 --- a/src/ast/function_test.cc +++ b/src/ast/function_test.cc @@ -24,6 +24,7 @@ #include "src/ast/type/i32_type.h" #include "src/ast/type/void_type.h" #include "src/ast/variable.h" +// #include "src/ast/workgroup_decoration.h" namespace tint { namespace ast { @@ -297,6 +298,28 @@ TEST_F(FunctionTest, ToStr) { )"); } +// TEST_F(FunctionTest, ToStr_WithDecoration) { +// type::VoidType void_type; +// type::I32Type i32; + +// auto block = std::make_unique(); +// block->append(std::make_unique()); + +// Function f("func", {}, &void_type); +// f.set_body(std::move(block)); +// f.add_decoration(std::make_unique(2, 4, 6)); + +// std::ostringstream out; +// f.to_str(out, 2); +// EXPECT_EQ(out.str(), R"( Function func -> __void +// workgroup_size 2 4 6 +// () +// { +// Discard{} +// } +// )"); +// } + TEST_F(FunctionTest, ToStr_WithParams) { type::VoidType void_type; type::I32Type i32;