Home | History | Annotate | Download | only in basic.lookup.classref
      1 // RUN: %clang_cc1 -fsyntax-only -fdiagnostics-show-option -verify %s
      2 
      3 // C++98 [basic.lookup.classref]p1:
      4 //   In a class member access expression (5.2.5), if the . or -> token is
      5 //   immediately followed by an identifier followed by a <, the identifier must
      6 //   be looked up to determine whether the < is the beginning of a template
      7 //   argument list (14.2) or a less-than operator. The identifier is first
      8 //   looked up in the class of the object expression. If the identifier is not
      9 //   found, it is then looked up in the context of the entire postfix-expression
     10 //   and shall name a class or function template. If the lookup in the class of
     11 //   the object expression finds a template, the name is also looked up in the
     12 //   context of the entire postfix-expression and
     13 //    -- if the name is not found, the name found in the class of the object
     14 //       expression is used, otherwise
     15 //    -- if the name is found in the context of the entire postfix-expression
     16 //       and does not name a class template, the name found in the class of the
     17 //       object expression is used, otherwise
     18 //    -- if the name found is a class template, it must refer to the same
     19 //       entity as the one found in the class of the object expression,
     20 //       otherwise the program is ill-formed.
     21 
     22 // From PR 7247
     23 template<typename T>
     24 struct set{};  // expected-note{{lookup from the current scope refers here}}
     25 struct Value {
     26   template<typename T>
     27   void set(T value) {}  // expected-note{{lookup in the object type 'Value' refers here}}
     28 
     29   void resolves_to_same() {
     30     Value v;
     31     v.set<double>(3.2);
     32   }
     33 };
     34 void resolves_to_different() {
     35   {
     36     Value v;
     37     // The fact that the next line is a warning rather than an error is an
     38     // extension.
     39     v.set<double>(3.2);  // expected-warning{{lookup of 'set' in member access expression is ambiguous; using member of 'Value'}}
     40   }
     41   {
     42     int set;  // Non-template.
     43     Value v;
     44     v.set<double>(3.2);
     45   }
     46 }
     47 
     48 namespace rdar9915664 {
     49   struct A {
     50     template<typename T> void a();
     51   };
     52 
     53   struct B : A { };
     54 
     55   struct C : A { };
     56 
     57   struct D : B, C {
     58     A &getA() { return static_cast<B&>(*this); }
     59 
     60     void test_a() {
     61       getA().a<int>();
     62     }
     63   };
     64 }
     65 
     66 namespace PR11856 {
     67   template<typename T> T end(T);
     68 
     69   template <typename T>
     70   void Foo() {
     71     T it1;
     72     if (it1->end < it1->end) {
     73     }
     74   }
     75 
     76   template<typename T> T *end(T*);
     77 
     78   class X { };
     79   template <typename T>
     80   void Foo2() {
     81     T it1;
     82     if (it1->end < it1->end) {
     83     }
     84 
     85     X *x;
     86     if (x->end < 7) {  // expected-error{{no member named 'end' in 'PR11856::X'}}
     87     }
     88   }
     89 }
     90