// RUN: %check_clang_tidy %s modernize-use-auto %t -- -- \ // RUN: -std=c++11 -I %S/Inputs/modernize-use-auto #include "containers.h" void f_array() { std::array C; std::array::iterator ArrayI1 = C.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators [modernize-use-auto] // CHECK-FIXES: auto ArrayI1 = C.begin(); std::array::reverse_iterator ArrayI2 = C.rbegin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto ArrayI2 = C.rbegin(); const std::array D; std::array::const_iterator ArrayI3 = D.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto ArrayI3 = D.begin(); std::array::const_reverse_iterator ArrayI4 = D.rbegin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto ArrayI4 = D.rbegin(); } void f_deque() { std::deque C; std::deque::iterator DequeI1 = C.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto DequeI1 = C.begin(); std::deque::reverse_iterator DequeI2 = C.rbegin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto DequeI2 = C.rbegin(); const std::deque D; std::deque::const_iterator DequeI3 = D.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto DequeI3 = D.begin(); std::deque::const_reverse_iterator DequeI4 = D.rbegin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto DequeI4 = D.rbegin(); } void f_forward_list() { std::forward_list C; std::forward_list::iterator FListI1 = C.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto FListI1 = C.begin(); const std::forward_list D; std::forward_list::const_iterator FListI2 = D.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto FListI2 = D.begin(); } void f_list() { std::list C; std::list::iterator ListI1 = C.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto ListI1 = C.begin(); std::list::reverse_iterator ListI2 = C.rbegin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto ListI2 = C.rbegin(); const std::list D; std::list::const_iterator ListI3 = D.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto ListI3 = D.begin(); std::list::const_reverse_iterator ListI4 = D.rbegin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto ListI4 = D.rbegin(); } void f_vector() { std::vector C; std::vector::iterator VecI1 = C.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto VecI1 = C.begin(); std::vector::reverse_iterator VecI2 = C.rbegin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto VecI2 = C.rbegin(); const std::vector D; std::vector::const_iterator VecI3 = D.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto VecI3 = D.begin(); std::vector::const_reverse_iterator VecI4 = D.rbegin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto VecI4 = D.rbegin(); } void f_map() { std::map C; std::map::iterator MapI1 = C.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto MapI1 = C.begin(); std::map::reverse_iterator MapI2 = C.rbegin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto MapI2 = C.rbegin(); const std::map D; std::map::const_iterator MapI3 = D.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto MapI3 = D.begin(); std::map::const_reverse_iterator MapI4 = D.rbegin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto MapI4 = D.rbegin(); } void f_multimap() { std::multimap C; std::multimap::iterator MMapI1 = C.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto MMapI1 = C.begin(); std::multimap::reverse_iterator MMapI2 = C.rbegin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto MMapI2 = C.rbegin(); const std::multimap D; std::multimap::const_iterator MMapI3 = D.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto MMapI3 = D.begin(); std::multimap::const_reverse_iterator MMapI4 = D.rbegin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto MMapI4 = D.rbegin(); } void f_set() { std::set C; std::set::iterator SetI1 = C.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto SetI1 = C.begin(); std::set::reverse_iterator SetI2 = C.rbegin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto SetI2 = C.rbegin(); const std::set D; std::set::const_iterator SetI3 = D.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto SetI3 = D.begin(); std::set::const_reverse_iterator SetI4 = D.rbegin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto SetI4 = D.rbegin(); } void f_multiset() { std::multiset C; std::multiset::iterator MSetI1 = C.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto MSetI1 = C.begin(); std::multiset::reverse_iterator MSetI2 = C.rbegin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto MSetI2 = C.rbegin(); const std::multiset D; std::multiset::const_iterator MSetI3 = D.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto MSetI3 = D.begin(); std::multiset::const_reverse_iterator MSetI4 = D.rbegin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto MSetI4 = D.rbegin(); } void f_unordered_map() { std::unordered_map C; std::unordered_map::iterator UMapI1 = C.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto UMapI1 = C.begin(); const std::unordered_map D; std::unordered_map::const_iterator UMapI2 = D.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto UMapI2 = D.begin(); } void f_unordered_multimap() { std::unordered_multimap C; std::unordered_multimap::iterator UMMapI1 = C.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto UMMapI1 = C.begin(); const std::unordered_multimap D; std::unordered_multimap::const_iterator UMMapI2 = D.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto UMMapI2 = D.begin(); } void f_unordered_set() { std::unordered_set C; std::unordered_set::iterator USetI1 = C.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto USetI1 = C.begin(); const std::unordered_set D; std::unordered_set::const_iterator USetI2 = D.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto USetI2 = D.begin(); } void f_unordered_multiset() { std::unordered_multiset C; std::unordered_multiset::iterator UMSetI1 = C.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto UMSetI1 = C.begin(); const std::unordered_multiset D; std::unordered_multiset::const_iterator UMSetI2 = D.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto UMSetI2 = D.begin(); } typedef std::vector::iterator int_iterator; std::vector Vec; std::unordered_map Map; void sugar() { // Types with more sugar should work. Types with less should not. int_iterator more_sugar = Vec.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto more_sugar = Vec.begin(); } void initializer_list() { // Initialization from initializer lists isn't allowed. Using 'auto' would // result in std::initializer_list being deduced for the type. std::unordered_map::iterator I{Map.begin()}; std::unordered_map::iterator I2 = {Map.begin()}; } void construction() { // 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::iterator copy(Map.begin()); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto copy(Map.begin()); std::unordered_map::iterator def; std::unordered_map::const_iterator constI; // Implicit conversion. std::unordered_map::const_iterator constI2 = def; std::unordered_map::const_iterator constI3(def); // Explicit conversion std::unordered_map::const_iterator constI4 = std::unordered_map::const_iterator(def); // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto constI4 // CHECK-FIXES-NEXT: = std::unordered_map::const_iterator(def); } void pointer_to_iterator() { int_iterator I = Vec.begin(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto I = Vec.begin(); // Pointers and references to iterators are not transformed. int_iterator *IPtr = &I; int_iterator &IRef = I; } void loop() { for (std::vector::iterator I = Vec.begin(); I != Vec.end(); ++I) { // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use auto when declaring iterators // CHECK-FIXES: for (auto I = Vec.begin(); I != Vec.end(); ++I) } for (int_iterator I = Vec.begin(), E = Vec.end(); I != E; ++I) { // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use auto when declaring iterators // CHECK-FIXES: for (auto I = Vec.begin(), E = Vec.end(); I != E; ++I) } std::vector::iterator> IterVec; for (std::vector::iterator I : IterVec) { // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use auto when declaring iterators // CHECK-FIXES: for (auto I : IterVec) } } void cv_qualifiers() { // Make sure references and cv qualifiers don't get removed (i.e. replaced // with just 'auto'). const auto & I = Vec.begin(); auto && I2 = Vec.begin(); } void cleanup() { // Passing a string as an argument to introduce a temporary object that will // create an expression with cleanups. std::map MapFind; std::map::iterator I = MapFind.find("foo"); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto I = MapFind.find("foo"); } void declaration_lists() { // Declaration lists that match the declaration type with written no-list // initializer are transformed. std::vector::iterator I = Vec.begin(), E = Vec.end(); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators // CHECK-FIXES: auto I = Vec.begin(), E = Vec.end(); // Declaration lists with non-initialized variables should not be transformed. std::vector::iterator J = Vec.begin(), K; }