[cfe-dev] Matching Indirect base classes

Daniel Jasper djasper at google.com
Mon Nov 11 07:43:41 PST 2013


On Mon, Nov 11, 2013 at 2:04 AM, Pedro Delgado Perez
<pedro.delgado at uca.es>wrote:

>  Well, using as reference what you named of Sema::CheckUsingDeclQualifier,
> I tried the following;
>
> DeclarationMatcher I_Matcher = recordDecl().bind("var");
>
> class HVD : public MatchFinder::MatchCallback {
> public :
>
>   llvm::SmallPtrSet<const CXXRecordDecl*, 4> Bases;
>
>   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?
>
The OpaqueData part seems correct.

> 2 - I got an error doing this and I can't understand the problem.
>
> IHD_operator:
> /home/pedro/clang-llvm/llvm/tools/clang/include/clang/AST/DeclCXX.h:558:
> const clang::CXXRecordDecl::DefinitionData& clang::CXXRecordDecl::data()
> const: Assertion `DefinitionData && "queried property of class with no
> definition"' failed.
> Stack dump:
> 0.    <eof> parser at end of file
>
As per its comment, forallBases needs to be called on a CXXRecordDecl that
is a definition (not e.g. a forward declaration or an injected class name).
Thus, you will need to ensure that FS->getDefinition() is not NULL and then
call it on that.

> 3. Once inside the for loop, how can I get each object CXXRecordDecl
> through SmallPtrSetIterator.<http://llvm.org/docs/doxygen/html/classllvm_1_1SmallPtrSetIterator.html#ac931fc62430140f2cce08d72e5f27c82>
>
I think you just need to dereference it:

const CXXRecordDecl *Base = *i;

> Thanks for your time,
>
> Pedro.
>
No problem, I hope this helps,
Daniel


> *El día 08 nov 2013 18:30, Daniel Jasper <djasper at google.com
> <djasper at google.com>> escribió:*
>
> Yes, sorry, lookupInBases() is what I meant. You'll need forAllBases().
> You can pass in a ForallBasesCallback, which is basically a callback
> function executed for each base class.
> I have not used this myself, but for an example, look at:
> CXXRecordDecl::isProvablyNotDerivedFrom defined in
> lib/AST/CXXInheritance.cpp.
>
> Also lib/Sema/SemaDeclCXX.cpp has an example close to the bottom
> of Sema::CheckUsingDeclQualifier()
> that collects all of the bases into a SmallPtrSet.
>
>
> On Fri, Nov 8, 2013 at 9:16 AM, Pedro Delgado Perez <pedro.delgado at uca.es>wrote:
>
>> Hi,
>>
>> Thanks Daniel, I suppose you mean CXXRecordDecl::lookupInBases() instead
>> CXXRecordDecl::findInBases().
>>
>> Have you ever used one of these methods? I don't understand quite well
>> how can I use them for my purpose. What I need is that, given an object
>> CXXRecordDecl, I can analyze something in particular in each one of its
>> base classes (direct or indirect). Thus, I need to get each one of these
>> classes to process them, but the methods you refer only return a *bool*.
>>
>> Could you please show me an example using these methods? Mainly, with
>> respect the arguments passed to these methdos.
>>
>> Thanks,
>>
>> Pedro.
>> *El día 08 nov 2013 15:32, Daniel Jasper <djasper at google.com
>> <djasper at google.com>> escribió:*
>>
>> Take a look at CXXRecordDecl::forallBases() and
>> CXXRecordDecl::findInBases(). Dependent on what you want to do, one of them
>> might do what you need.
>> Cheers,
>> Daniel
>>
>>
>> On Fri, Nov 8, 2013 at 2:39 AM, Pedro Delgado Perez <pedro.delgado at uca.es
>> > wrote:
>>
>>> Hello,
>>>
>>> Please, I need some help with an issue I noticed a few days ago and I am
>>> not able to solve.
>>>
>>> To illustrate my problem, I show this piece of code:
>>>
>>> class A{
>>>     public:
>>>         A(): a(1) {};
>>>         int a;
>>> };
>>>
>>> class B: public A{
>>>     public:
>>>         B(): b(2){};
>>>         int b;
>>> };
>>>
>>> class C: public B{
>>>     public:
>>>         C(): c(3){};
>>>         int b;
>>>         int a;
>>> };
>>>
>>> We have three classes, where:
>>> B  inherits directly from A
>>> C  inherits directly from B and INDIRECTLY from A
>>>
>>> Using CXXRecordDecl::base_class_iterator, the classes indirectly
>>> inherited are not visited. Please, can someone explain me how to take into
>>> account these indirectly inherited base classes? I've been thinking on
>>> recursion (use base_class_iterator on each class directly inherited), but
>>> I'm sure there should be another simpler way to do this.
>>>
>>> Thanks in advance,
>>>
>>> Pedro.
>>>
>>> _______________________________________________
>>> cfe-dev mailing list
>>> cfe-dev at cs.uiuc.edu
>>>
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20131111/90a1faf0/attachment.html>


More information about the cfe-dev mailing list