This patch turns DenseArrayBaseAttr into a fully-functional attribute by
adding a generic parser and printer, supporting bool or integer and floating
point element types with bitwidths divisible by 8. It has been renamed
to DenseArrayAttr. The patch maintains the specialized subclasses,
e.g. DenseI32ArrayAttr, which remain the preferred API for accessing
elements in C++.
This allows DenseArrayAttr to hold signed and unsigned integer elements:
array<si8: -128, 127> array<ui8: 255>
"Exotic" floating point elements:
array<bf16: 1.2, 3.4>
And integers of other bitwidths:
array<i24: 8388607>
I'm pretty sure this is incorrect for big-endian systems, e.g. an i8 is stored in the last 8 bytes of a 64-bit word instead of the first byte. I would implement this with a "extract a byte at a time from the low part of an APInt" loop.