Skip to content

Commit

Permalink
By Cristina: offset calculation also for virtual inheritance.
Browse files Browse the repository at this point in the history
  • Loading branch information
Axel-Naumann committed Oct 8, 2013
2 parents 4f81b4e + 3057b86 commit d5c61b2
Show file tree
Hide file tree
Showing 9 changed files with 352 additions and 59 deletions.
2 changes: 1 addition & 1 deletion core/meta/inc/TClass.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ friend class ROOT::TGenericClassInfo;
TClass *GetActualClass(const void *object) const;
TClass *GetBaseClass(const char *classname);
TClass *GetBaseClass(const TClass *base);
Int_t GetBaseClassOffset(const TClass *base);
Int_t GetBaseClassOffset(const TClass *base, void *address = 0);
TClass *GetBaseDataMember(const char *datamember);
ROOT::DirAutoAdd_t GetDirectoryAutoAdd() const;
UInt_t GetInstanceCount() const { return fInstanceCount; }
Expand Down
6 changes: 5 additions & 1 deletion core/meta/inc/TInterpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ class TInterpreter : public TNamed {
virtual ClassInfo_t *ClassInfo_Factory() const = 0;
virtual ClassInfo_t *ClassInfo_Factory(ClassInfo_t * /* cl */) const = 0;
virtual ClassInfo_t *ClassInfo_Factory(const char * /* name */) const = 0;
virtual Long_t ClassInfo_GetBaseOffset(ClassInfo_t* /* derived */,
ClassInfo_t* /* target */, void* /* address */ = 0) const {return 0;}
virtual int ClassInfo_GetMethodNArg(ClassInfo_t * /* info */, const char * /* method */,const char * /* proto */, Bool_t /* objectIsConst */ = false, ROOT::EFunctionMatchMode /* mode */ = ROOT::kConversionMatch) const {return 0;}
virtual Bool_t ClassInfo_HasDefaultConstructor(ClassInfo_t * /* info */) const {return 0;}
virtual Bool_t ClassInfo_HasMethod(ClassInfo_t * /* info */, const char * /* name */) const {return 0;}
Expand Down Expand Up @@ -240,9 +242,11 @@ class TInterpreter : public TNamed {
// BaseClassInfo interface
virtual void BaseClassInfo_Delete(BaseClassInfo_t * /* bcinfo */) const {;}
virtual BaseClassInfo_t *BaseClassInfo_Factory(ClassInfo_t * /* info */) const {return 0;}
virtual BaseClassInfo_t *BaseClassInfo_Factory(ClassInfo_t* /* derived */,
ClassInfo_t* /* base */) const {return 0;}
virtual int BaseClassInfo_Next(BaseClassInfo_t * /* bcinfo */) const {return 0;}
virtual int BaseClassInfo_Next(BaseClassInfo_t * /* bcinfo */, int /* onlyDirect */) const {return 0;}
virtual Long_t BaseClassInfo_Offset(BaseClassInfo_t * /* bcinfo */) const {return 0;}
virtual Long_t BaseClassInfo_Offset(BaseClassInfo_t * /* bcinfo */, void* /* address */ = 0 /*default for non-virtual*/) const {return 0;}
virtual Long_t BaseClassInfo_Property(BaseClassInfo_t * /* bcinfo */) const {return 0;}
virtual Long_t BaseClassInfo_Tagnum(BaseClassInfo_t * /* bcinfo */) const {return 0;}
virtual const char *BaseClassInfo_FullName(BaseClassInfo_t * /* bcinfo */) const {return 0;}
Expand Down
35 changes: 13 additions & 22 deletions core/meta/src/TClass.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2296,7 +2296,7 @@ Int_t TClass::GetBaseClassOffsetRecurse(const TClass *cl)
c = inh->GetClassPointer(kTRUE); // kFALSE);
if (c) {
if (cl == c) {
if ((inh->Property() & kIsVirtual) != 0)
if ((inh->Property() & kIsVirtualBase) != 0)
return -2;
return inh->GetDelta();
}
Expand All @@ -2310,34 +2310,25 @@ Int_t TClass::GetBaseClassOffsetRecurse(const TClass *cl)
}

//______________________________________________________________________________
Int_t TClass::GetBaseClassOffset(const TClass *cl)
Int_t TClass::GetBaseClassOffset(const TClass *cl, void *address)
{
// Return data member offset to the base class "cl".
// Returns -1 in case "cl" is not a base class.
// Takes care of multiple inheritance.

Int_t offset = GetBaseClassOffsetRecurse (cl);
if (offset == -2) {
// Can we get the offset from CINT?
if (cl->GetClassInfo()) {
R__LOCKGUARD(gClingMutex);
Long_t base_tagnum = gCling->ClassInfo_Tagnum(cl->GetClassInfo());
BaseClassInfo_t *t = gCling->BaseClassInfo_Factory(GetClassInfo());
while (gCling->BaseClassInfo_Next(t,0)) {
if (gCling->BaseClassInfo_Tagnum(t) == base_tagnum) {
if ((gCling->BaseClassInfo_Property(t) & kIsVirtualBase) != 0) {
break;
}
int off = gCling->BaseClassInfo_Offset(t);
gCling->BaseClassInfo_Delete(t);
return off;
}
}
gCling->BaseClassInfo_Delete(t);
R__LOCKGUARD(gClingMutex);
ClassInfo_t* derived = GetClassInfo();
ClassInfo_t* target = cl->GetClassInfo();
if(derived && target) {
return gCling->ClassInfo_GetBaseOffset(derived, target, address);
}
else {
Int_t offset = GetBaseClassOffsetRecurse (cl);
if (offset != -2) {
return offset;
}
offset = -1;
}
return offset;
return -1;
}

//______________________________________________________________________________
Expand Down
26 changes: 24 additions & 2 deletions core/meta/src/TCling.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -4745,6 +4745,15 @@ BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* cinfo) const
return (BaseClassInfo_t*) new TClingBaseClassInfo(fInterpreter, TClinginfo);
}

//______________________________________________________________________________
BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* derived,
ClassInfo_t* base) const
{
TClingClassInfo* TClinginfo = (TClingClassInfo*) derived;
TClingClassInfo* TClinginfoBase = (TClingClassInfo*) base;
return (BaseClassInfo_t*) new TClingBaseClassInfo(fInterpreter, TClinginfo, TClinginfoBase);
}

//______________________________________________________________________________
int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo) const
{
Expand All @@ -4760,10 +4769,23 @@ int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo, int onlyDirect) const
}

