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

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


Yeah, I need this for a tool for my thesis (finding common stl mistakes in
code), but I can just use for example "std::_Rb_tree_const_iterator", and
mention in my thesis, the current implementation only supports one certain
STL implementation, and will be improved in the future.

But when some experimental patches are available, I will be happy to test
them out.


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

> On Thu, Oct 11, 2012 at 1:28 PM, Gábor Horváth <xazax.hun at gmail.com>
> wrote:
> > 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.
>
> Can you work around that by specifying the names it has been
> typedef'ed to for 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/116dff00/attachment.html>


More information about the cfe-dev mailing list