SlideShare a Scribd company logo
Code Analysis and Refactoring with the CDT Doug Schaefer Wind River CDT Project Lead.
What is the CDT? A C/C++ Development Environment on Eclipse Intellig ent  Code Editor Source Navigation features using an index and internal parser Build with integration with different tool chains Debug with integration with different debug engines Out of the box support for GNU tools To facilitate testing and to ease adoption Extended by many vendors to support their own platforms Wind River, QNX, Nokia/Symbian, IBM, Intel, and many more
What is the CDT Used For? Embedded Development Leading IDE solution for the mobile and device market Adopted as IDE by most RTOS and silicon vendors Linux development Included in most enterprise Linux distributions Red Hat working to create “Visual Studio” for Linux High Performance Computing Basis for Parallel Tools Platform and Fortran IDEs Cross Platform Development Windows, Linux, MacOS X, most RTOSes, ...
Why does the CDT have a parser? Original intention was to support UML modeling and code gen Started by the CDT team at Rational Started with Outline view support CmodelBuilder to populate the Cmodel Moved on to populate index Full AST to capture symbol defs and references And now we have refactoring And they said it couldn't be done!
The C Model Adaptation of resources to C/C++ type things mainly intended to populate Project Navigator and Outline View Adds to Resource level ICProject, source and output folders, source and binary files And inside the file level ITranslationUnit and IBinary Entry point is the CoreModel class No nice OSGi service yet, not even an adapter e.g., ICProject cproj = CoreModel.getDefault.create(project); Root element is ICElement, open type hierarchy to see it all
CModel is good, but... Focused mainly on UI type things Simple, easy to understand But not necessarily the most accurate representation Traditional compilers have Abstract Syntax Trees Starts at the token level Arranged in syntax tree Semantic analysis support for “understanding” what's in the tree Enough information to translate into executable object code The CDT has an AST!
Getting a CDT AST Entry point is ITranslationUnit from the Cmodel IASTTranslationUnit ast = tu.getAST(); Uses parser to create a Full AST Determines language from content type Invokes associated parser for the language Produces a language dependent AST ICASTTranslationUnit, ICPPASTTranslationUnit ASTVisitor provided to facilitate walking the AST Trasitional visitor pattern, accept/visit/leave
 
Semantic Analysis “Bindings” connect Declarations and References Represent semantic concepts and their properties IBinding is root of type hierarchy IASTName represents point of declaration and reference getBinding() returns IBinding for given name Find Declarations and References from IASTTranslationUnit IASTName[] getDeclarationsInAST(IBinding binding) IASTName[] getReferencesInAST(IBinding binding)
AST is great, but... Creating Full AST is expensive both size (lots of objects) and time (parsing is compute intensive) Finding all References in a large project prohibitive Parsing every source file very time consuming (hours). We need a caching strategy...
Introducing the Index and Indexer Index captures all Names and Bindings in a project Stored in a hand coded database Used for C/C++ Search, Open Declaration Indexer runs in the background on file saves Parses files and walks AST adding names and bindings to DB Mode added to AST to reuse contents of Index instead of parsing Header files Huge performance improvement similar to pre-compiled headers Some cost in accuracy due to conditional compile directives
Parsing using the Index Parsers operate in different modes/styles e.g. ITranslationUnit.AST_SKIP_INDEXED_HEADERS Pass in Index and flags to parser ITranslationUnit.getAST(IIndex index, int style) Get Index from Index Manager CCorePlugin.getIndexManager().getIndex(ICProject[] projects) Acquire and release read index lock to avoid collision with indexer
Using the Index Use index in AST searches IName[] IASTTranslationUnit.getReferences(IBinding[] binding) IName super class for AST Names and Index Names IBindings are handled automagically If parsed using skip headers IASTName.getBinding() will return the binding from the index Information can be retrieved from the index directly e.g., IIndex.findBindings() which takes a Pattern and an IndexFilter
A Simple Static Analysis Tool Find all functions that call 'printf' Find ICProject, get IIndex for it IIndex.findBinding() for IFunction bindings called printf IIndex.findReference() for the binding For each reference name, create AST for containing file Find IASTNode at the offset in the reference name Search node parents looking for IASTFunctionDefinition Get declarator for function and print out the IASTName for it
Introducing CDT Refactoring Very similar to JDT Refactoring Reuses the LTK plug-in contributed by JDT team Uses semantic analysis capabilities to create TextEdits CRefactoring is root of type hierarchy Three steps checkInitialConditions to set up for refactoring for user options checkFinalConditions to ensure user entered options are valid collectModifications to set up refactoring changes
AST Rewriting and the LTK ModificationCollector manages ASTRewrites ASTRewrite creates TextEdits to affect AST changes Insert, remove, replace nodes LTK uses TextEdits to show preview and to execute the change Which makes refactoring easy to create LTK also provides UI framework for co-ordinating refactoring Add your own input page for user selectable options
Simple Refactoring Change calls to printf with calls to log collector Left as an exercise for the reader... Look at the current set of CDT refactorings Extract Constant Extract Function Generate Getters and Setters Hide Method Implement Method
Next Steps Framework needs documentation Spread the word on what can be done and how Framework a bit young and needs exercise Architecture needs a little clean up, but not much Feel free to submit bugs, patches, and new functionality Discuss on cdt-dev mailing list Let your imagination go wild and see what the CDT can do for you!

More Related Content

