@@ -251,6 +251,109 @@ ASTNode::type_c_str (const TypeSpec &type) const
251251
252252
253253
254+ ASTnamed_symbol::ASTnamed_symbol (NodeType node_type, OSLCompilerImpl *comp,
255+ ustring name)
256+ : ASTNode (node_type, comp, Nothing), m_name(name), m_sym(nullptr )
257+ {
258+ }
259+
260+
261+
262+ ASTnamed_symbol::ASTnamed_symbol (NodeType node_type, OSLCompilerImpl *comp,
263+ ustring name, ASTNode *a)
264+ : ASTNode (node_type, comp, Nothing, a), m_name(name), m_sym(nullptr )
265+ {
266+ }
267+
268+
269+
270+ ASTnamed_symbol::ASTnamed_symbol (NodeType node_type, OSLCompilerImpl *comp,
271+ ustring name, ASTNode *a, ASTNode *b)
272+ : ASTNode (node_type, comp, Nothing, a, b), m_name(name), m_sym(nullptr )
273+ {
274+ }
275+
276+
277+
278+ ASTnamed_symbol::ASTnamed_symbol (NodeType node_type, OSLCompilerImpl *comp,
279+ ustring name, ASTNode *a, ASTNode *b,
280+ ASTNode *c)
281+ : ASTNode (node_type, comp, Nothing, a, b, c), m_name(name), m_sym(nullptr )
282+ {
283+ }
284+
285+
286+
287+ void
288+ ASTnamed_symbol::check_reserved (ustring name, OSLCompilerImpl *comp)
289+ {
290+ if (Strutil::starts_with (name, " ___" )) {
291+ comp->error (comp->filename (), comp->lineno (),
292+ " '%s' : sorry, can't start with three underscores" ,
293+ name);
294+ }
295+ }
296+
297+
298+
299+ std::string
300+ ASTnamed_symbol::previous_decl (ASTNode* node)
301+ {
302+ if (! node)
303+ return " " ;
304+
305+ return Strutil::format (" \n\t\t previous declaration was at %s:%d" ,
306+ OIIO::Filesystem::filename (node->sourcefile ().string ()),
307+ node->sourceline ());
308+ }
309+
310+
311+
312+ Symbol*
313+ ASTnamed_symbol::validate (ustring name, OSLCompilerImpl *comp,
314+ Validation vflags, int allowed)
315+ {
316+ check_reserved (name, comp);
317+
318+ Symbol *f;
319+ bool shadow = vflags & warn_shadow;
320+ if (! (vflags & check_clashes)) {
321+ f = comp->symtab ().find (name);
322+ if (! f) {
323+ comp->error (comp->filename (), comp->lineno (),
324+ " '%s' was not declared in this scope" , name);
325+ // FIXME -- would be fun to troll through the symtab and try to
326+ // find the things that almost matched and offer suggestions.
327+ }
328+ else if (shadow && f->symtype () == SymTypeFunction) {
329+ comp->error (comp->filename (), comp->lineno (),
330+ " function '%s' can't be used as a variable" , name);
331+ }
332+ } else {
333+ f = comp->symtab ().clash (name);
334+ // If no symbol, or symbol matches allowed type: no clash.
335+ if (! f || f->symtype () == allowed)
336+ return f;
337+
338+ std::string e = Strutil::format (" '%s' already declared in this scope" ,
339+ name);
340+ e += previous_decl (f->node ());
341+
342+ if (shadow) {
343+ // special case: only a warning for param to mask global function
344+ shadow = f->scope () == 0 && f->symtype () == SymTypeFunction;
345+ }
346+
347+ if (shadow)
348+ comp->warning (comp->filename (), comp->lineno (), " %s" , e);
349+ else
350+ comp->error (comp->filename (), comp->lineno (), " %s" , e);
351+ }
352+ return f;
353+ }
354+
355+
356+
254357ASTshader_declaration::ASTshader_declaration (OSLCompilerImpl *comp,
255358 int stype, ustring name, ASTNode *form,
256359 ASTNode *stmts, ASTNode *meta)
@@ -305,22 +408,11 @@ ASTshader_declaration::shadertypename () const
305408ASTfunction_declaration::ASTfunction_declaration (OSLCompilerImpl *comp,
306409 TypeSpec type, ustring name,
307410 ASTNode *form, ASTNode *stmts, ASTNode *meta)
308- : ASTNode (function_declaration_node, comp, 0 , meta, form, stmts),
309- m_name(name), m_sym( NULL ), m_is_builtin(false )
411+ : ASTnamed_symbol (function_declaration_node, comp, name , meta, form, stmts),
412+ m_is_builtin(false )
310413{
311414 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- }
319-
320- if (name[0 ] == ' _' && name[1 ] == ' _' && name[2 ] == ' _' ) {
321- error (" \" %s\" : sorry, can't start with three underscores" ,
322- name.c_str ());
323- }
415+ Symbol* sym = validate (check_clashes, SymTypeFunction);
324416
325417 std::string argcodes = oslcompiler->code_from_type (m_typespec);
326418 for (ASTNode *arg = form; arg; arg = arg->nextptr ()) {
@@ -337,8 +429,8 @@ ASTfunction_declaration::ASTfunction_declaration (OSLCompilerImpl *comp,
337429 v->name ().c_str ());
338430 }
339431
340- if (stmts && f && f ->symtype () == SymTypeFunction) {
341- for (FunctionSymbol* poly = static_cast <FunctionSymbol*>(f ); poly;
432+ if (stmts && sym && sym ->symtype () == SymTypeFunction) {
433+ for (FunctionSymbol* poly = static_cast <FunctionSymbol*>(sym ); poly;
342434 poly = poly->nextpoly ()) {
343435 // If the argcodes match, only one should have statements.
344436 // If there is no ASTNode for the poly, must be a builtin, and has
@@ -351,11 +443,7 @@ ASTfunction_declaration::ASTfunction_declaration (OSLCompilerImpl *comp,
351443 type_c_str (type), m_name,
352444 argcodes.size () <= 1 ? " " :
353445 m_compiler->typelist_from_code (argcodes.c_str ()+1 ),
354- other ? Strutil::format (
355- " \n\t\t previous declaration was at %s:%d" ,
356- OIIO::Filesystem::filename (other->sourcefile ().string ()),
357- other->sourceline ())
358- : std::string ());
446+ previous_decl (other));
359447 // Set m_sym to the function that is being overwritten.
360448 m_sym = poly;
361449 return ;
@@ -364,7 +452,8 @@ ASTfunction_declaration::ASTfunction_declaration (OSLCompilerImpl *comp,
364452 }
365453
366454 m_sym = new FunctionSymbol (name, type, this );
367- func ()->nextpoly ((FunctionSymbol *)f);
455+ if (sym && sym->symtype () == SymTypeFunction)
456+ func ()->nextpoly ((FunctionSymbol *)sym);
368457
369458 func ()->argcodes (ustring (argcodes));
370459 oslcompiler->symtab ().insert (m_sym);
@@ -438,31 +527,16 @@ ASTvariable_declaration::ASTvariable_declaration (OSLCompilerImpl *comp,
438527 ustring name, ASTNode *init,
439528 bool isparam, bool ismeta,
440529 bool isoutput, bool initlist)
441- : ASTNode (variable_declaration_node, comp, 0 , init, NULL /* meta */ ),
442- m_name(name), m_sym(NULL ),
530+ : ASTnamed_symbol (variable_declaration_node, comp, name, init, NULL /* meta */ ),
443531 m_isparam(isparam), m_isoutput(isoutput), m_ismetadata(ismeta),
444532 m_initlist(initlist)
445533{
446534 m_typespec = type;
447- Symbol *f = comp->symtab ().clash (name);
448- if (f && ! m_ismetadata) {
449- std::string e = Strutil::format (" \" %s\" already declared in this scope" , name.c_str ());
450- if (f->node ()) {
451- std::string filename = OIIO::Filesystem::filename (f->node ()->sourcefile ().string ());
452- e += Strutil::format (" \n\t\t previous declaration was at %s:%d" ,
453- filename, f->node ()->sourceline ());
454- }
455- if (f->scope () == 0 && f->symtype () == SymTypeFunction && isparam) {
456- // special case: only a warning for param to mask global function
457- warning (" %s" , e.c_str ());
458- } else {
459- error (" %s" , e.c_str ());
460- }
461- }
462- if (name[0 ] == ' _' && name[1 ] == ' _' && name[2 ] == ' _' ) {
463- error (" \" %s\" : sorry, can't start with three underscores" ,
464- name.c_str ());
465- }
535+ if (! m_ismetadata)
536+ validate (warn_function_clash);
537+ else
538+ check_reserved ();
539+
466540 SymType symtype = isparam ? (isoutput ? SymTypeOutputParam : SymTypeParam)
467541 : SymTypeLocal;
468542 // Sneaky debugging aid: a local that starts with "__debug_tmp__"
@@ -523,20 +597,11 @@ ASTvariable_declaration::print (std::ostream &out, int indentlevel) const
523597
524598
525599ASTvariable_ref::ASTvariable_ref (OSLCompilerImpl *comp, ustring name)
526- : ASTNode (variable_ref_node, comp), m_name( name), m_sym( NULL )
600+ : ASTnamed_symbol (variable_ref_node, comp, name)
527601{
528- m_sym = comp->symtab ().find (name);
529- if (! m_sym) {
530- error (" '%s' was not declared in this scope" , name.c_str ());
531- // FIXME -- would be fun to troll through the symtab and try to
532- // find the things that almost matched and offer suggestions.
533- return ;
534- }
535- if (m_sym->symtype () == SymTypeFunction) {
536- error (" function '%s' can't be used as a variable" , name.c_str ());
537- return ;
538- }
539- m_typespec = m_sym->typespec ();
602+ m_sym = validate (warn_function_exists);
603+ if (m_sym)
604+ m_typespec = m_sym->typespec ();
540605}
541606
542607
@@ -1049,25 +1114,18 @@ ASTtype_constructor::childname (size_t i) const
10491114
10501115ASTfunction_call::ASTfunction_call (OSLCompilerImpl *comp, ustring name,
10511116 ASTNode *args, FunctionSymbol *funcsym)
1052- : ASTNode (function_call_node, comp, 0 , args), m_name(name),
1053- m_sym(funcsym ? funcsym : comp->symtab ().find (name)), // Look it up.
1117+ : ASTnamed_symbol (function_call_node, comp, name, args),
10541118 m_poly(funcsym), // Default - resolved symbol or null
10551119 m_argread(~1 ), // Default - all args are read except the first
10561120 m_argwrite(1 ), // Default - first arg only is written by the op
10571121 m_argtakesderivs(0 ) // Default - doesn't take derivs
10581122{
1059- if (! m_sym) {
1060- error (" function '%s' was not declared in this scope" , name);
1061- // FIXME -- would be fun to troll through the symtab and try to
1062- // find the things that almost matched and offer suggestions.
1123+ m_sym = funcsym ? funcsym : validate (err_must_exist); // Look it up.
1124+ if (! m_sym || is_struct_ctr ())
10631125 return ;
1064- }
1065- if (is_struct_ctr ()) {
1066- return ; // It's a struct constructor
1067- }
10681126 if (m_sym->symtype () != SymTypeFunction) {
10691127 error (" '%s' is not a function" , name.c_str ());
1070- m_sym = NULL ;
1128+ m_sym = nullptr ;
10711129 return ;
10721130 }
10731131}
0 commit comments