@@ -123,6 +123,8 @@ sub elem
123
123
my @no_read ;
124
124
# node types we don't want read/write support for
125
125
my @no_read_write ;
126
+ # node types that have handmade read/write support
127
+ my @special_read_write ;
126
128
# node types we don't want any support functions for, just node tags
127
129
my @nodetag_only ;
128
130
@@ -152,9 +154,12 @@ sub elem
152
154
# since we won't use its internal structure here anyway.
153
155
push @node_types , qw( List) ;
154
156
# Lists are specially treated in all four support files, too.
155
- push @no_copy , qw( List) ;
156
- push @no_equal , qw( List) ;
157
- push @no_read_write , qw( List) ;
157
+ # (Ideally we'd mark List as "special copy/equal" not "no copy/equal".
158
+ # But until there's other use-cases for that, just hot-wire the tests
159
+ # that would need to distinguish.)
160
+ push @no_copy , qw( List) ;
161
+ push @no_equal , qw( List) ;
162
+ push @special_read_write , qw( List) ;
158
163
159
164
# Nodes with custom copy/equal implementations are skipped from
160
165
# .funcs.c but need case statements in .switch.c.
@@ -338,16 +343,7 @@ sub elem
338
343
}
339
344
elsif ($attr eq ' special_read_write' )
340
345
{
341
- # This attribute is called
342
- # "special_read_write" because there is
343
- # special treatment in outNode() and
344
- # nodeRead() for these nodes. For this
345
- # script, it's the same as
346
- # "no_read_write", but calling the
347
- # attribute that externally would probably
348
- # be confusing, since read/write support
349
- # does in fact exist.
350
- push @no_read_write , $in_struct ;
346
+ push @special_read_write , $in_struct ;
351
347
}
352
348
elsif ($attr =~ / ^nodetag_number\( (\d +)\) $ / )
353
349
{
@@ -681,6 +677,9 @@ sub elem
681
677
{
682
678
" unless $struct_no_equal ;
683
679
680
+ # track already-processed fields to support field order checks
681
+ my %previous_fields ;
682
+
684
683
# print instructions for each field
685
684
foreach my $f (@{ $node_type_info {$n }-> {fields } })
686
685
{
@@ -697,6 +696,10 @@ sub elem
697
696
if ($a =~ / ^array_size\( ([\w .]+)\) $ / )
698
697
{
699
698
$array_size_field = $1 ;
699
+ # insist that we copy or compare the array size first!
700
+ die
701
+ " array size field $array_size_field for field $n .$f must precede $f \n "
702
+ if (!$previous_fields {$array_size_field });
700
703
}
701
704
elsif ($a =~ / ^copy_as\( ([\w .]+)\) $ / )
702
705
{
@@ -786,6 +789,17 @@ sub elem
786
789
elsif (($t =~ / ^(\w +)\* $ / or $t =~ / ^struct\s +(\w +)\* $ / )
787
790
and elem $1 , @node_types )
788
791
{
792
+ die
793
+ " node type \" $1 \" lacks copy support, which is required for struct \" $n \" field \" $f \"\n "
794
+ if (elem $1 , @no_copy or elem $1 , @nodetag_only )
795
+ and $1 ne ' List'
796
+ and !$copy_ignore ;
797
+ die
798
+ " node type \" $1 \" lacks equal support, which is required for struct \" $n \" field \" $f \"\n "
799
+ if (elem $1 , @no_equal or elem $1 , @nodetag_only )
800
+ and $1 ne ' List'
801
+ and !$equal_ignore ;
802
+
789
803
print $cff " \t COPY_NODE_FIELD($f );\n " unless $copy_ignore ;
790
804
print $eff " \t COMPARE_NODE_FIELD($f );\n " unless $equal_ignore ;
791
805
}
@@ -809,6 +823,8 @@ sub elem
809
823
die
810
824
" could not handle type \" $t \" in struct \" $n \" field \" $f \"\n " ;
811
825
}
826
+
827
+ $previous_fields {$f } = 1;
812
828
}
813
829
814
830
print $cff "
@@ -851,6 +867,7 @@ sub elem
851
867
next if elem $n , @abstract_types ;
852
868
next if elem $n , @nodetag_only ;
853
869
next if elem $n , @no_read_write ;
870
+ next if elem $n , @special_read_write ;
854
871
855
872
my $no_read = (elem $n , @no_read );
856
873
@@ -891,6 +908,11 @@ sub elem
891
908
" ;
892
909
}
893
910
911
+ # track already-processed fields to support field order checks
912
+ # (this isn't quite redundant with the previous loop, since
913
+ # we may be considering structs that lack copy/equal support)
914
+ my %previous_fields ;
915
+
894
916
# print instructions for each field
895
917
foreach my $f (@{ $node_type_info {$n }-> {fields } })
896
918
{
@@ -906,6 +928,10 @@ sub elem
906
928
if ($a =~ / ^array_size\( ([\w .]+)\) $ / )
907
929
{
908
930
$array_size_field = $1 ;
931
+ # insist that we read the array size first!
932
+ die
933
+ " array size field $array_size_field for field $n .$f must precede $f \n "
934
+ if (!$previous_fields {$array_size_field } && !$no_read );
909
935
}
910
936
elsif ($a =~ / ^read_as\( ([\w .]+)\) $ / )
911
937
{
@@ -1083,6 +1109,14 @@ sub elem
1083
1109
elsif (($t =~ / ^(\w +)\* $ / or $t =~ / ^struct\s +(\w +)\* $ / )
1084
1110
and elem $1 , @node_types )
1085
1111
{
1112
+ die
1113
+ " node type \" $1 \" lacks write support, which is required for struct \" $n \" field \" $f \"\n "
1114
+ if (elem $1 , @no_read_write or elem $1 , @nodetag_only );
1115
+ die
1116
+ " node type \" $1 \" lacks read support, which is required for struct \" $n \" field \" $f \"\n "
1117
+ if (elem $1 , @no_read or elem $1 , @nodetag_only )
1118
+ and !$no_read ;
1119
+
1086
1120
print $off " \t WRITE_NODE_FIELD($f );\n " ;
1087
1121
print $rff " \t READ_NODE_FIELD($f );\n " unless $no_read ;
1088
1122
}
@@ -1145,6 +1179,8 @@ sub elem
1145
1179
{
1146
1180
print $rff " \t local_node->$f = $read_as_field ;\n " unless $no_read ;
1147
1181
}
1182
+
1183
+ $previous_fields {$f } = 1;
1148
1184
}
1149
1185
1150
1186
print $off " }
0 commit comments