//______________________________________________________________________________
Long_t TCling::BaseClassInfo_Offset(BaseClassInfo_t* bcinfo) const
Long_t TCling::BaseClassInfo_Offset(BaseClassInfo_t* bcinfo, void * address) const
{
TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
return TClinginfo->Offset();
return TClinginfo->Offset(address);
}

//______________________________________________________________________________
Long_t TCling::ClassInfo_GetBaseOffset(ClassInfo_t* derived, ClassInfo_t* target, void * address) const
{
TClingClassInfo* TClinginfo = (TClingClassInfo*) derived;
TClingClassInfo* TClinginfoTarget = (TClingClassInfo*) target;
// Offset to the class itself.
if (TClinginfo->GetDecl() == TClinginfoTarget->GetDecl()) {
return 0;
}
TClingBaseClassInfo* binfo = new TClingBaseClassInfo(fInterpreter, TClinginfo, TClinginfoTarget);
return binfo->Offset(address);
}

//______________________________________________________________________________
Expand Down
5 changes: 4 additions & 1 deletion core/meta/src/TCling.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ class TCling : public TInterpreter {
virtual ClassInfo_t* ClassInfo_Factory() const;
virtual ClassInfo_t* ClassInfo_Factory(ClassInfo_t* cl) const;
virtual ClassInfo_t* ClassInfo_Factory(const char* name) const;
virtual Long_t ClassInfo_GetBaseOffset(ClassInfo_t* derived, ClassInfo_t* target, void * address) const;
virtual int ClassInfo_GetMethodNArg(ClassInfo_t* info, const char* method, const char* proto, Bool_t objectIsConst = false, ROOT::EFunctionMatchMode mode = ROOT::kConversionMatch) const;
virtual bool ClassInfo_HasDefaultConstructor(ClassInfo_t* info) const;
virtual bool ClassInfo_HasMethod(ClassInfo_t* info, const char* name) const;
Expand Down Expand Up @@ -316,9 +317,11 @@ class TCling : public TInterpreter {
// BaseClassInfo interface
virtual void BaseClassInfo_Delete(BaseClassInfo_t* bcinfo) const;
virtual BaseClassInfo_t* BaseClassInfo_Factory(ClassInfo_t* info) const;
virtual BaseClassInfo_t* BaseClassInfo_Factory(ClassInfo_t* derived,
ClassInfo_t* base) const;
virtual int BaseClassInfo_Next(BaseClassInfo_t* bcinfo) const;
virtual int BaseClassInfo_Next(BaseClassInfo_t* bcinfo, int onlyDirect) const;
virtual Long_t BaseClassInfo_Offset(BaseClassInfo_t* bcinfo) const;
virtual Long_t BaseClassInfo_Offset(BaseClassInfo_t* bcinfo, void * address) const;
virtual Long_t BaseClassInfo_Property(BaseClassInfo_t* bcinfo) const;
virtual Long_t BaseClassInfo_Tagnum(BaseClassInfo_t* bcinfo) const;
virtual const char* BaseClassInfo_FullName(BaseClassInfo_t* bcinfo) const;
Expand Down
Loading

0 comments on commit d5c61b2

Please sign in to comment.