@@ -620,8 +620,8 @@ ASTNode::codegen_assign_struct (StructSpec *structspec,
620620
621621
622622bool
623- ASTvariable_declaration::param_one_default_literal (const Symbol *sym,
624- ASTNode *init, std::string &out, const std::string & sep) const
623+ ASTNode::one_default_literal (const Symbol *sym, ASTNode *init ,
624+ std::string &out, string_view sep) const
625625{
626626 // FIXME -- this only works for single values or arrays made of
627627 // literals. Needs to be seriously beefed up.
@@ -792,7 +792,7 @@ ASTvariable_declaration::param_default_literals (const Symbol *sym,
792792 for (int i = 0 ; i==0 || init; ++i, init = init->nextptr ()) {
793793 if (i)
794794 out += separator;
795- completed &= param_one_default_literal (sym, init, out, separator);
795+ completed &= one_default_literal (sym, init, out, separator);
796796 if (! compound || ! init)
797797 break ;
798798 }
@@ -831,15 +831,14 @@ ASTvariable_declaration::codegen_initializer (ref init, Symbol *sym)
831831
832832
833833void
834- ASTvariable_declaration::codegen_initlist (ref init, TypeSpec type,
835- Symbol *sym)
834+ ASTNode::codegen_initlist (ref init, TypeSpec type, Symbol *sym)
836835{
837836 // If we're doing this initialization for shader params for their
838837 // init ops, we need to take care to set the codegen method names
839838 // properly.
840839 bool paraminit = (m_compiler->codegen_method () != m_compiler->main_method_name () &&
841- (m_sym ->symtype () == SymTypeParam ||
842- m_sym ->symtype () == SymTypeOutputParam));
840+ (sym ->symtype () == SymTypeParam ||
841+ sym ->symtype () == SymTypeOutputParam));
843842
844843 if (type.is_structure ()) {
845844 // Special case -- structure : Recurse to handle each field
@@ -850,9 +849,13 @@ ASTvariable_declaration::codegen_initlist (ref init, TypeSpec type,
850849 ustring fieldname = ustring::format (" %s.%s" , sym->mangled (),
851850 field.name );
852851 Symbol *fieldsym = m_compiler->symtab ().find_exact (fieldname);
853- std::string out;
854- if (paraminit && param_default_literals (fieldsym, init.get (), out))
855- continue ; // Skip if we had a static initalizer
852+ if (paraminit) {
853+ ASSERT (nodetype () == variable_declaration_node);
854+ ASTvariable_declaration *v = (ASTvariable_declaration *)this ;
855+ std::string out;
856+ if (v->param_default_literals (fieldsym, init.get (), out))
857+ continue ; // Skip if we had a static initalizer
858+ }
856859 codegen_initlist (init, fieldsym->typespec (), fieldsym);
857860 }
858861 return ;
@@ -954,17 +957,18 @@ ASTvariable_declaration::codegen_initlist (ref init, TypeSpec type,
954957
955958
956959Symbol *
957- ASTvariable_declaration::codegen_struct_initializers (ref init, Symbol *sym)
960+ ASTNode::codegen_struct_initializers (ref init, Symbol *sym,
961+ bool is_constructor)
958962{
959963 // If we're doing this initialization for shader params for their
960964 // init ops, we need to take care to set the codegen method names
961965 // properly.
962966 bool paraminit = (m_compiler->codegen_method () != m_compiler->main_method_name () &&
963- (m_sym ->symtype () == SymTypeParam ||
964- m_sym ->symtype () == SymTypeOutputParam));
967+ (sym ->symtype () == SymTypeParam ||
968+ sym ->symtype () == SymTypeOutputParam));
965969
966970 ASSERT (sym->typespec ().is_structure ());
967- if (init->nodetype () != compound_initializer_node) {
971+ if (init->nodetype () != compound_initializer_node && !is_constructor ) {
968972 // Just one initializer, it's a whole struct of the right type.
969973 Symbol *initsym = init->codegen (sym);
970974 if (initsym != sym) {
@@ -977,7 +981,9 @@ ASTvariable_declaration::codegen_struct_initializers (ref init, Symbol *sym)
977981 }
978982
979983 // General case -- per-field initializers
980- init = ((ASTcompound_initializer *)init.get ())->initlist ();
984+ if (init->nodetype () == compound_initializer_node) {
985+ init = ((ASTcompound_initializer *)init.get ())->initlist ();
986+ }
981987 StructSpec *structspec (sym->typespec ().structspec ());
982988 for (int i = 0 ; init && i < structspec->numfields (); init = init->next (), ++i) {
983989 // Structure element -- assign to the i-th member field
@@ -995,7 +1001,9 @@ ASTvariable_declaration::codegen_struct_initializers (ref init, Symbol *sym)
9951001 // For parameter initialization, don't really generate ops if it
9961002 // can be statically initialized.
9971003 std::string out;
998- if (param_default_literals (fieldsym, init.get (), out))
1004+ ASSERT (nodetype () == variable_declaration_node);
1005+ ASTvariable_declaration *v = (ASTvariable_declaration *)this ;
1006+ if (v->param_default_literals (fieldsym, init.get (), out))
9991007 continue ;
10001008
10011009 // Delineate and remember the init ops for this field individually
@@ -1639,6 +1647,14 @@ ASTfunction_call::argwrite (int arg) const
16391647Symbol *
16401648ASTfunction_call::codegen (Symbol *dest)
16411649{
1650+ if (is_struct_ctr ()) {
1651+ // Looks like function call, but is actually struct constructor
1652+ if (! dest)
1653+ dest = m_compiler->make_temporary (typespec ());
1654+ codegen_struct_initializers (args (), dest, true /* is_constructor*/ );
1655+ return dest;
1656+ }
1657+
16421658 // Set up a return destination if not passed one (or not the right type)
16431659 if (! typespec ().is_void ()) {
16441660 if (dest == NULL || ! equivalent (dest->typespec (), typespec ()))
0 commit comments