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

Samuel Benzaquen sbenza at google.com
Sun Jan 4 07:42:30 PST 2015


On Mon, Dec 29, 2014 at 5:22 PM, mobi phil <mobi at mobiphil.com> wrote:

> 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()
>

There is no "return" kind on a matcher because the matcher always returns
'bool'.


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

It is impossible to know the real type of the node before matching, as it
could be a subclass of what you are matching.
A DynTypedMatcher has 2 "Kinds": SupportedKind and RestrictKind.

SupportedKind is the minimum static type that the matcher accepts. This is
the argument type used in the static matcher declaration.
It is used to simulate the compile time errors you would get on the static
matchers during parsing of the dynamic matchers.
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.

RestrictKind is the minimum dynamic type that the matcher accepts. This is
used to do the type matching.
For example, recordDecl() has a RestrictKind of CXXRecordDecl because it
needs a node that is a CXXRecordDecl, hasName() has a RestrictKind of
NamedDecl.
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.

You should be able to use RestrictKind to determine the API supported by
the matched node.


>
> *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
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20150104/7b7f4eb2/attachment.html>


More information about the cfe-dev mailing list