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++
Related
When I include a header file, I often wonder what was pulled in.
What functions are now available to me?
what classes can I instantiate and what are their functions?
Is anything wrapped in a namespace?
Is anything in the global namespace?
Documentation does not always answer these questions nor provide any guarantee.
I could look at the source, but it becomes difficult to observe for large header files that also include a tree of other headers.
Is there any good programs out there to do this kind of analysis?
Use a tool like doxygen. You feed it your library's sources and it outputs cross-referenced documentation.
You can use the -E (or /E; all C and C++ compilers used to have this option using exactly this name) option of the compiler to get a preprocessed output of a translation unit. This dumps all declarations seen by the compiler. It seems, you are after just the functions and classes while the -E option would also write all declarations. If you really just want the functions and classes, you could use the clang library to get hold of the abstract syntax tree (AST) and dump out just these.
If you are using Visual Studio, an option for this is using code helpers such as MS intellisense, wholetomato visual assist or resharper. These may provide you with all accessible variables, classes, functions, types, namespaces, constants, etc... in a given context.
Other IDEs may provide this feature too but I've never used it other than in Visual Studio. It seems like QtCreator may be a good option as pointed here.
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.
Frequently, a class/struct is dependent on other classes/structs, which in turn are dependent on other classes/structs. In big projects, this can easily lead to confusion. Is there a tool (preferably a simple text-only command-line tool) that can show how classes or structs are nested/aggregated/related? Support for inheritance is not needed...
I think Doxygen is the best solution, when combinated with graphviz's dot.
http://www.graphviz.org/
http://www.doxygen.org/
The configuration of Doxygen is carried out by a configuration text file, and after that, you can re-launch it as soon as any file has changed, even automatically from another tool.
Using Dot, you'll get diagrams of class relations.
Doxygen does also parse the files and colors its syntax, it is a matter of checking the configuration file for five minutes.
$ doxygen -g app.dox
[...edit app.dox]
$ doxygen app.dox
GDB command - ptype typename
Print inheritance relationships as well as other information for type typename.
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.
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.