Compare commits

...

6 Commits

Author SHA1 Message Date
Bartek Kryza
1fe8640f7c Fixed Doxygen generation rules 2023-11-04 18:31:04 +01:00
Bartek Kryza
15233aa0da Refactored LLVM paths detection based on llvm-config binary 2023-11-04 17:34:55 +01:00
Bartek Kryza
5435f0ac30 Merge pull request #200 from bkryza/fix-gcc13-build
Ignore Wdangling-reference warnings on GCC 13
2023-10-25 14:03:12 +02:00
Bartek Kryza
7cf61a98aa Ignore Wdangling-reference warnings on GCC 13 2023-10-25 14:02:35 +02:00
Bartek Kryza
79801b2936 Fix handling of template template arguments which are not expressions (#199) 2023-10-24 18:29:47 +02:00
Bartek Kryza
57bc2f7309 Merge pull request #198 from bkryza/v0.4.1
V0.4.1
2023-10-22 19:46:41 +02:00
12 changed files with 168 additions and 103 deletions

View File

@@ -3,6 +3,7 @@ output_directory: docs/diagrams
comment_parser: clang
remove_compile_flags:
- -Wno-class-memaccess
- -Wno-dangling-reference
generate_links:
link: "{% if existsIn(element, \"doxygen_link\") %}{{ element.doxygen_link }}{% endif %}"
tooltip: "{% if existsIn(element, \"comment\") and existsIn(element.comment, \"brief\") %}{{ abbrv(trim(replace(element.comment.brief.0, \"\\n+\", \" \")), 256) }}{% else %}{{ element.name }}{% endif %}"

View File

@@ -46,6 +46,7 @@ endif(APPLE)
#
option(LINK_LLVM_SHARED "Should LLVM be linked using shared libraries" ON)
set(LLVM_VERSION CACHE STRING "Major LLVM version to use (e.g. 15)")
set(LLVM_CONFIG_PATH CACHE STRING "Path to llvm-config binary")
#
# Setup version string
@@ -58,92 +59,27 @@ message(STATUS "clang-uml version: "
#
# Setup LLVM
#
message(STATUS "Checking for LLVM and Clang...")
if(LLVM_PREFIX)
message(STATUS "Using llvm-config from ${LLVM_CONFIG_PATH}")
set(LIBCLANG_LLVM_CONFIG_EXECUTABLE ${LLVM_CONFIG_PATH})
set(LLVM_CONFIG_BINARY ${LLVM_CONFIG_PATH})
endif(LLVM_PREFIX)
find_package(LLVM ${LLVM_VERSION} CONFIG REQUIRED)
list(APPEND CMAKE_MODULE_PATH ${LLVM_DIR})
include(AddLLVM)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
message(STATUS "LLVM library dir: ${LLVM_LIBRARY_DIR}")
if(MSVC)
# LLVM_BUILD_LLVM_DYLIB is not available on Windows
set(LINK_LLVM_SHARED NO)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif(MSVC)
if(LINK_LLVM_SHARED)
set(LIBTOOLING_LIBS clang-cpp LLVM)
else(LINK_LLVM_SHARED)
set(LIBTOOLING_LIBS
clangLex
clangFrontend
clangSerialization
clangDriver
clangParse
clangSema
clangSupport
clangAnalysis
clangAST
clangBasic
clangEdit
clangLex
clangTooling
LLVMipo
LLVMScalarOpts
LLVMInstCombine
LLVMTransformUtils
LLVMAnalysis
LLVMTarget
LLVMOption
LLVMMCParser
LLVMMC
LLVMObject
LLVMBitReader
LLVMCore
LLVMSupport)
if(MSVC)
if(${LLVM_PACKAGE_VERSION} VERSION_LESS "15.0")
list(REMOVE_ITEM LIBTOOLING_LIBS clangSupport)
else()
list(APPEND LIBTOOLING_LIBS
LLVMWindowsDriver
LLVMWindowsManifest)
endif()
endif(MSVC)
endif(LINK_LLVM_SHARED)
if("${LIBTOOLING_LIBS}" STREQUAL "")
message(FATAL_ERROR "Failed to find LibTooling libraries!")
else()
message(STATUS "Found LibTooling libraries: ${LIBTOOLING_LIBS}")
endif()
if(APPLE OR (LLVM_VERSION_MAJOR GREATER_EQUAL 16))
set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES
${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
endif()
include(LLVMSetup)
#
# Setup custom compile options depending on various compiler
# and environment quirks
#
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "13.0")
# Workaround over Wdangling-reference false positives in libfmt
set(CUSTOM_COMPILE_OPTIONS ${CUSTOM_COMPILE_OPTIONS} -Wno-dangling-reference)
endif()
endif()
if(LLVM_VERSION_MAJOR GREATER_EQUAL 17)
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CUSTOM_COMPILE_OPTIONS "-Wno-class-memaccess")
set(CUSTOM_COMPILE_OPTIONS ${CUSTOM_COMPILE_OPTIONS} -Wno-class-memaccess)
endif()
endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(CUSTOM_COMPILE_OPTIONS
"${CUSTOM_COMPILE_OPTIONS} -Wno-unused-private-field")
${CUSTOM_COMPILE_OPTIONS} -Wno-unused-private-field)
endif()
#
@@ -156,8 +92,6 @@ find_package(Threads REQUIRED)
#
message(STATUS "Checking for yaml-cpp...")
if(APPLE)
find_package(PkgConfig)
if(PKG_CONFIG_FOUND)
pkg_check_modules(YAML_CPP yaml-cpp)
@@ -219,4 +153,4 @@ option(BUILD_TESTS "" ON)
if(BUILD_TESTS)
enable_testing()
add_subdirectory(tests)
endif(BUILD_TESTS)
endif(BUILD_TESTS)

