Finding a function definition using a call in C++ - c++

I'm trying to understand the source code of a fairly large C++ project. The source wasn't written with an IDE, so I don't have a "goto" button to go straight to the function definition.
For example:
srand();
I want to find out exactly where the function srand() is defined.
The only method I can come up with is manually checking all the header includes to recursively find the declaration and the corresponding file for the definition.
This is a linux environment and the source is compiled with g++ (using cmake).

Look into the ctags program.
ctags generates a file with information on the locations in the code where each identifier is used. It is then possible to use a plugin for your editor of choice that will allow you to jump to the definition of any identifier. (very mature ctags plugins exist for Vim and Emacs, and probably for most other popular editors as well.)

If you are using VI you can shift+k that will open it in a man page, if there is one for this word. I believe it automatically is set to search in man(3) but i'm not 100% sure. At least this way you can know wether it's a system function or not.
Another option is to use Doxygen to setup the call graphs and let it generate the source (even if there are no comments). With the call graph you can easily spot from where each function is coming from.

Related

Discovering Symbol Usage

Issue
I have recently found myself working with a large, unfamiliar, multi-department, C++ codebase in need of better organization. I would like to discover a way to map which symbols are used by which source files for any given header. This is in the hope that if only one department uses a given function, then it can be moved out of the shared area and into that department's area.
Attempts
My first thoughts were to use the symbol table: ie. compile the project and dump the symbols for each object file. From there I figured I could simply write a script to check if the symbols from my header file were used. While this approach seems viable, it would require me to create a list of symbols I am looking for from the headers. With my limited knowledge, I am unsure of how to automate such a process, and with hundreds of headers files to test, doing it manually is out of the question.
Questions
Is my approach valid? If so..
What can I use to generate the symbol names from my header file?
If not..
What else can I do?
Additionally, while I am using Linux, most of the development teams work in Windows only environments. What utilities could I use on both platforms?
Any and all help is greatly appreciated.
When I need to clean up APIs I sometimes use information from callcatcher. It basically builds a database of all symbols while compiling and allows you to determine what symbols are used in some build product.
I sometimes also use DXR (code on github, an example installation) to browse what code defined where is used how. In contrast to callcatcher with DXR you can drill down to much finer detail. Setting up DXR is pretty heavy duty, but might be worth it if you have enough code to work with.
On the other side of the spectrum there are tools like cscope. Even though it doesn't work super nicely with C++ code it is still very useful. If you deal with more than a couple 100kloc you will quickly feel limited though.
If I had to pick only one of these tools and would be working on a large code base (>1Mloc) I would definitely pick DXR.
You can get a reasonable start on the information that you've described by using doxygen.
Even for source that doesn't contain the doxygen formatted comments the documentation created can contain a list of places (ie. source files) where a particular symbol is used.
And, as doxygen can be used to generate html documentation, navigating through your source tree becomes trivial. It's can be even better if you enable the dot functionality to generate relationship diagrams for the classes in your source tree.
very old-school, simple, and possibly unix only, but are you aware of etags? there's also gnu global which i think is similar.
the gnu global link refers to the "comparison with similar tools" discussion here which might also be useful.

Using vim for coding with in a big C++ project

