cppinsights README

The project's README from github.com/andreasfertig/cppinsights. As one markdown file: README.md.

cpp insights logo

C++ Insights - See your source code with the eyes of a compiler.

License download Build Status codecov Try online Documentation patreon

Open in Gitpod

Contents

What

C++ Insights is a Clang-based tool that does a source-to-source transformation. The goal of C++ Insights is to make things visible that normally and intentionally happen behind the scenes. It's about the magic the compiler does for us to make things work.

Take this piece of code, for example:

class Base {
};

class Derived : public Base {
};

int main() {
  Derived d;

  Derived d2 = d;

  d2 = d;

  Base& b = d;
}

Nothing special, and of course, it compiles. This is the compiler's view on it:

class Base
{
  public:
  // inline constexpr Base() noexcept = default;
  // inline constexpr Base(const Base &) noexcept = default;
  // inline constexpr Base & operator=(const Base &) noexcept = default;
};



class Derived : public Base
{
  public:
  // inline constexpr Derived() noexcept = default;
  // inline constexpr Derived(const Derived &) noexcept = default;
  // inline constexpr Derived & operator=(const Derived &) noexcept = default;
};



int main()
{
  Derived d;
  Derived d2 = Derived(d);
  d2.operator=(d);
  Base & b = static_cast<Base&>(d);
  return 0;
}

You can see all the compiler-provided special member functions and the upcast from Derived to Base.

Why

C++ Insights is a Clang-based tool that does a source-to-source transformation. The goal of C++ Insights is to make things visible that normally and intentionally happen behind the scenes. It's about the magic the compiler does for us to make things work. Or looking through the classes of a compiler.

In 2017, I started looking into some new things we got with C++11, C++14, and C++17. Amazing things like lambdas, range-based for-loops, and structured bindings. I put it together in a talk. You can find the slides and a video online.

However, all that research and some of my training and teaching got me to start thinking about how it would be if we could see with the eyes of the compiler. Sure, there is an AST dump, at least for Clang. We can see what code the compiler generates from a C++ source snippet with tools like Compiler Explorer. However, what we see is assembler. Neither the AST nor the Compiler Explorer output is in the language I write code. Hence, I'm not very familiar with this output. Plus, when teaching students C++, showing an AST and explaining that it is all there was not quite satisfying for me.

I started to write a Clang-based tool that can transform a range-based for-loop into the compiler-internal version. Then, I did the same for structured bindings and lambdas. In the end, I did much more than initially planned. It shows where operators are invoked and places in which the compiler does some casting. C++ Insights can deduce the type behind auto or decltype. The goal is to produce compilable code. However, this is not possible in all places.

You can see, for example, the transformation of a lambda, range-based for-loop, or auto. Of course, you can transform any other C++ snippet.

See yourself. C++ Insights is available online: cppinsights.io.

Still, there is work to do.

I do not claim to get all the things right. I'm also working on supporting features from new standards, like C++20, at the moment. Please remember that C++ Insights is based on Clang and its understanding of the AST.

I did a couple of talks about C++ Insights since I released C++ Insights. For example, at C++ now. Here are the slides and the video.

Building

C++ Insights can be built inside or outside the Clang source tree.

Building on Windows

See Readme_Windows.md

Building on Arch Linux

To build with extra/clang use the following extra flags: -DINSIGHTS_USE_SYSTEM_INCLUDES=off -DCLANG_LINK_CLANG_DYLIB=on -DLLVM_LINK_LLVM_DYLIB=on

See https://github.com/andreasfertig/cppinsights/issues/186 for an explanation of why INSIGHTS_USE_SYSTEM_INCLUDES needs to be turned off.

extra/clang and extra/llvm provide /usr/lib/{libclangAST.so,libLLVM*.a,libLLVM.so}. libclangAST.so needs libLLVM.so and there would be a conflict if libLLVM*.a (instead of libLLVM.so) are linked. See https://bugs.archlinux.org/task/60512

Building outside Clang

You need to have a Clang installation in the search path.

git clone https://github.com/andreasfertig/cppinsights.git
mkdir build && cd build
cmake -G"Ninja" ../cppinsights
ninja

The resulting binary (insights) can be found in the build folder.

Building inside Clang

The easiest way to build C++ Insights inside the Clang source tree is using the LLVM_EXTERNAL_PROJECTS option.

git clone https://github.com/llvm/llvm-project.git
git clone https://github.com/andreasfertig/cppinsights.git

mkdir build
cd build
cmake -G Ninja -D=CMAKE_BUILD_TYPE=Release -DLLVM_EXTERNAL_PROJECTS=cppinsights -DLLVM_EXTERNAL_CPPINSIGHTS_SOURCE_DIR=<PATH/TO/cppinsights>  [INSIGHTS CMAKE OPTIONS] ../llvm-project/llvm

ninja

cmake options

There are a couple of options that can be enabled with cmake:

Option Description Default
INSIGHTS_STRIP Strip insight after build ON
INSIGHTS_STATIC Use static linking OFF
INSIGHTS_COVERAGE Enable code coverage OFF
INSIGHTS_USE_LIBCPP Use libc++ for tests OFF
DEBUG Enable debug OFF

Building for ARM on macOS

It seems best to supply the architecture during configuration:

cmake -DCMAKE_OSX_ARCHITECTURES=arm64 ../cppinsights

Use it with Cevelop

git clone https://github.com/andreasfertig/cppinsights.git
mkdir build_eclipse
cd build_eclipse
cmake -G"Eclipse CDT4 - Unix Makefiles" ../cppinsights/

Then, in Cevelop Import -> General -> Existing Project into Workspace. Select build_eclipse. Enjoy editing with Cevelop.

Usage

Using C++ Insights is fairly simple:

