Conditional Static Analysis of C source?
Mon, 28 Mar 1994 19:18:01 GMT

          From comp.compilers

Related articles
Conditional Static Analysis of C source? (1994-03-28)
| List of all articles for this month |

Newsgroups: comp.compilers
Keywords: C, analysis, question
Organization: Compilers Central
Date: Mon, 28 Mar 1994 19:18:01 GMT


      I would like to be able to calculate variable, type and function
dependencies (i.e. references, modifies, calls, etc.) in C source files.
Normally, I would use one of the commercial static analysis tools such as
C Information Abstractor, SMARTsystem from Procase, LogiScope from
Verilog, Hindsight, etc.; however, the source code contains #ifdef,
#ifndef, #if, #else and #elif directives. I need the dependency
relationships to take into account the conditional nature of dependencies.
I do not believe any of the commercial tools I mentioned above will allow
reporting (or storing in a database) of dependencies that are conditional
based on defined symbols and #if... directives. Typically these tool use
the C pre-processor, which makes the conditional dependencies I want
impossible to capture.

      An example of what I would like is

For the code:

                int f(int x)
                #ifdef USE_G
                      return g(x);
                      return h(x);

The analysis of the calls relationship would be:

                calls (f, g, defined(USE_G))
                calls (f, h, !defined(USE_G))

Can anyone suggest tools that can process unpreprocessed source to
generate dependency relationships similar to what I have outlined above?

If no such tools exist, does any one know of a parser (or parser
technology) that can process C source without running the pre-processor

Finally, if there is no parsing technology that can accomplish this then I
am thinking of implementing a parser to do what I need. I will outline my
approach for solving this problem below and I would appreciate any
feedback I can get regarding improving the design.

My approach:

Modify an existing LALR or LL parser and scanner so that whenever the
scanner detects a #if... directive (with a condition that cannot be
determined) the entire parse stack and pointers into the semantics
associated with the parse state and stack are saved onto a stack. The
condition corresponding the #if... is pushed onto a 'condition_stack'.
The initial condition on this stack would be TRUE. The compiler directive
would be skipped and parsing would resume at the next token. All of the
data structures used for program semantics, symbol tables, etc. would have
an additional field that contains the 'condition' that the data depends
upon. As structures are created the 'condition' is determined by the
'condition stack'. When a #else or #elif directive is encountered, the
parse state, etc. that was saved at the #if... would be restored and the
top of the condition stack would be modified appropriately. When a #endif
directory is encountered the 'condition stack' and the 'parse state, etc.
stack' would be popped. The reason for both of the stacks is to handle
nested #if.../#else/#endif directives.


        Mike Ogush

        Software Reuse Program
        Corporate Engineering
        Hewlett-Packard Company


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.