Code Analysis and Refactoring with CDT

  • 1. Code Analysis and Refactoring with the CDT Doug Schaefer Wind River CDT Project Lead.
  • 2. What is the CDT? A C/C++ Development Environment on Eclipse Intellig ent Code Editor Source Navigation features using an index and internal parser Build with integration with different tool chains Debug with integration with different debug engines Out of the box support for GNU tools To facilitate testing and to ease adoption Extended by many vendors to support their own platforms Wind River, QNX, Nokia/Symbian, IBM, Intel, and many more
  • 3. What is the CDT Used For? Embedded Development Leading IDE solution for the mobile and device market Adopted as IDE by most RTOS and silicon vendors Linux development Included in most enterprise Linux distributions Red Hat working to create “Visual Studio” for Linux High Performance Computing Basis for Parallel Tools Platform and Fortran IDEs Cross Platform Development Windows, Linux, MacOS X, most RTOSes, ...
  • 4. Why does the CDT have a parser? Original intention was to support UML modeling and code gen Started by the CDT team at Rational Started with Outline view support CmodelBuilder to populate the Cmodel Moved on to populate index Full AST to capture symbol defs and references And now we have refactoring And they said it couldn't be done!
  • 5. The C Model Adaptation of resources to C/C++ type things mainly intended to populate Project Navigator and Outline View Adds to Resource level ICProject, source and output folders, source and binary files And inside the file level ITranslationUnit and IBinary Entry point is the CoreModel class No nice OSGi service yet, not even an adapter e.g., ICProject cproj = CoreModel.getDefault.create(project); Root element is ICElement, open type hierarchy to see it all
  • 6. CModel is good, but... Focused mainly on UI type things Simple, easy to understand But not necessarily the most accurate representation Traditional compilers have Abstract Syntax Trees Starts at the token level Arranged in syntax tree Semantic analysis support for “understanding” what's in the tree Enough information to translate into executable object code The CDT has an AST!
  • 7. Getting a CDT AST Entry point is ITranslationUnit from the Cmodel IASTTranslationUnit ast = tu.getAST(); Uses parser to create a Full AST Determines language from content type Invokes associated parser for the language Produces a language dependent AST ICASTTranslationUnit, ICPPASTTranslationUnit ASTVisitor provided to facilitate walking the AST Trasitional visitor pattern, accept/visit/leave
  • 8.  
  • 9. Semantic Analysis “Bindings” connect Declarations and References Represent semantic concepts and their properties IBinding is root of type hierarchy IASTName represents point of declaration and reference getBinding() returns IBinding for given name Find Declarations and References from IASTTranslationUnit IASTName[] getDeclarationsInAST(IBinding binding) IASTName[] getReferencesInAST(IBinding binding)
  • 10. AST is great, but... Creating Full AST is expensive both size (lots of objects) and time (parsing is compute intensive) Finding all References in a large project prohibitive Parsing every source file very time consuming (hours). We need a caching strategy...
  • 11. Introducing the Index and Indexer Index captures all Names and Bindings in a project Stored in a hand coded database Used for C/C++ Search, Open Declaration Indexer runs in the background on file saves Parses files and walks AST adding names and bindings to DB Mode added to AST to reuse contents of Index instead of parsing Header files Huge performance improvement similar to pre-compiled headers Some cost in accuracy due to conditional compile directives
  • 12. Parsing using the Index Parsers operate in different modes/styles e.g. ITranslationUnit.AST_SKIP_INDEXED_HEADERS Pass in Index and flags to parser ITranslationUnit.getAST(IIndex index, int style) Get Index from Index Manager CCorePlugin.getIndexManager().getIndex(ICProject[] projects) Acquire and release read index lock to avoid collision with indexer
  • 13. Using the Index Use index in AST searches IName[] IASTTranslationUnit.getReferences(IBinding[] binding) IName super class for AST Names and Index Names IBindings are handled automagically If parsed using skip headers IASTName.getBinding() will return the binding from the index Information can be retrieved from the index directly e.g., IIndex.findBindings() which takes a Pattern and an IndexFilter
  • 14. A Simple Static Analysis Tool Find all functions that call 'printf' Find ICProject, get IIndex for it IIndex.findBinding() for IFunction bindings called printf IIndex.findReference() for the binding For each reference name, create AST for containing file Find IASTNode at the offset in the reference name Search node parents looking for IASTFunctionDefinition Get declarator for function and print out the IASTName for it
  • 15. Introducing CDT Refactoring Very similar to JDT Refactoring Reuses the LTK plug-in contributed by JDT team Uses semantic analysis capabilities to create TextEdits CRefactoring is root of type hierarchy Three steps checkInitialConditions to set up for refactoring for user options checkFinalConditions to ensure user entered options are valid collectModifications to set up refactoring changes
  • 16. AST Rewriting and the LTK ModificationCollector manages ASTRewrites ASTRewrite creates TextEdits to affect AST changes Insert, remove, replace nodes LTK uses TextEdits to show preview and to execute the change Which makes refactoring easy to create LTK also provides UI framework for co-ordinating refactoring Add your own input page for user selectable options
  • 17. Simple Refactoring Change calls to printf with calls to log collector Left as an exercise for the reader... Look at the current set of CDT refactorings Extract Constant Extract Function Generate Getters and Setters Hide Method Implement Method
  • 18. Next Steps Framework needs documentation Spread the word on what can be done and how Framework a bit young and needs exercise Architecture needs a little clean up, but not much Feel free to submit bugs, patches, and new functionality Discuss on cdt-dev mailing list Let your imagination go wild and see what the CDT can do for you!