@@ -251,6 +251,45 @@ ASTNode::type_c_str (const TypeSpec &type) const
251251
252252
253253
254+ void
255+ ASTNode::list_to_vec (const ref &A, std::vector<ref> &vec)
256+ {
257+ vec.clear ();
258+ for (ref node = A; node; node = node->next ())
259+ vec.push_back (node);
260+ }
261+
262+
263+
264+ ASTNode::ref
265+ ASTNode::vec_to_list (std::vector<ref> &vec)
266+ {
267+ if (vec.size ()) {
268+ for (size_t i = 0 ; i < vec.size ()-1 ; ++i)
269+ vec[i]->m_next = vec[i+1 ];
270+ vec[vec.size ()-1 ]->m_next = NULL ;
271+ return vec[0 ];
272+ } else {
273+ return ref ();
274+ }
275+ }
276+
277+
278+
279+ std::string
280+ ASTNode::list_to_types_string (const ASTNode *node)
281+ {
282+ std::ostringstream result;
283+ for (int i = 0 ; node; node = node->nextptr (), ++i) {
284+ if (i)
285+ result << " , " ;
286+ result << node->typespec ();
287+ }
288+ return result.str ();
289+ }
290+
291+
292+
254293ASTshader_declaration::ASTshader_declaration (OSLCompilerImpl *comp,
255294 int stype, ustring name, ASTNode *form,
256295 ASTNode *stmts, ASTNode *meta)
@@ -304,29 +343,31 @@ ASTshader_declaration::shadertypename () const
304343
305344ASTfunction_declaration::ASTfunction_declaration (OSLCompilerImpl *comp,
306345 TypeSpec type, ustring name,
307- ASTNode *form, ASTNode *stmts, ASTNode *meta)
346+ ASTNode *form, ASTNode *stmts, ASTNode *meta,
347+ int sourceline_start)
308348 : ASTNode (function_declaration_node, comp, 0 , meta, form, stmts),
309349 m_name(name), m_sym(NULL ), m_is_builtin(false )
310350{
311- m_typespec = type;
312- Symbol *f = comp->symtab ().clash (name);
313- if (f && f->symtype () != SymTypeFunction) {
314- error (" \" %s\" already declared in this scope as a " , name.c_str (),
315- f->typespec ().string ().c_str ());
316- // FIXME -- print the file and line of the other definition
317- f = NULL ;
318- }
351+ // Some trickery -- the compiler's idea of the "current" source line
352+ // is the END of the function body, so if a hint was passed about the
353+ // start of the declaration, substitute that.
354+ if (sourceline_start >= 0 )
355+ m_sourceline = sourceline_start;
319356
320- // FIXME -- allow multiple function declarations, but only if they
321- // aren 't the same polymorphic type.
357+ if ( Strutil::starts_with (name, " ___ " ))
358+ error ( " \" %s \" : sorry, can 't start with three underscores " , name);
322359
323- if (name[0 ] == ' _' && name[1 ] == ' _' && name[2 ] == ' _' ) {
324- error (" \" %s\" : sorry, can't start with three underscores" ,
325- name.c_str ());
360+ // Get a pointer to the first of the existing symbols of that name.
361+ Symbol *existing_syms = comp->symtab ().clash (name);
362+ if (existing_syms && existing_syms->symtype () != SymTypeFunction) {
363+ error (" \" %s\" already declared in this scope as a %s" ,
364+ name, existing_syms->typespec ());
365+ // FIXME -- print the file and line of the other definition
366+ existing_syms = NULL ;
326367 }
327368
328- m_sym = new FunctionSymbol (name, type, this );
329- func ()-> nextpoly ((FunctionSymbol *)f) ;
369+ // Build up the argument signature for this declared function
370+ m_typespec = type ;
330371 std::string argcodes = oslcompiler->code_from_type (m_typespec);
331372 for (ASTNode *arg = form; arg; arg = arg->nextptr ()) {
332373 const TypeSpec &t (arg->typespec ());
@@ -341,6 +382,22 @@ ASTfunction_declaration::ASTfunction_declaration (OSLCompilerImpl *comp,
341382 v->error (" function parameter '%s' may not have a default initializer." ,
342383 v->name ().c_str ());
343384 }
385+
386+ // Allow multiple function declarations, but only if they aren't the
387+ // same polymorphic type in the same scope.
388+ int current_scope = oslcompiler->symtab ().scopeid ();
389+ for (FunctionSymbol *f = reinterpret_cast <FunctionSymbol *>(existing_syms);
390+ f; f = f->nextpoly ()) {
391+ if (f->argcodes () == argcodes && f->scope () == current_scope) {
392+ warning (" Function '%s %s (%s)' declared twice in the same scope" ,
393+ type, name, list_to_types_string (form));
394+ }
395+ }
396+
397+
398+ m_sym = new FunctionSymbol (name, type, this );
399+ func ()->nextpoly ((FunctionSymbol *)existing_syms);
400+
344401 func ()->argcodes (ustring (argcodes));
345402 oslcompiler->symtab ().insert (m_sym);
346403
0 commit comments