[cfe-dev] Writing C++ refactoring tools in Common Lisp
Christian Schafmeister
chris.schaf at verizon.net
Tue Jan 7 09:52:27 PST 2014
On Jan 7, 2014, at 12:12 PM, Manuel Klimek <klimek at google.com> wrote:
> On Tue, Jan 7, 2014 at 5:16 PM, Christian Schafmeister <chris.schaf at verizon.net> wrote:
> Hey folks,
>
>
> I’ve written a new Common Lisp environment/compiler over the past two years.
> It uses LLVM as the back-end (by exposing the LLVM C++ library to Common Lisp) and interoperates with C++ in that it has a template library like boost::python for exposing arbitrary C++ classes/functions to Common Lisp.
>
> I want to do some automated refactoring to improve my C++ code so I’m exposing the Clang ASTMatcher and Refactoring libraries.
>
> I also think it would be really cool to write refactoring tools in a dynamic language like Lisp - without all the exhausting boilerplate required by the C++ approach.
>
> C++ refactoring tools actually don't require that much boilerplate…
Sorry, my statement sounded like a criticism - I never mean to criticize - these languages are what they are.
I was just speaking about my feelings from writing a few simple refactoring tools in C++ and my motivations for implementing a Common Lisp compiler and writing refactoring tools in Common Lisp. I’m a new convert to Common Lisp - I just discovered it two years ago and most of my experience with it is writing a self-hosting compiler.
>
> So I’m exposing the Clang AST library to this Common Lisp environment with the goal of writing a general tool for writing C++ refactoring tools in Common Lisp.
>
> My goal is to mimic C++ ASTMatchers like:
>
> recordDecl(hasDescendant(
> ifStmt(hasTrueExpression(
> expr(hasDescendant(
> ifStmt()))))))
>
> Using S-expressions: (record-decl (has-descendent (if-stmt (has-true-expression (expr (has-descendant( if-stmt)))))))
>
> And the source-to-source translation code will be small lambda functions that use the resulting MatchResults.
>
> That way I don’t have to write a lot of documentation :-).
>
> Currently I’m looking at calling the ASTMatcher/Dynamic/VariantValue interface to build ASTMatchers from S-expressions - does that sound like a good idea - or is there a better approach I should be exploring?
>
> Well, if your boost shim can already match "arbitrary C++ classes / functions", then it should in principle be able to expose the AST matchers as is (without the need to go through the dynamic parsing).
> After all, the matchers are mostly just template functions :)
I was trying to figure out how to do that at first but the ASTMatchers looked more exotic than just simple functions.
For instance “namedDecl” has the type internal::VariadicDynCastAllOfMatcher<Decl,NamedDecl>
VariadicDynCastAllOfMatcher is defined as:
template <typename SourceT, typename TargetT>
class VariadicDynCastAllOfMatcher
: public llvm::VariadicFunction<
BindableMatcher<SourceT>, Matcher<TargetT>,
makeDynCastAllOfComposite<SourceT, TargetT> > {
public:
VariadicDynCastAllOfMatcher() {}
};
llvm::VariadicFunction has many templated overloads of "operator()"
I haven’t written template code to automatically wrap variadic functions (as in functions that take … ellipses).
I can wrap functions that take ArrayRef’s though - is there a function like namedDecl(ArrayRef<ASTMatcher>) for ASTMatchers?
I’ve only been getting deep into C++ template programming for about two months so I’m still struggling with reading complex template code.
>
> Otherwise I think going the dynamic matcher route is a good approach.
>
> Cheers,
> /Manuel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140107/131027f8/attachment.html>
More information about the cfe-dev
mailing list