Index: lib/Sema/SemaCodeComplete.cpp =================================================================== --- lib/Sema/SemaCodeComplete.cpp +++ lib/Sema/SemaCodeComplete.cpp @@ -954,6 +954,13 @@ // Look through using declarations. if (const UsingShadowDecl *Using = dyn_cast(R.Declaration)) { + // When we are gathering global code completions for caching, the lookup + // is performed in the translation unit context which leads to a situation + // when a UsingShadowDecl hides a UsingDecl, and nested name specifiers are + // then incorrectly applied to the target declaration. This can be avoided + // by resetting the declaration that's being hidden. + if (Hiding && isa(Hiding)) + Hiding = nullptr; AddResult(Result(Using->getTargetDecl(), getBasePriority(Using->getTargetDecl()), R.Qualifier), Index: test/Index/complete-cached-globals.cpp =================================================================== --- /dev/null +++ test/Index/complete-cached-globals.cpp @@ -0,0 +1,25 @@ +// Note: the run lines follow their respective tests, since line/column +// matter in this test. + +namespace SomeNamespace { + class SomeClass { + }; + void SomeFunction(); +} + +using SomeNamespace::SomeClass; +using SomeNamespace::SomeFunction; + +static void foo() { + return; +} + +// rdar://23454249 + +// RUN: c-index-test -code-completion-at=%s:14:3 %s | FileCheck -check-prefix=CHECK-CC1 %s +// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:14:3 %s | FileCheck -check-prefix=CHECK-CC1 %s + +// CHECK-CC1: ClassDecl:{TypedText SomeClass} (50) +// CHECK-CC1: FunctionDecl:{ResultType void}{TypedText SomeFunction}{LeftParen (}{RightParen )} (50) +// CHECK-CC1-NOT: {Text SomeNamespace::}{TypedText SomeClass} +// CHECK-CC1-NOT: {Text SomeNamespace::}{TypedText SomeFunction}