{"id":6355,"date":"2015-04-18T01:39:37","date_gmt":"2015-04-18T00:39:37","guid":{"rendered":"http:\/\/sysprogs.com\/w\/?p=6355"},"modified":"2016-07-16T22:23:26","modified_gmt":"2016-07-16T21:23:26","slug":"exploring-code-with-visualgdb-5-0-preview-4","status":"publish","type":"post","link":"https:\/\/sysprogs.com\/w\/exploring-code-with-visualgdb-5-0-preview-4\/","title":{"rendered":"Exploring code with VisualGDB 5.0 Preview 4"},"content":{"rendered":"<p>We have recently released a new preview build of VisualGDB 5.0 featuring a new Clang-based IntelliSense engine. This\u00a0preview build focuses on greatly improving the experience with\u00a0navigating large code bases. In this post I will show how to quickly analyze the code structure and navigate in 2 large codebases:<\/p>\n<ul>\n<li>The source code of clang itself (~30MB of C++ sources)<\/li>\n<li>The source code of the Linux Kernel (~420MB of C sources)<\/li>\n<\/ul>\n<p><!--more--><\/p>\n<h2>Finding references and definitions<\/h2>\n<p>The first powerful feature we have added is a very fast and precise &#8220;Find All References&#8221; command. Unlike Visual Studio that first searches\u00a0all files for a certain text and then verifies each occurrence, VisualGDB builds a global cache containing\u00a0pre-sorted information about the code structure and references. As a result, finding references to the correct method or\u00a0field, even if its uses are scattered around 10 thousand files, is always instant.<\/p>\n<p>For example, let&#8217;s\u00a0try it with a <strong>Decl::PrintStats()<\/strong> function in clang itself. The clang\u00a0project contains\u00a0almost\u00a03000 .cpp files and 21 of them\u00a0contain the &#8216;PrintStats&#8217; word. However, right-clicking on the\u00a0function definition and\u00a0finding all references\u00a0takes less than a second with no false positives:<\/p>\n<p><a href=\"http:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/findrefs.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6356\" src=\"http:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/findrefs.png\" alt=\"findrefs\" width=\"743\" height=\"502\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/findrefs.png 743w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/findrefs-300x203.png 300w\" sizes=\"(max-width: 743px) 100vw, 743px\" \/><\/a>This is achieved because VisualGDB\u00a0pre-sorts the\u00a0references when building the cache, so finding the correct ones is as easy as finding the right word in a dictionary.<\/p>\n<p>Let&#8217;s look at another example:\u00a0search for all uses of panic()\u00a0in\u00a0almost 10000 source files of the Linux kernel. This takes a bit longer (3 seconds), but is still much faster than looking through each file manually.<\/p>\n<p><a href=\"http:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/panic.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6357\" src=\"http:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/panic.png\" alt=\"panic\" width=\"767\" height=\"353\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/panic.png 767w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/panic-300x138.png 300w\" sizes=\"(max-width: 767px) 100vw, 767px\" \/><\/a><\/p>\n<p>It will also find references\u00a0behind preprocessor macros. E.g. in this example\u00a0you will also see all\u00a0places where a use of IOMMU_WAIT_OP() was expanded to a call to panic():<a href=\"http:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/panicmacro.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6358\" src=\"http:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/panicmacro.png\" alt=\"panicmacro\" width=\"778\" height=\"539\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/panicmacro.png 778w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/panicmacro-300x208.png 300w\" sizes=\"(max-width: 778px) 100vw, 778px\" \/><\/a><\/p>\n<p>Building the cache initially\u00a0can take a while for a really large project, however we have\u00a0optimized that greatly:<\/p>\n<ul>\n<li>On multi-core machines the\u00a0cache building logic uses all the CPU cores. On a powerful 6-core workstation with hyper-threading this can\u00a0will be up to 12x faster than normal file-after-file compilation!<\/li>\n<li>If your code uses precompiled headers (or just tends to include a certain header file before defining anything else), VisualGDB will detect this and automatically precompile\u00a0those headers improving the cache building speed.<\/li>\n<li>Modifying a few files in a large project won&#8217;t necessarily result in\u00a0a long cache rebuilding. The cache is incremental, so most of the changes will be simply\u00a0added to it, seamlessly replacing the outdated parts.<\/li>\n<\/ul>\n<p>Go to definition works similarly to &#8220;find all references&#8221;. It uses the global cache to find the right function or class among thousands of source files.<\/p>\n<h2>Exploring code hierarchies<\/h2>\n<p>Althrough &#8220;Find all references&#8221; gives a good overview\u00a0where a certain function or class is used, sometimes\u00a0a good hierarchical view can\u00a0give a much better understanding. E.g. let&#8217;s explore the hierarchy of declaration classes in clang sources. Simply\u00a0right-click on the &#8216;Decl&#8217; class somewhere in the code and, &#8220;Explore class tree&#8221; and choose to only\u00a0explore the tree downwards (from parent to derived classes):<a href=\"http:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/hier.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6359\" src=\"http:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/hier.png\" alt=\"hier\" width=\"770\" height=\"464\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/hier.png 770w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/hier-300x181.png 300w\" sizes=\"(max-width: 770px) 100vw, 770px\" \/><\/a><\/p>\n<p>You can quickly see what classes are derived from a given\u00a0class in the entire solution (or browse parent classes if you change tree direction). Each time you expand a tree node,\u00a0it takes less than a second for VisualGDB to find the matching classes because it takes that data from the fast global cache.<\/p>\n<p>Similarly to class trees you can\u00a0explore override trees. E.g. if you right-click on the <strong>TypeDecl::getSourceRange()<\/strong> method, you will see that it overrides a method in the <strong>Decl<\/strong> class and is in turn overridden in 4 derived\u00a0classes.<a href=\"http:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/overrides.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6360\" src=\"http:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/overrides.png\" alt=\"overrides\" width=\"774\" height=\"388\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/overrides.png 774w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/overrides-300x150.png 300w\" sizes=\"(max-width: 774px) 100vw, 774px\" \/><\/a>Similarly to override trees you can explore call trees (e.g. see that <strong>get_random_bytes()<\/strong> calls <strong>extract_entropy()<\/strong>\u00a0that is also called by <strong>xfer_seconday_pool()<\/strong>).<a href=\"http:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/calls.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6361\" src=\"http:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/calls.png\" alt=\"calls\" width=\"772\" height=\"307\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/calls.png 772w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/calls-300x119.png 300w\" sizes=\"(max-width: 772px) 100vw, 772px\" \/><\/a><\/p>\n<h2>Tweaking<\/h2>\n<p>You can tweak numerous settings related to the new engine via Tools-&gt;Options-&gt;Text Editor-&gt;C\/C++(VisualGDB):<a href=\"http:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/settings.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6362\" src=\"http:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/settings.png\" alt=\"settings\" width=\"758\" height=\"512\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/settings.png 758w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2015\/04\/settings-300x203.png 300w\" sizes=\"(max-width: 758px) 100vw, 758px\" \/><\/a>You can read more about the features in our new Clang-based IntelliSense engine <a href=\"http:\/\/visualgdb.com\/news\/engine\/details.php\">here<\/a>.<\/p>\n<p>And\u00a0if you have further suggestions or encounter bugs, do not hesitate to drop a note to our support so that we can ensure your VisualGDB experience will be flawless.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We have recently released a new preview build of VisualGDB 5.0 featuring a new Clang-based IntelliSense engine. This\u00a0preview build focuses on greatly improving the experience with\u00a0navigating large code bases. In this post I will show how to quickly analyze the code structure and navigate in 2 large codebases: The source code of clang itself (~30MB &hellip; <a href=\"https:\/\/sysprogs.com\/w\/exploring-code-with-visualgdb-5-0-preview-4\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Exploring code with VisualGDB 5.0 Preview 4<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"footnotes":""},"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/posts\/6355"}],"collection":[{"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/comments?post=6355"}],"version-history":[{"count":5,"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/posts\/6355\/revisions"}],"predecessor-version":[{"id":8572,"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/posts\/6355\/revisions\/8572"}],"wp:attachment":[{"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/media?parent=6355"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/categories?post=6355"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/tags?post=6355"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}