Is there any plugin for VIM that I can use to index an C++ project code base?
I would apreciate functionalities like being capable of specifing a class and and may be a method and see what file/line the method/class is defined.
Regarding code navigation (and completion),
I'd take a look at clang_indexer (and clang_complete) --
ctag understanding of C++ code is quite bad, but universal-ctags has greatly improved the situation ; cscope understanding of C++ is non-existent.
Regarding plugins for C++ coding,
I have a suite for C and C++ programming. It is mainly oriented toward C++ programming, however a few, and unique features can be used in C as well:
context sensitive snippets (they require other plugins I'm maintaining);
a way to jump to a function definition from its declaration (or create it on the fly if it doesn't exists yet) (it used to requires the plugin alternate, which is a must have, however that I've forked it for my own needs) -> :GOTOIMPL;
a little tool that lists functions with a declaration and no definition, or functions with a definition and no declaration (NB: I haven't used it against C static function yet) (it requires ctags).
:Override that searches for overridable functions
:DOX that analyses C++ function signature to generate the appropriate (customizable) doxygen comment (with \param, \throw, ...)
a mapping to include the header file where the symbol under the cursor is defined* (which requires an up-to-date ctags base)
and few other things
Otherwise, I also use:
plugins like project/local_vimrc in order to have project specific settings ;
searchInRuntime to open/jump to files without the need to browse the directories of the current project ;
a refactoring plugin (that still lacks a few things ...) ;
a wrapper around :make in order to do background compiling, and to filter &makeprg results (e.g. pathnames conversions between cygwin posix form and dos form ; application of STLfilt ; etc.) (-> BuildToolWrapper which is stable, but still in an alpha stage) ;
and a few other things which have already been mentioned (alternate, ctags, ...).
Other Plugins.
Other people use c.vim, other templating systems (snipmate & co), pyclewn (that I highly recommend for debugging (with gdb) from within vim), other bracket-surrounding-and-expansion systems, ...
PS: I've answered, slightly differently, a question on the same subject on quora.
cscope is a nice tool for browsing. There is nice tutorial here.
ctags is another nice tool, I use it in my projects. Tutorial here. If you are in Ubuntu, you can install ctags by doing:
apt-get install exuberant-ctags
gtags is another tool.
I use taglist extensively.
The "Tag List" plugin is a source code browser for the Vim editor. It provides an overview of the structure of source code files and allows you to efficiently browse through source code files in different programming languages. It is the top-rated and most-downloaded plugin for the Vim editor.

Determining where a type is defined

I am working on a rather large code base that has a bit of the #ifdef magic going on. I'm looking at one file and trying to determine where a type is defined. Unfortunately, it includes many file, which include many files, which include many files, etc. some of which define macros that affect which definitions you might use. The structure is sufficiently complicated that after 10 minutes worth of grepping and following the include chains, I still have no idea which definition is being used. I recall that visual studio has a nice feature where I can right click on the type and it will show where the type is defined. Is there an equivalent nice tool for linux that reads make files, etc? I'm sure there is, but I still just use vim + grep for my development environment.
With complicated defines and dependencies this feature doesn't always work in Visual Studio either.
Solution: ask your compiler to dump the code after it was preprocessed, ask it to print #line and #file directives too. Search through the resulted file for your type, then look at the closest #file directive to see where it came from.
(In GCC you can use the -E switch)

C++ source tagging

Any suggestions on a quality way to tag and search c++ code. I use cscope/ctags for most stuff, but I have found it insufficient to find my way around some of the overly complex c++ code at work. I have started to switch from vim to Slickedit (which is still not perfect, but better) for browsing code, but would like to go back to exclusively vim.
What I would like is something that can understand scope of class members so, for instance, if I search for references to a member of a class where the same member name exists in other classes (and possibly out of c++ code) it will only give me the relevant references.
I'd prefer something that already works nice with vim, but any open source package such that I might create a plugin myself would be fine.
Any suggestions appreciated, thanks.
Are you sure you called ctags with the right options? For C++, I use:
ctags --c++-kinds=+p --fields=+iaS --extras=+q --language-force=C++
This is what the documentation has to say about the --c++-kinds=+p option:
When parsing a C++ member function definition (e.g.
"className::function"), ctags cannot determine whether the scope specifier
is a class name or a namespace specifier and always lists it as a class name
in the scope portion of the extension fields. Also, if a C++
function is defined outside of the class declaration (the usual case), the
access specification (i.e. public, protected, or private) and
implementation information (e.g. virtual, pure virtual) contained in the function
declaration are not known when the tag is generated for the function
definition. It will, however be available for prototypes
(e.g --c++-kinds=+p).
The --fields=+iaS option:
a Access (or export) of class members
i Inheritance information
S Signature of routine (e.g. prototype or parameter list)
The --extras=+q option:
Because, by default, ctags only generates tags for the separate identifiers found in the source files. If you specify the --extra=+q option, then ctags will also generate a
second, class-qualified tag for each class member (data and function/method) in the form class::member for C++, and in the form class.method for Eiffel and Java.
The --language-force=C++ option:
By default, ctags automatically selects the language of a source file, ignoring those files whose language cannot be determined (see SOURCE FILES, above). This option forces the specified language (case-insensitive; either built-in or user-defined) to be used for every supplied file instead of automatically selecting the language based upon its extension. In addition, the special value auto indicates that the language should be automatically selected (which effectively disables this option).
use doxygen its a great tool to browse code and see classes and members relations with each other. the tool produces clickable html output for your source code with references for each usage. you can compile it to a searchable chm file or use a web server to search the code for keywords.
Try GNU global http://www.gnu.org/software/global/
It can generate navigate:able web pages of your source code as well as having support for vim and a command line interface that is often useful.
I've no experience with this, but I have used Doxygen to browse the source code of complex projects. Just run it with all the settings turned on, and it will generate call graphs, callee graphs, reference and referenced-by relations, template instantiations, etc. Output formats include HTML, LaTeX, CHM, POD
Hope this works!
For a while I have been mixing different tools for this purposes. Vi is a great editor and you can run it over remote computers without hassles, but the completion information is not semantical.
When confronted with a big problem I tend to use either Eclipse CDT or QTCreator, in both cases the latest versions, versions from a year back are not really so nice. QTCreator is a lightweight tool, but I have been quite impressed on its ability to analyze the code. Eclipse CDT is heavier weight, but I am a little more used to the interface, so at the end I tend to use it.
The project I am working on is compiled within a separated sandbox, where none of those two IDEs can be used, but you can get a copy of the repository just for analysis and use the IDE just as a browsing tool.
instead of extras, extra worked for me. Also specified -R to scan all files/folders recursively.
ctags -R --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++

Any program or trick to find the definition of a variable?

Many times when I am watching others code I just want to find where and how a variable is defined. Normally what I do now is look for the type of the variable until I find the definition, that is very time consuming. And I guess that there are some tools that can help me in this rutinary situation. Any suggestion in some tools or commands to help me in this task?.
I know that using a GUI and creating a project this is done automatically I am talking of a way to do this without a GUI. I am working with only text mode. I am running under Linux and I am using C/C++, but suggestions for other languages are welcome.
Thanks a lot.
A possible solution
Michel in one of his comments propose a simple an effective solution define again the variable, in that case in compilation time, the compiler will inform where is the previous definiton. Of course to apply this solution we need to think previously in the locality of the variable.
You've already given the most appropriate tool: an IDE. This is exactly the kind of thing which an IDE excels at. Why would you not want to use an IDE if you're finding development painful without one?
Note that Emacs, Vim etc can work as IDEs - I'm not talking about forcing you the world of GUIs if you want to stay in a text-only situation, e.g. because you're SSHing in.
(I'm really not trying to be rude here. I just think you've discounted the obvious solution without explaining why.)
Edit: OK, you say you're using C++. I'm editing my response. I would use the C preprocessor and then grep for the variable. It will appear in the first place.
cpp -I...(preprocessor options here) file.cpp | grep variable
The C preprocessor will join all the includes that the program uses, and the definition has to be before any usage of that variable in the file. Not a perfect thing, but without an IDE or a complete language description/managing tool, you only have the text.
Another option would be using ctags. It understands the C and C++ syntaxes (among others), and can be searched for variables and functions using command line tools, emacs and vi, among others.
I use cscope and ctags-exuberant religiously. Run it once on my code base and then in Vim, I can use various commands like ^] or [D or [I or similar to find any definitions or declarations for a given word.
This is similar to facilities provided by mega-IDEs like Visual Studio and Eclipse.
Cscope also functions as a stand-alone tool that performs these searches.
I use one of three methods:
I will use CTags to process my source tree (nightly) and then can easily use commands in Vim (or other editors) to jump right to the definition.
I will just use grep (linux) or findstr (windows) to look for all occurrences of the variable name or type. The definition is usually quite obvious.
In Vim, you can just search backward in the scope and often find what you are looking for.
Grep for common patterns for variable declarations. Example: *, &, > or an alphanumeric followed by one or more whitespace characters then the name of the variable. Or variable name followed by zero or more whitespace characters, then a left parenthesis or a semicolon. Unless it was defined under really weird circumstances (like with some kind of macro), it works every time.
In VIM you can use gd to see local variable declarations or gD to see global variable declarations, if they're defined in the current file. Reference Go_to_definition_using_g
You can also use [i to see the definition without jumping to it, or [I to see all occurrences of the variable in all the included files as well, which will naturally show the definition as well.
If you work in Microsoft Visual Studio (which I think you could use for C++ as well, but would require working on a Windows workstation) there's an easily accessible right-click menu option for "Go to Definition...", which will take you to the definition of any currently marked variable, type or method.
if you insist on staying text mode, you can do this with either emacs or vi with the appropriate plug-ins.
But really, move into the 21st century.
EDIT: You commented that you are doing this over SSH because you need the build speed of the remote server cluster.
In that case, mount the drive on your local machine and use an IDE, and just SSH in to kick off a build.