[clang-tools-extra] r347675 - [clangd] textDocument/SymbolInfo extension

Jan Korous via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 28 02:09:11 PST 2018


Thanks for the notice and sorry for the delay! I somehow missed the failure mails before I went offline yesterday.

I am just running tests on my fix now and hopefully pushing shortly.

Since I didn’t know we are using old compilers for these builds I am now curious why. Is that intentional? For backward-compatibility?

Thanks.

Jan

> On Nov 28, 2018, at 8:59 AM, Yvan Roux <yvan.roux at linaro.org> wrote:
> 
> On Wed, 28 Nov 2018 at 09:56, Mikael Holmén via cfe-commits
> <cfe-commits at lists.llvm.org <mailto:cfe-commits at lists.llvm.org>> wrote:
>> 
>> Hi Jan,
>> 
>> This code doesn't compile with clang 3.6.0:
> 
> And broke ARM bots, logs available here:
> 
> http://lab.llvm.org:8011/builders/clang-cmake-armv7-quick/builds/5582/steps/build%20stage%201/logs/stdio <http://lab.llvm.org:8011/builders/clang-cmake-armv7-quick/builds/5582/steps/build%20stage%201/logs/stdio>
> 
> Cheers,
> Yvan
> 
>> ../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 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
>>> 
>>> 
>>> _______________________________________________
>>> cfe-commits mailing list
>>> cfe-commits at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>> 
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at lists.llvm.org <mailto:cfe-commits at lists.llvm.org>
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20181128/1e321041/attachment-0001.html>


More information about the cfe-commits mailing list