| 678 | |
| 679 | |
| 680 | void cSemanticASTVisitor::VisitFunctionCall(cASTFunctionCall& node) |
| 681 | { |
| 682 | if (m_fun_def_arg) { |
| 683 | SEMANTIC_ERROR(FUNCTION_DEFAULT_CALL_INVALID); |
| 684 | return; |
| 685 | } |
| 686 | |
| 687 | const cASFunction* libfun = NULL; |
| 688 | int fun_id = -1; |
| 689 | bool global = false; |
| 690 | |
| 691 | if (m_library->LookupFunction(node.GetName(), libfun)) { |
| 692 | // Check function parameters for match to the signature |
| 693 | cASTArgumentList* args = node.GetArguments(); |
| 694 | if (args && libfun->GetArity() == args->GetSize()) { |
| 695 | bool err = false; |
| 696 | tListIterator<cASTNode> cit = node.GetArguments()->Iterator(); |
| 697 | cASTNode* an = NULL; |
| 698 | for (int i = 0; i < libfun->GetArity(); i++) { |
| 699 | an = cit.Next(); |
| 700 | an->Accept(*this); |
| 701 | |
| 702 | ASType_t in_type = an->GetType().type; |
| 703 | ASType_t out_type = libfun->GetArgumentType(i).type; |
| 704 | if (valid_cast[in_type][out_type]) { |
| 705 | if ((in_type == TYPE(FLOAT) && out_type == TYPE(INT)) || (in_type == TYPE(INT) && out_type == TYPE(CHAR))) |
| 706 | SEMANTIC_WARNING(LOSS_OF_PRECISION, mapType(in_type), mapType(out_type)); |
| 707 | } else { |
| 708 | if (!err) { |
| 709 | SEMANTIC_ERROR(FUNCTION_CALL_SIGNATURE_MISMATCH, (const char*)node.GetName()); |
| 710 | err = true; |
| 711 | } |
| 712 | SEMANTIC_ERROR(CANNOT_CAST, mapType(in_type), mapType(out_type)); |
| 713 | } |
| 714 | } |
| 715 | } else if (libfun->GetArity()) { |
| 716 | SEMANTIC_ERROR(FUNCTION_CALL_SIGNATURE_MISMATCH, (const char*)node.GetName()); |
| 717 | } |
| 718 | |
| 719 | node.SetASFunction(libfun); |
| 720 | node.SetType(libfun->GetReturnType()); |
| 721 | |
| 722 | } else if (lookupFunction(node.GetName(), fun_id, global)) { |
| 723 | cASTVariableDefinitionList* sig = (global ? m_global_symtbl : m_cur_symtbl)->GetFunctionSignature(fun_id); |
| 724 | |
| 725 | // Check function parameters for match to the signature |
| 726 | cASTArgumentList* args = node.GetArguments(); |
| 727 | if (args) { |
| 728 | if (sig && args->GetSize() <= sig->GetSize()) { |
| 729 | |
| 730 | bool err = false; |
| 731 | tListIterator<cASTVariableDefinition> sit = sig->Iterator(); |
| 732 | tListIterator<cASTNode> cit = node.GetArguments()->Iterator(); |
| 733 | cASTNode* an = NULL; |
| 734 | while ((an = cit.Next())) { |
| 735 | an->Accept(*this); |
| 736 | |
| 737 | ASType_t in_type = an->GetType().type; |
nothing calls this directly
no test coverage detected