Beispiel #1
0
/// 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);
}