1
2
3
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(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
100 BindExpression(initDeclaratorNode.Initializer(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
101 }
102
103 void ExpressionBinder::Visit(CtorInitializerNode& ctorInitializerNode)
104 {
105 BindExpression(ctorInitializerNode.Child(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
106 }
107
108 void ExpressionBinder::Visit(MemberInitializerNode& memberInitializerNode)
109 {
110 BindExpression(memberInitializerNode.Id(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
111 BindExpression(memberInitializerNode.Initializer(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
112 }
113
114 void ExpressionBinder::Visit(MemberInitializerSequenceNode& memberInitializerSequenceNode)
115 {
116 BindExpression(memberInitializerSequenceNode.Left(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
117 BindExpression(memberInitializerSequenceNode.Right(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
118 }
119
120 void ExpressionBinder::Visit(AssignmentInitializerNode& assignmentInitializerNode)
121 {
122 symbols = std::move(BindExpression(assignmentInitializerNode.Child(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder));
123 }
124
125 void ExpressionBinder::Visit(ExpressionListInitializerNode& expressionListInitializerNode)
126 {
127 if (expressionListInitializerNode.Child())
128 {
129 symbols = std::move(BindExpression(expressionListInitializerNode.Child(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder));
130 }
131 }
132
133 void ExpressionBinder::Visit(ExpressionInitializerNode& expressionInitializerNode)
134 {
135 symbols = std::move(BindExpression(expressionInitializerNode.Child(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder));
136 }
137
138 void ExpressionBinder::Visit(BracedInitializerListNode& bracedInitializerListNode)
139 {
140 if (bracedInitializerListNode.Child())
141 {
142 symbols = std::move(BindExpression(bracedInitializerListNode.Child(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder));
143 }
144 }
145
146 void ExpressionBinder::Visit(ExpressionSequenceNode& expressionSequenceNode)
147 {
148 std::vector<Symbol*> leftSymbols = BindExpression(expressionSequenceNode.Left(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
149 symbols.insert(symbols.end(), leftSymbols.begin(), leftSymbols.end());
150 std::vector<Symbol*> rightSymbols = BindExpression(expressionSequenceNode.Right(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
151 symbols.insert(symbols.end(), rightSymbols.begin(), rightSymbols.end());
152 }
153
154 void ExpressionBinder::Visit(SimpleDeclarationNode& simpleDeclarationNode)
155 {
156 BindExpression(simpleDeclarationNode.TypeExpr(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
157 if (simpleDeclarationNode.Declarator())
158 {
159 symbols = std::move(BindExpression(simpleDeclarationNode.Declarator(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder));
160 }
161 }
162
163 void ExpressionBinder::Visit(IdDeclaratorNode& idDeclaratorNode)
164 {
165 symbols = std::move(BindExpression(idDeclaratorNode.IdNode(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder));
166 }
167
168 void ExpressionBinder::Visit(CommaExpressionNode& commaExpressionNode)
169 {
170 BindExpression(commaExpressionNode.Left(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
171 BindExpression(commaExpressionNode.Right(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
172 }
173
174 void ExpressionBinder::Visit(AssignmentExpressionNode& assignmentExpressionNode)
175 {
176 BindExpression(assignmentExpressionNode.Left(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
177 BindExpression(assignmentExpressionNode.Right(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
178 }
179
180 void ExpressionBinder::Visit(ConditionalExpressionNode& conditionalExpressionNode)
181 {
182 BindExpression(conditionalExpressionNode.Condition(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
183 BindExpression(conditionalExpressionNode.ThenExpr(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
184 BindExpression(conditionalExpressionNode.ElseExpr(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
185 }
186
187 void ExpressionBinder::Visit(ThrowExpressionNode& throwExpressionNode)
188 {
189 if (throwExpressionNode.Child())
190 {
191 BindExpression(throwExpressionNode.Child(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
192 }
193 }
194
195 void ExpressionBinder::Visit(LogicalOrExpressionNode& logicalOrExpressionNode)
196 {
197 BindExpression(logicalOrExpressionNode.Left(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
198 BindExpression(logicalOrExpressionNode.Right(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
199 }
200
201 void ExpressionBinder::Visit(LogicalAndExpressionNode& logicalAndExpressionNode)
202 {
203 BindExpression(logicalAndExpressionNode.Left(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
204 BindExpression(logicalAndExpressionNode.Right(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
205 }
206
207 void ExpressionBinder::Visit(InclusiveOrExpressionNode& inclusiveOrExpressionNode)
208 {
209 BindExpression(inclusiveOrExpressionNode.Left(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
210 BindExpression(inclusiveOrExpressionNode.Right(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
211 }
212
213 void ExpressionBinder::Visit(ExclusiveOrExpressionNode& exclusiveOrExpressionNode)
214 {
215 BindExpression(exclusiveOrExpressionNode.Left(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
216 BindExpression(exclusiveOrExpressionNode.Right(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
217 }
218
219 void ExpressionBinder::Visit(AndExpressionNode& andExpressionNode)
220 {
221 BindExpression(andExpressionNode.Left(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
222 BindExpression(andExpressionNode.Right(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
223 }
224
225 void ExpressionBinder::Visit(EqualityExpressionNode& equalityExpressionNode)
226 {
227 BindExpression(equalityExpressionNode.Left(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
228 BindExpression(equalityExpressionNode.Right(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
229 }
230
231 void ExpressionBinder::Visit(RelationalExpressionNode& relationalExpressionNode)
232 {
233 BindExpression(relationalExpressionNode.Left(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
234 BindExpression(relationalExpressionNode.Right(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
235 }
236
237 void ExpressionBinder::Visit(ShiftExpressionNode& shiftExpressionNode)
238 {
239 BindExpression(shiftExpressionNode.Left(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
240 BindExpression(shiftExpressionNode.Right(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
241 }
242
243 void ExpressionBinder::Visit(AdditiveExpressionNode& additiveExpressionNode)
244 {
245 BindExpression(additiveExpressionNode.Left(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
246 BindExpression(additiveExpressionNode.Right(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
247 }
248
249 void ExpressionBinder::Visit(MultiplicativeExpressionNode& multiplicativeExpressionNode)
250 {
251 BindExpression(multiplicativeExpressionNode.Left(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
252 BindExpression(multiplicativeExpressionNode.Right(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
253 }
254
255 void ExpressionBinder::Visit(PMExpressionNode& pmExpressionNode)
256 {
257 BindExpression(pmExpressionNode.Left(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
258 BindExpression(pmExpressionNode.Right(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
259 }
260
261 void ExpressionBinder::Visit(CastExpressionNode& castExpressionNode)
262 {
263 BindExpression(castExpressionNode.TypeExpr(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
264 BindExpression(castExpressionNode.Expr(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
265 }
266
267 void ExpressionBinder::Visit(UnaryExpressionNode& unaryExpressionNode)
268 {
269 std::vector<Symbol*> subjectSymbols = BindExpression(unaryExpressionNode.Child(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
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(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
293 }
294 BindExpression(newExpressionNode.TypeExpr(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
295 if (newExpressionNode.Initializer())
296 {
297 BindExpression(newExpressionNode.Initializer(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
298 }
299 }
300
301 void ExpressionBinder::Visit(SubscriptExpressionNode& subscriptExpressionNode)
302 {
303 BindExpression(subscriptExpressionNode.Child(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
304 BindExpression(subscriptExpressionNode.Index(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
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(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder,
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(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder));
351 }
352 if (functionGroup)
353 {
354 CallableSymbol* functionSymbol = functionGroup->ResolveOverload(argumentSymbols, invokeExpressionNode.Child()->GetNodeType() == NodeType::arrowNode && subjectIsConst);
355 if (functionSymbol)
356 {
357 symbolTable.MapNode(&invokeExpressionNode, functionSymbol);
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(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
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(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder));
405 }
406 }
407
408 void ExpressionBinder::Visit(ArrowNode& arrowNode)
409 {
410 std::vector<Symbol*> leftSymbols = BindExpression(arrowNode.Child(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
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(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder));
446 }
447 }
448
449 void ExpressionBinder::Visit(PostfixIncNode& postfixIncNode)
450 {
451 BindExpression(postfixIncNode.Child(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
452 }
453
454 void ExpressionBinder::Visit(PostfixDecNode& postfixDecNode)
455 {
456 BindExpression(postfixDecNode.Child(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
457 }
458
459 void ExpressionBinder::Visit(CppCastExpressionNode& cppCastExpressionNode)
460 {
461 BindExpression(cppCastExpressionNode.TypeExpr(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
462 BindExpression(cppCastExpressionNode.Expr(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
463 }
464
465 void ExpressionBinder::Visit(TypeIdExpressionNode& typeIdExpressionNode)
466 {
467 BindExpression(typeIdExpressionNode.Child(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
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(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
482 }
483
484 void ExpressionBinder::Visit(LambdaExpressionNode& lambdaExpressionNode)
485 {
486 if (lambdaExpressionNode.Captures())
487 {
488 BindExpression(lambdaExpressionNode.Captures(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
489 }
490 lambdaExpressionNode.Body()->Accept(*statementBinder);
491 }
492
493 void ExpressionBinder::Visit(CaptureSequenceNode& captureSequenceNode)
494 {
495 BindExpression(captureSequenceNode.Left(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
496 BindExpression(captureSequenceNode.Right(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
497 }
498
499 void ExpressionBinder::Visit(IdentifierCaptureNode& identifierCaptureNode)
500 {
501 BindExpression(identifierCaptureNode.Child(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
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(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder));
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(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder));
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(&identifierNode, symbol);
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(&dtorIdNode, currentClassType);
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(symbolTable, containerScope, prevContainerScopes, *boundSourceFile, TypeResolverFlags::none, currentClassType, &templateIdNode);
614 symbols.push_back(type);
615 }
616
617 void ExpressionBinder::Visit(ConstNode& constNode)
618 {
619 BindExpression(constNode.Child(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
620 }
621
622 void ExpressionBinder::Visit(VolatileNode& volatileNode)
623 {
624 BindExpression(volatileNode.Child(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
625 }
626
627 void ExpressionBinder::Visit(PointerNode& pointerNode)
628 {
629 BindExpression(pointerNode.Child(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
630 }
631
632 void ExpressionBinder::Visit(RValueRefNode& rValueRefNode)
633 {
634 BindExpression(rValueRefNode.Child(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
635 }
636
637 void ExpressionBinder::Visit(LValueRefNode& lValueRefNode)
638 {
639 BindExpression(lValueRefNode.Child(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
640 }
641
642 void ExpressionBinder::Visit(DeleteExpressionNode& deleteExpressionNode)
643 {
644 BindExpression(deleteExpressionNode.Child(), symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder);
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(derivations, symbolTable.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(derivations, symbolTable.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(derivations, symbolTable.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(derivations, symbolTable.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*node, SymbolTable&symbolTable, ContainerScope*containerScope, conststd::std::vector<ContainerScope*>&prevContainerScopes, BoundSourceFile*boundSourceFile,
690 FunctionSymbol* currentFunction, StatementBinder* statementBinder, bool& subjectIsConst)
691 {
692 ExpressionBinder expressionBinder(symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder, subjectIsConst);
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(symbolTable, containerScope, prevContainerScopes, *boundSourceFile, TypeResolverFlags::noExternalTypes | TypeResolverFlags::nothrow,
703 currentClassType, node);
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*node, SymbolTable&symbolTable, ContainerScope*containerScope, conststd::std::vector<ContainerScope*>&prevContainerScopes, BoundSourceFile*boundSourceFile,
717 FunctionSymbol* currentFunction, StatementBinder* statementBinder)
718 {
719 bool subjectIsConst = false;
720 return BindExpression(node, symbolTable, containerScope, prevContainerScopes, boundSourceFile, currentFunction, statementBinder, subjectIsConst);
721 }
722
723 } }