// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11

namespace value_range_detail {
  template<typename T>
  class value_range_iter {
    T t;
  public:
    value_range_iter(const T &t) : t(t) {}
    T operator*() const { return t; }
    bool operator!=(const value_range_iter &o) const { return t != o.t; }
    value_range_iter &operator++() { ++t; return *this; }
  };

  template<typename T>
  struct value_range {
    value_range(const T &a, const T &b) : begin_(a), end_(b) {}
    value_range_iter<T> begin_, end_;
  };

  template<typename T>
  value_range_iter<T> begin(const value_range<T> &r) { return r.begin_; }
  template<typename T>
  value_range_iter<T> end(const value_range<T> &r) { return r.end_; }


  struct end_t {};

  template<typename T>
  class value_range_step_iter {
    T it, step;
  public:
    value_range_step_iter(const T &it, const T &step) : it(it), step(step) {}
    T operator*() const { return it; }
    bool operator!=(value_range_step_iter end) const { return it != end.it; }
    value_range_step_iter &operator++() { it += step; return *this; }
  };

  template<typename T>
  class value_range_step {
    T it, step, end_;
  public:
    value_range_step(const T &it, const T &end, const T &step) :
      it(it), end_(end), step(step) {}
    typedef value_range_step_iter<T> iterator;
    iterator begin() const { return iterator(it, step); }
    iterator end() const { return iterator(end_, step); }
  };
}

template<typename T>
value_range_detail::value_range<T> range(const T &a, const T &b) { return value_range_detail::value_range<T>(a, b); }

template<typename T>
value_range_detail::value_range_step<T> range(const T &a, const T &b, const T &step) { return value_range_detail::value_range_step<T>(a, b, step); }


namespace map_range {
  template<typename T>
  class vector {
    T storage[100];
    decltype(sizeof(char)) size;
  public:
    vector() : size() {}
    void push_back(T t) { storage[size++] = t; }
    T *begin() { return storage; }
    T *end() { return storage + size; }
  };

  template<typename T> struct tuple_elem {
    T t;
    tuple_elem() {}
    tuple_elem(T t) : t(t) {}
  };
  template<typename... A>
  struct tuple : tuple_elem<A>... {
    tuple() : tuple_elem<A>()... {}
    tuple(A... a) : tuple_elem<A>(a)... {}
    template<typename B> B &get() { return tuple_elem<B>::t; }
  };

  template<typename F, typename I>
  class map_iter {
    F f;
    I i;
  public:
    map_iter(F f, I i) : f(f), i(i) {}
    auto operator*() const -> decltype(f(*i)) { return f(*i); }
    bool operator!=(const map_iter &o) const { return i != o.i; }
    map_iter &operator++() { ++i; return *this; }
  };

  template<typename T>
  struct iter_pair {
    T begin_, end_;
    iter_pair(T begin, T end) : begin_(begin), end_(end) {}
  };
  template<typename T> T begin(iter_pair<T> p) { return p.begin_; }
  template<typename T> T end(iter_pair<T> p) { return p.end_; }

  template<typename...> class mem_fun_impl;
  template<typename R, typename T, typename... A>
  class mem_fun_impl<R (T::*)(A...)> {
    typedef R (T::*F)(A...);
    F f;
  public:
    mem_fun_impl(F f) : f(f) {}
    R operator()(T &t, A &&...a) const { return (t.*f)(static_cast<A&&>(a)...); }
  };
  template<typename F> mem_fun_impl<F> mem_fun(F f) { return mem_fun_impl<F>(f); }

  template<typename F, typename T>
  auto map(const F &f, T &t) -> iter_pair<map_iter<F, decltype(t.begin())>> {
    typedef map_iter<F, decltype(t.begin())> iter;
    return iter_pair<iter>(iter(f, t.begin()), iter(f, t.end()));
  }
}

