This chapter describes the Static Analyzer, which is the WorkShop tool for examining the structure of a program's source code and the relationships between its parts, such as files, functions, and variables.
Many software projects today contain massive amounts of code that may or may not compile, have few or no comments, and are written by programmers unfamiliar with the original code. The ProDev WorkShop Static Analyzer helps solve problems like these. With the Static Analyzer, you can analyze source code written in C, C++, Fortran 77, Fortran 90 or 95.
The Static Analyzer shows you code structure, including how functions within programs call each other, where and how variables are defined, how files depend on each other, where you can find macros, and other structural details to help you understand the code. It displays answers in text or easily understood graphic form. Because the Static Analyzer is interactive, you can quickly locate the portion of code structure that interests you, or you can step back for an overview. And, because the Static Analyzer recognizes the connections between elements of the source code, you can readily trace how a proposed change to one element will affect related elements.
The following topics are covered in this chapter:
The Static Analyzer is basically a database program that reads through one or more source code files and creates a database that includes functions, macros, variables, files, and object-oriented elements for the C or C++ programming languages. The database also includes the interconnections between the elements--which functions call which other functions, which files include which other files, and so on.
|Note: Limited support for Fortran 90 is provided for the MIPSPro Fortran 90 compiler, beginning with version 7.1.|
The Static Analyzer provides two modes for extracting static analysis data from your source files:
The trade-off between the modes is speed versus accuracy. A very effective technique is to perform preliminary analysis in scanner mode when you need to see the overall structure of a large group of files and then focus on a smaller subset using parser mode to derive detailed relationship information. If a program cannot compile, parser mode will not work and you must use scanner mode.
The Static Analyzer can perform selective searches (called queries) through the database. The Static Analyzer displays the results of the query in the query results area (the interior of the main window). If you have used the UNIX grep(1) command, you will find that the Static Analyzer can perform the same kinds of simple searches through the text of your source code, finding strings of text as well as regular expressions. The Static Analyzer also performs more sophisticated queries that follow connections between the following elements of source code: function calls, file includes, class parenthood, and other similar relationships.
When making queries, try not to request too much data. Overly general queries (for example, a query that asks for all functions defined in millions of lines of source code) often return extensive results that are difficult to comprehend. The Static Analyzer can restrict the scope of your queries so you can break down large projects into pieces of a manageable size. For example, you can see the connections to and from a single function or take a look at all the classes defined within a single file.
By default, the Static Analyzer displays the results of your query in text form. You can scroll through the results, and you can immediately call up the file that contains any element you see in the results. The file appears in the Source View window, which shows you the exact source code line where that element occurs. You can also ask the Static Analyzer to display the results of the query in a graphic view that shows not only the elements found but also--using tree form--the relationships between elements. To help you see the structure more clearly, you can set the scale and orientation of the tree, or you can call for a full overview that shows all elements in the structure and helps you scroll to the particular elements you want.
Typically, in performing static analysis, you create an overview showing basic relationships and then concentrate on the source code requiring further work or analysis. There are five general steps in the static analysis process:
Decide which files to include in your static analysis.
It is good practice to narrow down the set of files to be analyzed as much as possible. Large static analysis databases are not only difficult to navigate through, but are time-consuming to build. You specify the files to be used in a special file called a fileset.
Choose how the files will be analyzed: parser mode, scanner mode, a combination, or different modes in multiple passes.
Scanner mode is good for determining the general structure of a program. It is most appropriate when you are working on uncompilable code, analyzing large filesets, or performing preliminary analysis. Parser mode is better when you need detailed relationship information. You should apply parser mode to smaller filesets, because it takes longer to extract data.
In some situations, it is desirable to use a combination of modes. For example, if you need detail but are having compilation problems, you can apply the scanner to the problem files and the parser to everything else. A different example would be applying the parser to a few files where you need detail and the scanner to the rest of the fileset.
An example of a multiple-pass scenario is to analyze a large fileset in scanner mode, zero in on a subset of the files, and then run that subset through parser mode to get a detailed analysis.
Build the static analysis database.
Both scanner mode and parser mode can be invoked within the Static Analyzer. After you have defined your fileset, the database will be built when you make your first query or when you select either the Rescan or the Force Scan option from the Admin menu of the Static Analyzer main window.
Generally, you can invoke parser mode through the compiler. A particularly convenient method for using the Static Analyzer parser is to modify an existing makefile so that it analyzes the files as part of the build process. This can be done with or without producing object code. For more information on this approach, see “Using the Compiler to Create a Static Analysis Database” in Chapter 2.
Perform static analysis queries and view the results.
The queries can give you a good idea of the structure and the relationship of components in your program. You can review the results in text form, as a list of items and their source lines or graphically as a tree showing relationships between items.
If you are programming in C++ you can make object-oriented queries by bringing up the class browser in the Class View window. This window lets you view structural and relational information.
Once you have isolated an area for analysis, you can edit the source code from the Static Analyzer. Double-clicking an element brings up the corresponding source code in the Source View window.