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
|
// 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.
// Base class for all nodes representing actual syntax
// (thus having a location in the source code)
ABSTRACT_SYNTAX_CLASS(SyntaxNodeBase, RefObject)
// The primary source location associated with this AST node
FIELD(CodePosition, Position)
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, RefObject)
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(Substitutions* 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(Substitutions* 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(ExpressionType, 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:
static RefPtr<ExpressionType> Error;
static RefPtr<ExpressionType> initializerListType;
static RefPtr<ExpressionType> Overloaded;
static Dictionary<int, RefPtr<ExpressionType>> sBuiltinTypes;
static Dictionary<String, Decl*> sMagicDecls;
// Note: just exists to make sure we can clean up
// canonical types we create along the way
static List<RefPtr<ExpressionType>> sCanonicalTypes;
static ExpressionType* GetBool();
static ExpressionType* GetFloat();
static ExpressionType* getDoubleType();
static ExpressionType* GetInt();
static ExpressionType* GetUInt();
static ExpressionType* GetVoid();
static ExpressionType* getInitializerListType();
static ExpressionType* GetError();
public:
virtual String ToString() = 0;
bool Equals(ExpressionType * type);
bool Equals(RefPtr<ExpressionType> 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();
static void Init();
static void Finalize();
ExpressionType* GetCanonicalType();
virtual RefPtr<Val> SubstituteImpl(Substitutions* subst, int* ioDiff) override;
virtual bool EqualsVal(Val* val) override;
protected:
virtual bool EqualsImpl(ExpressionType * type) = 0;
virtual ExpressionType* CreateCanonicalType() = 0;
ExpressionType* canonicalType = nullptr;
)
END_SYNTAX_CLASS()
// A substitution represents a binding of certain
// type-level variables to concrete argument values
SYNTAX_CLASS(Substitutions, RefObject)
// 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)
// Any further substitutions, relating to outer generic declarations
SYNTAX_FIELD(RefPtr<Substitutions>, outer)
RAW(
// Apply a set of substitutions to the bindings in this substitution
RefPtr<Substitutions> SubstituteImpl(Substitutions* subst, int* ioDiff);
// Check if these are equivalent substitutiosn to another set
bool Equals(Substitutions* subst);
bool operator == (const Substitutions & subst)
{
return Equals(const_cast<Substitutions*>(&subst));
}
int GetHashCode() const
{
int rs = 0;
for (auto && v : args)
{
rs ^= v->GetHashCode();
rs *= 16777619;
}
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, SyntaxNodeBase)
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 token that was used to name this modifier.
FIELD(Token, nameToken)
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(Token, Name)
RAW(
String const& getName() { return Name.Content; }
Token const& getNameToken() { return Name; }
)
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)
{
assert(state >= checkState);
checkState = state;
}
)
END_SYNTAX_CLASS()
ABSTRACT_SYNTAX_CLASS(ExpressionSyntaxNode, SyntaxNode)
RAW(typedef IExprVisitor Visitor;)
FIELD(QualType, Type)
RAW(virtual void accept(IExprVisitor* visitor, void* extra) = 0;)
END_SYNTAX_CLASS()
ABSTRACT_SYNTAX_CLASS(StatementSyntaxNode, ModifiableSyntaxNode)
RAW(typedef IStmtVisitor Visitor;)
RAW(virtual void accept(IStmtVisitor* visitor, void* extra) = 0;)
END_SYNTAX_CLASS()
|