0

I'm currently using libclang to do static code analysis for a school project. I've got it set up and working, and have so far managed to get the file location and physical length (number of lines) of a function, but the next thing I want to get is the depth of a function.

To be clear, for my purposes the depth of a function on any given line would be the number of nested if/for/while/etc. blocks surround that line. Assuming standard syntax, the depth would be related to the number of tabs/spaces at the start of the line.

The depth of a function overall would then simply be the depth of it's deepest line. For example this would have a depth of 2:

int foo()
{
    int n = 0; // Depth 0
    for (int i = 0; i < 10; ++i)
    {
        n = bar(i); // Depth 1
        if (i < n)
            ++n; // Depth 2, deepest line
    }
}
AgentPaper
  • 109
  • 4
  • sorry, for me your "To be clear" isnt that clear. I suppose you want to know how deep they are nested, not how many nested if/loops are present. Adding a more complete example would help. In the example you posted there is 1 nested construct and its depth is 2 – 463035818_is_not_an_ai Nov 23 '20 at 12:31
  • 1
    @idclev463035818 Sorry, added more clarification and a better example, hopefully that's enough. – AgentPaper Nov 25 '20 at 00:22

1 Answers1

1

You could do it by writing an AST visitor that would

  • Set depth to zero when you enter a FunctionDecl
  • Increment depth each time you entered a node like CompoundStmt
  • Decrement depth each time you left one of these nodes
  • The depth should be zero when you leave the function and you can keep track of the max depth along the way.
Dharman
  • 30,962
  • 25
  • 85
  • 135
Ani
  • 10,826
  • 3
  • 27
  • 46
  • So if I'm reading this right, what I need to do is something like checking `(kind == CXCursorKind::CXCursor_CompoundStmt)` to tell when I'm entering a compound statement. However, how would I know when I'm leaving one of those nodes? Will that come back true for both the entry and exit of a compound statement? And if so how do I tell if I'm coming or going? – AgentPaper Nov 25 '20 at 00:48
  • This is a tree traversal using a visitor pattern. The clang wrapper does pre or post-order traversal. The cursor visits all nodes in the order specified and it calls specific methods for the type of movement. In this case for exit, you'll need to implement `clang::RecursiveASTVisitor< Derived >::dataTraverseStmtPost` - https://clang.llvm.org/doxygen/classclang_1_1RecursiveASTVisitor.html#a5566dd3a5bac53c1eca54a9c00889c68 – Ani Nov 25 '20 at 02:58