static void cg_emit_proc_prototype()

in sources/cg_c.c [3429:3513]


static void cg_emit_proc_prototype(ast_node *ast, charbuf *proc_decl) {
  Contract(is_ast_create_proc_stmt(ast) || is_ast_declare_proc_stmt(ast));
  EXTRACT_NOTNULL(proc_params_stmts, ast->right);
  EXTRACT(params, proc_params_stmts->left);
  EXTRACT_MISC_ATTRS(ast, misc_attrs);

  CSTR name;

  if (is_ast_create_proc_stmt(ast)) {
    EXTRACT_STRING(n, ast->left);
    name = n;
  }
  else {
    EXTRACT_NOTNULL(proc_name_type, ast->left);
    EXTRACT_STRING(n, proc_name_type->left);
    name = n;
  }

  bool_t private_proc = misc_attrs && exists_attribute_str(misc_attrs, "private");
  bool_t dml_proc = is_dml_proc(ast->sem->sem_type);
  bool_t result_set_proc = has_result_set(ast);
  bool_t out_stmt_proc = has_out_stmt_result(ast);
  bool_t out_union_proc = has_out_union_stmt_result(ast);

  // if you're doing out_union then the row fetcher is all there is
  CSTR suffix = out_union_proc ? "_fetch_results" : "";

  CG_CHARBUF_OPEN_SYM(proc_name_base, name);
  CG_CHARBUF_OPEN_SYM(proc_sym, name, suffix);

  if (private_proc) {
    bprintf(proc_decl, "static ");
  }

  bool_t need_comma = 0;
  if (dml_proc) {
    bprintf(proc_decl, "CQL_WARN_UNUSED %s %s(sqlite3 *_Nonnull _db_", rt->cql_code, proc_sym.ptr);
    if (result_set_proc) {
      bprintf(proc_decl, ", sqlite3_stmt *_Nullable *_Nonnull _result_stmt");
    }
    need_comma = 1;
  }
  else {
    bprintf(proc_decl, "void %s(", proc_sym.ptr);
  }

  if (out_union_proc) {
    CG_CHARBUF_OPEN_SYM(result_set_ref, name, "_result_set_ref");

    if (need_comma) {
      bprintf(proc_decl, ", ");
    }

    // result set type
    bprintf(proc_decl, "%s _Nullable *_Nonnull _result_set_", result_set_ref.ptr);

    need_comma = 1;
    CHARBUF_CLOSE(result_set_ref);
  }

  // CREATE PROC [name] ( [params] )
  if (params) {
    if (need_comma) {
      bprintf(proc_decl, ", ");
    }
    cg_params(params, proc_decl);
  }

  if (out_stmt_proc) {
    if (dml_proc || params) {
      bprintf(proc_decl, ", ");
    }

    CG_CHARBUF_OPEN_SYM(result_type, name, "_row");
    bprintf(proc_decl, "%s *_Nonnull _result_", result_type.ptr);
    CHARBUF_CLOSE(result_type);
  }

  if (!params && !out_stmt_proc && !out_union_proc && !dml_proc) {
    bprintf(proc_decl, "void");  // make foo(void) rather than foo()
  }

  CHARBUF_CLOSE(proc_sym);
  CHARBUF_CLOSE(proc_name_base);
}