GHC already collects all RdrNames for imported things, for use when reporting unused imports. But it doesn’t collect the SrcSpan of the occurrences, nor does it collect occurrences of locally-bound things.
I suggest you write a general traversal looking like
data Gather var res
= Gather { g_empty :: res
, g_union :: res -> res -> res
, g_occ :: Located var -> res
, g_del :: Located var -> res -> res }
getExpr :: Gather v res -> HsExpr v -> res
.. and similarly for each other data type...