/// Return the symbol pointer to the individual field that this /// structselect represents; also set structid to the ID of the /// structure type, and fieldid to the field index within the struct. Symbol * ASTstructselect::find_fieldsym (int &structid, int &fieldid) { if (! lvalue()->typespec().is_structure() && ! lvalue()->typespec().is_structure_array()) { return NULL; } ustring structsymname; TypeSpec structtype; find_structsym (lvalue().get(), structsymname, structtype); structid = structtype.structure(); StructSpec *structspec (structtype.structspec()); fieldid = -1; for (int i = 0; i < (int)structspec->numfields(); ++i) { if (structspec->field(i).name == m_field) { fieldid = i; break; } } if (fieldid < 0) { error ("struct type '%s' does not have a member '%s'", structspec->name().c_str(), m_field.c_str()); return NULL; } const StructSpec::FieldSpec &fieldrec (structspec->field(fieldid)); ustring fieldsymname = ustring::format ("%s.%s", structsymname.c_str(), fieldrec.name.c_str()); Symbol *sym = m_compiler->symtab().find (fieldsymname); return sym; }
ASTvariable_declaration::ASTvariable_declaration (OSLCompilerImpl *comp, const TypeSpec &type, ustring name, ASTNode *init, bool isparam, bool ismeta, bool isoutput, bool initlist) : ASTNode (variable_declaration_node, comp, 0, init, NULL /* meta */), m_name(name), m_sym(NULL), m_isparam(isparam), m_isoutput(isoutput), m_ismetadata(ismeta), m_initlist(initlist) { m_typespec = type; Symbol *f = comp->symtab().clash (name); if (f && ! m_ismetadata) { std::string e = Strutil::format ("\"%s\" already declared in this scope", name.c_str()); if (f->node()) { std::string filename = OIIO::Filesystem::filename(f->node()->sourcefile().string()); e += Strutil::format ("\n\t\tprevious declaration was at %s:%d", filename, f->node()->sourceline()); } if (f->scope() == 0 && f->symtype() == SymTypeFunction && isparam) { // special case: only a warning for param to mask global function warning ("%s", e.c_str()); } else { error ("%s", e.c_str()); } } if (name[0] == '_' && name[1] == '_' && name[2] == '_') { error ("\"%s\" : sorry, can't start with three underscores", name.c_str()); } SymType symtype = isparam ? (isoutput ? SymTypeOutputParam : SymTypeParam) : SymTypeLocal; // Sneaky debugging aid: a local that starts with "__debug_tmp__" // gets declared as a temp. Don't do this on purpose!!! if (symtype == SymTypeLocal && Strutil::starts_with (name, "__debug_tmp__")) symtype = SymTypeTemp; m_sym = new Symbol (name, type, symtype, this); if (! m_ismetadata) oslcompiler->symtab().insert (m_sym); // A struct really makes several subvariables if (type.is_structure() || type.is_structure_array()) { ASSERT (! m_ismetadata); // Add the fields as individual declarations m_compiler->add_struct_fields (type.structspec(), m_sym->name(), symtype, type.is_unsized_array() ? -1 : type.arraylength(), this, init); } }