C++11 is here!!! (and it looks like it'll stay!)

I flipped the build systems to use C++11 today by default. Nothing seems to have broken, folks seem happy, and the bots are making good progress.

I plan to slowly remove support for building in C++98 mode over the weekend and watch the bots to see if there are any that were forcing things in the other direction. If all goes well, its open season. I’ve got a bunch of the basic cleanup (deleting the no longer needed #if’s) ready to go, but I’m being a bit conservative about submitting them.

I’ve also mailed out some additions to the coding standards to try and cover a few bikesheds that would likely diverge easily in C++11, and to cover a few corners of the new language where several people expressed strong opinions that we should have guidelines about when and where to use them. You can join the review on llvm-commits, or here: http://llvm-reviews.chandlerc.com/D2905

Let me know if anything breaks!
-Chandler

This is so awesome, congrats Chandler!

-Chris

Great news! It would be nice now that we're all using C++11 to have something in the style guide about providing C++11-friendly iterators. Currently, we have a lot of classes that implement foo_begin() and foo_end() methods. It would be nice to have a common pattern for moving these under an inline class that implemented begin() and end(), so instead of having to do:

for (auto I=X.foo_begin(),E=X.foo_end() ; I!=E, ++E) {
  auto V = *I;
  ...
}

We could do:

for (auto V : X.foo()) {
  ...
}

David

+1

--renato

Since the bots don't directly specify the standard level, I'm guessing
they're already adapted.

Now would be a good time to add a few breaking things to see at which
extent this is true.

cheers,
--renato

Didn't r202584 already does that ?

[C++11] Remove use of LLVM_HAS_RVALUE_REFERENCES from Clang. This macro is now always 1, as we're requiring C++11 now!

for (auto V : X.foo()) {
       ...
}

It would also be good to agree on a way to handle reverse iterators, especially on those which already use begin() and end() for going forwards. For example

For (auto& bb : MF)

Will iterate the BBs in a machine function forwards. How should we do it backwards? Whatever we choose should be the standard across other similar classes of this in different parts of the code base. I have 3 potential answers which are all quite similar.

1: for (auto& bb : MF.reverse())
2: for (auto& bb : MF.r_bb())
3: for (auto& bb : reverse(MF))

Personally I like 1 but I'm open to suggestions. Arguably 3 could also use 1 is people liked both. 2 is more explicit about what's going on but I don't like the style too much.

Pete

rbegin() and rend()?

--renato

It would also be good to agree on a way to handle reverse iterators, especially on those which already use begin() and end() for going forwards. For example

rbegin() and rend()?

Would those work with a foreach construct? Perhaps I forgot to mention that was what I'm trying to work out here.

In example 3 I was wondering if we could define a method reverse(). We could use sfinae to wrap that around rbegin/rend if people like that style?

Pete

Sorry, I was too terse... :wink:

If MF is a reverse_iterator, it'd just work, no? But to get the
reverse iterator, I think reverse() would be the best general pattern,
since you can adapt it to each container needs.

cheers,
--renato

I'm not aware of the prior art or standards are here, but I think that a global reverse() adapter is the way to go. Likewise, we should have a standard "enumerate()" adaptor like python.

-Chris

>> Would those work with a foreach construct? Perhaps I forgot to mention
that was what I'm trying to work out here.
>>
>> In example 3 I was wondering if we could define a method reverse(). We
could use sfinae to wrap that around rbegin/rend if people like that style?
>
> Sorry, I was too terse... :wink:
>
> If MF is a reverse_iterator, it'd just work, no? But to get the
> reverse iterator, I think reverse() would be the best general pattern,
> since you can adapt it to each container needs.

I'm not aware of the prior art or standards are here, but I think that a
global reverse() adapter is the way to go. Likewise, we should have a
standard "enumerate()" adaptor like python.

I definitely prefer the global adaptor pattern. As for prior art, I had
played with it a bit, and came up with
An implementation of a reverse iteration adaptor for range based for-loops in C++11. · GitHub a while back.

Yea, there is a pretty strong move toward range adaptors. If possible, I'm
going to work on contributing a basic selection of them to LLVM's ADT
specifically to address the immediate needs of range-based for loops.

Sounds good. We also have to decide what to do with Function::arg_begin() for example (and all the other secondary ranges hanging off IR and other things). IMO, “for (auto &arg : F.getArguments())” makes the most sense.

-Chris

>> Would those work with a foreach construct? Perhaps I forgot to
mention that was what I'm trying to work out here.
>>
>> In example 3 I was wondering if we could define a method reverse().
We could use sfinae to wrap that around rbegin/rend if people like that
style?
>
> Sorry, I was too terse... :wink:
>
> If MF is a reverse_iterator, it'd just work, no? But to get the
> reverse iterator, I think reverse() would be the best general pattern,
> since you can adapt it to each container needs.

I'm not aware of the prior art or standards are here, but I think that a
global reverse() adapter is the way to go. Likewise, we should have a
standard "enumerate()" adaptor like python.

I definitely prefer the global adaptor pattern. As for prior art, I had
played with it a bit, and came up with
An implementation of a reverse iteration adaptor for range based for-loops in C++11. · GitHub a while back.

Yea, there is a pretty strong move toward range adaptors. If possible, I'm
going to work on contributing a basic selection of them to LLVM's ADT
specifically to address the immediate needs of range-based for loops.

Sounds good. We also have to decide what to do with Function::arg_begin()
for example (and all the other secondary ranges hanging off IR and other
things). IMO, "for (auto &arg : F.getArguments())" makes the most sense.

I was actually going to check in this, but I can post it for review if
folks are worried.

My plan was to provide an implementation of std::iterator_range<T> and then
provide 'F.arguments()' which returns it.

Nice. What’s the logic behind .arguments() vs .getArguments()? I don’t have a strong opinion either way, but there should be rationale.

-Chris

In the best case 'get' doesn't really add any meaning, and in the worst
case it is actively misleading

For example, you might iterate over operands, and assign through the
iterator to mutate them.

Really, these operate as range-views over some sequence. It seems
particularly easy to teach foo_begin(), foo_end() -> foos() as well.

It’s getting the range though, just like Function::getArgumentList() returns the argument list.

That’s a very objective-c thing to do :-), they use the pattern foo() and setFoo() for the getter and setter, respectively (and the naming is baked into the property model). I don’t feel strongly against it, but we pretty consistently use the Java style ‘get’ prefix everywhere else.

-Chris

The Objective-C (technically, OpenStep) convention is to use getFoo when you provide a buffer into which the thing will be put, which isn't the case here. My reason for proposing foo() instead of getFoo() is that getFoo(), to me, implies that now you have a foo that you can hang on to for a bit, whereas the object returning the reverse iterators is intrinsically a transient thing. You don't want people doing:

auto args = foo.arguments();

And then later doing:

for (auto arg : args)
  ...

While this may be a valid thing to do, determining whether it actually is requires some thought. I would be more inclined to expect it to unconditionally work if the method were called getArguments() than if it is called arguments(), but that may be personal bias.

The only places where the C++ standard library uses get (from my memory, may be completely wrong) are when there is some notion of ownership transfer. When referring to internal properties of an object, the name is undecorated (see the begin() and end(), not get_begin(), get_end(), that are the original cause of this discussion...)

David

In the best case 'get' doesn't really add any meaning, and in the worst
case it is actively misleading

It's getting the range though, just like Function::getArgumentList()
returns the argument list.

I really disagree (and I disagree with getArgumentList for the same reason).

getFoo should return something with value semantics (even if its a const
reference to delay the copy). setFoo should directly mutate something.

What we're really doing is making the equivalent of a "member-like
accessor" method.

For example, you might iterate over operands, and assign through the
iterator to mutate them.

Really, these operate as range-views over some sequence. It seems
particularly easy to teach foo_begin(), foo_end() -> foos() as well.

That's a very objective-c thing to do :-), they use the pattern foo() and
setFoo() for the getter and setter, respectively (and the naming is baked
into the property model). I don't feel strongly against it, but we pretty
consistently use the Java style 'get' prefix everywhere else.

If we have a setFoo, then I'm with you we should have a value-semantic
getFoo. But we have just plain "op_begin" and "op_end" and I think that
makes sense to extend to a range adaptor "operands".