Improve and document Reference methods to get the datatypes
For:
integer, dimension(10) :: a
x = a(i)
psyir[0].rhs.datatype evaluates to integer, which makes sense in the context of psyir nodes because datatype is a property that exists in all nodes and evaluates the node subtree to get the resulting datatype.
However, when dealing with references, it can be ambiguous because if we do:
for reference in psyir.walk(Reference):
reference.datatype
it still evaluates to integer, but users could expect the "datatype of the reference", which we actually get with:
for reference in psyir.walk(Reference):
reference.symbol.datatype
At the very least we need to document this prominently as it is a common gotcha. And to make things more confusing, reference has a reference.is_array method that returns self.symbol.is_array, which is unfortunately the contrary to what the chose for the datatype method, and some could easily be expected to get ininstance(referende.datatype, ArrayType). I think we should remove this method and let users be clear of the intent with self.symbol.is_array or self.datatype.is_array.
We could probably improve all this chekcing datatypes API because in fact, the previous snippet is wrong because not all symbols are DataSymbols, so we need an extra check that we often forget:
for reference in psyir.walk(Reference):
if isinstance(reference, DataSymbol):
reference.symbol.datatype
else:
And then there is the datatype condition that we are writing this code for, making it quite ugly with all the required nested conditions.
So, to clarify the last point, we could add a datatype method to the Symbol class and have it return NoType() to make this clear.
Rename is_array on ArrayMixin and Refernce to is_array_access.
The Symbol.is_array generic implementation is also probably wrong, it defaults to False when for a generic symbol we don't know, I think it is meant the be is_array_access mentioned above