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