@@ -291,6 +291,109 @@ ASTNode::list_to_types_string (const ASTNode *node)
291291
292292
293293
294+ ASTnamed_symbol::ASTnamed_symbol (NodeType node_type, OSLCompilerImpl *comp,
295+ ustring name)
296+ : ASTNode (node_type, comp, Nothing), m_name(name), m_sym(nullptr )
297+ {
298+ }
299+
300+
301+
302+ ASTnamed_symbol::ASTnamed_symbol (NodeType node_type, OSLCompilerImpl *comp,
303+ ustring name, ASTNode *a)
304+ : ASTNode (node_type, comp, Nothing, a), m_name(name), m_sym(nullptr )
305+ {
306+ }
307+
308+
309+
310+ ASTnamed_symbol::ASTnamed_symbol (NodeType node_type, OSLCompilerImpl *comp,
311+ ustring name, ASTNode *a, ASTNode *b)
312+ : ASTNode (node_type, comp, Nothing, a, b), m_name(name), m_sym(nullptr )
313+ {
314+ }
315+
316+
317+
318+ ASTnamed_symbol::ASTnamed_symbol (NodeType node_type, OSLCompilerImpl *comp,
319+ ustring name, ASTNode *a, ASTNode *b,
320+ ASTNode *c)
321+ : ASTNode (node_type, comp, Nothing, a, b, c), m_name(name), m_sym(nullptr )
322+ {
323+ }
324+
325+
326+
327+ void
328+ ASTnamed_symbol::check_reserved (ustring name, OSLCompilerImpl *comp)
329+ {
330+ if (Strutil::starts_with (name, " ___" )) {
331+ comp->error (comp->filename (), comp->lineno (),
332+ " '%s' : sorry, can't start with three underscores" ,
333+ name);
334+ }
335+ }
336+
337+
338+
339+ std::string
340+ ASTnamed_symbol::previous_decl (ASTNode* node)
341+ {
342+ if (! node)
343+ return " " ;
344+
345+ return Strutil::format (" \n\t\t previous declaration was at %s:%d" ,
346+ OIIO::Filesystem::filename (node->sourcefile ().string ()),
347+ node->sourceline ());
348+ }
349+
350+
351+
352+ Symbol*
353+ ASTnamed_symbol::validate (ustring name, OSLCompilerImpl *comp,
354+ Validation vflags, int allowed)
355+ {
356+ check_reserved (name, comp);
357+
358+ Symbol *f;
359+ bool shadow = vflags & warn_shadow;
360+ if (! (vflags & check_clashes)) {
361+ f = comp->symtab ().find (name);
362+ if (! f) {
363+ comp->error (comp->filename (), comp->lineno (),
364+ " '%s' was not declared in this scope" , name);
365+ // FIXME -- would be fun to troll through the symtab and try to
366+ // find the things that almost matched and offer suggestions.
367+ }
368+ else if (shadow && f->symtype () == SymTypeFunction) {
369+ comp->error (comp->filename (), comp->lineno (),
370+ " function '%s' can't be used as a variable" , name);
371+ }
372+ } else {
373+ f = comp->symtab ().clash (name);
374+ // If no symbol, or symbol matches allowed type: no clash.
375+ if (! f || f->symtype () == allowed)
376+ return f;
377+
378+ std::string e = Strutil::format (" '%s' already declared in this scope" ,
379+ name);
380+ e += previous_decl (f->node ());
381+
382+ if (shadow) {
383+ // special case: only a warning for param to mask global function
384+ shadow = f->scope () == 0 && f->symtype () == SymTypeFunction;
385+ }
386+
387+ if (shadow)
388+ comp->warning (comp->filename (), comp->lineno (), " %s" , e);
389+ else
390+ comp->error (comp->filename (), comp->lineno (), " %s" , e);
391+ }
392+ return f;
393+ }
394+
395+
396+
294397ASTshader_declaration::ASTshader_declaration (OSLCompilerImpl *comp,
295398 int stype, ustring name, ASTNode *form,
296399 ASTNode *stmts, ASTNode *meta)
@@ -346,20 +449,17 @@ ASTfunction_declaration::ASTfunction_declaration (OSLCompilerImpl *comp,
346449 TypeSpec type, ustring name,
347450 ASTNode *form, ASTNode *stmts, ASTNode *meta,
348451 int sourceline_start)
349- : ASTNode (function_declaration_node, comp, 0 , meta, form, stmts),
350- m_name(name), m_sym( NULL ), m_is_builtin(false )
452+ : ASTnamed_symbol (function_declaration_node, comp, name , meta, form, stmts),
453+ m_is_builtin(false )
351454{
352455 // Some trickery -- the compiler's idea of the "current" source line
353456 // is the END of the function body, so if a hint was passed about the
354457 // start of the declaration, substitute that.
355458 if (sourceline_start >= 0 )
356459 m_sourceline = sourceline_start;
357460
358- if (Strutil::starts_with (name, " ___" ))
359- error (" \" %s\" : sorry, can't start with three underscores" , name);
360-
361461 // Get a pointer to the first of the existing symbols of that name.
362- Symbol *existing_syms = comp-> symtab (). clash (name );
462+ Symbol *existing_syms = validate (check_clashes, SymTypeFunction );
363463 if (existing_syms && existing_syms->symtype () != SymTypeFunction) {
364464 error (" \" %s\" already declared in this scope as a %s" ,
365465 name, existing_syms->typespec ());
@@ -493,8 +593,7 @@ ASTvariable_declaration::ASTvariable_declaration (OSLCompilerImpl *comp,
493593 ustring name, ASTNode *init,
494594 bool isparam, bool ismeta,
495595 bool isoutput, bool initlist)
496- : ASTNode (variable_declaration_node, comp, 0 , init, NULL /* meta */ ),
497- m_name(name), m_sym(NULL ),
596+ : ASTnamed_symbol (variable_declaration_node, comp, name, init, NULL /* meta */ ),
498597 m_isparam(isparam), m_isoutput(isoutput), m_ismetadata(ismeta),
499598 m_initlist(initlist)
500599{
@@ -505,25 +604,11 @@ ASTvariable_declaration::ASTvariable_declaration (OSLCompilerImpl *comp,
505604 }
506605
507606 m_typespec = type;
508- Symbol *f = comp->symtab ().clash (name);
509- if (f && ! m_ismetadata) {
510- std::string e = Strutil::format (" \" %s\" already declared in this scope" , name.c_str ());
511- if (f->node ()) {
512- std::string filename = OIIO::Filesystem::filename (f->node ()->sourcefile ().string ());
513- e += Strutil::format (" \n\t\t previous declaration was at %s:%d" ,
514- filename, f->node ()->sourceline ());
515- }
516- if (f->scope () == 0 && f->symtype () == SymTypeFunction && isparam) {
517- // special case: only a warning for param to mask global function
518- warning (" %s" , e.c_str ());
519- } else {
520- error (" %s" , e.c_str ());
521- }
522- }
523- if (name[0 ] == ' _' && name[1 ] == ' _' && name[2 ] == ' _' ) {
524- error (" \" %s\" : sorry, can't start with three underscores" ,
525- name.c_str ());
526- }
607+ if (! m_ismetadata)
608+ validate (warn_function_clash);
609+ else
610+ check_reserved ();
611+
527612 SymType symtype = isparam ? (isoutput ? SymTypeOutputParam : SymTypeParam)
528613 : SymTypeLocal;
529614 // Sneaky debugging aid: a local that starts with "__debug_tmp__"
@@ -584,20 +669,11 @@ ASTvariable_declaration::print (std::ostream &out, int indentlevel) const
584669
585670
586671ASTvariable_ref::ASTvariable_ref (OSLCompilerImpl *comp, ustring name)
587- : ASTNode (variable_ref_node, comp), m_name( name), m_sym( NULL )
672+ : ASTnamed_symbol (variable_ref_node, comp, name)
588673{
589- m_sym = comp->symtab ().find (name);
590- if (! m_sym) {
591- error (" '%s' was not declared in this scope" , name.c_str ());
592- // FIXME -- would be fun to troll through the symtab and try to
593- // find the things that almost matched and offer suggestions.
594- return ;
595- }
596- if (m_sym->symtype () == SymTypeFunction) {
597- error (" function '%s' can't be used as a variable" , name.c_str ());
598- return ;
599- }
600- m_typespec = m_sym->typespec ();
674+ m_sym = validate (warn_function_exists);
675+ if (m_sym)
676+ m_typespec = m_sym->typespec ();
601677}
602678
603679
@@ -1111,25 +1187,18 @@ ASTtype_constructor::childname (size_t i) const
11111187
11121188ASTfunction_call::ASTfunction_call (OSLCompilerImpl *comp, ustring name,
11131189 ASTNode *args, FunctionSymbol *funcsym)
1114- : ASTNode (function_call_node, comp, 0 , args), m_name(name),
1115- m_sym(funcsym ? funcsym : comp->symtab ().find (name)), // Look it up.
1190+ : ASTnamed_symbol (function_call_node, comp, name, args),
11161191 m_poly(funcsym), // Default - resolved symbol or null
11171192 m_argread(~1 ), // Default - all args are read except the first
11181193 m_argwrite(1 ), // Default - first arg only is written by the op
11191194 m_argtakesderivs(0 ) // Default - doesn't take derivs
11201195{
1121- if (! m_sym) {
1122- error (" function '%s' was not declared in this scope" , name);
1123- // FIXME -- would be fun to troll through the symtab and try to
1124- // find the things that almost matched and offer suggestions.
1196+ m_sym = funcsym ? funcsym : validate (err_must_exist); // Look it up.
1197+ if (! m_sym || is_struct_ctr ())
11251198 return ;
1126- }
1127- if (is_struct_ctr ()) {
1128- return ; // It's a struct constructor
1129- }
11301199 if (m_sym->symtype () != SymTypeFunction) {
11311200 error (" '%s' is not a function" , name.c_str ());
1132- m_sym = NULL ;
1201+ m_sym = nullptr ;
11331202 return ;
11341203 }
11351204}
0 commit comments