1 // Copyright 2021 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_SEM_VARIABLE_H_ 16 #define SRC_SEM_VARIABLE_H_ 17 18 #include <vector> 19 20 #include "src/ast/access.h" 21 #include "src/ast/storage_class.h" 22 #include "src/sem/binding_point.h" 23 #include "src/sem/expression.h" 24 #include "src/sem/parameter_usage.h" 25 26 namespace tint { 27 28 // Forward declarations 29 namespace ast { 30 class IdentifierExpression; 31 class Variable; 32 } // namespace ast 33 34 namespace sem { 35 36 // Forward declarations 37 class CallTarget; 38 class Type; 39 class VariableUser; 40 41 /// Variable is the base class for local variables, global variables and 42 /// parameters. 43 class Variable : public Castable<Variable, Node> { 44 public: 45 /// Constructor 46 /// @param declaration the AST declaration node 47 /// @param type the variable type 48 /// @param storage_class the variable storage class 49 /// @param access the variable access control type 50 /// @param constant_value the constant value for the variable. May be invalid 51 Variable(const ast::Variable* declaration, 52 const sem::Type* type, 53 ast::StorageClass storage_class, 54 ast::Access access, 55 Constant constant_value); 56 57 /// Destructor 58 ~Variable() override; 59 60 /// @returns the AST declaration node Declaration()61 const ast::Variable* Declaration() const { return declaration_; } 62 63 /// @returns the canonical type for the variable Type()64 const sem::Type* Type() const { return type_; } 65 66 /// @returns the storage class for the variable StorageClass()67 ast::StorageClass StorageClass() const { return storage_class_; } 68 69 /// @returns the access control for the variable Access()70 ast::Access Access() const { return access_; } 71 72 /// @return the constant value of this expression ConstantValue()73 const Constant& ConstantValue() const { return constant_value_; } 74 75 /// @returns the variable constructor expression, or nullptr if the variable 76 /// does not have one. Constructor()77 const Expression* Constructor() const { return constructor_; } 78 79 /// Sets the variable constructor expression. 80 /// @param constructor the constructor expression to assign to this variable. SetConstructor(const Expression * constructor)81 void SetConstructor(const Expression* constructor) { 82 constructor_ = constructor; 83 } 84 85 /// @returns the expressions that use the variable Users()86 const std::vector<const VariableUser*>& Users() const { return users_; } 87 88 /// @param user the user to add AddUser(const VariableUser * user)89 void AddUser(const VariableUser* user) { users_.emplace_back(user); } 90 91 private: 92 const ast::Variable* const declaration_; 93 const sem::Type* const type_; 94 const ast::StorageClass storage_class_; 95 const ast::Access access_; 96 const Constant constant_value_; 97 const Expression* constructor_ = nullptr; 98 std::vector<const VariableUser*> users_; 99 }; 100 101 /// LocalVariable is a function-scope variable 102 class LocalVariable : public Castable<LocalVariable, Variable> { 103 public: 104 /// Constructor 105 /// @param declaration the AST declaration node 106 /// @param type the variable type 107 /// @param storage_class the variable storage class 108 /// @param access the variable access control type 109 /// @param statement the statement that declared this local variable 110 /// @param constant_value the constant value for the variable. May be invalid 111 LocalVariable(const ast::Variable* declaration, 112 const sem::Type* type, 113 ast::StorageClass storage_class, 114 ast::Access access, 115 const sem::Statement* statement, 116 Constant constant_value); 117 118 /// Destructor 119 ~LocalVariable() override; 120 121 /// @returns the statement that declares this local variable Statement()122 const sem::Statement* Statement() const { return statement_; } 123 124 /// @returns the Type, Function or Variable that this local variable shadows Shadows()125 const sem::Node* Shadows() const { return shadows_; } 126 127 /// Sets the Type, Function or Variable that this local variable shadows 128 /// @param shadows the Type, Function or Variable that this variable shadows SetShadows(const sem::Node * shadows)129 void SetShadows(const sem::Node* shadows) { shadows_ = shadows; } 130 131 private: 132 const sem::Statement* const statement_; 133 const sem::Node* shadows_ = nullptr; 134 }; 135 136 /// GlobalVariable is a module-scope variable 137 class GlobalVariable : public Castable<GlobalVariable, Variable> { 138 public: 139 /// Constructor 140 /// @param declaration the AST declaration node 141 /// @param type the variable type 142 /// @param storage_class the variable storage class 143 /// @param access the variable access control type 144 /// @param constant_value the constant value for the variable. May be invalid 145 /// @param binding_point the optional resource binding point of the variable 146 GlobalVariable(const ast::Variable* declaration, 147 const sem::Type* type, 148 ast::StorageClass storage_class, 149 ast::Access access, 150 Constant constant_value, 151 sem::BindingPoint binding_point = {}); 152 153 /// Destructor 154 ~GlobalVariable() override; 155 156 /// @returns the resource binding point for the variable BindingPoint()157 sem::BindingPoint BindingPoint() const { return binding_point_; } 158 159 /// @param id the constant identifier to assign to this variable SetConstantId(uint16_t id)160 void SetConstantId(uint16_t id) { 161 constant_id_ = id; 162 is_overridable_ = true; 163 } 164 165 /// @returns the pipeline constant ID associated with the variable ConstantId()166 uint16_t ConstantId() const { return constant_id_; } 167 168 /// @param is_overridable true if this is a pipeline overridable constant 169 void SetIsOverridable(bool is_overridable = true) { 170 is_overridable_ = is_overridable; 171 } 172 173 /// @returns true if this is pipeline overridable constant IsOverridable()174 bool IsOverridable() const { return is_overridable_; } 175 176 private: 177 const sem::BindingPoint binding_point_; 178 179 bool is_overridable_ = false; 180 uint16_t constant_id_ = 0; 181 }; 182 183 /// Parameter is a function parameter 184 class Parameter : public Castable<Parameter, Variable> { 185 public: 186 /// Constructor for function parameters 187 /// @param declaration the AST declaration node 188 /// @param index the index of the parmeter in the function 189 /// @param type the variable type 190 /// @param storage_class the variable storage class 191 /// @param access the variable access control type 192 /// @param usage the semantic usage for the parameter 193 Parameter(const ast::Variable* declaration, 194 uint32_t index, 195 const sem::Type* type, 196 ast::StorageClass storage_class, 197 ast::Access access, 198 const ParameterUsage usage = ParameterUsage::kNone); 199 200 /// Destructor 201 ~Parameter() override; 202 203 /// @return the index of the parmeter in the function Index()204 uint32_t Index() const { return index_; } 205 206 /// @returns the semantic usage for the parameter Usage()207 ParameterUsage Usage() const { return usage_; } 208 209 /// @returns the CallTarget owner of this parameter Owner()210 CallTarget const* Owner() const { return owner_; } 211 212 /// @param owner the CallTarget owner of this parameter SetOwner(CallTarget const * owner)213 void SetOwner(CallTarget const* owner) { owner_ = owner; } 214 215 /// @returns the Type, Function or Variable that this local variable shadows Shadows()216 const sem::Node* Shadows() const { return shadows_; } 217 218 /// Sets the Type, Function or Variable that this local variable shadows 219 /// @param shadows the Type, Function or Variable that this variable shadows SetShadows(const sem::Node * shadows)220 void SetShadows(const sem::Node* shadows) { shadows_ = shadows; } 221 222 private: 223 const uint32_t index_; 224 const ParameterUsage usage_; 225 CallTarget const* owner_ = nullptr; 226 const sem::Node* shadows_ = nullptr; 227 }; 228 229 /// ParameterList is a list of Parameter 230 using ParameterList = std::vector<const Parameter*>; 231 232 /// VariableUser holds the semantic information for an identifier expression 233 /// node that resolves to a variable. 234 class VariableUser : public Castable<VariableUser, Expression> { 235 public: 236 /// Constructor 237 /// @param declaration the AST identifier node 238 /// @param statement the statement that owns this expression 239 /// @param variable the semantic variable 240 VariableUser(const ast::IdentifierExpression* declaration, 241 Statement* statement, 242 sem::Variable* variable); 243 244 /// @returns the variable that this expression refers to Variable()245 const sem::Variable* Variable() const { return variable_; } 246 247 private: 248 const sem::Variable* const variable_; 249 }; 250 251 } // namespace sem 252 } // namespace tint 253 254 #endif // SRC_SEM_VARIABLE_H_ 255