1 // =================================
   2 // Copyright (c) 2021 Seppo Laakko
   3 // Distributed under the MIT license
   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& nodeconst 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* operandNode& nodeconst 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& unaryNodeconst std::u32string& groupName);
 142     void BindBinaryOp(BinaryNode& binaryNodeconst std::u32string& groupName);
 143     void BindBinaryOp(BoundExpression* leftBoundExpression* rightNode& nodeconst std::u32string& groupName);
 144     void BindDerefExpr(Node& node);
 145     void BindSymbol(Symbol* symbolIdentifierNode* 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* operandNode& nodeconst 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_parentcontainerScope));
 161     functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parentoperand->GetType()->BaseType()->ClassOrNsScope()));
 162     functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::fileScopesnullptr));
 163     std::vector<TypeSymbol*> templateArgumentTypes;
 164     std::unique_ptr<Exception> exception;
 165     std::unique_ptr<BoundFunctionCall> operatorFunCall = ResolveOverload(groupNamecontainerScopefunctionScopeLookupsargumentsboundCompileUnitboundFunctionnode.GetSpan()node.ModuleId()
 166         OverloadResolutionFlags::dontThrowtemplateArgumentTypesexception);
 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(groupNamecontainerScopefunctionScopeLookupsargumentsboundCompileUnitboundFunctionnode.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(typenode.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(spanmoduleIdclassType->Destructor()));
 202                 destructorCall->AddArgument(std::unique_ptr<BoundExpression>(operatorFunCall->Arguments().back()->Clone()));
 203                 boundFunction->AddTemporaryDestructorCall(std::move(destructorCall)boundFunctioncontainerScopespanmoduleId);
 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& unaryNodeconst std::u32string& groupName)
 216 {
 217     unaryNode.Subject()->Accept(*this);
 218     BoundExpression* operand = expression.release();
 219     BindUnaryOp(operandunaryNodegroupName);
 220 }
 221 
 222 void ExpressionBinder::BindBinaryOp(BinaryNode& binaryNodeconst 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(leftrightbinaryNodegroupName);
 229 }
 230 
 231 void ExpressionBinder::BindBinaryOp(BoundExpression* leftBoundExpression* rightNode& nodeconst 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_parentcontainerScope));
 238     functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parentleft->GetType()->BaseType()->ClassOrNsScope()));
 239     functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parentright->GetType()->BaseType()->ClassOrNsScope()));
 240     functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::fileScopesnullptr));
 241     std::vector<TypeSymbol*> templateArgumentTypes;
 242     std::unique_ptr<Exception> exception;
 243     std::unique_ptr<BoundFunctionCall> operatorFunCall = ResolveOverload(groupNamecontainerScopefunctionScopeLookupsargumentsboundCompileUnitboundFunctionnode.GetSpan()node.ModuleId()
 244         OverloadResolutionFlags::dontThrowtemplateArgumentTypesexception);
 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(groupNamecontainerScopefunctionScopeLookupsargumentsboundCompileUnitboundFunctionnode.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(typenode.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(spanmoduleIdclassType->Destructor()));
 280                 destructorCall->AddArgument(std::unique_ptr<BoundExpression>(operatorFunCall->Arguments().back()->Clone()));
 281                 boundFunction->AddTemporaryDestructorCall(std::move(destructorCall)boundFunctioncontainerScopespanmoduleId);
 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* symbolIdentifierNode* 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(spanmoduleIdfunctionGroupSymbol);
 308             ParameterSymbol* thisParam = boundFunction->GetFunctionSymbol()->GetThisParam();
 309             if (thisParam)
 310             {
 311                 boundFunctionGroupExpression->SetClassPtr(std::unique_ptr<BoundExpression>(new BoundParameter(spnmidthisParam)));
 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(spanmoduleIdclassTypeSymbol));
 321             if (idNode && GetGlobalFlag(GlobalFlags::cmdoc))
 322             {
 323                 symbolTable.MapSymbol(idNodeclassTypeSymbol);
 324             }
 325             if (idNode)
 326             {
 327                 MapIdentifierToSymbolDefinition(idNodeclassTypeSymbol);
 328             }
 329             break;
 330         }
 331         case SymbolType::classGroupTypeSymbol:
 332         {
 333             ClassGroupTypeSymbol* classGroupTypeSymbol = static_cast<ClassGroupTypeSymbol*>(symbol);
 334             expression.reset(new BoundTypeExpression(spanmoduleIdclassGroupTypeSymbol));
 335             ClassTypeSymbol* classTypeSymbol = classGroupTypeSymbol->GetClass(0);
 336             if (idNode && GetGlobalFlag(GlobalFlags::cmdoc) && classTypeSymbol)
 337             {
 338                 symbolTable.MapSymbol(idNodeclassTypeSymbol);
 339             }
 340             if (idNode && classTypeSymbol)
 341             {
 342                 MapIdentifierToSymbolDefinition(idNodeclassTypeSymbol);
 343             }
 344             break;
 345         }
 346         case SymbolType::interfaceTypeSymbol:
 347         {
 348             InterfaceTypeSymbol* interfaceTypeSymbol = static_cast<InterfaceTypeSymbol*>(symbol);
 349             expression.reset(new BoundTypeExpression(spanmoduleIdinterfaceTypeSymbol));
 350             if (idNode && GetGlobalFlag(GlobalFlags::cmdoc))
 351             {
 352                 symbolTable.MapSymbol(idNodeinterfaceTypeSymbol);
 353             }
 354             if (idNode)
 355             {
 356                 MapIdentifierToSymbolDefinition(idNodeinterfaceTypeSymbol);
 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(spanmoduleIddelegateTypeSymbol));
 365             if (idNode && GetGlobalFlag(GlobalFlags::cmdoc))
 366             {
 367                 symbolTable.MapSymbol(idNodedelegateTypeSymbol);
 368             }
 369             if (idNode)
 370             {
 371                 MapIdentifierToSymbolDefinition(idNodedelegateTypeSymbol);
 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(spanmoduleIdclassDelegateTypeSymbol));
 380             if (idNode && GetGlobalFlag(GlobalFlags::cmdoc))
 381             {
 382                 symbolTable.MapSymbol(idNodeclassDelegateTypeSymbol);
 383             }
 384             if (idNode)
 385             {
 386                 MapIdentifierToSymbolDefinition(idNodeclassDelegateTypeSymbol);
 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(spanmoduleIdtypedefSymbol->GetType()));
 395             if (idNode && GetGlobalFlag(GlobalFlags::cmdoc))
 396             {
 397                 symbolTable.MapSymbol(idNodetypedefSymbol);
 398             }
 399             if (idNode)
 400             {
 401                 MapIdentifierToSymbolDefinition(idNodetypedefSymbol);
 402             }
 403             break;
 404         }
 405         case SymbolType::boundTemplateParameterSymbol:
 406         {
 407             BoundTemplateParameterSymbol* boundTemplateParameterSymbol = static_cast<BoundTemplateParameterSymbol*>(symbol);
 408             expression.reset(new BoundTypeExpression(spanmoduleIdboundTemplateParameterSymbol->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(spnmidparameterSymbol));
 416             if (idNode)
 417             {
 418                 MapIdentifierToSymbolDefinition(idNodeparameterSymbol);
 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(spnmidlocalVariableSymbol));
 427             if (idNode)
 428             {
 429                 MapIdentifierToSymbolDefinition(idNodelocalVariableSymbol);
 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(idNodememberVariableSymbol);
 439             }
 440             if (idNode)
 441             {
 442                 MapIdentifierToSymbolDefinition(idNodememberVariableSymbol);
 443             }
 444             FunctionSymbol* currentFuctionSymbol = boundFunction->GetFunctionSymbol();
 445             CheckAccess(currentFuctionSymbolmemberVariableSymbol);
 446             BoundMemberVariable* bmv = new BoundMemberVariable(spnmidmemberVariableSymbol);
 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(spanmoduleId);
 473                         if (thisParam->GetType()->IsConstType())
 474                         {
 475                             thisPointerType = thisPointerType->AddConst(spanmoduleId);
 476                         }
 477                         bmv->SetClassPtr(std::unique_ptr<BoundExpression>(new BoundParameter(spnmidthisParam)));
 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(spanmoduleId);
 488                     TypeSymbol* thisPointerType = thisParam->GetType()->BaseType()->AddPointer(spanmoduleId);
 489                     if (thisParam->GetType()->IsConstType())
 490                     {
 491                         thisPointerType = thisPointerType->AddConst(spanmoduleId);
 492                         containingClassPointerType->AddConst(spanmoduleId);
 493                     }
 494                     ArgumentMatch argumentMatch;
 495                     FunctionSymbol* conversionFun = boundCompileUnit.GetConversion(thisPointerTypecontainingClassPointerTypecontainerScopeboundFunctionspanmoduleIdargumentMatch);
 496                     if (conversionFun)
 497                     {
 498                         bmv->SetClassPtr(std::unique_ptr<BoundExpression>(new BoundConversion(std::unique_ptr<BoundExpression>(new BoundParameter(
 499                             spnmidthisParam))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(spnmidconstantSymbol));
 511             if (idNode && GetGlobalFlag(GlobalFlags::cmdoc))
 512             {
 513                 symbolTable.MapSymbol(idNodeconstantSymbol);
 514             }
 515             if (idNode)
 516             {
 517                 MapIdentifierToSymbolDefinition(idNodeconstantSymbol);
 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(spanmoduleIdenumTypeSymbol));
 526             if (idNode && GetGlobalFlag(GlobalFlags::cmdoc))
 527             {
 528                 symbolTable.MapSymbol(idNodeenumTypeSymbol);
 529             }
 530             if (idNode)
 531             {
 532                 MapIdentifierToSymbolDefinition(idNodeenumTypeSymbol);
 533             }
 534             break;
 535         }
 536         case SymbolType::enumConstantSymbol:
 537         {
 538             EnumConstantSymbol* enumConstantSymbol = static_cast<EnumConstantSymbol*>(symbol);
 539             expression.reset(new BoundEnumConstant(spnmidenumConstantSymbol));
 540             if (idNode && GetGlobalFlag(GlobalFlags::cmdoc))
 541             {
 542                 symbolTable.MapSymbol(idNodeenumConstantSymbol);
 543             }
 544             if (idNode)
 545             {
 546                 MapIdentifierToSymbolDefinition(idNodeenumConstantSymbol);
 547             }
 548             break;
 549         }
 550         case SymbolType::namespaceSymbol:
 551         {
 552             NamespaceSymbol* ns = static_cast<NamespaceSymbol*>(symbol);
 553             expression.reset(new BoundNamespaceExpression(spanmoduleIdns));
 554             if (idNode)
 555             {
 556                 MapIdentifierToSymbolDefinition(idNodens);
 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"spanmoduleId);
 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()spanmoduleIdglobalVariableSymbol->GetSpan()globalVariableSymbol->SourceModuleId());
 578                 }
 579                 else
 580                 {
 581                     expression.reset(new BoundGlobalVariable(spnmidglobalVariableSymbol));
 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                     spanmoduleId);
 603             }
 604             if (idNode)
 605             {
 606                 if (globalVariableSymbol)
 607                 {
 608                     MapIdentifierToSymbolDefinition(idNodeglobalVariableSymbol);
 609                 }
 610             }
 611             break;
 612         }
 613         default:
 614         {
 615             throw Exception("could not bind '" + ToUtf8(symbol->FullName()) + "'"spanmoduleIdsymbol->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(nameScopeLookup::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(spanmoduleIdtypeSymbol));
 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(templateArgumentNodeboundCompileUnitcontainerScope);
 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(templateArgumentTypesclassTypeSymbolcontainerScopetemplateIdNode.GetSpan()templateIdNode.ModuleId());
 872                     }
 873                     ClassTemplateSpecializationSymbol* classTemplateSpecialization = symbolTable.MakeClassTemplateSpecialization(classTypeSymboltemplateArgumentTypes
 874                         templateIdNode.GetSpan()templateIdNode.ModuleId());
 875                     if (!classTemplateSpecialization->IsBound())
 876                     {
 877                         boundCompileUnit.GetClassTemplateRepository().BindClassTemplateSpecialization(classTemplateSpecializationcontainerScopetemplateIdNode.GetSpan()templateIdNode.ModuleId());
 878                     }
 879                     expression.reset(new BoundTypeExpression(spanmoduleIdclassTemplateSpecialization));
 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(templateArgumentTypesclassTypeSymbolcontainerScopetemplateIdNode.GetSpan()templateIdNode.ModuleId());
 900                 }
 901                 ClassTemplateSpecializationSymbol* classTemplateSpecialization = symbolTable.MakeClassTemplateSpecialization(classTypeSymboltemplateArgumentTypestemplateIdNode.GetSpan()templateIdNode.ModuleId());
 902                 if (!classTemplateSpecialization->IsBound())
 903                 {
 904                     boundCompileUnit.GetClassTemplateRepository().BindClassTemplateSpecialization(classTemplateSpecializationcontainerScopetemplateIdNode.GetSpan()templateIdNode.ModuleId());
 905                 }
 906                 expression.reset(new BoundTypeExpression(spanmoduleIdclassTemplateSpecialization));
 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(nameScopeLookup::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()boundCompileUnitboundFunctioncontainerScopestatementBinderfalsetruetruefalse);
 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(idNodetypeSymbol);
 969             }
 970             MapIdentifierToSymbolDefinition(idNodetypeSymbol);
 971             if (!typeSymbol)
 972             {
 973                 throw Exception("ordinary class not found from class group '" + ToUtf8(classGroupTypeSymbol->FullName()) + "'"spanmoduleIdclassGroupTypeSymbol->GetSpan()classGroupTypeSymbol->SourceModuleId());
 974             }
 975             else
 976             {
 977                 expression.reset(new BoundTypeExpression(spanmoduleIdtypeSymbol));
 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(nameScopeLookup::this_);
 987         if (symbol)
 988         {
 989             BindSymbol(symboldotNode.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(nameScopeLookup::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(symboldotNode.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(spanmoduleId)->AddPointer(spanmoduleId)owner->AddConst(spanmoduleId)->AddPointer(spanmoduleId)containerScopeboundFunctiondotNode.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(spanmoduleId)owner->AddPointer(spanmoduleId)containerScopeboundFunctiondotNode.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(spanmoduleId)->AddPointer(spanmoduleId)owner->AddConst(spanmoduleId)->AddPointer(spanmoduleId)containerScopeboundFunctiondotNode.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(spanmoduleId)owner->AddPointer(spanmoduleId)containerScopeboundFunctiondotNode.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(nameScopeLookup::this_);
1110             if (symbol)
1111             {
1112                 std::unique_ptr<BoundExpression> interfacePtr;
1113                 interfacePtr.reset(expression.release());
1114                 BindSymbol(symboldotNode.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(symboldotNode.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(symboldotNode.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(symboldotNode.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& nodeconst 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(nameScopeLookup::this_and_base);
1210             if (symbol)
1211             {
1212                 BindSymbol(symbolnullptr);
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(spanmoduleId)->AddPointer(spanmoduleId)owner->AddConst(spanmoduleId)->AddPointer(spanmoduleId)containerScopeboundFunctionnode.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(spanmoduleId)owner->AddPointer(spanmoduleId)containerScopeboundFunctionnode.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(spanmoduleId)->AddPointer(spanmoduleId)owner->AddConst(spanmoduleId)->AddPointer(spanmoduleId)containerScopeboundFunctionnode.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(spanmoduleId)owner->AddPointer(spanmoduleId)containerScopeboundFunctionnode.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(typenode.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(spanmoduleIdclassType->Destructor()));
1299                 destructorCall->AddArgument(std::unique_ptr<BoundExpression>(boundFunctionCall->Arguments().back()->Clone()));
1300                 boundFunction->AddTemporaryDestructorCall(std::move(destructorCall)boundFunctioncontainerScopespanmoduleId);
1301             }
1302         }
1303         expression.reset(new BoundAddressOfExpression(std::unique_ptr<BoundExpression>(
1304             new BoundConstructAndReturnTemporaryExpression(std::move(expression)std::unique_ptr<BoundExpression>(new BoundLocalVariable(spanmoduleIdtemporary))))pointerType));
1305         BindUnaryOp(expression.release()nodeU"operator->");
1306         BindArrow(nodename);
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()arrowNodeU"operator->");
1334     if (argIsExplicitThisOrBasePtr)
1335     {
1336         expression->SetFlag(BoundExpressionFlags::argIsExplicitThisOrBasePtr);
1337     }
1338     BindArrow(arrowNodearrowNode.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()boundCompileUnitboundFunctioncontainerScopestatementBinder);
1349     std::unique_ptr<BoundExpression> right = BindExpression(disjunctionNode.Right()boundCompileUnitboundFunctioncontainerScopestatementBinder);
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()boundCompileUnitboundFunctioncontainerScopestatementBinder);
1359     std::unique_ptr<BoundExpression> right = BindExpression(conjunctionNode.Right()boundCompileUnitboundFunctioncontainerScopestatementBinder);
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(bitOrNodeU"operator|");
1369 }
1370 
1371 void ExpressionBinder::Visit(BitXorNode& bitXorNode)
1372 {
1373     BindBinaryOp(bitXorNodeU"operator^");
1374 }
1375 
1376 void ExpressionBinder::Visit(BitAndNode& bitAndNode)
1377 {
1378     BindBinaryOp(bitAndNodeU"operator&");
1379 }
1380 
1381 void ExpressionBinder::Visit(EqualNode& equalNode)
1382 {
1383     BindBinaryOp(equalNodeU"operator==");
1384 }
1385 
1386 void ExpressionBinder::Visit(NotEqualNode& notEqualNode)
1387 {
1388     BindBinaryOp(notEqualNodeU"operator==");
1389     BindUnaryOp(expression.release()notEqualNodeU"operator!");
1390 }
1391 
1392 void ExpressionBinder::Visit(LessNode& lessNode)
1393 {
1394     BindBinaryOp(lessNodeU"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(rightleftgreaterNodeU"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(rightleftlessOrEqualNodeU"operator<");
1413     BindUnaryOp(expression.release()lessOrEqualNodeU"operator!");
1414 }
1415 
1416 void ExpressionBinder::Visit(GreaterOrEqualNode& greaterOrEqualNode)
1417 {
1418     BindBinaryOp(greaterOrEqualNodeU"operator<");
1419     BindUnaryOp(expression.release()greaterOrEqualNodeU"operator!");
1420 }
1421 
1422 void ExpressionBinder::Visit(ShiftLeftNode& shiftLeftNode)
1423 {
1424     BindBinaryOp(shiftLeftNodeU"operator<<");
1425 }
1426 
1427 void ExpressionBinder::Visit(ShiftRightNode& shiftRightNode)
1428 {
1429     BindBinaryOp(shiftRightNodeU"operator>>");
1430 }
1431 
1432 void ExpressionBinder::Visit(AddNode& addNode)
1433 {
1434     BindBinaryOp(addNodeU"operator+");
1435 }
1436 
1437 void ExpressionBinder::Visit(SubNode& subNode)
1438 {
1439     BindBinaryOp(subNodeU"operator-");
1440 }
1441 
1442 void ExpressionBinder::Visit(MulNode& mulNode)
1443 {
1444     BindBinaryOp(mulNodeU"operator*");
1445 }
1446 
1447 void ExpressionBinder::Visit(DivNode& divNode)
1448 {
1449     BindBinaryOp(divNodeU"operator/");
1450 }
1451 
1452 void ExpressionBinder::Visit(RemNode& remNode)
1453 {
1454     BindBinaryOp(remNodeU"operator%");
1455 }
1456 
1457 void ExpressionBinder::Visit(NotNode& notNode)
1458 {
1459     BindUnaryOp(notNodeU"operator!");
1460 }
1461 
1462 void ExpressionBinder::Visit(UnaryPlusNode& unaryPlusNode)
1463 {
1464     BindUnaryOp(unaryPlusNodeU"operator+");
1465 }
1466 
1467 void ExpressionBinder::Visit(UnaryMinusNode& unaryMinusNode)
1468 {
1469     BindUnaryOp(unaryMinusNodeU"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(prefixIncrementNodeU"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(&assignmentStatementfalse);
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(&assignmentStatementfalse);
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(prefixDecrementNodeU"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(&assignmentStatementfalse);
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(&assignmentStatementfalse);
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()nodeU"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(complementNodeU"operator~");
1612 }
1613 
1614 void ExpressionBinder::Visit(IsNode& isNode)
1615 {
1616     TypeSymbol* rightType = ResolveType(isNode.TargetTypeExpr()boundCompileUnitcontainerScope);
1617     if (rightType->IsPointerType())
1618     {
1619         TypeSymbol* rightBaseType = rightType->RemovePointer(spanmoduleId);
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()boundCompileUnitboundFunctioncontainerScopestatementBinderfalsefalsefalsefalse);
1626                 TypeSymbol* leftType = boundExpr->GetType();
1627                 if (leftType->IsPointerType())
1628                 {
1629                     TypeSymbol* leftBaseType = leftType->RemovePointer(spanmoduleId);
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)rightClassTypesymbolTable.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()boundCompileUnitcontainerScope);
1676     if (rightType->IsPointerType())
1677     {
1678         TypeSymbol* rightBaseType = rightType->RemovePointer(spanmoduleId);
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()boundCompileUnitboundFunctioncontainerScopestatementBinderfalsefalsefalsefalse);
1685                 TypeSymbol* leftType = boundExpr->GetType();
1686                 if (leftType->IsPointerType())
1687                 {
1688                     TypeSymbol* leftBaseType = leftType->RemovePointer(spanmoduleId);
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()indexingNodeU"operator[]");
1744     }
1745     else  if (plainSubjectType->IsPointerType())
1746     {
1747         BindBinaryOp(subject.release()index.release()indexingNodeU"operator+");
1748         BindDerefExpr(indexingNode);
1749     }
1750     else if (plainSubjectType->IsArrayType())
1751     {
1752         std::unique_ptr<Value> value = Evaluate(&indexingNodestatic_cast<ArrayTypeSymbol*>(plainSubjectType)->ElementType()containerScopeboundCompileUnittrueboundFunction
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()indexingNodeU"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_parentcontainerScope));
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_basebme->ClassPtr()->GetType()->BaseType()->ClassInterfaceOrNsScope()));
1820             }
1821             arguments.push_back(std::unique_ptr<BoundExpression>(bme->ReleaseClassPtr()));
1822             if (arguments.front()->GetType()->PlainType(spanmoduleId)->GetSymbolType() == SymbolType::interfaceTypeSymbol)
1823             {
1824                 if (arguments.front()->GetType()->IsReferenceType())
1825                 {
1826                     TypeSymbol* type = arguments.front()->GetType()->RemoveReference(spanmoduleId)->AddPointer(spanmoduleId);
1827                     arguments[0].reset(new BoundReferenceToPointerExpression(std::move(arguments[0])type));
1828                 }
1829                 else
1830                 {
1831                     TypeSymbol* type = arguments.front()->GetType()->AddPointer(spanmoduleId);
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()) + "'"spanmoduleIdclassGroup->GetSpan()classGroup->SourceModuleId());
1851             }
1852             expression.reset(new BoundTypeExpression(spanmoduleIdclassTypeSymbol));
1853             type = classTypeSymbol;
1854         }
1855         if (!scopeQualified)
1856         {
1857             functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_basetype->BaseType()->ClassInterfaceEnumDelegateOrNsScope()));
1858         }
1859         temporary = boundFunction->GetFunctionSymbol()->CreateTemporary(typeinvokeNode.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(spanmoduleIdclassType->Destructor()));
1869                 destructorCall->AddArgument(std::unique_ptr<BoundExpression>(arguments.back()->Clone()));
1870                 boundFunction->AddTemporaryDestructorCall(std::move(destructorCall)boundFunctioncontainerScopespanmoduleId);
1871             }
1872         }
1873     }
1874     else if (expression->GetType()->PlainType(spanmoduleId)->IsClassTypeSymbol())
1875     {
1876         TypeSymbol* type = expression->GetType();
1877         ClassTypeSymbol* classType = static_cast<ClassTypeSymbol*>(type->PlainType(spanmoduleId));
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(spanmoduleId)->AddPointer(spanmoduleId)));
1883         }
1884         else
1885         {
1886             expression.reset(new BoundAddressOfExpression(std::move(expression)type->AddPointer(spanmoduleId)));
1887         }
1888         arguments.push_back(std::unique_ptr<BoundExpression>(expression.release()));
1889     }
1890     else if (expression->GetType()->PlainType(spanmoduleId)->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(spanmoduleId))));
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()) + "'"spanmoduleId);
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(argumentTypedelegateParameterType))
1914             {
1915                 if (TypesEqual(argumentType->PlainType(spanmoduleId)delegateParameterType->PlainType(spanmoduleId)))
1916                 {
1917                     if (argumentType->IsReferenceType() && !delegateParameterType->IsReferenceType())
1918                     {
1919                         TypeSymbol* type = argumentType->RemoveReference(spanmoduleId);
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(spanmoduleId);
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(argumentTypedelegateParameterTypecontainerScopeboundFunctionspanmoduleIdargumentMatch);
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()spanmoduleId);
1943                     }
1944                 }
1945             }
1946             arguments.push_back(std::unique_ptr<BoundExpression>(expression.release()));
1947         }
1948         BoundDelegateCall* delegateCall = new BoundDelegateCall(spanmoduleIddelegateTypeSymbol);
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(typeinvokeNode.GetSpan()invokeNode.ModuleId());
1958             delegateCall->AddArgument(std::unique_ptr<BoundExpression>(new BoundAddressOfExpression(std::unique_ptr<BoundExpression>(new BoundLocalVariable(spanmoduleIdtemporary))
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(spanmoduleIdclassType->Destructor()));
1966                     destructorCall->AddArgument(std::unique_ptr<BoundExpression>(delegateCall->Arguments().back()->Clone()));
1967                     boundFunction->AddTemporaryDestructorCall(std::move(destructorCall)boundFunctioncontainerScopespanmoduleId);
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(spanmoduleIdtemporary))));
1975             expression->SetFlag(BoundExpressionFlags::bindToRvalueReference);
1976         }
1977         return;
1978     }
1979     else if (expression->GetType()->PlainType(spanmoduleId)->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(spanmoduleId)->AddPointer(spanmoduleId))));
1985         }
1986         else
1987         {
1988             arguments.push_back(std::unique_ptr<BoundExpression>(new BoundAddressOfExpression(std::move(expression)type->AddPointer(spanmoduleId))));
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()) + "'"spanmoduleId);
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(argumentTypeclassDelegateParameterType))
2003             {
2004                 if (TypesEqual(argumentType->PlainType(spanmoduleId)classDelegateParameterType->PlainType(spanmoduleId)))
2005                 {
2006                     if (argumentType->IsReferenceType() && !classDelegateParameterType->IsReferenceType())
2007                     {
2008                         TypeSymbol* type = argumentType->RemoveReference(spanmoduleId);
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(spanmoduleId);
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(argumentTypeclassDelegateParameterTypecontainerScopeboundFunctionspanmoduleIdargumentMatch);
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()spanmoduleId);
2032                     }
2033                 }
2034             }
2035             arguments.push_back(std::unique_ptr<BoundExpression>(expression.release()));
2036         }
2037         BoundClassDelegateCall* classDelegateCall = new BoundClassDelegateCall(spanmoduleIdclassDelegateTypeSymbol);
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(typeinvokeNode.GetSpan()invokeNode.ModuleId());
2047             classDelegateCall->AddArgument(std::unique_ptr<BoundExpression>(new BoundAddressOfExpression(std::unique_ptr<BoundExpression>(new BoundLocalVariable(spanmoduleIdtemporary))
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(spanmoduleIdclassType->Destructor()));
2055                     destructorCall->AddArgument(std::unique_ptr<BoundExpression>(classDelegateCall->Arguments().back()->Clone()));
2056                     boundFunction->AddTemporaryDestructorCall(std::move(destructorCall)boundFunctioncontainerScopespanmoduleId);
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(spanmoduleIdtemporary))));
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_parentexpression->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::fileScopesnullptr));
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(groupNamecontainerScopefunctionScopeLookupsargumentsboundCompileUnitboundFunction
2095         invokeNode.GetSpan()invokeNode.ModuleId()OverloadResolutionFlags::dontThrowtemplateArgumentTypesexception);
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_basethisParam->GetType()->BaseType()->ClassInterfaceEnumDelegateOrNsScope()));
2106             functionCall = std::move(ResolveOverload(groupNamecontainerScopefunctionScopeLookupsargumentsboundCompileUnitboundFunctioninvokeNode.GetSpan()invokeNode.ModuleId()
2107                 OverloadResolutionFlags::dontThrowtemplateArgumentTypesthisEx));
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(groupNamecontainerScopefunctionScopeLookupsargumentsboundCompileUnitboundFunctioninvokeNode.GetSpan()invokeNode.ModuleId()
2120                 OverloadResolutionFlags::dontThrowtemplateArgumentTypesnsEx));
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"spanmoduleIdfunctionSymbol->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(typeinvokeNode.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(spanmoduleIdclassType->Destructor()));
2207                 destructorCall->AddArgument(std::unique_ptr<BoundExpression>(functionCall->Arguments().back()->Clone()));
2208                 boundFunction->AddTemporaryDestructorCall(std::move(destructorCall)boundFunctioncontainerScopespanmoduleId);
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(spanmoduleIdtemporary))));
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(&invokeNodereturnTypecontainerScopeboundCompileUnittrueboundFunctionspanmoduleId);
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(&invokeNodereturnTypecontainerScopeboundCompileUnittrueboundFunctionspanmoduleId);
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"spanmoduleId);
2251         }
2252         else
2253         {
2254             expression->SetFlag(BoundExpressionFlags::exceptionCapture);
2255         }
2256     }
2257     if (GetGlobalFlag(GlobalFlags::cmdoc) && functionSymbol->HasSource())
2258     {
2259         symbolTable.MapInvoke(invokeIdfunctionSymbol);
2260     }
2261     if (functionSymbol->HasSource())
2262     {
2263         MapIdentifierToSymbolDefinition(invokeIdfunctionSymbol);
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(&prefixIncrementExpressiontrue);
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(&assignmentStatementtrue);
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(&assignmentStatementtrue);
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(&prefixDecrementExpressiontrue);
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(&assignmentStatementtrue);
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(&assignmentStatementtrue);
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(spanmoduleIdclassTypeSymbol));
2361         }
2362         else
2363         {
2364             throw Exception("ordinary class not found from class group '" + ToUtf8(classGroup->FullName()) + "'"spanmoduleIdclassGroup->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()boundCompileUnitboundFunctioncontainerScopestatementBinderfalsefalsetruefalse);
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()) + "'"spanmoduleIdclassGroup->GetSpan()classGroup->SourceModuleId());
2382         }
2383         expr.reset(new BoundTypeExpression(spanmoduleIdclassTypeSymbol));
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()boundCompileUnitboundFunctioncontainerScopestatementBinderfalsefalsetruefalse);
2421     if (expr->GetType()->IsPointerType())
2422     {
2423         TypeSymbol* exprBaseType = expr->GetType()->RemovePointer(spanmoduleId);
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()boundCompileUnitcontainerScope);
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_parentcontainerScope));
2458     functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parenttargetType->BaseType()->ClassInterfaceEnumDelegateOrNsScope()));
2459     functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::fileScopesnullptr));
2460     std::unique_ptr<BoundFunctionCall> castFunctionCall = ResolveOverload(U"@return"containerScopefunctionScopeLookupstargetExprArgsboundCompileUnitboundFunctioncastNode.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(boundCompileUnitcastFunctionCall->GetFunctionSymbol()castArgumentsfunctionMatchConversionType::explicit_containerScopeboundFunction
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(spanmoduleId);
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(spanmoduleId);
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(spanmoduleIdconversionFun);
2492                 LocalVariableSymbol* temporary = boundFunction->GetFunctionSymbol()->CreateTemporary(conversionFun->ConversionTargetType()spanmoduleId);
2493                 constructorCall->AddArgument(std::unique_ptr<BoundExpression>(new BoundAddressOfExpression(std::unique_ptr<BoundExpression>(new BoundLocalVariable(spanmoduleIdtemporary))
2494                     conversionFun->ConversionTargetType()->AddPointer(spanmoduleId))));
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(spanmoduleIdclassType->Destructor()));
2502                         destructorCall->AddArgument(std::unique_ptr<BoundExpression>(constructorCall->Arguments()[0]->Clone()));
2503                         boundFunction->AddTemporaryDestructorCall(std::move(destructorCall)boundFunctioncontainerScopespanmoduleId);
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(spanmoduleIdtemporary)));
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(spanmoduleId);
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(spanmoduleId);
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_parentcontainerScope));
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::fileScopesnullptr));
2581     expression = ResolveOverload(U"@constructor"containerScopefunctionScopeLookupsargumentsboundCompileUnitboundFunctionconstructNode.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_parentcontainerScope));
2630     functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parentresultType->RemovePointer(newNode.GetSpan()newNode.ModuleId())->ClassInterfaceEnumDelegateOrNsScope()));
2631     functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::fileScopesnullptr));
2632     expression = ResolveOverload(U"@constructor"containerScopefunctionScopeLookupsargumentsboundCompileUnitboundFunctionnewNode.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()basePointerTypecontainerScopeboundFunctionbaseNode.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*nodeBoundCompileUnit&boundCompileUnitBoundFunction*boundFunctionContainerScope*containerScopeStatementBinder* statementBinder)
2706 {
2707     return BindExpression(nodeboundCompileUnitboundFunctioncontainerScopestatementBinderfalse);
2708 }
2709 
2710 std::std::unique_ptr<BoundExpression>BindExpression(Node*nodeBoundCompileUnit&boundCompileUnitBoundFunction*boundFunctionContainerScope*containerScopeStatementBinder* statementBinderbool lvalue)
2711 {
2712     return BindExpression(nodeboundCompileUnitboundFunctioncontainerScopestatementBinderlvaluefalse);
2713 }
2714 
2715 std::std::unique_ptr<BoundExpression>BindExpression(Node*nodeBoundCompileUnit&boundCompileUnitBoundFunction*boundFunctionContainerScope*containerScopeStatementBinder* statementBinderbool lvalue
2716     bool acceptFunctionGroupOrMemberExpression)
2717 {
2718     return BindExpression(nodeboundCompileUnitboundFunctioncontainerScopestatementBinderlvalueacceptFunctionGroupOrMemberExpressionfalse);
2719 }
2720 
2721 std::std::unique_ptr<BoundExpression>BindExpression(Node*nodeBoundCompileUnit&boundCompileUnitBoundFunction*boundFunctionContainerScope*containerScopeStatementBinder* statementBinderbool lvalue
2722     bool acceptFunctionGroupOrMemberExpressionbool acceptIncomplete)
2723 {
2724     return BindExpression(nodeboundCompileUnitboundFunctioncontainerScopestatementBinderlvalueacceptFunctionGroupOrMemberExpressionacceptIncompletetrue);
2725 }
2726 
2727 std::std::unique_ptr<BoundExpression>BindExpression(Node*nodeBoundCompileUnit&boundCompileUnitBoundFunction*boundFunctionContainerScope*containerScopeStatementBinder* statementBinderbool lvalue
2728     bool acceptFunctionGroupOrMemberExpressionbool acceptIncompletebool moveTemporaryDestructorCalls)
2729 {
2730     ExpressionBinder expressionBinder(node->GetSpan()node->ModuleId()boundCompileUnitboundFunctioncontainerScopestatementBinderlvalue);
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*operandNode&nodeconststd::u32string&groupName
2760     BoundCompileUnit& boundCompileUnitBoundFunction* boundFunctionContainerScope* containerScopeStatementBinder* statementBinder)
2761 {
2762     ExpressionBinder expressionBinder(node.GetSpan()node.ModuleId()boundCompileUnitboundFunctioncontainerScopestatementBinderfalse);
2763     expressionBinder.BindUnaryOp(operandnodegroupName);
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 } } // namespace cmajor::binder