<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Dec 29, 2014 at 5:22 PM, mobi phil <span dir="ltr"><<a href="mailto:mobi@mobiphil.com" target="_blank" class="cremed">mobi@mobiphil.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Hi,</div><div><br></div><div>I came across some problems I will describe below while I was designing/implementing some new libclang functions. These functions are a C interface (and interface for scripting languages) to query ast with text based matchers. On top of these functions I also wrote a tool that can query ast with matchers and can call a chain of methods on the retrived Ast nodes, like: </div><div><br></div><div>cmatch -a SemaDecl.ast \ <br></div><div><div>          -m "methodDecl(returns(pointsTo(hasDeclaration(recordDecl(isDerivedFrom(recordDecl(hasName(\"Decl\"))))))))" \</div><div>          -r getParent.getNameAsString.dump</div></div><div><br></div><div>I will make the source code as soon as possible public.</div><div>In the source code, the methods are added/defined in some special header files with macros in the form of.<br></div><div><div><br></div><div>METHOD(Decl, getDeclKindName, char)</div><div>METHOD(Decl, dump, void)</div><div>METHOD(Decl, dumpColor, void)</div><div>METHOD(NamedDecl, getNameAsString, string)<br></div><div>METHOD(RecordDecl, getPreviousDecl, Decl)<br></div><div>METHOD(RecordDecl, getMostRecentDecl, Decl)</div><div>METHOD(RecordDecl, hasVolatileMember, bool)</div><div>METHOD(FunctionDecl, getBody, Stmt)<br></div><div>METHOD(FunctionDecl, getDeclName, DeclarationName)</div><div>METHOD(FunctionDecl, getReturnType, QualType)</div><div>METHOD(CXXMethodDecl, getParent, Decl)<br></div><div><br></div></div><div>Will need to generate (also with matchers) the full list of "usable" methods in form of such declarations that can be compiled into my library. </div><div>The tool can also be called by zsh completion mechanism to complete the ast expression.</div><div><br></div><div>The above functionality is implemented, I can add almost all methods that have void parameters to all subclasses of Decl, Stmt, Type and some POD kind structures. (SourceLocation, QualType, etc)</div><div><br></div><div>The next feature I wanted to add is shell completion mechanism for the chain of methods that can be called on the matched ast nodes. Unfortunately I bumped into the following little annoyances:</div><div><br></div><div><b>1.a it is impossible to deduce the "inner" type that will be returned by a matcher, so that I can deduce the list of methods. </b></div><div><b><br></b></div><div>Optional<DynTypedMatcher> matcher = Parser::parseMatcherExpression(<br></div><div><div><div>         StringRef(expr), nullptr, namedValues, &diag);</div><div><br></div></div><div>would be nice to have something like matcher->getReturnKind() similar to matcher->getSupportedKind()</div></div></div></blockquote><div><br></div><div>There is no "return" kind on a matcher because the matcher always returns 'bool'.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><br></div><div>Question:<br></div><div>is there a way to find back this information?</div></div></div></blockquote><div><br></div><div>It is impossible to know the real type of the node before matching, as it could be a subclass of what you are matching.</div><div>A DynTypedMatcher has 2 "Kinds": SupportedKind and RestrictKind.</div><div><br></div><div>SupportedKind is the minimum static type that the matcher accepts. This is the argument type used in the static matcher declaration.</div><div>It is used to simulate the compile time errors you would get on the static matchers during parsing of the dynamic matchers.</div><div>For example, recordDecl() has a SupportedKind of Decl because it takes any Decl node to check if it is a CXXRecordDecl, hasName() has a SupportedKind of NamedDecl.</div><div><br></div><div>RestrictKind is the minimum dynamic type that the matcher accepts. This is used to do the type matching.</div><div>For example, recordDecl() has a RestrictKind of CXXRecordDecl because it needs a node that is a CXXRecordDecl, hasName() has a RestrictKind of NamedDecl.</div><div>There are some optimizations on the dynamic matcher creation that propagates and combines the RestrictKind to reject values earlier. RestrictKind has to be the same or a subclass of SupportedKind.</div><div><br></div><div>You should be able to use RestrictKind to determine the API supported by the matched node.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><br></div><div><b>1.b there is some information about the return type, but that is in case of recordDecl for instance is Matcher<Decl>,  and not Matcher<RecordDecl></b></div><div><br></div><div>I understand that the "narrowing matchers" like isDerivedFrom would have return type Matcher<CXXRecordDecl> and not Matcher<Decl>. </div><div>Question: Any reason for this inconsistency? </div></div></div></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><br></div><div><br></div><div><b>2. delving more into the source code to find out 1.b (and tested) I found that recordDecl matches only CXXRecordDecl, thus for C programs one cannot match-find structures/unions.</b></div><div><br></div><div>Question: was this intentionally implemented so? </div><div><br></div><div>regards</div><div>mph</div>
</div></div>
<br>_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@cs.uiuc.edu" class="cremed">cfe-dev@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank" class="cremed">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a><br>
<br></blockquote></div><br></div></div>