Search code examples
eclipsepluginseclipse-plugineclipse-cdt

Eclipse CDT plugin - Retrieve referenced CDTName values - function bodies and constant values


I am using the implementation of ASTVisitor class to retrieve information about CDT nodes in my code. This works as intended, however I cannot figure how to retrieve the BodyStatement node of a CASTFunctionCallExpression node from another file or any other referenced CDTName nodes from different files (like a referenced constant from another file of which I cannot retrieve the value of the constant - I am missing the needed node).

For example I have this code:

main.c

#include <stdlib.h>
#include <stdio.h>
#include "functions.h"

int main(void) {
    func1();
    func2();
    return 0;
}

functions.h

void func1(void);
void func2(void);

functions.c

#include "functions.h"

void func1(void) {
    printf("Function 1!\n"); 
}

void func2(void) {
    printf("Function 2!\n");
}

Now, I need to retrieve bodies of the func1 and func2 functions, while my ASTVisitor is collecting information from the main.c source file.

Is there any possible way how to retrieve values of referenced CDTNames (Function calls, constants, etc.) - function bodies (CASTCompoundStatements), constant values? I tried debugging the CASTFunctionCallExpression values of referenced functions but cant find no information on their origin and thus their bodies. Is there maybe a finder class for this?


Solution

  • In CDT, ASTs are built per-file. So, if you have an AST for file 1, and it references a function defined in file 2, the body of that function will not be present in the AST for file 1.

    If you need the body of the function, you need to build an AST for file 2 as well.

    Assuming your project is indexed, you could do something like this:

    • Navigate to the IASTName node representing the function's name in the AST for file 1.
    • Call IASTNode.resolveBinding() to obtain an IBinding object representing the called function.
    • Use IIndex.findDefinitions(IBinding) to look up the location of the function's definition in the project. This gives you an IIndexName representing the name at the function's definition site.
      • The IIndex object can be obtained using e.g. IASTTranslationUnit.getIndex().
    • Use IIndexName.getFile() to identify the file containing the definition (henceforth, "file 2")
    • Build an AST for file 2
    • To find the definition in the AST for file 2, you can use IASTTranslationUnit.getNodeSelector().findName(), passing in the offset and length from the IIndexName
    • Navigate the AST from the definition you found (which is an IASTName) to the body