clang-modernize: Can't get Loop Transform to work for STL for loops

Hello,

I’ve been using Clang as part of Xcode 5.02 on OS X 10.9 for over a year.

I’m trying clang-modernize for the first time. I’ve build llvm, clang and
its tools from sources on OS X 10.9.5. Clang-modernize works fine for
non-STL usage, but by default it can’t find STL headers:

    > clang-modernize simple.cpp
   
/Users/gerd/Desktop/ServerOnMac/hoereng-mac-pro-ServerOnMac/Main/clang-modernize/simple.cpp:1:10:
fatal error: 'iostream' file not found
    #include <iostream>

(The clang build instructions say it will try to find the best headers.)
I have a compile_commands.json file which contains my Xcode 5.02 Clang
invocation (including -std=c++11).

Clang-moderinze will find the STL headers if I add a –I to
compile_commands.json which points to my Xcode STL:

-I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1

But, it won’t replace the STL for{} loop in my example with a range-based
loop. Note that the “nullptr” and simple int array loops were updated as
expected.

How do I get this substation to work? Is there an STL compatibility issue
between this latest version of clang-modernize and Xcode 5.02?

Here’s the output of my test case from clang-modernize:

#include <iostream>
#include <vector>

void myfunc()
{
  int *p = nullptr;

  int arr = {1,2,3};
  for (auto & elem : arr) {
    std::cout << elem;
  }

  std::vector<int> my_container;
  for (std::vector<int>::const_iterator I = my_container.begin(); I !=
my_container.end(); ++I) {
    std::cout << *I << std::endl;
  }
}

I’ve run clang-modernize over several hundred thousand lines of legacy C++.
It does a good job of converting non-const-iterator loops, like

    int i;
    std::vector<int> my_container;
    for (std::vector<int>::iterator iter = my_container.begin(); iter !=
my_container.end(); ++iter) {
        i = *iter;
    }
To
    int i;
    std::vector<int> my_container;
    for (auto & elem : my_container) {
        i = elem;
    }

But, the same loop with a const_iterator doesn’t get converted. I’d expect:
    for (std::vector<int>::const_iterator iter = my_container.begin(); iter
!= my_container.end(); ++iter) {
        i = *iter;
    }
To transform into:
    for (const auto & elem : my_container) {
        i = elem;
    }

Is this a reasonable transformation?

Is it a bug or enhancement request?

Hmm, I don't have a direct answer for you, but the transformation there
does technically imply the loop changing from using const_iterator behind
the scenes to using iterator behind the scenes, so this might be
intentional. It depends on where the line is drawn regarding what is
considered to be only a minor change of behavior.