[cfe-dev] For loop conversion (was: C++11 migration tools)

Sam Panzer panzer at google.com
Fri Jul 13 13:54:23 PDT 2012


On Thu, Jul 12, 2012 at 11:07 PM, Manuel Klimek <klimek at google.com> wrote:

>
> On Thu, Jul 12, 2012 at 11:59 PM, Sam Panzer <panzer at google.com> wrote:
> > I accidentally sent the email before I was done (the Gmail tab/space
> combo
> > strikes again), and you replied before I finished fixing the original :)
> >
> > On Thu, Jul 12, 2012 at 2:37 PM, Manuel Klimek <klimek at google.com>
> wrote:
> >>
> >> On Thu, Jul 12, 2012 at 11:31 PM, Sam Panzer <panzer at google.com> wrote:
> >>>
> >>> Here are three kinds of operations that I would want to completely
> avoid
> >>> any kind of recursive AST traversal:
> >>>  - Optional matchers: In order to ignore certain ignorable parts of the
> >>> AST, I often want to create
> >>
> >>
> >> Is there something missing?
> >
> >
> > The missing part of optional matchers: I'm just wondering if a shorthand
> > would be reasonable to implement. instead of something like
> >   anyOf(unaryOperator(hasOperand(SomeOtherMatcher)), SomeOtherMatcher)
> > One could use
> >   optional(unaryOperator(hasOperand), SomeOtherMatcher)
>
> And we arrive at where the problem is with something that looks like a
> functional language but doesn't have a really nice way to express
> higher order functions without lots of syntactical crap around it.
>
> But it also doesn't strike me as so bad to repeat SomeOtherMatcher in
> there...
>

I was just curious if this was possible, though I didn't expect it to be.
It would only have been really useful when combined with the recursion
request.


