@@ -1605,15 +1605,11 @@ class CandidateFunctions {
16051605 return argscore;
16061606 }
16071607
1608- void candidateHeader (const char * msg) const {
1609- m_compiler->errhandler ().message (" %s:\n " , msg);
1610- }
1611-
16121608public:
1613- CandidateFunctions (OSLCompilerImpl* compiler, TypeSpec rval, ASTNode::ref args,
1614- FunctionSymbol* func) :
1615- m_compiler (compiler), m_rval(rval), m_args(args), m_nargs(0 ),
1616- m_called (func), m_had_initlist(false ) {
1609+ CandidateFunctions (OSLCompilerImpl* compiler, TypeSpec rval,
1610+ ASTNode::ref args, FunctionSymbol* func)
1611+ : m_compiler(compiler), m_rval(rval), m_args(args), m_nargs(0 ),
1612+ m_called (func), m_had_initlist(false ) {
16171613
16181614 // std::cerr << "Matching " << func->name() << " formals='" << (rval.simpletype().basetype != TypeDesc::UNKNOWN ? compiler->code_from_type (rval) : " ");
16191615 for (ASTNode::ref arg = m_args; arg; arg = arg->next ()) {
@@ -1630,46 +1626,37 @@ class CandidateFunctions {
16301626 }
16311627 }
16321628
1633- void reportAmbiguity (ASTNode* caller, const ustring& funcname,
1634- bool candidateMsg = true ,
1635- const char * msg = " No matching function call to" ,
1636- bool asWarning = true , bool showArgs = true ) const {
1629+ std::string reportAmbiguity (ustring funcname, bool candidateMsg,
1630+ string_view msg) const {
16371631 std::string argstr = funcname.string ();
1638- if (showArgs) {
1639- argstr += " (" ;
1640- const char *comma = " " ;
1641- for (ASTNode::ref arg = m_args; arg; arg = arg->next ()) {
1642- argstr += comma;
1643- if (arg->typespec ().simpletype ().is_unknown () &&
1644- arg->nodetype () == ASTNode::compound_initializer_node) {
1645- argstr += " initializer-list" ;
1646- } else
1647- argstr += arg->typespec ().string ();
1648- comma = " , " ;
1632+ argstr += " (" ;
1633+ const char *comma = " " ;
1634+ for (ASTNode::ref arg = m_args; arg; arg = arg->next ()) {
1635+ argstr += comma;
1636+ if (arg->typespec ().simpletype ().is_unknown () &&
1637+ arg->nodetype () == ASTNode::compound_initializer_node) {
1638+ argstr += " initializer-list" ;
1639+ } else {
1640+ argstr += arg->typespec ().string ();
16491641 }
1650- argstr + = " ) " ;
1642+ comma = " , " ;
16511643 }
1652- asWarning ? caller->warning (" %s '%s'" , msg, argstr)
1653- : caller->error (" %s '%s'" , msg, argstr);
1654- if (candidateMsg)
1655- candidateHeader (" Candidates are" );
1644+ argstr += " )" ;
1645+ return Strutil::format (" %s '%s'%s\n " , msg, argstr,
1646+ candidateMsg ? " \n Candidates are:" : " " );
16561647 }
16571648
1658- void reportFunction (FunctionSymbol* sym) const {
1649+ std::string reportFunction (FunctionSymbol* sym) const {
16591650 int advance;
16601651 const char *formals = sym->argcodes ().c_str ();
16611652 TypeSpec returntype = m_compiler->type_from_code (formals, &advance);
16621653 formals += advance;
1663-
1664- auto & errh = m_compiler->errhandler ();
1665- errh.message (" " );
1666-
1654+ std::string msg = " " ;
16671655 if (ASTNode* decl = sym->node ())
1668- errh.message (" %s:%d\t " , decl->sourcefile (), decl->sourceline ());
1669-
1670- errh.message (" %s %s (%s)\n " , m_compiler->type_c_str (returntype),
1671- sym->name (),
1672- m_compiler->typelist_from_code (formals).c_str ());
1656+ msg += Strutil::format (" %s:%d\t " , decl->sourcefile (), decl->sourceline ());
1657+ msg += Strutil::format (" %s %s (%s)\n " , m_compiler->type_c_str (returntype),
1658+ sym->name (), m_compiler->typelist_from_code (formals));
1659+ return msg;
16731660 }
16741661
16751662 std::pair<FunctionSymbol*, TypeSpec>
@@ -1680,21 +1667,20 @@ class CandidateFunctions {
16801667 auto best = [](Candidate* c) -> std::pair<FunctionSymbol*, TypeSpec> {
16811668 for (auto && t : c->bindings )
16821669 t.second .bind ();
1683- return {c->sym , c->rtype };
1670+ return { c->sym , c->rtype };
16841671 };
16851672
1673+ std::string errmsg;
16861674 switch (m_candidates.size ()) {
16871675 case 0 :
16881676 // Nothing at all, Error
16891677 // If m_called is 0, then user tried to call an undefined func.
16901678 // Might be nice to fuzzy match funcname against m_compiler->symtab()
1691- reportAmbiguity (caller, funcname,
1692- m_called != nullptr /* Candidate Msg?*/ ,
1693- " No matching function call to" ,
1694- false /* As warning*/ );
1679+ errmsg = reportAmbiguity (funcname, m_called != nullptr /* Candidate Msg?*/ ,
1680+ " No matching function call to" );
16951681 for (FunctionSymbol* f = m_called; f; f = f->nextpoly ())
1696- reportFunction (f);
1697-
1682+ errmsg += reportFunction (f);
1683+ caller-> error ( " %s " , errmsg);
16981684 return { nullptr , TypeSpec () };
16991685
17001686 case 1 : // Success
@@ -1717,7 +1703,6 @@ class CandidateFunctions {
17171703 ASSERT (c.first && c.first ->sym );
17181704
17191705 if (ambiguity != -1 ) {
1720-
17211706 unsigned userstructs = 0 ;
17221707
17231708 auto rank = [&userstructs] (const TypeSpec& s) -> int {
@@ -1751,7 +1736,7 @@ class CandidateFunctions {
17511736 }
17521737 if (s.is_void ())
17531738 return 10 ;
1754-
1739+
17551740 ASSERT (0 && " Unranked type" );
17561741 return std::numeric_limits<int >::max ();
17571742 };
@@ -1812,20 +1797,20 @@ class CandidateFunctions {
18121797 }
18131798 }
18141799
1815- reportAmbiguity (caller, funcname, !warn /* "Candidates are" msg*/ ,
1816- " Ambiguous call to " , warn /* As warning */ );
1800+ std::string errmsg = reportAmbiguity ( funcname, !warn /* "Candidates are" msg*/ ,
1801+ " Ambiguous call to " );
18171802 if (warn) {
1818- candidateHeader (" Chosen function is" );
1819- reportFunction (c.first ->sym );
1820-
1821- candidateHeader (" Other candidates are" );
1822- for (auto & candidate : m_candidates) {
1803+ errmsg += Strutil::format (" Chosen function is:\n %s" ,
1804+ reportFunction (c.first ->sym ));
1805+ errmsg += " Other candidates are:\n " ;
1806+ for (auto & candidate : m_candidates)
18231807 if (candidate.sym != c.first ->sym )
1824- reportFunction (candidate.sym );
1825- }
1808+ errmsg += reportFunction (candidate.sym );
1809+ caller-> warning ( " %s " , errmsg);
18261810 } else {
18271811 for (auto & candidate : m_candidates)
1828- reportFunction (candidate.sym );
1812+ errmsg += reportFunction (candidate.sym );
1813+ caller->error (" %s" , errmsg);
18291814 }
18301815 }
18311816
@@ -1964,23 +1949,29 @@ ASTfunction_call::typecheck (TypeSpec expected)
19641949 // Check resolution against prior versions of OSL.
19651950 // Skip the check if any arguments used initializer list syntax.
19661951 static const char * OSL_LEGACY = ::getenv (" OSL_LEGACY_FUNCTION_RESOLUTION" );
1967- if (candidates.hadinitlist () && OSL_LEGACY && strcmp (OSL_LEGACY, " 0" )) {
1952+ if (! candidates.hadinitlist () && OSL_LEGACY && strcmp (OSL_LEGACY, " 0" )) {
19681953 auto * legacy = LegacyOverload (m_compiler, this , poly,
19691954 &ASTfunction_call::check_arglist)(expected);
19701955 if (m_sym != legacy) {
1971- Strutil::iequals (OSL_LEGACY, " err" )
1972- ? error (" overload chosen differs from OSL 1.9" )
1973- : warning (" overload chosen differs from OSL 1.9" );
1974-
1975- m_compiler->errhandler ().message (" Current overload is " );
1976- !m_sym ? m_compiler->errhandler ().message (" <none>" )
1977- : candidates.reportFunction (static_cast <FunctionSymbol*>(m_sym));
1978- m_compiler->errhandler ().message (" Prior overload was " );
1979- !legacy ? m_compiler->errhandler ().message (" <none>" )
1980- : candidates.reportFunction (legacy);
1981-
1956+ bool as_warning = true ;
1957+ if (Strutil::iequals (OSL_LEGACY, " err" ))
1958+ as_warning = false ; // full error
1959+ std::string errmsg = " Current overload is\n " ;
1960+ if (m_sym)
1961+ errmsg += candidates.reportFunction (static_cast <FunctionSymbol*>(m_sym));
1962+ else
1963+ errmsg += " <none>" ;
1964+ errmsg += " \n Prior overload was " ;
1965+ if (legacy)
1966+ errmsg += candidates.reportFunction (legacy);
1967+ else
1968+ errmsg += " <none>" ;
19821969 if (Strutil::iequals (OSL_LEGACY, " use" ))
19831970 m_sym = legacy;
1971+ if (as_warning)
1972+ warning (" overload chosen differs from OSL 1.9\n %s" , errmsg);
1973+ else
1974+ warning (" overload chosen differs from OSL 1.9\n %s" , errmsg);
19841975 }
19851976 }
19861977
@@ -1989,7 +1980,7 @@ ASTfunction_call::typecheck (TypeSpec expected)
19891980 if (func ()->number_of_returns () == 0 &&
19901981 ! func ()->typespec ().is_void ()) {
19911982 error (" non-void function \" %s\" had no 'return' statement." ,
1992- func ()->name (). c_str () );
1983+ func ()->name ());
19931984 }
19941985 } else {
19951986 // built-in
0 commit comments