1 // =================================
  2 // Copyright (c) 2020 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #include <sngcpp/binder/ExpressionBinder.hpp>
  7 #include <sngcpp/binder/StatementBinder.hpp>
  8 #include <sngcpp/binder/TypeResolver.hpp>
  9 #include <sngcpp/symbols/TypedefSymbol.hpp>
 10 #include <sngcpp/symbols/ClassTemplateSpecializationSymbol.hpp>
 11 #include <sngcpp/ast/TypeExpr.hpp>
 12 #include <sngcpp/ast/Visitor.hpp>
 13 #include <soulng/util/Unicode.hpp>
 14 
 15 namespace sngcpp { namespace binder {
 16 
 17 using namespace soulng::unicode;
 18 
 19 class ExpressionBinder public sngcpp::ast::Visitor
 20 {
 21 public:
 22     ExpressionBinder(SymbolTable& symbolTable_ContainerScope* containerScope_const std::std::vector<ContainerScope*>&prevContainerScopes_
 23         BoundSourceFile* boundSourceFile_FunctionSymbol* currentFunction_StatementBinder* statementBinder_bool& subjectIsConst_);
 24     std::std::vector<Symbol*>GetSymbols(){returnstd::move(symbols);}
 25     void Visit(InitDeclaratorNode& initDeclaratorNode) override;
 26     void Visit(CtorInitializerNode& ctorInitializerNode) override;
 27     void Visit(MemberInitializerNode& memberInitializerNode) override;
 28     void Visit(MemberInitializerSequenceNode& memberInitializerSequenceNode) override;
 29     void Visit(AssignmentInitializerNode& assignmentInitializerNode) override;
 30     void Visit(ExpressionListInitializerNode& expressionListInitializerNode) override;
 31     void Visit(ExpressionInitializerNode& expressionInitializerNode) override;
 32     void Visit(BracedInitializerListNode& bracedInitializerListNode) override;
 33     void Visit(ExpressionSequenceNode& expressionSequenceNode) override;
 34     void Visit(SimpleDeclarationNode& simpleDeclarationNode) override;
 35     void Visit(IdDeclaratorNode& idDeclaratorNode) override;
 36     void Visit(CommaExpressionNode& commaExpressionNode) override;
 37     void Visit(AssignmentExpressionNode& assignmentExpressionNode) override;
 38     void Visit(ConditionalExpressionNode& conditionalExpressionNode) override;
 39     void Visit(ThrowExpressionNode& throwExpressionNode) override;
 40     void Visit(LogicalOrExpressionNode& logicalOrExpressionNode) override;
 41     void Visit(LogicalAndExpressionNode& logicalAndExpressionNode) override;
 42     void Visit(InclusiveOrExpressionNode& inclusiveOrExpressionNode) override;
 43     void Visit(ExclusiveOrExpressionNode& exclusiveOrExpressionNode) override;
 44     void Visit(AndExpressionNode& andExpressionNode) override;
 45     void Visit(EqualityExpressionNode& equalityExpressionNode) override;
 46     void Visit(RelationalExpressionNode& relationalExpressionNode) override;
 47     void Visit(ShiftExpressionNode& shiftExpressionNode) override;
 48     void Visit(AdditiveExpressionNode& additiveExpressionNode) override;
 49     void Visit(MultiplicativeExpressionNode& multiplicativeExpressionNode) override;
 50     void Visit(PMExpressionNode& pmExpressionNode) override;
 51     void Visit(CastExpressionNode& castExpressionNode) override;
 52     void Visit(UnaryExpressionNode& unaryExpressionNode) override;
 53     void Visit(NewExpressionNode& newExpressionNode) override;
 54     void Visit(SubscriptExpressionNode& subscriptExpressionNode) override;
 55     void Visit(InvokeExpressionNode& invokeExpressionNode) override;
 56     void Visit(DotNode& dotNode) override;
 57     void Visit(ArrowNode& arrowNode) override;
 58     void Visit(PostfixIncNode& postfixIncNode) override;
 59     void Visit(PostfixDecNode& postfixDecNode) override;
 60     void Visit(CppCastExpressionNode& cppCastExpressionNode) override;
 61     void Visit(TypeIdExpressionNode& typeIdExpressionNode) override;
 62     void Visit(ThisNode& thisNode) override;
 63     void Visit(ParenthesizedExprNode& parenthesizedExprNode) override;
 64     void Visit(LambdaExpressionNode& lambdaExpressionNode) override;
 65     void Visit(CaptureSequenceNode& captureSequenceNode) override;
 66     void Visit(IdentifierCaptureNode& identifierCaptureNode) override;
 67     void Visit(NestedIdNode& nestedIdNode) override;
 68     void Visit(IdentifierNode& identifierNode) override;
 69     void Visit(DtorIdNode& dtorIdNode) override;
 70     void Visit(TemplateIdNode& templateIdNode) override;
 71     void Visit(ConstNode& constNode) override;
 72     void Visit(VolatileNode& volatileNode) override;
 73     void Visit(PointerNode& pointerNode) override;
 74     void Visit(RValueRefNode& rValueRefNode) override;
 75     void Visit(LValueRefNode& lValueRefNode) override;
 76     void Visit(DeleteExpressionNode& deleteExpressionNode) override;
 77     void Visit(IntegerLiteralNode& integerLiteralNode) override;
 78     void Visit(StringLiteralNode& stringLiteralNode) override;
 79 private:
 80     StatementBinder* statementBinder;
 81     SymbolTable& symbolTable;
 82     ContainerScope* containerScope;
 83     std::vector<ContainerScope*> prevContainerScopes;
 84     BoundSourceFile* boundSourceFile;
 85     FunctionSymbol* currentFunction;
 86     std::vector<Symbol*> symbols;
 87     bool& subjectIsConst;
 88 };
 89 
 90 ExpressionBinder::ExpressionBinder(SymbolTable& symbolTable_ContainerScope* containerScope_const std::std::vector<ContainerScope*>&prevContainerScopes_BoundSourceFile*boundSourceFile_
 91     FunctionSymbol* currentFunction_StatementBinder* statementBinder_bool& subjectIsConst_) :
 92     statementBinder(statementBinder_)symbolTable(symbolTable_)containerScope(containerScope_)prevContainerScopes(prevContainerScopes_)boundSourceFile(boundSourceFile_)
 93     currentFunction(currentFunction_)symbols()subjectIsConst(subjectIsConst_)
 94 {
 95 }
 96 
 97 void ExpressionBinder::Visit(InitDeclaratorNode& initDeclaratorNode)
 98 {
 99     BindExpression(initDeclaratorNode.Declarator()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
100     BindExpression(initDeclaratorNode.Initializer()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
101 }
102 
103 void ExpressionBinder::Visit(CtorInitializerNode& ctorInitializerNode)
104 {
105     BindExpression(ctorInitializerNode.Child()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
106 }
107 
108 void ExpressionBinder::Visit(MemberInitializerNode& memberInitializerNode)
109 {
110     BindExpression(memberInitializerNode.Id()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
111     BindExpression(memberInitializerNode.Initializer()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
112 }
113 
114 void ExpressionBinder::Visit(MemberInitializerSequenceNode& memberInitializerSequenceNode)
115 {
116     BindExpression(memberInitializerSequenceNode.Left()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
117     BindExpression(memberInitializerSequenceNode.Right()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
118 }
119 
120 void ExpressionBinder::Visit(AssignmentInitializerNode& assignmentInitializerNode)
121 {
122     symbols = std::move(BindExpression(assignmentInitializerNode.Child()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder));
123 }
124 
125 void ExpressionBinder::Visit(ExpressionListInitializerNode& expressionListInitializerNode)
126 {
127     if (expressionListInitializerNode.Child())
128     {
129         symbols = std::move(BindExpression(expressionListInitializerNode.Child()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder));
130     }
131 }
132 
133 void ExpressionBinder::Visit(ExpressionInitializerNode& expressionInitializerNode)
134 {
135     symbols = std::move(BindExpression(expressionInitializerNode.Child()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder));
136 }
137 
138 void ExpressionBinder::Visit(BracedInitializerListNode& bracedInitializerListNode)
139 {
140     if (bracedInitializerListNode.Child())
141     {
142         symbols = std::move(BindExpression(bracedInitializerListNode.Child()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder));
143     }
144 }
145 
146 void ExpressionBinder::Visit(ExpressionSequenceNode& expressionSequenceNode)
147 {
148     std::vector<Symbol*> leftSymbols = BindExpression(expressionSequenceNode.Left()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
149     symbols.insert(symbols.end()leftSymbols.begin()leftSymbols.end());
150     std::vector<Symbol*> rightSymbols = BindExpression(expressionSequenceNode.Right()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
151     symbols.insert(symbols.end()rightSymbols.begin()rightSymbols.end());
152 }
153 
154 void ExpressionBinder::Visit(SimpleDeclarationNode& simpleDeclarationNode)
155 {
156     BindExpression(simpleDeclarationNode.TypeExpr()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
157     if (simpleDeclarationNode.Declarator())
158     {
159         symbols = std::move(BindExpression(simpleDeclarationNode.Declarator()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder));
160     }
161 }
162 
163 void ExpressionBinder::Visit(IdDeclaratorNode& idDeclaratorNode)
164 {
165     symbols = std::move(BindExpression(idDeclaratorNode.IdNode()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder));
166 }
167 
168 void ExpressionBinder::Visit(CommaExpressionNode& commaExpressionNode)
169 {
170     BindExpression(commaExpressionNode.Left()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
171     BindExpression(commaExpressionNode.Right()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
172 }
173 
174 void ExpressionBinder::Visit(AssignmentExpressionNode& assignmentExpressionNode)
175 {
176     BindExpression(assignmentExpressionNode.Left()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
177     BindExpression(assignmentExpressionNode.Right()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
178 }
179 
180 void ExpressionBinder::Visit(ConditionalExpressionNode& conditionalExpressionNode)
181 {
182     BindExpression(conditionalExpressionNode.Condition()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
183     BindExpression(conditionalExpressionNode.ThenExpr()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
184     BindExpression(conditionalExpressionNode.ElseExpr()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
185 }
186 
187 void ExpressionBinder::Visit(ThrowExpressionNode& throwExpressionNode)
188 {
189     if (throwExpressionNode.Child())
190     {
191         BindExpression(throwExpressionNode.Child()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
192     }
193 }
194 
195 void ExpressionBinder::Visit(LogicalOrExpressionNode& logicalOrExpressionNode)
196 {
197     BindExpression(logicalOrExpressionNode.Left()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
198     BindExpression(logicalOrExpressionNode.Right()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
199 }
200 
201 void ExpressionBinder::Visit(LogicalAndExpressionNode& logicalAndExpressionNode)
202 {
203     BindExpression(logicalAndExpressionNode.Left()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
204     BindExpression(logicalAndExpressionNode.Right()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
205 }
206 
207 void ExpressionBinder::Visit(InclusiveOrExpressionNode& inclusiveOrExpressionNode)
208 {
209     BindExpression(inclusiveOrExpressionNode.Left()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
210     BindExpression(inclusiveOrExpressionNode.Right()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
211 }
212 
213 void ExpressionBinder::Visit(ExclusiveOrExpressionNode& exclusiveOrExpressionNode)
214 {
215     BindExpression(exclusiveOrExpressionNode.Left()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
216     BindExpression(exclusiveOrExpressionNode.Right()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
217 }
218 
219 void ExpressionBinder::Visit(AndExpressionNode& andExpressionNode)
220 {
221     BindExpression(andExpressionNode.Left()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
222     BindExpression(andExpressionNode.Right()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
223 }
224 
225 void ExpressionBinder::Visit(EqualityExpressionNode& equalityExpressionNode)
226 {
227     BindExpression(equalityExpressionNode.Left()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
228     BindExpression(equalityExpressionNode.Right()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
229 }
230 
231 void ExpressionBinder::Visit(RelationalExpressionNode& relationalExpressionNode)
232 {
233     BindExpression(relationalExpressionNode.Left()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
234     BindExpression(relationalExpressionNode.Right()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
235 }
236 
237 void ExpressionBinder::Visit(ShiftExpressionNode& shiftExpressionNode)
238 {
239     BindExpression(shiftExpressionNode.Left()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
240     BindExpression(shiftExpressionNode.Right()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
241 }
242 
243 void ExpressionBinder::Visit(AdditiveExpressionNode& additiveExpressionNode)
244 {
245     BindExpression(additiveExpressionNode.Left()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
246     BindExpression(additiveExpressionNode.Right()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
247 }
248 
249 void ExpressionBinder::Visit(MultiplicativeExpressionNode& multiplicativeExpressionNode)
250 {
251     BindExpression(multiplicativeExpressionNode.Left()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
252     BindExpression(multiplicativeExpressionNode.Right()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
253 }
254 
255 void ExpressionBinder::Visit(PMExpressionNode& pmExpressionNode)
256 {
257     BindExpression(pmExpressionNode.Left()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
258     BindExpression(pmExpressionNode.Right()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
259 }
260 
261 void ExpressionBinder::Visit(CastExpressionNode& castExpressionNode)
262 {
263     BindExpression(castExpressionNode.TypeExpr()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
264     BindExpression(castExpressionNode.Expr()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
265 }
266 
267 void ExpressionBinder::Visit(UnaryExpressionNode& unaryExpressionNode)
268 {
269     std::vector<Symbol*> subjectSymbols = BindExpression(unaryExpressionNode.Child()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
270     Symbol* subject = nullptr;
271     if (!subjectSymbols.empty())
272     {
273         subject = subjectSymbols.front();
274     }
275     if (subject)
276     {
277         switch (unaryExpressionNode.Op())
278         {
279             case Operator::deref:
280             {
281                 symbols.push_back(subject);
282                 break;
283             }
284         }
285     }
286 }
287 
288 void ExpressionBinder::Visit(NewExpressionNode& newExpressionNode)
289 {
290     if (newExpressionNode.Placement())
291     {
292         BindExpression(newExpressionNode.Placement()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
293     }
294     BindExpression(newExpressionNode.TypeExpr()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
295     if (newExpressionNode.Initializer())
296     {
297         BindExpression(newExpressionNode.Initializer()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
298     }
299 }
300 
301 void ExpressionBinder::Visit(SubscriptExpressionNode& subscriptExpressionNode)
302 {
303     BindExpression(subscriptExpressionNode.Child()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
304     BindExpression(subscriptExpressionNode.Index()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
305 }
306 
307 void ExpressionBinder::Visit(InvokeExpressionNode& invokeExpressionNode)
308 {
309     FunctionGroupSymbol* functionGroup = nullptr;
310     bool subjectIsConst = false;
311     std::vector<Symbol*> subjectSymbols = BindExpression(invokeExpressionNode.Child()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder
312         subjectIsConst);
313     if (!subjectSymbols.empty())
314     {
315         Symbol* subject = subjectSymbols.front();
316         if (subject)
317         {
318             if (subject->IsFunctionGroupSymbol())
319             {
320                 functionGroup = static_cast<FunctionGroupSymbol*>(subject);
321             }
322             else if (subject->IsTypeSymbol())
323             {
324                 TypeSymbol* type = static_cast<TypeSymbol*>(subject);
325                 if (type->IsTypedefSymbol())
326                 {
327                     TypedefSymbol* typedefSymbol = static_cast<TypedefSymbol*>(type);
328                     type = typedefSymbol->GetType();
329                 }
330                 if (type && type->IsClassTemplateSpecializationSymbol())
331                 {
332                     ClassTemplateSpecializationSymbol* specialization = static_cast<ClassTemplateSpecializationSymbol*>(type);
333                     type = specialization->PrimaryClassTemplateSymbol();
334                 }
335                 if (type && type->IsClassTypeSymbol())
336                 {
337                     ClassTypeSymbol* classType = static_cast<ClassTypeSymbol*>(type);
338                     Symbol* symbol = classType->GetContainerScope()->Lookup(U"constructor");
339                     if (symbol && symbol->IsFunctionGroupSymbol())
340                     {
341                         functionGroup = static_cast<FunctionGroupSymbol*>(symbol);
342                     }
343                 }
344             }
345         }
346     }
347     std::vector<Symbol*> argumentSymbols;
348     if (invokeExpressionNode.Arguments())
349     {
350         argumentSymbols = std::move(BindExpression(invokeExpressionNode.Arguments()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder));
351     }
352     if (functionGroup)
353     {
354         CallableSymbol* functionSymbol = functionGroup->ResolveOverload(argumentSymbolsinvokeExpressionNode.Child()->GetNodeType() == NodeType::arrowNode && subjectIsConst);
355         if (functionSymbol)
356         {
357             symbolTable.MapNode(&invokeExpressionNodefunctionSymbol);
358             symbols.push_back(functionSymbol);
359             if (symbolTable.InGendocMode() && functionSymbol->IsFunctionSymbol())
360             {
361                 currentFunction->AddToCalls(static_cast<FunctionSymbol*>(functionSymbol));
362                 static_cast<FunctionSymbol*>(functionSymbol)->AddToCalledBy(currentFunction);
363             }
364         }
365     }
366 }
367 
368 void ExpressionBinder::Visit(DotNode& dotNode)
369 {
370     std::vector<Symbol*> leftSymbols = BindExpression(dotNode.Child()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
371     Symbol* s = nullptr;
372     if (!leftSymbols.empty())
373     {
374         s = leftSymbols.front();
375     }
376     if (s)
377     {
378         sngcpp::symbols::TypeSymbol* type = s->GetType();
379         if (type)
380         {
381             if (type->IsReferenceTypeSymbol())
382             {
383                 type = type->BaseType();
384             }
385             if (type->IsTypedefSymbol())
386             {
387                 TypedefSymbol* typedefSymbol = static_cast<TypedefSymbol*>(type);
388                 type = typedefSymbol->GetType();
389             }
390             if (type)
391             {
392                 if (std::find(prevContainerScopes.begin()prevContainerScopes.end()containerScope) == prevContainerScopes.end()) prevContainerScopes.push_back(containerScope);
393                 if (type->IsClassTemplateSpecializationSymbol())
394                 {
395                     ClassTemplateSpecializationSymbol* specialization = static_cast<ClassTemplateSpecializationSymbol*>(type);
396                     type = specialization->PrimaryClassTemplateSymbol();
397                 }
398                 containerScope = type->BaseType()->GetContainerScope();
399             }
400         }
401     }
402     if (containerScope)
403     {
404         symbols = std::move(BindExpression(dotNode.Id()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder));
405     }
406 }
407 
408 void ExpressionBinder::Visit(ArrowNode& arrowNode)
409 {
410     std::vector<Symbol*> leftSymbols = BindExpression(arrowNode.Child()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
411     Symbol* s = nullptr;
412     if (!leftSymbols.empty())
413     {
414         s = leftSymbols.front();
415     }
416     if (s)
417     {
418         sngcpp::symbols::TypeSymbol* type = s->GetType();
419         if (type)
420         {
421             if (type->HasConstDerivation())
422             {
423                 subjectIsConst = true;
424             }
425             else
426             {
427                 subjectIsConst = false;
428             }
429             if (type->IsTypedefSymbol())
430             {
431                 TypedefSymbol* typedefSymbol = static_cast<TypedefSymbol*>(type);
432                 type = typedefSymbol->GetType();
433             }
434             if (std::find(prevContainerScopes.begin()prevContainerScopes.end()containerScope) == prevContainerScopes.end()) prevContainerScopes.push_back(containerScope);
435             if (type->IsClassTemplateSpecializationSymbol())
436             {
437                 ClassTemplateSpecializationSymbol* specialization = static_cast<ClassTemplateSpecializationSymbol*>(type);
438                 type = specialization->PrimaryClassTemplateSymbol();
439             }
440             containerScope = type->BaseType()->GetContainerScope();
441         }
442     }
443     if (containerScope)
444     {
445         symbols = std::move(BindExpression(arrowNode.Id()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder));
446     }
447 }
448 
449 void ExpressionBinder::Visit(PostfixIncNode& postfixIncNode)
450 {
451     BindExpression(postfixIncNode.Child()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
452 }
453 
454 void ExpressionBinder::Visit(PostfixDecNode& postfixDecNode)
455 {
456     BindExpression(postfixDecNode.Child()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
457 }
458 
459 void ExpressionBinder::Visit(CppCastExpressionNode& cppCastExpressionNode)
460 {
461     BindExpression(cppCastExpressionNode.TypeExpr()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
462     BindExpression(cppCastExpressionNode.Expr()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
463 }
464 
465 void ExpressionBinder::Visit(TypeIdExpressionNode& typeIdExpressionNode)
466 {
467     BindExpression(typeIdExpressionNode.Child()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
468 }
469 
470 void ExpressionBinder::Visit(ThisNode& thisNode)
471 {
472     ClassTypeSymbol* cls = currentFunction->Class();
473     if (cls)
474     {
475         symbols.push_back(cls);
476     }
477 }
478 
479 void ExpressionBinder::Visit(ParenthesizedExprNode& parenthesizedExprNode)
480 {
481     BindExpression(parenthesizedExprNode.Child()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
482 }
483 
484 void ExpressionBinder::Visit(LambdaExpressionNode& lambdaExpressionNode)
485 {
486     if (lambdaExpressionNode.Captures())
487     {
488         BindExpression(lambdaExpressionNode.Captures()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
489     }
490     lambdaExpressionNode.Body()->Accept(*statementBinder);
491 }
492 
493 void ExpressionBinder::Visit(CaptureSequenceNode& captureSequenceNode)
494 {
495     BindExpression(captureSequenceNode.Left()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
496     BindExpression(captureSequenceNode.Right()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
497 }
498 
499 void ExpressionBinder::Visit(IdentifierCaptureNode& identifierCaptureNode)
500 {
501     BindExpression(identifierCaptureNode.Child()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
502 }
503 
504 void ExpressionBinder::Visit(NestedIdNode& nestedIdNode)
505 {
506     std::vector<Symbol*> symbols;
507     if (nestedIdNode.Left())
508     {
509         symbols = std::move(BindExpression(nestedIdNode.Left()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder));
510     }
511     else
512     {
513         symbols.push_back(symbolTable.GlobalNs());
514     }
515     Symbol* s = nullptr;
516     if (!symbols.empty())
517     {
518         s = symbols.front();
519     }
520     if (s)
521     {
522         if (s->IsNamespaceSymbol())
523         {
524             if (std::find(prevContainerScopes.begin()prevContainerScopes.end()containerScope) == prevContainerScopes.end()) prevContainerScopes.push_back(containerScope);
525             containerScope = s->GetContainerScope();
526         }
527         else if (s->IsTypedefSymbol())
528         {
529             TypedefSymbol* typedefSymbol = static_cast<TypedefSymbol*>(s);
530             sngcpp::symbols::TypeSymbol* type = typedefSymbol->GetType();
531             if (std::find(prevContainerScopes.begin()prevContainerScopes.end()containerScope) == prevContainerScopes.end()) prevContainerScopes.push_back(containerScope);
532             containerScope = type->GetContainerScope();
533         }
534         else if (s->IsTypeSymbol())
535         {
536             if (std::find(prevContainerScopes.begin()prevContainerScopes.end()containerScope) == prevContainerScopes.end()) prevContainerScopes.push_back(containerScope);
537             containerScope = s->GetContainerScope();
538         }
539         else if (s->IsClassGroupSymbol())
540         {
541             ClassGroupSymbol* group = static_cast<ClassGroupSymbol*>(s);
542             ClassTypeSymbol* cls = group->GetClass(0);
543             if (cls)
544             {
545                 if (std::find(prevContainerScopes.begin()prevContainerScopes.end()containerScope) == prevContainerScopes.end()) prevContainerScopes.push_back(containerScope);
546                 containerScope = cls->GetContainerScope();
547             }
548         }
549     }
550     if (containerScope)
551     {
552         symbols = std::move(BindExpression(nestedIdNode.Right()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder));
553     }
554     else
555     {
556         symbols.clear();
557     }
558     this->symbols = std::move(symbols);
559 }
560 
561 void ExpressionBinder::Visit(IdentifierNode& identifierNode)
562 {
563     Symbol* symbol = containerScope->Lookup(identifierNode.Identifier()ScopeLookup::this_and_bases_and_parent);
564     if (!symbol)
565     {
566         for (const std::std::unique_ptr<FileScope>&fileScope : boundSourceFile->FileScopes())
567         {
568             symbol = fileScope->Lookup(identifierNode.Identifier());
569             if (symbol)
570             {
571                 break;
572             }
573         }
574         if (!symbol)
575         {
576             for (ContainerScope* prevContainerScope : prevContainerScopes)
577             {
578                 symbol = prevContainerScope->Lookup(identifierNode.Identifier()ScopeLookup::this_and_bases_and_parent);
579                 if (symbol)
580                 {
581                     break;
582                 }
583             }
584         }
585     }
586     if (symbol)
587     {
588         symbolTable.MapNode(&identifierNodesymbol);
589         symbols.push_back(symbol);
590     }
591 }
592 
593 void ExpressionBinder::Visit(DtorIdNode& dtorIdNode)
594 {
595     ClassTypeSymbol* currentClassType = nullptr;
596     if (currentFunction && currentFunction->Parent() && currentFunction->Parent()->IsClassTypeSymbol())
597     {
598         currentClassType = static_cast<ClassTypeSymbol*>(currentFunction->Parent());
599     }
600     if (currentClassType)
601     {
602         symbolTable.MapNode(&dtorIdNodecurrentClassType);
603     }
604 }
605 
606 void ExpressionBinder::Visit(TemplateIdNode& templateIdNode)
607 {
608     ClassTypeSymbol* currentClassType = nullptr;
609     if (currentFunction && currentFunction->Parent() && currentFunction->Parent()->IsClassTypeSymbol())
610     {
611         currentClassType = static_cast<ClassTypeSymbol*>(currentFunction->Parent());
612     }
613     TypeSymbol* type = ResolveType(symbolTablecontainerScopeprevContainerScopes*boundSourceFileTypeResolverFlags::nonecurrentClassType&templateIdNode);
614     symbols.push_back(type);
615 }
616 
617 void ExpressionBinder::Visit(ConstNode& constNode)
618 {
619     BindExpression(constNode.Child()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
620 }
621 
622 void ExpressionBinder::Visit(VolatileNode& volatileNode)
623 {
624     BindExpression(volatileNode.Child()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
625 }
626 
627 void ExpressionBinder::Visit(PointerNode& pointerNode)
628 {
629     BindExpression(pointerNode.Child()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
630 }
631 
632 void ExpressionBinder::Visit(RValueRefNode& rValueRefNode)
633 {
634     BindExpression(rValueRefNode.Child()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
635 }
636 
637 void ExpressionBinder::Visit(LValueRefNode& lValueRefNode)
638 {
639     BindExpression(lValueRefNode.Child()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
640 }
641 
642 void ExpressionBinder::Visit(DeleteExpressionNode& deleteExpressionNode)
643 {
644     BindExpression(deleteExpressionNode.Child()symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBinder);
645 }
646 
647 void ExpressionBinder::Visit(IntegerLiteralNode& integerLiteralNode)
648 {
649     TypeSymbol* type = symbolTable.GetIntType();
650     symbols.push_back(type);
651 }
652 
653 void ExpressionBinder::Visit(StringLiteralNode& stringLiteralNode)
654 {
655     if (stringLiteralNode.EncodigPrefix().empty() || stringLiteralNode.EncodigPrefix() == U"u8")
656     {
657         std::vector<sngcpp::symbols::Derivation> derivations;
658         derivations.push_back(sngcpp::symbols::Derivation::const_);
659         derivations.push_back(sngcpp::symbols::Derivation::lvalueRef);
660         TypeSymbol* type = symbolTable.MakeDerivedTypeSymbol(derivationssymbolTable.MakeExternalTypeSymbol(stringLiteralNode.GetSpan()U"std::string"sngcpp::ast::ClassKey::none));
661         symbols.push_back(type);
662     }
663     else if (stringLiteralNode.EncodigPrefix() == U"u")
664     {
665         std::vector<sngcpp::symbols::Derivation> derivations;
666         derivations.push_back(sngcpp::symbols::Derivation::const_);
667         derivations.push_back(sngcpp::symbols::Derivation::lvalueRef);
668         TypeSymbol* type = symbolTable.MakeDerivedTypeSymbol(derivationssymbolTable.MakeExternalTypeSymbol(stringLiteralNode.GetSpan()U"std::u16string"sngcpp::ast::ClassKey::none));
669         symbols.push_back(type);
670     }
671     else if (stringLiteralNode.EncodigPrefix() == U"U")
672     {
673         std::vector<sngcpp::symbols::Derivation> derivations;
674         derivations.push_back(sngcpp::symbols::Derivation::const_);
675         derivations.push_back(sngcpp::symbols::Derivation::lvalueRef);
676         TypeSymbol* type = symbolTable.MakeDerivedTypeSymbol(derivationssymbolTable.MakeExternalTypeSymbol(stringLiteralNode.GetSpan()U"std::u32string"sngcpp::ast::ClassKey::none));
677         symbols.push_back(type);
678     }
679     else if (stringLiteralNode.EncodigPrefix() == U"L")
680     {
681         std::vector<sngcpp::symbols::Derivation> derivations;
682         derivations.push_back(sngcpp::symbols::Derivation::const_);
683         derivations.push_back(sngcpp::symbols::Derivation::lvalueRef);
684         TypeSymbol* type = symbolTable.MakeDerivedTypeSymbol(derivationssymbolTable.MakeExternalTypeSymbol(stringLiteralNode.GetSpan()U"std::wstring"sngcpp::ast::ClassKey::none));
685         symbols.push_back(type);
686     }
687 }
688 
689 std::std::vector<Symbol*>BindExpression(Node*nodeSymbolTable&symbolTableContainerScope*containerScopeconststd::std::vector<ContainerScope*>&prevContainerScopesBoundSourceFile*boundSourceFile
690     FunctionSymbol* currentFunctionStatementBinder* statementBinderbool& subjectIsConst)
691 {
692     ExpressionBinder expressionBinder(symbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBindersubjectIsConst);
693     node->Accept(expressionBinder);
694     std::vector<Symbol*> symbols = expressionBinder.GetSymbols();
695     if (symbols.empty())
696     {
697         ClassTypeSymbol* currentClassType = nullptr;
698         if (currentFunction && currentFunction->Parent() && currentFunction->Parent()->IsClassTypeSymbol())
699         {
700             currentClassType = static_cast<ClassTypeSymbol*>(currentFunction->Parent());
701         }
702         sngcpp::symbols::TypeSymbol* type = ResolveType(symbolTablecontainerScopeprevContainerScopes*boundSourceFileTypeResolverFlags::noExternalTypes | TypeResolverFlags::nothrow
703             currentClassTypenode);
704         if (type)
705         {
706             symbols.push_back(type);
707         }
708         else
709         {
710             symbols.push_back(nullptr);
711         }
712     }
713     return symbols;
714 }
715 
716 std::std::vector<Symbol*>BindExpression(Node*nodeSymbolTable&symbolTableContainerScope*containerScopeconststd::std::vector<ContainerScope*>&prevContainerScopesBoundSourceFile*boundSourceFile
717     FunctionSymbol* currentFunctionStatementBinder* statementBinder)
718 {
719     bool subjectIsConst = false;
720     return BindExpression(nodesymbolTablecontainerScopeprevContainerScopesboundSourceFilecurrentFunctionstatementBindersubjectIsConst);
721 }
722 
723 } } // namespace sngcppp::binder