179 lines
5.4 KiB
C++
179 lines
5.4 KiB
C++
// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
|
|
// RUN: clang-modernize -use-auto %t.cpp -- --std=c++11 -I %S/Inputs
|
|
// RUN: FileCheck -input-file=%t.cpp %s
|
|
//
|
|
// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
|
|
// RUN: clang-modernize -use-auto %t.cpp -- --std=c++11 -I %S/Inputs \
|
|
// RUN: -DUSE_INLINE_NAMESPACE=1
|
|
// RUN: FileCheck -input-file=%t.cpp %s
|
|
|
|
|
|
#define CONTAINER array
|
|
#include "test_std_container.h"
|
|
#undef CONTAINER
|
|
|
|
#define CONTAINER vector
|
|
#include "test_std_container.h"
|
|
#undef CONTAINER
|
|
|
|
#define CONTAINER unordered_map
|
|
#define USE_BASE_CLASS_ITERATORS 1
|
|
#include "test_std_container.h"
|
|
#undef USE_BASE_CLASS_ITERATORS
|
|
#undef CONTAINER
|
|
|
|
typedef std::vector<int>::iterator int_iterator;
|
|
|
|
namespace foo {
|
|
template <typename T>
|
|
class vector {
|
|
public:
|
|
class iterator {};
|
|
|
|
iterator begin() { return iterator(); }
|
|
};
|
|
} // namespace foo
|
|
|
|
int main(int argc, char **argv) {
|
|
std::vector<int> Vec;
|
|
// CHECK: std::vector<int> Vec;
|
|
|
|
std::unordered_map<int> Map;
|
|
// CHECK: std::unordered_map<int> Map;
|
|
|
|
// Types with more sugar should work. Types with less should not.
|
|
{
|
|
int_iterator more_sugar = Vec.begin();
|
|
// CHECK: auto more_sugar = Vec.begin();
|
|
|
|
internal::iterator_wrapper<std::vector<int>, 0> less_sugar = Vec.begin();
|
|
// CHECK: internal::iterator_wrapper<std::vector<int>, 0> less_sugar = Vec.begin();
|
|
}
|
|
|
|
// Initialization from initializer lists isn't allowed. Using 'auto'
|
|
// would result in std::initializer_list being deduced for the type.
|
|
{
|
|
std::unordered_map<int>::iterator I{Map.begin()};
|
|
// CHECK: std::unordered_map<int>::iterator I{Map.begin()};
|
|
|
|
std::unordered_map<int>::iterator I2 = {Map.begin()};
|
|
// CHECK: std::unordered_map<int>::iterator I2 = {Map.begin()};
|
|
}
|
|
|
|
// Various forms of construction. Default constructors and constructors with
|
|
// all-default parameters shouldn't get transformed. Construction from other
|
|
// types is also not allowed.
|
|
{
|
|
std::unordered_map<int>::iterator copy(Map.begin());
|
|
// CHECK: auto copy(Map.begin());
|
|
|
|
std::unordered_map<int>::iterator def;
|
|
// CHECK: std::unordered_map<int>::iterator def;
|
|
|
|
// const_iterator has no default constructor, just one that has >0 params
|
|
// with defaults.
|
|
std::unordered_map<int>::const_iterator constI;
|
|
// CHECK: std::unordered_map<int>::const_iterator constI;
|
|
|
|
// Uses iterator_provider::const_iterator's conversion constructor.
|
|
|
|
std::unordered_map<int>::const_iterator constI2 = def;
|
|
// CHECK: std::unordered_map<int>::const_iterator constI2 = def;
|
|
|
|
std::unordered_map<int>::const_iterator constI3(def);
|
|
// CHECK: std::unordered_map<int>::const_iterator constI3(def);
|
|
|
|
// Explicit use of conversion constructor
|
|
|
|
std::unordered_map<int>::const_iterator constI4 = std::unordered_map<int>::const_iterator(def);
|
|
// CHECK: auto constI4 = std::unordered_map<int>::const_iterator(def);
|
|
|
|
// Uses iterator_provider::iterator's const_iterator conversion operator.
|
|
|
|
std::unordered_map<int>::iterator I = constI;
|
|
// CHECK: std::unordered_map<int>::iterator I = constI;
|
|
|
|
std::unordered_map<int>::iterator I2(constI);
|
|
// CHECK: std::unordered_map<int>::iterator I2(constI);
|
|
}
|
|
|
|
// Weird cases of pointers and references to iterators are not transformed.
|
|
{
|
|
int_iterator I = Vec.begin();
|
|
|
|
int_iterator *IPtr = &I;
|
|
// CHECK: int_iterator *IPtr = &I;
|
|
|
|
int_iterator &IRef = I;
|
|
// CHECK: int_iterator &IRef = I;
|
|
}
|
|
|
|
{
|
|
// Variable declarations in iteration statements.
|
|
for (std::vector<int>::iterator I = Vec.begin(); I != Vec.end(); ++I) {
|
|
// CHECK: for (auto I = Vec.begin(); I != Vec.end(); ++I) {
|
|
}
|
|
|
|
// Range-based for loops.
|
|
std::array<std::vector<int>::iterator> iter_arr;
|
|
for (std::vector<int>::iterator I: iter_arr) {
|
|
// CHECK: for (auto I: iter_arr) {
|
|
}
|
|
|
|
// Test with init-declarator-list.
|
|
for (int_iterator I = Vec.begin(),
|
|
E = Vec.end(); I != E; ++I) {
|
|
// CHECK: for (auto I = Vec.begin(),
|
|
// CHECK-NEXT: E = Vec.end(); I != E; ++I) {
|
|
}
|
|
}
|
|
|
|
// Only std containers should be changed.
|
|
{
|
|
using namespace foo;
|
|
vector<int> foo_vec;
|
|
vector<int>::iterator I = foo_vec.begin();
|
|
// CHECK: vector<int>::iterator I = foo_vec.begin();
|
|
}
|
|
|
|
// Ensure using directives don't interfere with replacement.
|
|
{
|
|
using namespace std;
|
|
vector<int> std_vec;
|
|
vector<int>::iterator I = std_vec.begin();
|
|
// CHECK: auto I = std_vec.begin();
|
|
}
|
|
|
|
// Make sure references and cv qualifiers don't get removed (i.e. replaced
|
|
// with just 'auto').
|
|
{
|
|
const auto & I = Vec.begin();
|
|
// CHECK: const auto & I = Vec.begin();
|
|
|
|
auto && I2 = Vec.begin();
|
|
// CHECK: auto && I2 = Vec.begin();
|
|
}
|
|
|
|
// Passing a string as an argument to introduce a temporary object
|
|
// that will create an expression with cleanups. Bugzilla: 15550
|
|
{
|
|
std::unordered_map<int> MapFind;
|
|
std::unordered_map<int>::iterator I = MapFind.find("foo");
|
|
// CHECK: auto I = MapFind.find("foo");
|
|
}
|
|
|
|
// Test for declaration lists
|
|
{
|
|
// Ensusre declaration lists that matches the declaration type with written
|
|
// no-list initializer are transformed.
|
|
std::vector<int>::iterator I = Vec.begin(), E = Vec.end();
|
|
// CHECK: auto I = Vec.begin(), E = Vec.end();
|
|
|
|
// Declaration lists with non-initialized variables should not be
|
|
// transformed.
|
|
std::vector<int>::iterator J = Vec.begin(), K;
|
|
// CHECK: std::vector<int>::iterator J = Vec.begin(), K;
|
|
}
|
|
return 0;
|
|
}
|