arphaman created this revision. arphaman added reviewers: manmanren, ahatanak, akyrtzi. arphaman added a subscriber: cfe-commits. arphaman set the repository for this revision to rL LLVM.
This patch fixes an issue where cached global code completion results for a `using` declaration included the namespace incorrectly. The issue arises because the global code completion caching performs the lookup in the entire translation unit, which then reports that the `UsingDecl` is being hidden by `UsingShadowDecl`. This leads to the nested name qualifiers being applied incorrectly to the completion result. Repository: rL LLVM https://reviews.llvm.org/D28514 Files: lib/Sema/SemaCodeComplete.cpp test/Index/complete-cached-globals.cpp 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} 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<UsingShadowDecl>(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<UsingDecl>(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} 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<UsingShadowDecl>(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<UsingDecl>(Hiding)) + Hiding = nullptr; AddResult(Result(Using->getTargetDecl(), getBasePriority(Using->getTargetDecl()), R.Qualifier),
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits