@@ -865,9 +865,9 @@ ASTswizzle::print (std::ostream &out, int indentlevel) const
865865
866866
867867ASTNode* ASTfieldselect::create (OSLCompilerImpl *comp, ASTNode *expr,
868- ustring field)
868+ ustring field, bool swizzle )
869869{
870- if (expr->typespec ().is_structure_based ())
870+ if (!swizzle && expr->typespec ().is_structure_based ())
871871 return new ASTstructselect (comp, expr, field);
872872
873873 const TypeSpec &type = expr->nodetype () != structselect_node ? expr->typespec () :
@@ -883,13 +883,16 @@ ASTNode* ASTfieldselect::create (OSLCompilerImpl *comp, ASTNode *expr,
883883 int indexes[3 ];
884884 switch (ASTswizzle::indices (field, indexes, 3 , true )) {
885885 case 1 : {
886+ // c.0 && c.1 not allowed
887+ ASSERT (indexes[0 ] >= 0 );
886888 if (!index)
887889 return new ASTindex (comp, expr, new ASTliteral (comp, indexes[0 ]));
888890 index->extend (new ASTliteral (comp, indexes[0 ]));
889891 return index;
890892 }
891893
892894 case 3 : {
895+ bool allconst = true ;
893896 // Don't leak soon to be unused expr node
894897 std::unique_ptr<ASTNode> cleanup (index);
895898 ASTNode* index0 = nullptr ;
@@ -901,6 +904,7 @@ ASTNode* ASTfieldselect::create (OSLCompilerImpl *comp, ASTNode *expr,
901904 ASTNode *args[3 ];
902905 for (int i = 0 ; i < 3 ; ++i) {
903906 if (indexes[i] >= 0 ) {
907+ allconst = false ;
904908 args[i] = new ASTliteral (comp, indexes[i]);
905909 if (i == 0 && index) {
906910 // Re-use expr by extending the ASTindex.
@@ -918,6 +922,14 @@ ASTNode* ASTfieldselect::create (OSLCompilerImpl *comp, ASTNode *expr,
918922 }
919923 args[0 ]->append (args[1 ]);
920924 args[1 ]->append (args[2 ]);
925+
926+ if (allconst) {
927+ // return a type constructor instead of a swizzle
928+ ASSERT (!cleanup);
929+ // initial expression will be unused
930+ cleanup.reset (expr);
931+ return new ASTtype_constructor (comp, type, args[0 ]);
932+ }
921933 return new ASTswizzle (comp, args[0 ], field);
922934 }
923935
0 commit comments