Stephen Hines | 176edba | 2014-12-01 14:53:08 -0800 | [diff] [blame] | 1 | // RUN: rm -rf %t |
| 2 | // RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify %s -DORDER=1 |
| 3 | // RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify %s -DORDER=2 |
| 4 | |
| 5 | #if ORDER == 1 |
| 6 | #include "a.h" |
| 7 | #include "b.h" |
| 8 | #else |
| 9 | #include "b.h" |
| 10 | #include "a.h" |
| 11 | #endif |
| 12 | |
| 13 | struct Y { |
| 14 | int value; // expected-note 0-1{{target of using}} |
| 15 | typedef int type; // expected-note 0-1{{target of using}} |
| 16 | }; |
| 17 | |
| 18 | template<typename T> int Use() { |
| 19 | int k = T().v + T().value; // expected-note 0-2{{instantiation of}} |
| 20 | typedef typename T::type I; |
| 21 | typedef typename T::t I; |
| 22 | typedef int I; |
| 23 | return k; |
| 24 | } |
| 25 | |
| 26 | template<typename T> int UseAll() { |
| 27 | return Use<C<T> >() + Use<D<T> >() + Use<E<T> >() + Use<F<T> >(); // expected-note 0-2{{instantiation of}} |
| 28 | } |
| 29 | |
| 30 | template int UseAll<YA>(); |
| 31 | template int UseAll<YB>(); |
| 32 | template int UseAll<Y>(); |
| 33 | |
| 34 | #if ORDER == 1 |
| 35 | // Here, we're instantiating the definition from 'A' and merging the definition |
| 36 | // from 'B' into it. |
| 37 | |
| 38 | // expected-error@b.h:* {{'E::value' from module 'B' is not present in definition of 'E<T>' in module 'A'}} |
| 39 | // expected-error@b.h:* {{'E::v' from module 'B' is not present in definition of 'E<T>' in module 'A'}} |
| 40 | |
| 41 | // expected-error@b.h:* {{'F::type' from module 'B' is not present in definition of 'F<T>' in module 'A'}} |
| 42 | // expected-error@b.h:* {{'F::t' from module 'B' is not present in definition of 'F<T>' in module 'A'}} |
| 43 | // expected-error@b.h:* {{'F::value' from module 'B' is not present in definition of 'F<T>' in module 'A'}} |
| 44 | // expected-error@b.h:* {{'F::v' from module 'B' is not present in definition of 'F<T>' in module 'A'}} |
| 45 | |
| 46 | // expected-note@a.h:* +{{does not match}} |
| 47 | #else |
| 48 | // Here, we're instantiating the definition from 'B' and merging the definition |
| 49 | // from 'A' into it. |
| 50 | |
| 51 | // expected-error@a.h:* {{'D::type' from module 'A' is not present in definition of 'D<T>' in module 'B'}} |
| 52 | // expected-error@a.h:* {{'D::value' from module 'A' is not present in definition of 'D<T>' in module 'B'}} |
| 53 | // expected-error@b.h:* 2{{'typename' keyword used on a non-type}} |
| 54 | // expected-error@b.h:* 2{{dependent using declaration resolved to type without 'typename'}} |
| 55 | |
| 56 | // expected-error@a.h:* {{'E::type' from module 'A' is not present in definition of 'E<T>' in module 'B'}} |
| 57 | // expected-error@a.h:* {{'E::t' from module 'A' is not present in definition of 'E<T>' in module 'B'}} |
| 58 | // expected-error@a.h:* {{'E::value' from module 'A' is not present in definition of 'E<T>' in module 'B'}} |
| 59 | // expected-error@a.h:* {{'E::v' from module 'A' is not present in definition of 'E<T>' in module 'B'}} |
| 60 | // expected-note@b.h:* 2{{definition has no member}} |
| 61 | |
| 62 | // expected-error@a.h:* {{'F::type' from module 'A' is not present in definition of 'F<T>' in module 'B'}} |
| 63 | // expected-error@a.h:* {{'F::t' from module 'A' is not present in definition of 'F<T>' in module 'B'}} |
| 64 | // expected-error@a.h:* {{'F::value' from module 'A' is not present in definition of 'F<T>' in module 'B'}} |
| 65 | // expected-error@a.h:* {{'F::v' from module 'A' is not present in definition of 'F<T>' in module 'B'}} |
| 66 | |
| 67 | // expected-note@b.h:* +{{does not match}} |
| 68 | // expected-note@b.h:* +{{target of using}} |
| 69 | #endif |