13573b2c84372d9484296fa658f5276f6c09acb92Daniel Dunbar// RUN: %clang_cc1 -fsyntax-only -verify %s
29e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall
39e1d5827a6feaf18cb72a9d8eca80645e2075528John McCallstruct Opaque0 {};
49e1d5827a6feaf18cb72a9d8eca80645e2075528John McCallstruct Opaque1 {};
59e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall
69e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall// Redeclarations are okay in a namespace.
79e1d5827a6feaf18cb72a9d8eca80645e2075528John McCallnamespace test0 {
89e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  namespace ns {
99e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall    void foo(Opaque0); // expected-note 2 {{candidate function}}
109e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  }
119e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall
129e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  using ns::foo;
139e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  using ns::foo;
149e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall
159e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  void test0() {
169e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall    foo(Opaque1()); // expected-error {{no matching function for call}}
179e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  }
189e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall
199e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  namespace ns {
209e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall    void foo(Opaque1);
219e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  }
229e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall
239e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  void test1() {
249e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall    foo(Opaque1()); // expected-error {{no matching function for call}}
259e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  }
269e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall
279e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  using ns::foo;
289e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall
299e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  void test2() {
309e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall    foo(Opaque1());
319e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  }
329e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall
339e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  using ns::foo;
349e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall}
359e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall
369e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall// Make sure we handle transparent contexts the same way.
379e1d5827a6feaf18cb72a9d8eca80645e2075528John McCallnamespace test1 {
389e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  namespace ns {
399e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall    void foo(Opaque0); // expected-note 2 {{candidate function}}
409e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  }
419e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall
429e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  extern "C++" {
439e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall    using ns::foo;
449e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  }
459e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall
469e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  void test0() {
479e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall    foo(Opaque1()); // expected-error {{no matching function for call}}
489e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  }
499e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall
509e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  namespace ns {
519e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall    void foo(Opaque1);
529e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  }
539e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall
549e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  void test1() {
559e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall    foo(Opaque1()); // expected-error {{no matching function for call}}
569e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  }
579e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall
589e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  extern "C++" {
599e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall    using ns::foo;
609e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  }
619e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall
629e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  void test2() {
639e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall    foo(Opaque1());
649e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  }
659e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall}
669e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall
679e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall// Make sure we detect invalid redeclarations that can't be detected
689e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall// until template instantiation.
699e1d5827a6feaf18cb72a9d8eca80645e2075528John McCallnamespace test2 {
709e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  template <class T> struct Base {
719e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall    typedef Base type;
729e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall    void foo();
739e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  };
749e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall
759e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  template <class T> struct Derived : Base<T> {
769e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall    // These are invalid redeclarations, detectable only after
779e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall    // instantiation.
789e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall    using Base<T>::foo; // expected-note {{previous using decl}}
799e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall    using Base<T>::type::foo; //expected-error {{redeclaration of using decl}}
809e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  };
819e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall
829e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall  template struct Derived<int>; // expected-note {{in instantiation of template class}}
839e1d5827a6feaf18cb72a9d8eca80645e2075528John McCall}
842d04a90ca2f5c40da742bae370021dd98ea6fe67Douglas Gregor
852d04a90ca2f5c40da742bae370021dd98ea6fe67Douglas Gregor// Redeclarations are okay in a function.
862d04a90ca2f5c40da742bae370021dd98ea6fe67Douglas Gregornamespace test3 {
872d04a90ca2f5c40da742bae370021dd98ea6fe67Douglas Gregor  namespace N {
882d04a90ca2f5c40da742bae370021dd98ea6fe67Douglas Gregor    int f(int);
892d04a90ca2f5c40da742bae370021dd98ea6fe67Douglas Gregor    typedef int type;
902d04a90ca2f5c40da742bae370021dd98ea6fe67Douglas Gregor  }
912d04a90ca2f5c40da742bae370021dd98ea6fe67Douglas Gregor
922d04a90ca2f5c40da742bae370021dd98ea6fe67Douglas Gregor  void g() {
932d04a90ca2f5c40da742bae370021dd98ea6fe67Douglas Gregor    using N::f;
942d04a90ca2f5c40da742bae370021dd98ea6fe67Douglas Gregor    using N::f;
952d04a90ca2f5c40da742bae370021dd98ea6fe67Douglas Gregor    using N::type;
962d04a90ca2f5c40da742bae370021dd98ea6fe67Douglas Gregor    using N::type;
972d04a90ca2f5c40da742bae370021dd98ea6fe67Douglas Gregor  }
982d04a90ca2f5c40da742bae370021dd98ea6fe67Douglas Gregor}
99