unsafe fn define_function_with_visibility<T: Into<Vec<u8>>>(
        &mut self,
        ret_ty: LLVMTypeRef,
        arg_tys: &mut [LLVMTypeRef],
        visibility: LLVMLinkage,
        name: T,
    ) -> (LLVMValueRef, LLVMBuilderRef, LLVMBasicBlockRef) {
        let func_ty = LLVMFunctionType(ret_ty, arg_tys.as_mut_ptr(), arg_tys.len() as u32, 0);
        let name = CString::new(name).unwrap();
        let function = LLVMAddFunction(self.module(), name.as_ptr(), func_ty);
        // Add the default attributes to all functions.
        llvm_exts::LLVMExtAddDefaultAttrs(self.context(), function);

        let builder = LLVMCreateBuilderInContext(self.context());
        let block = LLVMAppendBasicBlockInContext(self.context(), function, c_str!(""));
        LLVMPositionBuilderAtEnd(builder, block);
        LLVMSetLinkage(function, visibility);
        (function, builder, block)
    }
Generates code to define a function with the given return type and argument type.

Returns a reference to the function, a builder used to build the function body, and the
entry basic block.
weld/src/codegen/llvm2/mod.rs