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 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, and not Matcher
I understand that the “narrowing matchers” like isDerivedFrom would have return type Matcher and not Matcher.
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