Reflection in a langauge only allows you to see what source code information the language designers thought was useful to keep, in most modern languages just function names, parameter types and classes.
If you want to do full code analysis, you always end up needing the source code. It doesn't make sense to store the source with the object code (frankly, if you had both, you'd just ditch the object code on the ground that's easy to get!).
Rather than insist that the langauge provide full access, you can simply step outside the langauge and get tools that can analyze the source code directly. Such tools can contain parsers for the full language, can build compiler data structures with useful facts ("who calls X?"), and make those facts available to your automated application.
One tool that can do this for many langauges (C, C++, Java, COBOL, C#, ...) is
The DMS Software Reengineering Toolkit.