-
Notifications
You must be signed in to change notification settings - Fork 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
Has dictionary #22
Has dictionary #22
Changes from 5 commits
66561a4
d1a11fa
7ac3dff
52680c9
3c1eef0
d8fd166
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2753,6 +2753,122 @@ const char* TCling::GetInterpreterTypeName(const char* name, Bool_t full) | |
return result.c_str(); | ||
} | ||
|
||
//______________________________________________________________________________ | ||
namespace UNNAMED { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Once you have removed the declaration in TCling you should be able to remove the "UNNAMED" part of the line above. |
||
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) return ; | ||
} | ||
else return ; | ||
|
||
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()) { | ||
clang::CXXRecordDecl* FD = pointeeType->getAsCXXRecordDecl(); | ||
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); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
return ; | ||
} | ||
} | ||
//______________________________________________________________________________ | ||
std::set<TClass*> TCling::GetMissingDictionaries(TClass* cl, bool recurse /*recurse*/) | ||
{ | ||
// 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)) { | ||
UNNAMED::GetMissingDictionariesForDecl(RD, netD, recurse); | ||
} | ||
|
||
std::set<TClass*> classesMissingDict; | ||
|
||
//convert set<Decl> to set<TClass> | ||
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)) { | ||
classesMissingDict.insert(clMissingDict); | ||
} else { | ||
Error("TCling::GetMissingDictionaries", "The class %s missing dictionary was not found.", name); | ||
} | ||
} | ||
|
||
//return the classes the have missing dictionaries | ||
|
||
if (netD.empty()) { | ||
classesMissingDict.insert(0); | ||
} | ||
return classesMissingDict; | ||
} | ||
|
||
//______________________________________________________________________________ | ||
void TCling::Execute(const char* function, const char* params, int* error) | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -137,6 +137,8 @@ class TCling : public TInterpreter { | |
const char* GetIncludePath(); | ||
virtual const char* GetSTLIncludePath() const; | ||
TObjArray* GetRootMapFiles() const { return fRootmapFiles; } | ||
void GetMissingDictionariesForDecl(const clang::Decl* D, std::set<const clang::Decl*> netD, bool recurse); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't declare GetMissingDictionariesForDecl() here; it is only needed by TCling.cxx. |
||
std::set<TClass*> GetMissingDictionaries(TClass* cl, bool recurse); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Following Philppe's suggestion maybe better |
||
virtual void Initialize(); | ||
void InspectMembers(TMemberInspector&, void* obj, const TClass* cl); | ||
Bool_t IsLoaded(const char* filename) const; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about simply
GetMissingDictionaries()
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the advantage of std::set over TObjArray or another of the ROOT collection. Try avoid extra code generation unless really necessary.
Isn't the semantic more akin to 'GetClassesWithMissingDictionary' or 'GetClassesWithoutDictionary'
or maybe GetMissingDictionaries ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like GetMissingDictionaries() - of course they are for classes :-) And yes, TObjArray would work. But then use a set<TClass*> for TCling.cxx's GetMissingDictionariesForDecl() to be more performant, and convert the set to the TObjArray in TCling::GetMissingDictionaries(). See comment below. This one should then read
void GetMissingClassDictionaries(bool recurse, TObjArray& result);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can also return/use a THashTable .... to avoid the end result copy ... actually I am not sure what is the 'performance' issue the std::set is suppose to resolve ... the number of elements in the resulting list should be 'low' in the general case ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is mainly about merging duplicates automatically: we don't care how often MyClass is missing its dictionary.
If the set<TClass*> is only in the source it's fine.