<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body><div>Hi Jordan,<br></div>
<div> </div>
<div>The motivation was to be able to seamlessly use e.g. the hasName() matcher inside the containerDecl() matcher, but having to go through one additional matcher - wrappedNamedDecl() - is not really an issue. I also thought that the AST matchers would only work for AST types, but apparently I was wrong.<br></div>
<div> </div>
<div>So I've rewritten the code so that ContainerDeclWrapper is only a wrapper around a NamedDecl, but doesn't inherit from it.<br></div>
<div>Thanks for your input!<br></div>
<div> </div>
<div id="sig19426269"><div class="signature">-- <br></div>
<div class="signature"> Gábor Kozár -- ShdNx<br></div>
<div class="signature"> kozargabor@gmail.com<br></div>
<div class="signature"> </div>
</div>
<div> </div>
<div> </div>
<div>On Wed, Oct 2, 2013, at 3:21, Jordan Rose wrote:<br></div>
<blockquote type="cite"><div>Hi, Gábor. I don't think this is the right approach. The AST is supposed to be completely fixed by the time it reaches the analyzer (except for synthesized functions generated with BodyFarm). I get that it's convenient to have these accessors, but I think it's better to use them as helper functions or a wrapper struct after you've matched an appropriate NamedDecl (or actually ValueDecl, probably).<br></div>
<div> </div>
<div>AST_MATCHER_P(ValueDecl, containerDecl, ContainerDeclMatcher, innerMatcher)<br></div>
<div>{<br></div>
<div> if (!isContainer(containerDecl))<br></div>
<div> return false;<br></div>
<div> return innerMatcher.matches(*containerDecl, Finder, Builder);<br></div>
<div>}<br></div>
<div> </div>
<div>assert(isContainer(result));<br></div>
<div>ContainerWrapper w(result);<br></div>
<div> </div>
<div>What was your motivation for using a custom subclass of NamedDecl in the first place?<br></div>
<div>Jordan<br></div>
<div> </div>
<div> </div>
<div><div>On Sep 30, 2013, at 10:18 , Gabor Kozar <<a href="mailto:kozargabor@gmail.com">kozargabor@gmail.com</a>> wrote:<br></div>
<div> </div>
<blockquote type="cite"><div><div>Hi,<br></div>
<div> </div>
<div>(Note: all of the code shown below is incomplete and totally untested - not even sure if it compiles.)<br></div>
<div> </div>
<div>I am developing a Static Analyzer plug-in for Clang 3.3. I have created a class like this:<br></div>
<div> </div>
<blockquote><div>class ContainerDecl : public NamedDecl<br></div>
<div>{<br></div>
<div>public:<br></div>
<div> static bool classof(const Decl* decl);<br></div>
<div> </div>
<div> static bool isContainerDecl(const NamedDecl* decl);<br></div>
<div> static const ContainerDecl* tryCreateFrom(const NamedDecl* decl);<br></div>
<div> </div>
<div> const NamedDecl* getWrappedDecl() const;<br></div>
<div> bool isValidContainer() const;<br></div>
<div> </div>
<div> QualType getIteratorType() const;<br></div>
<div> QualType getItemValueType() const;<br></div>
<div> </div>
<div>protected:<br></div>
<div> ContainerDecl(const NamedDecl* decl);<br></div>
<div> </div>
<div>private:<br></div>
<div> ...<br></div>
<div>};<br></div>
</blockquote><div> </div>
<div>As you can see, this is basically a wrapper around a NamedDecl, and provides convenience methods for getting information about the container the NamedDecl describes.<br></div>
<div> </div>
<div>The motivation comes from writing numerous Static Analyzer checkers for STL containers, and these usually utilize AST matchers. I want to be able to write a matcher expression like this:<br></div>
<div> </div>
<blockquote><div>containerDecl(hasItemValueType(hasDeclaration(namedDecl(hasName("std::auto_ptr")))))<br></div>
</blockquote><div> </div>
<div>... in order to detect issues with the now-depracted std::auto_ptr-s being put in a container, and then e.g. std::sort()-ed. (This is not a complete matcher expression of course.)<br></div>
<div> </div>
<div>With the above class, it is quite easy to do this:<br></div>
<div> </div>
<blockquote><div>typedef internal::Matcher<ContainerDecl> ContainerDeclMatcher;<br></div>
<div> </div>
<div>AST_MATCHER_P(NamedDecl, containerDecl, ContainerDeclMatcher, innerMatcher)<br></div>
<div>{<br></div>
<div> // TODO: lifetime management? if we don't need the containerDecl any longer, we should delete it<br></div>
<div> const ContainerDecl* containerDecl = ContainerDecl::tryCreateFrom(&Node);<br></div>
<div> if(!containerDecl) return false;<br></div>
<div> </div>
<div> return innerMatcher.matches(*containerDecl, Finder, Builder);<br></div>
<div>}<br></div>
<div> </div>
<div>AST_MATCHER_P(ContainerDecl, hasItemValueType, TypeMatcher, innerMatcher)<br></div>
<div>{<br></div>
<div> return innerMatcher.matches(Node.getItemValueType(), Finder, Builder);<br></div>
<div>}<br></div>
<div> </div>
<div>AST_MATCHER_P(ContainerDecl, hasIteratorType, TypeMatcher, innerMatcher)<br></div>
<div>{<br></div>
<div> return innerMatcher.matches(Node.getIteratorType(), Finder, Builder);<br></div>
<div>}<br></div>
</blockquote><div> </div>
<div>What I am not sure about, is how to handle the lifetime of a ContainerDecl, since this isn't strictly part of Clang's AST - it is just basically a wrapper around a NamedDecl. ContainerDecl objects in general will be short-lived, compared to e.g. the NamedDecl objects they wrap.<br></div>
<div> </div>
<div>I noticed that there is ASTContext::Allocate and Deallocate, but I am not sure whether I should use it. Thoughts on this?<br></div>
<div> </div>
<div>I am also not entirely happy about having to inherit from NamedDecl, but otherwise - as far as I know - I cannot implement the above matchers. Is this even the correct approach?<br></div>
<div> </div>
<div>The other problem is making ContainerDecl play well with llvm::dyn_cast and the like. Right now I have the following implementation for ContainerDecl::classof:<br></div>
<div> </div>
<blockquote><div>static bool ContainerDecl::classof(const Decl* decl)<br></div>
<div>{<br></div>
<div> return NamedDecl::classof(decl) && isContainerDecl(static_cast<const NamedDecl*>(decl));<br></div>
<div>}<br></div>
</blockquote><div> </div>
<div>Is this correct?<br></div>
<div> </div>
<div>Also, do you think this is something that could be integrated into Clang at some point? I'd happy to contribute the code once it is working, and my boss agrees to have this code open-sourced.<br></div>
<div> </div>
<div>Thanks!<br></div>
<div> </div>
<div><div>-- <br></div>
<div> Gábor Kozár -- ShdNx<br></div>
<div> <a href="mailto:kozargabor@gmail.com">kozargabor@gmail.com</a><br></div>
<div> </div>
</div>
</div>
<div>
_______________________________________________<br></div>
<div>cfe-dev mailing list<br></div>
<div><a href="mailto:cfe-dev@cs.uiuc.edu">cfe-dev@cs.uiuc.edu</a><br></div>
<div>http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev<br></div>
</blockquote></div>
<div> </div>
<div> </div>
</blockquote></body>
</html>