Fixed building main

This commit is contained in:
Bartek Kryza
2022-07-24 23:46:52 +02:00
parent 1cf271fedf
commit 3e4beef80b
10 changed files with 93 additions and 20 deletions

View File

@@ -204,7 +204,7 @@ void diagram::get_parents(
bool found_new{false};
for (const auto &parent : 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()) {
auto [it, found] = parents.emplace(p.value());
if (found)

View File

@@ -233,12 +233,17 @@ bool translation_unit_visitor::VisitClassTemplateSpecializationDecl(
return true;
// Skip forward declarations
if (!cls->isCompleteDefinition())
if (!cls->isCompleteDefinition()) {
// Register this forward declaration in case there is no complete
// definition (see t00036)
return true;
}
else
// Check if the class was already processed within VisitClassTemplateDecl()
if (diagram_.has_element(cls->getID()))
return true;
// Check if the class was already processed within
// VisitClassTemplateDecl()
if (diagram_.has_element(cls->getID()))
return true;
// TODO: Add support for classes defined in function/method bodies
if (cls->isLocalClass())
@@ -253,6 +258,9 @@ bool translation_unit_visitor::VisitClassTemplateSpecializationDecl(
process_template_specialization_children(cls, template_specialization);
// Process template specialization bases
process_class_bases(cls, template_specialization);
template_specialization.add_relationship({relationship_t::kInstantiation,
cls->getSpecializedTemplate()->getID()});
@@ -269,6 +277,10 @@ bool translation_unit_visitor::VisitClassTemplateDecl(
if (source_manager_.isInSystemHeader(cls->getSourceRange().getBegin()))
return true;
// Skip forward declarations
if (!cls->getTemplatedDecl()->isCompleteDefinition())
return true;
auto c_ptr = process_class_declaration(cls->getTemplatedDecl());
if (!c_ptr)
@@ -278,8 +290,17 @@ bool translation_unit_visitor::VisitClassTemplateDecl(
// underlying templated class id
c_ptr->set_id(cls->getID());
auto id = c_ptr->id();
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)) {
LOG_DBG("Adding class {} with id {}", c_ptr->full_name(), c_ptr->id());
diagram_.add_class(std::move(c_ptr));
@@ -298,10 +319,6 @@ bool translation_unit_visitor::VisitCXXRecordDecl(clang::CXXRecordDecl *cls)
if (cls->isTemplated() || cls->isTemplateDecl())
return true;
// Skip forward declarations
if (!cls->isCompleteDefinition())
return true;
// Check if the class was already processed within VisitClassTemplateDecl()
if (diagram_.has_element(cls->getID()))
return true;
@@ -315,6 +332,14 @@ bool translation_unit_visitor::VisitCXXRecordDecl(clang::CXXRecordDecl *cls)
if (!c_ptr)
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)) {
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());
if (!cls->isCompleteDefinition())
return c_ptr;
// Process class child entities
process_class_children(cls, c);
@@ -597,7 +625,8 @@ void translation_unit_visitor::process_class_children(
}
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
// template arguments
if (arg.getAsType()->getAs<clang::TemplateSpecializationType>()) {
const auto *nested_template_type =
arg.getAsType()->getAs<clang::TemplateSpecializationType>();
@@ -973,8 +1001,17 @@ translation_unit_visitor::process_template_specialization(
argument.to_string(config().using_namespace(), false));
}
else {
argument.set_name(
to_string(arg.getAsType(), cls->getASTContext()));
auto type_name =
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));
@@ -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(
template_parameter &ct, const std::string &full_name)
{

View File

@@ -63,6 +63,8 @@ public:
// void operator()();
void finalize();
private:
std::unique_ptr<clanguml::class_diagram::model::class_>
process_class_declaration(clang::CXXRecordDecl *cls);
@@ -143,6 +145,8 @@ private:
}
}
void add_incomplete_forward_declarations();
bool simplify_system_template(
model::template_parameter &ct, const std::string &full_name);
@@ -153,5 +157,9 @@ private:
// Reference to 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_;
};
}

View File

@@ -260,6 +260,7 @@ public:
// const auto* tud = ast_context.getTranslationUnitDecl();
//// tud->dump();
visitor_.TraverseDecl(ast_context.getTranslationUnitDecl());
visitor_.finalize();
}
};
@@ -273,6 +274,7 @@ public:
, config_{config}
{
}
virtual std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(
clang::CompilerInstance &CI, clang::StringRef file)
{

View File

@@ -237,7 +237,8 @@ tvl::value_t subclass_filter::match(const diagram &d, const element &e) const
// filter config
for (const auto &root : roots_) {
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;
}
}

View File

@@ -42,6 +42,7 @@ public:
void operator()(const cppast::cpp_entity &file);
void finalize() {}
private:
clang::SourceManager &source_manager_;

View File

@@ -46,7 +46,7 @@ bool check_output_directory(const std::string &dir);
void generate_diagram(const std::string &od, const std::string &name,
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[])
{
@@ -104,7 +104,17 @@ int main(int argc, const char *argv[])
LOG_INFO("Loading compilation database from {} directory",
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();
if (output_directory)
@@ -124,7 +134,7 @@ int main(int argc, const char *argv[])
futs.emplace_back(generator_executor.add(
[&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,
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::config::class_diagram;

View File

@@ -40,7 +40,7 @@ public:
clanguml::package_diagram::model::diagram &diagram,
const clanguml::config::package_diagram &config);
void finalize() {}
private:
clang::SourceManager &source_manager_;

View File

@@ -33,6 +33,7 @@ public:
clanguml::sequence_diagram::model::diagram &diagram,
const clanguml::config::sequence_diagram &config);
void finalize() {}
private:
clang::SourceManager &source_manager_;