According to the documentation all GLSL types except void can be used as uniform. That does not include user defined data types.
Am no crack in Godot shading language but know a bit about GLSL. There, that can't work. Any implementation of a C or C++ compiler is free to choose whatever memory layout it pleases for user-defined data types (here structs and classes, which are the same). So there must be a way to transmit that extra description together with a struct, like what datatypes come, how many bytes do they use, their memory order, is there any padding in between to fill spaces, and GDScript would have to do the same.
GLSL and its C specification solves this with uniform blocks and pre defined memory layouts, and a set of functions to query a shader's interface, it's list of uniforms and other buffer objects. Unless Godot shading language offers an own way of handling these interfaces (that'll be a lot of work on all the platforms), I believe that you have to pass in all the uniforms one by one. Though that's very slow compared to a properly set up GLSL or Vulkan buffer object.
But wait for a crack to show up with better knowledge about Godot shading language, maybe there's a way I'm not aware of.