@@ -175,7 +175,28 @@ static jl_value_t *resolve_definition_effects(jl_value_t *expr, jl_module_t *mod
175175 jl_task_t * ct = jl_current_task ;
176176 jl_value_t * fptr = jl_exprarg (e , 0 );
177177 // Handle dot expressions in tuple arguments for ccall by converting to GlobalRef eagerly
178- if (jl_is_expr (fptr ) && ((jl_expr_t * )fptr )-> head == jl_symbol ("tuple" )) {
178+ jl_sym_t * tuple_sym = jl_symbol ("tuple" );
179+ if (jl_is_quotenode (fptr )) {
180+ if (jl_is_string (jl_quotenode_value (fptr )) || jl_is_tuple (jl_quotenode_value (fptr )))
181+ fptr = jl_quotenode_value (fptr );
182+ }
183+ if (jl_is_tuple (fptr )) {
184+ // convert literal Tuple to Expr tuple
185+ jl_expr_t * tupex = jl_exprn (tuple_sym , jl_nfields (fptr ));
186+ jl_value_t * v = NULL ;
187+ JL_GC_PUSH2 (& tupex , & v );
188+ for (long i = 0 ; i < jl_nfields (fptr ); i ++ ) {
189+ v = jl_fieldref (fptr , i );
190+ if (!jl_is_string (v ))
191+ v = jl_new_struct (jl_quotenode_type , v );
192+ jl_exprargset (tupex , i , v );
193+ }
194+ jl_exprargset (e , 0 , tupex );
195+ fptr = (jl_value_t * )tupex ;
196+ JL_GC_POP ();
197+ }
198+ if (jl_is_expr (fptr ) && ((jl_expr_t * )fptr )-> head == tuple_sym ) {
199+ // verify Expr tuple can be interpreted and handle
179200 jl_expr_t * tuple_expr = (jl_expr_t * )fptr ;
180201 size_t nargs_tuple = jl_expr_nargs (tuple_expr );
181202 if (nargs_tuple == 0 )
@@ -212,15 +233,26 @@ static jl_value_t *resolve_definition_effects(jl_value_t *expr, jl_module_t *mod
212233 }
213234 }
214235 else if (jl_is_quotenode (arg )) {
215- jl_value_t * quoted_val = jl_quotenode_value (arg );
216- if (!jl_is_symbol (quoted_val ) && !jl_is_string (quoted_val ))
217- jl_type_error ("ccall function name" , (jl_value_t * )jl_symbol_type , quoted_val );
236+ if (i == 0 ) {
237+ // function name must be a symbol or string, library can be anything
238+ jl_value_t * quoted_val = jl_quotenode_value (arg );
239+ if (!jl_is_symbol (quoted_val ) && !jl_is_string (quoted_val ))
240+ jl_type_error ("ccall function name" , (jl_value_t * )jl_symbol_type , jl_quotenode_value (arg ));
241+ }
218242 }
219243 else if (!jl_is_globalref (arg ) && jl_isa_ast_node (arg )) {
220- jl_type_error ("ccall function name" , (jl_value_t * )jl_symbol_type , arg );
244+ jl_type_error (i == 0 ? "ccall function name" : "ccall library name" , (jl_value_t * )jl_symbol_type , arg );
221245 }
222246 }
223247 }
248+ else if (jl_is_string (fptr ) || (jl_is_quotenode (fptr ) && jl_is_symbol (jl_quotenode_value (fptr )))) {
249+ // convert String to Expr (String,)
250+ // convert QuoteNode(Symbol) to Expr (QuoteNode(Symbol),)
251+ jl_expr_t * tupex = jl_exprn (tuple_sym , 1 );
252+ jl_exprargset (tupex , 0 , fptr );
253+ jl_exprargset (e , 0 , tupex );
254+ fptr = (jl_value_t * )tupex ;
255+ }
224256 jl_value_t * rt = jl_exprarg (e , 1 );
225257 jl_value_t * at = jl_exprarg (e , 2 );
226258 if (!jl_is_type (rt )) {
0 commit comments