@@ -779,9 +779,9 @@ ASTswizzle::print (std::ostream &out, int indentlevel) const
779779
780780
781781ASTNode* ASTfieldselect::create (OSLCompilerImpl *comp, ASTNode *expr,
782- ustring field)
782+ ustring field, bool swizzle )
783783{
784- if (expr->typespec ().is_structure_based ())
784+ if (!swizzle && expr->typespec ().is_structure_based ())
785785 return new ASTstructselect (comp, expr, field);
786786
787787 const TypeSpec &type = expr->nodetype () != structselect_node ? expr->typespec () :
@@ -797,13 +797,16 @@ ASTNode* ASTfieldselect::create (OSLCompilerImpl *comp, ASTNode *expr,
797797 int indexes[3 ];
798798 switch (ASTswizzle::indices (field, indexes, 3 , true )) {
799799 case 1 : {
800+ // c.0 && c.1 not allowed
801+ ASSERT (indexes[0 ] >= 0 );
800802 if (!index)
801803 return new ASTindex (comp, expr, new ASTliteral (comp, indexes[0 ]));
802804 index->extend (new ASTliteral (comp, indexes[0 ]));
803805 return index;
804806 }
805807
806808 case 3 : {
809+ bool allconst = true ;
807810 // Don't leak soon to be unused expr node
808811 std::unique_ptr<ASTNode> cleanup (index);
809812 ASTNode* index0 = nullptr ;
@@ -815,6 +818,7 @@ ASTNode* ASTfieldselect::create (OSLCompilerImpl *comp, ASTNode *expr,
815818 ASTNode *args[3 ];
816819 for (int i = 0 ; i < 3 ; ++i) {
817820 if (indexes[i] >= 0 ) {
821+ allconst = false ;
818822 args[i] = new ASTliteral (comp, indexes[i]);
819823 if (i == 0 && index) {
820824 // Re-use expr by extending the ASTindex.
@@ -832,6 +836,14 @@ ASTNode* ASTfieldselect::create (OSLCompilerImpl *comp, ASTNode *expr,
832836 }
833837 args[0 ]->append (args[1 ]);
834838 args[1 ]->append (args[2 ]);
839+
840+ if (allconst) {
841+ // return a type constructor instead of a swizzle
842+ ASSERT (!cleanup);
843+ // initial expression will be unused
844+ cleanup.reset (expr);
845+ return new ASTtype_constructor (comp, type, args[0 ]);
846+ }
835847 return new ASTswizzle (comp, args[0 ], field);
836848 }
837849
0 commit comments