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