Matching Indirect base classes

Hi again,

I came across with a problem using this approach. In my message, I made the following question:

class HVD : public MatchFinder::MatchCallback {

static bool collect(const CXXRecordDecl *Base, void *OpaqueData) {
HVD Data = reinterpret_cast<HVD>(OpaqueData);
Data->Bases.insert(Base);
return true;
}

virtual void run(const MatchFinder::MatchResult &Result) {
… …
if (const CXXRecordDecl FS = Result.Nodes.getNodeAsclang::CXXRecordDecl(“var”)){
if(FS->forallBases(collect, this)){
for(llvm::SmallPtrSet<const CXXRecordDecl
, 4>::const_iterator i = Bases.begin(); i != Bases.end(); i++){
… …
}
}
}
}
};

1 - To tell you the truth, I have no idea what I have to do with OpaqueData. Is what I put above correct?

And you told me:

The OpaqueData part seems correct.

However, I have found that every class that is inherited from another class is added in the set of base classes, and not only the base classes inherited from the class calling forallBases. To illustrate what I’m saying, here I put an example:

class A;
class B: public A;
class C;
class D: public C;
class E: public D;

If I call “E”->forallBases(collect, this), what I want is that the classes C and D are found, but the class A is also being added because it is inherited from B. I guess the problem is in the second parameter passed to forAllBases (“this”) or with “HVD Data = reinterpret_cast<HVD>(OpaqueData);” inside “collect”, but I’m not so expert using these libraries.

Please, I need some help to finally solve this matter.

Thanks in advance,

Pedro.

El día 11 nov 2013 16:43, Daniel Jasper djasper@google.com escribió:

Hi again,

I came across with a problem using this approach. In my message, I made
the following question:

class HVD : public MatchFinder::MatchCallback {
...

static bool collect(const CXXRecordDecl *Base, void *OpaqueData) {
      HVD *Data = reinterpret_cast<HVD*>(OpaqueData);
      Data->Bases.insert(Base);
      return true;
  }

virtual void run(const MatchFinder::MatchResult &Result) {
      ... ....
     if (const CXXRecordDecl *FS =
Result.Nodes.getNodeAs<clang::CXXRecordDecl>("var")){
         if(FS->forallBases(collect, this)){
              for(llvm::SmallPtrSet<const CXXRecordDecl*,
4>::const_iterator i = Bases.begin(); i != Bases.end(); i++){
                  ... ...
              }
        }
     }
  }
};

1 - To tell you the truth, I have no idea what I have to do with
OpaqueData. Is what I put above correct?

And you told me:

The OpaqueData part seems correct.

However, I have found that every class that is inherited from another
class is added in the set of base classes, and not only the base classes
inherited from the class calling *forallBases*. To illustrate what I'm
saying, here I put an example:

class A;
class B: public A;
class C;
class D: public C;
class E: public D;

If I call "E"->forallBases(collect, this), what I want is that the classes
C and D are found, but the class A is also being added because it is
inherited from B. I guess the problem is in the second parameter passed to
forAllBases ("this") or with "HVD *Data =
reinterpret_cast<HVD*>(OpaqueData);" inside "collect", but I'm not so
expert using these libraries.

The usage of OpaqueData still seems correct to me and I very much doubt
that forallBases behaves in the way you are describing. Look at the
implementation:
http://clang.llvm.org/doxygen/CXXInheritance_8cpp_source.html#l00136

It basically iterates of all base classes of the class you are passing in
and is then recursively called on these. Are you clearing your "Bases" set
between callback invocations (e.g. right before the call to forallBases)?