Hi Jan, This code doesn't compile with clang 3.6.0:
../tools/clang/tools/extra/clangd/Protocol.cpp:456:10: error: no viable conversion from 'json::Object' to 'llvm::json::Value' return result; ^~~~~~ ../include/llvm/Support/JSON.h:291:3: note: candidate constructor not viable: no known conversion from 'json::Object' to 'const llvm::json::Value &' for 1st argument Value(const Value &M) { copyFrom(M); } ^ ../include/llvm/Support/JSON.h:292:3: note: candidate constructor not viable: no known conversion from 'json::Object' to 'llvm::json::Value &&' for 1st argument Value(Value &&M) { moveFrom(std::move(M)); } ^ ../include/llvm/Support/JSON.h:293:3: note: candidate constructor not viable: no known conversion from 'json::Object' to 'std::initializer_list<Value>' for 1st argument Value(std::initializer_list<Value> Elements); ^ ../include/llvm/Support/JSON.h:294:3: note: candidate constructor not viable: no known conversion from 'json::Object' to 'json::Array &&' for 1st argument Value(json::Array &&Elements) : Type(T_Array) { ^ ../include/llvm/Support/JSON.h:299:3: note: candidate constructor not viable: no known conversion from 'json::Object' to 'json::Object &&' for 1st argument Value(json::Object &&Properties) : Type(T_Object) { ^ ../include/llvm/Support/JSON.h:305:3: note: candidate constructor not viable: no known conversion from 'json::Object' to 'std::string' (aka 'basic_string<char>') for 1st argument Value(std::string V) : Type(T_String) { ^ ../include/llvm/Support/JSON.h:312:3: note: candidate constructor not viable: no known conversion from 'json::Object' to 'const llvm::SmallVectorImpl<char> &' for 1st argument Value(const llvm::SmallVectorImpl<char> &V) ^ ../include/llvm/Support/JSON.h:314:3: note: candidate constructor not viable: no known conversion from 'json::Object' to 'const llvm::formatv_object_base &' for 1st argument Value(const llvm::formatv_object_base &V) : Value(V.str()){}; ^ ../include/llvm/Support/JSON.h:316:3: note: candidate constructor not viable: no known conversion from 'json::Object' to 'llvm::StringRef' for 1st argument Value(StringRef V) : Type(T_StringRef) { ^ ../include/llvm/Support/JSON.h:323:3: note: candidate constructor not viable: no known conversion from 'json::Object' to 'const char *' for 1st argument Value(const char *V) : Value(StringRef(V)) {} ^ ../include/llvm/Support/JSON.h:324:3: note: candidate constructor not viable: no known conversion from 'json::Object' to 'std::nullptr_t' (aka 'nullptr_t') for 1st argument Value(std::nullptr_t) : Type(T_Null) {} ^ ../include/llvm/Support/JSON.h:298:3: note: candidate template ignored: could not match 'vector<type-parameter-0-0, allocator<type-parameter-0-0> >' against 'llvm::json::Object' Value(const std::vector<Elt> &C) : Value(json::Array(C)) {} ^ ../include/llvm/Support/JSON.h:303:3: note: candidate template ignored: could not match 'map<std::basic_string<char>, type-parameter-0-0, std::less<std::basic_string<char> >, allocator<pair<const std::basic_string<char>, type-parameter-0-0> > >' against 'llvm::json::Object' Value(const std::map<std::string, Elt> &C) : Value(json::Object(C)) {} ^ ../include/llvm/Support/JSON.h:329:42: note: candidate template ignored: disabled by 'enable_if' [with T = llvm::json::Object] typename = typename std::enable_if<std::is_same<T, bool>::value>::type, ^ ../include/llvm/Support/JSON.h:337:42: note: candidate template ignored: disabled by 'enable_if' [with T = llvm::json::Object] typename = typename std::enable_if<std::is_integral<T>::value>::type, ^ ../include/llvm/Support/JSON.h:345:41: note: candidate template ignored: disabled by 'enable_if' [with T = llvm::json::Object] typename std::enable_if<std::is_floating_point<T>::value>::type, ^ ../include/llvm/Support/JSON.h:355:3: note: candidate template ignored: substitution failure [with T = llvm::json::Object]: no matching function for call to 'toJSON' Value(const T &V) : Value(toJSON(V)) {} ^ 1 error generated. --- It looks very similar to a problem that was fixed in r347539: - return Result; + // Older gcc cannot compile 'return Result', even though it is legal. + return json::Value(std::move(Result)); Regards, Mikael On 11/27/18 5:40 PM, Jan Korous via cfe-commits wrote: > 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@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@foo#")} > + }, > + { > + R"cpp( // Simple function reference - definition > + void foo() {} > + int bar() { > + fo^o(); > + } > + )cpp", > + {CreateExpectedSymbolDetails("foo", "", "c:@F@foo#")} > + }, > + { > + R"cpp( // Function in namespace reference > + namespace bar { > + void foo(); > + int baz() { > + fo^o(); > + } > + } > + )cpp", > + {CreateExpectedSymbolDetails("foo", "bar::", "c:@N@bar@F@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@bar@F@foo#")} > + }, > + { > + R"cpp( // Function in global namespace reference > + void foo(); > + namespace Nbar { > + namespace Nbaz { > + int baz() { > + ::fo^o(); > + } > + } > + } > + )cpp", > + {CreateExpectedSymbolDetails("foo", "", "c:@F@foo#")} > + }, > + { > + R"cpp( // Function in anonymous namespace reference > + namespace { > + void foo(); > + } > + namespace barbar { > + int baz() { > + fo^o(); > + } > + } > + )cpp", > + {CreateExpectedSymbolDetails("foo", "(anonymous)", > "c:TestTU.cpp@aN@F@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@bar@F@foo#&1$@N@bar@S@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@49@F@foo#@aaa")} > + }, > + { > + R"cpp( // Function param > + void bar(int aaa) { > + int bbb = a^aa; > + } > + )cpp", > + {CreateExpectedSymbolDetails("aaa", "bar", > "c:TestTU.cpp@38@F@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@55@macro@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@foo#"), > + CreateExpectedSymbolDetails("foo", "", "c:@F@foo#b#"), > + CreateExpectedSymbolDetails("foo", "", "c:@F@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@218@F@func_baz2#@ff"), > + CreateExpectedSymbolDetails("bar", "bar::", > "c:@S@bar@F@bar#&1$@S@foo#"), > + } > + }, > + { > + R"cpp( // Type reference - declaration > + struct foo; > + void bar(fo^o*); > + )cpp", > + {CreateExpectedSymbolDetails("foo", "", "c:@S@foo")} > + }, > + { > + R"cpp( // Type reference - definition > + struct foo {}; > + void bar(fo^o*); > + )cpp", > + {CreateExpectedSymbolDetails("foo", "", "c:@S@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@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@foo@FI@aa")} > + }, > + { > + R"cpp( // Class member reference - pointer > + struct foo { > + int aa; > + }; > + void bar() { > + &foo::a^a; > + } > + )cpp", > + {CreateExpectedSymbolDetails("aa", "foo::", "c:@S@foo@FI@aa")} > + }, > + { > + R"cpp( // Class method reference - objec > + struct foo { > + void aa() {} > + }; > + void bar() { > + foo f; > + f.a^a(); > + } > + )cpp", > + {CreateExpectedSymbolDetails("aa", "foo::", "c:@S@foo@F@aa#")} > + }, > + { > + R"cpp( // Class method reference - pointer > + struct foo { > + void aa() {} > + }; > + void bar() { > + &foo::a^a; > + } > + )cpp", > + {CreateExpectedSymbolDetails("aa", "foo::", "c:@S@foo@F@aa#")} > + }, > + { > + R"cpp( // Typedef > + typedef int foo; > + void bar() { > + fo^o a; > + } > + )cpp", > + {CreateExpectedSymbolDetails("foo", "", "c:TestTU.cpp@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@foo")} > + }, > + { > + R"cpp( // Enum value reference > + enum foo { bar, baz }; > + void f() { > + foo fff = ba^r; > + } > + )cpp", > + {CreateExpectedSymbolDetails("bar", "foo", "c:@E@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@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 > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits