Skip to content

Commit

Permalink
DeclIt_t to TClass* map to have access to TClass* without name search…
Browse files Browse the repository at this point in the history
…. (ROOT-6159).
  • Loading branch information
CristinaCristescu authored and Axel-Naumann committed Mar 28, 2014
1 parent 7266b0a commit d7e306c
Show file tree
Hide file tree
Showing 4 changed files with 208 additions and 24 deletions.
7 changes: 7 additions & 0 deletions core/meta/inc/TClass.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include <map>
#include <string>
#include <set>
#include <vector>

class TBaseClass;
class TBrowser;
Expand Down Expand Up @@ -72,8 +73,10 @@ namespace ROOT {

namespace ROOT {
class TMapTypeToTClass;
class TMapDeclIdToTClass;
}
typedef ROOT::TMapTypeToTClass IdMap_t;
typedef ROOT::TMapDeclIdToTClass DeclIdMap_t;

class TClass : public TDictionary {

Expand Down Expand Up @@ -195,6 +198,7 @@ friend class ROOT::TGenericClassInfo;
void StreamerDefault(void *object, TBuffer &b, const TClass *onfile_class) const;

static IdMap_t *GetIdMap(); //Map from typeid to TClass pointer
static DeclIdMap_t *GetDeclIdMap(); //Map from DeclId_t to TClass pointer
static ENewType fgCallingNew; //Intent of why/how TClass::New() is called
static Int_t fgClassCount; //provides unique id for a each class
//stored in TObject::fUniqueID
Expand Down Expand Up @@ -402,11 +406,14 @@ friend class ROOT::TGenericClassInfo;

// Function to retrieve the TClass object and dictionary function
static void AddClass(TClass *cl);
static void AddClassToDeclIdMap(TDictionary::DeclId_t id, TClass* cl);
static void RemoveClass(TClass *cl);
static void RemoveClassDeclId(TDictionary::DeclId_t id);
static TClass *GetClassOrAlias(const char *name);
static TClass *GetClass(const char *name, Bool_t load = kTRUE, Bool_t silent = kFALSE);
static TClass *GetClass(const type_info &typeinfo, Bool_t load = kTRUE, Bool_t silent = kFALSE);
static TClass *GetClass(ClassInfo_t *info, Bool_t load = kTRUE, Bool_t silent = kFALSE);
static Bool_t GetClass(DeclId_t id, std::vector<TClass*> &classes);
static VoidFuncPtr_t GetDict (const char *cname);
static VoidFuncPtr_t GetDict (const type_info &info);

Expand Down
85 changes: 85 additions & 0 deletions core/meta/src/TClass.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
#include <typeinfo>
#include <cmath>
#include <assert.h>
#include <vector>

#include "TListOfDataMembers.h"
#include "TListOfFunctions.h"
Expand Down Expand Up @@ -253,6 +254,41 @@ namespace ROOT {
}
#endif
};

class TMapDeclIdToTClass {
// Wrapper class for the multimap of DeclId_t and TClass.
public:
typedef multimap<TDictionary::DeclId_t, TClass*> DeclIdMap_t;
typedef DeclIdMap_t::key_type key_type;
typedef DeclIdMap_t::mapped_type mapped_type;
typedef DeclIdMap_t::const_iterator const_iterator;
typedef std::pair <const_iterator, const_iterator> equal_range;
typedef DeclIdMap_t::size_type size_type;

private:
DeclIdMap_t fMap;

public:
void Add(const key_type &key, mapped_type obj)
{
// Add the <key,obj> pair to the map.
std::pair<const key_type, mapped_type> pair = make_pair(key, obj);
fMap.insert(pair);
}
size_type CountElementsWithKey(const key_type &key)
{
return fMap.count(key);
}
equal_range Find(const key_type &key) const
{
// Find the type corresponding to the key.
return fMap.equal_range(key);
}
void Remove(const key_type &key) {
// Remove the type corresponding to the key.
fMap.erase(key);
}
};
}