insights <YOUR_CPP_FILE> -- -std=c++17

Things get complicated when it comes to the system-include paths. These paths are hard-coded in the binary, which seems to come from the compiler C++ Insights was built with. To help with that, check out scripts/getinclude.py. The script tries to collect the system-include paths from the compiler. Without an option, getinclude.py uses g++. You can also pass another compiler as a first argument.

Here is an example:

./scripts/getinclude.py
-isystem/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1 -isystem/usr/local/include -isystem/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/7.3.0/include -isystem/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -isystem/usr/include

The script can be used together with C++ Insights:

insights <YOUR_CPP_FILE> -- -std=c++17 `./scripts/getinclude.py`

Custom GCC installation

In case you have a custom build of the GCC compiler, for example, gcc-11.2.0, and NOT installed in the compiler in the default system path, then after building, Clang fails to find the correct libstdc++ path (GCC's STL). If you run into this situation, you can use "--gcc-toolchain=/path/GCC-1x.x.x/installed/path" to tell Clang/C++ Insights the location of the STL:

./cppinsights Insights.cpp -- --gcc-toolchain=${GCC_11_2_0_INSTALL_PATH} -std=c++20

Here "${GCC_11_2_0_INSTALL_PATH}" is the installation directory of your customized-built GCC. The option for Clang is described here.

Ready to use Docker container

There is also another GitHub project that sets up a docker container with the latest C++ Insights version in it: C++ Insights - Docker

Plugins / Extensions / Packages

C++ Insights @ Vim

A plugin for Vim is available at here.

C++ Insights @ Neovim

A plugin for Neovim is available at here.

C++ Insights @ VSCode

An extension for Visual Studio Code is available at the VS Code marketplace: C++ Insights - VSCode Extension.

C++ Insights @ brew

At least for macOS, you can install C++ Insights via Homebrew thanks to this formular:

brew install cppinsights

Shell autocomplete

There are completion scripts for bash, zsh and fish. They autocomplete the C++ Insights options (including their descriptions) as well as the Clang options provided after --.

When building from source, the completion scripts are installed automatically into the shell-specific directories under share/ (configurable via CMAKE_INSTALL_PREFIX):

cmake --install build

This places the scripts at:

If you install C++ Insights yourself (or just want the script), you can download them individually:

cd <YOUR_BASH_COMPLETION.D>
curl -o insights https://github.com/andreasfertig/cppinsights/tree/main/scripts/bash-autocomplete.sh

Compatibility

I aim for the repository to compile with the latest version of Clang and at least the one before. The website tries to stay close to the latest release of Clang. However, due to certain issues (building Clang for Windows), the website's version is often delayed by a few months.

C++ Insights @ YouTube

I created a YouTube channel where I release a new video each month. In these videos, I use C++ Insights to show and explain certain C++ constructs, and sometimes I explain C++ Insights as well.

ToDo's

See TODO.

Get Involved

Support

If you like to support the project, consider submitting a patch. Another alternative is to become a GitHub Sponsor or a Patreon supporter.

cppinsights (andreasfertig/cppinsights)

Searching Database…

这是什么?C++ Insights 是一个基于 Clang 的源码到源码转换工具,它以编译器实际看待代码的方式展示 C++ 代码,揭示那些隐式发生的事情,比如编译器生成的特殊成员函数、隐式转换,以及 lambda、基于范围的 for 循环或 auto/decltype 实际展开成什么。
这是独立工具、网站,还是两者都是?两者都是:它是一个基于 Clang 的命令行工具/二进制文件(insights),你可以在本地编译运行;同一引擎也驱动着 cppinsights.io 上的在线版本。
怎么构建并运行它?用 CMake 在 Clang 源码树内或树外构建(需要搜索路径中有 Clang 安装),会生成一个 'insights' 二进制文件;在 macOS 上也可以直接通过现成的 Homebrew formula 执行 'brew install'。
构建它需要完整的 Clang/LLVM 开发环境吗?是的,你需要有可用的 Clang 安装;而且要正确设置系统头文件的包含路径,可能还需要额外的步骤,比如 getinclude.py 脚本,或者为自定义 GCC 环境添加 --gcc-toolchain 标志。
转换后的输出总能编译通过吗?不能,目标虽然是可编译的输出,但并非在所有情况下都能做到;作者也坦言他并不声称把一切都处理正确,尤其是 C++20 这类较新的标准。
它对谁最有用?C++ 开发者,以及想要具体、可读地了解编译器如何处理现代 C++ 特性的学生和教师——而不用去啃 AST 转储或汇编输出。
不从源码构建也能使用它吗?可以,除了 macOS 上的 Homebrew formula 和开箱即用的 Docker 容器,还有适用于 Vim、Neovim 的编辑器插件和一个 VS Code 扩展,以及在线托管网站。
它支持哪些 C++ 标准?它面向现代 C++ 特性,覆盖 C++11 到 C++23/26,处理 lambda、结构化绑定、基于范围的 for 循环、auto 和 decltype 等构造。
作者为什么不直接用 AST 转储,而要开发这个工具?他发现 AST 转储和 Compiler Explorer 的汇编输出用于 C++ 教学都不理想,因为两者都不是用开发者实际使用的语言写成的,于是他开发了一个输出可读、接近可编译 C++ 的工具。
它跟进 Clang 新版本的紧密程度如何?该仓库的目标是能用最新版 Clang 及其前一版本编译;公开网站尽量跟进最新的 Clang 发布,但由于 Windows 上的构建问题,可能滞后几个月。
在哪里可以学习如何阅读它的输出?作者运营着一个 YouTube 频道,每月发布视频讲解 C++ 构造以及如何解读 C++ Insights 的输出。
Size
3.1 MB
Stars
4.7K
Age
8y
Commits · 90 Days