Beispiel #1
0
ast_result_t expr_ffi(pass_opt_t* opt, ast_t* ast)
{
  if(!package_allow_ffi(&opt->check))
  {
    ast_error(opt->check.errors, ast, "This package isn't allowed to do C FFI");
    return AST_FATAL;
  }

  AST_GET_CHILDREN(ast, name, return_typeargs, args, namedargs, question);
  assert(name != NULL);

  ast_t* decl;
  if(!ffi_get_decl(&opt->check, ast, &decl, opt))
    return AST_ERROR;

  if(decl != NULL)  // We have a declaration
    return declared_ffi(opt, ast, decl);

  // We do not have a declaration
  for(ast_t* arg = ast_child(args); arg != NULL; arg = ast_sibling(arg))
  {
    ast_t* a_type = ast_type(arg);

    if((a_type != NULL) && is_type_literal(a_type))
    {
      ast_error(opt->check.errors, arg,
        "Cannot pass number literals as unchecked FFI arguments");
      return AST_ERROR;
    }
  }

  ast_t* return_type = ast_child(return_typeargs);

  if(return_type == NULL)
  {
    ast_error(opt->check.errors, name,
      "FFIs without declarations must specify return type");
    return AST_ERROR;
  }

  ast_settype(ast, return_type);
  ast_inheritflags(ast);

  if(ast_id(question) == TK_QUESTION)
    ast_seterror(ast);

  return AST_OK;
}
Beispiel #2
0
bool expr_ffi(pass_opt_t* opt, ast_t* ast)
{
  AST_GET_CHILDREN(ast, name, return_typeargs, args, namedargs, question);
  assert(name != NULL);

  ast_t* decl;
  if(!ffi_get_decl(&opt->check, ast, &decl, opt))
    return false;

  if(decl != NULL)  // We have a declaration
    return declared_ffi(opt, ast, decl);

  // We do not have a declaration
  for(ast_t* arg = ast_child(args); arg != NULL; arg = ast_sibling(arg))
  {
    ast_t* a_type = ast_type(arg);

    if((a_type != NULL) && is_type_literal(a_type))
    {
      ast_error(opt->check.errors, arg,
        "Cannot pass number literals as unchecked FFI arguments");
      return false;
    }
  }

  ast_t* return_type = ast_child(return_typeargs);

  if(return_type == NULL)
  {
    ast_error(opt->check.errors, name,
      "FFIs without declarations must specify return type");
    return false;
  }

  ast_settype(ast, return_type);

  return true;
}