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

Manuel Klimek klimek at google.com
Thu Oct 11 02:47:36 PDT 2012


On Thu, Oct 11, 2012 at 11:05 AM, Gábor Horváth <xazax.hun at gmail.com> wrote:
> Hi!
>
> It looks like ...hasType(namedDecl(matchesName("std::set.*iterator"))) ...
> only tries to match ::std::_Rb_tree_const_iterator, but not
> std::set<foobar>::iterator, so I basicaly can't match typedefs. I think it
> is not possible to match on typedef-ed types right now.
>
> There is one test case:
> EXPECT_TRUE(matches("typedef int X;", NamedX));
>
> However it matches a typedef declaration. However if we wan't to match
> something like "X i;" later on, we can not do that, however it would be
> extremely useful.
>
> Any comments on this?

We need to write a matcher that supports this. We already have some of
the supporting code for isDerivedFrom which looks through typedefs.
We'll basically want to have a matcher matchesNameOrTypedef (minus
finding a better name for the matcher ;) that does what you want.

Cheers,
/Manuel

>
> Thanks,
> Gábor
>
>
>
> On 11 October 2012 09:39, Gábor Horváth <xazax.hun at gmail.com> wrote:
>>
>> 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
>>>
>>>
>>
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>




More information about the cfe-dev mailing list