From 841a75e1b6dca35f9552222d43a56d1e76608fac Mon Sep 17 00:00:00 2001 From: Andrzej Warzynski Date: Sun, 5 May 2024 15:29:23 +0100 Subject: [PATCH] Update to LLVM 18 --- .../x86-darwin-llvm-from-sources.yml | 4 +- .github/workflows/x86-darwin.yml | 8 ++-- .../x86-ubuntu-llvm-from-sources.yml | 4 +- .github/workflows/x86-ubuntu.yml | 10 ++--- CMakeLists.txt | 6 +-- HelloWorld/CMakeLists.txt | 21 ++++++++-- HelloWorld/HelloWorld.cpp | 4 +- README.md | 42 +++++++++---------- lib/CodeStyleChecker.cpp | 4 +- 9 files changed, 58 insertions(+), 45 deletions(-) diff --git a/.github/workflows/x86-darwin-llvm-from-sources.yml b/.github/workflows/x86-darwin-llvm-from-sources.yml index cb33607..695165a 100644 --- a/.github/workflows/x86-darwin-llvm-from-sources.yml +++ b/.github/workflows/x86-darwin-llvm-from-sources.yml @@ -21,11 +21,11 @@ jobs: echo "${GITHUB_WORKSPACE}/ninja" >> $GITHUB_PATH - name: Clone llvm-project run: | - git clone --depth 1 --single-branch --branch release/16.x https://github.com/llvm/llvm-project + git clone --depth 1 --single-branch --branch release/18.x https://github.com/llvm/llvm-project - name: Build LLVM & Clang run: | cd llvm-project - git checkout release/16.x + git checkout release/18.x mkdir build && cd build cmake -G Ninja \ -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang" \ diff --git a/.github/workflows/x86-darwin.yml b/.github/workflows/x86-darwin.yml index 8467ef3..8ca9018 100644 --- a/.github/workflows/x86-darwin.yml +++ b/.github/workflows/x86-darwin.yml @@ -27,19 +27,19 @@ jobs: - name: Install Dependencies run: | brew update - brew install llvm@16 + brew install llvm brew install lit - name: Build HelloWorld run: | cd HelloWorld mkdir build && cd build - cmake -DCT_Clang_INSTALL_DIR=/usr/local/opt/llvm@16/ -DCMAKE_BUILD_TYPE=${{ matrix.type }} ../ + cmake -DCT_Clang_INSTALL_DIR=/opt/homebrew/opt/llvm/ -DCMAKE_BUILD_TYPE=${{ matrix.type }} ../ make -j2 - /usr/local/opt/llvm@16/bin/clang -cc1 -load ./libHelloWorld.dylib -plugin hello-world $GITHUB_WORKSPACE/test/HelloWorld-basic.cpp + /opt/homebrew/opt/llvm/bin/clang -cc1 -load ./libHelloWorld.dylib -plugin hello-world $GITHUB_WORKSPACE/test/HelloWorld-basic.cpp - name: Build clang-tutor + run tests run: | cd $GITHUB_WORKSPACE mkdir build && cd build - cmake -DCT_Clang_INSTALL_DIR=/usr/local/opt/llvm@16/ -DCMAKE_BUILD_TYPE=${{ matrix.type }} ../ + cmake -DCT_Clang_INSTALL_DIR=/opt/homebrew/opt/llvm/ -DCMAKE_BUILD_TYPE=${{ matrix.type }} ../ make -j2 lit test/ diff --git a/.github/workflows/x86-ubuntu-llvm-from-sources.yml b/.github/workflows/x86-ubuntu-llvm-from-sources.yml index 79e9c3e..fbbcc2a 100644 --- a/.github/workflows/x86-ubuntu-llvm-from-sources.yml +++ b/.github/workflows/x86-ubuntu-llvm-from-sources.yml @@ -21,7 +21,7 @@ jobs: echo "${GITHUB_WORKSPACE}/ninja" >> $GITHUB_PATH - name: Clone llvm-project run: | - git clone --depth 1 --single-branch --branch release/16.x https://github.com/llvm/llvm-project + git clone --depth 1 --single-branch --branch release/18.x https://github.com/llvm/llvm-project - name: Make ld.gold the default linker run: | # This a quick and easy hack. Not something I would use on my @@ -31,7 +31,7 @@ jobs: - name: Build LLVM & Clang run: | cd llvm-project - git checkout release/16.x + git checkout release/18.x mkdir build && cd build cmake -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ diff --git a/.github/workflows/x86-ubuntu.yml b/.github/workflows/x86-ubuntu.yml index 873a01e..c9a0adb 100644 --- a/.github/workflows/x86-ubuntu.yml +++ b/.github/workflows/x86-ubuntu.yml @@ -22,9 +22,9 @@ jobs: - name: Install Dependencies run: | wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - - sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-16 main" + sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-18 main" sudo apt-get update - sudo apt-get install -y llvm-16 llvm-16-dev libllvm16 clang-16 libclang-common-16-dev libclang-16-dev llvm-16-tools + sudo apt-get install -y llvm-18 llvm-18-dev libllvm18 clang-18 libclang-common-18-dev libclang-18-dev llvm-18-tools sudo apt-get install python3-setuptools sudo apt-get install ${{ matrix.compiler.CXX }} sudo pip3 install lit @@ -36,9 +36,9 @@ jobs: cd HelloWorld mkdir build && cd build # HelloWorld only supports CT_Clang_INSTALL_DIR - cmake -DCT_Clang_INSTALL_DIR=/usr/lib/llvm-16/ -DCMAKE_BUILD_TYPE=${{ matrix.type }} ../ + cmake -DCT_Clang_INSTALL_DIR=/usr/lib/llvm-18/ -DCMAKE_BUILD_TYPE=${{ matrix.type }} ../ make -j2 - /usr/lib/llvm-16/bin/clang -cc1 -load ./libHelloWorld.so -plugin hello-world $GITHUB_WORKSPACE/test/HelloWorld-basic.cpp + /usr/lib/llvm-18/bin/clang -cc1 -load ./libHelloWorld.so -plugin hello-world $GITHUB_WORKSPACE/test/HelloWorld-basic.cpp - name: Build clang-tutor + run tests env: CC: ${{ matrix.compiler.CC }} @@ -47,6 +47,6 @@ jobs: cd $GITHUB_WORKSPACE mkdir build && cd build # Test with Clang_ROOT - cmake -DClang_ROOT=/usr/lib/llvm-16/lib/cmake/clang/ -DCMAKE_BUILD_TYPE=${{ matrix.type }} ../ + cmake -DClang_ROOT=/usr/lib/llvm-18/lib/cmake/clang/ -DCMAKE_BUILD_TYPE=${{ matrix.type }} ../ make -j2 lit test/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 353ec0b..b8e693f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.13.4) +cmake_minimum_required(VERSION 3.20) project(clang-tutor) #=============================================================================== @@ -51,8 +51,8 @@ find_package(Clang REQUIRED CONFIG) # Sanity check. As Clang does not expose e.g. `CLANG_VERSION_MAJOR` through # AddClang.cmake, we have to use LLVM_VERSION_MAJOR instead. # TODO: Revisit when next version is released. -if("${LLVM_VERSION_MAJOR}" VERSION_LESS 16) - message(FATAL_ERROR "Found LLVM ${LLVM_VERSION_MAJOR}, but need LLVM 16 or above") +if("${LLVM_VERSION_MAJOR}" VERSION_LESS 18) + message(FATAL_ERROR "Found LLVM ${LLVM_VERSION_MAJOR}, but need LLVM 18 or above") endif() message(STATUS "Found Clang ${LLVM_PACKAGE_VERSION}") diff --git a/HelloWorld/CMakeLists.txt b/HelloWorld/CMakeLists.txt index 2178cbc..af865e1 100644 --- a/HelloWorld/CMakeLists.txt +++ b/HelloWorld/CMakeLists.txt @@ -1,24 +1,27 @@ -cmake_minimum_required(VERSION 3.4.3) +cmake_minimum_required(VERSION 3.20) project(clang-tutor-hello-world) #=============================================================================== -# 1. LOAD LLVM CONFIGURATION +# 1. LOAD Clang CONFIGURATION #=============================================================================== # Set this to a valid LLVM installation dir -set(CT_Clang_INSTALL_DIR "" CACHE PATH "LLVM installation directory") +set(CT_Clang_INSTALL_DIR "" CACHE PATH "Clang installation directory") # Add the location of ClangConfig.cmake to CMake search paths (so that # find_package can locate it) list(APPEND CMAKE_PREFIX_PATH "${CT_Clang_INSTALL_DIR}/lib/cmake/clang/") find_package(Clang REQUIRED CONFIG) +if("${LLVM_VERSION_MAJOR}" VERSION_LESS 18) + message(FATAL_ERROR "Found LLVM ${LLVM_VERSION_MAJOR}, but need LLVM 18 or above") +endif() # HelloWorld includes headers from LLVM and Clang - update the include paths # accordingly include_directories(SYSTEM "${LLVM_INCLUDE_DIRS};${CLANG_INCLUDE_DIRS}") #=============================================================================== -# 2. LLVM-TUTOR BUILD CONFIGURATION +# 2. CLANG-TUTOR BUILD CONFIGURATION #=============================================================================== # Use the same C++ standard as LLVM does set(CMAKE_CXX_STANDARD 17 CACHE STRING "") @@ -28,6 +31,16 @@ if(NOT LLVM_ENABLE_RTTI) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti") endif() +# -fvisibility-inlines-hidden is set when building LLVM and on Darwin warnings +# are triggered if llvm-tutor is built without this flag (though otherwise it +# builds fine). For consistency, add it here too. +include(CheckCXXCompilerFlag) +check_cxx_compiler_flag("-fvisibility-inlines-hidden" + SUPPORTS_FVISIBILITY_INLINES_HIDDEN_FLAG) +if(${SUPPORTS_FVISIBILITY_INLINES_HIDDEN_FLAG} EQUAL "1") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden") +endif() + #=============================================================================== # 3. ADD THE TARGET #=============================================================================== diff --git a/HelloWorld/HelloWorld.cpp b/HelloWorld/HelloWorld.cpp index c3b6a8b..306be16 100644 --- a/HelloWorld/HelloWorld.cpp +++ b/HelloWorld/HelloWorld.cpp @@ -57,8 +57,8 @@ bool HelloWorld::VisitCXXRecordDecl(CXXRecordDecl *Declaration) { FullLocation = FullLocation.getExpansionLoc(); SourceManager &SrcMgr = Context->getSourceManager(); - const FileEntry *Entry = - SrcMgr.getFileEntryForID(SrcMgr.getFileID(FullLocation)); + OptionalFileEntryRef Entry = + SrcMgr.getFileEntryRefForID(SrcMgr.getFileID(FullLocation)); DeclMap[Entry->getName()]++; return true; diff --git a/README.md b/README.md index cefe037..5d45906 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ clang-tutor [![x86-Darwin](https://github.com/banach-space/clang-tutor/actions/workflows/x86-darwin.yml/badge.svg)](https://github.com/banach-space/clang-tutor/actions/workflows/x86-darwin.yml) -Example Clang plugins for C and C++ - based on **Clang 16** +Example Clang plugins for C and C++ - based on **Clang 18** **clang-tutor** is a collection of self-contained reference Clang plugins. It's a tutorial that targets novice and aspiring Clang developers. Key features: @@ -52,7 +52,7 @@ implements the minimum set-up for an out-of-tree plugin. **HelloWorld** extracts some interesting information from the input _translation unit_. It visits all [C++ record -declarations](https://github.com/llvm/llvm-project/blob/release/16.x/clang/include/clang/AST/DeclCXX.h#L253) +declarations](https://github.com/llvm/llvm-project/blob/release/18.x/clang/include/clang/AST/DeclCXX.h#L253) (more specifically class, struct and union declarations) and counts them. Recall that translation unit consists of the input source file and all the header files that it includes (directly or indirectly). @@ -66,7 +66,7 @@ You can build and run **HelloWorld** like this: ```bash # Build the plugin -export Clang_DIR= +export Clang_DIR= export CLANG_TUTOR_DIR= mkdir build cd build @@ -123,7 +123,7 @@ Development Environment **clang-tutor** has been tested on **Ubuntu 20.04** and **Mac OS X 10.14.6**. In order to build **clang-tutor** you will need: - * LLVM 16 and Clang 16 + * LLVM 18 and Clang 18 * C++ compiler that supports C++17 * CMake 3.13.4 or higher @@ -132,14 +132,14 @@ As Clang is a subproject within **clang-tutor** requires development packages for both Clang and LLVM). There are additional requirements for tests (these will be satisfied by -installing LLVM 16): +installing LLVM 18): * [**lit**](https://llvm.org/docs/CommandGuide/lit.html) (aka **llvm-lit**, LLVM tool for executing the tests) * [**FileCheck**](https://llvm.org/docs/CommandGuide/FileCheck.html) (LIT requirement, it's used to check whether tests generate the expected output) -## Installing Clang 16 On Mac OS X -On Darwin you can install Clang 16 and LLVM 16 with +## Installing Clang 18 On Mac OS X +On Darwin you can install Clang 18 and LLVM 18 with [Homebrew](https://brew.sh/): ```bash @@ -147,7 +147,7 @@ brew install llvm ``` If you already have an older version of Clang and LLVM installed, you can -upgrade it to Clang 16 and LLVM 16 like this: +upgrade it to Clang 18 and LLVM 18 like this: ```bash brew upgrade llvm @@ -156,29 +156,29 @@ brew upgrade llvm Once the installation (or upgrade) is complete, all the required header files, libraries and tools will be located in `/usr/local/opt/llvm/`. -## Installing Clang 16 On Ubuntu +## Installing Clang 18 On Ubuntu On Ubuntu Jammy Jellyfish, you can [install modern LLVM](https://blog.kowalczyk.info/article/k/how-to-install-latest-clang-6.0-on-ubuntu-16.04-xenial-wsl.html) from the official [repository](http://apt.llvm.org/): ```bash wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - -sudo apt-add-repository "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-16 main" +sudo apt-add-repository "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-18 main" sudo apt-get update -sudo apt-get install -y llvm-16 llvm-16-dev libllvm16 llvm-16-tools clang-16 libclang-common-16-dev libclang-16-dev libmlir-16 libmlir-16-dev +sudo apt-get install -y llvm-18 llvm-18-dev libllvm18 llvm-18-tools clang-18 libclang-common-18-dev libclang-18-dev libmlir-18 libmlir-18-dev ``` This will install all the required header files, libraries and tools in -`/usr/lib/llvm-16/`. +`/usr/lib/llvm-18/`. -## Building Clang 16 From Sources +## Building Clang 18 From Sources Building from sources can be slow and tricky to debug. It is not necessary, but -might be your preferred way of obtaining LLVM/Clang 16. The following steps +might be your preferred way of obtaining LLVM/Clang 18. The following steps will work on Linux and Mac OS X: ```bash git clone https://github.com/llvm/llvm-project.git cd llvm-project -git checkout release/16.x +git checkout release/18.x mkdir build cd build cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD=host -DLLVM_ENABLE_PROJECTS="clang;libcxx;libcxxabi" /llvm/ @@ -199,17 +199,17 @@ Building & Testing You can build **clang-tutor** (and all the provided plugins) as follows: ```bash cd -cmake -DCT_Clang_INSTALL_DIR= +cmake -DCT_Clang_INSTALL_DIR= make ``` The `CT_Clang_INSTALL_DIR` variable should be set to the root of either the -installation or build directory of Clang 16. It is used to locate the +installation or build directory of Clang 18. It is used to locate the corresponding `LLVMConfig.cmake` script that is used to set the include and library paths. In order to run the tests, you need to install **llvm-lit** (aka **lit**). It's -not bundled with LLVM 16 packages, but you can install it with **pip**: +not bundled with LLVM 18 packages, but you can install it with **pip**: ```bash # Install lit - note that this installs lit globally pip install lit @@ -307,16 +307,16 @@ explaination about it can be found on [Eli Bendersky's blog](https://eli.thegree ## CodeStyleChecker This plugin demonstrates how to use Clang's -[DiagnosticEngine](https://github.com/llvm/llvm-project/blob/release/16.x/clang/include/clang/Basic/Diagnostic.h#L191) +[DiagnosticEngine](https://github.com/llvm/llvm-project/blob/release/18.x/clang/include/clang/Basic/Diagnostic.h#L191) to generate custom compiler warnings. Essentially, **CodeStyleChecker** checks whether names of classes, functions and variables in the input translation unit adhere to LLVM's [style guide](https://llvm.org/docs/CodingStandards.html#name-types-functions-variables-and-enumerators-properly). If not, a warning is printed. For every warning, **CodeStyleChecker** generates a suggestion that would fix the corresponding issue. This is done with the -[FixItHint](https://github.com/llvm/llvm-project/blob/release/16.x/clang/include/clang/Basic/Diagnostic.h#L70) +[FixItHint](https://github.com/llvm/llvm-project/blob/release/18.x/clang/include/clang/Basic/Diagnostic.h#L70) API. -[SourceLocation](https://github.com/llvm/llvm-project/blob/release/16.x/clang/include/clang/Basic/SourceLocation.h#L86) +[SourceLocation](https://github.com/llvm/llvm-project/blob/release/18.x/clang/include/clang/Basic/SourceLocation.h#L86) API is used to generate valid source location. **CodeStyleChecker** is robust enough to cope with complex examples like diff --git a/lib/CodeStyleChecker.cpp b/lib/CodeStyleChecker.cpp index 62d61f5..f368d15 100644 --- a/lib/CodeStyleChecker.cpp +++ b/lib/CodeStyleChecker.cpp @@ -177,10 +177,10 @@ class CSCASTAction : public PluginASTAction { bool ParseArgs(const CompilerInstance &CI, const std::vector &Args) override { for (StringRef Arg : Args) { - if (Arg.startswith("-main-tu-only=")) + if (Arg.starts_with("-main-tu-only=")) MainTuOnly = Arg.substr(strlen("-main-tu-only=")).equals_insensitive("true"); - else if (Arg.startswith("-help")) + else if (Arg.starts_with("-help")) PrintHelp(llvm::errs()); else return false;