Skip to content
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
89 changes: 21 additions & 68 deletions core/meta/src/TCling.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2791,48 +2791,21 @@ Bool_t TCling::HasDictionary(TClass* cl)
}

//______________________________________________________________________________
bool TCling::GetUnderlyingQualType(clang::QualType& qType)
bool TCling::InsertMissingDictionaryDecl(const clang::Decl* D, std::set<const clang::Type*> &netD, clang::QualType qType, bool recurse)
{

// Utility function to be able to obtain the underlying QualType for a given Type.
// Utility function to insert a type pointer to a decl that does not have a dictionary
// In the set of pointer for the classes without dictionaries.

bool changed = true;
while (changed) {
changed = false;
if (qType->isPointerType()) {
qType = qType->getPointeeType();
changed = true;
}
if (qType->isReferenceType()) {
qType = qType->getPointeeType();
changed = true;
}
if (qType->isArrayType()) {
const Type* elementType = qType->getArrayElementTypeNoTypeQual();
qType = QualType(elementType, 0);
changed = true;
}
// Already checked in the template parameter list.
if (isa<clang::TemplateTypeParmType>(qType.getTypePtr())) {
return false;
}
// Already checked in the template parameter list.
if (isa<clang::SubstTemplateTypeParmType>(qType.getTypePtr())) {
return false;
}
if (qType->isRecordType()) {
return true;
}
if (const clang::TypedefType* TD = dyn_cast<clang::TypedefType>(qType)) {
qType = (TD->desugar());
}
if (const clang::TemplateTypeParmType* TD = dyn_cast<clang::TemplateTypeParmType>(qType)) {
qType = (TD->desugar());
}
if (const clang::SubstTemplateTypeParmType* TD = dyn_cast<clang::SubstTemplateTypeParmType>(qType)) {
qType = (TD->desugar());
}
return false;
}

//______________________________________________________________________________
bool TCling::InsertMissingDictionaryDecl(const clang::Decl* D, std::set<const clang::Type*> &netD, clang::QualType& qType, bool recurse)
{

// Utility function to insert a type pointer to a decl that does not have a dictionary
// In the set of pointer for teh classes without dictionaries.

// Check whether the type pointer is not already in the set.
std::set<const clang::Type*>::iterator it = netD.find(qType.getTypePtr());
Expand All @@ -2842,6 +2815,7 @@ bool TCling::InsertMissingDictionaryDecl(const clang::Decl* D, std::set<const cl
std::string buf;
ROOT::TMetaUtils::GetNormalizedName(buf, qType, *fInterpreter, *fNormalizedCtxt);
const char* name = buf.c_str();

// Check for the dictionary of the curent class.
if (TClass* t = TClass::GetClass(name)) {
//Check whether a custom streamer
Expand Down Expand Up @@ -2873,36 +2847,14 @@ bool TCling::InsertMissingDictionaryDecl(const clang::Decl* D, std::set<const cl
if (!gClassTable->GetDict(name)) {
netD.insert(qType.getTypePtr());
}
// Check for templates.
if (!qType.isNull()) {
// Check whether the data member is a template and loop through the TemplateArguments
if (const clang::TemplateSpecializationType* templateType = dyn_cast<clang::TemplateSpecializationType>(qType.getTypePtr())) {
for (clang::TemplateSpecializationType::iterator TIB = templateType->begin(),
TIE = templateType->end(); TIB != TIE; ++TIB) {
if (TIB) {
clang::TemplateArgument::ArgKind tmpltArgKind = TIB->getKind();
if (tmpltArgKind == clang::TemplateArgument::Type) {
qType = TIB->getAsType();
if (GetUnderlyingQualType(qType)) {
clang::Decl* tmplD = qType->getAsCXXRecordDecl();
if (tmplD) {
GetMissingDictionariesForDecl(tmplD, netD, qType, recurse);
}
}
}
}
}
return recurse;
}
}

return true;
}
//______________________________________________________________________________
void TCling::GetMissingDictionariesForDecl(const clang::Decl* D, std::set<const clang::Type*> &netD, clang::QualType qType, bool recurse)
{
// Utility function to get the missing dictionaries for a record decl.
// Checks all the data members and if the recurse flag is true it recurses over contents of the data members as well.
// Checks all the data members and if the recurse flag is true it recurses over contents of the data members.

// Insert this Type pointer in the set if it is not already there and it does not have a dictionary.
if (!InsertMissingDictionaryDecl(D, netD, qType, recurse)) return;
Expand All @@ -2912,16 +2864,17 @@ void TCling::GetMissingDictionariesForDecl(const clang::Decl* D, std::set<const
for (clang::RecordDecl::field_iterator iField = RD->field_begin(),
eField = RD->field_end(); iField != eField; ++iField) {

clang::QualType fieldQType = (*iField)->getType();
if (!fieldQType.isNull()) {
clang::QualType fieldQualType = (*iField)->getType();
if (!fieldQualType.isNull()) {
// Check if not NullType.
if (GetUnderlyingQualType(fieldQType)) {
clang::Decl* FD = fieldQType->getAsCXXRecordDecl();
//if (const clang::TypedefType* TD = dyn_cast<clang::TypedefType>(fieldQualType.getTypePtr())) {
if (const clang::Type* fieldType = ROOT::TMetaUtils::GetUnderlyingType(fieldQualType)) {
clang::Decl* FD = fieldType->getAsCXXRecordDecl();
if (FD) {
if(recurse) {
GetMissingDictionariesForDecl(FD, netD, fieldQType, recurse);
GetMissingDictionariesForDecl(FD, netD, QualType(fieldType, 0), recurse);
} else {
InsertMissingDictionaryDecl(FD, netD, fieldQType, recurse);
InsertMissingDictionaryDecl(FD, netD, QualType(fieldType, 0), recurse);
}
}
}
Expand Down Expand Up @@ -3379,7 +3332,7 @@ Int_t TCling::LoadLibraryMap(const char* rootmapfile)
cls.ReplaceAll("-", " ");
cling::Transaction* T = 0;
fInterpreter->declare(cls.Data(), &T);
ClassTemplateDecl* D
ClassTemplateDecl* D
= cast<ClassTemplateDecl>(T->getFirstDecl().getSingleDecl());
if (TagDecl* TD = dyn_cast<TagDecl>(D->getTemplatedDecl()))
TD->setHasExternalLexicalStorage();
Expand Down
3 changes: 1 addition & 2 deletions core/meta/src/TCling.h
Original file line number Diff line number Diff line change
Expand Up @@ -425,9 +425,8 @@ class TCling : public TInterpreter {
bool LoadPCM(TString pcmFileName, const char** headers,
void (*triggerFunc)()) const;
void HandleEnumDecl(const clang::Decl* D, bool isGlobal, TClass *cl = 0) const;
bool GetUnderlyingQualType(clang::QualType& qualType);
void GetMissingDictionariesForDecl(const clang::Decl* D, std::set<const clang::Type*> &netD, clang::QualType qType, bool recurse);
bool InsertMissingDictionaryDecl(const clang::Decl* D, std::set<const clang::Type*> &netD, clang::QualType& qType, bool recurse);
bool InsertMissingDictionaryDecl(const clang::Decl* D, std::set<const clang::Type*> &netD, clang::QualType qType, bool recurse);

ClassDef(TCling, 0) //Interface to cling C++ interpreter
};
Expand Down