Related articles |
---|
Conditional Static Analysis of C source? ogush@hpcesra.ce.hp.com (1994-03-28) |
Newsgroups: | comp.compilers |
From: | ogush@hpcesra.ce.hp.com |
Keywords: | C, analysis, question |
Organization: | Compilers Central |
Date: | Mon, 28 Mar 1994 19:18:01 GMT |
Hello,
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);
#else
return h(x);
#endif
}
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
first?
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.
Thanks
Mike Ogush
Software Reuse Program
Corporate Engineering
Hewlett-Packard Company
ogush@hpcea.ce.hp.com
--
Return to the
comp.compilers page.
Search the
comp.compilers archives again.