diff --git a/oi/type_graph/ClangTypeParser.cpp b/oi/type_graph/ClangTypeParser.cpp index 24d5835..5919ac2 100644 --- a/oi/type_graph/ClangTypeParser.cpp +++ b/oi/type_graph/ClangTypeParser.cpp @@ -17,8 +17,10 @@ #include #include +#include #include #include +#include #include #include #include @@ -196,7 +198,7 @@ Type& ClangTypeParser::enumerateClass(const clang::RecordType& ty) { ty, kind, std::move(name), std::move(fqName), size, virtuality); enumerateClassTemplateParams(ty, c.templateParams); - // enumerateClassParents(type, c.parents); + enumerateClassParents(ty, c.parents); enumerateClassMembers(ty, c.members); // enumerateClassFunctions(type, c.functions); @@ -275,6 +277,34 @@ std::optional ClangTypeParser::enumerateTemplateTemplateParam( } } +void ClangTypeParser::enumerateClassParents(const clang::RecordType& ty, + std::vector& parents) { + assert(parents.empty()); + + auto* decl = ty.getDecl(); + auto* cxxDecl = llvm::dyn_cast(decl); + if (cxxDecl == nullptr) + return; + + const auto& layout = decl->getASTContext().getASTRecordLayout(decl); + for (const auto& base : cxxDecl->bases()) { + auto baseType = base.getType(); + const auto* baseRecordType = llvm::dyn_cast(&*baseType); + if (baseRecordType == nullptr) + continue; + + auto* baseDecl = baseRecordType->getDecl(); + auto* baseCxxDecl = llvm::dyn_cast(baseDecl); + if (baseCxxDecl == nullptr) + continue; + + auto offset = layout.getBaseClassOffset(baseCxxDecl).getQuantity(); + auto& ptype = enumerateType(*baseType); + Parent p{ptype, static_cast(offset)}; + parents.push_back(p); + } +} + void ClangTypeParser::enumerateClassMembers(const clang::RecordType& ty, std::vector& members) { assert(members.empty()); diff --git a/oi/type_graph/ClangTypeParser.h b/oi/type_graph/ClangTypeParser.h index 9b27d64..98f0f67 100644 --- a/oi/type_graph/ClangTypeParser.h +++ b/oi/type_graph/ClangTypeParser.h @@ -50,6 +50,7 @@ class Array; class Class; class Enum; class Member; +struct Parent; class Primitive; class Reference; class Type; @@ -114,6 +115,7 @@ class ClangTypeParser { std::optional enumerateTemplateTemplateParam( const clang::TemplateName&); + void enumerateClassParents(const clang::RecordType&, std::vector&); void enumerateClassMembers(const clang::RecordType&, std::vector&); ContainerInfo* getContainerInfo(const std::string& fqName) const;