IdMap_t *TClass::GetIdMap() {
Expand All @@ -266,6 +302,17 @@ IdMap_t *TClass::GetIdMap() {
#endif
}

DeclIdMap_t *TClass::GetDeclIdMap() {

#ifdef R__COMPLETE_MEM_TERMINATION
static DeclIdMap_t gDeclIdMapObject;
return &gIdMap;
#else
static DeclIdMap_t *gDeclIdMap = new DeclIdMap_t;
return gDeclIdMap;
#endif
}

//______________________________________________________________________________
void TClass::AddClass(TClass *cl)
{
Expand All @@ -276,6 +323,18 @@ void TClass::AddClass(TClass *cl)
if (cl->GetTypeInfo()) {
GetIdMap()->Add(cl->GetTypeInfo()->name(),cl);
}
if (cl->fClassInfo) {
GetDeclIdMap()->Add((void*)(cl->fClassInfo), cl);
}
}

//______________________________________________________________________________
void TClass::AddClassToDeclIdMap(TDictionary::DeclId_t id, TClass* cl)
{
// static: Add a TClass* to the map of classes.

if (!cl || !id) return;
GetDeclIdMap()->Add(id, cl);
}

//______________________________________________________________________________
Expand All @@ -288,6 +347,16 @@ void TClass::RemoveClass(TClass *oldcl)
if (oldcl->GetTypeInfo()) {
GetIdMap()->Remove(oldcl->GetTypeInfo()->name());
}
if (oldcl->fClassInfo) {
//GetDeclIdMap()->Remove((void*)(oldcl->fClassInfo));
}
}

//______________________________________________________________________________
void TClass::RemoveClassDeclId(TDictionary::DeclId_t id)
{
if (!id) return;
GetDeclIdMap()->Remove(id);
}

//______________________________________________________________________________
Expand Down Expand Up @@ -2865,6 +2934,22 @@ TClass *TClass::GetClass(ClassInfo_t *info, Bool_t load, Bool_t silent)
}
}

//______________________________________________________________________________
Bool_t TClass::GetClass(DeclId_t id, std::vector<TClass*> &classes)
{

if (!gROOT->GetListOfClasses()) return 0;

DeclIdMap_t* map = GetDeclIdMap();
// Get all the TClass pointer that have the same DeclId.
DeclIdMap_t::equal_range iter = map->Find(id);
if (iter.first == iter.second) return false;
std::vector<TClass*>::iterator vectIt = classes.begin();
for (DeclIdMap_t::const_iterator it = iter.first; it != iter.second; ++it)
vectIt = classes.insert(vectIt, it->second);
return true;
}

//______________________________________________________________________________
VoidFuncPtr_t TClass::GetDict (const char *cname)
{
Expand Down
138 changes: 115 additions & 23 deletions core/meta/src/TCling.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "TMemberInspector.h"
#include "TMethod.h"
#include "TMethodArg.h"
#include "TFunctionTemplate.h"
#include "TObjArray.h"
#include "TObjString.h"
#include "TString.h"
Expand Down Expand Up @@ -393,8 +394,7 @@ void TCling__GetNormalizedContext(const ROOT::TMetaUtils::TNormalizedCtxt*& norm
}

extern "C"
void TCling__UpdateListsOnCommitted(const cling::Transaction &T,
cling::Interpreter* interp) {
void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter*) {

((TCling*)gCling)->UpdateListsOnCommitted(T);
}
Expand Down Expand Up @@ -2205,7 +2205,12 @@ void TCling::SetClassInfo(TClass* cl, Bool_t reload)
if (cl->fClassInfo && !reload) {
return;
}
delete (TClingClassInfo*) cl->fClassInfo;
//Remove the decl_id from the DeclIdToTClass map
TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
if (TClinginfo) {
TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
}
delete TClinginfo;
cl->fClassInfo = 0;
std::string name(cl->GetName());
TClingClassInfo* info = new TClingClassInfo(fInterpreter, name.c_str());
Expand Down Expand Up @@ -2273,6 +2278,9 @@ void TCling::SetClassInfo(TClass* cl, Bool_t reload)
// }
}
}
if (cl->fClassInfo) {
TClass::AddClassToDeclIdMap(((TClingClassInfo*)cl->fClassInfo)->GetDeclId(), cl);
}
}