#define assert(b) if (!(b)) { return 1; }
int main() {
  int total = 0;

  for (auto n : range(1, 5)) {
    total += n;
  }
  assert(total == 10);

  for (auto n : range(10, 100, 10)) {
    total += n;
  }
  assert(total == 460);

  map_range::vector<char> chars;
  chars.push_back('a');
  chars.push_back('b');
  chars.push_back('c');
  for (char c : chars) {
    ++total;
  }
  assert(total == 463);

  typedef map_range::tuple<int, double> T;
  map_range::vector<T> pairs;
  pairs.push_back(T(42, 12.9));
  pairs.push_back(T(6, 4.2));
  pairs.push_back(T(9, 1.1));
  for (auto a : map(map_range::mem_fun(&T::get<int>), pairs)) {
    total += a;
  }
  assert(total == 500);
}

// PR11793
namespace test2 {
  class A {
    int xs[10]; // expected-note {{implicitly declared private here}}
  };
  void test(A &a) {
    for (int x : a.xs) { } // expected-error {{'xs' is a private member of 'test2::A'}}
  }
}

namespace test3 {
  // Make sure this doesn't crash
  struct A {};
  struct B { ~B(); operator bool(); };
  struct C { B operator!=(const C&); C& operator++(); int operator*(); };
  C begin(const A&);
  C end(const A&);
  template<typename T> void f() { for (auto a : A()) {} }
  void g() { f<int>(); }
}

namespace test4 {
  void f() {
    int y;

    // Make sure these don't crash. Better diagnostics would be nice.
    for (: {1, 2, 3}) {} // expected-error {{expected expression}} expected-error {{expected ';'}}
    for (1 : {1, 2, 3}) {} // expected-error {{must declare a variable}}
    for (+x : {1, 2, 3}) {} // expected-error {{undeclared identifier}} expected-error {{expected ';'}}
    for (+y : {1, 2, 3}) {} // expected-error {{must declare a variable}}
  }
}

namespace test5 {
  // Test error-recovery.
  void f() {
    for (auto x : undeclared_identifier) // expected-error {{undeclared identifier}}
      for (auto y : x->foo)
        y->bar();
    for (auto x : 123) // expected-error {{no viable 'begin'}}
      x->foo();
  }
}

namespace test6 {
  void foo(int arr[]) {  // expected-note {{declared here}}
    for (auto i : arr) { }
      // expected-error@-1 {{cannot build range expression with array function parameter 'arr' since parameter with array type 'int []' is treated as pointer type 'int *'}}
  }

  struct vector {
    int *begin() { return 0; }
    int *end() { return 0; }
  };

  void foo(vector arr[]) {  // expected-note {{declared here}}
    // Don't suggest to dereference arr.
    for (auto i : arr) { }
      // expected-error@-1 {{cannot build range expression with array function parameter 'arr' since parameter with array type 'test6::vector []' is treated as pointer type 'test6::vector *'}}
  }
}

namespace test7 {
  void f() {
    int arr[5], b;
    for (a : arr) {} // expected-error {{requires type for loop variable}}
    // FIXME: Give a different error in this case?
    for (b : arr) {} // expected-error {{requires type for loop variable}}
    for (arr : arr) {} // expected-error {{requires type for loop variable}}
    for (c alignas(8) : arr) { // expected-error {{requires type for loop variable}}
      static_assert(alignof(c) == 8, ""); // expected-warning {{extension}}
    }
    // FIXME: The fix-it hint here is not sufficient to fix the error.
    // We fail to diagnose that d is underaligned for its type, because
    // we check the alignment attribute before we perform the auto
    // deduction.
    for (d alignas(1) : arr) {} // expected-error {{requires type for loop variable}}
    for (e [[deprecated]] : arr) { e = 0; } // expected-warning {{deprecated}} expected-note {{here}} expected-error {{requires type for loop variable}}
  }
}

namespace pr18587 {
  class Arg {};
  struct Cont {
    int *begin();
    int *end();
  };
  void AddAllArgs(Cont &x) {
    for (auto Arg: x) {
    }
  }
}
