Skip to content

Commit b0b93d0

Browse files
committed
Add ASTfieldselect base class in preparation for color/vector rgb selectors.
1 parent 020214b commit b0b93d0

File tree

5 files changed

+56
-19
lines changed

5 files changed

+56
-19
lines changed

src/liboslcomp/ast.cpp

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -694,12 +694,12 @@ ASTindex::childname (size_t i) const
694694

695695
ASTstructselect::ASTstructselect (OSLCompilerImpl *comp, ASTNode *expr,
696696
ustring field)
697-
: ASTNode (structselect_node, comp, 0, expr), m_field(field),
697+
: ASTfieldselect (structselect_node, comp, expr, field),
698698
m_structid(-1), m_fieldid(-1), m_fieldsym(NULL)
699699
{
700700
m_fieldsym = find_fieldsym (m_structid, m_fieldid);
701701
if (m_fieldsym) {
702-
m_fieldname = m_fieldsym->name();
702+
m_fullname = m_fieldsym->name();
703703
m_typespec = m_fieldsym->typespec();
704704
}
705705
}
@@ -712,12 +712,7 @@ ASTstructselect::ASTstructselect (OSLCompilerImpl *comp, ASTNode *expr,
712712
Symbol *
713713
ASTstructselect::find_fieldsym (int &structid, int &fieldid)
714714
{
715-
if (! lvalue()->typespec().is_structure() &&
716-
! lvalue()->typespec().is_structure_array()) {
717-
error ("type '%s' does not have a member '%s'",
718-
type_c_str(lvalue()->typespec()), m_field);
719-
return NULL;
720-
}
715+
ASSERT (lvalue()->typespec().is_structure_based());
721716

722717
ustring structsymname;
723718
TypeSpec structtype;
@@ -763,8 +758,7 @@ ASTstructselect::find_structsym (ASTNode *structnode, ustring &structname,
763758
// or array of structs) down to a symbol that represents the
764759
// particular field. In the process, we set structname and its
765760
// type structtype.
766-
ASSERT (structnode->typespec().is_structure() ||
767-
structnode->typespec().is_structure_array());
761+
ASSERT (structnode->typespec().is_structure_based());
768762
if (structnode->nodetype() == variable_ref_node) {
769763
// The structnode is a top-level struct variable
770764
ASTvariable_ref *var = (ASTvariable_ref *) structnode;
@@ -811,6 +805,21 @@ ASTstructselect::print (std::ostream &out, int indentlevel) const
811805

812806

813807

808+
ASTfieldselect* ASTfieldselect::create (OSLCompilerImpl *comp, ASTNode *expr,
809+
ustring field) {
810+
if (expr->typespec().is_structure_based())
811+
return new ASTstructselect (comp, expr, field);
812+
813+
comp->error (comp->filename(), comp->lineno(),
814+
"type '%s' does not have a member '%s'",
815+
comp->type_c_str(expr->typespec()), field);
816+
817+
// Don't leak expr node
818+
delete expr;
819+
return nullptr;
820+
}
821+
822+
814823
const char *
815824
ASTconditional_statement::childname (size_t i) const
816825
{

src/liboslcomp/ast.h

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,28 @@ class ASTindex : public ASTNode
588588

589589

590590

591-
class ASTstructselect : public ASTNode
591+
class ASTfieldselect : public ASTNode
592+
{
593+
protected:
594+
ASTfieldselect (NodeType type, OSLCompilerImpl *comp, ASTNode *expr,
595+
ustring field) :
596+
ASTNode(type, comp, Nothing, expr), m_field(field) {}
597+
598+
ustring m_field; ///< Name of the field
599+
ustring m_fullname; ///< Full name of variable and field
600+
601+
public:
602+
static ASTfieldselect* create (OSLCompilerImpl *comp, ASTNode *expr,
603+
ustring field);
604+
605+
ustring field () const { return m_field; }
606+
ustring fullname () const { return m_fullname; }
607+
ref lvalue () const { return child (0); }
608+
};
609+
610+
611+
612+
class ASTstructselect : public ASTfieldselect
592613
{
593614
public:
594615
ASTstructselect (OSLCompilerImpl *comp, ASTNode *expr, ustring field);
@@ -602,9 +623,7 @@ class ASTstructselect : public ASTNode
602623
/// field.
603624
void codegen_assign (Symbol *dest, Symbol *src);
604625

605-
ref lvalue () const { return child (0); }
606-
ustring field () const { return m_field; }
607-
ustring fieldname () const { return m_fieldname; }
626+
ustring fieldname () const { return fullname(); }
608627
Symbol *fieldsym () const { return m_fieldsym; }
609628

610629
private:
@@ -613,10 +632,8 @@ class ASTstructselect : public ASTNode
613632
TypeSpec &structtype);
614633
Symbol *codegen_index ();
615634

616-
ustring m_field; ///< Name of the field
617635
int m_structid; ///< index of the structure
618636
int m_fieldid; ///< index of the field within the structure
619-
ustring m_fieldname; ///< Name of the field variable
620637
Symbol *m_fieldsym; ///< Symbol of the field variable
621638
};
622639

src/liboslcomp/oslgram.y

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,7 @@ id_or_field
780780
}
781781
| variable_lvalue '.' IDENTIFIER
782782
{
783-
$$ = new ASTstructselect (oslcompiler, $1, ustring($3));
783+
$$ = ASTfieldselect::create (oslcompiler, $1, ustring($3));
784784
}
785785
;
786786

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1-
test.osl:8: error: type 'color' does not have a member 'nope'
2-
test.osl:11: error: struct type 'custom' does not have a member 'bad'
1+
test.osl:11: error: type 'color' does not have a member 'invalid'
2+
test.osl:12: error: type 'color' does not have a member 'nope'
3+
test.osl:15: error: struct type 'custom' does not have a member 'bad'
4+
test.osl:18: error: type 'color' does not have a member 'sinvalid'
5+
test.osl:19: error: type 'color' does not have a member 'error'
36
FAILED test.osl

testsuite/oslc-err-field/test.osl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
// Test invalid field selections in function calls
22

33
struct custom { float field; };
4+
struct A { color valid; };
5+
struct B { A a; };
6+
struct C { B b; };
47

58
shader test ()
69
{
710
color c = color(4,3,2);
11+
c.invalid = 45;
812
printf("c.nope: %g\n", c.nope);
913

1014
custom cc = { 1 };
1115
printf("cc.bad: %g\n", cc.bad);
16+
17+
C nested;
18+
nested.b.a.valid.sinvalid = color(1);
19+
printf("nested.b.a.valid.error: %g\n", nested.b.a.valid.error);
1220
}

0 commit comments

Comments
 (0)