• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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