@@ -113,13 +113,6 @@ ASTvariable_declaration::typecheck (TypeSpec expected)
113113 init = ((ASTcompound_initializer *)init.get ())->initlist ();
114114 }
115115
116- if (m_typespec.is_structure ()) {
117- // struct initialization handled separately
118- return typecheck_struct_initializers (init, m_typespec, m_name.c_str ());
119- }
120-
121- typecheck_initlist (init, m_typespec, m_name.c_str ());
122-
123116 // Warning to catch confusing comma operator in variable initializers.
124117 // One place this comes up is when somebody forgets the proper syntax
125118 // for constructors, for example
@@ -138,103 +131,6 @@ ASTvariable_declaration::typecheck (TypeSpec expected)
138131
139132
140133
141- void
142- ASTNode::typecheck_initlist (ref init, TypeSpec type, string_view name)
143- {
144- // Loop over a list of initializers (it's just 1 if not an array)...
145- for (int i = 0 ; init; init = init->next (), ++i) {
146- // Check for too many initializers for an array
147- if (type.is_array () && !type.is_unsized_array () && i >= type.arraylength ()) {
148- error (" Too many initializers for a '%s'" , type_c_str (type));
149- break ;
150- }
151- // Special case: ok to assign a literal 0 to a closure to
152- // initialize it.
153- if ((type.is_closure () || type.is_closure_array ()) &&
154- ! init->typespec ().is_closure () &&
155- init->typespec ().is_int_or_float () &&
156- init->nodetype () == literal_node &&
157- ((ASTliteral *)init.get ())->floatval () == 0 .0f ) {
158- continue ; // it's ok
159- }
160- // Allow struct s = { ... }; vector v = { ... };
161- if (type.is_structure_based () || (!type.is_closure () && type.is_triple ()))
162- continue ;
163- if (! type.is_array () && i > 0 )
164- error (" Can't assign array initializers to non-array %s %s" ,
165- type_c_str (type), name);
166- if (! assignable (type.elementtype (), init->typespec ()))
167- error (" Can't assign '%s' to %s %s" , type_c_str (init->typespec ()),
168- type_c_str (type), name);
169- }
170- }
171-
172-
173-
174- TypeSpec
175- ASTNode::typecheck_struct_initializers (ref init, TypeSpec type,
176- string_view name)
177- {
178- ASSERT (type.is_structure ());
179-
180- if (! init->next () && init->typespec () == type) {
181- // Special case: just one initializer, it's a whole struct of
182- // the right type.
183- return type;
184- }
185-
186- // General case -- per-field initializers
187-
188- const StructSpec *structspec (type.structspec ());
189- int numfields = (int )structspec->numfields ();
190- for (int i = 0 ; init; init = init->next (), ++i) {
191- if (i >= numfields) {
192- error (" Too many initializers for '%s %s'" ,
193- type_c_str (type), name);
194- break ;
195- }
196- const StructSpec::FieldSpec &field (structspec->field (i));
197-
198- if (init->nodetype () == compound_initializer_node) {
199- // Initializer is itself a compound, it ought to be initializing
200- // a field that is an array.
201- ASTcompound_initializer *cinit = (ASTcompound_initializer *)init.get ();
202- ustring fieldname = ustring::format (" %s.%s" , name, field.name );
203- if (field.type .is_array ()) {
204- typecheck_initlist (cinit->initlist (), field.type , fieldname);
205- } else if (field.type .is_structure ()) {
206- typecheck_struct_initializers (cinit->initlist (), field.type ,
207- fieldname);
208- } else if (cinit->typecheck (field.type ) != field.type ) {
209- // Is this message still neccessary? typecheck above should have
210- // reported a more specific message.
211- error (" Can't use '{...}' for a struct field that is not an "
212- " array, vector, or constructable" );
213- }
214- continue ;
215- }
216-
217- init->typecheck (field.type );
218-
219- // Ok to assign a literal 0 to a closure to initialize it.
220- if (field.type .is_closure () && ! init->typespec ().is_closure () &&
221- (init->typespec ().is_float () || init->typespec ().is_int ()) &&
222- init->nodetype () == literal_node &&
223- ((ASTliteral *)init.get ())->floatval () == 0 .0f ) {
224- continue ; // it's ok
225- }
226-
227- // Normal initializer, normal field.
228- if (! assignable (field.type , init->typespec ()))
229- error (" Can't assign '%s' to '%s %s.%s'" ,
230- type_c_str (init->typespec ()),
231- type_c_str (field.type ), name, field.name );
232- }
233- return type;
234- }
235-
236-
237-
238134TypeSpec
239135ASTvariable_ref::typecheck (TypeSpec expected)
240136{
@@ -1425,7 +1321,10 @@ ASTfunction_call::typecheck_struct_constructor ()
14251321 error (" Constructor for '%s' has the wrong number of arguments (expected %d, got %d)" ,
14261322 structspec->name (), structspec->numfields (), listlength (args ()));
14271323 }
1428- return typecheck_struct_initializers (args (), m_typespec, " this" );
1324+
1325+ ASTcompound_initializer::TypeAdjuster (m_compiler)
1326+ .typecheck_fields (this , args ().get (), m_typespec);
1327+ return m_typespec;
14291328}
14301329
14311330
0 commit comments