{"id":13667431,"url":"https://github.com/banach-space/clang-tutor","last_synced_at":"2025-10-17T16:19:14.297Z","repository":{"id":37353946,"uuid":"250794860","full_name":"banach-space/clang-tutor","owner":"banach-space","description":"A collection of out-of-tree Clang plugins for teaching and learning","archived":false,"fork":false,"pushed_at":"2025-04-26T16:21:22.000Z","size":147,"stargazers_count":730,"open_issues_count":11,"forks_count":65,"subscribers_count":19,"default_branch":"main","last_synced_at":"2025-04-26T17:25:42.355Z","etag":null,"topics":["clang","clang-plugin","clang-plugins","clang-tooling","cplusplus","llvm-tutorial","tutorial"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/banach-space.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-03-28T12:55:14.000Z","updated_at":"2025-04-26T16:21:26.000Z","dependencies_parsed_at":"2024-01-14T16:13:47.903Z","dependency_job_id":"5159b85a-6796-4635-8530-41a51ab1bcbf","html_url":"https://github.com/banach-space/clang-tutor","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/banach-space%2Fclang-tutor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/banach-space%2Fclang-tutor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/banach-space%2Fclang-tutor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/banach-space%2Fclang-tutor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/banach-space","download_url":"https://codeload.github.com/banach-space/clang-tutor/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254292043,"owners_count":22046426,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clang","clang-plugin","clang-plugins","clang-tooling","cplusplus","llvm-tutorial","tutorial"],"created_at":"2024-08-02T07:00:36.820Z","updated_at":"2025-10-17T16:19:14.290Z","avatar_url":"https://github.com/banach-space.png","language":"C++","funding_links":[],"categories":["C++"],"sub_categories":[],"readme":"clang-tutor\n=========\n[![Apple Silicon](https://github.com/banach-space/clang-tutor/actions/workflows/apple-silicon.yml/badge.svg)](https://github.com/banach-space/clang-tutor/actions/workflows/apple-silicon.yml)\n[![x86-Ubuntu](https://github.com/banach-space/clang-tutor/actions/workflows/x86-ubuntu.yml/badge.svg)](https://github.com/banach-space/clang-tutor/actions/workflows/x86-ubuntu.yml)\n\n\nExample Clang plugins for C and C++ - based on **Clang 21**\n\n**clang-tutor** is a collection of self-contained reference Clang plugins. It's a\ntutorial that targets novice and aspiring Clang developers. Key features:\n\n  * **Modern** - based on the latest version of Clang (and updated with\n    every release)\n  * **Complete** - includes build scripts, LIT tests and CI set-up\n  * **Out of tree** - builds against a binary Clang installation (no\n    need to build Clang from sources)\n\nCorrections and feedback always welcome!\n\n### Overview\n[Clang](https://clang.llvm.org/) (together with\n[LibTooling](https://clang.llvm.org/docs/LibTooling.html)) provides a very\npowerful API and infrastructure for analysing and modifying source files from\nthe C language family. With Clang's plugin\n[framework](https://clang.llvm.org/docs/ClangPlugins.html) one can relatively\neasily create bespoke tools that aid development and improve productivity. The\naim of **clang-tutor** is to showcase this framework through small,\nself-contained and testable examples, implemented using [idiomatic\nLLVM](https://llvm.org/docs/CodingStandards.html).\n\nThis document explains how to set-up your environment, build and run the\nproject, and go about debugging. The source files, apart from the code itself,\ncontain comments that will guide you through the implementation. The\n[tests](https://github.com/banach-space/clang-tutor/tree/main/test) highlight what edge\ncases are supported, so you may want to skim through them as well.\n\n### Table of Contents\n* [HelloWorld](#helloworld)\n* [Development Environment](#development-environment)\n* [Building \u0026 Testing](#building--testing)\n* [Overview of the Plugins](#overview-of-the-plugins)\n* [References](#References)\n* [License](#license)\n\nHelloWorld\n==========\nThe **HelloWorld** plugin from\n[HelloWorld.cpp](https://github.com/banach-space/clang-tutor/blob/main/HelloWorld/HelloWorld.cpp)\nis a self-contained *reference example*. The corresponding\n[CMakeLists.txt](https://github.com/banach-space/clang-tutor/blob/main/HelloWorld/CMakeLists.txt)\nimplements the minimum set-up for an out-of-tree plugin.\n\n**HelloWorld** extracts some interesting information from the input\n_translation unit_. It visits all [C++ record\ndeclarations](https://github.com/llvm/llvm-project/blob/release/21.x/clang/include/clang/AST/DeclCXX.h#L253)\n(more specifically class, struct and union declarations) and counts them.\nRecall that translation unit consists of the input source file and all the\nheader files that it includes (directly or indirectly).\n\n**HelloWorld** prints the results on a file by file\nbasis, i.e. separately for every header file that has been included. It visits\n_all_ declarations - including the ones in header files included by other\nheader files. This may lead to some surprising results!\n\nYou can build and run **HelloWorld** like this:\n\n```bash\n# Build the plugin\nexport Clang_DIR=\u003cinstallation/dir/of/clang/21\u003e\nexport CLANG_TUTOR_DIR=\u003csource/dir/clang/tutor\u003e\nmkdir build\ncd build\ncmake -DCT_Clang_INSTALL_DIR=$Clang_DIR $CLANG_TUTOR_DIR/HelloWorld/\nmake\n# Run the plugin\n$Clang_DIR/bin/clang -cc1 -load ./libHelloWorld.{so|dylib} -plugin hello-world $CLANG_TUTOR_DIR/test/HelloWorld-basic.cpp\n```\n\nYou should see the following output:\n\n```\n# Expected output\n(clang-tutor) file: \u003csource/dir/clang/tutor\u003e/test/HelloWorld-basic.cpp\n(clang-tutor)  count: 3\n```\n\n### How To Analyze STL Headers\nIn order to see what happens with multiple _indirectly_ included header files,\nyou can run **HelloWorld** on one of the header files from the [Standard\nTemplate Library](https://en.wikipedia.org/wiki/Standard_Template_Library). For\nexample, you can use the following C++ file that simply includes `vector.h`:\n\n```cpp\n// file.cpp\n#include \u003cvector\u003e\n```\n\nWhen running a Clang plugin on a C++ file that includes headers from STL, it is\neasier to run it with `clang++` (rather than `clang -cc1`) like this:\n\n```bash\n$Clang_DIR/bin/clang++ -c -Xclang -load -Xclang libHelloWorld.dylib -Xclang -plugin -Xclang hello-world file.cpp\n```\n\nThis way you can be confident that all the necessary include paths (required to\nlocate STL headers) are automatically added. For the above input file,\n**HelloWorld** will print:\n\n* an overview of _all_ header files included when using `#include \u003cvector\u003e`,\n  and\n* the number of C++ records declared in each.\n\n\nNote that there are no explicit declarations in `file.cpp` and only one header\nfile is included. However, the output on my system consists of 37 header files\n(one of which contains 371 declarations). Note that the actual output depends\non your host OS, the C++ standard library implementation and its version. Your\nresults are likely to be different.\n\nDevelopment Environment\n=======================\n## Platform Support And Requirements\n**clang-tutor** has been tested on **Ubuntu 20.04** and **Mac OS X 10.14.6**. In\norder to build **clang-tutor** you will need:\n\n  * LLVM 21 and Clang 21\n  * C++ compiler that supports C++17\n  * CMake 3.13.4 or higher\n\nAs Clang is a subproject within\n[llvm-project](https://github.com/llvm/llvm-project), it depends on LLVM (i.e.\n**clang-tutor** requires development packages for both Clang and LLVM).\n\nThere are additional requirements for tests (these will be satisfied by\ninstalling LLVM 21):\n  * [**lit**](https://llvm.org/docs/CommandGuide/lit.html) (aka **llvm-lit**,\n    LLVM tool for executing the tests)\n  * [**FileCheck**](https://llvm.org/docs/CommandGuide/FileCheck.html) (LIT\n    requirement, it's used to check whether tests generate the expected output)\n\n## Installing Clang 21 On Mac OS X\nOn Darwin you can install Clang 21 and LLVM 21 with\n[Homebrew](https://brew.sh/):\n\n```bash\nbrew install llvm\n```\n\nIf you already have an older version of Clang and LLVM installed, you can\nupgrade it to Clang 21 and LLVM 21 like this:\n\n```bash\nbrew upgrade llvm\n```\n\nOnce the installation (or upgrade) is complete, all the required header files,\nlibraries and tools will be located in `/usr/local/opt/llvm/`.\n\n## Installing Clang 21 On Ubuntu\nOn Ubuntu Jammy Jellyfish, you can [install modern\nLLVM](https://blog.kowalczyk.info/article/k/how-to-install-latest-clang-6.0-on-ubuntu-16.04-xenial-wsl.html)\nfrom the official [repository](http://apt.llvm.org/):\n\n```bash\nwget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -\nsudo apt-add-repository \"deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-21 main\"\nsudo apt-get update\nsudo apt-get install -y llvm-21 llvm-21-dev libllvm21 llvm-21-tools clang-21 libclang-common-21-dev libclang-21-dev libmlir-21 libmlir-21-dev\n```\nThis will install all the required header files, libraries and tools in\n`/usr/lib/llvm-21/`.\n\n## Building Clang 21 From Sources\nBuilding from sources can be slow and tricky to debug. It is not necessary, but\nmight be your preferred way of obtaining LLVM/Clang 21. The following steps\nwill work on Linux and Mac OS X:\n\n```bash\ngit clone https://github.com/llvm/llvm-project.git\ncd llvm-project\ngit checkout release/21.x\nmkdir build\ncd build\ncmake -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD=host -DLLVM_ENABLE_PROJECTS=\"clang;libcxx;libcxxabi\" \u003cllvm-project/root/dir\u003e/llvm/\ncmake --build .\n```\nFor more details read the [official\ndocumentation](https://llvm.org/docs/CMake.html).\n\n### Note for macOS users\nAs per this great\n[description](https://quuxplusone.github.io/blog/2019/11/09/llvm-from-scratch/)\nby Arthur O’Dwyer , add `-DDEFAULT_SYSROOT=\"$(xcrun --show-sdk-path)\"` to your\nCMake invocation when building Clang from sources. Otherwise, `clang`  won't be\nable to find e.g. standard C headers (e.g.  `wchar.h`).\n\nBuilding \u0026 Testing\n===================\nYou can build **clang-tutor** (and all the provided plugins) as follows:\n```bash\ncd \u003cbuild/dir\u003e\ncmake -DCT_Clang_INSTALL_DIR=\u003cinstallation/dir/of/clang/21\u003e \u003csource/dir/clang-tutor\u003e\nmake\n```\n\nThe `CT_Clang_INSTALL_DIR` variable should be set to the root of either the\ninstallation or build directory of Clang 21. It is used to locate the\ncorresponding `LLVMConfig.cmake` script that is used to set the include and\nlibrary paths.\n\nIn order to run the tests, you need to install **llvm-lit** (aka **lit**). It's\nnot bundled with LLVM 21 packages, but you can install it with **pip**:\n```bash\n# Install lit - note that this installs lit globally\npip install lit\n```\nRunning the tests is as simple as:\n```bash\n$ lit \u003cbuild_dir\u003e/test\n```\nVoilà! You should see all tests passing.\n\nOverview of The Plugins\n=======================\nThis table contains a summary of the examples available in **clang-tutor**. The\n_Framework_ column refers to a plugin framework available in Clang that was\nused to implement the corresponding example. This is either\n[RecursiveASTVisitor](https://clang.llvm.org/docs/RAVFrontendAction.html),\n[ASTMatcher](https://clang.llvm.org/docs/LibASTMatchersTutorial.html) or both.\n\n| Name      | Description     | Framework |\n|-----------|-----------------|-----------|\n|[**HelloWorld**](#helloworld) | counts the number of class, struct and union declarations in the input translation unit | RecursiveASTVisitor |\n|[**LACommenter**](#lacommenter) | adds comments to literal arguments in functions calls | ASTMatcher |\n|[**CodeStyleChecker**](#codestylechecker) | issue a warning if the input file does not follow one of [LLVM's coding style guidelines](https://llvm.org/docs/CodingStandards.html#name-types-functions-variables-and-enumerators-properly) | RecursiveASTVisitor |\n|[**Obfuscator**](#obfuscator) | obfuscates integer addition and subtraction | ASTMatcher |\n|[**UnusedForLoopVar**](#unusedforloopvar) | issue a warning if a for-loop variable is not used | RecursiveASTVisitor + ASTMatcher |\n|[**CodeRefactor**](#coderefactor) | rename class/struct method names | ASTMatcher |\n\nOnce you've [built](#building--testing) this project, you can experiment with\nevery plugin separately. All of them accept C and C++ files as input. Below you\nwill find more detailed descriptions  (except for **HelloWorld**, which is\ndocumented [here](#helloworld)).\n\n## LACommenter\nThe **LACommenter** (Literal Argument Commenter) plugin will comment literal\narguments in function calls. For example, in the following input code:\n\n```c\nextern void foo(int some_arg);\n\nvoid bar() {\n  foo(123);\n}\n```\n\n**LACommenter** will decorate the invocation of `foo`  as follows:\n\n```c\nextern void foo(int some_arg);\n\nvoid bar() {\n  foo(/*some_arg=*/123);\n}\n```\n\nThis commenting style follows LLVM's [oficial guidelines](\nhttps://llvm.org/docs/CodingStandards.html#comment-formatting). **LACommenter**\nwill comment character, integer, floating point, boolean and string literal\narguments.\n\nThis plugin is based on a similar example by Peter Smith presented\n[here](https://static.linaro.org/connect/yvr18/presentations/yvr18-223.pdf).\n\n### Run the plugin\nYou can test **LACommenter** on the example presented above. Assuming that it\nwas saved in `input_file.c`, you can add comments to it as follows:\n\n```bash\n$Clang_DIR/bin/clang -cc1 -load \u003cbuild_dir\u003e/lib/libLACommenter.dylib -plugin LAC input_file.cpp\n```\n\n### Run the plugin through `ct-la-commenter`\n**locommenter** is a standalone tool that will run the **LACommenter** plugin,\nbut without the need of using `clang` and loading the plugin:\n\n```bash\n\u003cbuild_dir\u003e/bin/ct-la-commenter input_file.cpp --\n```\n\nIf you don't append `--` at the end of tools invocation will get the complain\nfrom Clang tools about missing compilation database as follow:\n\n```\nError while trying to load a compilation database:\nCould not auto-detect compilation database for file \"input_file.cpp\"\nNo compilation database found in \u003csource/dir/clang-tutor\u003e or any parent directory\nfixed-compilation-database: Error while opening fixed database: No such file or directory\njson-compilation-database: Error while opening JSON database: No such file or directory\nRunning without flags.\n```\nAnother workaround to solve the issue is to set the\n[CMAKE_EXPORT_COMPILE_COMMANDS flag](https://cmake.org/cmake/help/v3.14/variable/CMAKE_EXPORT_COMPILE_COMMANDS.html)\nduring the CMake invocation. It will give you the compilation database into your\nbuild directory with the filename as compile_commands.json. More detailed\nexplanation about it can be found on [Eli Bendersky's blog](https://eli.thegreenplace.net/2014/05/21/compilation-databases-for-clang-based-tools).\n\n## CodeStyleChecker\nThis plugin demonstrates how to use Clang's\n[DiagnosticEngine](https://github.com/llvm/llvm-project/blob/release/21.x/clang/include/clang/Basic/Diagnostic.h#L191)\nto generate custom compiler warnings.  Essentially, **CodeStyleChecker** checks\nwhether names of classes, functions and variables in the input translation unit\nadhere to LLVM's [style\nguide](https://llvm.org/docs/CodingStandards.html#name-types-functions-variables-and-enumerators-properly).\nIf not, a warning is printed. For every warning, **CodeStyleChecker** generates\na suggestion that would fix the corresponding issue. This is done with the\n[FixItHint](https://github.com/llvm/llvm-project/blob/release/21.x/clang/include/clang/Basic/Diagnostic.h#L70)\nAPI.\n[SourceLocation](https://github.com/llvm/llvm-project/blob/release/21.x/clang/include/clang/Basic/SourceLocation.h#L86)\nAPI is used to generate valid source location.\n\n**CodeStyleChecker** is robust enough to cope with complex examples like\n`vector.h` from STL, yet the actual implementation is fairly compact. For\nexample, it can correctly analyze names expanded from macros and knows that it\nshould ignore [user-defined conversion\noperators](https://en.cppreference.com/w/cpp/language/cast_operator).\n\n\n### Run the plugin\nLet's test **CodeStyleChecker** on the following file:\n\n```cpp\n// file.cpp\nclass clangTutor_BadName;\n```\n\nThe name of the class doesn't follow LLVM's coding guide and\n**CodeStyleChecker** indeed captures that:\n\n```bash\n$Clang_DIR/bin/clang -cc1 -fcolor-diagnostics -load libCodeStyleChecker.dylib -plugin CSC file.cpp\nfile.cpp:2:7: warning: Type and variable names should start with upper-case letter\nclass clangTutor_BadName;\n      ^~~~~~~~~~~~~~~~~~~\n      ClangTutor_BadName\nfile.cpp:2:17: warning: `_` in names is not allowed\nclass clangTutor_BadName;\n      ~~~~~~~~~~^~~~~~~~~\n      clangTutorBadName\n2 warnings generated.\n```\n\nThere are two warnings generated as two rules have been violated. Alongside\nevery warning, a suggestion (i.e. a `FixItHint`) that would make the\ncorresponding warning go away. Note that **CodeStyleChecker** also supplements\nthe warnings with correct source code information.\n\n`-fcolor-diagnostics` above instructs Clang to generate color output\n(unfortunately Markdown doesn't render the colors here).\n\n### Run the plugin through `ct-code-style-checker`\n**ct-code-style-checker** is a standalone tool that will run the **CodeStyleChecker** plugin,\nbut without the need of using `clang` and loading the plugin:\n\n```bash\n\u003cbuild_dir\u003e/bin/ct-code-style-checker input_file.cpp --\n```\n\n\n## Obfuscator\nThe **Obfuscator** plugin will rewrite integer addition and subtraction\naccording to the following formulae:\n\n```\na + b == (a ^ b) + 2 * (a \u0026 b)\na - b == (a + ~b) + 1\n```\n\nThe above transformations are often used in code obfuscation. You may also know\nthem from [Hacker's\nDelight](https://www.amazon.co.uk/Hackers-Delight-Henry-S-Warren/dp/0201914654).\n\nThe plugin runs twice over the input file. First it scans for integer\nadditions. If any are found, the input file is updated and printed to stdout.\nIf there are no integer additions, there is no output. Similar logic is\nimplemented for integer subtraction.\n\nSimilar code transformations are possible at the [LLVM\nIR](https://llvm.org/docs/LangRef.html) level. In particular, see\n[MBAsub](https://github.com/banach-space/llvm-tutor#mbasub) and\n[MBAAdd](https://github.com/banach-space/llvm-tutor#mbaadd) in\n[**llvm-tutor**](https://github.com/banach-space/llvm-tutor).\n\n### Run the plugin\nLets use the following file as our input:\n\n```c\nint foo(int a, int b) {\n  return a + b;\n}\n```\n\nYou can run the plugin like this:\n\n```bash\n$Clang_DIR/bin/clang -cc1 -load \u003cbuild_dir\u003e/lib/libObfuscator.dylib -plugin Obfuscator input.cpp\n```\n\nYou should see the following output on your screen.\n\n```c\nint foo(int a, int b) {\n  return (a ^ b) + 2 * (a \u0026 b);\n}\n```\n\n## UnusedForLoopVar\nThis plugin detects unused for-loop variables (more specifically, the variables\ndefined inside the\n[traditional](https://en.cppreference.com/w/cpp/language/for) and\n[range-based](https://en.cppreference.com/w/cpp/language/range-for) `for`\nloop statements) and issues a warning when one is found. For example, in\nfunction `foo` the loop variable `j` is not used:\n\n```c\nint foo(int var_a) {\n  for (int j = 0; j \u003c 10; j++)\n    var_a++;\n\n  return var_a;\n}\n```\n\n**UnusedForLoopVar** will warn you about it. Clearly the for loop in this case\ncan be replaced with `var_a += 10;`, so **UnusedForLoopVar** does a great job\nin drawing developer's attention to it. It can also detect unused loop\nvariables in range for loops, for example:\n\n```c++\n#include \u003cvector\u003e\n\nint bar(std::vector\u003cint\u003e var_a) {\n  int var_b = 10;\n  for (auto some_integer: var_a)\n    var_b++;\n\n  return var_b;\n}\n\n```\n\nIn this case, `some_integer` is not used and **UnusedForLoopVar** will\nhighlight it. The loop could be replaced with a much simpler expression: `var_b\n+= var_a.size();`.\n\nObviously unused loop variables _may_ indicate an issue or a potential\noptimisation (e.g. unroll the loop) or a simplification (e.g. replace the loop\nwith one arithmetic operation). However, that does not have to be the case and\nsometimes we have good reasons not to use the loop variable.\nIf the name of a loop variable matches the `[U|u][N|n][U|u][S|s][E|e][D|d]`\nthen it will be ignored by\"**UnusedForLoopVar**. For example, the following\nmodified version of the above example will not be reported:\n\n```c\nint foo(int var_a) {\n  for (int unused = 0; unused \u003c 10; unused++)\n    var_a++;\n\n  return var_a;\n}\n```\n\n**UnusedForLoopVar** mixes both the\n[ASTMatcher](https://clang.llvm.org/docs/LibASTMatchersTutorial.html) and\n[RecursiveASTVisitor](https://clang.llvm.org/docs/RAVFrontendAction.html)\nframeworks. It is an example of how to leverage both of them to solve a\nslightly more complex problem. The generated warnings are labelled so that you\ncan see which framework was used to capture a particular case of an unused\nfor-loop variable. For example, for the first example above you will get the\nfollowing warning:\n\n```bash\nwarning: (Recursive AST Visitor) regular for-loop variable not used\n```\n\nThe second example leads to the following warning:\n\n```bash\nwarning: (AST Matcher) range for-loop variable not used\n```\n\nReading the [source\ncode](https://github.com/banach-space/clang-tutor/blob/main/lib/UnusedForLoopVar.cpp)\nshould help you understand why different frameworks are needed in different\ncases. I have also added a few test files that you can use as reference\nexamples (e.g.\n[UnusedForLoopVar_regular_loop.cpp](https://github.com/banach-space/clang-tutor/blob/main/test/UnusedForLoopVar_regular_loop.cpp)).\n\n### Run the plugin\n```bash\n$Clang_DIR/bin/clang -cc1 -fcolor-diagnostics -load \u003cbuild_dir\u003e/lib/libUnusedForLoopVar.dylib -plugin UFLV input.cpp\n```\n\n## CodeRefactor\nThis plugin will rename a specified member method in a class (or a struct) and\nin all classes derived from it. It will also update all call sites in which the\nmethod is used so that the code remains semantically correct.\n\nThe following example contains all cases supported by **CodeRefactor**.\n\n```cpp\n// file.cpp\nstruct Base {\n    virtual void foo() {};\n};\n\nstruct Derived: public Base {\n    void foo() override {};\n};\n\nvoid StaticDispatch() {\n  Base B;\n  Derived D;\n\n  B.foo();\n  D.foo();\n}\n\nvoid DynamicDispatch() {\n  Base *B = new Base();\n  Derived *D = new Derived();\n\n  B-\u003efoo();\n  D-\u003efoo();\n}\n```\n\nWe will use **CodeRefactor** to rename `Base::foo` as `Base::bar`. Note that\nthis consists of two steps:\n\n* update the declaration and the definition of `foo` in the base class (i.e.\n  `Base`) as well as all in the derived classes (i.e. `Derived`)\n* update all call sites the use static dispatch (e.g. `B1.foo()`) and dynamic\n  dispatch (e.g. `B2-\u003efoo()`).\n\n**CodeRefactor** will do all this refactoring for you! See\n[below](#run-the-plugin-4) how to run it.\n\nThe\n[implementation](https://github.com/banach-space/clang-tutor/blob/main/lib/CodeRefactor.cpp)\nof **CodeRefactor** is rather straightforward, but it can only operate on one\nfile at a time.\n[**clang-rename**](https://clang.llvm.org/extra/clang-rename.html) is much more\npowerful in this respect.\n\n### Run the plugin\n**CodeRefactor** requires 3 command line arguments: `-class-name`, `-old-name`,\n`-new-name`. Hopefully these are self-explanatory. Passing the arguments to the\nplugin is  _a bit_ cumbersome and probably best demonstrated with an example:\n\n```bash\n$Clang_DIR/bin/clang -cc1 -load \u003cbuild_dir\u003e/lib/libCodeRefactor.dylib -plugin CodeRefactor -plugin-arg-CodeRefactor -class-name -plugin-arg-CodeRefactor Base  -plugin-arg-CodeRefactor -old-name -plugin-arg-CodeRefactor foo  -plugin-arg-CodeRefactor -new-name -plugin-arg-CodeRefactor bar file.cpp\n```\n\nIt is much easier when you the plugin through a stand-alone tool like\n`ct-code-refactor`!\n\n### Run the plugin through `ct-code-refactor`\n`ct-code-refactor` is a standalone tool that is basically a wrapper for\n**CodeRefactor**. You can use it to refactor your input file as follows:\n\n```bash\n\u003cbuild_dir\u003e/bin/ct-code-refactor --class-name=Base --new-name=bar --old-name=foo file.cpp  --\n```\n\n`ct-code-refactor` uses LLVM's [CommandLine\n2.0](https://llvm.org/docs/CommandLine.html) library for parsing command line\narguments. It is very well documented, relatively easy to integrate and the end\nresult is a very intuitive interface.\n\nReferences\n==========\nBelow is a list of clang resources available outside the official online\ndocumentation that I have found very helpful.\n\n* **Resources inside Clang**\n  * Refactoring tool template:\n    [clang-tools-extra/tool-template](https://github.com/llvm/llvm-project/tree/release/14.x/clang-tools-extra/tool-template)\n  * AST Matcher [Reference](https://clang.llvm.org/docs/LibASTMatchersReference.html)\n* **Clang Tool Development**\n  * _\"How to build a C++ processing tool using the Clang libraries\"_, Peter Smith, Linaro Connect 2018\n  ([video](https://www.youtube.com/watch?reload=9\u0026v=8QvLVEaxzC8), [slides](https://s3.amazonaws.com/connect.linaro.org/yvr18/presentations/yvr18-223.pdf))\n* **Diagnostics**\n  * _\"Emitting Diagnostics in Clang\"_, Peter Goldsborough ([blog\n  post](http://www.goldsborough.me/c++/clang/llvm/tools/2017/02/24/00-00-06-emitting_diagnostics_and_fixithints_in_clang_tools/))\n* **Projects That Use Clang Plugins**\n  * Mozilla: official documentation on [static analysis in Firefox](https://firefox-source-docs.mozilla.org/code-quality/static-analysis.html#build-time-static-analysis), custom [ASTMatchers](https://searchfox.org/mozilla-central/source/build/clang-plugin/CustomMatchers.h)\n  * Chromium: official documentation on [using clang plugins](https://chromium.googlesource.com/chromium/src.git/+/master/docs/clang.md#using-plugins), in-tree [source code](https://chromium.googlesource.com/chromium/src/+/master/tools/clang/plugins/)\n  * LibreOffice: official documentation on [developing Clang plugins](https://wiki.documentfoundation.org/Development/Clang_plugins), in-tree [source code](https://github.com/LibreOffice/core/tree/master/compilerplugins/clang)\n* **clang-query**\n  * _\"Exploring Clang Tooling Part 2: Examining the Clang AST with clang-query\"_, Stephen Kelly, [blog post](https://devblogs.microsoft.com/cppblog/exploring-clang-tooling-part-2-examining-the-clang-ast-with-clang-query/)\n  * _\"The Future of AST-Matcher based Refactoring\"_, Stephen Kelly, [video 1](https://www.youtube.com/watch?v=yqi8U8Q0h2g\u0026t=1202s), [video 2](https://www.youtube.com/watch?v=38tYYrnfNrs), [blog post](https://steveire.wordpress.com/2019/04/30/the-future-of-ast-matching-refactoring-tools-eurollvm-and-accu/)\n  * Compiler Explorer [view](https://godbolt.org/z/clang-query) with clang-query\n\nLicense\n========\nThis is free and unencumbered software released into the public domain.\n\nAnyone is free to copy, modify, publish, use, compile, sell, or distribute this\nsoftware, either in source code form or as a compiled binary, for any purpose,\ncommercial or non-commercial, and by any means.\n\nIn jurisdictions that recognize copyright laws, the author or authors of this\nsoftware dedicate any and all copyright interest in the software to the public\ndomain. We make this dedication for the benefit of the public at large and to\nthe detriment of our heirs and successors. We intend this dedication to be an\novert act of relinquishment in perpetuity of all present and future rights to\nthis software under copyright law.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\nACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nFor more information, please refer to http://unlicense.org/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbanach-space%2Fclang-tutor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbanach-space%2Fclang-tutor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbanach-space%2Fclang-tutor/lists"}