JavaScript is not currently enabled, but is required for full CodeSonar manual search and browse functionality.
If you are viewing this file in your hub's Web GUI, enable JavaScript in your browser: you will also need it for GUI functionality.
If you opened this file directly from disk, your browser may be directly suppressing JavaScript functionality: certain browsers perform this suppression on local files (but not files delivered by web servers) for security reasons.
| CodeSonar® 9.0p0 Hot Tips | CONFIDENTIAL | CodeSecure Inc |
Visitors specify actions to be carried out on elements of the CodeSonar internal representation (IR) at various stages of the analysis.
Language Module Support: visitors can be applied to C/C++, C#, and Java analyses (including analyses that involve some combination of these). However, C# and Java analyses do not generate internal representation for points or symbols, so point visitors, step visitors, and symbol visitors will generally not produce useful information when applied to those analyses.
Visitors specify actions to be carried out on elements of the CodeSonar internal representation (IR) at various stages of the analysis.
Most visitors consist of a function and a list of languages, except for step visitors (which consist of a set of four functions and a list of languages). Visitors can be attached to any of a number of visitor lists, which determine when and to which IR element types the function will be applied. The list of languages in the visitor provides an additional level of control: the function will only be applied to IR elements whose language appears on the list.
Each visitor list is associated with an element type, a traversal phase, and a visit time.
| element type |
Visitors can be applied to the following IR elements.
For maximal efficiency, use the finest granularity visitor that is appropriate for your check. The finer the granularity, the more likely it is that the analysis structures will fit in memory: a visitor at procedure level or below will probably not incur any page faults at all. All calls will be made from the same thread, so context information can be managed in the global scope if required. |
||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| traversal phase |
Each visitor list is associated with one of five phases.
|
||||||||||||||||||
| visit time | For a specific element type and traversal phase, a visitor list may be associated either with beginning traversal of the element or with finishing traversal of the element. We describe these lists as containing "visitors" and "finish visitors", respectively. |
The following table shows the available visitor types.
| IR element | drop phase | serial depth-first phase | parallel depth-first phase | bottom-up phase | |||
|---|---|---|---|---|---|---|---|
| visitor | finish visitor | visitor | finish visitor | visitor | finish visitor | ||
| program* | x | x | x | x | x | x | x |
| compilation unit | x | x | x | x | x | . | . |
| source file | . | x | x | x | x | . | . |
| source file instance | . | x | x | x | x | . | . |
| procedure (PDG) | x | x | x | x | x | x | x |
| point (PDG_VERTEX) | . | x | . | x | . | x | . |
| symbol (ABS_LOC) | x** | x | . | x | . | . | . |
| CFG edge (step visitors) | . | . | . | . | . | x | . |
Note that there are no finish visitors for source file instances, points (PDG_VERTEX) or variable symbols (ABS_LOC). This is because they are leaves of the traversal trees: no traversal takes place below them, so there is no distinction between starting and finishing.
Program-level visitors are not actually applied during the analysis traversals, but immediately before and after them.
There are several differences between step visitors and the other kinds of visitor:
| open() |
() -> USER_STATE
Create a new USER_STATE: will be called by CodeSonar every time the step traversal enters a function. |
|---|---|
| copy() |
USER_STATE -> USER_STATE
Copy a USER_STATE: will be called by CodeSonar every time the step traversal encounters a branch in the CFG. |
| close() |
USER_STATE -> ()
Close a USER_STATE and perform any necessary cleanup: will be called by CodeSonar when a USER_STATE is no longer needed. |
| transition() |
(USER_STATE, POINT, CFG_EDGE_LABEL, POINT, TRANSFORM,
TRANSFORM, STEP_PATH) -> USER_STATE
Perform any operations associated with a specified transition in the CFG, and return the resulting USER_STATE. Called by CodeSonar every time the step traversal moves across a CFG edge. If the state is stored in USER_STATE, the transition function will not need to depend on the traversal order. However, for the sake of completeness, we note that the step traversal is currently breadth first. This may change in future releases. |
Step visitors have the following limitations.
Note: Step visitors will generally not produce useful information when applied to C# and Java analyses, because internal representation for points is not generated for those analyses .
When CodeSonar runs in incremental mode, drop visitors are applied during the drop phase to IR elements that existed in the previous analysis of the project but will not exist in the current analysis.
Use drop visitors to clean up any additional information that your plug-in has associated with these elements. Drop visitors are not responsible for cleaning up the elements themselves: CodeSonar will do that.
Because the IR elements no longer exist, drop visitors should not access their contents. The only API functions that can be called by drop visitors are:
If the analysis runs in serial mode, all visitors are called by the analysis process. In parallel analyses, responsibility for applying visitors is divided between the analysis master and the analysis slaves as shown in the following table.
| Analysis Phase | Visitor Application |
|---|---|
| drop | All visitors are called by the analysis master. |
| serial depth-first | All visitors are called by the analysis master. |
| parallel depth-first | Program parallel visitors and program parallel finish
visitors are called by the analysis master. Traversal for each compilation unit is handled by a single analysis slave, which calls all visitors applied during that traversal. |
| pointer analysis | (no visitors in this phase) |
| bottom up | The master manages a set of slaves during the bottom-up traversal, with each slave calling all the applicable visitors for a single procedure and the elements it contains. The master is responsible for calling program bottom-up visitors. |
An example trace is provided below.
In incremental analyses, visitors are applied as follows.
| Analysis Phase | Visitor Application |
|---|---|
| drop | Drop visitors are applied, as described above. |
| serial depth-first |
|
| parallel depth-first |
|
| pointer analysis | (no visitors in this phase) |
| bottom up |
|
Here is an example trace of calls that CodeSonar might make to the various visitors for a program with two compilation units, each including foo.h and defining two procedures, each with two points, two CFG edges, and two local symbols. All procedures have no arguments and return void. Assume pdg4 calls pdg1 which calls pdg3 which calls pdg2. The order in which visitors registered with the same function are called is undefined. Assume there is exactly one visitor of each kind.
In this example, the analysis is running in parallel mode (see Visitors in Parallel Analyses above for more information). For the sake of clarity we refer to slaves A, B, C and D in the trace that follows; note that:
CALLING | VISITOR PROCESS | ---------+-------- master | setup_visitor master | program_visitor master | uid_visitor(uid1) master | pdg_visitor(pdg1 in uid1) master | abs_loc_visitor(function abs_loc alf1 corresponding to pdg1) master | abs_loc_visitor(al1 referenced in pdg1) master | abs_loc_visitor(al2 referenced in pdg1) master | pdg_vertex_visitor(v1 in pdg1) master | pdg_vertex_visitor(v2 in pdg1) master | pdg_finish_visitor(pdg1 in uid1) master | pdg_visitor(pdg2 in uid1) master | abs_loc_visitor(function abs_loc alf2 corresponding to pdg2) master | abs_loc_visitor(al3 referenced in pdg2) master | abs_loc_visitor(al4 referenced in pdg2) master | pdg_vertex_visitor(v3 in pdg2) master | pdg_vertex_visitor(v4 in pdg2) master | pdg_finish_visitor(pdg2 in uid1) master | sf_visitor(sfid1 (=comp1.c) ) master | sfi_visitor(sfid1 (=comp1.c) ) master | sf_visitor(sfid2 (=foo.h) ) master | sfi_visitor(sfid2 (=foo.h) ) master | sfi_finish_visitor(sfid2 (=foo.h) ) master | sf_finish_visitor(sfid2 (=foo.h) ) master | sfi_finish_visitor(sfid1 (=comp1.c) ) master | sf_finish_visitor(sfid1 (=comp1.c) ) master | uid_finish_visitor(uid1) master | uid_visitor(uid2) master | pdg_visitor(pdg3 in uid2) master | abs_loc_visitor(function abs_loc alf3 corresponding to pdg3) master | abs_loc_visitor(al5 referenced in pdg3) master | abs_loc_visitor(al6 referenced in pdg3) master | pdg_vertex_visitor(v5 in pdg3) master | pdg_vertex_visitor(v6 in pdg3) master | pdg_finish_visitor(pdg3 in uid2) master | pdg_visitor(pdg4 in uid2) master | abs_loc_visitor(function abs_loc alf4 corresponding to pdg4) master | abs_loc_visitor(al7 referenced in pdg4) master | abs_loc_visitor(al8 referenced in pdg4) master | pdg_vertex_visitor(v7 in pdg4) master | pdg_vertex_visitor(v8 in pdg4) master | pdg_finish_visitor(pdg4 in uid2) master | sf_visitor(sfid3 (=comp2.c) ) master | sfi_visitor(sfid3 (=comp2.c) ) master | sfi_visitor(sfid4 (=foo.h) ) master | sfi_finish_visitor(sfid4 (=foo.h) ) master | sfi_finish_visitor(sfid3 (=comp2.c) ) master | sf_finish_visitor(sfid3 (=comp2.c) ) master | uid_finish_visitor(uid2) master | program_finish_visitor master | program_parallel_visitor slave A | uid_parallel_visitor(uid1) slave A | pdg_parallel_visitor(pdg1 in uid1) slave A | abs_loc_parallel_visitor(function abs_loc alf1 corresponding to pdg1) slave A | abs_loc_parallel_visitor(al1 referenced in pdg1) slave A | abs_loc_parallel_visitor(al2 referenced in pdg1) slave A | pdg_vertex_parallel_visitor(v1 in pdg1) slave A | pdg_vertex_parallel_visitor(v2 in pdg1) slave A | pdg_parallel_finish_visitor(pdg1 in uid1) slave A | pdg_parallel_visitor(pdg2 in uid1) slave A | abs_loc_parallel_visitor(function abs_loc alf2 corresponding to pdg2) slave A | abs_loc_parallel_visitor(al3 referenced in pdg2) slave A | abs_loc_parallel_visitor(al4 referenced in pdg2) slave A | pdg_vertex_parallel_visitor(v3 in pdg2) slave A | pdg_vertex_parallel_visitor(v4 in pdg2) slave A | pdg_parallel_finish_visitor(pdg2 in uid1) slave A | sf_parallel_visitor(sfid1 (=comp1.c) ) slave A | sfi_parallel_visitor(sfid1 (=comp1.c) ) slave A | sf_parallel_visitor(sfid2 (=foo.h) ) slave A | sfi_parallel_visitor(sfid2 (=foo.h) ) slave A | sfi_parallel_finish_visitor(sfid2 (=foo.h) ) slave A | sf_parallel_finish_visitor(sfid2 (=foo.h) ) slave A | sfi_parallel_finish_visitor(sfid1 (=comp1.c) ) slave A | sf_parallel_finish_visitor(sfid1 (=comp1.c) ) slave A | uid_parallel_finish_visitor(uid1) slave B | uid_parallel_visitor(uid2) slave B | pdg_parallel_visitor(pdg3 in uid2) slave B | abs_loc_parallel_visitor(function abs_loc alf3 corresponding to pdg3) slave B | abs_loc_parallel_visitor(al5 referenced in pdg3) slave B | abs_loc_parallel_visitor(al6 referenced in pdg3) slave B | pdg_vertex_parallel_visitor(v5 in pdg3) slave B | pdg_vertex_parallel_visitor(v6 in pdg3) slave B | pdg_parallel_finish_visitor(pdg3 in uid2) slave B | pdg_parallel_visitor(pdg4 in uid2) slave B | abs_loc_parallel_visitor(function abs_loc alf4 corresponding to pdg4) slave B | abs_loc_parallel_visitor(al7 referenced in pdg4) slave B | abs_loc_parallel_visitor(al8 referenced in pdg4) slave B | pdg_vertex_parallel_visitor(v7 in pdg4) slave B | pdg_vertex_parallel_visitor(v8 in pdg4) slave B | pdg_parallel_finish_visitor(pdg4 in uid2) slave B | sf_parallel_visitor(sfid3 (=comp2.c) ) slave B | sfi_parallel_visitor(sfid3 (=comp2.c) ) slave B | sfi_parallel_visitor(sfid4 (=foo.h) ) slave B | sfi_parallel_finish_visitor(sfid4 (=foo.h) ) slave B | sfi_parallel_finish_visitor(sfid3 (=comp2.c) ) slave B | sf_parallel_finish_visitor(sfid3 (=comp2.c) ) slave B | uid_parallel_finish_visitor(uid2) master | program_parallel_finish_visitor master | program_bottom_up_visitor slave A | pdg_bottom_up_visitor(pdg2) slave A | pdg_vertex_bottom_up_visitor(v3 in pdg2) slave A | pdg_vertex_bottom_up_visitor(v4 in pdg2) slave A | step_visitor(cfg edge e3 in pdg2) slave A | step_visitor(cfg edge e4 in pdg2) slave A | pdg_bottom_up_finish_visitor(pdg2) slave B | pdg_bottom_up_visitor(pdg3) slave B | pdg_vertex_bottom_up_visitor(v5 in pdg3) slave B | pdg_vertex_bottom_up_visitor(v6 in pdg3) slave B | step_visitor(cfg edge e5 in pdg3) slave B | step_visitor(cfg edge e6 in pdg3) slave B | pdg_bottom_up_finish_visitor(pdg3) slave C | pdg_bottom_up_visitor(pdg1) slave C | pdg_vertex_bottom_up_visitor(v1 in pdg1) slave C | pdg_vertex_bottom_up_visitor(v2 in pdg1) slave C | step_visitor(cfg edge e1 in pdg1) slave C | step_visitor(cfg edge e2 in pdg2) slave C | pdg_bottom_up_finish_visitor(pdg1) slave D | pdg_bottom_up_visitor(pdg4) slave D | pdg_vertex_bottom_up_visitor(v7 in pdg4) slave D | pdg_vertex_bottom_up_visitor(v8 in pdg4) slave D | step_visitor(cfg edge e7 in pdg4) slave D | step_visitor(cfg edge e8 in pdg4) slave D | pdg_bottom_up_finish_visitor(pdg4) master | program_bottom_up_finish_visitor
Visitors other than step visitors are added by defining a visitor function and then instructing CodeSonar to add it as a particular kind of visitor. Step visitors involve a slightly different mechanism.
In both cases, the adding operation must take place in a specific location.
| API language | Visitors must be added... |
|---|---|
| C++ | ...in the top-level scope of the plug-in, or in cs_plug_main(). |
| Python | ...in the top-level scope of the plug-in. |
| C | ...in cs_plug_main(). |
There are two stages involved in adding a visitor.
| API language | Add a visitor with | Main work of visitor carried out by |
|---|---|---|
| C++ | analysis::add_*_visitor()(vobj,
langs) where vobj points to an instance of a concrete subclass VSC of class visitor with member data suitably initialized. |
vobj->operator() |
| Python | Applying the appropriate visitor decorator to visitor function vf(). | vf() |
| C | csonar_add_*_visitor(langs, vf,
ctx) Where vf points to the visitor function. |
vf() |
There are three stages involved in adding a step visitor.
| API language | USER_STATE corresponds to |
|---|---|
| C++ | an instance of a concrete cs::step_state subclass |
| Python | an instance of a concrete cs.step_state subclass |
| C | data of type cs_step_user_state_t (treated as opaque by CodeSonar) |
| API language | Add a step visitor with... | Step Visitor Operations | |||
|---|---|---|---|---|---|
| open | copy | transition | close | ||
| C++ |
analysis::add_step_bottom_up_visitor(ssobj,
langs) where ssobj points to an instance of a concrete subclass SSSC of class step_state with member data suitably initialized. |
ssobj->copy() | SSSC::copy() | SSSC::transition() | SSSC destructor |
| Python |
analysis.add_step_bottom_up_visitor(ssobj,
langs) where ssobj is an instance of a concrete subclass SSSC of class step_state with member data suitably initialized. |
ssobj.copy() | SSSC.copy() | SSSC.transition() | SSSC destructor |
| C |
csonar_add_step_bottom_up_visitor( langs, svis, ctx
) where svis points to a cs_step_visitor_dispatch_t |
svis->open() | svis->copy() | svis->transition() | svis->close() |
The following table shows the API functions for adding visitors at the various build/analysis phases.
General Information:
| Visitors (this page) |
Plug-ins are based on visitors, which specify actions to be carried out on elements of the CodeSonar internal representation (IR) at various stages of the analysis. |
|---|---|
| Writing Plug-Ins | General information about creating plug-ins to attach custom functionality to the CodeSonar analysis. |
| Custom Checks: Accounting for Incrementality | Ensuring that custom checks implemented in plug-ins generate appropriate results in incremental analyses. |
| Plug-In Tutorial | Two annotated example plug-ins (each provided in all API languages), with building and installation instructions. |
| AST API Tutorial | The AST API tutorial (provided in all API languages) also uses plug-ins. |
Specific API Language:
| Plug-In Guidelines | Key API References | |
|---|---|---|
| C++ | Writing C++ Plug-Ins | classes analysis, visitor, warningclass, project_metricclass, compunit_metricclass, sfile_metricclass, procedure_metricclass. |
| Python | Writing Python Plug-Ins | Visitor decorators, Metric decorators; classes analysis, warningclass, project_metricclass, compunit_metricclass, sfile_metricclass, procedure_metricclass. |
| C | Writing C Plug-Ins | CodeSonar Plug-In API: C Functions and Types for Visitors, Warnings, and Metrics |