https://github.com/dyollb/modernize_cpp
small collection of script to refactor legacy C++ code.
https://github.com/dyollb/modernize_cpp
clang-tidy cplusplus cpp cpp11 cpp14 modernization refactoring
Last synced: about 1 year ago
JSON representation
small collection of script to refactor legacy C++ code.
- Host: GitHub
- URL: https://github.com/dyollb/modernize_cpp
- Owner: dyollb
- License: apache-2.0
- Created: 2020-11-04T14:13:47.000Z (over 5 years ago)
- Default Branch: main
- Last Pushed: 2022-06-09T06:38:13.000Z (almost 4 years ago)
- Last Synced: 2025-01-30T05:27:36.167Z (about 1 year ago)
- Topics: clang-tidy, cplusplus, cpp, cpp11, cpp14, modernization, refactoring
- Language: Python
- Homepage:
- Size: 46.9 KB
- Stars: 2
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Modernizing legacy C++ code
## Overview
`clang-tidy` offers a wide range of checks to lint C++ code. In some cases it can generate automatic fixes, e.g. to replace expressions with `typedef` to `using`.
`run-clang-tidy.py` is a tool which runs `clang-tidy` with a set of checks for an entire source code directory. To do this it needs to know how the source is compiled.
CMake can generate this information for `ninja` and `Makefile` generators by specifying the option `CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=ON`.
## Tools
### clang-tidy provides a range of checks with fixits.
For a list of these checks see https://clang.llvm.org/extra/clang-tidy/. Some warn about bugprone code, improve readability or allow to enforce coding styles. The `modernize-*` checks mostly help to transform pre-c++11 code to c++11 (or c++14) code.
On Ubuntu you can install it via:
- `apt-get update`
- `apt install clang-tools-10`
- `apt install clang-tidy-10`
### The run-clang-tidy.py script
This script is available at [llvm](https://clang.llvm.org/extra/doxygen/run-clang-tidy_8py_source.html). Run it with `-h` to get help.
*Note: I patched the script*, because it did not merge patches correctly (because warnings did not have normalized paths). Due to this bug it would sometimes add keywords multiple times, e.g. `std::string Name() override override`.
### The batch-run-clang-tidy.py script
This script runs `run-clang-tidy.py` for a range of checks. After each check it tries to compile the code. If compilation succeeds, it commits tha patch using `git commit -am ""`.
The script includes code compiled withing a folder (recursively), so if you want to focus on refactoring e.g. subfolder XYZ then you could run:
`python ./Modernize/batch-run-clang-tidy.py -b /work/build/debug -s /work/src/YourProject/XYZ -c modernize-use-using -c modernize-use-override`
In the call above, the folder `/work/build/debug` is where the build folder in this example. Also note that multiple checks can be queued. If you want the script to cancel if something fails, then add `-stop-on-error`.
## clazy
[This is a project](https://github.com/KDE/clazy) I recently stumbled upon. It is built on clang-tidy/llvm tooling to perform static checks on Qt4/Qt5 code.
A nice summary of some of these checks that help to avoid typical issues with Qt signals and slots is given [here](https://www.kdab.com/nailing-13-signal-slot-mistakes-clazy-1-3/).
## Other scripts to replace legacy code
Since large parts of our code is only built with msvc14 (VS 20215), and we use precompiled headers, clang-tidy was not always successful at providing fixits. Therefore, I created collection of python scripts to modernize our code, and e.g. reduce depedencies on boost where c++11 provides an alternative. The basic logic is implemented in [replace_expression.py](replace_scripts/replace_expression.py)
- replace_boost_foreach.py
- replaces BOOST_FOREACH if on a single line
- removes header
- skips removing header in files with `BOOST_REVERSE_FOREACH`
- replace_lexical_cast.py:
- replaces `boost::lexical_cast` by `std::to_string`
- removes unused header
- replace_typedef_with_using.py
- transforms `typedef x::y::z xyz_t` to `using xyz_t = x::y::z`
- skips multiline typedefs and function pointer-like typedefs
- replace_incorrect_include_capitalization.py
- tries to fix incorrect spelling of headers (relative paths only)
- replace_assign_list_of.py
- replaces `boost::assign::list_of(X)(Y)` by `{ X, Y }`
- replace_null.py
- finds typical context where `NULL` is used and replaces it by `nullptr`
- etc.