View File

@@ -1014,7 +1014,7 @@ EXAMPLE_RECURSIVE = NO
# \image command).
IMAGE_PATH = docs/img
IMAGE_PATH += docs/diagrams
IMAGE_PATH += docs/diagrams/plantuml
IMAGE_PATH += docs/test_cases
# The INPUT_FILTER tag can be used to specify a program that doxygen should

View File

@@ -31,6 +31,7 @@ else
endif
LLVM_VERSION ?=
LLVM_CONFIG_PATH ?=
CMAKE_CXX_FLAGS ?=
CMAKE_EXE_LINKER_FLAGS ?=
@@ -52,7 +53,8 @@ debug/CMakeLists.txt:
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_FLAGS="$(CMAKE_CXX_FLAGS)" \
-DCMAKE_EXE_LINKER_FLAGS="$(CMAKE_EXE_LINKER_FLAGS)" \
-DLLVM_VERSION=${LLVM_VERSION}
-DLLVM_VERSION=${LLVM_VERSION} \
-DLLVM_CONFIG_PATH=${LLVM_CONFIG_PATH}
release/CMakeLists.txt:
cmake -S . -B release \
@@ -61,7 +63,8 @@ release/CMakeLists.txt:
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_FLAGS="$(CMAKE_CXX_FLAGS)" \
-DCMAKE_EXE_LINKER_FLAGS="$(CMAKE_EXE_LINKER_FLAGS)" \
-DLLVM_VERSION=${LLVM_VERSION}
-DLLVM_VERSION=${LLVM_VERSION} \
-DLLVM_CONFIG_PATH=${LLVM_CONFIG_PATH}
debug_tidy/CMakeLists.txt:
cmake -S . -B debug_tidy \
@@ -71,7 +74,8 @@ debug_tidy/CMakeLists.txt:
-DBUILD_TESTS=OFF \
-DCMAKE_CXX_FLAGS="$(CMAKE_CXX_FLAGS)" \
-DCMAKE_EXE_LINKER_FLAGS="$(CMAKE_EXE_LINKER_FLAGS)" \
-DLLVM_VERSION=${LLVM_VERSION}
-DLLVM_VERSION=${LLVM_VERSION} \
-DLLVM_CONFIG_PATH=${LLVM_CONFIG_PATH}
debug: debug/CMakeLists.txt
echo "Using ${NUMPROC} cores"
@@ -158,8 +162,8 @@ docs:
doxygen: docs
cp CONTRIBUTING.md docs/contributing.md
cp CHANGELOG.md docs/changelog.md
cp docs/diagrams/plantuml/*.svg docs/doxygen/html/
mkdir -p docs/doxygen/html/test_cases
cp docs/diagrams/plantuml/*.svg docs/doxygen/html/
cp docs/test_cases/*.svg docs/doxygen/html/test_cases/
../doxygen/_build/bin/doxygen

90
cmake/LLVMSetup.cmake Normal file
View File

@@ -0,0 +1,90 @@
message(STATUS "Checking for LLVM and Clang...")
# If user provided a path to llvm-config executable use it to detect
# LLVM Version and appropriate CMake module path
if(NOT "${LLVM_CONFIG_PATH}" STREQUAL "")
# Get LLVM prefix
message(STATUS "Using llvm-config from ${LLVM_CONFIG_PATH}")
set(LIBCLANG_LLVM_CONFIG_EXECUTABLE ${LLVM_CONFIG_PATH})
set(LLVM_CONFIG_BINARY ${LLVM_CONFIG_PATH})
execute_process(COMMAND ${LLVM_CONFIG_PATH} --prefix
OUTPUT_VARIABLE LLVM_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE)
set(LLVM_CMAKE_DIR "${LLVM_PREFIX}/lib/cmake/llvm")
list(APPEND CMAKE_MODULE_PATH ${LLVM_DIR})
# Get LLVM version
execute_process(COMMAND ${LLVM_CONFIG_PATH} --version
OUTPUT_VARIABLE LLVM_VERSION_STR OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.(.+)"
GIT_VERSION_MATCH ${LLVM_VERSION_STR})
set(LLVM_VERSION ${CMAKE_MATCH_1})
endif()
find_package(LLVM ${LLVM_VERSION} CONFIG REQUIRED)
list(APPEND CMAKE_MODULE_PATH ${LLVM_CMAKE_DIR})
include(AddLLVM)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake from: ${LLVM_CMAKE_DIR}")
message(STATUS "LLVM library dir: ${LLVM_LIBRARY_DIR}")
if(MSVC)
# LLVM_BUILD_LLVM_DYLIB is not available on Windows
set(LINK_LLVM_SHARED NO)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif(MSVC)
if(LINK_LLVM_SHARED)
set(LIBTOOLING_LIBS clang-cpp LLVM)
else(LINK_LLVM_SHARED)
set(LIBTOOLING_LIBS
clangLex
clangFrontend
clangSerialization
clangDriver
clangParse
clangSema
clangSupport
clangAnalysis
clangAST
clangBasic
clangEdit
clangLex
clangTooling
LLVMipo
LLVMScalarOpts
LLVMInstCombine
LLVMTransformUtils
LLVMAnalysis
LLVMTarget
LLVMOption
LLVMMCParser
LLVMMC
LLVMObject
LLVMBitReader
LLVMCore
LLVMSupport)
if(MSVC)
if(${LLVM_PACKAGE_VERSION} VERSION_LESS "15.0")
list(REMOVE_ITEM LIBTOOLING_LIBS clangSupport)
else()
list(APPEND LIBTOOLING_LIBS
LLVMWindowsDriver
LLVMWindowsManifest)
endif()
endif(MSVC)
endif(LINK_LLVM_SHARED)
if("${LIBTOOLING_LIBS}" STREQUAL "")
message(FATAL_ERROR "Failed to find LibTooling libraries!")
else()
message(STATUS "Found LibTooling libraries: ${LIBTOOLING_LIBS}")
endif()
if(APPLE OR (LLVM_VERSION_MAJOR GREATER_EQUAL 16))
set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES
${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
endif()

View File

@@ -33,16 +33,16 @@ sudo apt install clang-uml
```bash
# Fedora 36
wget https://github.com/bkryza/clang-uml/releases/download/0.4.0/clang-uml-0.4.0-1.fc36.x86_64.rpm
sudo dnf install ./clang-uml-0.4.0-1.fc36.x86_64.rpm
wget https://github.com/bkryza/clang-uml/releases/download/0.4.1/clang-uml-0.4.1-1.fc36.x86_64.rpm
sudo dnf install ./clang-uml-0.4.1-1.fc36.x86_64.rpm
# Fedora 37
wget https://github.com/bkryza/clang-uml/releases/download/0.4.0/clang-uml-0.4.0-1.fc37.x86_64.rpm
sudo dnf install ./clang-uml-0.4.0-1.fc37.x86_64.rpm
wget https://github.com/bkryza/clang-uml/releases/download/0.4.1/clang-uml-0.4.1-1.fc37.x86_64.rpm
sudo dnf install ./clang-uml-0.4.1-1.fc37.x86_64.rpm
# Fedora 38
wget https://github.com/bkryza/clang-uml/releases/download/0.4.0/clang-uml-0.4.0-1.fc38.x86_64.rpm
sudo dnf install ./clang-uml-0.4.0-1.fc38.x86_64.rpm
wget https://github.com/bkryza/clang-uml/releases/download/0.4.1/clang-uml-0.4.1-1.fc38.x86_64.rpm
sudo dnf install ./clang-uml-0.4.1-1.fc38.x86_64.rpm
```
#### Conda
@@ -78,7 +78,9 @@ make release
release/src/clang-uml --help
# To build using a specific installed version of LLVM use:
LLVM_VERSION=14 make release
LLVM_VERSION=16 make release
# or specify path to a specific llvm-config binary, e.g.:
LLVM_CONFIG_PATH=/usr/bin/llvm-config-16 make release
# Optionally, to install in default prefix
make install
@@ -95,7 +97,7 @@ brew install ccache cmake llvm yaml-cpp
export CC=/usr/local/opt/llvm/bin/clang
export CCX=/usr/local/opt/llvm/bin/clang++
LLVM_VERSION=14 make release
LLVM_VERSION=16 make release
```
#### Windows
@@ -164,10 +166,12 @@ bin\clang-uml.exe --version
```
It should produce something like:
```bash
clang-uml 0.4.0
clang-uml 0.4.1
Copyright (C) 2021-2023 Bartek Kryza <bkryza@gmail.com>
Built against LLVM/Clang libraries version: 15.0.6
Using LLVM/Clang libraries version: clang version 15.0.6 (https://github.com/llvm/llvm-project.git 088f33605d8a61ff519c580a71b1dd57d16a03f8)
Linux x86_64 6.2.0-36-generic
Built against LLVM/Clang libraries version: 17.0.3
Using LLVM/Clang libraries version: Ubuntu clang version 17.0.3 (++20231010073202+37b79e779f44-1~exp1~20231010073304.52)
```
Finally, remove the temporary build directory:

View File

@@ -238,6 +238,11 @@ std::string to_string(const clang::Expr *expr)
return result;
}
std::string to_string(const clang::ValueDecl *val)
{
return val->getQualifiedNameAsString();
}
std::string to_string(const clang::Stmt *stmt)
{
const clang::LangOptions lang_options;

View File

@@ -111,6 +111,8 @@ std::string to_string(
std::string to_string(const clang::Expr *expr);
std::string to_string(const clang::ValueDecl *val);
std::string to_string(const clang::Stmt *stmt);
std::string to_string(const clang::FunctionTemplateDecl *decl);

View File

@@ -76,7 +76,7 @@ clang::ASTContext *call_expression_context::get_ast_context() const
}
if (current_method_decl_ != nullptr) {
return &current_function_decl_->getASTContext();
return &current_method_decl_->getASTContext();
}
return nullptr;

View File

@@ -1601,11 +1601,20 @@ bool translation_unit_visitor::process_template_parameters(
clang::dyn_cast_or_null<clang::TemplateTemplateParmDecl>(
parameter);
std::optional<std::string> default_arg;
if (template_template_parameter->hasDefaultArgument())
default_arg = common::to_string(
if (template_template_parameter->hasDefaultArgument()) {
const auto &def_arg =
template_template_parameter->getDefaultArgument()
.getArgument()
.getAsExpr());
.getArgument();
if (def_arg.getKind() ==
clang::TemplateArgument::ArgKind::Expression) {
default_arg = common::to_string(def_arg.getAsExpr());
}
else if (def_arg.getKind() ==
clang::TemplateArgument::ArgKind::Declaration) {
default_arg = common::to_string(def_arg.getAsDecl());
}
}
auto ct = template_parameter::make_template_template_type(
template_template_parameter->getNameAsString(), default_arg,
template_template_parameter->isParameterPack());

View File

@@ -54,10 +54,10 @@ TEST_CASE("t00056", "[test-case][class]")
REQUIRE_THAT(
src, IsConceptRequirement(_A("iterable<T>"), "container.end()"));
#ifdef _MSC_VER
#if (LLVM_VERSION_MAJOR == 13) || (LLVM_VERSION_MAJOR == 14)
REQUIRE_THAT(src,
IsConceptRequirement(
_A("convertible_to_string<T>"), "std::string{s}"));
_A("convertible_to_string<T>"), "std::string({s})"));
#else
REQUIRE_THAT(src,
IsConceptRequirement(
@@ -161,10 +161,10 @@ TEST_CASE("t00056", "[test-case][class]")
REQUIRE_THAT(
src, IsConceptRequirement(_A("iterable<T>"), "container.end()"));
#ifdef _MSC_VER
#if (LLVM_VERSION_MAJOR == 13) || (LLVM_VERSION_MAJOR == 14)
REQUIRE_THAT(src,
IsConceptRequirement(
_A("convertible_to_string<T>"), "std::string{s}"));
_A("convertible_to_string<T>"), "std::string({s})"));
#else
REQUIRE_THAT(src,
IsConceptRequirement(

16
util/test_llvm_versions.sh Executable file
View File

@@ -0,0 +1,16 @@
#!/bin/bash
declare -a llvm_configs=("llvm-config-12"
"llvm-config-13"
"llvm-config-14"
"llvm-config-15"
"llvm-config-16"
"llvm-config-17")
for config_path in ${llvm_configs[@]}; do
echo "---------------------------------------------------------"
echo " Running clang-uml tests against LLVM $(${config_path} --version)"
echo "---------------------------------------------------------"
make clean
LLVM_CONFIG_PATH=$config_path NUMPROC=12 make test
done