[cfe-dev] ast matchers, structDecl, unionDecl missing? recordDecl is only for CXXRecordDecl

mobi phil mobi at mobiphil.com
Mon Dec 29 14:22:36 PST 2014


Hi,

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:

cmatch -a SemaDecl.ast \
          -m
"methodDecl(returns(pointsTo(hasDeclaration(recordDecl(isDerivedFrom(recordDecl(hasName(\"Decl\"))))))))"
\
          -r getParent.getNameAsString.dump

I will make the source code as soon as possible public.
In the source code, the methods are added/defined in some special header
files with macros in the form of.

METHOD(Decl, getDeclKindName, char)
METHOD(Decl, dump, void)
METHOD(Decl, dumpColor, void)
METHOD(NamedDecl, getNameAsString, string)
METHOD(RecordDecl, getPreviousDecl, Decl)
METHOD(RecordDecl, getMostRecentDecl, Decl)
METHOD(RecordDecl, hasVolatileMember, bool)
METHOD(FunctionDecl, getBody, Stmt)
METHOD(FunctionDecl, getDeclName, DeclarationName)
METHOD(FunctionDecl, getReturnType, QualType)
METHOD(CXXMethodDecl, getParent, Decl)

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.
The tool can also be called by zsh completion mechanism to complete the ast
expression.

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)

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:

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

Optional<DynTypedMatcher> matcher = Parser::parseMatcherExpression(
         StringRef(expr), nullptr, namedValues, &diag);

would be nice to have something like matcher->getReturnKind() similar to
matcher->getSupportedKind()

Question:
is there a way to find back this information?

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

I understand that the "narrowing matchers" like isDerivedFrom would have
return type Matcher<CXXRecordDecl> and not Matcher<Decl>.
Question: Any reason for this inconsistency?


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

Question: was this intentionally implemented so?

regards
mph
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20141229/6af8e27e/attachment.html>


More information about the cfe-dev mailing list