Author: ioeric Date: Fri Nov 30 03:12:40 2018 New Revision: 347982 URL: http://llvm.org/viewvc/llvm-project?rev=347982&view=rev Log: [clangd] Drop injected class name when class scope is not explicitly specified.
Summary: E.g. allow injected "A::A" in `using A::A^` but not in "A^". Reviewers: kadircet Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, cfe-commits Differential Revision: https://reviews.llvm.org/D55065 Modified: clang-tools-extra/trunk/clangd/CodeComplete.cpp clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp Modified: clang-tools-extra/trunk/clangd/CodeComplete.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CodeComplete.cpp?rev=347982&r1=347981&r2=347982&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/CodeComplete.cpp (original) +++ clang-tools-extra/trunk/clangd/CodeComplete.cpp Fri Nov 30 03:12:40 2018 @@ -656,6 +656,13 @@ bool contextAllowsIndex(enum CodeComplet llvm_unreachable("unknown code completion context"); } +static bool isInjectedClass(const NamedDecl &D) { + if (auto *R = dyn_cast_or_null<RecordDecl>(&D)) + if (R->isInjectedClassName()) + return true; + return false; +} + // Some member calls are blacklisted because they're so rarely useful. static bool isBlacklistedMember(const NamedDecl &D) { // Destructor completion is rarely useful, and works inconsistently. @@ -663,9 +670,8 @@ static bool isBlacklistedMember(const Na if (D.getKind() == Decl::CXXDestructor) return true; // Injected name may be useful for A::foo(), but who writes A::A::foo()? - if (auto *R = dyn_cast_or_null<RecordDecl>(&D)) - if (R->isInjectedClassName()) - return true; + if (isInjectedClass(D)) + return true; // Explicit calls to operators are also rare. auto NameKind = D.getDeclName().getNameKind(); if (NameKind == DeclarationName::CXXOperatorName || @@ -744,6 +750,11 @@ struct CompletionRecorder : public CodeC !Context.getBaseType().isNull() // is this a member-access context? && isBlacklistedMember(*Result.Declaration)) continue; + // Skip injected class name when no class scope is not explicitly set. + // E.g. show injected A::A in `using A::A^` but not in "A^". + if (Result.Declaration && !Context.getCXXScopeSpecifier().hasValue() && + isInjectedClass(*Result.Declaration)) + continue; // We choose to never append '::' to completion results in clangd. Result.StartsNestedNameSpecifier = false; Results.push_back(Result); Modified: clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp?rev=347982&r1=347981&r2=347982&view=diff ============================================================================== --- clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp (original) +++ clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp Fri Nov 30 03:12:40 2018 @@ -416,6 +416,11 @@ TEST(CompletionTest, InjectedTypename) { Has("X")); } +TEST(CompletionTest, SkipInjectedWhenUnqualified) { + EXPECT_THAT(completions("struct X { void f() { X^ }};").Completions, + ElementsAre(Named("X"), Named("~X"))); +} + TEST(CompletionTest, Snippets) { clangd::CodeCompleteOptions Opts; auto Results = completions( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits