[cfe-dev] Writing C++ refactoring tools in Common Lisp

Samuel Benzaquen sbenza at google.com
Mon Jan 13 14:19:59 PST 2014


On Mon, Jan 13, 2014 at 3:18 PM, Christian Schafmeister
<meister at temple.edu>wrote:

> So, I managed to hack/rewrite parts of Registry.cpp, Registry.h,
> Marshaller.h and Diagnostics.h so that they work with Common Lisp Symbols
> and Conses.
> I can now assemble ASTMatchers from s-expressions.
> I exposed the entire ASTMatcher interface in one go - so I can write any
> ASTMatcher using S-expressions that can be written with the C++ DSL.
>
> Using the C++ DSL you would use:
>
> fieldDecl(hasType(recordDecl(isDerivedFrom(recordDecl(hasName(“GCObject”)))))).bind(“all”)
>
> In Common Lisp I would use:
> (:bind :all (:field-decl (:has-type (:record-decl (:is-derived-from
> (:record-decl (:has-name "GCObject"))))))))
>
>
> Question:
>
> How do you get proficient at writing these matchers?   I still struggle
> with it.
>

In theory, they should read as english (with some bad grammar =P).
In your example, it reads as:
"A <fieldDecl> that a <hasType> that is a <recordDecl> which
<isDerivedFrom> ..."
In my experience, the hardest part is figuring out which matchers to use
(which basically requires knowing about them), not how to assemble them.

Do you have some way of looking at the AST dumps and then inverting them in
> your head into queries?
>

I don't see what you mean by inverting.
There are two types of matchers: filters and traversal.
The filters check properties on the nodes, like "hasName()".
The traversal matchers help you reach other nodes in the AST, like
"hasType()".

There are various trees that are interconnected; expressions, declarations
and types. Matchers allow you to go from one to the other.
Eg. you can go from an expression (like &a->foo) to its type, from a type
to some expression (like getting the initializer for a member field), etc.
In each tree you can also go up and down the hierarchies. Eg. you can go
from Foo[] type to Foo, or from "1+foo->bar()" to "1" and "foo->bar()".


> I’ll build something like the “clang-query” tool and practice.
>
> I’m going to expose the refactoring classes/functions next and try some
> interactive source-to-source translation of C++ in Common Lisp.
>
> Best,
>
> .Chris.
>
>
>
>
>
>
> On Jan 9, 2014, at 6:16 PM, Christian Schafmeister <meister at temple.edu>
> wrote:
>
>
> On Jan 9, 2014, at 5:41 PM, Samuel Benzaquen <sbenza at google.com> wrote:
>
>
>
>
> On Wed, Jan 8, 2014 at 2:44 AM, Manuel Klimek <klimek at google.com> wrote:
>
>> +Sam, who has written the dynamic registry stuff for ideas...
>>
>>
>> On Tue, Jan 7, 2014 at 7:50 PM, Christian Schafmeister <
>> chris.schaf at verizon.net> wrote:
>>
>
> Most of them are simple functions, but there are also a lot that are
> "polymorphic". That is, they return a proxy type that allows late binding
> of the real matcher type.
> During the implementation of the dynamic matcher registry I changed all
> these polymorphic/adaptative types to provide extra type information that
> allowed the registry to instantiate all the required functions.
>
> What about this?
> Instead of wrapping the actual matchers the way it is done in C++, you
> could make meta matchers that really only know their name and their
> arguments.
> Basically all matchers would be functions that return an object that has a
> name() method and a list of their arguments.
> Then you can generate the C++ matcher string and use the C++ matcher
> parser to generate the actual matcher.
> This way you only wrap a few [simple] functions from C++ and are shielded
> from the template metaprogramming craziness.
> Hadn't thought this through, so it might be too simple to work =P.
>
>
> I think I solved the problem by hacking the Registry.cpp, Registry.h,
> Marshaller.h and Diagnostics.h files to deal with Symbols and Conses.  I
> can now assemble ASTMatchers from s-expressions.
>
> However, when I upgraded to the TOT LLVM/CLANG build to get access to the
> MatchFinder::addDynamicMatcher function all hell broke loose with my
> exception handling code.
>
> For some reason the TOT LLVM/CLANG build is hiding my RTTI typeinfo for
> some exception classes that I define in my executable and need to catch in
> my generated code (loaded from bitcode files).
>
> I’ll post a question about this to the group shortly.
>
>
>
>
> _Sam
>
>
>>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140113/c2e6c349/attachment.html>


More information about the cfe-dev mailing list