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

Manuel Klimek klimek at google.com
Thu Oct 11 05:32:28 PDT 2012


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
>>> >>
>>
>>
>




More information about the cfe-dev mailing list