mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-05-16 20:31:20 +00:00
Handle access control on var declarations instead of via [[access]] decorations. This change does the minimal work to migrate the WGSL parser over to the new syntax. Additional changes will be needed to correctly generate defaulted access qualifiers, as well as validating access usage. The [[access]] decorations are still supported by the WGSL parser, with new deprecated warnings, but not for aliases. Example: var x : [[access(x)]] alias_to_struct; Making this work is far more effort than I want to dedicate to backwards compatibility, and I do not beleive any real-world usage will be doing this. Still TODO: * Adding access control as the optional, third parameter to ptr<>. * Calculating default accesses for the various storage types. * Validating usage of variables against the different accesses. Bug: tint:846 Change-Id: If8ca82e5d16ec319ecd01f9a2cafffd930963bde Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/53088 Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: James Price <jrprice@google.com> Reviewed-by: David Neto <dneto@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
204 lines
7.0 KiB
C++
204 lines
7.0 KiB
C++
// 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_VARIABLE_H_
|
|
#define SRC_AST_VARIABLE_H_
|
|
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include "src/ast/access.h"
|
|
#include "src/ast/decoration.h"
|
|
#include "src/ast/expression.h"
|
|
#include "src/ast/storage_class.h"
|
|
|
|
namespace tint {
|
|
namespace ast {
|
|
|
|
// Forward declarations
|
|
class BindingDecoration;
|
|
class GroupDecoration;
|
|
class LocationDecoration;
|
|
class Type;
|
|
|
|
/// A Variable statement.
|
|
///
|
|
/// An instance of this class represents one of three constructs in WGSL: "var"
|
|
/// declaration, "let" declaration, or formal parameter to a function.
|
|
///
|
|
/// 1. A "var" declaration is a name for typed storage. Examples:
|
|
///
|
|
/// // Declared outside a function, i.e. at module scope, requires
|
|
/// // a storage class.
|
|
/// var<workgroup> width : i32; // no initializer
|
|
/// var<private> height : i32 = 3; // with initializer
|
|
///
|
|
/// // A variable declared inside a function doesn't take a storage class,
|
|
/// // and maps to SPIR-V Function storage.
|
|
/// var computed_depth : i32;
|
|
/// var area : i32 = compute_area(width, height);
|
|
///
|
|
/// 2. A "let" declaration is a name for a typed value. Examples:
|
|
///
|
|
/// let twice_depth : i32 = width + width; // Must have initializer
|
|
///
|
|
/// 3. A formal parameter to a function is a name for a typed value to
|
|
/// be passed into a function. Example:
|
|
///
|
|
/// fn twice(a: i32) -> i32 { // "a:i32" is the formal parameter
|
|
/// return a + a;
|
|
/// }
|
|
///
|
|
/// From the WGSL draft, about "var"::
|
|
///
|
|
/// A variable is a named reference to storage that can contain a value of a
|
|
/// particular type.
|
|
///
|
|
/// Two types are associated with a variable: its store type (the type of
|
|
/// value that may be placed in the referenced storage) and its reference
|
|
/// type (the type of the variable itself). If a variable has store type T
|
|
/// and storage class S, then its reference type is pointer-to-T-in-S.
|
|
///
|
|
/// This class uses the term "type" to refer to:
|
|
/// the value type of a "let",
|
|
/// the value type of the formal parameter,
|
|
/// or the store type of the "var".
|
|
//
|
|
/// Setting is_const:
|
|
/// - "var" gets false
|
|
/// - "let" gets true
|
|
/// - formal parameter gets true
|
|
///
|
|
/// Setting storage class:
|
|
/// - "var" is StorageClass::kNone when using the
|
|
/// defaulting syntax for a "var" declared inside a function.
|
|
/// - "let" is always StorageClass::kNone.
|
|
/// - formal parameter is always StorageClass::kNone.
|
|
class Variable : public Castable<Variable, Node> {
|
|
public:
|
|
/// BindingPoint holds a group and binding decoration.
|
|
struct BindingPoint {
|
|
/// The `[[group]]` part of the binding point
|
|
GroupDecoration* group = nullptr;
|
|
/// The `[[binding]]` part of the binding point
|
|
BindingDecoration* binding = nullptr;
|
|
|
|
/// @returns true if the BindingPoint has a valid group and binding
|
|
/// decoration.
|
|
inline operator bool() const { return group && binding; }
|
|
};
|
|
|
|
/// Create a variable
|
|
/// @param program_id the identifier of the program that owns this node
|
|
/// @param source the variable source
|
|
/// @param sym the variable symbol
|
|
/// @param declared_storage_class the declared storage class
|
|
/// @param declared_access the declared access control
|
|
/// @param type the declared variable type
|
|
/// @param is_const true if the variable is const
|
|
/// @param constructor the constructor expression
|
|
/// @param decorations the variable decorations
|
|
Variable(ProgramID program_id,
|
|
const Source& source,
|
|
const Symbol& sym,
|
|
StorageClass declared_storage_class,
|
|
Access declared_access,
|
|
const ast::Type* type,
|
|
bool is_const,
|
|
Expression* constructor,
|
|
DecorationList decorations);
|
|
/// Move constructor
|
|
Variable(Variable&&);
|
|
|
|
~Variable() override;
|
|
|
|
/// @returns the variable symbol
|
|
const Symbol& symbol() const { return symbol_; }
|
|
|
|
/// @returns the variable type
|
|
ast::Type* type() const { return const_cast<ast::Type*>(type_); }
|
|
|
|
/// @returns the declared storage class
|
|
StorageClass declared_storage_class() const {
|
|
return declared_storage_class_;
|
|
}
|
|
|
|
/// @returns the declared access control
|
|
Access declared_access() const { return declared_access_; }
|
|
|
|
/// @returns the constructor expression or nullptr if none set
|
|
Expression* constructor() const { return constructor_; }
|
|
/// @returns true if the variable has an constructor
|
|
bool has_constructor() const { return constructor_ != nullptr; }
|
|
|
|
/// @returns true if this is a constant, false otherwise
|
|
bool is_const() const { return is_const_; }
|
|
|
|
/// @returns the decorations attached to this variable
|
|
const DecorationList& decorations() const { return decorations_; }
|
|
|
|
/// @returns the binding point information for the variable
|
|
BindingPoint binding_point() const;
|
|
|
|
/// Clones this node and all transitive child nodes using the `CloneContext`
|
|
/// `ctx`.
|
|
/// @param ctx the clone context
|
|
/// @return the newly cloned node
|
|
Variable* Clone(CloneContext* ctx) const override;
|
|
|
|
/// Writes a representation of the node to the output stream
|
|
/// @param sem the semantic info for the program
|
|
/// @param out the stream to write to
|
|
/// @param indent number of spaces to indent the node when writing
|
|
void to_str(const sem::Info& sem,
|
|
std::ostream& out,
|
|
size_t indent) const override;
|
|
|
|
protected:
|
|
/// Output information for this variable.
|
|
/// @param sem the semantic info for the program
|
|
/// @param out the stream to write to
|
|
/// @param indent number of spaces to indent the node when writing
|
|
void info_to_str(const sem::Info& sem,
|
|
std::ostream& out,
|
|
size_t indent) const;
|
|
/// Output constructor for this variable.
|
|
/// @param sem the semantic info for the program
|
|
/// @param out the stream to write to
|
|
/// @param indent number of spaces to indent the node when writing
|
|
void constructor_to_str(const sem::Info& sem,
|
|
std::ostream& out,
|
|
size_t indent) const;
|
|
|
|
private:
|
|
Variable(const Variable&) = delete;
|
|
|
|
Symbol const symbol_;
|
|
// The value type if a const or formal paramter, and the store type if a var
|
|
ast::Type const* const type_;
|
|
bool const is_const_;
|
|
Expression* const constructor_;
|
|
DecorationList const decorations_;
|
|
StorageClass const declared_storage_class_;
|
|
Access const declared_access_;
|
|
};
|
|
|
|
/// A list of variables
|
|
using VariableList = std::vector<Variable*>;
|
|
|
|
} // namespace ast
|
|
} // namespace tint
|
|
|
|
#endif // SRC_AST_VARIABLE_H_
|