[Qt-creator] Extract complete prototype of a function from AST
Nikolai Kosjar
nikolai.kosjar at digia.com
Thu Oct 31 10:12:44 CET 2013
Hi!
On 10/30/2013 05:04 PM, dydx wrote:
> Hello all, I have read the AST traverse code in FindUsages class. It
> seems that a AST just organize all tokens in a file into a tree. Each
> node in the tree corresponds a syntax element(For example, a statement,
> or an expression). Also, a leaf node will carry a token index, which can
> be used to query the actual token by calling ASTVisitor::tokenAt(idx).
Correct, though non-leaf nodes might also carry token indices, e.g. the
*statements having a ';' in the end. The AST (Abstract Syntax Tree) is
the output of the parser.
To visually inspect the AST for given code, you can use the
cplusplus-ast2png tool residing in tests/tools/cplusplus-ast2png. See
also [1]
> (1) Is the code above right? Why doc->check() will crash?
Looks ok-ish in general.
Where is your snapshot from? If your file/document is already in the
snapshot, Snapshot::preprocessedDocument will return the appropriate
document for that file. And that one was probably already "check()ed",
hence the Q_ASSERT triggers. Either use an empty Snapshot or don't try
to check() again.
Document::tokenize() obviously creates tokens, so you can access/inspect
them via document->translationUnit()->tokenAt(i)/tokenCount().
Document::parse() inspects the tokens and creates the AST, which you can
access by document->translationsUnit()->ast().
Document::check() runs on the AST and creates the symbols hierarchy. The
entry point here is document->globalNamespace().
Note that check() calls parse() if necessary, and this one calls
tokenize() if necessary.
> // It seems that both AST are the same, isn't it ?
Yes. The Control and TranslationUnit are tightly coupled, that's why
there are two ways to get the AST. If you don't have to, don't use the
control (way).
> (2) How to release memory when I don't need the AST any more? Just call
> Document::releaseSourceAndAST() ?
Yes. Note that this will also clear the tokens.
> (3) Most importantly, as I want to extract the call graph, I want to get
> the complete and exact declaration of any function I encounter.
> For example, there are several overloaded versions of the
> following function:
> int ClassA::funcA();
> int ClassA::funcA(int varA);
> Suppose when I traverse the AST, I encounter "objA->funcA(5);" .
> So how can I find its prototype "int ClassA::funcA(int varA);",
> instead of "int ClassA::funcA();"? Is there any "binding" for a
> ast element, such as the definition of a function?
The ASTs of function declarations and definitions (SimpleDeclarationAST,
FunctionDefinitionAST) have a symbol(s) member once Document::check()
was executed. Check symbol->type()->asFunctionType() - the "Function"
contains the information about the return value and arguments.
For CallASTs, you have to do a lookup via TypeOfExpression. This is e.g.
done for F2 / Follow Symbol Under Cursor in Creator. Take a look at
FollowSymbolUnderCursor::findLink, starting with the line creating the
TypeOfExpression object.
The SymbolFinder class will help you find the matching
declarations/definitions.
> (4) An extra question, when I debugged the QtCreator code in visual
> studio, I found it sometimes took a lot of time for QtCreator to
> parse the source after a project was opened, but quite fast
> (several seconds) in other times. This was really strange because the
> project was the same. That wasted me a lot of time. How to solve it ?
Might be cache related?
Nikolai
[1]
https://qt-project.org/wiki/Qt_Creator_DevIntro_CppSupport#a6c32c7c0e089ee14dca4cc704f6efe2
More information about the Qt-creator
mailing list