/// 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; }
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); }