Fixed building main
This commit is contained in:
@@ -204,7 +204,7 @@ void diagram::get_parents(
|
|||||||
bool found_new{false};
|
bool found_new{false};
|
||||||
for (const auto &parent : parents) {
|
for (const auto &parent : parents) {
|
||||||
for (const auto &pp : parent.get().parents()) {
|
for (const auto &pp : parent.get().parents()) {
|
||||||
const auto p = get_class(pp.name());
|
const auto p = get_class(pp.id());
|
||||||
if (p.has_value()) {
|
if (p.has_value()) {
|
||||||
auto [it, found] = parents.emplace(p.value());
|
auto [it, found] = parents.emplace(p.value());
|
||||||
if (found)
|
if (found)
|
||||||
|
|||||||
@@ -233,12 +233,17 @@ bool translation_unit_visitor::VisitClassTemplateSpecializationDecl(
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Skip forward declarations
|
// Skip forward declarations
|
||||||
if (!cls->isCompleteDefinition())
|
if (!cls->isCompleteDefinition()) {
|
||||||
|
// Register this forward declaration in case there is no complete
|
||||||
|
// definition (see t00036)
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
|
||||||
// Check if the class was already processed within VisitClassTemplateDecl()
|
// Check if the class was already processed within
|
||||||
if (diagram_.has_element(cls->getID()))
|
// VisitClassTemplateDecl()
|
||||||
return true;
|
if (diagram_.has_element(cls->getID()))
|
||||||
|
return true;
|
||||||
|
|
||||||
// TODO: Add support for classes defined in function/method bodies
|
// TODO: Add support for classes defined in function/method bodies
|
||||||
if (cls->isLocalClass())
|
if (cls->isLocalClass())
|
||||||
@@ -253,6 +258,9 @@ bool translation_unit_visitor::VisitClassTemplateSpecializationDecl(
|
|||||||
|
|
||||||
process_template_specialization_children(cls, template_specialization);
|
process_template_specialization_children(cls, template_specialization);
|
||||||
|
|
||||||
|
// Process template specialization bases
|
||||||
|
process_class_bases(cls, template_specialization);
|
||||||
|
|
||||||
template_specialization.add_relationship({relationship_t::kInstantiation,
|
template_specialization.add_relationship({relationship_t::kInstantiation,
|
||||||
cls->getSpecializedTemplate()->getID()});
|
cls->getSpecializedTemplate()->getID()});
|
||||||
|
|
||||||
@@ -269,6 +277,10 @@ bool translation_unit_visitor::VisitClassTemplateDecl(
|
|||||||
if (source_manager_.isInSystemHeader(cls->getSourceRange().getBegin()))
|
if (source_manager_.isInSystemHeader(cls->getSourceRange().getBegin()))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// Skip forward declarations
|
||||||
|
if (!cls->getTemplatedDecl()->isCompleteDefinition())
|
||||||
|
return true;
|
||||||
|
|
||||||
auto c_ptr = process_class_declaration(cls->getTemplatedDecl());
|
auto c_ptr = process_class_declaration(cls->getTemplatedDecl());
|
||||||
|
|
||||||
if (!c_ptr)
|
if (!c_ptr)
|
||||||
@@ -278,8 +290,17 @@ bool translation_unit_visitor::VisitClassTemplateDecl(
|
|||||||
// underlying templated class id
|
// underlying templated class id
|
||||||
c_ptr->set_id(cls->getID());
|
c_ptr->set_id(cls->getID());
|
||||||
|
|
||||||
|
auto id = c_ptr->id();
|
||||||
|
|
||||||
process_template_parameters(*cls, *c_ptr);
|
process_template_parameters(*cls, *c_ptr);
|
||||||
|
|
||||||
|
if(!cls->getTemplatedDecl()->isCompleteDefinition()) {
|
||||||
|
forward_declarations_.emplace(id, std::move(c_ptr));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
forward_declarations_.erase(id);
|
||||||
|
|
||||||
if (diagram_.should_include(*c_ptr)) {
|
if (diagram_.should_include(*c_ptr)) {
|
||||||
LOG_DBG("Adding class {} with id {}", c_ptr->full_name(), c_ptr->id());
|
LOG_DBG("Adding class {} with id {}", c_ptr->full_name(), c_ptr->id());
|
||||||
diagram_.add_class(std::move(c_ptr));
|
diagram_.add_class(std::move(c_ptr));
|
||||||
@@ -298,10 +319,6 @@ bool translation_unit_visitor::VisitCXXRecordDecl(clang::CXXRecordDecl *cls)
|
|||||||
if (cls->isTemplated() || cls->isTemplateDecl())
|
if (cls->isTemplated() || cls->isTemplateDecl())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Skip forward declarations
|
|
||||||
if (!cls->isCompleteDefinition())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// Check if the class was already processed within VisitClassTemplateDecl()
|
// Check if the class was already processed within VisitClassTemplateDecl()
|
||||||
if (diagram_.has_element(cls->getID()))
|
if (diagram_.has_element(cls->getID()))
|
||||||
return true;
|
return true;
|
||||||
@@ -315,6 +332,14 @@ bool translation_unit_visitor::VisitCXXRecordDecl(clang::CXXRecordDecl *cls)
|
|||||||
if (!c_ptr)
|
if (!c_ptr)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
auto id = c_ptr->id();
|
||||||
|
if(!cls->isCompleteDefinition()) {
|
||||||
|
forward_declarations_.emplace(id, std::move(c_ptr));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
forward_declarations_.erase(id);
|
||||||
|
|
||||||
if (diagram_.should_include(*c_ptr)) {
|
if (diagram_.should_include(*c_ptr)) {
|
||||||
diagram_.add_class(std::move(c_ptr));
|
diagram_.add_class(std::move(c_ptr));
|
||||||
}
|
}
|
||||||
@@ -349,6 +374,9 @@ std::unique_ptr<class_> translation_unit_visitor::process_class_declaration(
|
|||||||
|
|
||||||
c.set_style(c.style_spec());
|
c.set_style(c.style_spec());
|
||||||
|
|
||||||
|
if (!cls->isCompleteDefinition())
|
||||||
|
return c_ptr;
|
||||||
|
|
||||||
// Process class child entities
|
// Process class child entities
|
||||||
process_class_children(cls, c);
|
process_class_children(cls, c);
|
||||||
|
|
||||||
@@ -597,7 +625,8 @@ void translation_unit_visitor::process_class_children(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const auto *friend_declaration : cls->friends()) {
|
for (const auto *friend_declaration : cls->friends()) {
|
||||||
process_friend(*friend_declaration, c);
|
if (friend_declaration != nullptr)
|
||||||
|
process_friend(*friend_declaration, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -947,7 +976,6 @@ translation_unit_visitor::process_template_specialization(
|
|||||||
// If this is a nested template type - add nested templates as
|
// If this is a nested template type - add nested templates as
|
||||||
// template arguments
|
// template arguments
|
||||||
if (arg.getAsType()->getAs<clang::TemplateSpecializationType>()) {
|
if (arg.getAsType()->getAs<clang::TemplateSpecializationType>()) {
|
||||||
|
|
||||||
const auto *nested_template_type =
|
const auto *nested_template_type =
|
||||||
arg.getAsType()->getAs<clang::TemplateSpecializationType>();
|
arg.getAsType()->getAs<clang::TemplateSpecializationType>();
|
||||||
|
|
||||||
@@ -973,8 +1001,17 @@ translation_unit_visitor::process_template_specialization(
|
|||||||
argument.to_string(config().using_namespace(), false));
|
argument.to_string(config().using_namespace(), false));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
argument.set_name(
|
auto type_name =
|
||||||
to_string(arg.getAsType(), cls->getASTContext()));
|
to_string(arg.getAsType(), cls->getASTContext());
|
||||||
|
// Sometimes template instantiation is reported as RecordType in
|
||||||
|
// the AST and getAs to TemplateSpecializationType returns null
|
||||||
|
// pointer so we have to at least make sure it's properly
|
||||||
|
// formatted
|
||||||
|
// TODO: Change this to manual parsing of the template
|
||||||
|
// instantiation
|
||||||
|
if (type_name.find('<') != std::string::npos)
|
||||||
|
util::replace_all(type_name, ", ", ",");
|
||||||
|
argument.set_name(type_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
template_instantiation.add_template(std::move(argument));
|
template_instantiation.add_template(std::move(argument));
|
||||||
@@ -1210,6 +1247,19 @@ void translation_unit_visitor::set_source_location(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void translation_unit_visitor::add_incomplete_forward_declarations() {
|
||||||
|
for(auto & [id, c] : forward_declarations_) {
|
||||||
|
if(diagram().should_include(c->full_name(false))) {
|
||||||
|
diagram().add_class(std::move(c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
forward_declarations_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void translation_unit_visitor::finalize() {
|
||||||
|
add_incomplete_forward_declarations();
|
||||||
|
}
|
||||||
|
|
||||||
bool translation_unit_visitor::simplify_system_template(
|
bool translation_unit_visitor::simplify_system_template(
|
||||||
template_parameter &ct, const std::string &full_name)
|
template_parameter &ct, const std::string &full_name)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ public:
|
|||||||
|
|
||||||
// void operator()();
|
// void operator()();
|
||||||
|
|
||||||
|
void finalize();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<clanguml::class_diagram::model::class_>
|
std::unique_ptr<clanguml::class_diagram::model::class_>
|
||||||
process_class_declaration(clang::CXXRecordDecl *cls);
|
process_class_declaration(clang::CXXRecordDecl *cls);
|
||||||
@@ -143,6 +145,8 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void add_incomplete_forward_declarations();
|
||||||
|
|
||||||
bool simplify_system_template(
|
bool simplify_system_template(
|
||||||
model::template_parameter &ct, const std::string &full_name);
|
model::template_parameter &ct, const std::string &full_name);
|
||||||
|
|
||||||
@@ -153,5 +157,9 @@ private:
|
|||||||
|
|
||||||
// Reference to class diagram config
|
// Reference to class diagram config
|
||||||
const clanguml::config::class_diagram &config_;
|
const clanguml::config::class_diagram &config_;
|
||||||
|
|
||||||
|
std::map<common::model::diagram_element::id_t,
|
||||||
|
std::unique_ptr<clanguml::class_diagram::model::class_>>
|
||||||
|
forward_declarations_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -260,6 +260,7 @@ public:
|
|||||||
// const auto* tud = ast_context.getTranslationUnitDecl();
|
// const auto* tud = ast_context.getTranslationUnitDecl();
|
||||||
//// tud->dump();
|
//// tud->dump();
|
||||||
visitor_.TraverseDecl(ast_context.getTranslationUnitDecl());
|
visitor_.TraverseDecl(ast_context.getTranslationUnitDecl());
|
||||||
|
visitor_.finalize();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -273,6 +274,7 @@ public:
|
|||||||
, config_{config}
|
, config_{config}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(
|
virtual std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(
|
||||||
clang::CompilerInstance &CI, clang::StringRef file)
|
clang::CompilerInstance &CI, clang::StringRef file)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -237,7 +237,8 @@ tvl::value_t subclass_filter::match(const diagram &d, const element &e) const
|
|||||||
// filter config
|
// filter config
|
||||||
for (const auto &root : roots_) {
|
for (const auto &root : roots_) {
|
||||||
for (const auto &parent : parents) {
|
for (const auto &parent : parents) {
|
||||||
if (root == parent.get().full_name(false))
|
auto full_name = parent.get().full_name(false);
|
||||||
|
if (root == full_name)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ public:
|
|||||||
|
|
||||||
void operator()(const cppast::cpp_entity &file);
|
void operator()(const cppast::cpp_entity &file);
|
||||||
|
|
||||||
|
void finalize() {}
|
||||||
private:
|
private:
|
||||||
clang::SourceManager &source_manager_;
|
clang::SourceManager &source_manager_;
|
||||||
|
|
||||||
|
|||||||
18
src/main.cc
18
src/main.cc
@@ -46,7 +46,7 @@ bool check_output_directory(const std::string &dir);
|
|||||||
|
|
||||||
void generate_diagram(const std::string &od, const std::string &name,
|
void generate_diagram(const std::string &od, const std::string &name,
|
||||||
std::shared_ptr<clanguml::config::diagram> diagram,
|
std::shared_ptr<clanguml::config::diagram> diagram,
|
||||||
const cppast::libclang_compilation_database &db, bool verbose);
|
const clang::tooling::CompilationDatabase &db, bool verbose);
|
||||||
|
|
||||||
int main(int argc, const char *argv[])
|
int main(int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
@@ -104,7 +104,17 @@ int main(int argc, const char *argv[])
|
|||||||
LOG_INFO("Loading compilation database from {} directory",
|
LOG_INFO("Loading compilation database from {} directory",
|
||||||
config.compilation_database_dir());
|
config.compilation_database_dir());
|
||||||
|
|
||||||
cppast::libclang_compilation_database db{config.compilation_database_dir()};
|
std::string err{};
|
||||||
|
|
||||||
|
auto db =
|
||||||
|
clang::tooling::CompilationDatabase::autoDetectFromDirectory(
|
||||||
|
config.compilation_database_dir(), err);
|
||||||
|
|
||||||
|
if (!err.empty()) {
|
||||||
|
LOG_ERROR("Failed to load compilation database from {}",
|
||||||
|
config.compilation_database_dir());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
auto od = config.output_directory();
|
auto od = config.output_directory();
|
||||||
if (output_directory)
|
if (output_directory)
|
||||||
@@ -124,7 +134,7 @@ int main(int argc, const char *argv[])
|
|||||||
|
|
||||||
futs.emplace_back(generator_executor.add(
|
futs.emplace_back(generator_executor.add(
|
||||||
[&od, &name = name, &diagram = diagram, &db = db, verbose]() {
|
[&od, &name = name, &diagram = diagram, &db = db, verbose]() {
|
||||||
generate_diagram(od, name, diagram, db, verbose);
|
generate_diagram(od, name, diagram, *db, verbose);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,7 +147,7 @@ int main(int argc, const char *argv[])
|
|||||||
|
|
||||||
void generate_diagram(const std::string &od, const std::string &name,
|
void generate_diagram(const std::string &od, const std::string &name,
|
||||||
std::shared_ptr<clanguml::config::diagram> diagram,
|
std::shared_ptr<clanguml::config::diagram> diagram,
|
||||||
const cppast::libclang_compilation_database &db, bool verbose)
|
const clang::tooling::CompilationDatabase &db, bool verbose)
|
||||||
{
|
{
|
||||||
using clanguml::common::model::diagram_t;
|
using clanguml::common::model::diagram_t;
|
||||||
using clanguml::config::class_diagram;
|
using clanguml::config::class_diagram;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public:
|
|||||||
clanguml::package_diagram::model::diagram &diagram,
|
clanguml::package_diagram::model::diagram &diagram,
|
||||||
const clanguml::config::package_diagram &config);
|
const clanguml::config::package_diagram &config);
|
||||||
|
|
||||||
|
void finalize() {}
|
||||||
private:
|
private:
|
||||||
clang::SourceManager &source_manager_;
|
clang::SourceManager &source_manager_;
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ public:
|
|||||||
clanguml::sequence_diagram::model::diagram &diagram,
|
clanguml::sequence_diagram::model::diagram &diagram,
|
||||||
const clanguml::config::sequence_diagram &config);
|
const clanguml::config::sequence_diagram &config);
|
||||||
|
|
||||||
|
void finalize() {}
|
||||||
private:
|
private:
|
||||||
clang::SourceManager &source_manager_;
|
clang::SourceManager &source_manager_;
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ struct key_t {
|
|||||||
std::string key;
|
std::string key;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T> struct map;
|
template <typename T> struct map {};
|
||||||
|
|
||||||
using namespace thirdparty::ns1;
|
using namespace thirdparty::ns1;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user