From 5df6568d4035b9605586ae5d92cc114c83d5ccb3 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Mon, 17 Aug 2015 20:24:17 +0000 Subject: [PATCH] [modules] When parsing the base specifiers of a parse-merged class, the current context is the class itself but lookups should be performed starting with the lookup parent of the class (class and base members don't shadow types from the surrounding context because they have not been declared yet). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@245236 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDecl.cpp | 4 ++- .../Inputs/submodules-merge-defs/defs.h | 7 +++++ test/Modules/Inputs/template-default-args/a.h | 3 ++ test/Modules/submodules-merge-defs.cpp | 28 +++++++++---------- test/Modules/template-default-args.cpp | 3 ++ 5 files changed, 30 insertions(+), 15 deletions(-) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 9282ecad4c..a8d1e1203e 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1089,7 +1089,9 @@ Sema::SkippedDefinitionContext Sema::ActOnTagStartSkippedDefinition(Scope *S, auto Result = static_cast(CurContext); CurContext = cast(D)->getDefinition(); assert(CurContext && "skipping definition of undefined tag"); - S->setEntity(CurContext); + // Start lookups from the parent of the current context; we don't want to look + // into the pre-existing complete definition. + S->setEntity(CurContext->getLookupParent()); return Result; } diff --git a/test/Modules/Inputs/submodules-merge-defs/defs.h b/test/Modules/Inputs/submodules-merge-defs/defs.h index ba6956fb98..e9d7284719 100644 --- a/test/Modules/Inputs/submodules-merge-defs/defs.h +++ b/test/Modules/Inputs/submodules-merge-defs/defs.h @@ -5,10 +5,17 @@ class B { struct Inner1 {}; public: struct Inner2; + struct Inner3; template void f(); }; +struct BFriend { + friend class B::Inner3; +private: + struct Inner3Base {}; +}; // Check that lookup and access checks are performed in the right context. struct B::Inner2 : Inner1 {}; +struct B::Inner3 : BFriend::Inner3Base {}; template void B::f() {} template<> inline void B::f() {} diff --git a/test/Modules/Inputs/template-default-args/a.h b/test/Modules/Inputs/template-default-args/a.h index 19c80549d1..a8a01a9e31 100644 --- a/test/Modules/Inputs/template-default-args/a.h +++ b/test/Modules/Inputs/template-default-args/a.h @@ -6,4 +6,7 @@ template struct D; template struct E; template struct G; template struct H; +template struct J {}; +template struct J; +struct K : J<> {}; END diff --git a/test/Modules/submodules-merge-defs.cpp b/test/Modules/submodules-merge-defs.cpp index 62cbbd5109..6a46e6dfa8 100644 --- a/test/Modules/submodules-merge-defs.cpp +++ b/test/Modules/submodules-merge-defs.cpp @@ -26,38 +26,38 @@ int pre_use_a = use_a(pre_a); // expected-error {{'A' must be imported}} expecte B::Inner2 pre_bi; // expected-error +{{must be imported}} // expected-note@defs.h:4 +{{here}} -// expected-note@defs.h:11 +{{here}} +// expected-note@defs.h:17 +{{here}} void pre_bfi(B b) { // expected-error {{must use 'class'}} expected-error +{{must be imported}} b.f(); // expected-error +{{must be imported}} expected-error +{{}} - // expected-note@defs.h:12 +{{here}} + // expected-note@defs.h:19 +{{here}} } C_Base<1> pre_cb1; // expected-error +{{must be imported}} -// expected-note@defs.h:16 +{{here}} +// expected-note@defs.h:23 +{{here}} C1 pre_c1; // expected-error +{{must be imported}} expected-error {{must use 'struct'}} -// expected-note@defs.h:18 +{{here}} +// expected-note@defs.h:25 +{{here}} C2 pre_c2; // expected-error +{{must be imported}} expected-error {{must use 'struct'}} -// expected-note@defs.h:19 +{{here}} +// expected-note@defs.h:26 +{{here}} D::X pre_dx; // expected-error +{{must be imported}} -// expected-note@defs.h:21 +{{here}} -// expected-note@defs.h:22 +{{here}} +// expected-note@defs.h:28 +{{here}} +// expected-note@defs.h:29 +{{here}} // FIXME: We should warn that use_dx is being used without being imported. int pre_use_dx = use_dx(pre_dx); int pre_e = E(0); // expected-error {{must be imported}} -// expected-note@defs.h:25 +{{here}} +// expected-note@defs.h:32 +{{here}} int pre_ff = F().f(); // expected-error +{{must be imported}} int pre_fg = F().g(); // expected-error +{{must be imported}} -// expected-note@defs.h:27 +{{here}} +// expected-note@defs.h:34 +{{here}} G::A pre_ga // expected-error +{{must be imported}} = G::a; // expected-error +{{must be imported}} -// expected-note@defs.h:42 +{{here}} -// expected-note@defs.h:43 +{{here}} +// expected-note@defs.h:49 +{{here}} +// expected-note@defs.h:50 +{{here}} decltype(G::h) pre_gh = G::h; // expected-error +{{must be imported}} -// expected-note@defs.h:44 +{{here}} +// expected-note@defs.h:51 +{{here}} J<> pre_j; // expected-error {{declaration of 'J' must be imported}} #ifdef IMPORT_USE_2 @@ -67,10 +67,10 @@ J<> pre_j; // expected-error {{declaration of 'J' must be imported}} #else // expected-error@-6 {{default argument of 'J' must be imported from module 'stuff.use'}} #endif -// expected-note@defs.h:51 +{{here}} +// expected-note@defs.h:58 +{{here}} ScopedEnum pre_scopedenum; // expected-error {{must be imported}} expected-error {{must use 'enum'}} -// expected-note@defs.h:99 {{here}} +// expected-note@defs.h:106 {{here}} enum ScopedEnum : int; ScopedEnum pre_scopedenum_declared; // ok diff --git a/test/Modules/template-default-args.cpp b/test/Modules/template-default-args.cpp index c2a6ddca2d..3a519f2d8a 100644 --- a/test/Modules/template-default-args.cpp +++ b/test/Modules/template-default-args.cpp @@ -22,6 +22,9 @@ template struct C; template struct D {}; template struct F {}; template struct G {}; +template struct J {}; +template struct J; +struct K : J<> {}; END #include "c.h" -- 2.40.0