mirror of
https://github.com/bkryza/clang-uml.git
synced 2025-05-17 03:05:20 +08:00
Fixed building with LLVM 18 (#251)
This commit is contained in:
parent
97b094f77e
commit
06ada3af55
@ -1,5 +1,7 @@
|
|||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
|
* Fixed building with LLVM 18 (#251)
|
||||||
|
|
||||||
### 0.5.1
|
### 0.5.1
|
||||||
|
|
||||||
* Fixed elements filter in sequence diagrams (#248)
|
* Fixed elements filter in sequence diagrams (#248)
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
[](https://github.com/bkryza/clang-uml/actions)
|
[](https://github.com/bkryza/clang-uml/actions)
|
||||||
[](https://codecov.io/gh/bkryza/clang-uml)
|
[](https://codecov.io/gh/bkryza/clang-uml)
|
||||||
[](https://github.com/bkryza/clang-uml/releases)
|
[](https://github.com/bkryza/clang-uml/releases)
|
||||||
[](https://github.com/bkryza/clang-uml/releases)
|
[](https://github.com/bkryza/clang-uml/releases)
|
||||||
[](https://clang-uml.github.io)
|
[](https://clang-uml.github.io)
|
||||||
|
|
||||||
`clang-uml` is an automatic C++ to UML class, sequence, package and include diagram generator, driven by
|
`clang-uml` is an automatic C++ to UML class, sequence, package and include diagram generator, driven by
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
message(STATUS "Checking for LLVM and Clang...")
|
message(STATUS "Checking for LLVM and Clang...")
|
||||||
|
|
||||||
|
if(LLVM_VERSION STREQUAL "18")
|
||||||
|
set(LLVM_VERSION "18.1")
|
||||||
|
endif()
|
||||||
|
|
||||||
# If user provided a path to llvm-config executable use it to detect
|
# If user provided a path to llvm-config executable use it to detect
|
||||||
# LLVM Version and appropriate CMake module path
|
# LLVM Version and appropriate CMake module path
|
||||||
if(NOT "${LLVM_CONFIG_PATH}" STREQUAL "")
|
if(NOT "${LLVM_CONFIG_PATH}" STREQUAL "")
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
* [Diagram generation is very slow](#diagram-generation-is-very-slow)
|
* [Diagram generation is very slow](#diagram-generation-is-very-slow)
|
||||||
* [Diagram generated with PlantUML is cropped](#diagram-generated-with-plantuml-is-cropped)
|
* [Diagram generated with PlantUML is cropped](#diagram-generated-with-plantuml-is-cropped)
|
||||||
* [Clang produces several warnings during diagram generation](#clang-produces-several-warnings-during-diagram-generation)
|
* [Clang produces several warnings during diagram generation](#clang-produces-several-warnings-during-diagram-generation)
|
||||||
|
* [Errors with C++20 modules and LLVM 18](#errors-with-c20-modules-and-llvm-18)
|
||||||
* [Cannot generate diagrams from header-only projects](#cannot-generate-diagrams-from-header-only-projects)
|
* [Cannot generate diagrams from header-only projects](#cannot-generate-diagrams-from-header-only-projects)
|
||||||
* [YAML anchors and aliases are not fully supported](#yaml-anchors-and-aliases-are-not-fully-supported)
|
* [YAML anchors and aliases are not fully supported](#yaml-anchors-and-aliases-are-not-fully-supported)
|
||||||
* [Schema validation error is thrown, but the configuration file is correct](#schema-validation-error-is-thrown-but-the-configuration-file-is-correct)
|
* [Schema validation error is thrown, but the configuration file is correct](#schema-validation-error-is-thrown-but-the-configuration-file-is-correct)
|
||||||
@ -143,6 +144,21 @@ remove_compile_flags:
|
|||||||
- -Wshadow
|
- -Wshadow
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Errors with C++20 modules and LLVM 18
|
||||||
|
|
||||||
|
When running `clang-uml` on code using C++20 modules, the LLVM version used to
|
||||||
|
build the project must be compatible with the LLVM version linked to
|
||||||
|
`clang-uml`, otherwise you'll get error like this:
|
||||||
|
```
|
||||||
|
fatal error: malformed or corrupted AST file: 'malformed block record in AST file'
|
||||||
|
```
|
||||||
|
or like this:
|
||||||
|
```
|
||||||
|
error: PCH file uses an older PCH format that is no longer supported
|
||||||
|
```
|
||||||
|
|
||||||
|
In particular versions 17 and 18 of LLVM are not compatible in this regard.
|
||||||
|
|
||||||
### Cannot generate diagrams from header-only projects
|
### Cannot generate diagrams from header-only projects
|
||||||
|
|
||||||
Currently, in order to generate UML diagrams using `clang-uml` it is necessary
|
Currently, in order to generate UML diagrams using `clang-uml` it is necessary
|
||||||
|
@ -1280,7 +1280,11 @@ void translation_unit_visitor::process_method_properties(
|
|||||||
const bool is_constructor = c.name() == method_name;
|
const bool is_constructor = c.name() == method_name;
|
||||||
const bool is_destructor = fmt::format("~{}", c.name()) == method_name;
|
const bool is_destructor = fmt::format("~{}", c.name()) == method_name;
|
||||||
|
|
||||||
|
#if LLVM_VERSION_MAJOR > 17
|
||||||
|
method.is_pure_virtual(mf.isPureVirtual());
|
||||||
|
#else
|
||||||
method.is_pure_virtual(mf.isPure());
|
method.is_pure_virtual(mf.isPure());
|
||||||
|
#endif
|
||||||
method.is_virtual(mf.isVirtual());
|
method.is_virtual(mf.isVirtual());
|
||||||
method.is_const(mf.isConst());
|
method.is_const(mf.isConst());
|
||||||
method.is_defaulted(mf.isDefaulted());
|
method.is_defaulted(mf.isDefaulted());
|
||||||
|
@ -18,6 +18,14 @@
|
|||||||
|
|
||||||
#include "clang_visitor.h"
|
#include "clang_visitor.h"
|
||||||
|
|
||||||
|
#if LLVM_VERSION_MAJOR > 17
|
||||||
|
#define CLANG_UML_LLVM_COMMENT_KIND(COMMENT_KIND) \
|
||||||
|
clang::comments::CommentKind::COMMENT_KIND
|
||||||
|
#else
|
||||||
|
#define CLANG_UML_LLVM_COMMENT_KIND(COMMENT_KIND) \
|
||||||
|
clang::comments::Comment::COMMENT_KIND##Kind
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace clanguml::common::visitor::comment {
|
namespace clanguml::common::visitor::comment {
|
||||||
|
|
||||||
clang_visitor::clang_visitor(clang::SourceManager &source_manager)
|
clang_visitor::clang_visitor(clang::SourceManager &source_manager)
|
||||||
@ -45,7 +53,6 @@ void clang_visitor::visit(
|
|||||||
cmt["formatted"] = formatted_comment;
|
cmt["formatted"] = formatted_comment;
|
||||||
|
|
||||||
using clang::comments::BlockCommandComment;
|
using clang::comments::BlockCommandComment;
|
||||||
using clang::comments::Comment;
|
|
||||||
using clang::comments::FullComment;
|
using clang::comments::FullComment;
|
||||||
using clang::comments::ParagraphComment;
|
using clang::comments::ParagraphComment;
|
||||||
using clang::comments::ParamCommandComment;
|
using clang::comments::ParamCommandComment;
|
||||||
@ -59,7 +66,7 @@ void clang_visitor::visit(
|
|||||||
|
|
||||||
for (const auto *block : full_comment->getBlocks()) {
|
for (const auto *block : full_comment->getBlocks()) {
|
||||||
const auto block_kind = block->getCommentKind();
|
const auto block_kind = block->getCommentKind();
|
||||||
if (block_kind == Comment::ParagraphCommentKind) {
|
if (block_kind == CLANG_UML_LLVM_COMMENT_KIND(ParagraphComment)) {
|
||||||
std::string paragraph_text;
|
std::string paragraph_text;
|
||||||
|
|
||||||
visit_paragraph(clang::dyn_cast<ParagraphComment>(block), traits,
|
visit_paragraph(clang::dyn_cast<ParagraphComment>(block), traits,
|
||||||
@ -75,18 +82,21 @@ void clang_visitor::visit(
|
|||||||
|
|
||||||
cmt["paragraph"].push_back(paragraph_text);
|
cmt["paragraph"].push_back(paragraph_text);
|
||||||
}
|
}
|
||||||
else if (block_kind == Comment::TextCommentKind) {
|
else if (block_kind == CLANG_UML_LLVM_COMMENT_KIND(TextComment)) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
else if (block_kind == Comment::ParamCommandCommentKind) {
|
else if (block_kind ==
|
||||||
|
CLANG_UML_LLVM_COMMENT_KIND(ParamCommandComment)) {
|
||||||
visit_param_command(
|
visit_param_command(
|
||||||
clang::dyn_cast<ParamCommandComment>(block), traits, cmt);
|
clang::dyn_cast<ParamCommandComment>(block), traits, cmt);
|
||||||
}
|
}
|
||||||
else if (block_kind == Comment::TParamCommandCommentKind) {
|
else if (block_kind ==
|
||||||
|
CLANG_UML_LLVM_COMMENT_KIND(TParamCommandComment)) {
|
||||||
visit_tparam_command(
|
visit_tparam_command(
|
||||||
clang::dyn_cast<TParamCommandComment>(block), traits, cmt);
|
clang::dyn_cast<TParamCommandComment>(block), traits, cmt);
|
||||||
}
|
}
|
||||||
else if (block_kind == Comment::BlockCommandCommentKind) {
|
else if (block_kind ==
|
||||||
|
CLANG_UML_LLVM_COMMENT_KIND(BlockCommandComment)) {
|
||||||
if (const auto *command =
|
if (const auto *command =
|
||||||
clang::dyn_cast<BlockCommandComment>(block);
|
clang::dyn_cast<BlockCommandComment>(block);
|
||||||
command != nullptr) {
|
command != nullptr) {
|
||||||
@ -135,7 +145,7 @@ void clang_visitor::visit_block_command(
|
|||||||
paragraph_it != command->child_end(); ++paragraph_it) {
|
paragraph_it != command->child_end(); ++paragraph_it) {
|
||||||
|
|
||||||
if ((*paragraph_it)->getCommentKind() ==
|
if ((*paragraph_it)->getCommentKind() ==
|
||||||
Comment::ParagraphCommentKind) {
|
CLANG_UML_LLVM_COMMENT_KIND(ParagraphComment)) {
|
||||||
visit_paragraph(clang::dyn_cast<ParagraphComment>(*paragraph_it),
|
visit_paragraph(clang::dyn_cast<ParagraphComment>(*paragraph_it),
|
||||||
traits, command_text);
|
traits, command_text);
|
||||||
}
|
}
|
||||||
@ -168,7 +178,8 @@ void clang_visitor::visit_param_command(
|
|||||||
for (const auto *it = command->child_begin(); it != command->child_end();
|
for (const auto *it = command->child_begin(); it != command->child_end();
|
||||||
++it) {
|
++it) {
|
||||||
|
|
||||||
if ((*it)->getCommentKind() == Comment::ParagraphCommentKind) {
|
if ((*it)->getCommentKind() ==
|
||||||
|
CLANG_UML_LLVM_COMMENT_KIND(ParagraphComment)) {
|
||||||
visit_paragraph(
|
visit_paragraph(
|
||||||
clang::dyn_cast<ParagraphComment>(*it), traits, description);
|
clang::dyn_cast<ParagraphComment>(*it), traits, description);
|
||||||
}
|
}
|
||||||
@ -202,7 +213,8 @@ void clang_visitor::visit_tparam_command(
|
|||||||
|
|
||||||
for (const auto *it = command->child_begin(); it != command->child_end();
|
for (const auto *it = command->child_begin(); it != command->child_end();
|
||||||
++it) {
|
++it) {
|
||||||
if ((*it)->getCommentKind() == Comment::ParagraphCommentKind) {
|
if ((*it)->getCommentKind() ==
|
||||||
|
CLANG_UML_LLVM_COMMENT_KIND(ParagraphComment)) {
|
||||||
visit_paragraph(
|
visit_paragraph(
|
||||||
clang::dyn_cast<ParagraphComment>(*it), traits, description);
|
clang::dyn_cast<ParagraphComment>(*it), traits, description);
|
||||||
}
|
}
|
||||||
@ -232,7 +244,8 @@ void clang_visitor::visit_paragraph(
|
|||||||
for (const auto *text_it = paragraph->child_begin();
|
for (const auto *text_it = paragraph->child_begin();
|
||||||
text_it != paragraph->child_end(); ++text_it) {
|
text_it != paragraph->child_end(); ++text_it) {
|
||||||
|
|
||||||
if ((*text_it)->getCommentKind() == Comment::TextCommentKind &&
|
if ((*text_it)->getCommentKind() ==
|
||||||
|
CLANG_UML_LLVM_COMMENT_KIND(TextComment) &&
|
||||||
clang::dyn_cast<TextComment>(*text_it) != nullptr) {
|
clang::dyn_cast<TextComment>(*text_it) != nullptr) {
|
||||||
// Merge paragraph lines into a single string
|
// Merge paragraph lines into a single string
|
||||||
text += clang::dyn_cast<TextComment>(*text_it)->getText();
|
text += clang::dyn_cast<TextComment>(*text_it)->getText();
|
||||||
|
@ -217,6 +217,21 @@ public:
|
|||||||
template_parameter process_integral_argument(
|
template_parameter process_integral_argument(
|
||||||
const clang::TemplateArgument &arg);
|
const clang::TemplateArgument &arg);
|
||||||
|
|
||||||
|
#if LLVM_VERSION_MAJOR > 17
|
||||||
|
/**
|
||||||
|
* @brief Process `clang::TemplateArgument::StructuralValue`
|
||||||
|
*
|
||||||
|
* @note The template argument is a non-type template argument that can't be
|
||||||
|
* represented by the special-case Declaration, NullPtr, or Integral
|
||||||
|
* forms.
|
||||||
|
*
|
||||||
|
* @param arg Template argument
|
||||||
|
* @return Return template argument model
|
||||||
|
*/
|
||||||
|
template_parameter process_structural_argument(
|
||||||
|
const clang::TemplateArgument &arg);
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Process `clang::TemplateArgument::NullPtr`
|
* @brief Process `clang::TemplateArgument::NullPtr`
|
||||||
*
|
*
|
||||||
@ -1041,6 +1056,10 @@ void template_builder<VisitorT>::argument_process_dispatch(
|
|||||||
argument.push_back(a);
|
argument.push_back(a);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#if LLVM_VERSION_MAJOR > 17
|
||||||
|
case clang::TemplateArgument::StructuralValue:
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1213,6 +1232,21 @@ template_parameter template_builder<VisitorT>::process_integral_argument(
|
|||||||
return template_parameter::make_argument(result);
|
return template_parameter::make_argument(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LLVM_VERSION_MAJOR > 17
|
||||||
|
template <typename VisitorT>
|
||||||
|
template_parameter template_builder<VisitorT>::process_structural_argument(
|
||||||
|
const clang::TemplateArgument &arg)
|
||||||
|
{
|
||||||
|
assert(arg.getKind() == clang::TemplateArgument::StructuralValue);
|
||||||
|
|
||||||
|
std::string result;
|
||||||
|
llvm::raw_string_ostream ostream(result);
|
||||||
|
arg.dump(ostream);
|
||||||
|
|
||||||
|
return template_parameter::make_argument(result);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template <typename VisitorT>
|
template <typename VisitorT>
|
||||||
template_parameter template_builder<VisitorT>::process_null_argument(
|
template_parameter template_builder<VisitorT>::process_null_argument(
|
||||||
const clang::TemplateArgument &arg)
|
const clang::TemplateArgument &arg)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user