The history of developing the PVS-Studio version for Embarcadero RAD Studio

23.04.2013 Paul Eremeev
C++ Builder support in PVS-Studio had been dropped after version 5.20. If you have any questions, feel free to contact our support.

I suppose most readers of our blog already knew that PVS-Studio is a static analyzer for C/C++ source code. But I believe that few of you really wonder about what a static code analyzer actually is, while studying analysis results under your favorite IDE. But if you come to think of it, an analyzer is but a simple command-line application that requires cumbersome and intricate cfg files to operate properly and a long command line for it to be launched. Besides, it is possible to launch the analyzer to check only one file at a time, so you have to launch it individually for each file if you want to check them all, and the analysis results are generated in the form of a common plain-text log. But these aspects of the analyzer's operation are, of course, hidden from the end user inside an IDE plugin. It is this plugin that, directly interacting with the project loaded in IDE, collects all the necessary parameters, generates command lines, and finally performs the verification of all of the necessary source files - and does so in a parallel mode, exploiting all of the available processor cores on a multi-processor system. And it actually executes all of this by just one simple mouse click on the "check project" command.

In fact, the analyzer, of course, is not designed to be used directly by developers, and in this aspect it very much resembles other programming and building tools, such as compilers, linkers, debuggers, etc. But an employment of the analyzer is not limited only in by the form of a plugin for Microsoft IDEs, of course. As with any other command-line tool, it can be integrated directly into a project's build system, for example into MSBuild or make based one. This procedure requires a certain level of understanding of design and functioning principles of a particular build system in the first place, and certainly of the command-line analyzer itself.

