bool Function::maybeValidPrototype(unsigned actualArgumentCount) const { const unsigned argc = argumentCount(); unsigned minNumberArguments = 0; for (; minNumberArguments < argc; ++minNumberArguments) { Argument *arg = argumentAt(minNumberArguments)->asArgument(); if (! arg) return false; if (arg->hasInitializer()) break; } if (actualArgumentCount < minNumberArguments) { // not enough arguments. return false; } else if (!isVariadic() && actualArgumentCount > argc) { // too many arguments. return false; } return true; }
bool CheckDeclarator::visit(FunctionDeclaratorAST *ast) { Function *fun = control()->newFunction(ast->firstToken()); fun->setAmbiguous(ast->as_cpp_initializer != 0); ast->symbol = fun; fun->setReturnType(_fullySpecifiedType); if (_fullySpecifiedType.isVirtual()) fun->setVirtual(true); if (ast->parameters) { DeclarationListAST *parameter_declarations = ast->parameters->parameter_declarations; for (DeclarationListAST *decl = parameter_declarations; decl; decl = decl->next) { semantic()->check(decl->declaration, fun->arguments()); } if (ast->parameters->dot_dot_dot_token) fun->setVariadic(true); } // check the arguments bool hasDefaultArguments = false; for (unsigned i = 0; i < fun->argumentCount(); ++i) { Argument *arg = fun->argumentAt(i)->asArgument(); if (hasDefaultArguments && ! arg->hasInitializer()) { translationUnit()->error(ast->firstToken(), "default argument missing for parameter at position %d", i + 1); } else if (! hasDefaultArguments) { hasDefaultArguments = arg->hasInitializer(); } } FullySpecifiedType funTy(fun); _fullySpecifiedType = funTy; for (SpecifierAST *it = ast->cv_qualifier_seq; it; it = it->next) { SimpleSpecifierAST *cv = static_cast<SimpleSpecifierAST *>(it); int k = tokenKind(cv->specifier_token); if (k == T_CONST) fun->setConst(true); else if (k == T_VOLATILE) fun->setVolatile(true); } accept(ast->next); return false; }