Skip to content

Commit 28f0f18

Browse files
committed
Add ASTfieldselect base class in preparation for color/vector rgb selectors.
1 parent df98828 commit 28f0f18

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
@@ -608,12 +608,12 @@ ASTindex::childname (size_t i) const
608608

609609
ASTstructselect::ASTstructselect (OSLCompilerImpl *comp, ASTNode *expr,
610610
ustring field)
611-
: ASTNode (structselect_node, comp, 0, expr), m_field(field),
611+
: ASTfieldselect (structselect_node, comp, expr, field),
612612
m_structid(-1), m_fieldid(-1), m_fieldsym(NULL)
613613
{
614614
m_fieldsym = find_fieldsym (m_structid, m_fieldid);
615615
if (m_fieldsym) {
616-
m_fieldname = m_fieldsym->name();
616+
m_fullname = m_fieldsym->name();
617617
m_typespec = m_fieldsym->typespec();
618618
}
619619
}
@@ -626,12 +626,7 @@ ASTstructselect::ASTstructselect (OSLCompilerImpl *comp, ASTNode *expr,
626626
Symbol *
627627
ASTstructselect::find_fieldsym (int &structid, int &fieldid)
628628
{
629-
if (! lvalue()->typespec().is_structure() &&
630-
! lvalue()->typespec().is_structure_array()) {
631-
error ("type '%s' does not have a member '%s'",
632-
type_c_str(lvalue()->typespec()), m_field);
633-
return NULL;
634-
}
629+
ASSERT (lvalue()->typespec().is_structure_based());
635630

636631
ustring structsymname;
637632
TypeSpec structtype;
@@ -677,8 +672,7 @@ ASTstructselect::find_structsym (ASTNode *structnode, ustring &structname,
677672
// or array of structs) down to a symbol that represents the
678673
// particular field. In the process, we set structname and its
679674
// type structtype.
680-
ASSERT (structnode->typespec().is_structure() ||
681-
structnode->typespec().is_structure_array());
675+
ASSERT (structnode->typespec().is_structure_based());
682676
if (structnode->nodetype() == variable_ref_node) {
683677
// The structnode is a top-level struct variable
684678
ASTvariable_ref *var = (ASTvariable_ref *) structnode;
@@ -725,6 +719,21 @@ ASTstructselect::print (std::ostream &out, int indentlevel) const
725719

726720

727721

722+
ASTfieldselect* ASTfieldselect::create (OSLCompilerImpl *comp, ASTNode *expr,
723+
ustring field) {
724+
if (expr->typespec().is_structure_based())
725+
return new ASTstructselect (comp, expr, field);
726+
727+
comp->error (comp->filename(), comp->lineno(),
728+
"type '%s' does not have a member '%s'",
729+
comp->type_c_str(expr->typespec()), field);
730+
731+
// Don't leak expr node
732+
delete expr;
733+
return nullptr;
734+
}
735+
736+
728737
const char *
729738
ASTconditional_statement::childname (size_t i) const
730739
{

src/liboslcomp/ast.h

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

588588

589589

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

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

609628
private:
@@ -612,10 +631,8 @@ class ASTstructselect : public ASTNode
612631
TypeSpec &structtype);
613632
Symbol *codegen_index ();
614633

615-
ustring m_field; ///< Name of the field
616634
int m_structid; ///< index of the structure
617635
int m_fieldid; ///< index of the field within the structure
618-
ustring m_fieldname; ///< Name of the field variable
619636
Symbol *m_fieldsym; ///< Symbol of the field variable
620637
};
621638

src/liboslcomp/oslgram.y

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,7 @@ id_or_field
771771
}
772772
| variable_lvalue '.' IDENTIFIER
773773
{
774-
$$ = new ASTstructselect (oslcompiler, $1, ustring($3));
774+
$$ = ASTfieldselect::create (oslcompiler, $1, ustring($3));
775775
}
776776
;
777777

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)