1 // Copyright 2020 The Tint Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef SRC_AST_VARIABLE_H_ 16 #define SRC_AST_VARIABLE_H_ 17 18 #include <utility> 19 #include <vector> 20 21 #include "src/ast/access.h" 22 #include "src/ast/decoration.h" 23 #include "src/ast/expression.h" 24 #include "src/ast/storage_class.h" 25 26 namespace tint { 27 namespace ast { 28 29 // Forward declarations 30 class BindingDecoration; 31 class GroupDecoration; 32 class LocationDecoration; 33 class Type; 34 35 /// VariableBindingPoint holds a group and binding decoration. 36 struct VariableBindingPoint { 37 /// The `[[group]]` part of the binding point 38 const GroupDecoration* group = nullptr; 39 /// The `[[binding]]` part of the binding point 40 const BindingDecoration* binding = nullptr; 41 42 /// @returns true if the BindingPoint has a valid group and binding 43 /// decoration. 44 inline operator bool() const { return group && binding; } 45 }; 46 47 /// A Variable statement. 48 /// 49 /// An instance of this class represents one of three constructs in WGSL: "var" 50 /// declaration, "let" declaration, or formal parameter to a function. 51 /// 52 /// 1. A "var" declaration is a name for typed storage. Examples: 53 /// 54 /// // Declared outside a function, i.e. at module scope, requires 55 /// // a storage class. 56 /// var<workgroup> width : i32; // no initializer 57 /// var<private> height : i32 = 3; // with initializer 58 /// 59 /// // A variable declared inside a function doesn't take a storage class, 60 /// // and maps to SPIR-V Function storage. 61 /// var computed_depth : i32; 62 /// var area : i32 = compute_area(width, height); 63 /// 64 /// 2. A "let" declaration is a name for a typed value. Examples: 65 /// 66 /// let twice_depth : i32 = width + width; // Must have initializer 67 /// 68 /// 3. A formal parameter to a function is a name for a typed value to 69 /// be passed into a function. Example: 70 /// 71 /// fn twice(a: i32) -> i32 { // "a:i32" is the formal parameter 72 /// return a + a; 73 /// } 74 /// 75 /// From the WGSL draft, about "var":: 76 /// 77 /// A variable is a named reference to storage that can contain a value of a 78 /// particular type. 79 /// 80 /// Two types are associated with a variable: its store type (the type of 81 /// value that may be placed in the referenced storage) and its reference 82 /// type (the type of the variable itself). If a variable has store type T 83 /// and storage class S, then its reference type is pointer-to-T-in-S. 84 /// 85 /// This class uses the term "type" to refer to: 86 /// the value type of a "let", 87 /// the value type of the formal parameter, 88 /// or the store type of the "var". 89 // 90 /// Setting is_const: 91 /// - "var" gets false 92 /// - "let" gets true 93 /// - formal parameter gets true 94 /// 95 /// Setting storage class: 96 /// - "var" is StorageClass::kNone when using the 97 /// defaulting syntax for a "var" declared inside a function. 98 /// - "let" is always StorageClass::kNone. 99 /// - formal parameter is always StorageClass::kNone. 100 class Variable : public Castable<Variable, Node> { 101 public: 102 /// Create a variable 103 /// @param program_id the identifier of the program that owns this node 104 /// @param source the variable source 105 /// @param sym the variable symbol 106 /// @param declared_storage_class the declared storage class 107 /// @param declared_access the declared access control 108 /// @param type the declared variable type 109 /// @param is_const true if the variable is const 110 /// @param constructor the constructor expression 111 /// @param decorations the variable decorations 112 Variable(ProgramID program_id, 113 const Source& source, 114 const Symbol& sym, 115 StorageClass declared_storage_class, 116 Access declared_access, 117 const ast::Type* type, 118 bool is_const, 119 const Expression* constructor, 120 DecorationList decorations); 121 /// Move constructor 122 Variable(Variable&&); 123 124 ~Variable() override; 125 126 /// @returns the binding point information for the variable 127 VariableBindingPoint BindingPoint() const; 128 129 /// Clones this node and all transitive child nodes using the `CloneContext` 130 /// `ctx`. 131 /// @param ctx the clone context 132 /// @return the newly cloned node 133 const Variable* Clone(CloneContext* ctx) const override; 134 135 /// The variable symbol 136 const Symbol symbol; 137 138 /// The variable type 139 const ast::Type* const type; 140 141 /// True if this is a constant, false otherwise 142 const bool is_const; 143 144 /// The constructor expression or nullptr if none set 145 const Expression* const constructor; 146 147 /// The decorations attached to this variable 148 const DecorationList decorations; 149 150 /// The declared storage class 151 const StorageClass declared_storage_class; 152 153 /// The declared access control 154 const Access declared_access; 155 }; 156 157 /// A list of variables 158 using VariableList = std::vector<const Variable*>; 159 160 } // namespace ast 161 } // namespace tint 162 163 #endif // SRC_AST_VARIABLE_H_ 164