Virtual Developer Workshop: Containerized Development with Docker
The VC7 Call Browser is a VS .NET add-in that displays inheritance, file use, variable reference, call, and (most importantly) call-by information for your C++ projects. It is written in C++ with ATL 7, and it only works with VC++ .NET (VC7).
In the screen fragment to the left the VC7 Call Browser (VCB) displays call and call-by information for several member functions from the classic Scribble sample. The InitDocument function is open, revealing the two functions that it is called by (with the blue icon) and then the functions that it calls (with the red icon).
I've included a detailed description of the VCB below, but it is fairly simple to use so you might want to just skim the rest of this page initially, and then return here if you have questions while using it.
The VCB is under continued development. The most important feature still to come is a sync command that will show you a member's call and call-by info with a single key-stroke.
This add-in has a home page at www.malcolmson.com/vcb.
How the Information Is Generated
The data used by the VCB (and by some of the features of the Visual Studio IDE) is generated by the Browser Information Tool from debug data output by the compiler. The Browse Information Tool runs at the end of a compile or build if it is turned on. It can be turned on and off via a project's properties, or using the VCB.
The VCB displays information in a standard Visual Studio tool-window containing a tree control. The top-level of the tree control has the following nodes:
- If any of your projects use MFC or ATL, there is a node for the MFC/ATL library (more on this below).
- There is a node for each C++ project in the current solution. These provide access to all the browse info for the project.
- There is a node for each file open in the editor that belongs to one of the C++ projects. These provide quick access to the browse info for the files that you are currently working on (the files scribble.h & scribble.cpp in the screenshot).
Turning On the Browse Tool
The 'BscReader' project in the screenshot has "(off but available)" appended to its name because it has browse info generation turned off in its project settings, but there is still a browse info file available from an earlier build. To turn the browse information tool back on (or off again), just double-click on the project.
When you open a project it lists all the files used to build that project. The files that are not from the project's home folder (or folders beneath this) are listed seperately, organized by path.
When you open a file, it will display the globals, members, and classes defined in the file, though the members will be displayed inside their class if it is defined in the same file (headers, typically).
Libraries (Including the MFC, ATL, & STL)
If you find that there isn't much call information listed for the headers of a library that you use, it is because only the libraries' headers are part of your project—not the source. So, by default, your project's browse info will include all calls into the library, but not the calls within it. It is possible for you to configure your project to include all the browse data for the libraries it uses, but it is simpler and faster to access the libraries' browse data seperately.
In the case of MFC & ATL, Microsoft ships a browse data file for these libraries with Visual Studio (it is included in a standard installation). If any of the projects in the current solution use these libraries, then the VCB displays an 'MFC/ATL' entry as shown in the screenshot to the left. Since there are so many classes in these libraries the 'less prominent' classes are organized into subfolders.
Note that the class hierarchy (near the top in the screenshot) does not include all of the classes in the library. It includes the main ones—the ones not organized into subfolders - and the classes related to the main ones. Class hierarchies will soon be available for user projects.)
The templates in your libraries are a different story. Just as the object code for template instantiations reside in your program, the related browse info will appear in your program's browse info. As a result, there is no need for a seperate project for the STL. Templates are shown as, and where, they are used, complete with their instantiation parameters. For more on this, see the section on templates, below.
Jumping to the Source Code
If you double-click on a program element—a class, function, variable, or file—then the releveant file will be opened in the Visual Studio editor with the first line of the element's definition highlighted. If it highlights the wrong line it is probably because the browse info is not in sync with the source code, or because of unusual weather patterns.
Those who have used the MFC/ATL browse info might have noted that it can't be used to jump to source code. The VCB fixes that problem, so you can jump into the MFC and ATL source code. The only exception to this is the class hierarchy - double clicking on a class in the hierarchy has no effect.
As mentioned above, the browse information is a reflection of the code used by your program. This means that information is available for each instantiation of a template, so the name of the template is displayed with the parameters of each instantiation listed below it. One disadvantage of this is that if your source code contains a template that doesn't get instantiated, the VCB will not display it.
For function templates and for class templates used as function parameters, the template parameters are not displayed. They are removed in order to keep the symbol names short. In MFC7 CString is typedef'ed to a template, so a type such as std::map<CString*, CString*> would get expanded into something quite long and ugly. Some template expansions are so long (more than 217 chars) that the name gets truncated, in which case you will see '<...' at the end of the name.
The hierarchy includes all the classes defined in the project folder or subfolders—these are displayed in bold—plus their descendents and bases.
A tree control is not, of course, very good at displaying multiple inheritance. MI is currently handled by displaying the client class multiple times—once beneath each of the classes it inherits from. Inverse hierarchies have also been implemented but these don't appear to be useful in the majority of case. The best solution seems to be to show the regular hierarchy (as in the screenshot) plus inverse mini-hierarchies that just show cases of MI.
Other Projects by the Same Author
These three projects are all written in C++ for Win32, and are open-source with a flexible BSD style license.
To use the VCB, follow these steps:
- Download the install file. This is version 1.4.2.
- Install it by selecting Install from the file's context menu.
- Start Visual Studio, select the Add-In Manager from the Tools menu, and then check the box to the left of the 'Call Browser' add-in. You can also check the box in the start-up column if you want the VCB to start automatically each time you run Visual Studio.
This will start the VCB and add a 'Call Browser' entry to the IDE's Tools menu.
There is a page of FAQ's here.
The Source Code
If there is sufficient interest then I will write a seperate article about the source code. In the meantime, if you have questions just post them here and I will try to respond.
The source code is a little in advance of the executable. It includes changes I've made to start adapting it to work with managed dotNet projects.
If you base your own project on my source code but sure to change the names and the GUID's so that our add-ins don't conflict.