struct Base1 {
  int member1;
  float member2;
};

struct Base2 {
  int member1;
  double member3;
  void memfun1(int);
};

struct Base3 : Base1, Base2 {
  void memfun1(float);
  void memfun1(double) const;
  void memfun2(int);
};

struct Derived : Base3 {
  int member4;
  int memfun3(int);
};

class Proxy {
public:
  Derived *operator->() const;
};

void test(const Proxy &p) {
  p->
}

struct Test1 {
  Base1 b;

  static void sfunc() {
    b. // expected-error {{invalid use of member 'b' in static member function}}
  }
};

struct Foo {
  void foo() const;
  static void foo(bool);
};

struct Bar {
  void foo(bool param) {
    Foo::foo(  );// unresolved member expression with an implicit base
  }
};

  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:29:6 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
  // CHECK-CC1: Base1 : Base1::
  // CHECK-CC1: member1 : [#int#][#Base1::#]member1
  // CHECK-CC1: member1 : [#int#][#Base2::#]member1
  // CHECK-CC1: member2 : [#float#][#Base1::#]member2
  // CHECK-CC1: member3
  // CHECK-CC1: member4
  // CHECK-CC1: memfun1 : [#void#][#Base3::#]memfun1(<#float#>)
  // CHECK-CC1: memfun1 : [#void#][#Base3::#]memfun1(<#double#>)[# const#]
  // CHECK-CC1: memfun1 (Hidden) : [#void#]Base2::memfun1(<#int#>)
  // CHECK-CC1: memfun2 : [#void#][#Base3::#]memfun2(<#int#>)
  // CHECK-CC1: memfun3 : [#int#]memfun3(<#int#>)

// Make sure this doesn't crash
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:36:7 %s -verify

// Make sure this also doesn't crash
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:47:14 %s


template<typename T>
class BaseTemplate {
public:
  T baseTemplateFunction();

  T baseTemplateField;
};

template<typename T, typename S>
class TemplateClass: public Base1 , public BaseTemplate<T> {
public:
  T function() { }
  T field;

  void overload1(const T &);
  void overload1(const S &);
};

template<typename T, typename S>
void completeDependentMembers(TemplateClass<T, S> &object,
                              TemplateClass<int, S> *object2) {
  object.field;
  object2->field;
// CHECK-CC2: baseTemplateField : [#T#][#BaseTemplate<T>::#]baseTemplateField
// CHECK-CC2: baseTemplateFunction : [#T#][#BaseTemplate<T>::#]baseTemplateFunction()
// CHECK-CC2: field : [#T#]field
// CHECK-CC2: function : [#T#]function()
// CHECK-CC2: member1 : [#int#][#Base1::#]member1
// CHECK-CC2: member2 : [#float#][#Base1::#]member2
// CHECK-CC2: overload1 : [#void#]overload1(<#const T &#>)
// CHECK-CC2: overload1 : [#void#]overload1(<#const S &#>)

// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:92:10 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:93:12 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
}


void completeDependentSpecializedMembers(TemplateClass<int, double> &object,
                                         TemplateClass<int, double> *object2) {
  object.field;
  object2->field;
// CHECK-CC3: baseTemplateField : [#int#][#BaseTemplate<int>::#]baseTemplateField
// CHECK-CC3: baseTemplateFunction : [#int#][#BaseTemplate<int>::#]baseTemplateFunction()
// CHECK-CC3: field : [#int#]field
// CHECK-CC3: function : [#int#]function()
// CHECK-CC3: member1 : [#int#][#Base1::#]member1
// CHECK-CC3: member2 : [#float#][#Base1::#]member2
// CHECK-CC3: overload1 : [#void#]overload1(<#const int &#>)
// CHECK-CC3: overload1 : [#void#]overload1(<#const double &#>)

// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:110:10 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:111:12 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s
}

template <typename T>
class Template {
public:
  BaseTemplate<int> o1;
  BaseTemplate<T> o2;

  void function() {
    o1.baseTemplateField;
// CHECK-CC4: BaseTemplate : BaseTemplate::
// CHECK-CC4: baseTemplateField : [#int#]baseTemplateField
// CHECK-CC4: baseTemplateFunction : [#int#]baseTemplateFunction()
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:132:8 %s -o - | FileCheck -check-prefix=CHECK-CC4 %s
    o2.baseTemplateField;
// CHECK-CC5: BaseTemplate : BaseTemplate::
// CHECK-CC5: baseTemplateField : [#T#]baseTemplateField
// CHECK-CC5: baseTemplateFunction : [#T#]baseTemplateFunction()
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:137:8 %s -o - | FileCheck -check-prefix=CHECK-CC5 %s
    this->o1;
// CHECK-CC6: [#void#]function()
// CHECK-CC6: o1 : [#BaseTemplate<int>#]o1
// CHECK-CC6: o2 : [#BaseTemplate<T>#]o2
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:142:11 %s -o - | FileCheck -check-prefix=CHECK-CC6 %s
  }

  static void staticFn(T &obj);

  struct Nested { };
};

template<typename T>
void dependentColonColonCompletion() {
  Template<T>::staticFn();
// CHECK-CC7: function : [#void#]function()
// CHECK-CC7: Nested : Nested
// CHECK-CC7: o1 : [#BaseTemplate<int>#]o1
// CHECK-CC7: o2 : [#BaseTemplate<T>#]o2
// CHECK-CC7: staticFn : [#void#]staticFn(<#T &obj#>)
// CHECK-CC7: Template : Template
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:156:16 %s -o - | FileCheck -check-prefix=CHECK-CC7 %s
  typename Template<T>::Nested m;
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:164:25 %s -o - | FileCheck -check-prefix=CHECK-CC7 %s
}