We have always strived to make this scenario of our tool usage to as easy as possible for our customers. For that purpose we have implemented the support for various popular preprocessors into the tool (for instance gcc and clang, as the analyzer should in any case be able to parse code specific to C++ dialects that these compilers employ) and provided compatibility with popular continuous integration systems. We even released an individual plugin for the MSBuild build system (don't mix it up with an IDE plugin!) not a long time ago so that you could integrate the analyzer into this system by simply adding just a couple of lines into your build script.

Such a method of code analysis execution, however, is still not a match for the direct integration of the tool into the IDE as a plugin. The reason is that besides the necessity to modify build scripts, you also need to somehow handle analysis results generated by the tool. And it could be achieved in a most convenient way exactly through an IDE plugin, as it provides both a comprehensible representation of results and the ability for navigation through code fragments containing issues reported by the analyzer, by the means of IDE's native code editor. This is not to mention such indispensable options provided by the editor as syntax highlighting and navigation through macro and type definitions. Of course, you can still meet some developers who write their code in plain text editors, build it directly from the command line, and then manually link a debugger to a running process. Although this approach is more flexible and "ideologically true", it is hard to deny the convenience of using a full-feature IDE that keeps these 'insides' hidden from the developer, allowing him not to get distracted from the process of writing the application itself. The same thing is true with static analysis as well: you feel more comfortable when everything runs directly "out of the box", and not distracting you from the process of search for errors in your code.

Until version 5.00, the PVS-Studio distribution kit had shipped with a plugin for only one IDE, Microsoft Visual Studio, or, to be more exact, for Visual Studio 2005 and later versions. But starting with version 5.00 of PVS-Studio, the distribution kit includes a similar plugin for another development environment — Embarcadero RAD Studio (for versions 2009, 2010, XE, XE2, and XE3). In addition to that, we have also implemented the support for the bcc preprocessor (C++Builder's preprocessor) in the command line analyzer itself. It enables all the users of this IDE to use the PVS-Studio analyzer to the full extent, without having to perform "shamanic rites" and manually parse analysis logs (or, as a workaround, install Visual Studio specifically to handle them through the PVS-Studio IDE plugin).

C++Builder (as a part of RAD Studio IDE designed for C++ development) is obviously not the most popular IDE among Windows C++ developers. It may well appear less popular than such environments (besides Visual Studio, of course) as Eclipse and QtCreator. So why did we choose to support this particular IDE? Certainly, the main reason was the simplicity of porting the existing Visual Studio plugin to C++Builder. Unfortunately, as PVS-Studio is currently not a cross-platform project, neither is its Visual Studio plugin. Such IDEs as Eclipse and QtCreator are, on the contrary, cross-platform orientated and designed for cross-platform software development. So, porting of our plugin to such IDEs will be practically impossible. We would have to develop an absolutely new product instead. And that implies more expenses on testing and maintenance, which must not be underestimated even in case of such a seemingly simple application as an IDE plugin. We should also keep in mind that these IDESs are widely spread first of all among the open-source community, and purchasing a proprietary close-source commercial product like PVS-Studio would be an exception rather than a common practice among developers from the open-source ecosystem. C++Builder, on the other hand, is highly popular, due to understandable reasons, in the corporate sector which currently happens to be our product's main target. Besides, despite its relative oblivion at present, C++Builder used to be (together with Delphi closely related to it) pretty popular thanks to the VCL library and, as a consequence, has left large amounts of legacy code which still is required to be maintained and, therefore, analyzed. Embarcadero's activity in the last couple of years, namely a debut of the 64-bit mode for XE3 version, orientation for cross-platform development, and intensive promotion of the new FireMonkey framework for replacing the aging VCL, gives a hope for a renaissance of this IDE.

Now, let's discuss in more detail the process of developing our extension for RAD Studio, or, to be more exact, the process of porting the existing Visual Studio plugin to this IDE. We employ C# together with.NET/WinForms to develop our IDE plugin. Therefore, it is natively supported in the Visual Studio environment. Visual Studio itself, or rather, its core, is a native application (however, more and more of its components get redesigned for WPF in each new version), so its interaction with the managed plugin is arranged in an indirect way, through COM interfaces. These interfaces form the so called Visual Studio Extensibility APIs. It may seem strange at first, but RAD Studio is also capable to load managed libraries as plugins and it provides similar COM interfaces for such libraries. It is probably a hard legacy of the stillborn C#Builder project which was meant to enable development for .NET Framework under RAD Studio. The set of these interfaces is united under the term OTA (Open Tools API). Theoretically you can communicate with these interfaces from under any external application. We need to mention here that RAD Studio provides one more set of interfaces to develop native extensions (i.e. bpl libraries) which is called NTA (Native Tools API). What's interesting is that some functionality (like that creation of dockable MDI tool windows) is available only to clients utilizing these interfaces, and these interfaces are, unfortunately, available only for native IDE plugins written in C++Builder/Delphi. But even the limited OTA functionality satisfied our needs up to 99%, while the most noticeable feature we've missed was those very dockable MDI tool windows.

Even though both IDEs (Visual Studio and RAD Studio) provide COM interfaces for managed plugins, they are quite different. A logical step when porting our IDE plugin to C++Builder was to isolate the code that utilizes these interfaces into some individual entity with its own unified interface. That is, it can be called a "wrapper" for IDE interfaces. This in its turn allows us to create implementations of this "wrapper" for other IDEs as well, and in particular, for RAD Studio. For example, we have the internal command "open file in IDE editor". It will have different wrapper implementations for each particular IDE, but the rest plugin's code will use a single signature to perform this action. But such an approach was not utilized from the beginning, since the plugin had not initially implied supporting several IDEs, and so the invocations to IDE APIs were spread all over the code. But after some minor refactoring we managed to clear the plugin's code of API-dependent fragments without changing the operation logic, achieving the source code reuse at the level of about 80% for our new IDE plug-in. Moreover, besides providing an identical functionality of the IDE plugin for RAD Studio, this refactoring theoretically enables us to use these general components to create plugins for any build platform with the ability to load managed code. In fact, the MSBuild plugin mentioned above also employs a part of this general code as well.

In conclusion, we need to mention that the process of plugin redesign described above will perhaps allow us to create an independent full-feature UI version of our analyzer. Similar to some open-source projects of a similar kind, this will be a step towards PVS-Studio becoming truly a platform-independent project.