1
2
3
4
5
6 #include <cmajor/binder/ExpressionBinder.hpp>
7 #include <cmajor/binder/BoundCompileUnit.hpp>
8 #include <cmajor/binder/BoundFunction.hpp>
9 #include <cmajor/binder/BoundExpression.hpp>
10 #include <cmajor/binder/OverloadResolution.hpp>
11 #include <cmajor/binder/StatementBinder.hpp>
12 #include <cmajor/binder/TypeResolver.hpp>
13 #include <cmajor/binder/Evaluator.hpp>
14 #include <cmajor/binder/Access.hpp>
15 #include <cmajor/symbols/ClassTypeSymbol.hpp>
16 #include <cmajor/symbols/InterfaceTypeSymbol.hpp>
17 #include <cmajor/symbols/ConstantSymbol.hpp>
18 #include <cmajor/symbols/EnumSymbol.hpp>
19 #include <cmajor/symbols/TypedefSymbol.hpp>
20 #include <cmajor/symbols/TemplateSymbol.hpp>
21 #include <cmajor/symbols/GlobalFlags.hpp>
22 #include <cmajor/symbols/DebugFlags.hpp>
23 #include <sngcm/ast/BasicType.hpp>
24 #include <sngcm/ast/Literal.hpp>
25 #include <sngcm/ast/Expression.hpp>
26 #include <sngcm/ast/Identifier.hpp>
27 #include <sngcm/ast/Visitor.hpp>
28 #include <soulng/util/Unicode.hpp>
29 #include <soulng/util/Log.hpp>
30 #include <soulng/util/Time.hpp>
31
32 namespace cmajor { namespace binder {
33
34 using soulng::lexer::Span;
35 using namespace soulng::unicode;
36
37 class ExpressionBinder : public sngcm::ast::Visitor
38 {
39 public:
40 ExpressionBinder(const Span& span_, const boost::uuids::uuid& moduleId_, BoundCompileUnit& boundCompileUnit_, BoundFunction* boundFunction_, ContainerScope* containerScope_,
41 StatementBinder* statementBinder_, bool lvalue_);
42 std::std::unique_ptr<BoundExpression>GetExpression(){returnstd::move(expression);}
43
44 void Visit(BoolNode& boolNode) override;
45 void Visit(SByteNode& sbyteNode) override;
46 void Visit(ByteNode& byteNode) override;
47 void Visit(ShortNode& shortNode) override;
48 void Visit(UShortNode& ushortNode) override;
49 void Visit(IntNode& intNode) override;
50 void Visit(UIntNode& uintNode) override;
51 void Visit(LongNode& longNode) override;
52 void Visit(ULongNode& ulongNode) override;
53 void Visit(FloatNode& floatNode) override;
54 void Visit(DoubleNode& doubleNode) override;
55 void Visit(CharNode& charNode) override;
56 void Visit(WCharNode& wcharNode) override;
57 void Visit(UCharNode& ucharNode) override;
58 void Visit(VoidNode& voidNode) override;
59
60 void Visit(BooleanLiteralNode& booleanLiteralNode) override;
61 void Visit(SByteLiteralNode& sbyteLiteralNode) override;
62 void Visit(ByteLiteralNode& byteLiteralNode) override;
63 void Visit(ShortLiteralNode& shortLiteralNode) override;
64 void Visit(UShortLiteralNode& ushortLiteralNode) override;
65 void Visit(IntLiteralNode& intLiteralNode) override;
66 void Visit(UIntLiteralNode& uintLiteralNode) override;
67 void Visit(LongLiteralNode& longLiteralNode) override;
68 void Visit(ULongLiteralNode& ulongLiteralNode) override;
69 void Visit(FloatLiteralNode& floatLiteralNode) override;
70 void Visit(DoubleLiteralNode& doubleLiteralNode) override;
71 void Visit(CharLiteralNode& charLiteralNode) override;
72 void Visit(WCharLiteralNode& wcharLiteralNode) override;
73 void Visit(UCharLiteralNode& ucharLiteralNode) override;
74 void Visit(StringLiteralNode& stringLiteralNode) override;
75 void Visit(WStringLiteralNode& wstringLiteralNode) override;
76 void Visit(UStringLiteralNode& ustringLiteralNode) override;
77 void Visit(NullLiteralNode& nullLiteralNode) override;
78 void Visit(UuidLiteralNode& uuidLiteralNode) override;
79
80 void Visit(IdentifierNode& identifierNode) override;
81 void Visit(TemplateIdNode& templateIdNode) override;
82 void Visit(ParameterNode& parameterNode) override;
83 void Visit(DotNode& dotNode) override;
84 void Visit(ArrowNode& arrowNode) override;
85 void BindArrow(Node& node, const std::u32string& name);
86 void Visit(DisjunctionNode& disjunctionNode) override;
87 void Visit(ConjunctionNode& conjunctionNode) override;
88 void Visit(BitOrNode& bitOrNode) override;
89 void Visit(BitXorNode& bitXorNode) override;
90 void Visit(BitAndNode& bitAndNode) override;
91 void Visit(EqualNode& equalNode) override;
92 void Visit(NotEqualNode& notEqualNode) override;
93 void Visit(LessNode& lessNode) override;
94 void Visit(GreaterNode& greaterNode) override;
95 void Visit(LessOrEqualNode& lessOrEqualNode) override;
96 void Visit(GreaterOrEqualNode& greaterOrEqualNode) override;
97 void Visit(ShiftLeftNode& shiftLeftNode) override;
98 void Visit(ShiftRightNode& shiftRightNode) override;
99 void Visit(AddNode& addNode) override;
100 void Visit(SubNode& subNode) override;
101 void Visit(MulNode& mulNode) override;
102 void Visit(DivNode& divNode) override;
103 void Visit(RemNode& remNode) override;
104 void Visit(NotNode& notNode) override;
105 void Visit(UnaryPlusNode& unaryPlusNode) override;
106 void Visit(UnaryMinusNode& unaryMinusNode) override;
107 void Visit(PrefixIncrementNode& prefixIncrementNode) override;
108 void Visit(PrefixDecrementNode& prefixDecrementNode) override;
109 void Visit(DerefNode& derefNode) override;
110 void Visit(AddrOfNode& addrOfNode) override;
111 void Visit(ComplementNode& complementNode) override;
112 void Visit(IsNode& isNode) override;
113 void Visit(AsNode& asNode) override;
114 void Visit(IndexingNode& indexingNode) override;
115 void Visit(InvokeNode& invokeNode) override;
116 void Visit(PostfixIncrementNode& postfixIncrementNode) override;
117 void Visit(PostfixDecrementNode& postfixDecrementNode) override;
118 void Visit(SizeOfNode& sizeOfNode) override;
119 void Visit(TypeNameNode& typeNameNode) override;
120 void Visit(TypeIdNode& typeNameNode) override;
121 void Visit(CastNode& castNode) override;
122 void Visit(ConstructNode& constructNode) override;
123 void Visit(NewNode& newNode) override;
124 void Visit(ThisNode& thisNode) override;
125 void Visit(BaseNode& baseNode) override;
126 void Visit(ParenthesizedExpressionNode& parenthesizedExpressionNode) override;
127 void Visit(FunctionPtrNode& functionPtrNode) override;
128 void BindUnaryOp(BoundExpression* operand, Node& node, const std::u32string& groupName);
129 private:
130 Span span;
131 boost::uuids::uuid moduleId;
132 BoundCompileUnit& boundCompileUnit;
133 SymbolTable& symbolTable;
134 Module* module;
135 BoundFunction* boundFunction;
136 ContainerScope* containerScope;
137 StatementBinder* statementBinder;
138 std::unique_ptr<BoundExpression> expression;
139 bool lvalue;
140 bool inhibitCompile;
141 void BindUnaryOp(UnaryNode& unaryNode, const std::u32string& groupName);
142 void BindBinaryOp(BinaryNode& binaryNode, const std::u32string& groupName);
143 void BindBinaryOp(BoundExpression* left, BoundExpression* right, Node& node, const std::u32string& groupName);
144 void BindDerefExpr(Node& node);
145 void BindSymbol(Symbol* symbol, IdentifierNode* idNode);
146 };
147
148 ExpressionBinder::ExpressionBinder(const Span& span_, const boost::uuids::uuid& moduleId_, BoundCompileUnit& boundCompileUnit_, BoundFunction* boundFunction_, ContainerScope* containerScope_,
149 StatementBinder* statementBinder_, bool lvalue_) :
150 span(span_), moduleId(moduleId_), boundCompileUnit(boundCompileUnit_), symbolTable(boundCompileUnit.GetSymbolTable()), module(&boundCompileUnit.GetModule()),
151 boundFunction(boundFunction_), containerScope(containerScope_), statementBinder(statementBinder_), lvalue(lvalue_), inhibitCompile(false)
152 {
153 }
154
155 void ExpressionBinder::BindUnaryOp(BoundExpression* operand, Node& node, const std::u32string& groupName)
156 {
157 std::vector<std::std::unique_ptr<BoundExpression>>arguments;
158 arguments.push_back(std::unique_ptr<BoundExpression>(operand));
159 std::vector<FunctionScopeLookup> functionScopeLookups;
160 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parent, containerScope));
161 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parent, operand->GetType()->BaseType()->ClassOrNsScope()));
162 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::fileScopes, nullptr));
163 std::vector<TypeSymbol*> templateArgumentTypes;
164 std::unique_ptr<Exception> exception;
165 std::unique_ptr<BoundFunctionCall> operatorFunCall = ResolveOverload(groupName, containerScope, functionScopeLookups, arguments, boundCompileUnit, boundFunction, node.GetSpan(), node.ModuleId(),
166 OverloadResolutionFlags::dontThrow, templateArgumentTypes, exception);
167 if (!operatorFunCall)
168 {
169 if (arguments[0]->GetType()->PlainType(node.GetSpan(), node.ModuleId())->IsClassTypeSymbol())
170 {
171 if (arguments[0]->GetType()->IsReferenceType())
172 {
173 TypeSymbol* type = arguments[0]->GetType()->RemoveReference(node.GetSpan(), node.ModuleId())->AddPointer(node.GetSpan(), node.ModuleId());
174 arguments[0].reset(new BoundReferenceToPointerExpression(std::move(arguments[0]), type));
175 }
176 else
177 {
178 TypeSymbol* type = arguments[0]->GetType()->PlainType(node.GetSpan(), node.ModuleId())->AddPointer(node.GetSpan(), node.ModuleId());
179 arguments[0].reset(new BoundAddressOfExpression(std::move(arguments[0]), type));
180 }
181 operatorFunCall = std::move(ResolveOverload(groupName, containerScope, functionScopeLookups, arguments, boundCompileUnit, boundFunction, node.GetSpan(), node.ModuleId()));
182 }
183 else
184 {
185 throw *exception;
186 }
187 }
188 CheckAccess(boundFunction->GetFunctionSymbol(), operatorFunCall->GetFunctionSymbol());
189 LocalVariableSymbol* temporary = nullptr;
190 if (operatorFunCall->GetFunctionSymbol()->ReturnsClassInterfaceOrClassDelegateByValue())
191 {
192 TypeSymbol* type = operatorFunCall->GetFunctionSymbol()->ReturnType();
193 temporary = boundFunction->GetFunctionSymbol()->CreateTemporary(type, node.GetSpan(), node.ModuleId());
194 operatorFunCall->AddArgument(std::unique_ptr<BoundExpression>(new BoundAddressOfExpression(std::unique_ptr<BoundExpression>(new BoundLocalVariable(node.GetSpan(), node.ModuleId(), temporary)),
195 type->AddPointer(node.GetSpan(), node.ModuleId()))));
196 if (type->IsClassTypeSymbol())
197 {
198 ClassTypeSymbol* classType = static_cast<ClassTypeSymbol*>(type);
199 if (classType->Destructor())
200 {
201 std::unique_ptr<BoundFunctionCall> destructorCall(new BoundFunctionCall(span, moduleId, classType->Destructor()));
202 destructorCall->AddArgument(std::unique_ptr<BoundExpression>(operatorFunCall->Arguments().back()->Clone()));
203 boundFunction->AddTemporaryDestructorCall(std::move(destructorCall), boundFunction, containerScope, span, moduleId);
204 }
205 }
206 }
207 expression.reset(operatorFunCall.release());
208 if (temporary)
209 {
210 expression.reset(new BoundConstructAndReturnTemporaryExpression(std::move(expression), std::unique_ptr<BoundExpression>(new BoundLocalVariable(node.GetSpan(), node.ModuleId(), temporary))));
211 expression->SetFlag(BoundExpressionFlags::bindToRvalueReference);
212 }
213 }
214
215 void ExpressionBinder::BindUnaryOp(UnaryNode& unaryNode, const std::u32string& groupName)
216 {
217 unaryNode.Subject()->Accept(*this);
218 BoundExpression* operand = expression.release();
219 BindUnaryOp(operand, unaryNode, groupName);
220 }
221
222 void ExpressionBinder::BindBinaryOp(BinaryNode& binaryNode, const std::u32string& groupName)
223 {
224 binaryNode.Left()->Accept(*this);
225 BoundExpression* left = expression.release();
226 binaryNode.Right()->Accept(*this);
227 BoundExpression* right = expression.release();
228 BindBinaryOp(left, right, binaryNode, groupName);
229 }
230
231 void ExpressionBinder::BindBinaryOp(BoundExpression* left, BoundExpression* right, Node& node, const std::u32string& groupName)
232 {
233 std::vector<std::std::unique_ptr<BoundExpression>>arguments;
234 arguments.push_back(std::unique_ptr<BoundExpression>(left));
235 arguments.push_back(std::unique_ptr<BoundExpression>(right));
236 std::vector<FunctionScopeLookup> functionScopeLookups;
237 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parent, containerScope));
238 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parent, left->GetType()->BaseType()->ClassOrNsScope()));
239 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parent, right->GetType()->BaseType()->ClassOrNsScope()));
240 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::fileScopes, nullptr));
241 std::vector<TypeSymbol*> templateArgumentTypes;
242 std::unique_ptr<Exception> exception;
243 std::unique_ptr<BoundFunctionCall> operatorFunCall = ResolveOverload(groupName, containerScope, functionScopeLookups, arguments, boundCompileUnit, boundFunction, node.GetSpan(), node.ModuleId(),
244 OverloadResolutionFlags::dontThrow, templateArgumentTypes, exception);
245 if (!operatorFunCall)
246 {
247 if (arguments[0]->GetType()->PlainType(node.GetSpan(), node.ModuleId())->IsClassTypeSymbol())
248 {
249 if (arguments[0]->GetType()->IsReferenceType())
250 {
251 TypeSymbol* type = arguments[0]->GetType()->RemoveReference(node.GetSpan(), node.ModuleId())->AddPointer(node.GetSpan(), node.ModuleId());
252 arguments[0].reset(new BoundReferenceToPointerExpression(std::move(arguments[0]), type));
253 }
254 else
255 {
256 TypeSymbol* type = arguments[0]->GetType()->PlainType(node.GetSpan(), node.ModuleId())->AddPointer(node.GetSpan(), node.ModuleId());
257 arguments[0].reset(new BoundAddressOfExpression(std::move(arguments[0]), type));
258 }
259 operatorFunCall = std::move(ResolveOverload(groupName, containerScope, functionScopeLookups, arguments, boundCompileUnit, boundFunction, node.GetSpan(), node.ModuleId()));
260 }
261 else
262 {
263 throw *exception;
264 }
265 }
266 CheckAccess(boundFunction->GetFunctionSymbol(), operatorFunCall->GetFunctionSymbol());
267 LocalVariableSymbol* temporary = nullptr;
268 if (operatorFunCall->GetFunctionSymbol()->ReturnsClassInterfaceOrClassDelegateByValue())
269 {
270 TypeSymbol* type = operatorFunCall->GetFunctionSymbol()->ReturnType();
271 temporary = boundFunction->GetFunctionSymbol()->CreateTemporary(type, node.GetSpan(), node.ModuleId());
272 operatorFunCall->AddArgument(std::unique_ptr<BoundExpression>(new BoundAddressOfExpression(std::unique_ptr<BoundExpression>(new BoundLocalVariable(node.GetSpan(), node.ModuleId(), temporary)),
273 type->AddPointer(node.GetSpan(), node.ModuleId()))));
274 if (type->IsClassTypeSymbol())
275 {
276 ClassTypeSymbol* classType = static_cast<ClassTypeSymbol*>(type);
277 if (classType->Destructor())
278 {
279 std::unique_ptr<BoundFunctionCall> destructorCall(new BoundFunctionCall(span, moduleId, classType->Destructor()));
280 destructorCall->AddArgument(std::unique_ptr<BoundExpression>(operatorFunCall->Arguments().back()->Clone()));
281 boundFunction->AddTemporaryDestructorCall(std::move(destructorCall), boundFunction, containerScope, span, moduleId);
282 }
283 }
284 }
285 expression.reset(operatorFunCall.release());
286 if (temporary)
287 {
288 expression.reset(new BoundConstructAndReturnTemporaryExpression(std::move(expression), std::unique_ptr<BoundExpression>(new BoundLocalVariable(node.GetSpan(), node.ModuleId(), temporary))));
289 expression->SetFlag(BoundExpressionFlags::bindToRvalueReference);
290 }
291 }
292
293 void ExpressionBinder::BindSymbol(Symbol* symbol, IdentifierNode* idNode)
294 {
295 Span spn = span;
296 boost::uuids::uuid mid = moduleId;
297 if (idNode)
298 {
299 spn = idNode->GetSpan();
300 mid = idNode->ModuleId();
301 }
302 switch (symbol->GetSymbolType())
303 {
304 case SymbolType::functionGroupSymbol:
305 {
306 FunctionGroupSymbol* functionGroupSymbol = static_cast<FunctionGroupSymbol*>(symbol);
307 BoundFunctionGroupExpression* boundFunctionGroupExpression = new BoundFunctionGroupExpression(span, moduleId, functionGroupSymbol);
308 ParameterSymbol* thisParam = boundFunction->GetFunctionSymbol()->GetThisParam();
309 if (thisParam)
310 {
311 boundFunctionGroupExpression->SetClassPtr(std::unique_ptr<BoundExpression>(new BoundParameter(spn, mid, thisParam)));
312 }
313 expression.reset(boundFunctionGroupExpression);
314 break;
315 }
316 case SymbolType::classTypeSymbol: case SymbolType::classTemplateSpecializationSymbol:
317 {
318 ClassTypeSymbol* classTypeSymbol = static_cast<ClassTypeSymbol*>(symbol);
319 CheckAccess(boundFunction->GetFunctionSymbol(), classTypeSymbol);
320 expression.reset(new BoundTypeExpression(span, moduleId, classTypeSymbol));
321 if (idNode && GetGlobalFlag(GlobalFlags::cmdoc))
322 {
323 symbolTable.MapSymbol(idNode, classTypeSymbol);
324 }
325 if (idNode)
326 {
327 MapIdentifierToSymbolDefinition(idNode, classTypeSymbol);
328 }
329 break;
330 }
331 case SymbolType::classGroupTypeSymbol:
332 {
333 ClassGroupTypeSymbol* classGroupTypeSymbol = static_cast<ClassGroupTypeSymbol*>(symbol);
334 expression.reset(new BoundTypeExpression(span, moduleId, classGroupTypeSymbol));
335 ClassTypeSymbol* classTypeSymbol = classGroupTypeSymbol->GetClass(0);
336 if (idNode && GetGlobalFlag(GlobalFlags::cmdoc) && classTypeSymbol)
337 {
338 symbolTable.MapSymbol(idNode, classTypeSymbol);
339 }
340 if (idNode && classTypeSymbol)
341 {
342 MapIdentifierToSymbolDefinition(idNode, classTypeSymbol);
343 }
344 break;
345 }
346 case SymbolType::interfaceTypeSymbol:
347 {
348 InterfaceTypeSymbol* interfaceTypeSymbol = static_cast<InterfaceTypeSymbol*>(symbol);
349 expression.reset(new BoundTypeExpression(span, moduleId, interfaceTypeSymbol));
350 if (idNode && GetGlobalFlag(GlobalFlags::cmdoc))
351 {
352 symbolTable.MapSymbol(idNode, interfaceTypeSymbol);
353 }
354 if (idNode)
355 {
356 MapIdentifierToSymbolDefinition(idNode, interfaceTypeSymbol);
357 }
358 break;
359 }
360 case SymbolType::delegateTypeSymbol:
361 {
362 DelegateTypeSymbol* delegateTypeSymbol = static_cast<DelegateTypeSymbol*>(symbol);
363 CheckAccess(boundFunction->GetFunctionSymbol(), delegateTypeSymbol);
364 expression.reset(new BoundTypeExpression(span, moduleId, delegateTypeSymbol));
365 if (idNode && GetGlobalFlag(GlobalFlags::cmdoc))
366 {
367 symbolTable.MapSymbol(idNode, delegateTypeSymbol);
368 }
369 if (idNode)
370 {
371 MapIdentifierToSymbolDefinition(idNode, delegateTypeSymbol);
372 }
373 break;
374 }
375 case SymbolType::classDelegateTypeSymbol:
376 {
377 ClassDelegateTypeSymbol* classDelegateTypeSymbol = static_cast<ClassDelegateTypeSymbol*>(symbol);
378 CheckAccess(boundFunction->GetFunctionSymbol(), classDelegateTypeSymbol);
379 expression.reset(new BoundTypeExpression(span, moduleId, classDelegateTypeSymbol));
380 if (idNode && GetGlobalFlag(GlobalFlags::cmdoc))
381 {
382 symbolTable.MapSymbol(idNode, classDelegateTypeSymbol);
383 }
384 if (idNode)
385 {
386 MapIdentifierToSymbolDefinition(idNode, classDelegateTypeSymbol);
387 }
388 break;
389 }
390 case SymbolType::typedefSymbol:
391 {
392 TypedefSymbol* typedefSymbol = static_cast<TypedefSymbol*>(symbol);
393 CheckAccess(boundFunction->GetFunctionSymbol(), typedefSymbol);
394 expression.reset(new BoundTypeExpression(span, moduleId, typedefSymbol->GetType()));
395 if (idNode && GetGlobalFlag(GlobalFlags::cmdoc))
396 {
397 symbolTable.MapSymbol(idNode, typedefSymbol);
398 }
399 if (idNode)
400 {
401 MapIdentifierToSymbolDefinition(idNode, typedefSymbol);
402 }
403 break;
404 }
405 case SymbolType::boundTemplateParameterSymbol:
406 {
407 BoundTemplateParameterSymbol* boundTemplateParameterSymbol = static_cast<BoundTemplateParameterSymbol*>(symbol);
408 expression.reset(new BoundTypeExpression(span, moduleId, boundTemplateParameterSymbol->GetType()));
409 break;
410 }
411 case SymbolType::parameterSymbol:
412 {
413 ParameterSymbol* parameterSymbol = static_cast<ParameterSymbol*>(symbol);
414 CheckAccess(boundFunction->GetFunctionSymbol(), parameterSymbol);
415 expression.reset(new BoundParameter(spn, mid, parameterSymbol));
416 if (idNode)
417 {
418 MapIdentifierToSymbolDefinition(idNode, parameterSymbol);
419 }
420 break;
421 }
422 case SymbolType::localVariableSymbol:
423 {
424 LocalVariableSymbol* localVariableSymbol = static_cast<LocalVariableSymbol*>(symbol);
425 CheckAccess(boundFunction->GetFunctionSymbol(), localVariableSymbol);
426 expression.reset(new BoundLocalVariable(spn, mid, localVariableSymbol));
427 if (idNode)
428 {
429 MapIdentifierToSymbolDefinition(idNode, localVariableSymbol);
430 }
431 break;
432 }
433 case SymbolType::memberVariableSymbol:
434 {
435 MemberVariableSymbol* memberVariableSymbol = static_cast<MemberVariableSymbol*>(symbol);
436 if (idNode && GetGlobalFlag(GlobalFlags::cmdoc))
437 {
438 symbolTable.MapSymbol(idNode, memberVariableSymbol);
439 }
440 if (idNode)
441 {
442 MapIdentifierToSymbolDefinition(idNode, memberVariableSymbol);
443 }
444 FunctionSymbol* currentFuctionSymbol = boundFunction->GetFunctionSymbol();
445 CheckAccess(currentFuctionSymbol, memberVariableSymbol);
446 BoundMemberVariable* bmv = new BoundMemberVariable(spn, mid, memberVariableSymbol);
447 bool accessFromOwnScope = false;
448 ClassTypeSymbol* currentClass = currentFuctionSymbol->ContainingClassNoThrow();
449 if (currentClass)
450 {
451 ClassTypeSymbol* cp = memberVariableSymbol->ContainingClassNoThrow();
452 Assert(cp, "class type symbol expected");
453 if (cp == currentClass)
454 {
455 accessFromOwnScope = true;
456 }
457 }
458 if (memberVariableSymbol->IsStatic())
459 {
460 if (!accessFromOwnScope)
461 {
462 bmv->SetStaticInitNeeded();
463 }
464 }
465 else
466 {
467 ParameterSymbol* thisParam = currentFuctionSymbol->GetThisParam();
468 if (accessFromOwnScope && !currentFuctionSymbol->IsStatic())
469 {
470 if (thisParam)
471 {
472 TypeSymbol* thisPointerType = thisParam->GetType()->BaseType()->AddPointer(span, moduleId);
473 if (thisParam->GetType()->IsConstType())
474 {
475 thisPointerType = thisPointerType->AddConst(span, moduleId);
476 }
477 bmv->SetClassPtr(std::unique_ptr<BoundExpression>(new BoundParameter(spn, mid, thisParam)));
478 }
479 else
480 {
481 Assert(false, "this param expected");
482 }
483 }
484 else if (thisParam)
485 {
486 ClassTypeSymbol* containingClass = memberVariableSymbol->ContainingClassNoThrow();
487 TypeSymbol* containingClassPointerType = containingClass->AddPointer(span, moduleId);
488 TypeSymbol* thisPointerType = thisParam->GetType()->BaseType()->AddPointer(span, moduleId);
489 if (thisParam->GetType()->IsConstType())
490 {
491 thisPointerType = thisPointerType->AddConst(span, moduleId);
492 containingClassPointerType->AddConst(span, moduleId);
493 }
494 ArgumentMatch argumentMatch;
495 FunctionSymbol* conversionFun = boundCompileUnit.GetConversion(thisPointerType, containingClassPointerType, containerScope, boundFunction, span, moduleId, argumentMatch);
496 if (conversionFun)
497 {
498 bmv->SetClassPtr(std::unique_ptr<BoundExpression>(new BoundConversion(std::unique_ptr<BoundExpression>(new BoundParameter(
499 spn, mid, thisParam)), conversionFun)));
500 }
501 }
502 }
503 expression.reset(bmv);
504 break;
505 }
506 case SymbolType::constantSymbol:
507 {
508 ConstantSymbol* constantSymbol = static_cast<ConstantSymbol*>(symbol);
509 CheckAccess(boundFunction->GetFunctionSymbol(), constantSymbol);
510 expression.reset(new BoundConstant(spn, mid, constantSymbol));
511 if (idNode && GetGlobalFlag(GlobalFlags::cmdoc))
512 {
513 symbolTable.MapSymbol(idNode, constantSymbol);
514 }
515 if (idNode)
516 {
517 MapIdentifierToSymbolDefinition(idNode, constantSymbol);
518 }
519 break;
520 }
521 case SymbolType::enumTypeSymbol:
522 {
523 EnumTypeSymbol* enumTypeSymbol = static_cast<EnumTypeSymbol*>(symbol);
524 CheckAccess(boundFunction->GetFunctionSymbol(), enumTypeSymbol);
525 expression.reset(new BoundTypeExpression(span, moduleId, enumTypeSymbol));
526 if (idNode && GetGlobalFlag(GlobalFlags::cmdoc))
527 {
528 symbolTable.MapSymbol(idNode, enumTypeSymbol);
529 }
530 if (idNode)
531 {
532 MapIdentifierToSymbolDefinition(idNode, enumTypeSymbol);
533 }
534 break;
535 }
536 case SymbolType::enumConstantSymbol:
537 {
538 EnumConstantSymbol* enumConstantSymbol = static_cast<EnumConstantSymbol*>(symbol);
539 expression.reset(new BoundEnumConstant(spn, mid, enumConstantSymbol));
540 if (idNode && GetGlobalFlag(GlobalFlags::cmdoc))
541 {
542 symbolTable.MapSymbol(idNode, enumConstantSymbol);
543 }
544 if (idNode)
545 {
546 MapIdentifierToSymbolDefinition(idNode, enumConstantSymbol);
547 }
548 break;
549 }
550 case SymbolType::namespaceSymbol:
551 {
552 NamespaceSymbol* ns = static_cast<NamespaceSymbol*>(symbol);
553 expression.reset(new BoundNamespaceExpression(span, moduleId, ns));
554 if (idNode)
555 {
556 MapIdentifierToSymbolDefinition(idNode, ns);
557 }
558 break;
559 }
560 case SymbolType::globalVariableGroupSymbol:
561 {
562 GlobalVariableSymbol* globalVariableSymbol = nullptr;
563 GlobalVariableGroupSymbol* globalVariableGroup = static_cast<GlobalVariableGroupSymbol*>(symbol);
564 std::vector<GlobalVariableSymbol*> globalVariables;
565 globalVariableGroup->CollectGlobalVariables(boundCompileUnit.GetCompileUnitNode()->FilePath(), globalVariables);
566 if (globalVariables.empty())
567 {
568 throw Exception("global variable group '" + ToUtf8(globalVariableGroup->Name()) + "' contains no relevant public or internal global variables", span, moduleId);
569 }
570 else if (globalVariables.size() == 1)
571 {
572 globalVariableSymbol = globalVariables.front();
573 if (globalVariableSymbol->Access() == SymbolAccess::private_ && globalVariableSymbol->CompileUnitFilePath() != boundCompileUnit.GetCompileUnitNode()->FilePath())
574 {
575 throw Exception("global variable group '" + ToUtf8(globalVariableGroup->Name()) +
576 "' does not contain a public or internal global variable with the given name but do contain a private global variable defined in the compile unit " +
577 globalVariableSymbol->CompileUnitFilePath(), span, moduleId, globalVariableSymbol->GetSpan(), globalVariableSymbol->SourceModuleId());
578 }
579 else
580 {
581 expression.reset(new BoundGlobalVariable(spn, mid, globalVariableSymbol));
582 }
583 }
584 else
585 {
586 std::string compileUnits;
587 bool first = true;
588 for (GlobalVariableSymbol* globalVariableSymbol : globalVariables)
589 {
590 if (first)
591 {
592 first = false;
593 }
594 else
595 {
596 compileUnits.append(", ");
597 }
598 compileUnits.append(globalVariableSymbol->CompileUnitFilePath());
599 }
600 throw Exception("global variable group '" + ToUtf8(globalVariableGroup->Name()) +
601 "' does not contain a public or internal global variable with the given name but do contain private global variables defined in the following compile units: " + compileUnits,
602 span, moduleId);
603 }
604 if (idNode)
605 {
606 if (globalVariableSymbol)
607 {
608 MapIdentifierToSymbolDefinition(idNode, globalVariableSymbol);
609 }
610 }
611 break;
612 }
613 default:
614 {
615 throw Exception("could not bind '" + ToUtf8(symbol->FullName()) + "'", span, moduleId, symbol->GetSpan(), symbol->SourceModuleId());
616 }
617 }
618 }
619
620 void ExpressionBinder::Visit(BoolNode& boolNode)
621 {
622 expression.reset(new BoundTypeExpression(boolNode.GetSpan(), boolNode.ModuleId(), symbolTable.GetTypeByName(U"bool")));
623 }
624
625 void ExpressionBinder::Visit(SByteNode& sbyteNode)
626 {
627 expression.reset(new BoundTypeExpression(sbyteNode.GetSpan(), sbyteNode.ModuleId(), symbolTable.GetTypeByName(U"sbyte")));
628 }
629
630 void ExpressionBinder::Visit(ByteNode& byteNode)
631 {
632 expression.reset(new BoundTypeExpression(byteNode.GetSpan(), byteNode.ModuleId(), symbolTable.GetTypeByName(U"byte")));
633 }
634
635 void ExpressionBinder::Visit(ShortNode& shortNode)
636 {
637 expression.reset(new BoundTypeExpression(shortNode.GetSpan(), shortNode.ModuleId(), symbolTable.GetTypeByName(U"short")));
638 }
639
640 void ExpressionBinder::Visit(UShortNode& ushortNode)
641 {
642 expression.reset(new BoundTypeExpression(ushortNode.GetSpan(), ushortNode.ModuleId(), symbolTable.GetTypeByName(U"ushort")));
643 }
644
645 void ExpressionBinder::Visit(IntNode& intNode)
646 {
647 expression.reset(new BoundTypeExpression(intNode.GetSpan(), intNode.ModuleId(), symbolTable.GetTypeByName(U"int")));
648 }
649
650 void ExpressionBinder::Visit(UIntNode& uintNode)
651 {
652 expression.reset(new BoundTypeExpression(uintNode.GetSpan(), uintNode.ModuleId(), symbolTable.GetTypeByName(U"uint")));
653 }
654
655 void ExpressionBinder::Visit(LongNode& longNode)
656 {
657 expression.reset(new BoundTypeExpression(longNode.GetSpan(), longNode.ModuleId(), symbolTable.GetTypeByName(U"long")));
658 }
659
660 void ExpressionBinder::Visit(ULongNode& ulongNode)
661 {
662 expression.reset(new BoundTypeExpression(ulongNode.GetSpan(), ulongNode.ModuleId(), symbolTable.GetTypeByName(U"ulong")));
663 }
664
665 void ExpressionBinder::Visit(FloatNode& floatNode)
666 {
667 expression.reset(new BoundTypeExpression(floatNode.GetSpan(), floatNode.ModuleId(), symbolTable.GetTypeByName(U"float")));
668 }
669
670 void ExpressionBinder::Visit(DoubleNode& doubleNode)
671 {
672 expression.reset(new BoundTypeExpression(doubleNode.GetSpan(), doubleNode.ModuleId(), symbolTable.GetTypeByName(U"double")));
673 }
674
675 void ExpressionBinder::Visit(CharNode& charNode)
676 {
677 expression.reset(new BoundTypeExpression(charNode.GetSpan(), charNode.ModuleId(), symbolTable.GetTypeByName(U"char")));
678 }
679
680 void ExpressionBinder::Visit(WCharNode& wcharNode)
681 {
682 expression.reset(new BoundTypeExpression(wcharNode.GetSpan(), wcharNode.ModuleId(), symbolTable.GetTypeByName(U"wchar")));
683 }
684
685 void ExpressionBinder::Visit(UCharNode& ucharNode)
686 {
687 expression.reset(new BoundTypeExpression(ucharNode.GetSpan(), ucharNode.ModuleId(), symbolTable.GetTypeByName(U"uchar")));
688 }
689
690 void ExpressionBinder::Visit(VoidNode& voidNode)
691 {
692 expression.reset(new BoundTypeExpression(voidNode.GetSpan(), voidNode.ModuleId(), symbolTable.GetTypeByName(U"void")));
693 }
694
695 void ExpressionBinder::Visit(BooleanLiteralNode& booleanLiteralNode)
696 {
697 expression.reset(new BoundLiteral(std::unique_ptr<Value>(new BoolValue(booleanLiteralNode.GetSpan(), booleanLiteralNode.ModuleId(), booleanLiteralNode.Value())), symbolTable.GetTypeByName(U"bool")));
698 }
699
700 void ExpressionBinder::Visit(SByteLiteralNode& sbyteLiteralNode)
701 {
702 expression.reset(new BoundLiteral(std::unique_ptr<Value>(new SByteValue(sbyteLiteralNode.GetSpan(), sbyteLiteralNode.ModuleId(), sbyteLiteralNode.Value())), symbolTable.GetTypeByName(U"sbyte")));
703 }
704
705 void ExpressionBinder::Visit(ByteLiteralNode& byteLiteralNode)
706 {
707 expression.reset(new BoundLiteral(std::unique_ptr<Value>(new ByteValue(byteLiteralNode.GetSpan(), byteLiteralNode.ModuleId(), byteLiteralNode.Value())), symbolTable.GetTypeByName(U"byte")));
708 }
709
710 void ExpressionBinder::Visit(ShortLiteralNode& shortLiteralNode)
711 {
712 expression.reset(new BoundLiteral(std::unique_ptr<Value>(new ShortValue(shortLiteralNode.GetSpan(), shortLiteralNode.ModuleId(), shortLiteralNode.Value())), symbolTable.GetTypeByName(U"short")));
713 }
714
715 void ExpressionBinder::Visit(UShortLiteralNode& ushortLiteralNode)
716 {
717 expression.reset(new BoundLiteral(std::unique_ptr<Value>(new UShortValue(ushortLiteralNode.GetSpan(), ushortLiteralNode.ModuleId(), ushortLiteralNode.Value())), symbolTable.GetTypeByName(U"ushort")));
718 }
719
720 void ExpressionBinder::Visit(IntLiteralNode& intLiteralNode)
721 {
722 expression.reset(new BoundLiteral(std::unique_ptr<Value>(new IntValue(intLiteralNode.GetSpan(), intLiteralNode.ModuleId(), intLiteralNode.Value())), symbolTable.GetTypeByName(U"int")));
723 }
724
725 void ExpressionBinder::Visit(UIntLiteralNode& uintLiteralNode)
726 {
727 expression.reset(new BoundLiteral(std::unique_ptr<Value>(new UIntValue(uintLiteralNode.GetSpan(), uintLiteralNode.ModuleId(), uintLiteralNode.Value())), symbolTable.GetTypeByName(U"uint")));
728 }
729
730 void ExpressionBinder::Visit(LongLiteralNode& longLiteralNode)
731 {
732 expression.reset(new BoundLiteral(std::unique_ptr<Value>(new LongValue(longLiteralNode.GetSpan(), longLiteralNode.ModuleId(), longLiteralNode.Value())), symbolTable.GetTypeByName(U"long")));
733 }
734
735 void ExpressionBinder::Visit(ULongLiteralNode& ulongLiteralNode)
736 {
737 expression.reset(new BoundLiteral(std::unique_ptr<Value>(new ULongValue(ulongLiteralNode.GetSpan(), ulongLiteralNode.ModuleId(), ulongLiteralNode.Value())), symbolTable.GetTypeByName(U"ulong")));
738 }
739
740 void ExpressionBinder::Visit(FloatLiteralNode& floatLiteralNode)
741 {
742 expression.reset(new BoundLiteral(std::unique_ptr<Value>(new FloatValue(floatLiteralNode.GetSpan(), floatLiteralNode.ModuleId(), floatLiteralNode.Value())), symbolTable.GetTypeByName(U"float")));
743 }
744
745 void ExpressionBinder::Visit(DoubleLiteralNode& doubleLiteralNode)
746 {
747 expression.reset(new BoundLiteral(std::unique_ptr<Value>(new DoubleValue(doubleLiteralNode.GetSpan(), doubleLiteralNode.ModuleId(), doubleLiteralNode.Value())), symbolTable.GetTypeByName(U"double")));
748 }
749
750 void ExpressionBinder::Visit(CharLiteralNode& charLiteralNode)
751 {
752 expression.reset(new BoundLiteral(std::unique_ptr<Value>(new CharValue(charLiteralNode.GetSpan(), charLiteralNode.ModuleId(), charLiteralNode.Value())), symbolTable.GetTypeByName(U"char")));
753 }
754
755 void ExpressionBinder::Visit(WCharLiteralNode& wcharLiteralNode)
756 {
757 expression.reset(new BoundLiteral(std::unique_ptr<Value>(new WCharValue(wcharLiteralNode.GetSpan(), wcharLiteralNode.ModuleId(), wcharLiteralNode.Value())), symbolTable.GetTypeByName(U"wchar")));
758 }
759
760 void ExpressionBinder::Visit(UCharLiteralNode& ucharLiteralNode)
761 {
762 expression.reset(new BoundLiteral(std::unique_ptr<Value>(new UCharValue(ucharLiteralNode.GetSpan(), ucharLiteralNode.ModuleId(), ucharLiteralNode.Value())), symbolTable.GetTypeByName(U"uchar")));
763 }
764
765 void ExpressionBinder::Visit(StringLiteralNode& stringLiteralNode)
766 {
767 expression.reset(new BoundLiteral(std::unique_ptr<Value>(new StringValue(stringLiteralNode.GetSpan(), stringLiteralNode.ModuleId(), boundCompileUnit.Install(stringLiteralNode.Value()), stringLiteralNode.Value())),
768 symbolTable.GetTypeByName(U"char")->AddConst(stringLiteralNode.GetSpan(), stringLiteralNode.ModuleId())->AddPointer(stringLiteralNode.GetSpan(), stringLiteralNode.ModuleId())));
769 }
770
771 void ExpressionBinder::Visit(WStringLiteralNode& wstringLiteralNode)
772 {
773 expression.reset(new BoundLiteral(std::unique_ptr<Value>(new WStringValue(wstringLiteralNode.GetSpan(), wstringLiteralNode.ModuleId(), boundCompileUnit.Install(wstringLiteralNode.Value()), wstringLiteralNode.Value())),
774 symbolTable.GetTypeByName(U"wchar")->AddConst(wstringLiteralNode.GetSpan(), wstringLiteralNode.ModuleId())->AddPointer(wstringLiteralNode.GetSpan(), wstringLiteralNode.ModuleId())));
775 }
776
777 void ExpressionBinder::Visit(UStringLiteralNode& ustringLiteralNode)
778 {
779 expression.reset(new BoundLiteral(std::unique_ptr<Value>(new UStringValue(ustringLiteralNode.GetSpan(), ustringLiteralNode.ModuleId(), boundCompileUnit.Install(ustringLiteralNode.Value()), ustringLiteralNode.Value())),
780 symbolTable.GetTypeByName(U"uchar")->AddConst(ustringLiteralNode.GetSpan(), ustringLiteralNode.ModuleId())->AddPointer(ustringLiteralNode.GetSpan(), ustringLiteralNode.ModuleId())));
781 }
782
783 void ExpressionBinder::Visit(NullLiteralNode& nullLiteralNode)
784 {
785 TypeSymbol* nullPtrType = symbolTable.GetTypeByName(U"@nullptr_type");
786 expression.reset(new BoundLiteral(std::unique_ptr<Value>(new NullValue(nullLiteralNode.GetSpan(), nullLiteralNode.ModuleId(), nullPtrType)), nullPtrType));
787 }
788
789 void ExpressionBinder::Visit(UuidLiteralNode& uuidLiteralNode)
790 {
791 expression.reset(new BoundLiteral(std::unique_ptr<Value>(new UuidValue(uuidLiteralNode.GetSpan(), uuidLiteralNode.ModuleId(), boundCompileUnit.Install(uuidLiteralNode.GetUuid()))),
792 symbolTable.GetTypeByName(U"void")->AddPointer(uuidLiteralNode.GetSpan(), uuidLiteralNode.ModuleId())));
793 }
794
795 void ExpressionBinder::Visit(IdentifierNode& identifierNode)
796 {
797 boundCompileUnit.SetLatestIdentifier(&identifierNode);
798 std::u32string name = identifierNode.Str();
799 Symbol* symbol = containerScope->Lookup(name, ScopeLookup::this_and_base_and_parent);
800 if (!symbol)
801 {
802 for (const std::std::unique_ptr<FileScope>&fileScope : boundCompileUnit.FileScopes())
803 {
804 symbol = fileScope->Lookup(name);
805 if (symbol)
806 {
807 break;
808 }
809 }
810 }
811 if (symbol)
812 {
813 BindSymbol(symbol, &identifierNode);
814 }
815 else
816 {
817 throw Exception("symbol '" + ToUtf8(name) + "' not found", identifierNode.GetSpan(), identifierNode.ModuleId());
818 }
819 }
820
821 void ExpressionBinder::Visit(TemplateIdNode& templateIdNode)
822 {
823 int arity = templateIdNode.TemplateArguments().Count();
824 templateIdNode.Primary()->Accept(*this);
825 if (expression->GetBoundNodeType() == BoundNodeType::boundTypeExpression)
826 {
827 TypeSymbol* typeSymbol = expression->GetType();
828 if (typeSymbol->GetSymbolType() == SymbolType::classGroupTypeSymbol)
829 {
830 ClassGroupTypeSymbol* classGroup = static_cast<ClassGroupTypeSymbol*>(typeSymbol);
831 typeSymbol = classGroup->GetClass(arity);
832 if (templateIdNode.Primary()->GetNodeType() == sngcm::ast::NodeType::identifierNode)
833 {
834 MapIdentifierToSymbolDefinition(static_cast<sngcm::ast::IdentifierNode*>(templateIdNode.Primary()), typeSymbol);
835 }
836 expression.reset(new BoundTypeExpression(span, moduleId, typeSymbol));
837 }
838 }
839 std::vector<TypeSymbol*> templateArgumentTypes;
840 int n = arity;
841 for (int i = 0; i < n; ++i)
842 {
843 Node* templateArgumentNode = templateIdNode.TemplateArguments()[i];
844 TypeSymbol* type = ResolveType(templateArgumentNode, boundCompileUnit, containerScope);
845 templateArgumentTypes.push_back(type);
846 }
847 if (expression->GetBoundNodeType() == BoundNodeType::boundFunctionGroupExpression)
848 {
849 BoundFunctionGroupExpression* bfge = static_cast<BoundFunctionGroupExpression*>(expression.get());
850 bfge->SetTemplateArgumentTypes(templateArgumentTypes);
851 }
852 else if (expression->GetBoundNodeType() == BoundNodeType::boundMemberExpression)
853 {
854 BoundMemberExpression* bme = static_cast<BoundMemberExpression*>(expression.get());
855 if (bme->Member()->GetBoundNodeType() == BoundNodeType::boundFunctionGroupExpression)
856 {
857 BoundFunctionGroupExpression* bfge = static_cast<BoundFunctionGroupExpression*>(bme->Member());
858 bfge->SetTemplateArgumentTypes(templateArgumentTypes);
859 }
860 else if (bme->Member()->GetBoundNodeType() == BoundNodeType::boundTypeExpression)
861 {
862 TypeSymbol* typeSymbol = bme->Member()->GetType();
863 if (typeSymbol->IsClassTypeSymbol())
864 {
865 ClassTypeSymbol* classTypeSymbol = static_cast<ClassTypeSymbol*>(typeSymbol);
866 if (classTypeSymbol->IsClassTemplate())
867 {
868 int m = classTypeSymbol->TemplateParameters().size();
869 if (n < m)
870 {
871 boundCompileUnit.GetClassTemplateRepository().ResolveDefaultTemplateArguments(templateArgumentTypes, classTypeSymbol, containerScope, templateIdNode.GetSpan(), templateIdNode.ModuleId());
872 }
873 ClassTemplateSpecializationSymbol* classTemplateSpecialization = symbolTable.MakeClassTemplateSpecialization(classTypeSymbol, templateArgumentTypes,
874 templateIdNode.GetSpan(), templateIdNode.ModuleId());
875 if (!classTemplateSpecialization->IsBound())
876 {
877 boundCompileUnit.GetClassTemplateRepository().BindClassTemplateSpecialization(classTemplateSpecialization, containerScope, templateIdNode.GetSpan(), templateIdNode.ModuleId());
878 }
879 expression.reset(new BoundTypeExpression(span, moduleId, classTemplateSpecialization));
880 }
881 }
882 }
883 else
884 {
885 throw Exception("function group or class group expected", templateIdNode.GetSpan(), templateIdNode.ModuleId());
886 }
887 }
888 else if (expression->GetBoundNodeType() == BoundNodeType::boundTypeExpression)
889 {
890 TypeSymbol* typeSymbol = expression->GetType();
891 if (typeSymbol->IsClassTypeSymbol())
892 {
893 ClassTypeSymbol* classTypeSymbol = static_cast<ClassTypeSymbol*>(typeSymbol);
894 if (classTypeSymbol->IsClassTemplate())
895 {
896 int m = classTypeSymbol->TemplateParameters().size();
897 if (n < m)
898 {
899 boundCompileUnit.GetClassTemplateRepository().ResolveDefaultTemplateArguments(templateArgumentTypes, classTypeSymbol, containerScope, templateIdNode.GetSpan(), templateIdNode.ModuleId());
900 }
901 ClassTemplateSpecializationSymbol* classTemplateSpecialization = symbolTable.MakeClassTemplateSpecialization(classTypeSymbol, templateArgumentTypes, templateIdNode.GetSpan(), templateIdNode.ModuleId());
902 if (!classTemplateSpecialization->IsBound())
903 {
904 boundCompileUnit.GetClassTemplateRepository().BindClassTemplateSpecialization(classTemplateSpecialization, containerScope, templateIdNode.GetSpan(), templateIdNode.ModuleId());
905 }
906 expression.reset(new BoundTypeExpression(span, moduleId, classTemplateSpecialization));
907 }
908 }
909 }
910 else
911 {
912 throw Exception("function group or class group expected", templateIdNode.GetSpan(), templateIdNode.ModuleId());
913 }
914 }
915
916 void ExpressionBinder::Visit(ParameterNode& parameterNode)
917 {
918 if (!parameterNode.Id())
919 {
920 throw Exception("parameter not named", parameterNode.GetSpan(), parameterNode.ModuleId());
921 }
922 std::u32string name = parameterNode.Id()->Str();
923 Symbol* symbol = containerScope->Lookup(name, ScopeLookup::this_and_base_and_parent);
924 if (!symbol)
925 {
926 for (const std::std::unique_ptr<FileScope>&fileScope : boundCompileUnit.FileScopes())
927 {
928 symbol = fileScope->Lookup(name);
929 if (symbol)
930 {
931 break;
932 }
933 }
934 }
935 if (symbol)
936 {
937 if (symbol->GetSymbolType() == SymbolType::parameterSymbol)
938 {
939 ParameterSymbol* parameterSymbol = static_cast<ParameterSymbol*>(symbol);
940 expression.reset(new BoundParameter(parameterNode.GetSpan(), parameterNode.ModuleId(), parameterSymbol));
941 }
942 else
943 {
944 throw Exception("symbol '" + ToUtf8(name) + "' does not denote a parameter", parameterNode.GetSpan(), parameterNode.ModuleId());
945 }
946 }
947 else
948 {
949 throw Exception("parameter symbol '" + ToUtf8(name) + "' not found", parameterNode.GetSpan(), parameterNode.ModuleId());
950 }
951 }
952
953 void ExpressionBinder::Visit(DotNode& dotNode)
954 {
955 ContainerScope* prevContainerScope = containerScope;
956 expression = BindExpression(dotNode.Subject(), boundCompileUnit, boundFunction, containerScope, statementBinder, false, true, true, false);
957 IdentifierNode* idNode = boundCompileUnit.GetLatestIdentifier();
958 boundCompileUnit.SetLatestIdentifier(dotNode.MemberId());
959 if (expression->GetBoundNodeType() == BoundNodeType::boundTypeExpression)
960 {
961 TypeSymbol* typeSymbol = expression->GetType();
962 if (typeSymbol->GetSymbolType() == SymbolType::classGroupTypeSymbol)
963 {
964 ClassGroupTypeSymbol* classGroupTypeSymbol = static_cast<ClassGroupTypeSymbol*>(typeSymbol);
965 typeSymbol = classGroupTypeSymbol->GetClass(0);
966 if (GetGlobalFlag(GlobalFlags::cmdoc))
967 {
968 symbolTable.MapSymbol(idNode, typeSymbol);
969 }
970 MapIdentifierToSymbolDefinition(idNode, typeSymbol);
971 if (!typeSymbol)
972 {
973 throw Exception("ordinary class not found from class group '" + ToUtf8(classGroupTypeSymbol->FullName()) + "'", span, moduleId, classGroupTypeSymbol->GetSpan(), classGroupTypeSymbol->SourceModuleId());
974 }
975 else
976 {
977 expression.reset(new BoundTypeExpression(span, moduleId, typeSymbol));
978 }
979 }
980 }
981 if (expression->GetBoundNodeType() == BoundNodeType::boundNamespaceExpression)
982 {
983 BoundNamespaceExpression* bns = static_cast<BoundNamespaceExpression*>(expression.get());
984 containerScope = bns->Ns()->GetContainerScope();
985 std::u32string name = dotNode.MemberId()->Str();
986 Symbol* symbol = containerScope->Lookup(name, ScopeLookup::this_);
987 if (symbol)
988 {
989 BindSymbol(symbol, dotNode.MemberId());
990 if (expression->GetBoundNodeType() == BoundNodeType::boundFunctionGroupExpression)
991 {
992 BoundFunctionGroupExpression* bfe = static_cast<BoundFunctionGroupExpression*>(expression.get());
993 bfe->SetScopeQualified();
994 bfe->SetQualifiedScope(containerScope);
995 }
996 }
997 else
998 {
999 throw Exception("symbol '" + ToUtf8(name) + "' not found from namespace '" + ToUtf8(bns->Ns()->FullName()) + "'", dotNode.MemberId()->GetSpan(), dotNode.MemberId()->ModuleId());
1000 }
1001 }
1002 else
1003 {
1004 TypeSymbol* type = expression->GetType()->PlainType(dotNode.GetSpan(), dotNode.ModuleId());
1005 if (type->IsClassDelegateType())
1006 {
1007 ClassDelegateTypeSymbol* classDelegateType = static_cast<ClassDelegateTypeSymbol*>(type);
1008 type = classDelegateType->ObjectDelegatePairType();
1009 }
1010 if (type->IsClassTypeSymbol())
1011 {
1012 ClassTypeSymbol* classType = static_cast<ClassTypeSymbol*>(type->BaseType());
1013 ContainerScope* scope = classType->GetContainerScope();
1014 std::u32string name = dotNode.MemberId()->Str();
1015 Symbol* symbol = scope->Lookup(name, ScopeLookup::this_and_base);
1016 if (symbol)
1017 {
1018 std::unique_ptr<BoundExpression> classPtr;
1019 BoundExpression* plainClassPtr = expression.get();
1020 if (expression->GetType()->IsClassTypeSymbol())
1021 {
1022 TypeSymbol* type = expression->GetType()->AddPointer(dotNode.GetSpan(), dotNode.ModuleId());
1023 classPtr.reset(new BoundAddressOfExpression(std::unique_ptr<BoundExpression>(expression.release()), type));
1024 }
1025 else if (expression->GetType()->IsReferenceType())
1026 {
1027 TypeSymbol* type = expression->GetType()->RemoveReference(dotNode.GetSpan(), dotNode.ModuleId())->AddPointer(dotNode.GetSpan(), dotNode.ModuleId());
1028 classPtr.reset(new BoundReferenceToPointerExpression(std::unique_ptr<BoundExpression>(expression.release()), type));
1029 }
1030 else
1031 {
1032 classPtr.reset(expression.release());
1033 }
1034 BindSymbol(symbol, dotNode.MemberId());
1035 if (expression->GetBoundNodeType() == BoundNodeType::boundFunctionGroupExpression)
1036 {
1037 BoundFunctionGroupExpression* bfg = static_cast<BoundFunctionGroupExpression*>(expression.get());
1038 if (!classPtr->GetFlag(BoundExpressionFlags::argIsExplicitThisOrBasePtr))
1039 {
1040 Symbol* parent = symbol->Parent();
1041 Assert(parent->GetSymbolType() == SymbolType::classTypeSymbol || parent->GetSymbolType() == SymbolType::classTemplateSpecializationSymbol, "class type expected");
1042 ClassTypeSymbol* owner = static_cast<ClassTypeSymbol*>(parent);
1043 if (classType->HasBaseClass(owner))
1044 {
1045 if (classPtr->GetType()->IsConstType())
1046 {
1047 ArgumentMatch argumentMatch;
1048 classPtr.reset(new BoundConversion(std::unique_ptr<BoundExpression>(classPtr.release()),
1049 boundCompileUnit.GetConversion(classType->AddConst(span, moduleId)->AddPointer(span, moduleId), owner->AddConst(span, moduleId)->AddPointer(span, moduleId), containerScope, boundFunction, dotNode.GetSpan(), dotNode.ModuleId(), argumentMatch)));
1050 }
1051 else
1052 {
1053 ArgumentMatch argumentMatch;
1054 classPtr.reset(new BoundConversion(std::unique_ptr<BoundExpression>(classPtr.release()),
1055 boundCompileUnit.GetConversion(classType->AddPointer(span, moduleId), owner->AddPointer(span, moduleId), containerScope, boundFunction, dotNode.GetSpan(), dotNode.ModuleId(), argumentMatch)));
1056 }
1057 }
1058 }
1059 if (plainClassPtr->GetBoundNodeType() == BoundNodeType::boundTypeExpression)
1060 {
1061 BoundTypeExpression* bte = static_cast<BoundTypeExpression*>(plainClassPtr);
1062 bfg->SetScopeQualified();
1063 bfg->SetQualifiedScope(bte->GetType()->GetContainerScope());
1064 }
1065 BoundMemberExpression* bme = new BoundMemberExpression(dotNode.GetSpan(), dotNode.ModuleId(), std::unique_ptr<BoundExpression>(classPtr.release()), std::move(expression));
1066 expression.reset(bme);
1067 }
1068 else if (expression->GetBoundNodeType() == BoundNodeType::boundMemberVariable)
1069 {
1070 BoundMemberVariable* bmv = static_cast<BoundMemberVariable*>(expression.get());
1071 if (!bmv->GetMemberVariableSymbol()->IsStatic())
1072 {
1073 Symbol* parent = symbol->Parent();
1074 Assert(parent->GetSymbolType() == SymbolType::classTypeSymbol || parent->GetSymbolType() == SymbolType::classTemplateSpecializationSymbol, "class type expected");
1075 ClassTypeSymbol* owner = static_cast<ClassTypeSymbol*>(parent);
1076 if (classType->HasBaseClass(owner))
1077 {
1078 if (classPtr->GetType()->IsConstType())
1079 {
1080 ArgumentMatch argumentMatch;
1081 classPtr.reset(new BoundConversion(std::unique_ptr<BoundExpression>(classPtr.release()),
1082 boundCompileUnit.GetConversion(classType->AddConst(span, moduleId)->AddPointer(span, moduleId), owner->AddConst(span, moduleId)->AddPointer(span, moduleId), containerScope, boundFunction, dotNode.GetSpan(), dotNode.ModuleId(), argumentMatch)));
1083 }
1084 else
1085 {
1086 ArgumentMatch argumentMatch;
1087 classPtr.reset(new BoundConversion(std::unique_ptr<BoundExpression>(classPtr.release()),
1088 boundCompileUnit.GetConversion(classType->AddPointer(span, moduleId), owner->AddPointer(span, moduleId), containerScope, boundFunction, dotNode.GetSpan(), dotNode.ModuleId(), argumentMatch)));
1089 }
1090 }
1091 bmv->SetClassPtr(std::unique_ptr<BoundExpression>(classPtr.release()));
1092 }
1093 }
1094 else if (expression->GetBoundNodeType() != BoundNodeType::boundTypeExpression && expression->GetBoundNodeType() != BoundNodeType::boundConstant)
1095 {
1096 throw Exception("symbol '" + ToUtf8(name) + "' does not denote a function group, member variable, or type", dotNode.MemberId()->GetSpan(), dotNode.MemberId()->ModuleId());
1097 }
1098 }
1099 else
1100 {
1101 throw Exception("symbol '" + ToUtf8(name) + "' not found from class '" + ToUtf8(classType->FullName()) + "'", dotNode.MemberId()->GetSpan(), dotNode.MemberId()->ModuleId());
1102 }
1103 }
1104 else if (type->GetSymbolType() == SymbolType::interfaceTypeSymbol)
1105 {
1106 InterfaceTypeSymbol* interfaceType = static_cast<InterfaceTypeSymbol*>(type->BaseType());
1107 ContainerScope* scope = interfaceType->GetContainerScope();
1108 std::u32string name = dotNode.MemberId()->Str();
1109 Symbol* symbol = scope->Lookup(name, ScopeLookup::this_);
1110 if (symbol)
1111 {
1112 std::unique_ptr<BoundExpression> interfacePtr;
1113 interfacePtr.reset(expression.release());
1114 BindSymbol(symbol, dotNode.MemberId());
1115 if (expression->GetBoundNodeType() == BoundNodeType::boundFunctionGroupExpression)
1116 {
1117 BoundFunctionGroupExpression* bfg = static_cast<BoundFunctionGroupExpression*>(expression.get());
1118 BoundMemberExpression* bme = new BoundMemberExpression(dotNode.GetSpan(), dotNode.ModuleId(), std::unique_ptr<BoundExpression>(interfacePtr.release()), std::move(expression));
1119 expression.reset(bme);
1120 }
1121 else
1122 {
1123 throw Exception("symbol '" + ToUtf8(name) + "' does not denote a function group", dotNode.MemberId()->GetSpan(), dotNode.MemberId()->ModuleId());
1124 }
1125 }
1126 else
1127 {
1128 throw Exception("symbol '" + ToUtf8(name) + "' not found from interface '" + ToUtf8(interfaceType->FullName()) + "'", dotNode.MemberId()->GetSpan(), dotNode.MemberId()->ModuleId());
1129 }
1130 }
1131 else if (type->GetSymbolType() == SymbolType::enumTypeSymbol)
1132 {
1133 EnumTypeSymbol* enumType = static_cast<EnumTypeSymbol*>(type);
1134 ContainerScope* scope = enumType->GetContainerScope();
1135 std::u32string name = dotNode.MemberId()->Str();
1136 Symbol* symbol = scope->Lookup(name);
1137 if (symbol)
1138 {
1139 BindSymbol(symbol, dotNode.MemberId());
1140 }
1141 else
1142 {
1143 throw Exception("symbol '" + ToUtf8(name) + "' not found from enumerated type '" + ToUtf8(enumType->FullName()) + "'", dotNode.MemberId()->GetSpan(), dotNode.MemberId()->ModuleId());
1144 }
1145 }
1146 else if (type->GetSymbolType() == SymbolType::arrayTypeSymbol)
1147 {
1148 ArrayTypeSymbol* arrayType = static_cast<ArrayTypeSymbol*>(type);
1149 ContainerScope* scope = arrayType->GetContainerScope();
1150 std::u32string name = dotNode.MemberId()->Str();
1151 Symbol* symbol = scope->Lookup(name);
1152 if (symbol)
1153 {
1154 std::unique_ptr<BoundExpression> receiverPtr = std::move(expression);
1155 BindSymbol(symbol, dotNode.MemberId());
1156 if (expression->GetBoundNodeType() == BoundNodeType::boundFunctionGroupExpression)
1157 {
1158 BoundFunctionGroupExpression* bfe = static_cast<BoundFunctionGroupExpression*>(expression.get());
1159 bfe->SetScopeQualified();
1160 bfe->SetQualifiedScope(scope);
1161 bfe->SetClassPtr(std::move(receiverPtr));
1162 }
1163 }
1164 else
1165 {
1166 throw Exception("symbol '" + ToUtf8(name) + "' not found from array type '" + ToUtf8(arrayType->FullName()) + "'", dotNode.MemberId()->GetSpan(), dotNode.MemberId()->ModuleId());
1167 }
1168 }
1169 else if (type->IsCharacterPointerType() && expression->GetBoundNodeType() == BoundNodeType::boundLiteral)
1170 {
1171 TypeSymbol* stringFunctionContainer = symbolTable.GetTypeByName(U"@string_functions");
1172 ContainerScope* scope = stringFunctionContainer->GetContainerScope();
1173 std::u32string name = dotNode.MemberId()->Str();
1174 Symbol* symbol = scope->Lookup(name);
1175 if (symbol)
1176 {
1177 std::unique_ptr<BoundExpression> receiverPtr = std::move(expression);
1178 BindSymbol(symbol, dotNode.MemberId());
1179 if (expression->GetBoundNodeType() == BoundNodeType::boundFunctionGroupExpression)
1180 {
1181 BoundFunctionGroupExpression* bfe = static_cast<BoundFunctionGroupExpression*>(expression.get());
1182 bfe->SetScopeQualified();
1183 bfe->SetQualifiedScope(scope);
1184 bfe->SetClassPtr(std::move(receiverPtr));
1185 }
1186 }
1187 else
1188 {
1189 throw Exception("symbol '" + ToUtf8(name) + "' not found from string functions", dotNode.MemberId()->GetSpan(), dotNode.MemberId()->ModuleId());
1190 }
1191 }
1192 else
1193 {
1194 throw Exception("expression must denote a namespace, class type, interface type, array type or an enumerated type type object", dotNode.GetSpan(), dotNode.ModuleId());
1195 }
1196 }
1197 containerScope = prevContainerScope;
1198 }
1199
1200 void ExpressionBinder::BindArrow(Node& node, const std::u32string& name)
1201 {
1202 if (expression->GetType()->IsPointerType())
1203 {
1204 std::unique_ptr<BoundExpression> classPtr(std::move(expression));
1205 if (classPtr->GetType()->BaseType()->IsClassTypeSymbol())
1206 {
1207 ClassTypeSymbol* classType = static_cast<ClassTypeSymbol*>(classPtr->GetType()->BaseType());
1208 ContainerScope* scope = classType->GetContainerScope();
1209 Symbol* symbol = scope->Lookup(name, ScopeLookup::this_and_base);
1210 if (symbol)
1211 {
1212 BindSymbol(symbol, nullptr);
1213 if (expression->GetBoundNodeType() == BoundNodeType::boundFunctionGroupExpression)
1214 {
1215 BoundFunctionGroupExpression* bfg = static_cast<BoundFunctionGroupExpression*>(expression.get());
1216 if (!classPtr->GetFlag(BoundExpressionFlags::argIsExplicitThisOrBasePtr))
1217 {
1218 Symbol* parent = symbol->Parent();
1219 Assert(parent->GetSymbolType() == SymbolType::classTypeSymbol || parent->GetSymbolType() == SymbolType::classTemplateSpecializationSymbol, "class type expected");
1220 ClassTypeSymbol* owner = static_cast<ClassTypeSymbol*>(parent);
1221 if (classType->HasBaseClass(owner))
1222 {
1223 if (classPtr->GetType()->IsConstType())
1224 {
1225 ArgumentMatch argumentMatch;
1226 classPtr.reset(new BoundConversion(std::unique_ptr<BoundExpression>(classPtr.release()),
1227 boundCompileUnit.GetConversion(classType->AddConst(span, moduleId)->AddPointer(span, moduleId), owner->AddConst(span, moduleId)->AddPointer(span, moduleId), containerScope, boundFunction, node.GetSpan(), node.ModuleId(), argumentMatch)));
1228 }
1229 else
1230 {
1231 ArgumentMatch argumentMatch;
1232 classPtr.reset(new BoundConversion(std::unique_ptr<BoundExpression>(classPtr.release()),
1233 boundCompileUnit.GetConversion(classType->AddPointer(span, moduleId), owner->AddPointer(span, moduleId), containerScope, boundFunction, node.GetSpan(), node.ModuleId(), argumentMatch)));
1234 }
1235 }
1236 }
1237 BoundMemberExpression* bme = new BoundMemberExpression(node.GetSpan(), node.ModuleId(), std::unique_ptr<BoundExpression>(classPtr.release()), std::move(expression));
1238 expression.reset(bme);
1239 }
1240 else if (expression->GetBoundNodeType() == BoundNodeType::boundMemberVariable)
1241 {
1242 BoundMemberVariable* bmv = static_cast<BoundMemberVariable*>(expression.get());
1243 if (!bmv->GetMemberVariableSymbol()->IsStatic())
1244 {
1245 Symbol* parent = symbol->Parent();
1246 Assert(parent->GetSymbolType() == SymbolType::classTypeSymbol || parent->GetSymbolType() == SymbolType::classTemplateSpecializationSymbol, "class type expected");
1247 ClassTypeSymbol* owner = static_cast<ClassTypeSymbol*>(parent);
1248 if (classType->HasBaseClass(owner))
1249 {
1250 if (classPtr->GetType()->IsConstType())
1251 {
1252 ArgumentMatch argumentMatch;
1253 classPtr.reset(new BoundConversion(std::unique_ptr<BoundExpression>(classPtr.release()),
1254 boundCompileUnit.GetConversion(classType->AddConst(span, moduleId)->AddPointer(span, moduleId), owner->AddConst(span, moduleId)->AddPointer(span, moduleId), containerScope, boundFunction, node.GetSpan(), node.ModuleId(), argumentMatch)));
1255 }
1256 else
1257 {
1258 ArgumentMatch argumentMatch;
1259 classPtr.reset(new BoundConversion(std::unique_ptr<BoundExpression>(classPtr.release()),
1260 boundCompileUnit.GetConversion(classType->AddPointer(span, moduleId), owner->AddPointer(span, moduleId), containerScope, boundFunction, node.GetSpan(), node.ModuleId(), argumentMatch)));
1261 }
1262 }
1263 bmv->SetClassPtr(std::unique_ptr<BoundExpression>(classPtr.release()));
1264 }
1265 else
1266 {
1267 throw Exception("member variable '" + ToUtf8(bmv->GetMemberVariableSymbol()->FullName()) + +"' is static", node.GetSpan(), node.ModuleId());
1268 }
1269 }
1270 else
1271 {
1272 throw Exception("symbol '" + ToUtf8(name) + "' does not denote a function group or a member variable", node.GetSpan(), node.ModuleId());
1273 }
1274 }
1275 else
1276 {
1277 throw Exception("symbol '" + ToUtf8(name) + "' not found from class '" + ToUtf8(classType->FullName()) + "'", node.GetSpan(), node.ModuleId());
1278 }
1279 }
1280 else
1281 {
1282 throw Exception("type of arrow expression subject must be pointer to class type", node.GetSpan(), node.ModuleId());
1283 }
1284 }
1285 else if (expression->GetType()->IsClassTypeSymbol())
1286 {
1287 TypeSymbol* type = expression->GetType();
1288 TypeSymbol* pointerType = type->AddPointer(node.GetSpan(), node.ModuleId());
1289 LocalVariableSymbol* temporary = boundFunction->GetFunctionSymbol()->CreateTemporary(type, node.GetSpan(), node.ModuleId());
1290 Assert(expression->GetBoundNodeType() == BoundNodeType::boundFunctionCall, "function call expected");
1291 BoundFunctionCall* boundFunctionCall = static_cast<BoundFunctionCall*>(expression.get());
1292 boundFunctionCall->AddArgument(std::unique_ptr<BoundExpression>(new BoundAddressOfExpression(std::unique_ptr<BoundExpression>(new BoundLocalVariable(node.GetSpan(), node.ModuleId(), temporary)), pointerType)));
1293 if (type->IsClassTypeSymbol())
1294 {
1295 ClassTypeSymbol* classType = static_cast<ClassTypeSymbol*>(type);
1296 if (classType->Destructor())
1297 {
1298 std::unique_ptr<BoundFunctionCall> destructorCall(new BoundFunctionCall(span, moduleId, classType->Destructor()));
1299 destructorCall->AddArgument(std::unique_ptr<BoundExpression>(boundFunctionCall->Arguments().back()->Clone()));
1300 boundFunction->AddTemporaryDestructorCall(std::move(destructorCall), boundFunction, containerScope, span, moduleId);
1301 }
1302 }
1303 expression.reset(new BoundAddressOfExpression(std::unique_ptr<BoundExpression>(
1304 new BoundConstructAndReturnTemporaryExpression(std::move(expression), std::unique_ptr<BoundExpression>(new BoundLocalVariable(span, moduleId, temporary)))), pointerType));
1305 BindUnaryOp(expression.release(), node, U"operator->");
1306 BindArrow(node, name);
1307 }
1308 else
1309 {
1310 throw Exception("arrow operator member function must return a class type object or a pointer to a class type object", node.GetSpan(), node.ModuleId());
1311 }
1312 }
1313
1314 void ExpressionBinder::Visit(ArrowNode& arrowNode)
1315 {
1316 arrowNode.Subject()->Accept(*this);
1317 bool argIsExplicitThisOrBasePtr = expression->GetFlag(BoundExpressionFlags::argIsExplicitThisOrBasePtr);
1318 if (expression->GetType()->IsReferenceType() && expression->GetType()->PlainType(arrowNode.GetSpan(), arrowNode.ModuleId())->IsClassTypeSymbol())
1319 {
1320 TypeSymbol* type = expression->GetType()->RemoveReference(arrowNode.GetSpan(), arrowNode.ModuleId())->AddPointer(arrowNode.GetSpan(), arrowNode.ModuleId());
1321 expression.reset(new BoundReferenceToPointerExpression(std::move(expression), type));
1322 }
1323 else if (expression->GetType()->IsReferenceType())
1324 {
1325 TypeSymbol* type = expression->GetType()->RemoveReference(arrowNode.GetSpan(), arrowNode.ModuleId())->AddPointer(arrowNode.GetSpan(), arrowNode.ModuleId());
1326 expression.reset(new BoundAddressOfExpression(std::unique_ptr<BoundExpression>(new BoundDereferenceExpression(std::move(expression), type)), type->AddPointer(arrowNode.GetSpan(), arrowNode.ModuleId())));
1327 }
1328 else
1329 {
1330 TypeSymbol* type = expression->GetType()->AddPointer(arrowNode.GetSpan(), arrowNode.ModuleId());
1331 expression.reset(new BoundAddressOfExpression(std::move(expression), type));
1332 }
1333 BindUnaryOp(expression.release(), arrowNode, U"operator->");
1334 if (argIsExplicitThisOrBasePtr)
1335 {
1336 expression->SetFlag(BoundExpressionFlags::argIsExplicitThisOrBasePtr);
1337 }
1338 BindArrow(arrowNode, arrowNode.MemberId()->Str());
1339 if (argIsExplicitThisOrBasePtr)
1340 {
1341 expression->SetFlag(BoundExpressionFlags::argIsExplicitThisOrBasePtr);
1342 }
1343 boundCompileUnit.SetLatestIdentifier(arrowNode.MemberId());
1344 }
1345
1346 void ExpressionBinder::Visit(DisjunctionNode& disjunctionNode)
1347 {
1348 std::unique_ptr<BoundExpression> left = BindExpression(disjunctionNode.Left(), boundCompileUnit, boundFunction, containerScope, statementBinder);
1349 std::unique_ptr<BoundExpression> right = BindExpression(disjunctionNode.Right(), boundCompileUnit, boundFunction, containerScope, statementBinder);
1350 BoundDisjunction* boundDisjunction = new BoundDisjunction(disjunctionNode.GetSpan(), disjunctionNode.ModuleId(), std::move(left), std::move(right), symbolTable.GetTypeByName(U"bool"));
1351 LocalVariableSymbol* temporary = boundFunction->GetFunctionSymbol()->CreateTemporary(symbolTable.GetTypeByName(U"bool"), disjunctionNode.GetSpan(), disjunctionNode.ModuleId());
1352 boundDisjunction->SetTemporary(new BoundLocalVariable(disjunctionNode.GetSpan(), disjunctionNode.ModuleId(), temporary));
1353 expression.reset(boundDisjunction);
1354 }
1355
1356 void ExpressionBinder::Visit(ConjunctionNode& conjunctionNode)
1357 {
1358 std::unique_ptr<BoundExpression> left = BindExpression(conjunctionNode.Left(), boundCompileUnit, boundFunction, containerScope, statementBinder);
1359 std::unique_ptr<BoundExpression> right = BindExpression(conjunctionNode.Right(), boundCompileUnit, boundFunction, containerScope, statementBinder);
1360 BoundConjunction* boundConjunction = new BoundConjunction(conjunctionNode.GetSpan(), conjunctionNode.ModuleId(), std::move(left), std::move(right), symbolTable.GetTypeByName(U"bool"));
1361 LocalVariableSymbol* temporary = boundFunction->GetFunctionSymbol()->CreateTemporary(symbolTable.GetTypeByName(U"bool"), conjunctionNode.GetSpan(), conjunctionNode.ModuleId());
1362 boundConjunction->SetTemporary(new BoundLocalVariable(conjunctionNode.GetSpan(), conjunctionNode.ModuleId(), temporary));
1363 expression.reset(boundConjunction);
1364 }
1365
1366 void ExpressionBinder::Visit(BitOrNode& bitOrNode)
1367 {
1368 BindBinaryOp(bitOrNode, U"operator|");
1369 }
1370
1371 void ExpressionBinder::Visit(BitXorNode& bitXorNode)
1372 {
1373 BindBinaryOp(bitXorNode, U"operator^");
1374 }
1375
1376 void ExpressionBinder::Visit(BitAndNode& bitAndNode)
1377 {
1378 BindBinaryOp(bitAndNode, U"operator&");
1379 }
1380
1381 void ExpressionBinder::Visit(EqualNode& equalNode)
1382 {
1383 BindBinaryOp(equalNode, U"operator==");
1384 }
1385
1386 void ExpressionBinder::Visit(NotEqualNode& notEqualNode)
1387 {
1388 BindBinaryOp(notEqualNode, U"operator==");
1389 BindUnaryOp(expression.release(), notEqualNode, U"operator!");
1390 }
1391
1392 void ExpressionBinder::Visit(LessNode& lessNode)
1393 {
1394 BindBinaryOp(lessNode, U"operator<");
1395 }
1396
1397 void ExpressionBinder::Visit(GreaterNode& greaterNode)
1398 {
1399 greaterNode.Left()->Accept(*this);
1400 BoundExpression* left = expression.release();
1401 greaterNode.Right()->Accept(*this);
1402 BoundExpression* right = expression.release();
1403 BindBinaryOp(right, left, greaterNode, U"operator<");
1404 }
1405
1406 void ExpressionBinder::Visit(LessOrEqualNode& lessOrEqualNode)
1407 {
1408 lessOrEqualNode.Left()->Accept(*this);
1409 BoundExpression* left = expression.release();
1410 lessOrEqualNode.Right()->Accept(*this);
1411 BoundExpression* right = expression.release();
1412 BindBinaryOp(right, left, lessOrEqualNode, U"operator<");
1413 BindUnaryOp(expression.release(), lessOrEqualNode, U"operator!");
1414 }
1415
1416 void ExpressionBinder::Visit(GreaterOrEqualNode& greaterOrEqualNode)
1417 {
1418 BindBinaryOp(greaterOrEqualNode, U"operator<");
1419 BindUnaryOp(expression.release(), greaterOrEqualNode, U"operator!");
1420 }
1421
1422 void ExpressionBinder::Visit(ShiftLeftNode& shiftLeftNode)
1423 {
1424 BindBinaryOp(shiftLeftNode, U"operator<<");
1425 }
1426
1427 void ExpressionBinder::Visit(ShiftRightNode& shiftRightNode)
1428 {
1429 BindBinaryOp(shiftRightNode, U"operator>>");
1430 }
1431
1432 void ExpressionBinder::Visit(AddNode& addNode)
1433 {
1434 BindBinaryOp(addNode, U"operator+");
1435 }
1436
1437 void ExpressionBinder::Visit(SubNode& subNode)
1438 {
1439 BindBinaryOp(subNode, U"operator-");
1440 }
1441
1442 void ExpressionBinder::Visit(MulNode& mulNode)
1443 {
1444 BindBinaryOp(mulNode, U"operator*");
1445 }
1446
1447 void ExpressionBinder::Visit(DivNode& divNode)
1448 {
1449 BindBinaryOp(divNode, U"operator/");
1450 }
1451
1452 void ExpressionBinder::Visit(RemNode& remNode)
1453 {
1454 BindBinaryOp(remNode, U"operator%");
1455 }
1456
1457 void ExpressionBinder::Visit(NotNode& notNode)
1458 {
1459 BindUnaryOp(notNode, U"operator!");
1460 }
1461
1462 void ExpressionBinder::Visit(UnaryPlusNode& unaryPlusNode)
1463 {
1464 BindUnaryOp(unaryPlusNode, U"operator+");
1465 }
1466
1467 void ExpressionBinder::Visit(UnaryMinusNode& unaryMinusNode)
1468 {
1469 BindUnaryOp(unaryMinusNode, U"operator-");
1470 }
1471
1472 void ExpressionBinder::Visit(PrefixIncrementNode& prefixIncrementNode)
1473 {
1474 if (statementBinder->CompilingThrow())
1475 {
1476 throw Exception("prefix increment in throw expression no allowed", prefixIncrementNode.GetSpan(), prefixIncrementNode.ModuleId());
1477 }
1478 prefixIncrementNode.Subject()->Accept(*this);
1479 if (expression->GetType()->PlainType(prefixIncrementNode.GetSpan(), prefixIncrementNode.ModuleId())->IsClassTypeSymbol())
1480 {
1481 BindUnaryOp(prefixIncrementNode, U"operator++");
1482 }
1483 else
1484 {
1485 if (!inhibitCompile)
1486 {
1487 if (expression->GetType()->IsUnsignedType())
1488 {
1489 CloneContext cloneContext;
1490 AssignmentStatementNode assignmentStatement(prefixIncrementNode.GetSpan(), prefixIncrementNode.ModuleId(), prefixIncrementNode.Subject()->Clone(cloneContext),
1491 new AddNode(prefixIncrementNode.GetSpan(), prefixIncrementNode.ModuleId(), prefixIncrementNode.Subject()->Clone(cloneContext),
1492 new ByteLiteralNode(prefixIncrementNode.GetSpan(), prefixIncrementNode.ModuleId(), 1u)));
1493 statementBinder->CompileStatement(&assignmentStatement, false);
1494 }
1495 else
1496 {
1497 CloneContext cloneContext;
1498 AssignmentStatementNode assignmentStatement(prefixIncrementNode.GetSpan(), prefixIncrementNode.ModuleId(), prefixIncrementNode.Subject()->Clone(cloneContext),
1499 new AddNode(prefixIncrementNode.GetSpan(), prefixIncrementNode.ModuleId(), prefixIncrementNode.Subject()->Clone(cloneContext),
1500 new SByteLiteralNode(prefixIncrementNode.GetSpan(), prefixIncrementNode.ModuleId(), 1)));
1501 statementBinder->CompileStatement(&assignmentStatement, false);
1502 }
1503 }
1504 bool prevInhibitCompile = inhibitCompile;
1505 inhibitCompile = true;
1506 prefixIncrementNode.Subject()->Accept(*this);
1507 inhibitCompile = prevInhibitCompile;
1508 }
1509 }
1510
1511 void ExpressionBinder::Visit(PrefixDecrementNode& prefixDecrementNode)
1512 {
1513 if (statementBinder->CompilingThrow())
1514 {
1515 throw Exception("prefix decrement in throw expression no allowed", prefixDecrementNode.GetSpan(), prefixDecrementNode.ModuleId());
1516 }
1517 prefixDecrementNode.Subject()->Accept(*this);
1518 if (expression->GetType()->PlainType(prefixDecrementNode.GetSpan(), prefixDecrementNode.ModuleId())->IsClassTypeSymbol())
1519 {
1520 BindUnaryOp(prefixDecrementNode, U"operator--");
1521 }
1522 else
1523 {
1524 if (!inhibitCompile)
1525 {
1526 if (expression->GetType()->IsUnsignedType())
1527 {
1528 CloneContext cloneContext;
1529 AssignmentStatementNode assignmentStatement(prefixDecrementNode.GetSpan(), prefixDecrementNode.ModuleId(), prefixDecrementNode.Subject()->Clone(cloneContext),
1530 new SubNode(prefixDecrementNode.GetSpan(), prefixDecrementNode.ModuleId(), prefixDecrementNode.Subject()->Clone(cloneContext),
1531 new ByteLiteralNode(prefixDecrementNode.GetSpan(), prefixDecrementNode.ModuleId(), 1u)));
1532 statementBinder->CompileStatement(&assignmentStatement, false);
1533 }
1534 else
1535 {
1536 CloneContext cloneContext;
1537 AssignmentStatementNode assignmentStatement(prefixDecrementNode.GetSpan(), prefixDecrementNode.ModuleId(), prefixDecrementNode.Subject()->Clone(cloneContext),
1538 new SubNode(prefixDecrementNode.GetSpan(), prefixDecrementNode.ModuleId(), prefixDecrementNode.Subject()->Clone(cloneContext),
1539 new SByteLiteralNode(prefixDecrementNode.GetSpan(), prefixDecrementNode.ModuleId(), 1)));
1540 statementBinder->CompileStatement(&assignmentStatement, false);
1541 }
1542 }
1543 bool prevInhibitCompile = inhibitCompile;
1544 inhibitCompile = true;
1545 prefixDecrementNode.Subject()->Accept(*this);
1546 inhibitCompile = prevInhibitCompile;
1547 }
1548 }
1549
1550 void ExpressionBinder::BindDerefExpr(Node& node)
1551 {
1552 if (expression->GetType()->IsPointerType())
1553 {
1554 TypeSymbol* type = expression->GetType()->RemovePointer(node.GetSpan(), node.ModuleId());
1555 expression.reset(new BoundDereferenceExpression(std::unique_ptr<BoundExpression>(expression.release()), type));
1556 }
1557 else
1558 {
1559 TypeSymbol* plainSubjectType = expression->GetType()->PlainType(node.GetSpan(), node.ModuleId());
1560 if (plainSubjectType->IsClassTypeSymbol())
1561 {
1562 if (expression->GetType()->IsReferenceType())
1563 {
1564 TypeSymbol* type = expression->GetType()->RemoveReference(node.GetSpan(), node.ModuleId())->AddPointer(node.GetSpan(), node.ModuleId());
1565 expression.reset(new BoundReferenceToPointerExpression(std::move(expression), type));
1566 }
1567 else if (expression->GetType()->IsClassTypeSymbol())
1568 {
1569 TypeSymbol* type = expression->GetType()->AddPointer(node.GetSpan(), node.ModuleId());
1570 expression.reset(new BoundAddressOfExpression(std::move(expression), type));
1571 }
1572 BindUnaryOp(expression.release(), node, U"operator*");
1573 }
1574 else
1575 {
1576 throw Exception("dereference needs pointer or class type argument", node.GetSpan(), node.ModuleId());
1577 }
1578 }
1579 }
1580
1581 void ExpressionBinder::Visit(DerefNode& derefNode)
1582 {
1583 derefNode.Subject()->Accept(*this);
1584 BindDerefExpr(derefNode);
1585 }
1586
1587 void ExpressionBinder::Visit(AddrOfNode& addrOfNode)
1588 {
1589 addrOfNode.Subject()->Accept(*this);
1590 if (expression->IsLvalueExpression())
1591 {
1592 if (expression->GetType()->IsReferenceType())
1593 {
1594 TypeSymbol* type = expression->GetType()->RemoveReference(addrOfNode.GetSpan(), addrOfNode.ModuleId())->AddPointer(addrOfNode.GetSpan(), addrOfNode.ModuleId());
1595 expression.reset(new BoundReferenceToPointerExpression(std::unique_ptr<BoundExpression>(expression.release()), type));
1596 }
1597 else
1598 {
1599 TypeSymbol* type = expression->GetType()->AddPointer(addrOfNode.GetSpan(), addrOfNode.ModuleId());
1600 expression.reset(new BoundAddressOfExpression(std::unique_ptr<BoundExpression>(expression.release()), type));
1601 }
1602 }
1603 else
1604 {
1605 throw Exception("cannot take address of " + expression->TypeString(), addrOfNode.GetSpan(), addrOfNode.ModuleId());
1606 }
1607 }
1608
1609 void ExpressionBinder::Visit(ComplementNode& complementNode)
1610 {
1611 BindUnaryOp(complementNode, U"operator~");
1612 }
1613
1614 void ExpressionBinder::Visit(IsNode& isNode)
1615 {
1616 TypeSymbol* rightType = ResolveType(isNode.TargetTypeExpr(), boundCompileUnit, containerScope);
1617 if (rightType->IsPointerType())
1618 {
1619 TypeSymbol* rightBaseType = rightType->RemovePointer(span, moduleId);
1620 if (rightBaseType->IsClassTypeSymbol())
1621 {
1622 ClassTypeSymbol* rightClassType = static_cast<ClassTypeSymbol*>(rightBaseType);
1623 if (rightClassType->IsPolymorphic())
1624 {
1625 std::unique_ptr<BoundExpression> boundExpr = BindExpression(isNode.Expr(), boundCompileUnit, boundFunction, containerScope, statementBinder, false, false, false, false);
1626 TypeSymbol* leftType = boundExpr->GetType();
1627 if (leftType->IsPointerType())
1628 {
1629 TypeSymbol* leftBaseType = leftType->RemovePointer(span, moduleId);
1630 if (leftBaseType->IsClassTypeSymbol())
1631 {
1632 ClassTypeSymbol* leftClassType = static_cast<ClassTypeSymbol*>(leftBaseType);
1633 if (leftClassType->IsPolymorphic())
1634 {
1635 std::unique_ptr<BoundLocalVariable> leftClassIdVar(new BoundLocalVariable(isNode.GetSpan(), isNode.ModuleId(),
1636 boundFunction->GetFunctionSymbol()->CreateTemporary(symbolTable.GetTypeByName(U"ulong"), isNode.GetSpan(), isNode.ModuleId())));
1637 std::unique_ptr<BoundLocalVariable> rightClassIdVar(new BoundLocalVariable(isNode.GetSpan(), isNode.ModuleId(),
1638 boundFunction->GetFunctionSymbol()->CreateTemporary(symbolTable.GetTypeByName(U"ulong"), isNode.GetSpan(), isNode.ModuleId())));
1639 expression.reset(new BoundIsExpression(std::move(boundExpr), rightClassType, symbolTable.GetTypeByName(U"bool"),
1640 std::move(leftClassIdVar), std::move(rightClassIdVar)));
1641 }
1642 else
1643 {
1644 throw Exception("left type in 'is' expression must be pointer to polymorphic class type", isNode.Expr()->GetSpan(), isNode.Expr()->ModuleId());
1645 }
1646 }
1647 else
1648 {
1649 throw Exception("left type in 'is' expression must be pointer to polymorphic class type", isNode.Expr()->GetSpan(), isNode.Expr()->ModuleId());
1650 }
1651 }
1652 else
1653 {
1654 throw Exception("left type in 'is' expression must be pointer to polymorphic class type", isNode.Expr()->GetSpan(), isNode.Expr()->ModuleId());
1655 }
1656 }
1657 else
1658 {
1659 throw Exception("right type in 'is' expression must be pointer to polymorphic class type", isNode.TargetTypeExpr()->GetSpan(), isNode.TargetTypeExpr()->ModuleId());
1660 }
1661 }
1662 else
1663 {
1664 throw Exception("right type in 'is' expression must be be pointer to polymorphic class type", isNode.TargetTypeExpr()->GetSpan(), isNode.TargetTypeExpr()->ModuleId());
1665 }
1666 }
1667 else
1668 {
1669 throw Exception("right type in 'is' expression must be be pointer to polymorphic class type", isNode.TargetTypeExpr()->GetSpan(), isNode.TargetTypeExpr()->ModuleId());
1670 }
1671 }
1672
1673 void ExpressionBinder::Visit(AsNode& asNode)
1674 {
1675 TypeSymbol* rightType = ResolveType(asNode.TargetTypeExpr(), boundCompileUnit, containerScope);
1676 if (rightType->IsPointerType())
1677 {
1678 TypeSymbol* rightBaseType = rightType->RemovePointer(span, moduleId);
1679 if (rightBaseType->IsClassTypeSymbol())
1680 {
1681 ClassTypeSymbol* rightClassType = static_cast<ClassTypeSymbol*>(rightBaseType);
1682 if (rightClassType->IsPolymorphic())
1683 {
1684 std::unique_ptr<BoundExpression> boundExpr = BindExpression(asNode.Expr(), boundCompileUnit, boundFunction, containerScope, statementBinder, false, false, false, false);
1685 TypeSymbol* leftType = boundExpr->GetType();
1686 if (leftType->IsPointerType())
1687 {
1688 TypeSymbol* leftBaseType = leftType->RemovePointer(span, moduleId);
1689 if (leftBaseType->IsClassTypeSymbol())
1690 {
1691 ClassTypeSymbol* leftClassType = static_cast<ClassTypeSymbol*>(leftBaseType);
1692 if (leftClassType->IsPolymorphic())
1693 {
1694 std::unique_ptr<BoundLocalVariable> leftClassIdVar(new BoundLocalVariable(asNode.GetSpan(), asNode.ModuleId(),
1695 boundFunction->GetFunctionSymbol()->CreateTemporary(symbolTable.GetTypeByName(U"ulong"), asNode.GetSpan(), asNode.ModuleId())));
1696 std::unique_ptr<BoundLocalVariable> rightClassIdVar(new BoundLocalVariable(asNode.GetSpan(), asNode.ModuleId(),
1697 boundFunction->GetFunctionSymbol()->CreateTemporary(symbolTable.GetTypeByName(U"ulong"), asNode.GetSpan(), asNode.ModuleId())));
1698 expression.reset(new BoundAsExpression(std::move(boundExpr), rightClassType,
1699 std::unique_ptr<BoundLocalVariable>(new BoundLocalVariable(asNode.GetSpan(), asNode.ModuleId(), boundFunction->GetFunctionSymbol()->CreateTemporary(
1700 rightClassType->AddPointer(asNode.GetSpan(), asNode.ModuleId()), asNode.GetSpan(), asNode.ModuleId()))),
1701 std::move(leftClassIdVar), std::move(rightClassIdVar)));
1702 }
1703 else
1704 {
1705 throw Exception("left type in 'as' expression must be pointer to polymorphic class type", asNode.Expr()->GetSpan(), asNode.Expr()->ModuleId());
1706 }
1707 }
1708 else
1709 {
1710 throw Exception("left type in 'as' expression must be pointer to polymorphic class type", asNode.Expr()->GetSpan(), asNode.Expr()->ModuleId());
1711 }
1712 }
1713 else
1714 {
1715 throw Exception("left type in 'as' expression must be pointer to polymorphic class type", asNode.Expr()->GetSpan(), asNode.Expr()->ModuleId());
1716 }
1717 }
1718 else
1719 {
1720 throw Exception("right type in 'as' expression must be pointer to polymorphic class type", asNode.TargetTypeExpr()->GetSpan(), asNode.TargetTypeExpr()->ModuleId());
1721 }
1722 }
1723 else
1724 {
1725 throw Exception("right type in 'as' expression must be be pointer to polymorphic class type", asNode.TargetTypeExpr()->GetSpan(), asNode.TargetTypeExpr()->ModuleId());
1726 }
1727 }
1728 else
1729 {
1730 throw Exception("right type in 'as' expression must be be pointer to polymorphic class type", asNode.TargetTypeExpr()->GetSpan(), asNode.TargetTypeExpr()->ModuleId());
1731 }
1732 }
1733
1734 void ExpressionBinder::Visit(IndexingNode& indexingNode)
1735 {
1736 indexingNode.Subject()->Accept(*this);
1737 std::unique_ptr<BoundExpression> subject = std::move(expression);
1738 indexingNode.Index()->Accept(*this);
1739 std::unique_ptr<BoundExpression> index = std::move(expression);
1740 TypeSymbol* plainSubjectType = subject->GetType()->PlainType(indexingNode.GetSpan(), indexingNode.ModuleId());
1741 if (plainSubjectType->IsClassTypeSymbol())
1742 {
1743 BindBinaryOp(subject.release(), index.release(), indexingNode, U"operator[]");
1744 }
1745 else if (plainSubjectType->IsPointerType())
1746 {
1747 BindBinaryOp(subject.release(), index.release(), indexingNode, U"operator+");
1748 BindDerefExpr(indexingNode);
1749 }
1750 else if (plainSubjectType->IsArrayType())
1751 {
1752 std::unique_ptr<Value> value = Evaluate(&indexingNode, static_cast<ArrayTypeSymbol*>(plainSubjectType)->ElementType(), containerScope, boundCompileUnit, true, boundFunction,
1753 indexingNode.GetSpan(), indexingNode.ModuleId());
1754 if (value)
1755 {
1756 expression.reset(new BoundLiteral(std::move(value), value->GetType(&symbolTable)));
1757 }
1758 else
1759 {
1760 BindBinaryOp(subject.release(), index.release(), indexingNode, U"operator[]");
1761 }
1762 }
1763 else
1764 {
1765 throw Exception("subscript operator can be applied only to pointer, array or class type subject", indexingNode.GetSpan(), indexingNode.ModuleId());
1766 }
1767 }
1768
1769 void ExpressionBinder::Visit(InvokeNode& invokeNode)
1770 {
1771 IdentifierNode* prevIdentifier = boundCompileUnit.GetLatestIdentifier();
1772 boundCompileUnit.SetLatestIdentifier(nullptr);
1773 invokeNode.Subject()->Accept(*this);
1774 IdentifierNode* invokeId = boundCompileUnit.GetLatestIdentifier();
1775 boundCompileUnit.SetLatestIdentifier(prevIdentifier);
1776 bool argIsExplicitThisOrBasePtr = expression->GetFlag(BoundExpressionFlags::argIsExplicitThisOrBasePtr);
1777 std::vector<std::std::unique_ptr<BoundExpression>>arguments;
1778 std::vector<FunctionScopeLookup> functionScopeLookups;
1779 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parent, containerScope));
1780 FunctionGroupSymbol* functionGroupSymbol = nullptr;
1781 std::vector<TypeSymbol*> templateArgumentTypes;
1782 std::u32string groupName;
1783 bool scopeQualified = false;
1784 LocalVariableSymbol* temporary = nullptr;
1785 if (expression->GetBoundNodeType() == BoundNodeType::boundFunctionGroupExpression)
1786 {
1787 BoundFunctionGroupExpression* bfge = static_cast<BoundFunctionGroupExpression*>(expression.get());
1788 functionGroupSymbol = bfge->FunctionGroup();
1789 templateArgumentTypes = bfge->TemplateArgumentTypes();
1790 groupName = functionGroupSymbol->Name();
1791 if (bfge->IsScopeQualified())
1792 {
1793 functionScopeLookups.clear();
1794 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_, bfge->QualifiedScope()));
1795 scopeQualified = true;
1796 if (bfge->ClassPtr())
1797 {
1798 arguments.push_back(std::unique_ptr<BoundExpression>(bfge->ReleaseClassPtr()));
1799 }
1800 }
1801 }
1802 else if (expression->GetBoundNodeType() == BoundNodeType::boundMemberExpression)
1803 {
1804 BoundMemberExpression* bme = static_cast<BoundMemberExpression*>(expression.get());
1805 if (bme->Member()->GetBoundNodeType() == BoundNodeType::boundFunctionGroupExpression)
1806 {
1807 BoundFunctionGroupExpression* bfge = static_cast<BoundFunctionGroupExpression*>(bme->Member());
1808 functionGroupSymbol = bfge->FunctionGroup();
1809 templateArgumentTypes = bfge->TemplateArgumentTypes();
1810 groupName = functionGroupSymbol->Name();
1811 if (bfge->IsScopeQualified())
1812 {
1813 functionScopeLookups.clear();
1814 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_, bfge->QualifiedScope()));
1815 scopeQualified = true;
1816 }
1817 if (!scopeQualified)
1818 {
1819 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base, bme->ClassPtr()->GetType()->BaseType()->ClassInterfaceOrNsScope()));
1820 }
1821 arguments.push_back(std::unique_ptr<BoundExpression>(bme->ReleaseClassPtr()));
1822 if (arguments.front()->GetType()->PlainType(span, moduleId)->GetSymbolType() == SymbolType::interfaceTypeSymbol)
1823 {
1824 if (arguments.front()->GetType()->IsReferenceType())
1825 {
1826 TypeSymbol* type = arguments.front()->GetType()->RemoveReference(span, moduleId)->AddPointer(span, moduleId);
1827 arguments[0].reset(new BoundReferenceToPointerExpression(std::move(arguments[0]), type));
1828 }
1829 else
1830 {
1831 TypeSymbol* type = arguments.front()->GetType()->AddPointer(span, moduleId);
1832 arguments[0].reset(new BoundAddressOfExpression(std::move(arguments[0]), type));
1833 }
1834 }
1835 }
1836 else
1837 {
1838 throw Exception("invoke cannot be applied to this type of expression", invokeNode.Subject()->GetSpan(), invokeNode.Subject()->ModuleId());
1839 }
1840 }
1841 else if (expression->GetBoundNodeType() == BoundNodeType::boundTypeExpression)
1842 {
1843 TypeSymbol* type = expression->GetType();
1844 if (type->GetSymbolType() == SymbolType::classGroupTypeSymbol)
1845 {
1846 ClassGroupTypeSymbol* classGroup = static_cast<ClassGroupTypeSymbol*>(type);
1847 ClassTypeSymbol* classTypeSymbol = classGroup->GetClass(0);
1848 if (!classTypeSymbol)
1849 {
1850 throw Exception("ordinary class not found from class group '" + ToUtf8(classGroup->FullName()) + "'", span, moduleId, classGroup->GetSpan(), classGroup->SourceModuleId());
1851 }
1852 expression.reset(new BoundTypeExpression(span, moduleId, classTypeSymbol));
1853 type = classTypeSymbol;
1854 }
1855 if (!scopeQualified)
1856 {
1857 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base, type->BaseType()->ClassInterfaceEnumDelegateOrNsScope()));
1858 }
1859 temporary = boundFunction->GetFunctionSymbol()->CreateTemporary(type, invokeNode.GetSpan(), invokeNode.ModuleId());
1860 std::unique_ptr<BoundExpression> addrOfTemporary(new BoundAddressOfExpression(std::unique_ptr<BoundExpression>(new BoundLocalVariable(invokeNode.GetSpan(), invokeNode.ModuleId(), temporary)), type->AddPointer(invokeNode.GetSpan(), invokeNode.ModuleId())));
1861 arguments.push_back(std::move(addrOfTemporary));
1862 groupName = U"@constructor";
1863 if (type->IsClassTypeSymbol())
1864 {
1865 ClassTypeSymbol* classType = static_cast<ClassTypeSymbol*>(type);
1866 if (classType->Destructor())
1867 {
1868 std::unique_ptr<BoundFunctionCall> destructorCall(new BoundFunctionCall(span, moduleId, classType->Destructor()));
1869 destructorCall->AddArgument(std::unique_ptr<BoundExpression>(arguments.back()->Clone()));
1870 boundFunction->AddTemporaryDestructorCall(std::move(destructorCall), boundFunction, containerScope, span, moduleId);
1871 }
1872 }
1873 }
1874 else if (expression->GetType()->PlainType(span, moduleId)->IsClassTypeSymbol())
1875 {
1876 TypeSymbol* type = expression->GetType();
1877 ClassTypeSymbol* classType = static_cast<ClassTypeSymbol*>(type->PlainType(span, moduleId));
1878 groupName = U"operator()";
1879 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_, classType->GetContainerScope()));
1880 if (type->IsReferenceType())
1881 {
1882 expression.reset(new BoundReferenceToPointerExpression(std::move(expression), type->RemoveReference(span, moduleId)->AddPointer(span, moduleId)));
1883 }
1884 else
1885 {
1886 expression.reset(new BoundAddressOfExpression(std::move(expression), type->AddPointer(span, moduleId)));
1887 }
1888 arguments.push_back(std::unique_ptr<BoundExpression>(expression.release()));
1889 }
1890 else if (expression->GetType()->PlainType(span, moduleId)->GetSymbolType() == SymbolType::delegateTypeSymbol)
1891 {
1892 TypeSymbol* type = expression->GetType();
1893 if (type->IsReferenceType())
1894 {
1895 arguments.push_back(std::unique_ptr<BoundExpression>(new BoundDereferenceExpression(std::move(expression), type->RemoveReference(span, moduleId))));
1896 }
1897 else
1898 {
1899 arguments.push_back(std::move(expression));
1900 }
1901 DelegateTypeSymbol* delegateTypeSymbol = static_cast<DelegateTypeSymbol*>(type->BaseType());
1902 int n = invokeNode.Arguments().Count();
1903 if (n != delegateTypeSymbol->Arity())
1904 {
1905 throw Exception("wrong number of arguments for calling delegate type '" + ToUtf8(delegateTypeSymbol->FullName()) + "'", span, moduleId);
1906 }
1907 for (int i = 0; i < n; ++i)
1908 {
1909 TypeSymbol* delegateParameterType = delegateTypeSymbol->Parameters()[i]->GetType();
1910 Node* argument = invokeNode.Arguments()[i];
1911 argument->Accept(*this);
1912 TypeSymbol* argumentType = expression->GetType();
1913 if (!TypesEqual(argumentType, delegateParameterType))
1914 {
1915 if (TypesEqual(argumentType->PlainType(span, moduleId), delegateParameterType->PlainType(span, moduleId)))
1916 {
1917 if (argumentType->IsReferenceType() && !delegateParameterType->IsReferenceType())
1918 {
1919 TypeSymbol* type = argumentType->RemoveReference(span, moduleId);
1920 BoundDereferenceExpression* dereferenceExpression = new BoundDereferenceExpression(std::move(expression), type);
1921 expression.reset(dereferenceExpression);
1922 }
1923 else if (!argumentType->IsReferenceType() && (delegateParameterType->IsReferenceType() || delegateParameterType->IsClassTypeSymbol()))
1924 {
1925 TypeSymbol* type = argumentType->AddLvalueReference(span, moduleId);
1926 BoundAddressOfExpression* addressOfExpression = new BoundAddressOfExpression(std::move(expression), type);
1927 expression.reset(addressOfExpression);
1928 }
1929 }
1930 else
1931 {
1932 ArgumentMatch argumentMatch;
1933 FunctionSymbol* conversionFun = boundCompileUnit.GetConversion(argumentType, delegateParameterType, containerScope, boundFunction, span, moduleId, argumentMatch);
1934 if (conversionFun)
1935 {
1936 BoundConversion* conversion = new BoundConversion(std::move(expression), conversionFun);
1937 expression.reset(conversion);
1938 }
1939 else
1940 {
1941 throw Exception("cannot convert '" + ToUtf8(argumentType->FullName()) + "' type argument to '" + ToUtf8(delegateParameterType->FullName()) + "' type parameter",
1942 argument->GetSpan(), argument->ModuleId(), span, moduleId);
1943 }
1944 }
1945 }
1946 arguments.push_back(std::unique_ptr<BoundExpression>(expression.release()));
1947 }
1948 BoundDelegateCall* delegateCall = new BoundDelegateCall(span, moduleId, delegateTypeSymbol);
1949 for (std::std::unique_ptr<BoundExpression>&argument : arguments)
1950 {
1951 delegateCall->AddArgument(std::move(argument));
1952 }
1953 LocalVariableSymbol* temporary = nullptr;
1954 if (delegateTypeSymbol->ReturnsClassInterfaceOrClassDelegateByValue())
1955 {
1956 TypeSymbol* type = delegateTypeSymbol->ReturnType();
1957 temporary = boundFunction->GetFunctionSymbol()->CreateTemporary(type, invokeNode.GetSpan(), invokeNode.ModuleId());
1958 delegateCall->AddArgument(std::unique_ptr<BoundExpression>(new BoundAddressOfExpression(std::unique_ptr<BoundExpression>(new BoundLocalVariable(span, moduleId, temporary)),
1959 type->AddPointer(invokeNode.GetSpan(), invokeNode.ModuleId()))));
1960 if (type->IsClassTypeSymbol())
1961 {
1962 ClassTypeSymbol* classType = static_cast<ClassTypeSymbol*>(type);
1963 if (classType->Destructor())
1964 {
1965 std::unique_ptr<BoundFunctionCall> destructorCall(new BoundFunctionCall(span, moduleId, classType->Destructor()));
1966 destructorCall->AddArgument(std::unique_ptr<BoundExpression>(delegateCall->Arguments().back()->Clone()));
1967 boundFunction->AddTemporaryDestructorCall(std::move(destructorCall), boundFunction, containerScope, span, moduleId);
1968 }
1969 }
1970 }
1971 expression.reset(delegateCall);
1972 if (temporary)
1973 {
1974 expression.reset(new BoundConstructAndReturnTemporaryExpression(std::move(expression), std::unique_ptr<BoundExpression>(new BoundLocalVariable(span, moduleId, temporary))));
1975 expression->SetFlag(BoundExpressionFlags::bindToRvalueReference);
1976 }
1977 return;
1978 }
1979 else if (expression->GetType()->PlainType(span, moduleId)->GetSymbolType() == SymbolType::classDelegateTypeSymbol)
1980 {
1981 TypeSymbol* type = expression->GetType();
1982 if (type->IsReferenceType())
1983 {
1984 arguments.push_back(std::unique_ptr<BoundExpression>(new BoundReferenceToPointerExpression(std::move(expression), type->RemoveReference(span, moduleId)->AddPointer(span, moduleId))));
1985 }
1986 else
1987 {
1988 arguments.push_back(std::unique_ptr<BoundExpression>(new BoundAddressOfExpression(std::move(expression), type->AddPointer(span, moduleId))));
1989 }
1990 ClassDelegateTypeSymbol* classDelegateTypeSymbol = static_cast<ClassDelegateTypeSymbol*>(type->BaseType());
1991 int n = invokeNode.Arguments().Count();
1992 if (n != classDelegateTypeSymbol->Arity())
1993 {
1994 throw Exception("wrong number of arguments for calling delegate type '" + ToUtf8(classDelegateTypeSymbol->FullName()) + "'", span, moduleId);
1995 }
1996 for (int i = 0; i < n; ++i)
1997 {
1998 TypeSymbol* classDelegateParameterType = classDelegateTypeSymbol->Parameters()[i]->GetType();
1999 Node* argument = invokeNode.Arguments()[i];
2000 argument->Accept(*this);
2001 TypeSymbol* argumentType = expression->GetType();
2002 if (!TypesEqual(argumentType, classDelegateParameterType))
2003 {
2004 if (TypesEqual(argumentType->PlainType(span, moduleId), classDelegateParameterType->PlainType(span, moduleId)))
2005 {
2006 if (argumentType->IsReferenceType() && !classDelegateParameterType->IsReferenceType())
2007 {
2008 TypeSymbol* type = argumentType->RemoveReference(span, moduleId);
2009 BoundDereferenceExpression* dereferenceExpression = new BoundDereferenceExpression(std::move(expression), type);
2010 expression.reset(dereferenceExpression);
2011 }
2012 else if (!argumentType->IsReferenceType() && (classDelegateParameterType->IsReferenceType() || classDelegateParameterType->IsClassTypeSymbol()))
2013 {
2014 TypeSymbol* type = argumentType->AddLvalueReference(span, moduleId);
2015 BoundAddressOfExpression* addressOfExpression = new BoundAddressOfExpression(std::move(expression), type);
2016 expression.reset(addressOfExpression);
2017 }
2018 }
2019 else
2020 {
2021 ArgumentMatch argumentMatch;
2022 FunctionSymbol* conversionFun = boundCompileUnit.GetConversion(argumentType, classDelegateParameterType, containerScope, boundFunction, span, moduleId, argumentMatch);
2023 if (conversionFun)
2024 {
2025 BoundConversion* conversion = new BoundConversion(std::move(expression), conversionFun);
2026 expression.reset(conversion);
2027 }
2028 else
2029 {
2030 throw Exception("cannot convert '" + ToUtf8(argumentType->FullName()) + "' type argument to '" + ToUtf8(classDelegateParameterType->FullName()) + "' type parameter",
2031 argument->GetSpan(), argument->ModuleId(), span, moduleId);
2032 }
2033 }
2034 }
2035 arguments.push_back(std::unique_ptr<BoundExpression>(expression.release()));
2036 }
2037 BoundClassDelegateCall* classDelegateCall = new BoundClassDelegateCall(span, moduleId, classDelegateTypeSymbol);
2038 for (std::std::unique_ptr<BoundExpression>&argument : arguments)
2039 {
2040 classDelegateCall->AddArgument(std::move(argument));
2041 }
2042 LocalVariableSymbol* temporary = nullptr;
2043 if (classDelegateTypeSymbol->ReturnsClassInterfaceOrClassDelegateByValue())
2044 {
2045 TypeSymbol* type = classDelegateTypeSymbol->ReturnType();
2046 temporary = boundFunction->GetFunctionSymbol()->CreateTemporary(type, invokeNode.GetSpan(), invokeNode.ModuleId());
2047 classDelegateCall->AddArgument(std::unique_ptr<BoundExpression>(new BoundAddressOfExpression(std::unique_ptr<BoundExpression>(new BoundLocalVariable(span, moduleId, temporary)),
2048 type->AddPointer(invokeNode.GetSpan(), invokeNode.ModuleId()))));
2049 if (type->IsClassTypeSymbol())
2050 {
2051 ClassTypeSymbol* classType = static_cast<ClassTypeSymbol*>(type);
2052 if (classType->Destructor())
2053 {
2054 std::unique_ptr<BoundFunctionCall> destructorCall(new BoundFunctionCall(span, moduleId, classType->Destructor()));
2055 destructorCall->AddArgument(std::unique_ptr<BoundExpression>(classDelegateCall->Arguments().back()->Clone()));
2056 boundFunction->AddTemporaryDestructorCall(std::move(destructorCall), boundFunction, containerScope, span, moduleId);
2057 }
2058 }
2059 }
2060 expression.reset(classDelegateCall);
2061 if (temporary)
2062 {
2063 expression.reset(new BoundConstructAndReturnTemporaryExpression(std::move(expression), std::unique_ptr<BoundExpression>(new BoundLocalVariable(span, moduleId, temporary))));
2064 expression->SetFlag(BoundExpressionFlags::bindToRvalueReference);
2065 }
2066 return;
2067 }
2068 else
2069 {
2070 throw Exception("invoke cannot be applied to this type of expression", invokeNode.Subject()->GetSpan(), invokeNode.Subject()->ModuleId());
2071 }
2072 int n = invokeNode.Arguments().Count();
2073 for (int i = 0; i < n; ++i)
2074 {
2075 Node* argument = invokeNode.Arguments()[i];
2076 argument->Accept(*this);
2077 if (expression->GetType()->GetSymbolType() != SymbolType::functionGroupTypeSymbol && !scopeQualified)
2078 {
2079 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parent, expression->GetType()->BaseType()->ClassInterfaceEnumDelegateOrNsScope()));
2080 }
2081 arguments.push_back(std::unique_ptr<BoundExpression>(expression.release()));
2082 }
2083 if (!scopeQualified)
2084 {
2085 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::fileScopes, nullptr));
2086 }
2087 std::unique_ptr<Exception> exception;
2088 std::unique_ptr<Exception> thisEx;
2089 std::unique_ptr<Exception> nsEx;
2090 if (!arguments.empty() && arguments[0]->GetFlag(BoundExpressionFlags::argIsExplicitThisOrBasePtr))
2091 {
2092 argIsExplicitThisOrBasePtr = true;
2093 }
2094 std::unique_ptr<BoundFunctionCall> functionCall = ResolveOverload(groupName, containerScope, functionScopeLookups, arguments, boundCompileUnit, boundFunction,
2095 invokeNode.GetSpan(), invokeNode.ModuleId(), OverloadResolutionFlags::dontThrow, templateArgumentTypes, exception);
2096 if (!functionCall)
2097 {
2098 ParameterSymbol* thisParam = boundFunction->GetFunctionSymbol()->GetThisParam();
2099 bool thisParamInserted = false;
2100 if (thisParam)
2101 {
2102 BoundParameter* boundThisParam = new BoundParameter(invokeNode.GetSpan(), invokeNode.ModuleId(), thisParam);
2103 arguments.insert(arguments.begin(), std::unique_ptr<BoundExpression>(boundThisParam));
2104 thisParamInserted = true;
2105 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base, thisParam->GetType()->BaseType()->ClassInterfaceEnumDelegateOrNsScope()));
2106 functionCall = std::move(ResolveOverload(groupName, containerScope, functionScopeLookups, arguments, boundCompileUnit, boundFunction, invokeNode.GetSpan(), invokeNode.ModuleId(),
2107 OverloadResolutionFlags::dontThrow, templateArgumentTypes, thisEx));
2108 }
2109 if (!functionCall)
2110 {
2111 if (thisParamInserted)
2112 {
2113 arguments.erase(arguments.begin());
2114 }
2115 if (!arguments.empty())
2116 {
2117 arguments.erase(arguments.begin());
2118 }
2119 functionCall = std::move(ResolveOverload(groupName, containerScope, functionScopeLookups, arguments, boundCompileUnit, boundFunction, invokeNode.GetSpan(), invokeNode.ModuleId(),
2120 OverloadResolutionFlags::dontThrow, templateArgumentTypes, nsEx));
2121 }
2122 }
2123 if (!functionCall)
2124 {
2125 if (CastOverloadException* castException= dynamic_cast<CastOverloadException*>(exception.get());)
2126 {
2127 throw *exception;
2128 }
2129 if (CastOverloadException* castException= dynamic_cast<CastOverloadException*>(thisEx.get());)
2130 {
2131 throw *thisEx;
2132 }
2133 if (CastOverloadException* castException= dynamic_cast<CastOverloadException*>(nsEx.get());)
2134 {
2135 throw *nsEx;
2136 }
2137 if (CannotBindConstToNonconstOverloadException* bindException= dynamic_cast<CannotBindConstToNonconstOverloadException*>(exception.get());)
2138 {
2139 throw *exception;
2140 }
2141 if (CannotBindConstToNonconstOverloadException* bindException= dynamic_cast<CannotBindConstToNonconstOverloadException*>(thisEx.get());)
2142 {
2143 throw *thisEx;
2144 }
2145 if (CannotBindConstToNonconstOverloadException* bindException= dynamic_cast<CannotBindConstToNonconstOverloadException*>(nsEx.get());)
2146 {
2147 throw *nsEx;
2148 }
2149 if (CannotAssignToConstOverloadException* assignmentException= dynamic_cast<CannotAssignToConstOverloadException*>(exception.get());)
2150 {
2151 throw *exception;
2152 }
2153 if (CannotAssignToConstOverloadException* assignmentException= dynamic_cast<CannotAssignToConstOverloadException*>(thisEx.get());)
2154 {
2155 throw *thisEx;
2156 }
2157 if (CannotAssignToConstOverloadException* assignmentException= dynamic_cast<CannotAssignToConstOverloadException*>(nsEx.get());)
2158 {
2159 throw *nsEx;
2160 }
2161 Exception* ex = exception.get();
2162 if (dynamic_cast<NoViableFunctionException*>(ex) && thisEx)
2163 {
2164 ex = thisEx.get();
2165 }
2166 if (dynamic_cast<NoViableFunctionException*>(ex) && nsEx)
2167 {
2168 ex = nsEx.get();
2169 }
2170 if (ex)
2171 {
2172 throw *ex;
2173 }
2174 else
2175 {
2176 throw Exception("overload resolution failed: overload not found", invokeNode.GetSpan(), invokeNode.ModuleId());
2177 }
2178 }
2179 CheckAccess(boundFunction->GetFunctionSymbol(), functionCall->GetFunctionSymbol());
2180 FunctionSymbol* functionSymbol = functionCall->GetFunctionSymbol();
2181 if (functionSymbol->GetSymbolType() == SymbolType::memberFunctionSymbol && !functionSymbol->IsStatic() && functionSymbol->IsVirtualAbstractOrOverride())
2182 {
2183 if (argIsExplicitThisOrBasePtr)
2184 {
2185 if (functionSymbol->IsAbstract())
2186 {
2187 throw Exception("cannot call abstract member function", span, moduleId, functionSymbol->GetSpan(), functionSymbol->SourceModuleId());
2188 }
2189 }
2190 else
2191 {
2192 functionCall->SetFlag(BoundExpressionFlags::virtualCall);
2193 }
2194 }
2195 if (functionSymbol->ReturnsClassInterfaceOrClassDelegateByValue())
2196 {
2197 TypeSymbol* type = functionSymbol->ReturnType();
2198 temporary = boundFunction->GetFunctionSymbol()->CreateTemporary(type, invokeNode.GetSpan(), invokeNode.ModuleId());
2199 functionCall->AddArgument(std::unique_ptr<BoundExpression>(new BoundAddressOfExpression(std::unique_ptr<BoundExpression>(new BoundLocalVariable(invokeNode.GetSpan(), invokeNode.ModuleId(), temporary)),
2200 type->AddPointer(invokeNode.GetSpan(), invokeNode.ModuleId()))));
2201 if (type->IsClassTypeSymbol())
2202 {
2203 ClassTypeSymbol* classType = static_cast<ClassTypeSymbol*>(type);
2204 if (classType->Destructor())
2205 {
2206 std::unique_ptr<BoundFunctionCall> destructorCall(new BoundFunctionCall(span, moduleId, classType->Destructor()));
2207 destructorCall->AddArgument(std::unique_ptr<BoundExpression>(functionCall->Arguments().back()->Clone()));
2208 boundFunction->AddTemporaryDestructorCall(std::move(destructorCall), boundFunction, containerScope, span, moduleId);
2209 }
2210 }
2211 }
2212 expression.reset(functionCall.release());
2213 if (temporary)
2214 {
2215 expression.reset(new BoundConstructAndReturnTemporaryExpression(std::move(expression), std::unique_ptr<BoundExpression>(new BoundLocalVariable(span, moduleId, temporary))));
2216 expression->SetFlag(BoundExpressionFlags::bindToRvalueReference);
2217 }
2218 if (functionSymbol->IsConstExpr())
2219 {
2220 TypeSymbol* returnType = functionSymbol->ReturnType();
2221 if (returnType && !returnType->IsVoidType())
2222 {
2223 std::unique_ptr<Value> value = Evaluate(&invokeNode, returnType, containerScope, boundCompileUnit, true, boundFunction, span, moduleId);
2224 if (value)
2225 {
2226 TypeSymbol* type = value->GetType(&symbolTable);
2227 BoundLiteral* literal = new BoundLiteral(std::move(value), type);
2228 expression.reset(literal);
2229 }
2230 }
2231 }
2232 else if (functionSymbol->IsCompileTimePrimitiveFunction())
2233 {
2234 TypeSymbol* returnType = functionSymbol->ReturnType();
2235 if (returnType && !returnType->IsVoidType())
2236 {
2237 std::unique_ptr<Value> value = Evaluate(&invokeNode, returnType, containerScope, boundCompileUnit, true, boundFunction, span, moduleId);
2238 if (value)
2239 {
2240 TypeSymbol* type = value->GetType(&symbolTable);
2241 BoundLiteral* literal = new BoundLiteral(std::move(value), type);
2242 expression.reset(literal);
2243 }
2244 }
2245 }
2246 if (functionSymbol->FullName() == U"System.CaptureCurrentException()")
2247 {
2248 if (!statementBinder->InsideCatch())
2249 {
2250 throw Exception("System.CaptureCurrentException() can only be called from inside a catch block", span, moduleId);
2251 }
2252 else
2253 {
2254 expression->SetFlag(BoundExpressionFlags::exceptionCapture);
2255 }
2256 }
2257 if (GetGlobalFlag(GlobalFlags::cmdoc) && functionSymbol->HasSource())
2258 {
2259 symbolTable.MapInvoke(invokeId, functionSymbol);
2260 }
2261 if (functionSymbol->HasSource())
2262 {
2263 MapIdentifierToSymbolDefinition(invokeId, functionSymbol);
2264 }
2265 }
2266
2267 void ExpressionBinder::Visit(PostfixIncrementNode& postfixIncrementNode)
2268 {
2269 if (statementBinder->CompilingThrow())
2270 {
2271 throw Exception("postfix increment in throw expression no allowed", postfixIncrementNode.GetSpan(), postfixIncrementNode.ModuleId());
2272 }
2273 bool prevInhibitCompile = inhibitCompile;
2274 inhibitCompile = true;
2275 postfixIncrementNode.Subject()->Accept(*this);
2276 inhibitCompile = prevInhibitCompile;
2277 if (!inhibitCompile)
2278 {
2279 if (expression->GetType()->PlainType(postfixIncrementNode.GetSpan(), postfixIncrementNode.ModuleId())->IsClassTypeSymbol())
2280 {
2281 CloneContext cloneContext;
2282 ExpressionStatementNode prefixIncrementExpression(postfixIncrementNode.GetSpan(), postfixIncrementNode.ModuleId(), new PrefixIncrementNode(postfixIncrementNode.GetSpan(),
2283 postfixIncrementNode.ModuleId(), postfixIncrementNode.Subject()->Clone(cloneContext)));
2284 statementBinder->CompileStatement(&prefixIncrementExpression, true);
2285 }
2286 else
2287 {
2288 if (expression->GetType()->IsUnsignedType())
2289 {
2290 CloneContext cloneContext;
2291 AssignmentStatementNode assignmentStatement(postfixIncrementNode.GetSpan(), postfixIncrementNode.ModuleId(), postfixIncrementNode.Subject()->Clone(cloneContext),
2292 new AddNode(postfixIncrementNode.GetSpan(), postfixIncrementNode.ModuleId(), postfixIncrementNode.Subject()->Clone(cloneContext),
2293 new ByteLiteralNode(postfixIncrementNode.GetSpan(), postfixIncrementNode.ModuleId(), 1u)));
2294 statementBinder->CompileStatement(&assignmentStatement, true);
2295 }
2296 else
2297 {
2298 CloneContext cloneContext;
2299 AssignmentStatementNode assignmentStatement(postfixIncrementNode.GetSpan(), postfixIncrementNode.ModuleId(), postfixIncrementNode.Subject()->Clone(cloneContext),
2300 new AddNode(postfixIncrementNode.GetSpan(), postfixIncrementNode.ModuleId(), postfixIncrementNode.Subject()->Clone(cloneContext),
2301 new SByteLiteralNode(postfixIncrementNode.GetSpan(), postfixIncrementNode.ModuleId(), 1)));
2302 statementBinder->CompileStatement(&assignmentStatement, true);
2303 }
2304 }
2305 }
2306 postfixIncrementNode.Subject()->Accept(*this);
2307 }
2308
2309 void ExpressionBinder::Visit(PostfixDecrementNode& postfixDecrementNode)
2310 {
2311 if (statementBinder->CompilingThrow())
2312 {
2313 throw Exception("postfix decrement in throw expression no allowed", postfixDecrementNode.GetSpan(), postfixDecrementNode.ModuleId());
2314 }
2315 bool prevInhibitCompile = inhibitCompile;
2316 inhibitCompile = true;
2317 postfixDecrementNode.Subject()->Accept(*this);
2318 inhibitCompile = prevInhibitCompile;
2319 if (!inhibitCompile)
2320 {
2321 if (expression->GetType()->PlainType(postfixDecrementNode.GetSpan(), postfixDecrementNode.ModuleId())->IsClassTypeSymbol())
2322 {
2323 CloneContext cloneContext;
2324 ExpressionStatementNode prefixDecrementExpression(postfixDecrementNode.GetSpan(), postfixDecrementNode.ModuleId(), new PrefixDecrementNode(postfixDecrementNode.GetSpan(),
2325 postfixDecrementNode.ModuleId(), postfixDecrementNode.Subject()->Clone(cloneContext)));
2326 statementBinder->CompileStatement(&prefixDecrementExpression, true);
2327 }
2328 else
2329 {
2330 if (expression->GetType()->IsUnsignedType())
2331 {
2332 CloneContext cloneContext;
2333 AssignmentStatementNode assignmentStatement(postfixDecrementNode.GetSpan(), postfixDecrementNode.ModuleId(), postfixDecrementNode.Subject()->Clone(cloneContext),
2334 new AddNode(postfixDecrementNode.GetSpan(), postfixDecrementNode.ModuleId(), postfixDecrementNode.Subject()->Clone(cloneContext),
2335 new ByteLiteralNode(postfixDecrementNode.GetSpan(), postfixDecrementNode.ModuleId(), 1u)));
2336 statementBinder->CompileStatement(&assignmentStatement, true);
2337 }
2338 else
2339 {
2340 CloneContext cloneContext;
2341 AssignmentStatementNode assignmentStatement(postfixDecrementNode.GetSpan(), postfixDecrementNode.ModuleId(), postfixDecrementNode.Subject()->Clone(cloneContext),
2342 new AddNode(postfixDecrementNode.GetSpan(), postfixDecrementNode.ModuleId(), postfixDecrementNode.Subject()->Clone(cloneContext),
2343 new SByteLiteralNode(postfixDecrementNode.GetSpan(), postfixDecrementNode.ModuleId(), 1)));
2344 statementBinder->CompileStatement(&assignmentStatement, true);
2345 }
2346 }
2347 }
2348 postfixDecrementNode.Subject()->Accept(*this);
2349 }
2350
2351 void ExpressionBinder::Visit(SizeOfNode& sizeOfNode)
2352 {
2353 sizeOfNode.Expression()->Accept(*this);
2354 if (expression->GetBoundNodeType() == BoundNodeType::boundTypeExpression && expression->GetType()->GetSymbolType() == SymbolType::classGroupTypeSymbol)
2355 {
2356 ClassGroupTypeSymbol* classGroup = static_cast<ClassGroupTypeSymbol*>(expression->GetType());
2357 ClassTypeSymbol* classTypeSymbol = classGroup->GetClass(0);
2358 if (classTypeSymbol)
2359 {
2360 expression.reset(new BoundTypeExpression(span, moduleId, classTypeSymbol));
2361 }
2362 else
2363 {
2364 throw Exception("ordinary class not found from class group '" + ToUtf8(classGroup->FullName()) + "'", span, moduleId, classGroup->GetSpan(), classGroup->SourceModuleId());
2365 }
2366 }
2367 expression.reset(new BoundSizeOfExpression(sizeOfNode.GetSpan(), sizeOfNode.ModuleId(), symbolTable.GetTypeByName(U"long"), expression->GetType()->AddPointer(sizeOfNode.GetSpan(), sizeOfNode.ModuleId())));
2368 }
2369
2370 void ExpressionBinder::Visit(TypeNameNode& typeNameNode)
2371 {
2372 bool staticTypeName = typeNameNode.Static();
2373 std::unique_ptr<BoundExpression> expr = BindExpression(typeNameNode.Expression(), boundCompileUnit, boundFunction, containerScope, statementBinder, false, false, true, false);
2374 TypeSymbol* type = expr->GetType();
2375 if (type->GetSymbolType() == SymbolType::classGroupTypeSymbol)
2376 {
2377 ClassGroupTypeSymbol* classGroup = static_cast<ClassGroupTypeSymbol*>(type);
2378 ClassTypeSymbol* classTypeSymbol = classGroup->GetClass(0);
2379 if (!classTypeSymbol)
2380 {
2381 throw Exception("ordinary class not found from class group '" + ToUtf8(classGroup->FullName()) + "'", span, moduleId, classGroup->GetSpan(), classGroup->SourceModuleId());
2382 }
2383 expr.reset(new BoundTypeExpression(span, moduleId, classTypeSymbol));
2384 type = classTypeSymbol;
2385 staticTypeName = true;
2386 }
2387 if (expr->GetType()->PlainType(typeNameNode.GetSpan(), typeNameNode.ModuleId())->IsClassTypeSymbol())
2388 {
2389 ClassTypeSymbol* classType = static_cast<ClassTypeSymbol*>(expr->GetType()->BaseType());
2390 if (!staticTypeName && classType->IsPolymorphic())
2391 {
2392 if (expr->GetBoundNodeType() == BoundNodeType::boundDereferenceExpression)
2393 {
2394 BoundDereferenceExpression* derefExpr = static_cast<BoundDereferenceExpression*>(expr.get());
2395 expr.reset(derefExpr->Subject().release());
2396 }
2397 else
2398 {
2399 TypeSymbol* ptrType = expr->GetType()->AddPointer(typeNameNode.GetSpan(), typeNameNode.ModuleId());
2400 expr.reset(new BoundAddressOfExpression(std::move(expr), ptrType));
2401 }
2402 expression.reset(new BoundTypeNameExpression(std::move(expr), symbolTable.GetTypeByName(U"char")->AddConst(typeNameNode.GetSpan(), typeNameNode.ModuleId())->AddPointer(
2403 typeNameNode.GetSpan(), typeNameNode.ModuleId())));
2404 }
2405 else
2406 {
2407 expression.reset(new BoundLiteral(std::unique_ptr<Value>(new StringValue(typeNameNode.GetSpan(), typeNameNode.ModuleId(), boundCompileUnit.Install(ToUtf8(classType->FullName())),
2408 ToUtf8(classType->FullName()))), symbolTable.GetTypeByName(U"char")->AddConst(typeNameNode.GetSpan(), typeNameNode.ModuleId())->AddPointer(typeNameNode.GetSpan(), typeNameNode.ModuleId())));
2409 }
2410 }
2411 else
2412 {
2413 expression.reset(new BoundLiteral(std::unique_ptr<Value>(new StringValue(typeNameNode.GetSpan(), typeNameNode.ModuleId(), boundCompileUnit.Install(ToUtf8(expr->GetType()->FullName())),
2414 ToUtf8(expr->GetType()->FullName()))), symbolTable.GetTypeByName(U"char")->AddConst(typeNameNode.GetSpan(), typeNameNode.ModuleId())->AddPointer(typeNameNode.GetSpan(), typeNameNode.ModuleId())));
2415 }
2416 }
2417
2418 void ExpressionBinder::Visit(TypeIdNode& typeIdNode)
2419 {
2420 std::unique_ptr<BoundExpression> expr = BindExpression(typeIdNode.Expression(), boundCompileUnit, boundFunction, containerScope, statementBinder, false, false, true, false);
2421 if (expr->GetType()->IsPointerType())
2422 {
2423 TypeSymbol* exprBaseType = expr->GetType()->RemovePointer(span, moduleId);
2424 if (exprBaseType->IsClassTypeSymbol())
2425 {
2426 ClassTypeSymbol* exprClassType = static_cast<ClassTypeSymbol*>(exprBaseType);
2427 if (exprClassType->IsPolymorphic())
2428 {
2429 expression.reset(new BoundTypeIdExpression(std::move(expr), symbolTable.GetTypeByName(U"ulong")));
2430 }
2431 else
2432 {
2433 throw Exception("typeid can be applied to a pointer to a polymorphic class type expression",
2434 typeIdNode.GetSpan(), typeIdNode.ModuleId(), boundFunction->GetFunctionSymbol()->GetSpan(), boundFunction->GetFunctionSymbol()->SourceModuleId());
2435 }
2436 }
2437 else
2438 {
2439 throw Exception("typeid can be applied to a pointer to a polymorphic class type expression",
2440 typeIdNode.GetSpan(), typeIdNode.ModuleId(), boundFunction->GetFunctionSymbol()->GetSpan(), boundFunction->GetFunctionSymbol()->SourceModuleId());
2441 }
2442 }
2443 else
2444 {
2445 throw Exception("typeid can be applied to a pointer to a polymorphic class type expression",
2446 typeIdNode.GetSpan(), typeIdNode.ModuleId(), boundFunction->GetFunctionSymbol()->GetSpan(), boundFunction->GetFunctionSymbol()->SourceModuleId());
2447 }
2448 }
2449
2450 void ExpressionBinder::Visit(CastNode& castNode)
2451 {
2452 TypeSymbol* targetType = ResolveType(castNode.TargetTypeExpr(), boundCompileUnit, containerScope);
2453 castNode.SourceExpr()->Accept(*this);
2454 std::vector<std::std::unique_ptr<BoundExpression>>targetExprArgs;
2455 targetExprArgs.push_back(std::unique_ptr<BoundExpression>(new BoundTypeExpression(castNode.GetSpan(), castNode.ModuleId(), targetType)));
2456 std::vector<FunctionScopeLookup> functionScopeLookups;
2457 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parent, containerScope));
2458 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parent, targetType->BaseType()->ClassInterfaceEnumDelegateOrNsScope()));
2459 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::fileScopes, nullptr));
2460 std::unique_ptr<BoundFunctionCall> castFunctionCall = ResolveOverload(U"@return", containerScope, functionScopeLookups, targetExprArgs, boundCompileUnit, boundFunction, castNode.GetSpan(),
2461 castNode.ModuleId());
2462 std::vector<std::std::unique_ptr<BoundExpression>>castArguments;
2463 castArguments.push_back(std::move(expression));
2464 FunctionMatch functionMatch(castFunctionCall->GetFunctionSymbol());
2465 bool conversionFound = FindConversions(boundCompileUnit, castFunctionCall->GetFunctionSymbol(), castArguments, functionMatch, ConversionType::explicit_, containerScope, boundFunction,
2466 castNode.GetSpan(), castNode.ModuleId());
2467 if (conversionFound)
2468 {
2469 Assert(!functionMatch.argumentMatches.empty(), "argument match expected");
2470 ArgumentMatch& argumentMatch = functionMatch.argumentMatches[0];
2471 if (argumentMatch.preReferenceConversionFlags != OperationFlags::none)
2472 {
2473 if (argumentMatch.preReferenceConversionFlags == OperationFlags::addr)
2474 {
2475 TypeSymbol* type = castArguments[0]->GetType()->AddLvalueReference(span, moduleId);
2476 BoundAddressOfExpression* addressOfExpression = new BoundAddressOfExpression(std::move(castArguments[0]), type);
2477 castArguments[0].reset(addressOfExpression);
2478 }
2479 else if (argumentMatch.preReferenceConversionFlags == OperationFlags::deref)
2480 {
2481 TypeSymbol* type = castArguments[0]->GetType()->RemoveReference(span, moduleId);
2482 BoundDereferenceExpression* dereferenceExpression = new BoundDereferenceExpression(std::move(castArguments[0]), type);
2483 castArguments[0].reset(dereferenceExpression);
2484 }
2485 }
2486 FunctionSymbol* conversionFun = argumentMatch.conversionFun;
2487 if (conversionFun)
2488 {
2489 if (conversionFun->GetSymbolType() == SymbolType::constructorSymbol)
2490 {
2491 BoundFunctionCall* constructorCall = new BoundFunctionCall(span, moduleId, conversionFun);
2492 LocalVariableSymbol* temporary = boundFunction->GetFunctionSymbol()->CreateTemporary(conversionFun->ConversionTargetType(), span, moduleId);
2493 constructorCall->AddArgument(std::unique_ptr<BoundExpression>(new BoundAddressOfExpression(std::unique_ptr<BoundExpression>(new BoundLocalVariable(span, moduleId, temporary)),
2494 conversionFun->ConversionTargetType()->AddPointer(span, moduleId))));
2495 TypeSymbol* conversionTargetType = conversionFun->ConversionTargetType();
2496 if (conversionTargetType->IsClassTypeSymbol())
2497 {
2498 ClassTypeSymbol* classType = static_cast<ClassTypeSymbol*>(conversionTargetType);
2499 if (classType->Destructor())
2500 {
2501 std::unique_ptr<BoundFunctionCall> destructorCall(new BoundFunctionCall(span, moduleId, classType->Destructor()));
2502 destructorCall->AddArgument(std::unique_ptr<BoundExpression>(constructorCall->Arguments()[0]->Clone()));
2503 boundFunction->AddTemporaryDestructorCall(std::move(destructorCall), boundFunction, containerScope, span, moduleId);
2504 }
2505 }
2506 constructorCall->AddArgument(std::move(castArguments[0]));
2507 BoundConstructAndReturnTemporaryExpression* conversion = new BoundConstructAndReturnTemporaryExpression(std::unique_ptr<BoundExpression>(constructorCall),
2508 std::unique_ptr<BoundExpression>(new BoundLocalVariable(span, moduleId, temporary)));
2509 castArguments[0].reset(conversion);
2510 }
2511 else
2512 {
2513 castArguments[0].reset(new BoundConversion(std::unique_ptr<BoundExpression>(castArguments[0].release()), conversionFun));
2514 }
2515 }
2516 if (argumentMatch.postReferenceConversionFlags != OperationFlags::none)
2517 {
2518 if (argumentMatch.postReferenceConversionFlags == OperationFlags::addr)
2519 {
2520 TypeSymbol* type = castArguments[0]->GetType()->AddLvalueReference(span, moduleId);
2521 BoundAddressOfExpression* addressOfExpression = new BoundAddressOfExpression(std::move(castArguments[0]), type);
2522 castArguments[0].reset(addressOfExpression);
2523 }
2524 else if (argumentMatch.postReferenceConversionFlags == OperationFlags::deref)
2525 {
2526 TypeSymbol* type = castArguments[0]->GetType()->RemoveReference(span, moduleId);
2527 BoundDereferenceExpression* dereferenceExpression = new BoundDereferenceExpression(std::move(castArguments[0]), type);
2528 castArguments[0].reset(dereferenceExpression);
2529 }
2530 }
2531 castFunctionCall->SetArguments(std::move(castArguments));
2532 }
2533 else
2534 {
2535 throw Exception("no explicit conversion from '" + ToUtf8(castArguments[0]->GetType()->FullName()) + "' to '" + ToUtf8(targetType->FullName()) + "' exists",
2536 castNode.GetSpan(), castNode.ModuleId(), boundFunction->GetFunctionSymbol()->GetSpan(), boundFunction->GetFunctionSymbol()->SourceModuleId());
2537 }
2538 CheckAccess(boundFunction->GetFunctionSymbol(), castFunctionCall->GetFunctionSymbol());
2539 expression.reset(castFunctionCall.release());
2540 }
2541
2542 void ExpressionBinder::Visit(ConstructNode& constructNode)
2543 {
2544 TypeSymbol* resultType = nullptr;
2545 int n = constructNode.Arguments().Count();
2546 if (n == 0)
2547 {
2548 throw Exception("must supply at least one argument to construct expression", constructNode.GetSpan(), constructNode.ModuleId());
2549 }
2550 std::vector<std::std::unique_ptr<BoundExpression>>arguments;
2551 for (int i = 0; i < n; ++i)
2552 {
2553 Node* argumentNode = constructNode.Arguments()[i];
2554 if (i == 0)
2555 {
2556 CloneContext cloneContext;
2557 CastNode castNode(constructNode.GetSpan(), constructNode.ModuleId(), new PointerNode(constructNode.GetSpan(), constructNode.ModuleId(),
2558 constructNode.TypeExpr()->Clone(cloneContext)), argumentNode->Clone(cloneContext));
2559 castNode.Accept(*this);
2560 resultType = expression->GetType();
2561 if (!resultType->IsPointerType())
2562 {
2563 throw Exception("first argument of a construct expression must be of a pointer type", argumentNode->GetSpan(), argumentNode->ModuleId());
2564 }
2565 if (!resultType->RemovePointer(constructNode.GetSpan(), constructNode.ModuleId())->IsClassTypeSymbol())
2566 {
2567 expression->SetFlag(BoundExpressionFlags::deref);
2568 }
2569 }
2570 else
2571 {
2572 argumentNode->Accept(*this);
2573 }
2574 arguments.push_back(std::move(expression));
2575 }
2576 std::vector<FunctionScopeLookup> functionScopeLookups;
2577 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parent, containerScope));
2578 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parent,
2579 resultType->RemovePointer(constructNode.GetSpan(), constructNode.ModuleId())->ClassInterfaceEnumDelegateOrNsScope()));
2580 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::fileScopes, nullptr));
2581 expression = ResolveOverload(U"@constructor", containerScope, functionScopeLookups, arguments, boundCompileUnit, boundFunction, constructNode.GetSpan(), constructNode.ModuleId());
2582 expression.reset(new BoundConstructExpression(std::move(expression), resultType));
2583 }
2584
2585 void ExpressionBinder::Visit(NewNode& newNode)
2586 {
2587 CloneContext cloneContext;
2588 InvokeNode* invokeMemAlloc = nullptr;
2589 bool memDebug = boundCompileUnit.GetModule().IsSymbolDefined(U"MEM_DEBUG");
2590 if (GetBackEnd() == BackEnd::llvm || GetBackEnd() == BackEnd::cmcpp)
2591 {
2592 if (memDebug)
2593 {
2594 invokeMemAlloc = new InvokeNode(newNode.GetSpan(), newNode.ModuleId(), new IdentifierNode(newNode.GetSpan(), newNode.ModuleId(), U"RtMemAllocInfo"));
2595 }
2596 else
2597 {
2598 invokeMemAlloc = new InvokeNode(newNode.GetSpan(), newNode.ModuleId(), new IdentifierNode(newNode.GetSpan(), newNode.ModuleId(), U"RtMemAlloc"));
2599 }
2600 }
2601 else if (GetBackEnd() == BackEnd::cmsx)
2602 {
2603 invokeMemAlloc = new InvokeNode(newNode.GetSpan(), newNode.ModuleId(), new DotNode(newNode.GetSpan(), newNode.ModuleId(),
2604 new IdentifierNode(newNode.GetSpan(), newNode.ModuleId(), U"System"), new IdentifierNode(newNode.GetSpan(), newNode.ModuleId(), U"MemAlloc")));
2605 }
2606 invokeMemAlloc->AddArgument(new SizeOfNode(newNode.GetSpan(), newNode.ModuleId(), newNode.TypeExpr()->Clone(cloneContext)));
2607 if (memDebug)
2608 {
2609 TypeNameNode* typeNameNode = new TypeNameNode(newNode.GetSpan(), newNode.ModuleId(), newNode.TypeExpr()->Clone(cloneContext));
2610 typeNameNode->SetStatic();
2611 invokeMemAlloc->AddArgument(typeNameNode);
2612 }
2613 CastNode castNode(newNode.GetSpan(), newNode.ModuleId(), new PointerNode(newNode.GetSpan(), newNode.ModuleId(), newNode.TypeExpr()->Clone(cloneContext)), invokeMemAlloc);
2614 castNode.Accept(*this);
2615 std::vector<std::std::unique_ptr<BoundExpression>>arguments;
2616 TypeSymbol* resultType = expression->GetType();
2617 if (!resultType->RemovePointer(newNode.GetSpan(), newNode.ModuleId())->IsClassTypeSymbol())
2618 {
2619 expression->SetFlag(BoundExpressionFlags::deref);
2620 }
2621 arguments.push_back(std::move(expression));
2622 int n = newNode.Arguments().Count();
2623 for (int i = 0; i < n; ++i)
2624 {
2625 newNode.Arguments()[i]->Accept(*this);
2626 arguments.push_back(std::move(expression));
2627 }
2628 std::vector<FunctionScopeLookup> functionScopeLookups;
2629 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parent, containerScope));
2630 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parent, resultType->RemovePointer(newNode.GetSpan(), newNode.ModuleId())->ClassInterfaceEnumDelegateOrNsScope()));
2631 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::fileScopes, nullptr));
2632 expression = ResolveOverload(U"@constructor", containerScope, functionScopeLookups, arguments, boundCompileUnit, boundFunction, newNode.GetSpan(), newNode.ModuleId());
2633 expression.reset(new BoundConstructExpression(std::move(expression), resultType));
2634 }
2635
2636 void ExpressionBinder::Visit(ThisNode& thisNode)
2637 {
2638 ParameterSymbol* thisParam = boundFunction->GetFunctionSymbol()->GetThisParam();
2639 if (thisParam)
2640 {
2641 expression.reset(new BoundParameter(thisNode.GetSpan(), thisNode.ModuleId(), thisParam));
2642 expression->SetFlag(BoundExpressionFlags::argIsExplicitThisOrBasePtr);
2643 }
2644 else
2645 {
2646 throw Exception("'this' can only be used in member function context", thisNode.GetSpan(), thisNode.ModuleId());
2647 }
2648 }
2649
2650 void ExpressionBinder::Visit(BaseNode& baseNode)
2651 {
2652 ParameterSymbol* thisParam = boundFunction->GetFunctionSymbol()->GetThisParam();
2653 if (thisParam)
2654 {
2655 TypeSymbol* thisType = thisParam->GetType()->BaseType();
2656 if (thisType->IsClassTypeSymbol())
2657 {
2658 ClassTypeSymbol* thisClassType = static_cast<ClassTypeSymbol*>(thisType);
2659 if (thisClassType->BaseClass())
2660 {
2661 TypeSymbol* basePointerType = thisClassType->BaseClass()->AddPointer(baseNode.GetSpan(), baseNode.ModuleId());
2662 if (thisParam->GetType()->IsConstType())
2663 {
2664 basePointerType = basePointerType->AddConst(baseNode.GetSpan(), baseNode.ModuleId());
2665 }
2666 ArgumentMatch argumentMatch;
2667 FunctionSymbol* thisAsBaseConversionFunction = boundCompileUnit.GetConversion(thisParam->GetType(), basePointerType, containerScope, boundFunction, baseNode.GetSpan(), baseNode.ModuleId(), argumentMatch);
2668 if (thisAsBaseConversionFunction)
2669 {
2670 expression.reset(new BoundConversion(std::unique_ptr<BoundExpression>(new BoundParameter(baseNode.GetSpan(), baseNode.ModuleId(), thisParam)), thisAsBaseConversionFunction));
2671 expression->SetFlag(BoundExpressionFlags::argIsExplicitThisOrBasePtr);
2672 }
2673 else
2674 {
2675 throw Exception("cannot convert from '" + ToUtf8(thisParam->GetType()->FullName()) + "' to '" + ToUtf8(basePointerType->FullName()) + "'", baseNode.GetSpan(), baseNode.ModuleId());
2676 }
2677 }
2678 else
2679 {
2680 throw Exception("class '" + ToUtf8(thisClassType->FullName()) + "' does not have a base class", baseNode.GetSpan(), baseNode.ModuleId());
2681 }
2682 }
2683 else
2684 {
2685 throw Exception("'base' can only be used in member function context", baseNode.GetSpan(), baseNode.ModuleId());
2686 }
2687 }
2688 else
2689 {
2690 throw Exception("'base' can only be used in member function context", baseNode.GetSpan(), baseNode.ModuleId());
2691 }
2692 }
2693
2694 void ExpressionBinder::Visit(ParenthesizedExpressionNode& parenthesizedExpressionNode)
2695 {
2696 parenthesizedExpressionNode.Subject()->Accept(*this);
2697 }
2698
2699 void ExpressionBinder::Visit(FunctionPtrNode& functionPtrNode)
2700 {
2701 BoundExpression* boundExpression = static_cast<BoundFunctionPtr*>(functionPtrNode.GetBoundExpression());
2702 expression.reset(boundExpression->Clone());
2703 }
2704
2705 std::std::unique_ptr<BoundExpression>BindExpression(Node*node, BoundCompileUnit&boundCompileUnit, BoundFunction*boundFunction, ContainerScope*containerScope, StatementBinder* statementBinder)
2706 {
2707 return BindExpression(node, boundCompileUnit, boundFunction, containerScope, statementBinder, false);
2708 }
2709
2710 std::std::unique_ptr<BoundExpression>BindExpression(Node*node, BoundCompileUnit&boundCompileUnit, BoundFunction*boundFunction, ContainerScope*containerScope, StatementBinder* statementBinder, bool lvalue)
2711 {
2712 return BindExpression(node, boundCompileUnit, boundFunction, containerScope, statementBinder, lvalue, false);
2713 }
2714
2715 std::std::unique_ptr<BoundExpression>BindExpression(Node*node, BoundCompileUnit&boundCompileUnit, BoundFunction*boundFunction, ContainerScope*containerScope, StatementBinder* statementBinder, bool lvalue,
2716 bool acceptFunctionGroupOrMemberExpression)
2717 {
2718 return BindExpression(node, boundCompileUnit, boundFunction, containerScope, statementBinder, lvalue, acceptFunctionGroupOrMemberExpression, false);
2719 }
2720
2721 std::std::unique_ptr<BoundExpression>BindExpression(Node*node, BoundCompileUnit&boundCompileUnit, BoundFunction*boundFunction, ContainerScope*containerScope, StatementBinder* statementBinder, bool lvalue,
2722 bool acceptFunctionGroupOrMemberExpression, bool acceptIncomplete)
2723 {
2724 return BindExpression(node, boundCompileUnit, boundFunction, containerScope, statementBinder, lvalue, acceptFunctionGroupOrMemberExpression, acceptIncomplete, true);
2725 }
2726
2727 std::std::unique_ptr<BoundExpression>BindExpression(Node*node, BoundCompileUnit&boundCompileUnit, BoundFunction*boundFunction, ContainerScope*containerScope, StatementBinder* statementBinder, bool lvalue,
2728 bool acceptFunctionGroupOrMemberExpression, bool acceptIncomplete, bool moveTemporaryDestructorCalls)
2729 {
2730 ExpressionBinder expressionBinder(node->GetSpan(), node->ModuleId(), boundCompileUnit, boundFunction, containerScope, statementBinder, lvalue);
2731 node->Accept(expressionBinder);
2732 std::unique_ptr<BoundExpression> expression = expressionBinder.GetExpression();
2733 if (!expression)
2734 {
2735 throw Exception("could not bind expression", node->GetSpan(), node->ModuleId());
2736 }
2737 if (moveTemporaryDestructorCalls)
2738 {
2739 boundFunction->MoveTemporaryDestructorCallsTo(*expression);
2740 }
2741 if (acceptFunctionGroupOrMemberExpression&&( expression->GetBoundNodeType() == BoundNodeType::boundFunctionGroupExpression || expression->GetBoundNodeType() == BoundNodeType::boundMemberExpression))
2742 {
2743 return expression;
2744 }
2745 if (!acceptIncomplete)
2746 {
2747 if (!expression->IsComplete())
2748 {
2749 throw Exception("incomplete expression", node->GetSpan(), node->ModuleId());
2750 }
2751 }
2752 if (lvalue && !expression->IsLvalueExpression())
2753 {
2754 throw Exception("not an lvalue expression", node->GetSpan(), node->ModuleId());
2755 }
2756 return expression;
2757 }
2758
2759 std::std::unique_ptr<BoundExpression>BindUnaryOp(BoundExpression*operand, Node&node, conststd::u32string&groupName,
2760 BoundCompileUnit& boundCompileUnit, BoundFunction* boundFunction, ContainerScope* containerScope, StatementBinder* statementBinder)
2761 {
2762 ExpressionBinder expressionBinder(node.GetSpan(), node.ModuleId(), boundCompileUnit, boundFunction, containerScope, statementBinder, false);
2763 expressionBinder.BindUnaryOp(operand, node, groupName);
2764 std::unique_ptr<BoundExpression> expression = expressionBinder.GetExpression();
2765 if (!expression)
2766 {
2767 throw Exception("cound not bind expression", node.GetSpan(), node.ModuleId());
2768 }
2769 return expression;
2770 }
2771
2772 } }