/// 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; }
void SymbolTable::add_struct_field (const TypeSpec &type, ustring name) { StructSpec *s = current_struct(); ASSERT (s && "add_struct_field couldn't find a current struct"); s->add_field (type, name); }
TypeSpec ASTstructselect::typecheck (TypeSpec expected) { // The ctr already figured out if this was a valid structure selection if (m_fieldid < 0 || m_mangledsym == NULL) return TypeSpec(); typecheck_children (); StructSpec *structspec (TypeSpec::structspec (m_structid)); m_typespec = structspec->field(m_fieldid).type; m_is_lvalue = lvalue()->is_lvalue(); return m_typespec; }
void OSLCompilerImpl::struct_field_pair (Symbol *sym1, Symbol *sym2, int fieldnum, Symbol * &field1, Symbol * &field2) { ASSERT (sym1 && sym2 && sym1->typespec().is_structure() && sym1->typespec().structure() && sym2->typespec().structure()); // Find the StructSpec for the type of struct that the symbols are StructSpec *structspec (sym1->typespec().structspec()); ASSERT (structspec && fieldnum < (int)structspec->numfields()); // Find the FieldSpec for the field we are interested in const StructSpec::FieldSpec &field (structspec->field(fieldnum)); // Construct mangled names that describe the symbols for the // individual fields ustring name1 = ustring::format ("%s.%s", sym1->mangled().c_str(), field.name.c_str()); ustring name2 = ustring::format ("%s.%s", sym2->mangled().c_str(), field.name.c_str()); // Retrieve the symbols field1 = symtab().find_exact (name1); field2 = symtab().find_exact (name2); ASSERT (field1 && field2); }
void OSOReaderToMaster::hint (string_view hintstring) { std::string h (hintstring); // FIXME -- use string_view ops here if (extract_prefix (h, "%filename{\"")) { m_sourcefile = readuntil (h, "\""); return; } if (extract_prefix (h, "%line{")) { m_sourceline = atoi (h.c_str()); return; } if (extract_prefix (h, "%structfields{")) { ASSERT (m_master->m_symbols.size() && "structfields hint but no sym"); Symbol &sym (m_master->m_symbols.back()); StructSpec *structspec = sym.typespec().structspec(); if (structspec->numfields() == 0) { while (1) { std::string afield = readuntil (h, ",}", true); if (! afield.length()) break; // std::cerr << " struct field " << afield << "\n"; structspec->add_field (TypeSpec(), ustring(afield)); } } return; } if (extract_prefix (h, "%mystructfield{")) { ASSERT (m_master->m_symbols.size() && "mystructfield hint but no sym"); Symbol &sym (m_master->m_symbols.back()); sym.fieldid (atoi(h.c_str()+15)); return; } if (extract_prefix (h, "%read{")) { ASSERT (m_master->m_symbols.size() && "read hint but no sym"); Symbol &sym (m_master->m_symbols.back()); int first, last; sscanf (h.c_str(), "%d,%d", &first, &last); sym.set_read (first, last); return; } if (extract_prefix (h, "%write{")) { ASSERT (m_master->m_symbols.size() && "write hint but no sym"); Symbol &sym (m_master->m_symbols.back()); int first, last; sscanf (h.c_str(), "%d,%d", &first, &last); sym.set_write (first, last); return; } if (extract_prefix(h, "%argrw{")) { const char* str = h.c_str(); ASSERT(*str == '\"'); str++; // skip open quote size_t i = 0; for (; *str != '\"'; i++, str++) { ASSERT(*str == 'r' || *str == 'w' || *str == 'W' || *str == '-'); m_master->m_ops.back().argwrite(i, *str == 'w' || *str =='W'); m_master->m_ops.back().argread(i, *str == 'r' || *str =='W'); } ASSERT(m_nargs == i); // Fix old bug where oslc forgot to mark getmatrix last arg as write static ustring getmatrix("getmatrix"); if (m_master->m_ops.back().opname() == getmatrix) m_master->m_ops.back().argwrite(m_nargs-1, true); } if (extract_prefix(h, "%argderivs{")) { while (1) { std::string afield = readuntil (h, ",}", true); if (! afield.length()) break; int arg = atoi (afield.c_str()); if (arg >= 0) m_master->m_ops.back().argtakesderivs (arg, true); } } if (extract_prefix (h, "%meta{") && m_master->m_symbols.size()) { Symbol &sym (m_master->m_symbols.back()); int lockval = -1; int ok = sscanf (h.c_str(), " int , lockgeom , %d", &lockval); if (ok) sym.lockgeom (lockval); } }