//______________________________________________________________________________
Expand Down Expand Up @@ -2706,6 +2714,10 @@ TClass *TCling::GenerateTClass(ClassInfo_t *classinfo, Bool_t silent /* = kFALSE
// Not quite useful yet, but that what CINT used to do anyway.
cl = new TClass(classinfo, 1, 0, 0, -1, -1, silent);
}
// Add the new TClass to the map of declid and TClass*.
if (cl) {
TClass::AddClassToDeclIdMap(((TClingClassInfo*)classinfo)->GetDeclId(), cl);
}
return cl;
}

Expand Down Expand Up @@ -4371,9 +4383,11 @@ void TCling::UpdateClassInfoWithDecl(const void* vTD)
const TagDecl* tdOld = llvm::dyn_cast_or_null<TagDecl>(cci->GetDecl());
if (!tdOld || (tdDef && tdDef != tdOld)) {
cl->ResetCaches();
TClass::RemoveClassDeclId(cci->GetDeclId());
if (td) {
// It's a tag decl, not a namespace decl.
cci->Init(*cci->GetType());
TClass::AddClassToDeclIdMap(cci->GetDeclId(), cl);
}
}
} else {
Expand All @@ -4382,6 +4396,7 @@ void TCling::UpdateClassInfoWithDecl(const void* vTD)
// the 'type' corresponding to the TClass anyway in order to
// preserve the opaque typedefs (Double32_t)
cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(fInterpreter, cl->GetName());
TClass::AddClassToDeclIdMap(((TClingClassInfo*)(cl->fClassInfo))->GetDeclId(), cl);
}
}
SetClassAutoloading(storedAutoloading);
Expand Down Expand Up @@ -4513,43 +4528,46 @@ void TCling::UpdateListsOnUnloaded(const cling::Transaction &T)
HandleNewTransaction(T);

// Unload the objects from the lists and update the objects' state.
TGlobal *global = 0;
TFunction *function = 0;
TDataMember* var = 0;
TFunction* function = 0;
TEnum* e = 0;
TListOfDataMembers* globals = (TListOfDataMembers*)gROOT->GetListOfGlobals();
TFunctionTemplate* functiontemplate = 0;
TListOfFunctions* functions = (TListOfFunctions*)gROOT->GetListOfGlobalFunctions();
TListOfFunctionTemplates* functiontemplates = (TListOfFunctionTemplates*)gROOT->GetListOfFunctionTemplates();
TListOfEnums* enums = (TListOfEnums*)gROOT->GetListOfEnums();
TListOfDataMembers* globals = (TListOfDataMembers*)gROOT->GetListOfGlobals();
for(cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
I != E; ++I)
I != E; ++I) {
for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
DE = I->m_DGR.end(); DI != DE; ++DI) {
// Deal with global variables and globa enum constants.
if (isa<VarDecl>(*DI) || isa<EnumConstantDecl>(*DI)) {
clang::ValueDecl* VD = dyn_cast<ValueDecl>(*DI);
global = (TGlobal*)globals->FindObject(VD->getNameAsString().c_str());
if (global && global->IsValid()) {
var = (TDataMember*)globals->FindObject(VD->getNameAsString().c_str());
if (var && var->IsValid()) {
// Unload the global by setting the DataMemberInfo_t to 0
globals->Unload(global);
global->Update(0);
}
} else if (isa<RecordDecl>(*DI) || isa<NamespaceDecl>(*DI)) {
const clang::NamedDecl* ND = dyn_cast<NamedDecl>(*DI);
if (ND) {
std::string buf = ND->getNameAsString();
const char* name = buf.c_str();
TClass* cl = TClass::GetClass(name);
if (cl) {
cl->ResetClassInfo();
}
globals->Unload(var);
var->Update(0);
}
// Deal with global functions.
} else if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(*DI)) {
function = gROOT->GetGlobalFunction(FD->getNameAsString().c_str());
function = (TFunction*)functions->FindObject(FD->getNameAsString().c_str());
if (function && function->IsValid()) {
functions->Unload(function);
function->Update(0);
}
// Deal with global function templates.
} else if (const FunctionTemplateDecl* FTD = dyn_cast<FunctionTemplateDecl>(*DI)) {
functiontemplate = (TFunctionTemplate*)functiontemplates->FindObject(FTD->getNameAsString().c_str());
if (functiontemplate) {
functiontemplates->Unload(functiontemplate);
functiontemplate->Update(0);
}
// Deal with global enums.
} else if (const EnumDecl* ED = dyn_cast<EnumDecl>(*DI)) {
e = (TEnum*)enums->FindObject(ED->getNameAsString().c_str());
if (e && e->IsValid()) {
if (e) {
globals = (TListOfDataMembers*)gROOT->GetListOfGlobals();
TIter iEnumConst(e->GetConstants());
while (TEnumConstant* enumConst = (TEnumConstant*)iEnumConst()) {
// Since the enum is already created and valid that ensures us that
Expand All @@ -4563,8 +4581,82 @@ void TCling::UpdateListsOnUnloaded(const cling::Transaction &T)
enums->Unload(e);
e->Update(0);
}
// Deal with classes. Unload the class and the data members will be not accessible anymore
// Cannot declare the members in a different declaration like redeclarable namespaces.
} else if (const clang::RecordDecl* RD = dyn_cast<RecordDecl>(*DI)) {
std::vector<TClass*> vectTClass;
if (TClass::GetClass(RD, vectTClass)) {
for (std::vector<TClass*>::iterator CI = vectTClass.begin(), CE = vectTClass.end();
CI != CE; ++CI) {
(*CI)->ResetClassInfo();
}
}
// Deal with namespaces. Unload the members of the current redeclaration only.
} else if (const clang::NamespaceDecl* ND = dyn_cast<NamespaceDecl>(*DI)) {
if (ND->isOriginalNamespace()) {
std::vector<TClass*> vectTClass;
if (TClass::GetClass(ND, vectTClass)) {
for (std::vector<TClass*>::iterator CI = vectTClass.begin(), CE = vectTClass.end();
CI != CE; ++CI) {
(*CI)->ResetClassInfo();
}
}
} else {
std::vector<TClass*> vectTClass;
if (TClass::GetClass(ND->getCanonicalDecl(), vectTClass)) {
for (std::vector<TClass*>::iterator CI = vectTClass.begin(), CE = vectTClass.end();
CI != CE; ++CI) {
TClass* cl = (*CI);
TListOfDataMembers* datamembers = (TListOfDataMembers*)cl->GetListOfDataMembers();
TListOfFunctions* functions = (TListOfFunctions*)cl->GetListOfMethods();
TListOfEnums* enums = (TListOfEnums*)cl->GetListOfEnums();
TListOfFunctionTemplates* functiontemplates = (TListOfFunctionTemplates*)cl->GetListOfFunctionTemplates();
// If this is a redeclaration of the namespace, we iterate over the members to unload them
for (DeclContext::decl_iterator RI = ND->decls_begin(), RE = ND->decls_end(); RI != RE; ++RI) {
if (isa<VarDecl>(*RI) || isa<EnumConstantDecl>(*RI)) {
clang::ValueDecl* VD = dyn_cast<ValueDecl>(*RI);
var = (TDataMember*)datamembers->FindObject(VD->getNameAsString().c_str());
if (var) {
// Unload the global by setting the DataMemberInfo_t to 0
datamembers->Unload(var);
var->Update(0);
}
} else if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(*RI)) {
function = (TFunction*)functions->FindObject(FD->getNameAsString().c_str());
if (function) {
functions->Unload(function);
function->Update(0);
}
} else if (const EnumDecl* ED = dyn_cast<EnumDecl>(*RI)) {
e = (TEnum*)enums->FindObject(ED->getNameAsString().c_str());
if (e) {
TIter iEnumConst(e->GetConstants());
while (TEnumConstant* enumConst = (TEnumConstant*)iEnumConst()) {
// Since the enum is already created and valid that ensures us that
// we have the enum constants created as well.
enumConst = (TEnumConstant*)datamembers->FindObject(enumConst->GetName());
if (enumConst && enumConst->IsValid()) {
datamembers->Unload(enumConst);
enumConst->Update(0);
}
}
enums->Unload(e);
e->Update(0);
}
} else if (const FunctionTemplateDecl* FTD = dyn_cast<FunctionTemplateDecl>(*RI)) {
functiontemplate = (TFunctionTemplate*)functiontemplates->FindObject(FTD->getNameAsString().c_str());
if (functiontemplate) {
functiontemplates->Unload(functiontemplate);
functiontemplate->Update(0);
}
}
}
}
}
}
}
}
}
}


Expand Down
Loading

0 comments on commit d7e306c

Please sign in to comment.