>
> >>>  - Right-recursive matchers:
> >>>
> >>>   I have a function that hunts for the expression which is actually
> >>> passed to a single-parameter constructor, which sheds
> ImplicitCastExprs,
> >>> single-parameter CXXConstructExprs, and MaterializeTemporaryExprs
> until it
> >>> finds something that is not a single-parameter constructor.
> Essentially, the
> >>> matcher would look like
> >>>   StmtMatcher =
> >>>
> expression(rightRecursion(ignoreImplicitCasts(constructorCall(argumentCountIs(1),
> >>> hasArgument(0, optional(materializeTemporaryExpr(RecursionPoint))),
> >>> withBaseCase(id(expresion))))
> >>
> >>
> >> hasDescendant / forEachDescendant doesn't work?
> >
> >
> > I am trying to enforce a particular structure on the way to those
> > descendants - I only want to match the innermost expression if the AST
> was a
> > linear chain of these particular kinds of node, and
> {has,forEach}Descendant
> > throws this information away. If I'm wrong, that would be great!
>
> hasDescendant will match at the first occurrence in tree-search order
> (RecursiveASTVisitor order)
>
>
I think the difficulty here is matching against a recurring pattern. In
some sense, what I'm really looking for is the first descendant that
doesn't match. To make this as explicit as possible, my current code looks
like this:

const Expr *digThroughConstructors(const Expr *E) {
  if (!E)
    return NULL;
  E = E->IgnoreParenCasts();
  if (const CXXConstructExpr *ConstructExpr =
dyn_cast<CXXConstructExpr>(E)) {
    if (ConstructExpr->getNumArgs() != 1)
      return NULL;
    E = ConstructExpr->getArg(0);
    if (const MaterializeTemporaryExpr *MTE
= dyn_cast<MaterializeTemporaryExpr>(E))
      E = MTE->GetTemporaryExpr();
    return digThroughConstructors(E);
  }
  return E;
}

It's short enough that I don't mind leaving it as its own separate check.
Thanks again for taking the time to help me with this!

-Sam


> Cheers,
> /Manuel
>
> >>>  - The ability to run the equivalent of a MatchFinder on an arbitrary
> AST
> >>> (e.g. in the callback of another matcher)
> >>
> >>
> >> That shouldn't be too hard to implement.
> >
> >
> > Excellent!
> >
> > Thanks,
> > -Sam
> >
> >>
> >>
> >>>
> >>>
> >>>
> >>> On Thu, Jul 12, 2012 at 1:06 AM, Manuel Klimek <klimek at google.com>
> wrote:
> >>>>
> >>>> On Wed, Jul 11, 2012 at 11:17 PM, Sam Panzer <panzer at google.com>
> wrote:
> >>>> >
> >>>> >
> >>>> >
> >>>> > On Wed, Jul 11, 2012 at 11:20 AM, Manuel Klimek <klimek at google.com>
> >>>> > wrote:
> >>>> >>
> >>>> >> On Wed, Jul 11, 2012 at 8:08 PM, Sam Panzer <panzer at google.com>
> >>>> >> wrote:
> >>>> >> > Good point. I currently have a matcher that finds for loops that
> >>>> >> > appear
> >>>> >> > to
> >>>> >> > have the right shape for conversion, and I do some extra checking
> >>>> >> > along
> >>>> >> > with
> >>>> >> > the conversion work in the callback. I can completely handle
> >>>> >> > array-style
> >>>> >> > loops with a Preprocessor, which is used when generating the
> names
> >>>> >> > of
> >>>> >> > new
> >>>> >>
> >>>> >> I don't understand yet what the Preprocessor is needed for here...
> >>>> >
> >>>> >
> >>>> > I use Preprocessor in exactly one place right now, namely to create
> an
> >>>> > IdentifierResolver. When I am generating the name of a new loop
> >>>> > variable, I
> >>>> > want to make sure that the identifier is unique, which is an
> >>>> > approximation
> >>>> > to checking that the identifier neither shadows an existing
> definition
> >>>> > nor
> >>>> > is shadowed in an inner scope. If there's a better way to do this, I
> >>>> > would
> >>>> > be happy to change it.
> >>>>
> >>>> The ASTContext has the identifier table. (ASTContext::Idents).
> >>>>
> >>>> >> > variables. For iterator-style loops, I use Sema to determine the
> >>>> >> > return
> >>>> >> > type
> >>>> >> > of operator*, which will be the type of the loop variable.
> Finally
> >>>> >> > (though
> >>>> >>
> >>>> >> Isn't the return type of the oeprator* already in the AST?
> >>>> >
> >>>> >
> >>>> > It's actually possible that operator* is never called. My initial
> >>>> > implementation tried to infer the type from  expressions involving
> the
> >>>> > iterator, but this didn't work correctly for CXXMemberCallExpr. I
> can
> >>>> > conceivably work around this without checking operator*, but
> >>>>
> >>>> did you want to finish that
> >>>>
> >>>> >> > this isn't implemented yet), containers that are used as if
> they're
> >>>> >> > arrays
> >>>> >> > will require Sema to check if suitable begin() and end()
> functions
> >>>> >> > exist.
> >>>> >>
> >>>> >> Ah, I see - basically you want to trigger overload resolution to
> see
> >>>> >> whether the conversion would work. That makes sense. I'm not sure
> we
> >>>> >> want to get all of Sema available though - it's an insanely huge
> >>>> >> interface, and it's rather hard to figure out what's safe to do and
> >>>> >> what's not.
> >>>> >>
> >>>> >> Perhaps we can create a class that encapsulates Sema for those
> >>>> >> "what-if" type questions we'll need to answer for refactoring
> tools?
> >>>> >
> >>>> >
> >>>> > This sounds like a good idea. I can try to identify exactly the
> >>>> > features I
> >>>> > need (most likely just overload resolution).
> >>>>
> >>>> That would sound like most of what we need. It has come up a few
> >>>> times. Let me know if you identify more things we need.
> >>>>
> >>>> Cheers,
> >>>> /Manuel
> >>>>
> >>>> >
> >>>> >>
> >>>> >>
> >>>> >> > For now, I can force the use of auto rather than an explicit type
> >>>> >> > listing
> >>>> >> > for iterator-based loops and get most of the work done without
> >>>> >> > Sema. The
> >>>> >> > question then becomes the correct way to avoid repeatedly
> creating
> >>>> >> > a
> >>>> >> > Preprocessor object, though if this is a cheap operation, I can
> >>>> >> > create
> >>>> >> > one
> >>>> >> > in the callback.
> >>>> >> >
> >>>> >> > Does this make the use clearer?
> >>>> >>
> >>>> >> Yep, thx.
> >>>> >>
> >>>> >> Cheers,
> >>>> >> /Manuel
> >>>> >>
> >>>> >> > Thanks!
> >>>> >> >
> >>>> >> >
> >>>> >> > On Wed, Jul 11, 2012 at 12:29 AM, Manuel Klimek <
> klimek at google.com>
> >>>> >> > wrote:
> >>>> >> >>
> >>>> >> >> On Wed, Jul 11, 2012 at 6:03 AM, Sam Panzer <panzer at google.com>
> >>>> >> >> wrote:
> >>>> >> >> > I'm trying to port my code to take advantage of matchers, now
> >>>> >> >> > that
> >>>> >> >> > they
> >>>> >> >> > are
> >>>> >> >> > in mainline. Some of the work I want to do involves semantic
> >>>> >> >> > analysis
> >>>> >> >> > of
> >>>> >> >> > the
> >>>> >> >> > results (i.e. in the callback). What would be the best way to
> >>>> >> >> > get a
> >>>> >> >> > Sema
> >>>> >> >> > or
> >>>> >> >> > CompilerInstance out of either RefactoringTool or MatchResult?
> >>>> >> >> > I'm
> >>>> >> >> > currently
> >>>> >> >> > playing with changing MatchASTConsumer to inherit from
> >>>> >> >> > SemaConsumer,
> >>>> >> >> > so
> >>>> >> >> > that
> >>>> >> >> > MatchFinder can track a Sema object the same way it does an
> >>>> >> >> > ASTContext.
> >>>> >> >>
> >>>> >> >> I'd be interested in what the use cases for the semantic
> analysis
> >>>> >> >> are
> >>>> >> >> first. Often it seems like it would be better to have the
> >>>> >> >> information
> >>>> >> >> available in the AST instead of rerunning (potentially
> expensive)
> >>>> >> >> semantic analysis.
> >>>> >> >>
> >>>> >> >> Cheers,
> >>>> >> >> /Manuel
> >>>> >> >>
> >>>> >> >> >
> >>>> >> >> > Thanks!
> >>>> >> >> >
> >>>> >> >> >
> >>>> >> >> > On Mon, Jul 2, 2012 at 7:22 AM, Manuel Klimek
> >>>> >> >> > <klimek at google.com>
> >>>> >> >> > wrote:
> >>>> >> >> >>
> >>>> >> >> >> On Mon, Jul 2, 2012 at 4:16 PM, Sam Panzer <
> panzer at google.com>
> >>>> >> >> >> wrote:
> >>>> >> >> >>>
> >>>> >> >> >>> On Sun, Jul 1, 2012 at 10:45 PM, Manuel Klimek
> >>>> >> >> >>> <klimek at google.com>
> >>>> >> >> >>> wrote:
> >>>> >> >> >>>>
> >>>> >> >> >>>> On Fri, Jun 29, 2012 at 8:17 PM, Sam Panzer
> >>>> >> >> >>>> <panzer at google.com>
> >>>> >> >> >>>> wrote:
> >>>> >> >> >>>>>
> >>>> >> >> >>>>> Thanks for the input!
> >>>> >> >> >>>>>
> >>>> >> >> >>>>> Tooling/Refactoring is definitely the right way to go -
> >>>> >> >> >>>>> dumping
> >>>> >> >> >>>>> to
> >>>> >> >> >>>>> stdout was just a holdover from the example on LibTooling.
> >>>> >> >> >>>>> I'll
> >>>> >> >> >>>>> change it
> >>>> >> >> >>>>> once I figure out how it works - and a clean way to
> arrange
> >>>> >> >> >>>>> the
> >>>> >> >> >>>>> tests.
> >>>> >> >> >>>>>
> >>>> >> >> >>>>> As for the use of matchers vs. visitors, I decided to use
> a
> >>>> >> >> >>>>> visitor
> >>>> >> >> >>>>> because this is a relatively complex transformation. I
> would
> >>>> >> >> >>>>> happily
> >>>> >> >> >>>>> use
> >>>> >> >> >>>>> matchers if I thought I could - and I think that some
> other
> >>>> >> >> >>>>> c++11
> >>>> >> >> >>>>> migrations
> >>>> >> >> >>>>> can easily be written with matchers - but I think the for
> >>>> >> >> >>>>> loop
> >>>> >> >> >>>>
> >>>> >> >> >>>>
> >>>> >> >> >>>> I'm not claiming that the matchers needed to match those
> >>>> >> >> >>>> constructs
> >>>> >> >> >>>> are
> >>>> >> >> >>>> all already written - but if we write the questions you
> need
> >>>> >> >> >>>> to
> >>>> >> >> >>>> ask
> >>>> >> >> >>>> into
> >>>> >> >> >>>> matchers, other people who want to match similar things can
> >>>> >> >> >>>> reuse
> >>>> >> >> >>>> them, thus
> >>>> >> >> >>>> amplifying the impact of the code you write ;)
> >>>> >> >> >>>>
> >>>> >> >> >>>>>
> >>>> >> >> >>>>> checks need some features that matchers don't have
> (correct
> >>>> >> >> >>>>> me if
> >>>> >> >> >>>>> I'm
> >>>> >> >> >>>>> wrong!). For example, the check for statically allocated
> >>>> >> >> >>>>> array-based
> >>>> >> >> >>>>> loops
> >>>> >> >> >>>>> does this:
> >>>> >> >> >>>>> Given a for loop, determine if:
> >>>> >> >> >>>>>  - The increment statement increments (via ++) exactly one
> >>>> >> >> >>>>> integral
> >>>> >> >> >>>>> index variable, such that the variable is declared and
> >>>> >> >> >>>>> initialized
> >>>> >> >> >>>>> to zero
> >>>> >> >> >>>>> in the init portion of the loop, and that this variable's
> >>>> >> >> >>>>> value
> >>>> >> >> >>>>> is a
> >>>> >> >> >>>>> compared (via <, > or !=) to a nonnegative compile-time
> >>>> >> >> >>>>> constant
> >>>> >> >> >>>>> N
> >>>> >> >> >>>>> in the
> >>>> >> >> >>>>> compare portion.
> >>>> >> >> >>>>>  - The index variable is only ever used in an
> >>>> >> >> >>>>> ArrayIndexExpession
> >>>> >> >> >>>>> indexing a single, statically allocated array A.
> >>>> >> >> >>>>>  - The array A has exactly N elements.
> >>>> >> >> >>>>>  - Additionally, if the ArrayIndexExpression A[index] is
> >>>> >> >> >>>>> ever
> >>>> >> >> >>>>> assigned,
> >>>> >> >> >>>>> passed to a function or copied as a non-const reference,
> or
> >>>> >> >> >>>>> its
> >>>> >> >> >>>>> address
> >>>> >> >> >>>>> taken with & (I still need to add a check for calls to
> >>>> >> >> >>>>> non-const
> >>>> >> >> >>>>> member
> >>>> >> >> >>>>> functions), the loop variable in the converted version
> needs
> >>>> >> >> >>>>> to
> >>>> >> >> >>>>> be a
> >>>> >> >> >>>>> non-const reference so that the value will be correctly
> >>>> >> >> >>>>> updated
> >>>> >> >> >>>>> (this step
> >>>> >> >> >>>>> adds the most complexity).
> >>>> >> >> >>>>
> >>>> >> >> >>>>
> >>>> >> >> >>>> ... and the matcher I would want to write for this looks
> >>>> >> >> >>>> something
> >>>> >> >> >>>> like
> >>>> >> >> >>>> that:
> >>>> >> >> >>>> ForLoop(
> >>>> >> >> >>>>   HasInitialization(Declaration(Id("loopvar",
> >>>> >> >> >>>> HasType(IsIntegral())))),
> >>>> >> >> >>>>   HasCondition(BinaryOperator(
> >>>> >> >> >>>>     HasAnyOperand(DeclarationReference(Id("condref",
> >>>> >> >> >>>> To(Variable())))),
> >>>> >> >> >>>>     HasAnyOperand(IntegerLiteral()))),
> >>>> >> >> >>>>
> >>>> >> >> >>>>
> >>>> >> >> >>>>
> >>>> >> >> >>>>
> >>>> >> >> >>>>
> HasIncrement(UnaryOperator(HasUnaryOperand(DeclarationReference(Id("incref",
> >>>> >> >> >>>> To(Variable()))))), ...),
> >>>> >> >> >>>> )
> >>>> >> >> >>>>
> >>>> >> >> >>>> In general, the complex stuff can stay complex, but the
> >>>> >> >> >>>> simple
> >>>> >> >> >>>> stuff
> >>>> >> >> >>>> shouldn't be lots of code.
> >>>> >> >> >>>
> >>>> >> >> >>>
> >>>> >> >> >>> Good point - and this is much easier to read than the
> >>>> >> >> >>> equivalent
> >>>> >> >> >>> code
> >>>> >> >> >>> I
> >>>> >> >> >>> had written.
> >>>> >> >> >>>
> >>>> >> >> >>>>
> >>>> >> >> >>>>
> >>>> >> >> >>>>>
> >>>> >> >> >>>>> The other types of loop (iterator-based, and array-like
> >>>> >> >> >>>>> container)
> >>>> >> >> >>>>> are
> >>>> >> >> >>>>> more complicated to detect, since there are more permitted
> >>>> >> >> >>>>> ways
> >>>> >> >> >>>>> to
> >>>> >> >> >>>>> define
> >>>> >> >> >>>>> and use the index/iterators. What makes this difficult to
> do
> >>>> >> >> >>>>> entirely with
> >>>> >> >> >>>>> matchers is the number of back- and cross-references, as
> >>>> >> >> >>>>> well as
> >>>> >> >> >>>>> the
> >>>> >> >> >>>>> different local behaviors based on semantic properties. On
> >>>> >> >> >>>>> the
> >>>> >> >> >>>>> other
> >>>> >> >> >>>>> hand,
> >>>> >> >> >>>>> if there were some kind of backreference-enabled matcher
> >>>> >> >> >>>>> that
> >>>> >> >> >>>>
> >>>> >> >> >>>>
> >>>> >> >> >>>> The way to handle the back-refs is to bind the nodes you
> >>>> >> >> >>>> want, and
> >>>> >> >> >>>> then
> >>>> >> >> >>>> pull them out and compare them in the callback.
> >>>> >> >> >>>
> >>>> >> >> >>>
> >>>> >> >> >>> I see - make the matcher slightly more general, then filter
> >>>> >> >> >>> the
> >>>> >> >> >>> results,
> >>>> >> >> >>> perhaps with a visitor.
> >>>> >> >> >>>
> >>>> >> >> >>>>
> >>>> >> >> >>>>
> >>>> >> >> >>>> Thoughts?
> >>>> >> >> >>>> /Manuel
> >>>> >> >> >>>
> >>>> >> >> >>>
> >>>> >> >> >>> This sounds like it would make at least half the work much
> >>>> >> >> >>> easier,
> >>>> >> >> >>> so
> >>>> >> >> >>> I
> >>>> >> >> >>> think it would definitely be worth it to try switching to a
> >>>> >> >> >>> matcher-based
> >>>> >> >> >>> solution. When are matchers supposed to hit mainline (or
> some
> >>>> >> >> >>> extra
> >>>> >> >> >>> cloneable repo) :) ?
> >>>> >> >> >>
> >>>> >> >> >>
> >>>> >> >> >> Matchers are currently in
> >>>> >> >> >> ^cfe/branches/tooling/include/clang/ASTMatchers/...
> >>>> >> >> >>
> >>>> >> >> >> I'm currently working on renaming them to camelCase from
> >>>> >> >> >> CamelCase;
> >>>> >> >> >> there's a Tool to help with the conversion though, so no
> >>>> >> >> >> problem in
> >>>> >> >> >> starting
> >>>> >> >> >> now ...
> >>>> >> >> >>
> >>>> >> >> >> Cheers,
> >>>> >> >> >> /Manuel
> >>>> >> >> >>
> >>>> >> >> >>>
> >>>> >> >> >>>
> >>>> >> >> >>> -Sam
> >>>> >> >> >>>
> >>>> >> >> >>>>
> >>>> >> >> >>>>
> >>>> >> >> >>>>>
> >>>> >> >> >>>>> allowed me to locate all matches in a given Stmt, it could
> >>>> >> >> >>>>> be
> >>>> >> >> >>>>> *much*
> >>>> >> >> >>>>> easier to express some parts of the logic, such as the
> first
> >>>> >> >> >>>>> step
> >>>> >> >> >>>>> in
> >>>> >> >> >>>>> the
> >>>> >> >> >>>>> above list. I also suspect that a single-Stmt matcher
> would
> >>>> >> >> >>>>> better
> >>>> >> >> >>>>> way to
> >>>> >> >> >>>>> handle the last step; currently I track  whether the
> visitor
> >>>> >> >> >>>>> is
> >>>> >> >> >>>>> looking at a
> >>>> >> >> >>>>> statement or expression which fits any of the
> >>>> >> >> >>>>> const-disqualifying
> >>>> >> >> >>>>> conditions, and a note is made if I run into A[index].
> >>>> >> >> >>>>>
> >>>> >> >> >>>>> Does this make the use case clearer? I don't really see a
> >>>> >> >> >>>>> better
> >>>> >> >> >>>>> way
> >>>> >> >> >>>>> to
> >>>> >> >> >>>>> approach this problem, but you guys know the available
> >>>> >> >> >>>>> toolkit
> >>>> >> >> >>>>> far
> >>>> >> >> >>>>> better
> >>>> >> >> >>>>> than I do.
> >>>> >> >> >>>>>
> >>>> >> >> >>>>> On Fri, Jun 29, 2012 at 2:48 AM, Manuel Klimek
> >>>> >> >> >>>>> <klimek at google.com>
> >>>> >> >> >>>>> wrote:
> >>>> >> >> >>>>>>
> >>>> >> >> >>>>>> On Fri, Jun 29, 2012 at 11:45 AM, Chandler Carruth
> >>>> >> >> >>>>>> <chandlerc at google.com> wrote:
> >>>> >> >> >>>>>>>
> >>>> >> >> >>>>>>> I tend to agree that this should use the
> >>>> >> >> >>>>>>> Tooling/Refactoring
> >>>> >> >> >>>>>>> stuff.
> >>>> >> >> >>>>>>>
> >>>> >> >> >>>>>>> However, I'm curious about the best way to structure the
> >>>> >> >> >>>>>>> location
> >>>> >> >> >>>>>>> of
> >>>> >> >> >>>>>>> migration candidates: AST matchers vs. visitor.
> >>>> >> >> >>>>>>>
> >>>> >> >> >>>>>>> I can almost see the visitor pattern working really well
> >>>> >> >> >>>>>>> here
> >>>> >> >> >>>>>>> as
> >>>> >> >> >>>>>>> each
> >>>> >> >> >>>>>>> different construct can have a pile of migration logic
> >>>> >> >> >>>>>>> dropped
> >>>> >> >> >>>>>>> in.... But if
> >>>> >> >> >>>>>>> there is a need to connect dots between more distant
> >>>> >> >> >>>>>>> constructs,
> >>>> >> >> >>>>>>> that
> >>>> >> >> >>>>>>> wouldn't work so well.... Not at all sure what would be
> >>>> >> >> >>>>>>> best
> >>>> >> >> >>>>>>> here.
> >>>> >> >> >>>>>>
> >>>> >> >> >>>>>>
> >>>> >> >> >>>>>> I've used a combination before - use matchers for the
> stuff
> >>>> >> >> >>>>>> where
> >>>> >> >> >>>>>> they
> >>>> >> >> >>>>>> work well, then write a very small easy-to-understand
> >>>> >> >> >>>>>> visitor if
> >>>> >> >> >>>>>> you need
> >>>> >> >> >>>>>> more. I think that brings down code size by quite a bit -
> >>>> >> >> >>>>>> obviously
> >>>> >> >> >>>>>> just a
> >>>> >> >> >>>>>> gut feeling here.
> >>>> >> >> >>>>>>
> >>>> >> >> >>>>>>>
> >>>> >> >> >>>>>>>
> >>>> >> >> >>>>>>>
> >>>> >> >> >>>>>>> On Fri, Jun 29, 2012 at 1:37 AM, Manuel Klimek
> >>>> >> >> >>>>>>> <klimek at google.com>
> >>>> >> >> >>>>>>> wrote:
> >>>> >> >> >>>>>>>>
> >>>> >> >> >>>>>>>> On Fri, Jun 29, 2012 at 4:06 AM, Sam Panzer
> >>>> >> >> >>>>>>>> <panzer at google.com>
> >>>> >> >> >>>>>>>> wrote:
> >>>> >> >> >>>>>>>>>
> >>>> >> >> >>>>>>>>> In case anyone wanted to take a look, the attached
> patch
> >>>> >> >> >>>>>>>>> includes
> >>>> >> >> >>>>>>>>> the tool I've been working on. I create a new binary,
> >>>> >> >> >>>>>>>>> c++migrate, which
> >>>> >> >> >>>>>>>>> attempts to convert for loops in the source files
> given
> >>>> >> >> >>>>>>>>> to
> >>>> >> >> >>>>>>>>> it.
> >>>> >> >> >>>>>>>>> Most of my
> >>>> >> >> >>>>>>>>> focus has been on the FrontedAction, so I skirted all
> of
> >>>> >> >> >>>>>>>>> the
> >>>> >> >> >>>>>>>>> issues
> >>>> >> >> >>>>>>>>> mentioned above by keeping the frontend interaction
> >>>> >> >> >>>>>>>>> minimal
> >>>> >> >> >>>>>>>>> (i.e. I just
> >>>> >> >> >>>>>>>>> call Tooling::ClangTool::run), and the changes are
> just
> >>>> >> >> >>>>>>>>> reported
> >>>> >> >> >>>>>>>>> on standard
> >>>> >> >> >>>>>>>>> output, if there are any to be made.
> >>>> >> >> >>>>>>>>>
> >>>> >> >> >>>>>>>>> The tool can currently convert for loops that range
> over
> >>>> >> >> >>>>>>>>> (1)
> >>>> >> >> >>>>>>>>> statically allocated arrays, and (2) Clang-style
> >>>> >> >> >>>>>>>>> iterator-based
> >>>> >> >> >>>>>>>>> loops (with
> >>>> >> >> >>>>>>>>> begin and end iterators defined). All loop variables
> >>>> >> >> >>>>>>>>> need to
> >>>> >> >> >>>>>>>>> be
> >>>> >> >> >>>>>>>>> declared
> >>>> >> >> >>>>>>>>> within the loop's initialization step in order for it
> to
> >>>> >> >> >>>>>>>>> be
> >>>> >> >> >>>>>>>>> converted,
> >>>> >> >> >>>>>>>>> though this requirement can potentially be eliminated.
> >>>> >> >> >>>>>>>>> I'm
> >>>> >> >> >>>>>>>>> working on
> >>>> >> >> >>>>>>>>> converting iterator-based loops that call
> >>>> >> >> >>>>>>>>> someContainer.end()
> >>>> >> >> >>>>>>>>> on
> >>>> >> >> >>>>>>>>> each
> >>>> >> >> >>>>>>>>> iteration, since they're probably the common case in
> >>>> >> >> >>>>>>>>> many
> >>>> >> >> >>>>>>>>> codebases.
> >>>> >> >> >>>>>>>>>
> >>>> >> >> >>>>>>>>> Just for fun, I ran the tool over the 41 .cpp files in
> >>>> >> >> >>>>>>>>> lib/Sema,
> >>>> >> >> >>>>>>>>> and my tool found 71 convertible loops in 17 files.
> >>>> >> >> >>>>>>>>> There is
> >>>> >> >> >>>>>>>>> plenty more
> >>>> >> >> >>>>>>>>> work to go, because it clearly missed some easy ones.
> >>>> >> >> >>>>>>>>>
> >>>> >> >> >>>>>>>>> Any input or feedback is welcome!
> >>>> >> >> >>>>>>>>
> >>>> >> >> >>>>>>>>
> >>>> >> >> >>>>>>>> High-level observations:
> >>>> >> >> >>>>>>>> 1. the handling of the rewrites; any reason not to use
> >>>> >> >> >>>>>>>> the
> >>>> >> >> >>>>>>>> Tooling/Refactoring stuff? Currently in the patch it
> >>>> >> >> >>>>>>>> looks to
> >>>> >> >> >>>>>>>> me
> >>>> >> >> >>>>>>>> like the
> >>>> >> >> >>>>>>>> files are not rewritten, but dumped to stdout
> >>>> >> >> >>>>>>>> 2. is the reason not to use the matchers here that
> >>>> >> >> >>>>>>>> they're not
> >>>> >> >> >>>>>>>> landed in mainline yet?
> >>>> >> >> >>>>>>>>
> >>>> >> >> >>>>>>>> Cheers,
> >>>> >> >> >>>>>>>> /Manuel
> >>>> >> >> >>>>>>>>
> >>>> >> >> >>>>>>>>>
> >>>> >> >> >>>>>>>>>
> >>>> >> >> >>>>>>>>> -Sam
> >>>> >> >> >>>>>>>>>
> >>>> >> >> >>>>>>>>> On Thu, Jun 28, 2012 at 10:50 AM, Sam Panzer
> >>>> >> >> >>>>>>>>> <panzer at google.com>
> >>>> >> >> >>>>>>>>> wrote:
> >>>> >> >> >>>>>>>>>>
> >>>> >> >> >>>>>>>>>> I'm that intern :)
> >>>> >> >> >>>>>>>>>>
> >>>> >> >> >>>>>>>>>> -Sam
> >>>> >> >> >>>>>>>>>>
> >>>> >> >> >>>>>>>>>>
> >>>> >> >> >>>>>>>>>> On Wed, Jun 27, 2012 at 9:48 PM, John Wiegley
> >>>> >> >> >>>>>>>>>> <johnw at boostpro.com>
> >>>> >> >> >>>>>>>>>> wrote:
> >>>> >> >> >>>>>>>>>>>
> >>>> >> >> >>>>>>>>>>> >>>>> Sam Panzer <panzer at google.com> writes:
> >>>> >> >> >>>>>>>>>>>
> >>>> >> >> >>>>>>>>>>> > In particular, I am working on a tool to convert
> >>>> >> >> >>>>>>>>>>> > existing
> >>>> >> >> >>>>>>>>>>> > C++
> >>>> >> >> >>>>>>>>>>> > for loops to
> >>>> >> >> >>>>>>>>>>> > take advantage of the new C++11 range-based
> syntax.
> >>>> >> >> >>>>>>>>>>> > I can
> >>>> >> >> >>>>>>>>>>> > imagine similar
> >>>> >> >> >>>>>>>>>>> > tools to replace const with constexpr, macro hacks
> >>>> >> >> >>>>>>>>>>> > with
> >>>> >> >> >>>>>>>>>>> > static_assert, and
> >>>> >> >> >>>>>>>>>>> > potentially other common refactorings.
> >>>> >> >> >>>>>>>>>>>
> >>>> >> >> >>>>>>>>>>> > Thoughts? Suggestions?
> >>>> >> >> >>>>>>>>>>>
> >>>> >> >> >>>>>>>>>>> You really must watch this presentation, if you
> >>>> >> >> >>>>>>>>>>> haven't
> >>>> >> >> >>>>>>>>>>> already:
> >>>> >> >> >>>>>>>>>>>
> >>>> >> >> >>>>>>>>>>>     http://www.youtube.com/watch?v=yuIOGfcOH0k
> >>>> >> >> >>>>>>>>>>>
> >>>> >> >> >>>>>>>>>>> --
> >>>> >> >> >>>>>>>>>>> John Wiegley
> >>>> >> >> >>>>>>>>>>> BoostPro Computing
> >>>> >> >> >>>>>>>>>>> http://www.boostpro.com
> >>>> >> >> >>>>>>>>>>> _______________________________________________
> >>>> >> >> >>>>>>>>>>> cfe-dev mailing list
> >>>> >> >> >>>>>>>>>>> cfe-dev at cs.uiuc.edu
> >>>> >> >> >>>>>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
> >>>> >> >> >>>>>>>>>>
> >>>> >> >> >>>>>>>>>>
> >>>> >> >> >>>>>>>>>
> >>>> >> >> >>>>>>>>>
> >>>> >> >> >>>>>>>>> _______________________________________________
> >>>> >> >> >>>>>>>>> cfe-dev mailing list
> >>>> >> >> >>>>>>>>> cfe-dev at cs.uiuc.edu
> >>>> >> >> >>>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
> >>>> >> >> >>>>>>>>>
> >>>> >> >> >>>>>>>>
> >>>> >> >> >>>>>>>>
> >>>> >> >> >>>>>>>> _______________________________________________
> >>>> >> >> >>>>>>>> cfe-dev mailing list
> >>>> >> >> >>>>>>>> cfe-dev at cs.uiuc.edu
> >>>> >> >> >>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
> >>>> >> >> >>>>>>>>
> >>>> >> >> >>>>>>>
> >>>> >> >> >>>>>>
> >>>> >> >> >>>>>
> >>>> >> >> >>>>
> >>>> >> >> >>>
> >>>> >> >> >>
> >>>> >> >> >
> >>>> >> >> >
> >>>> >> >> > _______________________________________________
> >>>> >> >> > 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/20120713/e68f65f3/attachment.html>


More information about the cfe-dev mailing list