1
2
3
4
5
6 #ifndef CMAJOR_BINDER_BOUND_EXPRESSION_INCLUDED
7 #define CMAJOR_BINDER_BOUND_EXPRESSION_INCLUDED
8 #include <cmajor/binder/BoundNode.hpp>
9 #include <cmajor/symbols/TypeSymbol.hpp>
10 #include <cmajor/symbols/VariableSymbol.hpp>
11 #include <cmajor/symbols/ConstantSymbol.hpp>
12 #include <cmajor/symbols/EnumSymbol.hpp>
13 #include <cmajor/symbols/DelegateSymbol.hpp>
14
15 namespace cmajor { namespace binder {
16
17 using namespace cmajor::symbols;
18 class BoundCompileUnit;
19
20 enum class BoundExpressionFlags : uint8_t
21 {
22 none= 0,
23 argIsExplicitThisOrBasePtr= 1 << 0,
24 bindToRvalueReference= 1 << 1,
25 virtualCall= 1 << 2,
26 deref= 1 << 3,
27 exceptionCapture= 1 << 4
28 };
29
30 inline BoundExpressionFlags operator|(BoundExpressionFlags left, BoundExpressionFlags right)
31 {
32 return BoundExpressionFlags(uint8_t(left) | uint8_t(right));
33 }
34
35 inline BoundExpressionFlags operator&(BoundExpressionFlags left, BoundExpressionFlags right)
36 {
37 return BoundExpressionFlags(uint8_t(left) & uint8_t(right));
38 }
39
40 class BoundFunctionCall;
41 class BoundFunction;
42
43 class BoundExpression : public BoundNode
44 {
45 public:
46 BoundExpression(const Span& span_, const boost::uuids::uuid& moduleId_, BoundNodeType boundNodeType_, TypeSymbol* type_);
47 BoundExpression(const BoundExpression&) = delete;
48 BoundExpression& operator=(const BoundExpression&) = delete;
49 virtual BoundExpression* Clone() = 0;
50 virtual bool IsComplete() const { return true; }
51 virtual bool IsLvalueExpression() const { return false; }
52 virtual bool HasValue() const { return false; }
53 virtual std::string TypeString() const { return "expression"; }
54 virtual std::std::unique_ptr<Value>ToValue(BoundCompileUnit&boundCompileUnit) const{returnstd::unique_ptr<Value>(); }
55 virtual bool ContainsExceptionCapture() const { return GetFlag(BoundExpressionFlags::exceptionCapture); }
56 const TypeSymbol* GetType() const { return type; }
57 TypeSymbol* GetType() { return type; }
58 bool GetFlag(BoundExpressionFlags flag) const { return (flags & flag) != BoundExpressionFlags::none; }
59 void SetFlag(BoundExpressionFlags flag) { flags = flags | flag; }
60 void AddTemporaryDestructorCall(std::std::unique_ptr<BoundFunctionCall>&&destructorCall);
61 void MoveTemporaryDestructorCallsTo(BoundExpression& expression);
62 void DestroyTemporaries(Emitter& emitter);
63 private:
64 TypeSymbol* type;
65 BoundExpressionFlags flags;
66 std::vector<std::std::unique_ptr<BoundFunctionCall>>temporaryDestructorCalls;
67 };
68
69 class BoundParameter : public BoundExpression
70 {
71 public:
72 BoundParameter(const Span& span_, const boost::uuids::uuid& moduleId_, ParameterSymbol* parameterSymbol_);
73 BoundExpression* Clone() override;
74 ParameterSymbol* GetParameterSymbol() { return parameterSymbol; }
75 void Load(Emitter& emitter, OperationFlags flags) override;
76 void Store(Emitter& emitter, OperationFlags flags) override;
77 void Accept(BoundNodeVisitor& visitor) override;
78 bool HasValue() const override { return true; }
79 bool IsLvalueExpression() const override { return true; }
80 std::string TypeString() const override { return "parameter"; }
81 private:
82 ParameterSymbol* parameterSymbol;
83 };
84
85 class BoundLocalVariable : public BoundExpression
86 {
87 public:
88 BoundLocalVariable(const Span& span_, const boost::uuids::uuid& moduleId_, LocalVariableSymbol* localVariableSymbol_);
89 BoundExpression* Clone() override;
90 LocalVariableSymbol* GetLocalVariableSymbol() { return localVariableSymbol; }
91 void Load(Emitter& emitter, OperationFlags flags) override;
92 void Store(Emitter& emitter, OperationFlags flags) override;
93 void Accept(BoundNodeVisitor& visitor) override;
94 bool HasValue() const override { return true; }
95 bool IsLvalueExpression() const override { return true; }
96 std::string TypeString() const override { return "local variable"; }
97 private:
98 LocalVariableSymbol* localVariableSymbol;
99 };
100
101 class BoundMemberVariable : public BoundExpression
102 {
103 public:
104 BoundMemberVariable(const Span& span_, const boost::uuids::uuid& moduleId_, MemberVariableSymbol* memberVariableSymbol_);
105 BoundExpression* Clone() override;
106 void Load(Emitter& emitter, OperationFlags flags) override;
107 void Store(Emitter& emitter, OperationFlags flags) override;
108 void Accept(BoundNodeVisitor& visitor) override;
109 bool HasValue() const override { return true; }
110 bool IsLvalueExpression() const override { return true; }
111 void SetClassPtr(std::std::unique_ptr<BoundExpression>&&classPtr_);
112 void SetStaticInitNeeded() { staticInitNeeded = true; }
113 std::string TypeString() const override { return "member variable"; }
114 MemberVariableSymbol* GetMemberVariableSymbol() { return memberVariableSymbol; }
115 private:
116 MemberVariableSymbol* memberVariableSymbol;
117 std::unique_ptr<BoundExpression> classPtr;
118 bool staticInitNeeded;
119 };
120
121 class BoundConstant : public BoundExpression
122 {
123 public:
124 BoundConstant(const Span& span_, const boost::uuids::uuid& moduleId_, ConstantSymbol* constantSymbol_);
125 BoundExpression* Clone() override;
126 void Load(Emitter& emitter, OperationFlags flags) override;
127 void Store(Emitter& emitter, OperationFlags flags) override;
128 void Accept(BoundNodeVisitor& visitor) override;
129 bool HasValue() const override { return true; }
130 std::string TypeString() const override { return "constant"; }
131 std::std::unique_ptr<Value>ToValue(BoundCompileUnit&boundCompileUnit) const override{returnstd::unique_ptr<Value>(constantSymbol->GetValue()->Clone()); }
132 ConstantSymbol* GetConstantSymbol() { return constantSymbol; }
133 private:
134 ConstantSymbol* constantSymbol;
135 };
136
137 class BoundEnumConstant : public BoundExpression
138 {
139 public:
140 BoundEnumConstant(const Span& span_, const boost::uuids::uuid& moduleId_, EnumConstantSymbol* enumConstantSymbol_);
141 BoundExpression* Clone() override;
142 void Load(Emitter& emitter, OperationFlags flags) override;
143 void Store(Emitter& emitter, OperationFlags flags) override;
144 void Accept(BoundNodeVisitor& visitor) override;
145 bool HasValue() const override { return true; }
146 std::string TypeString() const override { return "enumeration constant"; }
147 std::std::unique_ptr<Value>ToValue(BoundCompileUnit&boundCompileUnit) const override{returnstd::unique_ptr<Value>(enumConstantSymbol->GetValue()->Clone()); }
148 EnumConstantSymbol* GetEnumConstantSymbol() { return enumConstantSymbol; }
149 private:
150 EnumConstantSymbol* enumConstantSymbol;
151 };
152
153 class BoundLiteral : public BoundExpression
154 {
155 public:
156 BoundLiteral(std::std::unique_ptr<Value>&&value_, TypeSymbol*type_);
157 BoundExpression* Clone() override;
158 void Load(Emitter& emitter, OperationFlags flags) override;
159 void Store(Emitter& emitter, OperationFlags flags) override;
160 void Accept(BoundNodeVisitor& visitor) override;
161 std::string TypeString() const override { return "literal"; }
162 bool HasValue() const override { return true; }
163 std::unique_ptr<Value> ToValue(BoundCompileUnit& boundCompileUnit) const override;
164 Value* GetValue() { return value.get(); }
165 private:
166 std::unique_ptr<Value> value;
167 };
168
169 class BoundGlobalVariable : public BoundExpression
170 {
171 public:
172 BoundGlobalVariable(const Span& span_, const boost::uuids::uuid& moduleId_, GlobalVariableSymbol* globalVariableSymbol_);
173 GlobalVariableSymbol* GetGlobalVariableSymbol() const { return globalVariableSymbol; }
174 BoundExpression* Clone() override;
175 bool IsLvalueExpression() const override { return true; }
176 bool HasValue() const override { return true; }
177 void Load(Emitter& emitter, OperationFlags flags) override;
178 void Store(Emitter& emitter, OperationFlags flags) override;
179 void Accept(BoundNodeVisitor& visitor) override;
180 std::string TypeString() const override { return "global variable"; }
181 private:
182 GlobalVariableSymbol* globalVariableSymbol;
183 };
184
185
186 class BoundTemporary : public BoundExpression
187 {
188 public:
189 BoundTemporary(std::std::unique_ptr<BoundExpression>&&rvalueExpr_, std::std::unique_ptr<BoundLocalVariable>&&backingStore_);
190 BoundExpression* Clone() override;
191 void Load(Emitter& emitter, OperationFlags flags) override;
192 void Store(Emitter& emitter, OperationFlags flags) override;
193 void Accept(BoundNodeVisitor& visitor) override;
194 bool HasValue() const override { return true; }
195 bool IsLvalueExpression() const override { return true; }
196 std::string TypeString() const override { return "temporary"; }
197 std::unique_ptr<Value> ToValue(BoundCompileUnit& boundCompileUnit) const override;
198 bool ContainsExceptionCapture() const override;
199 BoundExpression* RvalueExpr() { return rvalueExpr.get(); }
200 BoundLocalVariable* BackingStore() { return backingStore.get(); }
201 private:
202 std::unique_ptr<BoundExpression> rvalueExpr;
203 std::unique_ptr<BoundLocalVariable> backingStore;
204 };
205
206 class BoundSizeOfExpression : public BoundExpression
207 {
208 public:
209 BoundSizeOfExpression(const Span& span_, const boost::uuids::uuid& moduleId_, TypeSymbol* type_, TypeSymbol* pointerType_);
210 BoundExpression* Clone() override;
211 void Load(Emitter& emitter, OperationFlags flags) override;
212 void Store(Emitter& emitter, OperationFlags flags) override;
213 void Accept(BoundNodeVisitor& visitor) override;
214 std::string TypeString() const override { return "sizeof"; }
215 TypeSymbol* PointerType() { return pointerType; }
216 private:
217 TypeSymbol* pointerType;
218 };
219
220 class BoundAddressOfExpression : public BoundExpression
221 {
222 public:
223 BoundAddressOfExpression(std::std::unique_ptr<BoundExpression>&&subject_, TypeSymbol*type_);
224 BoundExpression* Clone() override;
225 void Load(Emitter& emitter, OperationFlags flags) override;
226 void Store(Emitter& emitter, OperationFlags flags) override;
227 void Accept(BoundNodeVisitor& visitor) override;
228 std::string TypeString() const override { return "address of expression"; }
229 std::std::unique_ptr<BoundExpression>&Subject(){returnsubject;}
230 std::unique_ptr<Value> ToValue(BoundCompileUnit& boundCompileUnit) const override;
231 bool ContainsExceptionCapture() const override;
232 private:
233 std::unique_ptr<BoundExpression> subject;
234 };
235
236 class BoundDereferenceExpression : public BoundExpression
237 {
238 public:
239 BoundDereferenceExpression(std::std::unique_ptr<BoundExpression>&&subject_, TypeSymbol*type_);
240 BoundExpression* Clone() override;
241 void Load(Emitter& emitter, OperationFlags flags) override;
242 void Store(Emitter& emitter, OperationFlags flags) override;
243 void Accept(BoundNodeVisitor& visitor) override;
244 std::string TypeString() const override { return "deference expression"; }
245 bool IsLvalueExpression() const override { return true; }
246 std::std::unique_ptr<BoundExpression>&Subject(){returnsubject;}
247 bool ContainsExceptionCapture() const override;
248 private:
249 std::unique_ptr<BoundExpression> subject;
250 };
251
252 class BoundReferenceToPointerExpression : public BoundExpression
253 {
254 public:
255 BoundReferenceToPointerExpression(std::std::unique_ptr<BoundExpression>&&subject_, TypeSymbol*type_);
256 BoundExpression* Clone() override;
257 void Load(Emitter& emitter, OperationFlags flags) override;
258 void Store(Emitter& emitter, OperationFlags flags) override;
259 void Accept(BoundNodeVisitor& visitor) override;
260 std::string TypeString() const override { return "reference to pointer expression"; }
261 bool ContainsExceptionCapture() const override;
262 std::std::unique_ptr<BoundExpression>&Subject(){returnsubject;}
263 private:
264 std::unique_ptr<BoundExpression> subject;
265 };
266
267 class BoundFunctionCall : public BoundExpression
268 {
269 public:
270 BoundFunctionCall(const Span& span_, const boost::uuids::uuid& moduleId_, FunctionSymbol* functionSymbol_);
271 BoundFunctionCall(const BoundFunctionCall&) = delete;
272 BoundFunctionCall& operator=(const BoundFunctionCall&) = delete;
273 BoundExpression* Clone() override;
274 void Load(Emitter& emitter, OperationFlags flags) override;
275 void Store(Emitter& emitter, OperationFlags flags) override;
276 void Accept(BoundNodeVisitor& visitor) override;
277 bool HasValue() const override;
278 std::string TypeString() const override { return "function call"; }
279 bool IsLvalueExpression() const override;
280 const FunctionSymbol* GetFunctionSymbol() const { return functionSymbol; }
281 FunctionSymbol* GetFunctionSymbol() { return functionSymbol; }
282 void AddArgument(std::std::unique_ptr<BoundExpression>&&argument);
283 void SetArguments(std::std::vector<std::std::unique_ptr<BoundExpression>>&&arguments_);
284 const std::std::vector<std::std::unique_ptr<BoundExpression>>&Arguments() const{returnarguments;}
285 void AddTemporary(std::std::unique_ptr<BoundLocalVariable>&&temporary);
286 bool ContainsExceptionCapture() const override;
287 std::vector<std::std::unique_ptr<GenObject>>ReleaseTemporaries();
288 private:
289 FunctionSymbol* functionSymbol;
290 std::vector<std::std::unique_ptr<BoundExpression>>arguments;
291 std::vector<std::std::unique_ptr<BoundLocalVariable>>temporaries;
292 };
293
294 class BoundDelegateCall : public BoundExpression
295 {
296 public:
297 BoundDelegateCall(const Span& span_, const boost::uuids::uuid& moduleId_, DelegateTypeSymbol* delegateType_);
298 BoundExpression* Clone() override;
299 void Load(Emitter& emitter, OperationFlags flags) override;
300 void Store(Emitter& emitter, OperationFlags flags) override;
301 void Accept(BoundNodeVisitor& visitor) override;
302 bool HasValue() const override;
303 std::string TypeString() const override { return "delegate call"; }
304 bool IsLvalueExpression() const override;
305 DelegateTypeSymbol* GetDelegateSymbol() { return delegateTypeSymbol; }
306 void AddArgument(std::std::unique_ptr<BoundExpression>&&argument);
307 const std::std::vector<std::std::unique_ptr<BoundExpression>>&Arguments() const{returnarguments;}
308 bool ContainsExceptionCapture() const override;
309 private:
310 DelegateTypeSymbol* delegateTypeSymbol;
311 std::vector<std::std::unique_ptr<BoundExpression>>arguments;
312 };
313
314 class BoundClassDelegateCall : public BoundExpression
315 {
316 public:
317 BoundClassDelegateCall(const Span& span_, const boost::uuids::uuid& moduleId_, ClassDelegateTypeSymbol* classDelegateType_);
318 BoundExpression* Clone() override;
319 void Load(Emitter& emitter, OperationFlags flags) override;
320 void Store(Emitter& emitter, OperationFlags flags) override;
321 void Accept(BoundNodeVisitor& visitor) override;
322 bool HasValue() const override;
323 std::string TypeString() const override { return "class delegate call"; }
324 bool IsLvalueExpression() const override;
325 ClassDelegateTypeSymbol* GetClassDelegateSymbol() { return classDelegateTypeSymbol; }
326 void AddArgument(std::std::unique_ptr<BoundExpression>&&argument);
327 const std::std::vector<std::std::unique_ptr<BoundExpression>>&Arguments() const{returnarguments;}
328 bool ContainsExceptionCapture() const override;
329 private:
330 ClassDelegateTypeSymbol* classDelegateTypeSymbol;
331 std::vector<std::std::unique_ptr<BoundExpression>>arguments;
332 };
333
334 class BoundConstructExpression : public BoundExpression
335 {
336 public:
337 BoundConstructExpression(std::std::unique_ptr<BoundExpression>&&constructorCall_, TypeSymbol*resultType_);
338 BoundExpression* Clone() override;
339 void Load(Emitter& emitter, OperationFlags flags) override;
340 void Store(Emitter& emitter, OperationFlags flags) override;
341 void Accept(BoundNodeVisitor& visitor) override;
342 bool HasValue() const override { return true; }
343 std::string TypeString() const override { return "construct expression"; }
344 bool ContainsExceptionCapture() const override;
345 BoundExpression* ConstructorCall() { return constructorCall.get(); }
346 private:
347 std::unique_ptr<BoundExpression> constructorCall;
348 };
349
350 class BoundConstructAndReturnTemporaryExpression : public BoundExpression
351 {
352 public:
353 BoundConstructAndReturnTemporaryExpression(std::std::unique_ptr<BoundExpression>&&constructorCall_, std::std::unique_ptr<BoundExpression>&&boundTemporary_);
354 BoundExpression* Clone() override;
355 void Load(Emitter& emitter, OperationFlags flags) override;
356 void Store(Emitter& emitter, OperationFlags flags) override;
357 void Accept(BoundNodeVisitor& visitor) override;
358 bool HasValue() const override { return true; }
359 bool IsLvalueExpression() const override { return true; }
360 std::string TypeString() const override { return "construct and return temporary expression"; }
361 bool ContainsExceptionCapture() const override;
362 BoundExpression* ConstructorCall() { return constructorCall.get(); }
363 BoundExpression* BoundTemporary() { return boundTemporary.get(); }
364 private:
365 std::unique_ptr<BoundExpression> constructorCall;
366 std::unique_ptr<BoundExpression> boundTemporary;
367 };
368
369 class BoundClassOrClassDelegateConversionResult : public BoundExpression
370 {
371 public:
372 BoundClassOrClassDelegateConversionResult(std::std::unique_ptr<BoundExpression>&&conversionResult_, std::std::unique_ptr<BoundFunctionCall>&&conversionFunctionCall_);
373 BoundExpression* Clone() override;
374 void Load(Emitter& emitter, OperationFlags flags) override;
375 void Store(Emitter& emitter, OperationFlags flags) override;
376 void Accept(BoundNodeVisitor& visitor) override;
377 bool HasValue() const override { return true; }
378 bool IsLvalueExpression() const override { return true; }
379 std::string TypeString() const override { return "class conversion result"; }
380 bool ContainsExceptionCapture() const override;
381 BoundExpression* ConversionResult() { return conversionResult.get(); }
382 BoundFunctionCall* ConversionFunctionCall() { return conversionFunctionCall.get(); }
383 private:
384 std::unique_ptr<BoundExpression> conversionResult;
385 std::unique_ptr<BoundFunctionCall> conversionFunctionCall;
386 };
387
388 class BoundConversion : public BoundExpression
389 {
390 public:
391 BoundConversion(std::std::unique_ptr<BoundExpression>&&sourceExpr_, FunctionSymbol*conversionFun_);
392 BoundExpression* Clone() override;
393 void Load(Emitter& emitter, OperationFlags flags) override;
394 void Store(Emitter& emitter, OperationFlags flags) override;
395 void Accept(BoundNodeVisitor& visitor) override;
396 bool HasValue() const override { return true; }
397 bool IsLvalueExpression() const override;
398 std::string TypeString() const override { return "conversion"; }
399 BoundExpression* SourceExpr() { return sourceExpr.get(); }
400 FunctionSymbol* ConversionFun() { return conversionFun; }
401 std::unique_ptr<Value> ToValue(BoundCompileUnit& boundCompileUnit) const override;
402 bool ContainsExceptionCapture() const override;
403 void AddTemporary(std::std::unique_ptr<BoundLocalVariable>&&temporary);
404 private:
405 std::unique_ptr<BoundExpression> sourceExpr;
406 FunctionSymbol* conversionFun;
407 std::vector<std::std::unique_ptr<BoundLocalVariable>>temporaries;
408 };
409
410 class BoundIsExpression : public BoundExpression
411 {
412 public:
413 BoundIsExpression(std::std::unique_ptr<BoundExpression>&&expr_, ClassTypeSymbol*rightClassType_, TypeSymbol*boolType_,
414 std::std::unique_ptr<BoundLocalVariable>&&leftClassIdVar_, std::std::unique_ptr<BoundLocalVariable>&&rightClassIdVar_);
415 BoundExpression* Clone() override;
416 void Load(Emitter& emitter, OperationFlags flags) override;
417 void Store(Emitter& emitter, OperationFlags flags) override;
418 void Accept(BoundNodeVisitor& visitor) override;
419 bool HasValue() const override { return true; }
420 std::string TypeString() const override { return "is expression"; }
421 bool ContainsExceptionCapture() const override;
422 BoundExpression* Expr() { return expr.get(); }
423 ClassTypeSymbol* RightClassType() { return rightClassType; }
424 private:
425 std::unique_ptr<BoundExpression> expr;
426 ClassTypeSymbol* rightClassType;
427 std::unique_ptr<BoundLocalVariable> leftClassIdVar;
428 std::unique_ptr<BoundLocalVariable> rightClassIdVar;
429 };
430
431 class BoundAsExpression : public BoundExpression
432 {
433 public:
434 BoundAsExpression(std::std::unique_ptr<BoundExpression>&&expr_, ClassTypeSymbol*rightClassType_, std::std::unique_ptr<BoundLocalVariable>&&variable_,
435 std::std::unique_ptr<BoundLocalVariable>&&leftClassIdVar_, std::std::unique_ptr<BoundLocalVariable>&&rightClassIdVar_);
436 BoundExpression* Clone() override;
437 void Load(Emitter& emitter, OperationFlags flags) override;
438 void Store(Emitter& emitter, OperationFlags flags) override;
439 void Accept(BoundNodeVisitor& visitor) override;
440 bool HasValue() const override { return true; }
441 std::string TypeString() const override { return "as expression"; }
442 bool ContainsExceptionCapture() const override;
443 BoundExpression* Expr() { return expr.get(); }
444 BoundLocalVariable* Variable() { return variable.get(); }
445 ClassTypeSymbol* RightClassType() { return rightClassType; }
446 private:
447 std::unique_ptr<BoundExpression> expr;
448 ClassTypeSymbol* rightClassType;
449 std::unique_ptr<BoundLocalVariable> variable;
450 std::unique_ptr<BoundLocalVariable> leftClassIdVar;
451 std::unique_ptr<BoundLocalVariable> rightClassIdVar;
452 };
453
454 class BoundTypeNameExpression : public BoundExpression
455 {
456 public:
457 BoundTypeNameExpression(std::std::unique_ptr<BoundExpression>&&classPtr_, TypeSymbol*constCharPtrType_);
458 BoundExpression* Clone() override;
459 void Load(Emitter& emitter, OperationFlags flags) override;
460 void Store(Emitter& emitter, OperationFlags flags) override;
461 void Accept(BoundNodeVisitor& visitor) override;
462 bool HasValue() const override { return true; }
463 bool ContainsExceptionCapture() const override;
464 BoundExpression* ClassPtr() { return classPtr.get(); }
465 private:
466 std::unique_ptr<BoundExpression> classPtr;
467 };
468
469 class BoundTypeIdExpression : public BoundExpression
470 {
471 public:
472 BoundTypeIdExpression(std::std::unique_ptr<BoundExpression>&&classPtr_, TypeSymbol*ulongType_);
473 BoundExpression* Clone() override;
474 void Load(Emitter& emitter, OperationFlags flags) override;
475 void Store(Emitter& emitter, OperationFlags flags) override;
476 void Accept(BoundNodeVisitor& visitor) override;
477 bool HasValue() const override { return true; }
478 bool ContainsExceptionCapture() const override;
479 BoundExpression* ClassPtr() { return classPtr.get(); }
480 private:
481 std::unique_ptr<BoundExpression> classPtr;
482 };
483
484 class BoundBitCast : public BoundExpression
485 {
486 public:
487 BoundBitCast(std::std::unique_ptr<BoundExpression>&&expr_, TypeSymbol*type_);
488 BoundExpression* Clone() override;
489 void Load(Emitter& emitter, OperationFlags flags) override;
490 void Store(Emitter& emitter, OperationFlags flags) override;
491 void Accept(BoundNodeVisitor& visitor) override;
492 bool HasValue() const override { return true; }
493 bool ContainsExceptionCapture() const override;
494 BoundExpression* Expr() { return expr.get(); }
495 private:
496 std::unique_ptr<BoundExpression> expr;
497 };
498
499 class BoundFunctionPtr : public BoundExpression
500 {
501 public:
502 BoundFunctionPtr(const Span& span_, const boost::uuids::uuid& moduleId_, FunctionSymbol* function_, TypeSymbol* type_);
503 BoundExpression* Clone() override;
504 void Load(Emitter& emitter, OperationFlags flags) override;
505 void Store(Emitter& emitter, OperationFlags flags) override;
506 void Accept(BoundNodeVisitor& visitor) override;
507 bool HasValue() const override { return true; }
508 FunctionSymbol* Function() { return function; }
509 private:
510 FunctionSymbol* function;
511 };
512
513 class BoundDisjunction : public BoundExpression
514 {
515 public:
516 BoundDisjunction(const Span& span_, const boost::uuids::uuid& moduleId_, std::std::unique_ptr<BoundExpression>&&left_, std::std::unique_ptr<BoundExpression>&&right_, TypeSymbol*boolType_);
517 BoundExpression* Clone() override;
518 void Load(Emitter& emitter, OperationFlags flags) override;
519 void Store(Emitter& emitter, OperationFlags flags) override;
520 void Accept(BoundNodeVisitor& visitor) override;
521 bool HasValue() const override { return true; }
522 BoundExpression* Left() { return left.get(); }
523 BoundExpression* Right() { return right.get(); }
524 void SetTemporary(BoundLocalVariable* temporary_);
525 bool ContainsExceptionCapture() const override;
526 private:
527 std::unique_ptr<BoundExpression> left;
528 std::unique_ptr<BoundExpression> right;
529 std::unique_ptr<BoundLocalVariable> temporary;
530 };
531
532 class BoundConjunction : public BoundExpression
533 {
534 public:
535 BoundConjunction(const Span& span_, const boost::uuids::uuid& moduleId_, std::std::unique_ptr<BoundExpression>&&left_, std::std::unique_ptr<BoundExpression>&&right_, TypeSymbol*boolType_);
536 BoundExpression* Clone() override;
537 void Load(Emitter& emitter, OperationFlags flags) override;
538 void Store(Emitter& emitter, OperationFlags flags) override;
539 void Accept(BoundNodeVisitor& visitor) override;
540 bool HasValue() const override { return true; }
541 BoundExpression* Left() { return left.get(); }
542 BoundExpression* Right() { return right.get(); }
543 void SetTemporary(BoundLocalVariable* temporary_);
544 bool ContainsExceptionCapture() const override;
545 private:
546 std::unique_ptr<BoundExpression> left;
547 std::unique_ptr<BoundExpression> right;
548 std::unique_ptr<BoundLocalVariable> temporary;
549 };
550
551 class BoundTypeExpression : public BoundExpression
552 {
553 public:
554 BoundTypeExpression(const Span& span_, const boost::uuids::uuid& moduleId_, TypeSymbol* type_);
555 BoundExpression* Clone() override;
556 bool IsComplete() const override { return false; }
557 void Load(Emitter& emitter, OperationFlags flags) override;
558 void Store(Emitter& emitter, OperationFlags flags) override;
559 void Accept(BoundNodeVisitor& visitor) override;
560 std::string TypeString() const override { return "type expression"; }
561 };
562
563 class BoundNamespaceExpression : public BoundExpression
564 {
565 public:
566 BoundNamespaceExpression(const Span& span_, const boost::uuids::uuid& moduleId_, NamespaceSymbol* ns_);
567 BoundExpression* Clone() override;
568 bool IsComplete() const override { return false; }
569 void Load(Emitter& emitter, OperationFlags flags) override;
570 void Store(Emitter& emitter, OperationFlags flags) override;
571 void Accept(BoundNodeVisitor& visitor) override;
572 std::string TypeString() const override { return "namespace expression"; }
573 NamespaceSymbol* Ns() { return ns; }
574 private:
575 NamespaceSymbol* ns;
576 std::unique_ptr<TypeSymbol> nsType;
577 };
578
579 class BoundFunctionGroupExpression : public BoundExpression
580 {
581 public:
582 BoundFunctionGroupExpression(const Span& span_, const boost::uuids::uuid& moduleId_, FunctionGroupSymbol* functionGroupSymbol_);
583 BoundExpression* Clone() override;
584 bool IsComplete() const override { return false; }
585 void Load(Emitter& emitter, OperationFlags flags) override;
586 void Store(Emitter& emitter, OperationFlags flags) override;
587 void Accept(BoundNodeVisitor& visitor) override;
588 std::string TypeString() const override { return "function group expression"; }
589 const FunctionGroupSymbol* FunctionGroup() const { return functionGroupSymbol; }
590 FunctionGroupSymbol* FunctionGroup() { return functionGroupSymbol; }
591 void SetClassPtr(std::std::unique_ptr<BoundExpression>&&classPtr_);
592 BoundExpression* ClassPtr() { return classPtr.get(); }
593 BoundExpression* ReleaseClassPtr() { return classPtr.release(); }
594 bool IsScopeQualified() const { return scopeQualified; }
595 void SetScopeQualified() { scopeQualified = true; }
596 ContainerScope* QualifiedScope() const { return qualifiedScope; }
597 void SetQualifiedScope(ContainerScope* qualifiedScope_) { qualifiedScope = qualifiedScope_; }
598 void SetTemplateArgumentTypes(const std::std::vector<TypeSymbol*>&templateArgumentTypes_);
599 const std::std::vector<TypeSymbol*>&TemplateArgumentTypes() const{returntemplateArgumentTypes;}
600 private:
601 FunctionGroupSymbol* functionGroupSymbol;
602 std::unique_ptr<TypeSymbol> functionGroupType;
603 std::unique_ptr<BoundExpression> classPtr;
604 bool scopeQualified;
605 ContainerScope* qualifiedScope;
606 std::vector<TypeSymbol*> templateArgumentTypes;
607 };
608
609 class BoundMemberExpression : public BoundExpression
610 {
611 public:
612 BoundMemberExpression(const Span& span_, const boost::uuids::uuid& moduleId_, std::std::unique_ptr<BoundExpression>&&classPtr_, std::std::unique_ptr<BoundExpression>&&member_);
613 BoundExpression* Clone() override;
614 bool IsComplete() const override { return false; }
615 void Load(Emitter& emitter, OperationFlags flags) override;
616 void Store(Emitter& emitter, OperationFlags flags) override;
617 void Accept(BoundNodeVisitor& visitor) override;
618 std::string TypeString() const override { return "member expression"; }
619 BoundExpression* ClassPtr() { return classPtr.get(); }
620 void ResetClassPtr() { classPtr.reset(); }
621 BoundExpression* ReleaseClassPtr() { return classPtr.release(); }
622 BoundExpression* Member() { return member.get(); }
623 private:
624 std::unique_ptr<BoundExpression> classPtr;
625 std::unique_ptr<BoundExpression> member;
626 std::unique_ptr<TypeSymbol> memberExpressionType;
627 };
628
629 } }
630
631 #endif // CMAJOR_BINDER_BOUND_EXPRESSION_INCLUDED