1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  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 leftBoundExpressionFlags right)
 31 {
 32     return BoundExpressionFlags(uint8_t(left) | uint8_t(right));
 33 }
 34 
 35 inline BoundExpressionFlags operator&(BoundExpressionFlags leftBoundExpressionFlags 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& emitterOperationFlags flags) override;
 76     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
 92     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
107     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
127     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
143     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
159     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
178     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
192     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
212     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
226     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
242     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
258     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
275     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
300     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
320     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
340     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
356     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
375     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
394     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
417     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
438     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
460     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
475     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
490     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
505     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
519     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
538     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
558     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
570     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
586     void Store(Emitter& emitterOperationFlags 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& emitterOperationFlags flags) override;
616     void Store(Emitter& emitterOperationFlags 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 } } // namespace cmajor::binder
630 
631 #endif // CMAJOR_BINDER_BOUND_EXPRESSION_INCLUDED