void FunctionAnalyzer::visitFunction(const FunctionDefPtr& node) { if(node->hasModifier(DeclarationModifiers::_Generated)) return; //visit implementation FunctionSymbolPtr func = static_pointer_cast<SymboledFunction>(node)->symbol; if(func->getDeclaringType() && func->getDeclaringType()->getCategory() == Type::Protocol) return;//do not check implementation if it's defined as protocol function assert(func != nullptr); SCOPED_SET(ctx->currentFunction, func->getType()); node->getBody()->accept(semanticAnalyzer); if(!Type::equals(func->getType()->getReturnType(), symbolRegistry->getGlobalScope()->Void())) { //check return in all branches ReturnStatementValidator validator(ctx); node->getBody()->accept(&validator); NodePtr refNode = validator.getRefNode() ? validator.getRefNode() : node; ReturnCoverResult result = validator.getResult(); if (result & ReturnCoverDeadcode) { this->warning(refNode, Errors::W_CODE_AFTER_A_WILL_NEVER_BE_EXECUTED_1, L"return"); return; } switch (result) { case ReturnCoverNoResult: case ReturnCoverUnmatched: case ReturnCoverPartial: error(refNode, Errors::E_MISSING_RETURN_IN_A_FUNCTION_EXPECTED_TO_RETURN_A_1, func->getType()->getReturnType()->toString()); return; default: break; } } }