Skip to content

Modifying the Redpoint Clang LLVM Fork

June Rhodes edited this page Jul 9, 2024 · 1 revision

If you want to modify this fork (perhaps to add your own AST matchers or contribute back changes), this document describes how to build it from source on Windows.

Prerequisites

To build this fork from source, you'll need:

  • CMake, installed underneath "C:\Program Files".
  • Visual Studio / C++ toolchain.

Building Clang/LLVM

Then, at an Administrative PowerShell prompt in the directory where you've cloned this repository, run:

.redpoint\build.ps1

This will generate Visual Studio projects underneath build\win64\debug and build\win64\release, and then build the Release version. If you want to build in Debug, you can pass -Debug to the script. Note that each build directory will only have a VS configuration for either Debug or Release, but not both since the LLVM build scripts cause unnecessary rebuilding when swapping configurations in VS if the same directory is used for multiple configurations.

The Debug build of Clang/LLVM is only really suitable when testing small C++ files. The Debug compiler is simply too slow to actually build Unreal Engine code, so for any testing against Unreal C++, you'll need to use the Release build instead (and probably just add logging with llvm::errs() << "some test message\n"; where needed).

Installing Clang/LLVM

To install your source build and use it with the Unreal Engine build system, use -Install. This will build (if needed) and install the Release build underneath C:\Program Files\LLVM. If you have an existing build of LLVM, it will overwrite it. You must be at an Administrative terminal to use -Install, or you'll get permission errors.

If you want to install only (and skip potentially building if out-of-date), use -InstallOnly instead of -Install.

Adding a new AST Matcher

If you want to add a new AST matcher for use in Clang rulesets, the relevant files are:

  • clang\include\clang\ASTMatchers\ASTMatchers.Unreal.h: This file is where most AST matchers are declared and defined, using the AST_MATCHER macros. There are plenty of examples here on how to write an AST matcher of any kind, and using Visual Studio's "Go to Definition" for various Clang declaration types is useful for figuring how what functions various Clang AST nodes have available.
  • clang\lib\ASTMatchers\Dynamic\Registry.Unreal.h: This file is where the AST matchers are registered. After adding an AST matcher to ASTMatchers.Unreal.h, you need to add a line to this file to register it at runtime.
  • clang\lib\ASTMatchers\ASTMatchersInternal.Unreal.h: Only for some advanced AST matchers that can't be fully defined in ASTMatchers.Unreal.h.

If you're looking for these files in Visual Studio, they show up in the Solution Explorer under Object Libraries -> obj.clangASTMatchers and Object Libraries -> obj.clangDynamicASTMatchers.

If you do add your own AST matcher, it's highly recommended that you do so in a GitHub fork and, once it's working, create a Pull Request to get it merged back into this fork. We're already forked off Clang/LLVM upstream, so we're pretty likely to accept any AST matcher that people create.

Hacking on the Clang rulesets engine

If you want to add new options to the Clang rulesets engine itself, or modify how it works, the relevant file is:

  • clang\lib\Frontend\ClangRulesets.cpp

There is technically an accompanying header file, but it only declares ClangRulesetsProvider::CreateASTConsumer which is already called in the correct place inside Clang to get the rulesets engine wired up.

This file has a few defines you can toggle on during development:

  • RULESET_ENABLE_TIMING: Enables time tracing for Clang ruleset evaluation. By default, it only activates at runtime if the -ftime-report option is passed.
  • RULESET_ENABLE_TIMING_ALWAYS: If RULESET_ENABLE_TIMING is enabled, this forces it to always be active, even when Clang isn't doing time tracing for it's other operations. Building with this option enabled will result in time data for Clang rulesets emitted to the "Build" window for Unreal Engine builds, so it's really only used temporarily in development to make sure Clang rulesets isn't negatively impacting build performance.
  • RULESET_ENABLE_TRACING: Enables extremely verbose logging output from Clang for the operations that Clang rulesets is performing, such as calculating what .clang-rules files apply, figuring out what rules to match against, etc. Any debugging output you add should always use RULESET_TRACE to ensure it gets compiled out when Clang/LLVM is built for distribution.