Skip to content

GetMissingDictionaries #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions core/meta/inc/TClass.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@
#ifndef ROOT_TObjString
#include "TObjString.h"
#endif

#include <map>
#include <string>
#include <set>

class TBaseClass;
class TBrowser;
Expand Down Expand Up @@ -308,6 +310,8 @@ friend class ROOT::TGenericClassInfo;
TVirtualStreamerInfo *GetStreamerInfo(Int_t version=0) const;
TVirtualStreamerInfo *GetStreamerInfoAbstractEmulated(Int_t version=0) const;
const type_info *GetTypeInfo() const { return fTypeInfo; };
Bool_t HasDictionary() const;
void GetMissingDictionaries(bool recurse, TObjArray& result);
void IgnoreTObjectStreamer(Bool_t ignore=kTRUE);
Bool_t InheritsFrom(const char *cl) const;
Bool_t InheritsFrom(const TClass *cl) const;
Expand Down
4 changes: 4 additions & 0 deletions core/meta/inc/TInterpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#include "TDictionary.h"
#endif

#include <set>

class TClass;
class TEnv;
class TFunction;
Expand Down Expand Up @@ -73,6 +75,8 @@ class TInterpreter : public TNamed {
virtual const char *GetIncludePath() = 0;
virtual const char *GetSTLIncludePath() const { return ""; }
virtual TObjArray *GetRootMapFiles() const = 0;
virtual Bool_t HasDictionary(TClass* cl) const = 0;
virtual void GetMissingDictionaries(TClass* cl, bool recurse, TObjArray& result) = 0;
virtual void Initialize() = 0;
virtual void InspectMembers(TMemberInspector&, void* obj, const TClass* cl) = 0;
virtual Bool_t IsLoaded(const char *filename) const = 0;
Expand Down
14 changes: 14 additions & 0 deletions core/meta/src/TClass.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3159,6 +3159,20 @@ void TClass::GetMenuItems(TList *list)
}
}

Bool_t TClass::HasDictionary() const
{
// Check whether a class has a dictionary or not.

return gInterpreter->HasDictionary(this);
}

void TClass::GetMissingDictionaries(bool recurse, TObjArray& result)
{
// Get the classes that have a missing dictionary.

gInterpreter->GetMissingDictionaries(this, recurse, result);
}

//______________________________________________________________________________
Bool_t TClass::IsFolder(void *obj) const
{
Expand Down
156 changes: 156 additions & 0 deletions core/meta/src/TCling.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2753,6 +2753,162 @@ const char* TCling::GetInterpreterTypeName(const char* name, Bool_t full)
return result.c_str();
}

//______________________________________________________________________________
Bool_t TCling::HasDictionary(TClass* cl) const
{
// Check whether a class has a dictionary or not.

// Get the Decl for the class.
TClingClassInfo* cli = (TClingClassInfo*)cl->GetClassInfo();
const clang::Decl* D = cli->GetDecl();

// Convert to RecordDecl.
if (const clang::RecordDecl* RD = llvm::dyn_cast<clang::RecordDecl>(D)) {

// Get the name of the class
std::string buf;
if (const NamedDecl* ND = llvm::dyn_cast<NamedDecl>(RD)) {
PrintingPolicy Policy(ND->getASTContext().getPrintingPolicy());
llvm::raw_string_ostream stream(buf);
ND->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
}
const char* name = buf.c_str();

// Check for the dictionary of the curent class.
if (gClassTable->GetDict(name))
return true;
}
return false;
}

