[clang-tools-extra] r347675 - [clangd] textDocument/SymbolInfo extension
Jan Korous via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 27 08:40:46 PST 2018
Author: jkorous
Date: Tue Nov 27 08:40:46 2018
New Revision: 347675
URL: http://llvm.org/viewvc/llvm-project?rev=347675&view=rev
Log:
[clangd] textDocument/SymbolInfo extension
New method returning symbol info for given source position.
Differential Revision: https://reviews.llvm.org/D54799
rdar://problem/46050281
Added:
clang-tools-extra/trunk/test/clangd/symbol-info.test
clang-tools-extra/trunk/unittests/clangd/SymbolInfoTests.cpp
Modified:
clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp
clang-tools-extra/trunk/clangd/ClangdLSPServer.h
clang-tools-extra/trunk/clangd/ClangdServer.cpp
clang-tools-extra/trunk/clangd/ClangdServer.h
clang-tools-extra/trunk/clangd/Protocol.cpp
clang-tools-extra/trunk/clangd/Protocol.h
clang-tools-extra/trunk/clangd/XRefs.cpp
clang-tools-extra/trunk/clangd/XRefs.h
clang-tools-extra/trunk/unittests/clangd/CMakeLists.txt
Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp?rev=347675&r1=347674&r2=347675&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp Tue Nov 27 08:40:46 2018
@@ -698,6 +698,12 @@ void ClangdLSPServer::onReference(const
std::move(Reply));
}
+void ClangdLSPServer::onSymbolInfo(const TextDocumentPositionParams &Params,
+ Callback<std::vector<SymbolDetails>> Reply) {
+ Server->symbolInfo(Params.textDocument.uri.file(), Params.position,
+ std::move(Reply));
+}
+
ClangdLSPServer::ClangdLSPServer(class Transport &Transp,
const clangd::CodeCompleteOptions &CCOpts,
Optional<Path> CompileCommandsDir,
@@ -733,6 +739,7 @@ ClangdLSPServer::ClangdLSPServer(class T
MsgHandler->bind("textDocument/didChange", &ClangdLSPServer::onDocumentDidChange);
MsgHandler->bind("workspace/didChangeWatchedFiles", &ClangdLSPServer::onFileEvent);
MsgHandler->bind("workspace/didChangeConfiguration", &ClangdLSPServer::onChangeConfiguration);
+ MsgHandler->bind("textDocument/symbolInfo", &ClangdLSPServer::onSymbolInfo);
// clang-format on
}
Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.h?rev=347675&r1=347674&r2=347675&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdLSPServer.h (original)
+++ clang-tools-extra/trunk/clangd/ClangdLSPServer.h Tue Nov 27 08:40:46 2018
@@ -92,6 +92,8 @@ private:
void onHover(const TextDocumentPositionParams &,
Callback<llvm::Optional<Hover>>);
void onChangeConfiguration(const DidChangeConfigurationParams &);
+ void onSymbolInfo(const TextDocumentPositionParams &,
+ Callback<std::vector<SymbolDetails>>);
std::vector<Fix> getFixes(StringRef File, const clangd::Diagnostic &D);
Modified: clang-tools-extra/trunk/clangd/ClangdServer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.cpp?rev=347675&r1=347674&r2=347675&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdServer.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdServer.cpp Tue Nov 27 08:40:46 2018
@@ -503,6 +503,18 @@ void ClangdServer::findReferences(PathRe
WorkScheduler.runWithAST("References", File, Bind(Action, std::move(CB)));
}
+void ClangdServer::symbolInfo(PathRef File, Position Pos,
+ Callback<std::vector<SymbolDetails>> CB) {
+ auto Action = [Pos](Callback<std::vector<SymbolDetails>> CB,
+ Expected<InputsAndAST> InpAST) {
+ if (!InpAST)
+ return CB(InpAST.takeError());
+ CB(clangd::getSymbolInfo(InpAST->AST, Pos));
+ };
+
+ WorkScheduler.runWithAST("SymbolInfo", File, Bind(Action, std::move(CB)));
+}
+
std::vector<std::pair<Path, std::size_t>>
ClangdServer::getUsedBytesPerFile() const {
return WorkScheduler.getUsedBytesPerFile();
Modified: clang-tools-extra/trunk/clangd/ClangdServer.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.h?rev=347675&r1=347674&r2=347675&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdServer.h (original)
+++ clang-tools-extra/trunk/clangd/ClangdServer.h Tue Nov 27 08:40:46 2018
@@ -202,6 +202,11 @@ public:
/// Called when an event occurs for a watched file in the workspace.
void onFileEvent(const DidChangeWatchedFilesParams &Params);
+ /// Get symbol info for given position.
+ /// Clangd extension - not part of official LSP.
+ void symbolInfo(PathRef File, Position Pos,
+ Callback<std::vector<SymbolDetails>> CB);
+
/// Returns estimated memory usage for each of the currently open files.
/// The order of results is unspecified.
/// Overall memory usage of clangd may be significantly more than reported
Modified: clang-tools-extra/trunk/clangd/Protocol.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Protocol.cpp?rev=347675&r1=347674&r2=347675&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Protocol.cpp (original)
+++ clang-tools-extra/trunk/clangd/Protocol.cpp Tue Nov 27 08:40:46 2018
@@ -14,7 +14,9 @@
#include "Protocol.h"
#include "Logger.h"
#include "URI.h"
+#include "index/Index.h"
#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormatVariadic.h"
@@ -428,6 +430,44 @@ raw_ostream &operator<<(raw_ostream &O,
return O;
}
+bool operator==(const SymbolDetails &LHS, const SymbolDetails &RHS) {
+ return LHS.name == RHS.name && LHS.containerName == RHS.containerName &&
+ LHS.USR == RHS.USR && LHS.ID == RHS.ID;
+}
+
+llvm::json::Value toJSON(const SymbolDetails &P) {
+ json::Object result{{"name", llvm::json::Value(nullptr)},
+ {"containerName", llvm::json::Value(nullptr)},
+ {"usr", llvm::json::Value(nullptr)},
+ {"id", llvm::json::Value(nullptr)}};
+
+ if (!P.name.empty())
+ result["name"] = P.name;
+
+ if (!P.containerName.empty())
+ result["containerName"] = P.containerName;
+
+ if (!P.USR.empty())
+ result["usr"] = P.USR;
+
+ if (P.ID.hasValue())
+ result["id"] = P.ID.getValue().str();
+
+ return result;
+}
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &O, const SymbolDetails &S) {
+ if (!S.containerName.empty()) {
+ O << S.containerName;
+ StringRef ContNameRef;
+ if (!ContNameRef.endswith("::")) {
+ O << " ";
+ }
+ }
+ O << S.name << " - " << toJSON(S);
+ return O;
+}
+
bool fromJSON(const json::Value &Params, WorkspaceSymbolParams &R) {
json::ObjectMapper O(Params);
return O && O.map("query", R.query);
Modified: clang-tools-extra/trunk/clangd/Protocol.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Protocol.h?rev=347675&r1=347674&r2=347675&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Protocol.h (original)
+++ clang-tools-extra/trunk/clangd/Protocol.h Tue Nov 27 08:40:46 2018
@@ -713,6 +713,26 @@ struct SymbolInformation {
llvm::json::Value toJSON(const SymbolInformation &);
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolInformation &);
+/// Represents information about identifier.
+/// This is returned from textDocument/symbolInfo, which is a clangd extension.
+struct SymbolDetails {
+ std::string name;
+
+ std::string containerName;
+
+ /// Unified Symbol Resolution identifier
+ /// This is an opaque string uniquely identifying a symbol.
+ /// Unlike SymbolID, it is variable-length and somewhat human-readable.
+ /// It is a common representation across several clang tools.
+ /// (See USRGeneration.h)
+ std::string USR;
+
+ llvm::Optional<SymbolID> ID;
+};
+llvm::json::Value toJSON(const SymbolDetails &);
+llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolDetails &);
+bool operator==(const SymbolDetails &, const SymbolDetails &);
+
/// The parameters of a Workspace Symbol Request.
struct WorkspaceSymbolParams {
/// A non-empty query string
Modified: clang-tools-extra/trunk/clangd/XRefs.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/XRefs.cpp?rev=347675&r1=347674&r2=347675&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/XRefs.cpp (original)
+++ clang-tools-extra/trunk/clangd/XRefs.cpp Tue Nov 27 08:40:46 2018
@@ -750,5 +750,48 @@ std::vector<Location> findReferences(Par
return Results;
}
+std::vector<SymbolDetails> getSymbolInfo(ParsedAST &AST, Position Pos) {
+ const SourceManager &SM = AST.getASTContext().getSourceManager();
+
+ auto Loc = getBeginningOfIdentifier(AST, Pos, SM.getMainFileID());
+ auto Symbols = getSymbolAtPosition(AST, Loc);
+
+ std::vector<SymbolDetails> Results;
+
+ for (const auto &Sym : Symbols.Decls) {
+ SymbolDetails NewSymbol;
+ if (const NamedDecl *ND = dyn_cast<NamedDecl>(Sym.D)) {
+ std::string QName = printQualifiedName(*ND);
+ std::tie(NewSymbol.containerName, NewSymbol.name) =
+ splitQualifiedName(QName);
+
+ if (NewSymbol.containerName.empty()) {
+ if (const auto *ParentND =
+ dyn_cast_or_null<NamedDecl>(ND->getDeclContext()))
+ NewSymbol.containerName = printQualifiedName(*ParentND);
+ }
+ }
+ llvm::SmallString<32> USR;
+ if (!index::generateUSRForDecl(Sym.D, USR)) {
+ NewSymbol.USR = USR.str();
+ NewSymbol.ID = SymbolID(NewSymbol.USR);
+ }
+ Results.push_back(std::move(NewSymbol));
+ }
+
+ for (const auto &Macro : Symbols.Macros) {
+ SymbolDetails NewMacro;
+ NewMacro.name = Macro.Name;
+ llvm::SmallString<32> USR;
+ if (!index::generateUSRForMacro(NewMacro.name, Loc, SM, USR)) {
+ NewMacro.USR = USR.str();
+ NewMacro.ID = SymbolID(NewMacro.USR);
+ }
+ Results.push_back(std::move(NewMacro));
+ }
+
+ return Results;
+}
+
} // 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=347675&r1=347674&r2=347675&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/XRefs.h (original)
+++ clang-tools-extra/trunk/clangd/XRefs.h Tue Nov 27 08:40:46 2018
@@ -38,6 +38,9 @@ llvm::Optional<Hover> getHover(ParsedAST
std::vector<Location> findReferences(ParsedAST &AST, Position Pos,
const SymbolIndex *Index = nullptr);
+/// Get info about symbols at \p Pos.
+std::vector<SymbolDetails> getSymbolInfo(ParsedAST &AST, Position Pos);
+
} // namespace clangd
} // namespace clang
Added: clang-tools-extra/trunk/test/clangd/symbol-info.test
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clangd/symbol-info.test?rev=347675&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clangd/symbol-info.test (added)
+++ clang-tools-extra/trunk/test/clangd/symbol-info.test Tue Nov 27 08:40:46 2018
@@ -0,0 +1,14 @@
+# RUN: clangd -lit-test < %s | FileCheck %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///simple.cpp","languageId":"cpp","version":1,"text":"void foo(); int main() { foo(); }\n"}}}
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/symbolInfo","params":{"textDocument":{"uri":"test:///simple.cpp"},"position":{"line":0,"character":27}}}
+# CHECK: "containerName": null,
+# CHECK-NEXT: "id": "CA2EBE44A1D76D2A",
+# CHECK-NEXT: "name": "foo",
+# CHECK-NEXT: "usr": "c:@F at foo#"
+---
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
Modified: clang-tools-extra/trunk/unittests/clangd/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/CMakeLists.txt?rev=347675&r1=347674&r2=347675&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/unittests/clangd/CMakeLists.txt Tue Nov 27 08:40:46 2018
@@ -35,6 +35,7 @@ add_extra_unittest(ClangdTests
SerializationTests.cpp
SourceCodeTests.cpp
SymbolCollectorTests.cpp
+ SymbolInfoTests.cpp
SyncAPI.cpp
TUSchedulerTests.cpp
TestFS.cpp
Added: clang-tools-extra/trunk/unittests/clangd/SymbolInfoTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/SymbolInfoTests.cpp?rev=347675&view=auto
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/SymbolInfoTests.cpp (added)
+++ clang-tools-extra/trunk/unittests/clangd/SymbolInfoTests.cpp Tue Nov 27 08:40:46 2018
@@ -0,0 +1,357 @@
+//===-- SymbolInfoTests.cpp -----------------------*- C++ -*--------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "Annotations.h"
+#include "ClangdUnit.h"
+#include "Compiler.h"
+#include "Matchers.h"
+#include "SyncAPI.h"
+#include "TestFS.h"
+#include "TestTU.h"
+#include "XRefs.h"
+#include "index/FileIndex.h"
+#include "index/SymbolCollector.h"
+#include "clang/Index/IndexingAction.h"
+#include "llvm/Support/Path.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+namespace clang {
+namespace clangd {
+namespace {
+
+using testing::ElementsAreArray;
+
+auto CreateExpectedSymbolDetails = [](const std::string &name,
+ const std::string &container,
+ const std::string &USR) {
+ return SymbolDetails{name, container, USR, SymbolID(USR)};
+};
+
+TEST(SymbolInfoTests, All) {
+ std::pair<const char *, std::vector<SymbolDetails>>
+ TestInputExpectedOutput[] = {
+ {
+ R"cpp( // Simple function reference - declaration
+ void foo();
+ int bar() {
+ fo^o();
+ }
+ )cpp",
+ {CreateExpectedSymbolDetails("foo", "", "c:@F at foo#")}
+ },
+ {
+ R"cpp( // Simple function reference - definition
+ void foo() {}
+ int bar() {
+ fo^o();
+ }
+ )cpp",
+ {CreateExpectedSymbolDetails("foo", "", "c:@F at foo#")}
+ },
+ {
+ R"cpp( // Function in namespace reference
+ namespace bar {
+ void foo();
+ int baz() {
+ fo^o();
+ }
+ }
+ )cpp",
+ {CreateExpectedSymbolDetails("foo", "bar::", "c:@N at bar@F at foo#")}
+ },
+ {
+ R"cpp( // Function in different namespace reference
+ namespace bar {
+ void foo();
+ }
+ namespace barbar {
+ int baz() {
+ bar::fo^o();
+ }
+ }
+ )cpp",
+ {CreateExpectedSymbolDetails("foo", "bar::", "c:@N at bar@F at foo#")}
+ },
+ {
+ R"cpp( // Function in global namespace reference
+ void foo();
+ namespace Nbar {
+ namespace Nbaz {
+ int baz() {
+ ::fo^o();
+ }
+ }
+ }
+ )cpp",
+ {CreateExpectedSymbolDetails("foo", "", "c:@F at foo#")}
+ },
+ {
+ R"cpp( // Function in anonymous namespace reference
+ namespace {
+ void foo();
+ }
+ namespace barbar {
+ int baz() {
+ fo^o();
+ }
+ }
+ )cpp",
+ {CreateExpectedSymbolDetails("foo", "(anonymous)", "c:TestTU.cpp at aN@F at foo#")}
+ },
+ {
+ R"cpp( // Function reference - ADL
+ namespace bar {
+ struct BarType {};
+ void foo(const BarType&);
+ }
+ namespace barbar {
+ int baz() {
+ bar::BarType b;
+ fo^o(b);
+ }
+ }
+ )cpp",
+ {CreateExpectedSymbolDetails("foo", "bar::", "c:@N at bar@F at foo#&1$@N at bar@S at BarType#")}
+ },
+ {
+ R"cpp( // Global value reference
+ int value;
+ void foo(int) { }
+ void bar() {
+ foo(val^ue);
+ }
+ )cpp",
+ {CreateExpectedSymbolDetails("value", "", "c:@value")}
+ },
+ {
+ R"cpp( // Local value reference
+ void foo() { int aaa; int bbb = aa^a; }
+ )cpp",
+ {CreateExpectedSymbolDetails("aaa", "foo", "c:TestTU.cpp at 49@F at foo#@aaa")}
+ },
+ {
+ R"cpp( // Function param
+ void bar(int aaa) {
+ int bbb = a^aa;
+ }
+ )cpp",
+ {CreateExpectedSymbolDetails("aaa", "bar", "c:TestTU.cpp at 38@F at bar#I#@aaa")}
+ },
+ {
+ R"cpp( // Lambda capture
+ int ii;
+ auto lam = [ii]() {
+ return i^i;
+ };
+ )cpp",
+ {CreateExpectedSymbolDetails("ii", "", "c:@ii")}
+ },
+ {
+ R"cpp( // Macro reference
+ #define MACRO 5\nint i = MAC^RO;
+ )cpp",
+ {CreateExpectedSymbolDetails("MACRO", "", "c:TestTU.cpp at 55@macro at MACRO")}
+ },
+ {
+ R"cpp( // Multiple symbols returned - using overloaded function name
+ void foo() {}
+ void foo(bool) {}
+ void foo(int) {}
+ namespace bar {
+ using ::fo^o;
+ }
+ )cpp",
+ {
+ CreateExpectedSymbolDetails("foo", "", "c:@F at foo#"),
+ CreateExpectedSymbolDetails("foo", "", "c:@F at foo#b#"),
+ CreateExpectedSymbolDetails("foo", "", "c:@F at foo#I#")
+ }
+ },
+ {
+ R"cpp( // Multiple symbols returned - implicit conversion
+ struct foo {};
+ struct bar {
+ bar(const foo&) {}
+ };
+ void func_baz1(bar) {}
+ void func_baz2() {
+ foo ff;
+ func_baz1(f^f);
+ }
+ )cpp",
+ {
+ CreateExpectedSymbolDetails("ff", "func_baz2", "c:TestTU.cpp at 218@F at func_baz2#@ff"),
+ CreateExpectedSymbolDetails("bar", "bar::", "c:@S at bar@F at bar#&1$@S at foo#"),
+ }
+ },
+ {
+ R"cpp( // Type reference - declaration
+ struct foo;
+ void bar(fo^o*);
+ )cpp",
+ {CreateExpectedSymbolDetails("foo", "", "c:@S at foo")}
+ },
+ {
+ R"cpp( // Type reference - definition
+ struct foo {};
+ void bar(fo^o*);
+ )cpp",
+ {CreateExpectedSymbolDetails("foo", "", "c:@S at foo")}
+ },
+ {
+ R"cpp( // Type Reference - template argumen
+ struct foo {};
+ template<class T> struct bar {};
+ void baz() {
+ bar<fo^o> b;
+ }
+ )cpp",
+ {CreateExpectedSymbolDetails("foo", "", "c:@S at foo")}
+ },
+ {
+ R"cpp( // Template parameter reference - type param
+ template<class TT> struct bar {
+ T^T t;
+ };
+ )cpp",
+ { /* not implemented */ }
+ },
+ {
+ R"cpp( // Template parameter reference - type param
+ template<int NN> struct bar {
+ int a = N^N;
+ };
+ )cpp",
+ { /* not implemented */ }
+ },
+ {
+ R"cpp( // Class member reference - objec
+ struct foo {
+ int aa;
+ };
+ void bar() {
+ foo f;
+ f.a^a;
+ }
+ )cpp",
+ {CreateExpectedSymbolDetails("aa", "foo::", "c:@S at foo@FI at aa")}
+ },
+ {
+ R"cpp( // Class member reference - pointer
+ struct foo {
+ int aa;
+ };
+ void bar() {
+ &foo::a^a;
+ }
+ )cpp",
+ {CreateExpectedSymbolDetails("aa", "foo::", "c:@S at foo@FI at aa")}
+ },
+ {
+ R"cpp( // Class method reference - objec
+ struct foo {
+ void aa() {}
+ };
+ void bar() {
+ foo f;
+ f.a^a();
+ }
+ )cpp",
+ {CreateExpectedSymbolDetails("aa", "foo::", "c:@S at foo@F at aa#")}
+ },
+ {
+ R"cpp( // Class method reference - pointer
+ struct foo {
+ void aa() {}
+ };
+ void bar() {
+ &foo::a^a;
+ }
+ )cpp",
+ {CreateExpectedSymbolDetails("aa", "foo::", "c:@S at foo@F at aa#")}
+ },
+ {
+ R"cpp( // Typedef
+ typedef int foo;
+ void bar() {
+ fo^o a;
+ }
+ )cpp",
+ {CreateExpectedSymbolDetails("foo", "", "c:TestTU.cpp at T@foo")}
+ },
+ {
+ R"cpp( // Type alias
+ using foo = int;
+ void bar() {
+ fo^o a;
+ }
+ )cpp",
+ {CreateExpectedSymbolDetails("foo", "", "c:@foo")}
+ },
+ {
+ R"cpp( // Namespace reference
+ namespace foo {}
+ using namespace fo^o;
+ )cpp",
+ {CreateExpectedSymbolDetails("foo", "", "c:@N at foo")}
+ },
+ {
+ R"cpp( // Enum value reference
+ enum foo { bar, baz };
+ void f() {
+ foo fff = ba^r;
+ }
+ )cpp",
+ {CreateExpectedSymbolDetails("bar", "foo", "c:@E at foo@bar")}
+ },
+ {
+ R"cpp( // Enum class value reference
+ enum class foo { bar, baz };
+ void f() {
+ foo fff = foo::ba^r;
+ }
+ )cpp",
+ {CreateExpectedSymbolDetails("bar", "foo::", "c:@E at foo@bar")}
+ },
+ {
+ R"cpp( // Type inferrence with auto keyword
+ struct foo {};
+ foo getfoo() { return foo{}; }
+ void f() {
+ au^to a = getfoo();
+ }
+ )cpp",
+ {/* not implemented */}
+ },
+ {
+ R"cpp( // decltype
+ struct foo {};
+ void f() {
+ foo f;
+ declt^ype(f);
+ }
+ )cpp",
+ {/* not implemented */}
+ },
+ };
+
+ for (const auto &T : TestInputExpectedOutput) {
+ Annotations TestInput(T.first);
+ auto AST = TestTU::withCode(TestInput.code()).build();
+
+ EXPECT_THAT(getSymbolInfo(AST, TestInput.point()),
+ ElementsAreArray(T.second))
+ << T.first;
+ }
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang
More information about the cfe-commits
mailing list