Create sub module with atom name

__CALLER__ looks good for me and there should not be any problem. As always just an example to check what you worry about:

defmodule MyLib do
  defmacro my_macro(name, do: block) do
    module =
      name
      |> Atom.to_string()
      |> Macro.camelize()
      |> String.to_atom()
      |> then(&Module.concat(__CALLER__.module, &1))

    quote do
      defmodule unquote(module) do
        _ = unquote(block)
      end
    end
  end
end

defmodule A do
  import MyLib

  my_macro :b do
    my_macro :c do
      IO.inspect(__MODULE__)
    end
  end
end

The above code prints A.B.C. :+1: