[cfe-dev] Matching std::set::iterator

Gábor Horváth xazax.hun at gmail.com
Thu Oct 11 00:39:27 PDT 2012


Hi!

More details on matching template specializations. After further trials I
even tried this piece of code:

MatcherProxy StlCOAPPred::getMatcher()
{
  TypeMatcher type = unless(anything());

  for(const auto& e : gContainers)
    type = anyOf(hasDeclaration(recordDecl(hasName(e))), type);

  return id("id",
            varDecl(allOf(hasType(

classTemplateSpecializationDecl(hasAnyTemplateArgument(

refersToType(hasDeclaration(hasDescendant(recordDecl(hasName("std::auto_ptr")))))))),
                          hasType(type))));
}

If I remove the hasDescendant, it works flawlessly for example for
vector<auto_ptr<int>>, however it will not fork for
vector<vector<auto_ptr<int>>>. If I add that hasDescendant it will not
match anything. The same applies to the code I pasted in my mail earlier.
If you have any idea what could cause this issue, please tell me.

Thanks,
Gábor


On 10 October 2012 15:37, Gábor Horváth <xazax.hun at gmail.com> wrote:

> For the second one, I altered my snippet:
>
>
> MatcherProxy StlCOAPPred::getMatcher()
> {
>   TypeMatcher type = unless(anything());
>
>   for(const auto& e : gContainers)
>     type = anyOf(hasDeclaration(recordDecl(hasName(e))), type);
>
>   return id("id",
>             varDecl(allOf(hasType(recordDecl(hasDescendant(
>
> classTemplateSpecializationDecl(hasAnyTemplateArgument(
>
> refersToType(hasDeclaration(recordDecl(hasName("std::auto_ptr"))))))))),
>                          hasType(type))));
> }
>
>
> But it does not seems to work. It do not give me any matches.
>
> For the first one, I futher will investigate it later today, however my
> bet would be that, it tries to match "std::_Rb_tree_const_iterator".
>
> Thanks,
> Gábor
>
>
> On 10 October 2012 13:55, Daniel Jasper <djasper at google.com> wrote:
>
>> +cfe-dev, please remember to include
>>
>> I don't see anything generally wrong with your approach to match
>> iterators. What I would do to debug this is locally editing
>> ASTMatchers.h to add a "llvm::outs() << FullName;" debug output into
>> the matchesName matcher. That way, you can see what it is actually
>> trying to match.
>>
>> The second question should work like:
>>
>>   varDecl(hasType(recordDecl(
>>     hasDescendent(classTemplateSpecialization(hasAnyTemplateArgument(
>>       refersToType(hasName("std::auto_ptr")))))))).bind("id")
>>
>> This is just as a general idea, it might not yet be correct.
>>
>> Cheers,
>> Daniel
>>
>> On Wed, Oct 10, 2012 at 1:23 PM, Gábor Horváth <xazax.hun at gmail.com>
>> wrote:
>> > Hi!
>> >
>> > I want to create a matcher to match things like std::set<int>::iterator.
>> >
>> > I come up with this one: ...
>> > hasType(namedDecl(matchesName("std::set.*iterator"))) ...
>> > however it did not give me any match.
>> >
>> > Using the internal name of the iterator class like
>> > std::_Rb_tree_const_iterator would work, however that is implementation
>> > defined, so I do not want to rely on that one.
>> >
>> > Do you have any idea what am I doing wrong?
>> >
>> > My another question is, for example if I want to search for auto_ptr as
>> > template arguments in containers, I want to match vector<auto_ptr<int>>
>> and
>> > also vector<vector<auto_ptr<int>>> ... etc.
>> >
>> > Is there any proper way to do it? My current solution:
>> >
>> > MatcherProxy StlCOAPPred::getMatcher()
>> > {
>> >   TypeMatcher type = unless(anything());
>> >
>> >   for(const auto& e : gContainers)
>> >     type = anyOf(hasDeclaration(recordDecl(hasName(e))), type);
>> >
>> >   auto templateSpecWithArgument = [](DeclarationMatcher decl) ->
>> > DeclarationMatcher {
>> >     return
>> >
>> classTemplateSpecializationDecl(hasAnyTemplateArgument(refersToType(hasDeclaration(decl))));
>> >   };
>> >
>> >   // 1, 2, 3 times embedded
>> >   DeclarationMatcher decl =
>> > anyOf(templateSpecWithArgument(recordDecl(hasName("std::auto_ptr"))),
>> >
>> >
>> templateSpecWithArgument(templateSpecWithArgument(recordDecl(hasName("std::auto_ptr")))),
>> >
>> >
>> templateSpecWithArgument(templateSpecWithArgument(templateSpecWithArgument(recordDecl(hasName("std::auto_ptr"))))));
>> >
>> >
>> >   return id("id",varDecl(allOf(hasType(decl),hasType(type))));
>> > }
>> >
>> > I use templateSpecWithArgument, and nesting it. I could write a loop to
>> do
>> > this nesting several times, however I think that could degrade the
>> > performance significantly (I did not measure yet).
>> >
>> > Thanks
>> > Gábor
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20121011/1a1473c7/attachment.html>


More information about the cfe-dev mailing list