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

Gábor Horváth xazax.hun at gmail.com
Thu Oct 11 05:28:07 PDT 2012


>From my point of view, maybe something like matchesNameOrTypedef would be
clean/easy. However I will be happy with any approach that provides an
obvious interface. I think not being able to match typedefs is one of the
biggest shortcomings of the matchers right now.


On 11 October 2012 14:14, Manuel Klimek <klimek at google.com> wrote:

> On Thu, Oct 11, 2012 at 12:03 PM, Daniel Jasper <djasper at google.com>wrote:
>
>> We should make that decisions together with the Type/TypeLoc matching.
>> I think looking through typedefs needs to be done with matchers for
>> types. matchesName()/hasName() on declarations should always look at
>> the name of the type used for the declaration and not at an alias
>> defined in a typedef.
>>
>
>
> I'm not sure I agree. It seems like the name property is really one of the
> decl or typedef, not one of the type.
>
> I'm curious about other opinions, though...
>
> Cheers,
> /Manuel
>
>
>>
>> Cheers,
>> Daniel
>>
>> On Thu, Oct 11, 2012 at 11:47 AM, Manuel Klimek <klimek at google.com>
>> wrote:
>> > 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
>> >>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20121011/59924859/attachment.html>


More information about the cfe-dev mailing list