1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
|
// syntax-base-defs.h
// This file defines the primary base classes for the hierarchy of
// AST nodes and related objects. For example, this is where the
// basic `Decl`, `Stmt`, `Expr`, `type`, etc. definitions come from.
ABSTRACT_SYNTAX_CLASS(NodeBase, RefObject)
// A helper to access the corresponding class on a concrete instance
RAW(
virtual SyntaxClass<NodeBase> getClass() = 0;
)
END_SYNTAX_CLASS()
// Base class for all nodes representing actual syntax
// (thus having a location in the source code)
ABSTRACT_SYNTAX_CLASS(SyntaxNodeBase, NodeBase)
// The primary source location associated with this AST node
FIELD(SourceLoc, loc)
RAW(
// Allow dynamic casting with a convenient syntax
template<typename T>
T* As()
{
SLANG_ASSERT(this);
return dynamic_cast<T*>(this);
}
)
END_SYNTAX_CLASS()
// Base class for compile-time values (most often a type).
// These are *not* syntax nodes, because they do not have
// a unique location, and any two `Val`s representing
// the same value should be conceptually equal.
ABSTRACT_SYNTAX_CLASS(Val, NodeBase)
RAW(typedef IValVisitor Visitor;)
RAW(virtual void accept(IValVisitor* visitor, void* extra) = 0;)
RAW(
// construct a new value by applying a set of parameter
// substitutions to this one
RefPtr<Val> Substitute(SubstitutionSet subst);
// Lower-level interface for substition. Like the basic
// `Substitute` above, but also takes a by-reference
// integer parameter that should be incremented when
// returning a modified value (this can help the caller
// decide whether they need to do anything).
virtual RefPtr<Val> SubstituteImpl(SubstitutionSet subst, int* ioDiff);
virtual bool EqualsVal(Val* val) = 0;
virtual String ToString() = 0;
virtual int GetHashCode() = 0;
bool operator == (const Val & v)
{
return EqualsVal(const_cast<Val*>(&v));
}
)
END_SYNTAX_CLASS()
// A type, representing a classifier for some term in the AST.
//
// Types can include "sugar" in that they may refer to a
// `typedef` which gives them a good name when printed as
// part of diagnostic messages.
//
// In order to operation on types, though, we often want
// to look past any sugar, and operate on an underlying
// "canonical" type. The reprsentation caches a pointer to
// a canonical type on every type, so we can easily
// operate on the raw representation when needed.
ABSTRACT_SYNTAX_CLASS(Type, Val)
RAW(typedef ITypeVisitor Visitor;)
RAW(virtual void accept(IValVisitor* visitor, void* extra) override;)
RAW(virtual void accept(ITypeVisitor* visitor, void* extra) = 0;)
RAW(
public:
Session* getSession() { return this->session; }
void setSession(Session* s) { this->session = s; }
bool Equals(Type * type);
bool Equals(RefPtr<Type> type);
bool IsVectorType() { return As<VectorExpressionType>() != nullptr; }
bool IsArray() { return As<ArrayExpressionType>() != nullptr; }
template<typename T>
T* As()
{
return dynamic_cast<T*>(GetCanonicalType());
}
// Convenience/legacy wrappers for `As<>`
ArithmeticExpressionType * AsArithmeticType() { return As<ArithmeticExpressionType>(); }
BasicExpressionType * AsBasicType() { return As<BasicExpressionType>(); }
VectorExpressionType * AsVectorType() { return As<VectorExpressionType>(); }
MatrixExpressionType * AsMatrixType() { return As<MatrixExpressionType>(); }
ArrayExpressionType * AsArrayType() { return As<ArrayExpressionType>(); }
DeclRefType* AsDeclRefType() { return As<DeclRefType>(); }
NamedExpressionType* AsNamedType();
bool IsTextureOrSampler();
bool IsTexture() { return As<TextureType>() != nullptr; }
bool IsSampler() { return As<SamplerStateType>() != nullptr; }
bool IsStruct();
bool IsClass();
Type* GetCanonicalType();
virtual RefPtr<Val> SubstituteImpl(SubstitutionSet subst, int* ioDiff) override;
virtual bool EqualsVal(Val* val) override;
protected:
virtual bool EqualsImpl(Type * type) = 0;
virtual RefPtr<Type> CreateCanonicalType() = 0;
Type* canonicalType = nullptr;
RefPtr<Type> canonicalTypeRefPtr;
Session* session = nullptr;
)
END_SYNTAX_CLASS()
// A substitution represents a binding of certain
// type-level variables to concrete argument values
ABSTRACT_SYNTAX_CLASS(Substitutions, RefObject)
// The next outer that this one refines.
FIELD(RefPtr<Substitutions>, outer)
RAW(
// Apply a set of substitutions to the bindings in this substitution
virtual RefPtr<Substitutions> applySubstitutionsShallow(SubstitutionSet substSet, RefPtr<Substitutions> substOuter, int* ioDiff) = 0;
// Check if these are equivalent substitutiosn to another set
virtual bool Equals(Substitutions* subst) = 0;
virtual bool operator == (const Substitutions & subst) = 0;
virtual int GetHashCode() const = 0;
)
END_SYNTAX_CLASS()
SYNTAX_CLASS(GenericSubstitution, Substitutions)
// The generic declaration that defines the
// parametesr we are binding to arguments
DECL_FIELD(GenericDecl*, genericDecl)
// The actual values of the arguments
SYNTAX_FIELD(List<RefPtr<Val>>, args)
RAW(
// Apply a set of substitutions to the bindings in this substitution
virtual RefPtr<Substitutions> applySubstitutionsShallow(SubstitutionSet substSet, RefPtr<Substitutions> substOuter, int* ioDiff) override;
// Check if these are equivalent substitutiosn to another set
virtual bool Equals(Substitutions* subst) override;
virtual bool operator == (const Substitutions & subst) override
{
return Equals(const_cast<Substitutions*>(&subst));
}
virtual int GetHashCode() const override
{
int rs = 0;
for (auto && v : args)
{
rs ^= v->GetHashCode();
rs *= 16777619;
}
return rs;
}
)
END_SYNTAX_CLASS()
SYNTAX_CLASS(ThisTypeSubstitution, Substitutions)
// The declaration of the interface that we are specializing
FIELD_INIT(InterfaceDecl*, interfaceDecl, nullptr)
// A witness that shows that the concrete type used to
// specialize the interface conforms to the interface.
FIELD(RefPtr<SubtypeWitness>, witness)
// The actual type that provides the lookup scope for an associated type
RAW(
// Apply a set of substitutions to the bindings in this substitution
virtual RefPtr<Substitutions> applySubstitutionsShallow(SubstitutionSet substSet, RefPtr<Substitutions> substOuter, int* ioDiff) override;
// Check if these are equivalent substitutiosn to another set
virtual bool Equals(Substitutions* subst) override;
virtual bool operator == (const Substitutions & subst) override
{
return Equals(const_cast<Substitutions*>(&subst));
}
virtual int GetHashCode() const override;
)
END_SYNTAX_CLASS()
SYNTAX_CLASS(GlobalGenericParamSubstitution, Substitutions)
// the __generic_param decl to be substituted
DECL_FIELD(GlobalGenericParamDecl*, paramDecl)
// the actual type to substitute in
SYNTAX_FIELD(RefPtr<Type>, actualType)
RAW(
struct ConstraintArg
{
RefPtr<Decl> decl;
RefPtr<Val> val;
};
)
// the values that satisfy any constraints on the type parameter
SYNTAX_FIELD(List<ConstraintArg>, constraintArgs)
RAW(
// Apply a set of substitutions to the bindings in this substitution
virtual RefPtr<Substitutions> applySubstitutionsShallow(SubstitutionSet substSet, RefPtr<Substitutions> substOuter, int* ioDiff) override;
// Check if these are equivalent substitutiosn to another set
virtual bool Equals(Substitutions* subst) override;
virtual bool operator == (const Substitutions & subst) override
{
return Equals(const_cast<Substitutions*>(&subst));
}
virtual int GetHashCode() const override
{
int rs = actualType->GetHashCode();
for (auto && a : constraintArgs)
{
rs = combineHash(rs, a.val->GetHashCode());
}
return rs;
}
)
END_SYNTAX_CLASS()
ABSTRACT_SYNTAX_CLASS(SyntaxNode, SyntaxNodeBase)
END_SYNTAX_CLASS()
//
// All modifiers are represented as full-fledged objects in the AST
// (that is, we don't use a bitfield, even for simple/common flags).
// This ensures that we can track source locations for all modifiers.
//
ABSTRACT_SYNTAX_CLASS(Modifier, SyntaxNode)
RAW(typedef IModifierVisitor Visitor;)
RAW(virtual void accept(IModifierVisitor* visitor, void* extra) = 0;)
// Next modifier in linked list of modifiers on same piece of syntax
SYNTAX_FIELD(RefPtr<Modifier>, next)
// The keyword that was used to introduce t that was used to name this modifier.
FIELD(Name*, name)
RAW(
Name* getName() { return name; }
NameLoc getNameAndLoc() { return NameLoc(name, loc); }
)
END_SYNTAX_CLASS()
// A syntax node which can have modifiers appled
ABSTRACT_SYNTAX_CLASS(ModifiableSyntaxNode, SyntaxNode)
SYNTAX_FIELD(Modifiers, modifiers)
RAW(
template<typename T>
FilteredModifierList<T> GetModifiersOfType() { return FilteredModifierList<T>(modifiers.first.Ptr()); }
// Find the first modifier of a given type, or return `nullptr` if none is found.
template<typename T>
T* FindModifier()
{
return *GetModifiersOfType<T>().begin();
}
template<typename T>
bool HasModifier() { return FindModifier<T>() != nullptr; }
)
END_SYNTAX_CLASS()
// An intermediate type to represent either a single declaration, or a group of declarations
ABSTRACT_SYNTAX_CLASS(DeclBase, ModifiableSyntaxNode)
RAW(typedef IDeclVisitor Visitor;)
RAW(virtual void accept(IDeclVisitor* visitor, void* extra) = 0;)
END_SYNTAX_CLASS()
ABSTRACT_SYNTAX_CLASS(Decl, DeclBase)
DECL_FIELD(ContainerDecl*, ParentDecl RAW(=nullptr))
FIELD(NameLoc, nameAndLoc)
RAW(
Name* getName() { return nameAndLoc.name; }
SourceLoc getNameLoc() { return nameAndLoc.loc ; }
NameLoc getNameAndLoc() { return nameAndLoc ; }
)
FIELD_INIT(DeclCheckState, checkState, DeclCheckState::Unchecked)
// The next declaration defined in the same container with the same name
DECL_FIELD(Decl*, nextInContainerWithSameName RAW(= nullptr))
RAW(
bool IsChecked(DeclCheckState state) { return checkState >= state; }
void SetCheckState(DeclCheckState state)
{
SLANG_RELEASE_ASSERT(state >= checkState);
checkState = state;
}
)
END_SYNTAX_CLASS()
ABSTRACT_SYNTAX_CLASS(Expr, SyntaxNode)
RAW(typedef IExprVisitor Visitor;)
FIELD(QualType, type)
RAW(virtual void accept(IExprVisitor* visitor, void* extra) = 0;)
END_SYNTAX_CLASS()
ABSTRACT_SYNTAX_CLASS(Stmt, ModifiableSyntaxNode)
RAW(typedef IStmtVisitor Visitor;)
RAW(virtual void accept(IStmtVisitor* visitor, void* extra) = 0;)
END_SYNTAX_CLASS()
|