[clang-tools-extra] r372948 - [clangd] Add a helper for extracting nonlocal decls in a FunctionDecl
Kadir Cetinkaya via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 26 00:27:43 PDT 2019
Author: kadircet
Date: Thu Sep 26 00:27:43 2019
New Revision: 372948
URL: http://llvm.org/viewvc/llvm-project?rev=372948&view=rev
Log:
[clangd] Add a helper for extracting nonlocal decls in a FunctionDecl
Summary:
To be used by define-inline code action to determine whether the
function/method body will still be valid in another context.
Traverses clang-ast to find all decl nodes under the function decl and stores
the non-local ones.
Reviewers: hokein
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D67748
Modified:
clang-tools-extra/trunk/clangd/XRefs.cpp
clang-tools-extra/trunk/clangd/XRefs.h
clang-tools-extra/trunk/clangd/unittests/XRefsTests.cpp
Modified: clang-tools-extra/trunk/clangd/XRefs.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/XRefs.cpp?rev=372948&r1=372947&r2=372948&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/XRefs.cpp (original)
+++ clang-tools-extra/trunk/clangd/XRefs.cpp Thu Sep 26 00:27:43 2019
@@ -9,6 +9,7 @@
#include "AST.h"
#include "CodeCompletionStrings.h"
#include "FindSymbols.h"
+#include "FindTarget.h"
#include "FormattedString.h"
#include "Logger.h"
#include "ParsedAST.h"
@@ -1299,5 +1300,18 @@ llvm::raw_ostream &operator<<(llvm::raw_
return OS;
}
+llvm::DenseSet<const Decl *> getNonLocalDeclRefs(ParsedAST &AST,
+ const FunctionDecl *FD) {
+ if (!FD->hasBody())
+ return {};
+ llvm::DenseSet<const Decl *> DeclRefs;
+ findExplicitReferences(FD, [&](ReferenceLoc Ref) {
+ for (const Decl *D : Ref.Targets) {
+ if (!index::isFunctionLocalSymbol(D) && !D->isTemplateParameter())
+ DeclRefs.insert(D);
+ }
+ });
+ return DeclRefs;
+}
} // namespace clangd
} // namespace clang
Modified: clang-tools-extra/trunk/clangd/XRefs.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/XRefs.h?rev=372948&r1=372947&r2=372948&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/XRefs.h (original)
+++ clang-tools-extra/trunk/clangd/XRefs.h Thu Sep 26 00:27:43 2019
@@ -17,8 +17,8 @@
#include "Path.h"
#include "Protocol.h"
#include "index/Index.h"
-#include "clang/AST/Type.h"
#include "index/SymbolLocation.h"
+#include "clang/AST/Type.h"
#include "clang/Format/Format.h"
#include "clang/Index/IndexSymbol.h"
#include "llvm/ADT/Optional.h"
@@ -158,6 +158,9 @@ llvm::Optional<QualType> getDeducedType(
/// SourceLocationBeg must point to the first character of the token
bool hasDeducedType(ParsedAST &AST, SourceLocation SourceLocationBeg);
+/// Returns all decls that are referenced in the \p FD except local symbols.
+llvm::DenseSet<const Decl *> getNonLocalDeclRefs(ParsedAST &AST,
+ const FunctionDecl *FD);
} // namespace clangd
} // namespace clang
Modified: clang-tools-extra/trunk/clangd/unittests/XRefsTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/XRefsTests.cpp?rev=372948&r1=372947&r2=372948&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/XRefsTests.cpp (original)
+++ clang-tools-extra/trunk/clangd/unittests/XRefsTests.cpp Thu Sep 26 00:27:43 2019
@@ -10,6 +10,7 @@
#include "Matchers.h"
#include "ParsedAST.h"
#include "Protocol.h"
+#include "SourceCode.h"
#include "SyncAPI.h"
#include "TestFS.h"
#include "TestIndex.h"
@@ -18,13 +19,19 @@
#include "index/FileIndex.h"
#include "index/MemIndex.h"
#include "index/SymbolCollector.h"
+#include "clang/AST/Decl.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Index/IndexingAction.h"
#include "llvm/ADT/None.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/ScopedPrinter.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <string>
+#include <vector>
namespace clang {
namespace clangd {
@@ -2187,6 +2194,84 @@ TEST(GetDeducedType, KwAutoExpansion) {
}
}
+TEST(GetNonLocalDeclRefs, All) {
+ struct Case {
+ llvm::StringRef AnnotatedCode;
+ std::vector<llvm::StringRef> ExpectedDecls;
+ } Cases[] = {
+ {
+ // VarDecl and ParamVarDecl
+ R"cpp(
+ void bar();
+ void ^foo(int baz) {
+ int x = 10;
+ bar();
+ })cpp",
+ {"bar"},
+ },
+ {
+ // Method from class
+ R"cpp(
+ class Foo { public: void foo(); };
+ class Bar {
+ void foo();
+ void bar();
+ };
+ void Bar::^foo() {
+ Foo f;
+ bar();
+ f.foo();
+ })cpp",
+ {"Bar", "Bar::bar", "Foo", "Foo::foo"},
+ },
+ {
+ // Local types
+ R"cpp(
+ void ^foo() {
+ class Foo { public: void foo() {} };
+ class Bar { public: void bar() {} };
+ Foo f;
+ Bar b;
+ b.bar();
+ f.foo();
+ })cpp",
+ {},
+ },
+ {
+ // Template params
+ R"cpp(
+ template <typename T, template<typename> class Q>
+ void ^foo() {
+ T x;
+ Q<T> y;
+ })cpp",
+ {},
+ },
+ };
+ for (const Case &C : Cases) {
+ Annotations File(C.AnnotatedCode);
+ auto AST = TestTU::withCode(File.code()).build();
+ ASSERT_TRUE(AST.getDiagnostics().empty())
+ << AST.getDiagnostics().begin()->Message;
+ SourceLocation SL = llvm::cantFail(
+ sourceLocationInMainFile(AST.getSourceManager(), File.point()));
+
+ const FunctionDecl *FD =
+ llvm::dyn_cast<FunctionDecl>(&findDecl(AST, [SL](const NamedDecl &ND) {
+ return ND.getLocation() == SL && llvm::isa<FunctionDecl>(ND);
+ }));
+ ASSERT_NE(FD, nullptr);
+
+ auto NonLocalDeclRefs = getNonLocalDeclRefs(AST, FD);
+ std::vector<std::string> Names;
+ for (const Decl *D : NonLocalDeclRefs) {
+ if (const auto *ND = llvm::dyn_cast<NamedDecl>(D))
+ Names.push_back(ND->getQualifiedNameAsString());
+ }
+ EXPECT_THAT(Names, UnorderedElementsAreArray(C.ExpectedDecls));
+ }
+}
+
} // namespace
} // namespace clangd
} // namespace clang
More information about the cfe-commits
mailing list