| 832 | |
| 833 | |
| 834 | void |
| 835 | ASTNode::codegen_initlist (ref init, TypeSpec type, Symbol *sym) |
| 836 | { |
| 837 | // If we're doing this initialization for shader params for their |
| 838 | // init ops, we need to take care to set the codegen method names |
| 839 | // properly. |
| 840 | bool paraminit = (m_compiler->codegen_method() != m_compiler->main_method_name() && |
| 841 | (sym->symtype() == SymTypeParam || |
| 842 | sym->symtype() == SymTypeOutputParam)); |
| 843 | |
| 844 | if (type.is_structure()) { |
| 845 | // Special case -- structure : Recurse to handle each field |
| 846 | // individually. |
| 847 | StructSpec *structspec (type.structspec()); |
| 848 | for (int i = 0; init && i < structspec->numfields(); init = init->next(), ++i) { |
| 849 | const StructSpec::FieldSpec &field (structspec->field(i)); |
| 850 | ustring fieldname = ustring::format ("%s.%s", sym->mangled(), |
| 851 | field.name); |
| 852 | Symbol *fieldsym = m_compiler->symtab().find_exact (fieldname); |
| 853 | if (paraminit) { |
| 854 | ASSERT (nodetype() == variable_declaration_node); |
| 855 | ASTvariable_declaration *v = (ASTvariable_declaration *)this; |
| 856 | std::string out; |
| 857 | if (v->param_default_literals(fieldsym, init.get(), out)) |
| 858 | continue; // Skip if we had a static initalizer |
| 859 | } |
| 860 | codegen_initlist (init, fieldsym->typespec(), fieldsym); |
| 861 | } |
| 862 | return; |
| 863 | } |
| 864 | |
| 865 | if (paraminit) { |
| 866 | // For parameter initialization, don't really generate ops if it |
| 867 | // can be statically initialized. |
| 868 | m_compiler->codegen_method (sym->name()); |
| 869 | sym->initbegin (m_compiler->next_op_label ()); |
| 870 | } |
| 871 | |
| 872 | // Special case for arrays initialized by only constants of the |
| 873 | // right type. |
| 874 | ASSERT (sym->typespec() == type); |
| 875 | if (type.is_array() && ! type.is_closure_based() && |
| 876 | ! type.is_structure_array()) { |
| 877 | TypeDesc elemtype = type.simpletype().elementtype(); |
| 878 | bool all_const = true; |
| 879 | int length = 0; |
| 880 | for (ref i = init; i; i = i->next(), ++length) { |
| 881 | // It's not a constant if the initializer isn't a literal |
| 882 | if (i->nodetype() != ASTNode::literal_node) { |
| 883 | all_const = false; |
| 884 | break; |
| 885 | } |
| 886 | // Also check that the initializer type is equivalent to the |
| 887 | // element type of the array, but allow for float arrays with |
| 888 | // int literal initializers. |
| 889 | TypeDesc itype = i->typespec().simpletype(); |
| 890 | if (itype != elemtype && |
| 891 | !(itype == TypeDesc::INT && elemtype == TypeDesc::FLOAT)) { |
nothing calls this directly
no test coverage detected