Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-dev] RE:Call Graph Extraction



Hi Dharma,
Using the latest code from the cvs head, the code you provided works for me
with and without the brackets.
I expect this was a bug in CDT 2.0.x which has since been fixed.

In general, your callback looks fine, so if you find that some code doesn't
produce the expected results then feel free
to raise a bug in bugzilla (http://bugs.eclipse.org).

Also, you might want to use the enter & exit include callbacks to filter
your results, since including a system header will
greatly increase the amount of output you get.

-Andrew

"Ganesan, Dharmalingam" <Dharmalingam.Ganesan@xxxxxxxxxxxxxxxxxx> wrote on
10/26/2004 07:49:34 AM:
"Ganesan, Dharmalingam" <Dharmalingam.Ganesan@xxxxxxxxxxxxxxxxxx> wrote on
10/26/2004 07:32:01 AM:
> >> Andrew Wrote:
> >> Hi Dharma, It looks like there is a bug in the parser that is
> causing ECHAR * str = (ECHAR *) "X"; to be parsed as an expression
> instead of as a declaration. >> Until this is fixed, you can get
> around this problem by changing your declaration of ECHAR: typedef
> char * ECHAR; ...... ECHAR str = (ECHAR)"X";
> Hi Andrew,
> Thanks for the quick reply. I changed the typedef according to your
> suggestion, the problem still remains. However, we can make an
> interesting observation on "myFunction2": In the casting, if an
> additional brackets is placed, correct call graph is coming,
> otherwise the call graph is incomplete.
> Thanks for time.
> Dharma
>
-------------------------------------------------------------------------------------------------------------------------
> void myFunction2(char c)
> {
>         typedef char* ECHAR;
>         ECHAR str = (ECHAR)("X"); /* Note the brackets */
>         ECHAR str2 = (ECHAR)"XX";
>
>         /* myFunction2 calling strlen - This works correctly */
>         strlen(str);
>         /* myFunction2 calling strlen using ECHAR str is working
correctly */
>         //int x = strlen(str) + strlen(str);
>         //if(x) { strlen(str);}
>
>         /* myFunction2 calling strlen using ECHAR str2 is NOT
> working correctly */
>         strlen(str2) + strlen(str2);
> };
>
--------------------------------------------------------------------------------------------------------------------------

> _____________________________________________
> From:   Ganesan, Dharmalingam
> Sent:   Dienstag, 26. Oktober 2004 09:36
> To:     'aniefer@xxxxxxxxxx'
> Subject:        Call Graph Extraction
> >>Andrew wrote:
> >>You can implement ISourceElementRequestor and do a complete parse
> and watch for the enter/exit function/method callbacks along with
> the acceptReference >>callback. Look at MatchLocator to see how
> search does something similar. -Andrew
> Hello Andrew,
> First of all sorry to contact you directly. It is bit urgent for me.
> I tried your idea. I have a few problems.
> I'm trying to extract call relation among functions using CDT Parser. I
> wrote a class that inherits StructuralParseCallback and overrides
> acceptFunctionReference, enterFunctionBody and exitFunctionBody. When a
> function is entered, its name is stored and all function references
within
> the body are functions called by currently entered function body. But,
> this does not work for my small piece of C code. Can you please tell me
> whether it is a problem with Eclipse CDT or my Java code that queries the

> parser ?.
> I commented the call graph problem within the C code itself. You can
> diretly exectue "TestCallGraph", a java code attached below to see the
> call graph for a given C program.
> Thanks for your time.
> Dharma
>
-----------------------------------------------------------------------------
> #include <string.h>
> typedef char ECHAR;
> void myFunction()
> {
>         ECHAR * str = (ECHAR *)"X";
>         ECHAR * str2 = (ECHAR *)"XX";
>         char * cStr = "Y";
>
>         /* myFunction calling strlen - This works correctly */
>         /* I can see "call myFunction strlen" */
>         strlen(str);
>         /* myFunction calling strlen using ECHAR as argument is
completely
> missing - NOT Working*/
>         /* I can NOT see "call myFunction strlen" */
>         if(strlen(str) + strlen(str2) <= 3) { };
>
>         /* myFunction calling strlen using cStr - This works correctly */

>         /* I can see "call myFunction strlen */
>         //if (strlen(cStr) + strlen(cStr)) { };
> }
>
>
------------------------------------------------------------------------------
> Java code that access parser:
>
> import java.io.File;
> import java.util.LinkedHashMap;
> import java.util.Map;
> import org.eclipse.cdt.core.parser.IParser;
> import org.eclipse.cdt.core.parser.IProblem;
> import org.eclipse.cdt.core.parser.IScanner;
> import org.eclipse.cdt.core.parser.ParserFactory;
> import org.eclipse.cdt.core.parser.ParserLanguage;
> import org.eclipse.cdt.core.parser.ParserMode;
> import org.eclipse.cdt.core.parser.ScannerInfo;
> import org.eclipse.cdt.core.parser.ast.IASTFunction;
> import org.eclipse.cdt.core.parser.ast.IASTFunctionReference;
> import org.eclipse.cdt.internal.core.parser.InternalParserUtil;
> import org.eclipse.cdt.internal.core.parser.StructuralParseCallback;
>
> class CMySourceElementRequestor extends StructuralParseCallback {
>
>         private String inputFileName = null; // file to be parsed
>         private String currentlyEnteredFunction = null; // name of
> function that
> is currently entered
>
>
>         public CMySourceElementRequestor(File inputFileName){
>
>                 this.inputFileName = inputFileName.getAbsolutePath();
>         }
>
>         public void acceptFunctionReference( IASTFunctionReference
> reference ) {
>
>                 // function calls other functions
>                 System.out.println("call " + currentlyEnteredFunction + "
" +
> reference.getName());
>         }
>
>         public void enterFunctionBody(IASTFunction function) {
>
>                 currentlyEnteredFunction = function.getName();
>         }
>
>         public void exitFunctionBody(IASTFunction function) {
>
>                 System.out.println("**** Exiting function body: " +
> function.getName());
>                 function.setHasFunctionBody(true);
>         }
>
>         public boolean parserTimeout() {
>
>                 return false;
>         }
>
>         public boolean acceptProblem( IProblem problem ) {
>
>                 System.out.println("Parsing problem: " + problem.
> getMessage());
>                 System.out.println("Problem at line: " + problem.
> getSourceLineNumber());
>                 String src = new
String(problem.getOriginatingFileName());
>                 System.out.println("Originating problem in file: " +
src);
>
>
>                 return true;
>         }
> }
>
> public class TestCallGraph {
>
>         private final static String[] incPaths  = getIncludePaths();
>         private final static Map definedSymbols = getDefinedSymbols();
>
>         private File srcFile; // C file to be parsed
>         private CMySourceElementRequestor mySourceElementRequestor;
>
>         public TestCallGraph(File srcFile) {
>
>                 this.srcFile = srcFile;
>                 mySourceElementRequestor = new
> CMySourceElementRequestor(srcFile);
>         }
>
>         private static String[] getIncludePaths() {
>
>                 String[] incPaths = new String[2];
>
>                 incPaths[0] = "C:\\cygwin\\usr\\include";
>                 incPaths[1] = "C:\\cygwin\\lib\\gcc-lib\\i686-pc-
> cygwin\\3.3.1\\include";
>
>                 return incPaths;
>         }
>
>         private static Map getDefinedSymbols() {
>
>                 Map m = new LinkedHashMap();
>                 String key = "__IEEE_LITTLE_ENDIAN";
>                 m.put(key, "");
>
>                 return m;
>         }
>
>         public void printCallGraph() {
>
>                 IScanner myIScanner;
>                 IParser myIParser;
>
>                 /* Create a Scanner */
>                 myIScanner = ParserFactory.createScanner(
>                                 InternalParserUtil.
> createFileReader(srcFile.getAbsolutePath()),
> srcFile.getAbsolutePath(), new ScannerInfo(definedSymbols, incPaths),
>                                 ParserMode.COMPLETE_PARSE,
ParserLanguage.C,
>                                 mySourceElementRequestor, null, null);
>
>                 /* Create a Parser */
>                 myIParser = ParserFactory.createParser(myIScanner,
>                                 mySourceElementRequestor,
> ParserMode.COMPLETE_PARSE,
>                                 ParserLanguage.C, null);
>
>                 if (myIParser.parse() == true) {
>                         System.out.println("Parse successful for file: "
+
> srcFile.getAbsolutePath());
>                 } else {
>                         System.out.println("Parse unsuccessful for file:
" +
> srcFile.getAbsolutePath());
>                 }
>         }
>
>         /* Main program */
>         public static void main(String[] args) {
>
>                 if(args.length < 1) {
>                         System.out.println("Usage: java
> TestCallGraph <absolute path to a .c
> file>");
>                 }
>
>                 TestCallGraph callGraph = new TestCallGraph(new
> File(args[0]));
>                 callGraph.printCallGraph();
>         }
>
> }
>
------------------------------------------------------------------------------



Back to the top