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 _______________________________________________ Qt-creator mailing list [email protected] http://lists.qt-project.org/mailman/listinfo/qt-creator
