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

Daniel Jasper djasper at google.com
Thu Oct 11 03:03:00 PDT 2012


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.

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