//______________________________________________________________________________
namespace {
void GetMissingDictionariesForDataMembers(const clang::Decl* D, std::set<const clang::Decl*> &netD, bool recurse);
void GetMissingDictionariesForDecl(const clang::Decl* D, std::set<const clang::Decl*> &netD, bool recurse)
{
// Get the data members that do not have a dictionary for a Decl.

// Get the name of the class
std::string buf;
if (const NamedDecl* ND = llvm::dyn_cast<NamedDecl>(D)) {
PrintingPolicy Policy(ND->getASTContext().getPrintingPolicy());
llvm::raw_string_ostream stream(buf);
ND->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
}
const char* name = buf.c_str();

// Check for the dictionary of the curent class.
if (!gClassTable->GetDict(name)){
std::set<const clang::Decl*>::iterator it = netD.find(D);
if (it != netD.end()) return ;
netD.insert(D);
}
if (recurse) {
GetMissingDictionariesForDataMembers(D, netD, recurse);
}
return ;
}

void GetMissingDictionariesForDataMembers(const clang::Decl* D, std::set<const clang::Decl*> &netD, bool recurse) {

if (const clang::CXXRecordDecl* RD = llvm::dyn_cast<clang::CXXRecordDecl>(D)) {
// Recurse for the data members.
for (clang::RecordDecl::field_iterator iField = RD->field_begin(),
eField = RD->field_end(); iField != eField; ++iField) {

clang::QualType qualType = (*iField)->getType();
if (!qualType.isNull()) {

//Repetion of code will be fixed with next commit.
//class
if (qualType->isRecordType()) {
if(clang::CXXRecordDecl* FD = qualType->getAsCXXRecordDecl()) {
GetMissingDictionariesForDecl(FD, netD, recurse);
}
}
//pointer to class or to array or reference
if (qualType->isPointerType() || qualType->isReferenceType()) {
QualType pointeeType = qualType->getPointeeType();
if (pointeeType->isRecordType()) {
if(clang::CXXRecordDecl* FD = pointeeType->getAsCXXRecordDecl()) {
GetMissingDictionariesForDecl(FD, netD, recurse);
}
}
else if(pointeeType->isArrayType()) {
const Type* elementType = pointeeType->getArrayElementTypeNoTypeQual();
if (elementType->isRecordType()) {
if(clang::CXXRecordDecl* FD = elementType->getAsCXXRecordDecl()) {
GetMissingDictionariesForDecl(FD, netD, recurse);
}
}
}
}
//array of class elements
if (qualType->isArrayType()) {
const Type* elementType = qualType->getArrayElementTypeNoTypeQual();
if (elementType->isRecordType()) {
clang::CXXRecordDecl* FD = elementType->getAsCXXRecordDecl();
GetMissingDictionariesForDecl(FD, netD, recurse);
}
}
}
}
}
}
}
//______________________________________________________________________________
void TCling::GetMissingDictionaries(TClass* cl, bool recurse /*recurse*/, TObjArray& result)
{
// Get the Tclass-s that do not have a dictionary.

// Get the Decl for the class.
TClingClassInfo* cli = (TClingClassInfo*)cl->GetClassInfo();
const clang::Decl* D = cli->GetDecl();

// Get the Decls recursively for all data members of TClass cl

std::set<const clang::Decl*> netD;
// Convert to RecordDecl.
if (const clang::RecordDecl* RD = llvm::dyn_cast<clang::RecordDecl>(D)) {

// Get the name of the class
std::string buf;
if (const NamedDecl* ND = llvm::dyn_cast<NamedDecl>(D)) {
PrintingPolicy Policy(ND->getASTContext().getPrintingPolicy());
llvm::raw_string_ostream stream(buf);
ND->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
}
const char* name = buf.c_str();

// Check for the dictionary of the curent class.
if (!gClassTable->GetDict(name)){
std::set<const clang::Decl*>::iterator it = netD.find(D);
if (it == netD.end())
netD.insert(D);
}

GetMissingDictionariesForDataMembers(D, netD, recurse);
}

//convert set<Decl> to TObjArray
for (std::set<const clang::Decl*>::const_iterator I = netD.begin(),
E = netD.end(); I != E; ++I) {
// Get name of the class.
std::string buf;
if (const NamedDecl* ND = llvm::dyn_cast<NamedDecl>(*I)) {
PrintingPolicy Policy(ND->getASTContext().getPrintingPolicy());
llvm::raw_string_ostream stream(buf);
ND->getNameForDiagnostic(stream, Policy, /*Qualified=*/true);
}
const char* name = buf.c_str();
if (TClass* clMissingDict = TClass::GetClass(name)) {
result.Add(clMissingDict);
} else {
Error("TCling::GetMissingDictionaries", "The class %s missing dictionary was not found.", name);
}
}
}

//______________________________________________________________________________
void TCling::Execute(const char* function, const char* params, int* error)
{
Expand Down
2 changes: 2 additions & 0 deletions core/meta/src/TCling.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ class TCling : public TInterpreter {
const char* GetIncludePath();
virtual const char* GetSTLIncludePath() const;
TObjArray* GetRootMapFiles() const { return fRootmapFiles; }
Bool_t HasDictionary(TClass* cl) const;
void GetMissingDictionaries(TClass* cl, bool recurse, TObjArray& result);
virtual void Initialize();
void InspectMembers(TMemberInspector&, void* obj, const TClass* cl);
Bool_t IsLoaded(const char* filename) const;
Expand Down