summaryrefslogtreecommitdiff
path: root/test/Modules
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2017-10-18 01:41:38 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2017-10-18 01:41:38 +0000
commit5920af940999e0ef4041735c53d828cac90ef1fc (patch)
treeae7ebc918337f2824598efdba1877b75f4d2439d /test/Modules
parentd5aad901c029f9723373809ef0f2314be50167a0 (diff)
downloadclang-5920af940999e0ef4041735c53d828cac90ef1fc.tar.gz
[modules] When finding the owning module of an instantiated context in template
instantiation, follow lexical parents not semantic ones: we want to find the module where the pattern was written. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@316055 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Modules')
-rw-r--r--test/Modules/visibility-in-instantiation.cpp51
1 files changed, 51 insertions, 0 deletions
diff --git a/test/Modules/visibility-in-instantiation.cpp b/test/Modules/visibility-in-instantiation.cpp
new file mode 100644
index 0000000000..8689758a42
--- /dev/null
+++ b/test/Modules/visibility-in-instantiation.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -std=c++11 -fmodules %s -verify
+
+#pragma clang module build M
+ module M { module A {} module B {} module C {} }
+#pragma clang module contents
+
+ #pragma clang module begin M.A
+ template<typename U> struct X {
+ template<typename T> void f();
+ };
+ #pragma clang module end
+
+ #pragma clang module begin M.B
+ template<typename T, typename U = void> struct ST { static void f(); };
+ #pragma clang module end
+
+ #pragma clang module begin M.C
+ template<typename U> struct X;
+ void foo(X<int>);
+ #pragma clang module end
+#pragma clang module endbuild
+
+#pragma clang module build N
+ module N {}
+#pragma clang module contents
+ #pragma clang module begin N
+ #pragma clang module import M.B // not re-exported
+
+ template<typename U> struct X {
+ template<typename T> void f();
+ template<typename T> void g();
+ };
+
+ template<typename U> template<typename T>
+ void X<U>::f() {
+ ST<T>::f(); // definition and default argument found in M.B
+ foo(*this); // found by ADL in M.C
+ };
+
+ #pragma clang module import M.C // not re-exported
+ #pragma clang module end
+#pragma clang module endbuild
+
+#pragma clang module import N
+void g() {
+ X<int>().f<int>();
+
+ ST<int>::f(); // expected-error {{must be imported from module 'M.B'}}
+ foo(X<int>()); // expected-error {{must be imported from module 'M.C'}}
+ // expected-note@* 2{{previous declaration is here}}
+}