[cfe-dev] Matching std::set::iterator
Gábor Horváth
xazax.hun at gmail.com
Thu Oct 11 02:05:25 PDT 2012
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?
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
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20121011/d66e4954/attachment.html>
More information about the cfe-dev
mailing list