clang-tools  14.0.0git
ClangdXPCTestClient.cpp
Go to the documentation of this file.
1 //===-- ClangdXPCTestClient.cpp ----------------------------------*- C++-*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "xpc/Conversion.h"
10 #include "clang/Basic/LLVM.h"
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/Support/LineIterator.h"
13 #include "llvm/Support/MemoryBuffer.h"
14 #include "llvm/Support/Path.h"
15 #include "llvm/Support/raw_ostream.h"
16 #include <dlfcn.h>
17 #include <stdio.h>
18 #include <string>
19 #include <xpc/xpc.h>
20 
21 typedef const char *(*clangd_xpc_get_bundle_identifier_t)(void);
22 
23 using namespace llvm;
24 using namespace clang;
25 
26 static std::string getLibraryPath() {
27  Dl_info info;
28  if (dladdr((void *)(uintptr_t)getLibraryPath, &info) == 0)
29  llvm_unreachable("Call to dladdr() failed");
30  llvm::SmallString<128> LibClangPath;
31  LibClangPath = llvm::sys::path::parent_path(
32  llvm::sys::path::parent_path(info.dli_fname));
33  llvm::sys::path::append(LibClangPath, "lib", "ClangdXPC.framework",
34  "ClangdXPC");
35  return std::string(LibClangPath.str());
36 }
37 
38 static void dumpXPCObject(xpc_object_t Object, llvm::raw_ostream &OS) {
39  xpc_type_t Type = xpc_get_type(Object);
40  if (Type == XPC_TYPE_DICTIONARY) {
42  OS << Json;
43  } else {
44  OS << "<UNKNOWN>";
45  }
46 }
47 
48 int main(int argc, char *argv[]) {
49  // Open the ClangdXPC dylib in the framework.
50  std::string LibPath = getLibraryPath();
51  void *dlHandle = dlopen(LibPath.c_str(), RTLD_LOCAL | RTLD_FIRST);
52  if (!dlHandle) {
53  llvm::errs() << "Failed to load framework from \'" << LibPath << "\'\n";
54  return 1;
55  }
56 
57  // Lookup the XPC service bundle name, and launch it.
60  dlHandle, "clangd_xpc_get_bundle_identifier");
61  xpc_connection_t conn = xpc_connection_create(
62  clangd_xpc_get_bundle_identifier(), dispatch_get_main_queue());
63 
64  // Dump the XPC events.
65  xpc_connection_set_event_handler(conn, ^(xpc_object_t event) {
66  if (event == XPC_ERROR_CONNECTION_INVALID) {
67  llvm::errs() << "Received XPC_ERROR_CONNECTION_INVALID.";
68  exit(EXIT_SUCCESS);
69  }
70  if (event == XPC_ERROR_CONNECTION_INTERRUPTED) {
71  llvm::errs() << "Received XPC_ERROR_CONNECTION_INTERRUPTED.";
72  exit(EXIT_SUCCESS);
73  }
74 
75  dumpXPCObject(event, llvm::outs());
76  llvm::outs() << "\n";
77  });
78 
79  xpc_connection_resume(conn);
80 
81  // Read the input to determine the things to send to clangd.
82  llvm::ErrorOr<std::unique_ptr<MemoryBuffer>> Stdin =
83  llvm::MemoryBuffer::getSTDIN();
84  if (!Stdin) {
85  llvm::errs() << "Failed to get STDIN!\n";
86  return 1;
87  }
88  for (llvm::line_iterator It(**Stdin, /*SkipBlanks=*/true,
89  /*CommentMarker=*/'#');
90  !It.is_at_eof(); ++It) {
91  StringRef Line = *It;
92  if (auto Request = json::parse(Line)) {
93  xpc_object_t Object = clangd::jsonToXpc(*Request);
94  xpc_connection_send_message(conn, Object);
95  } else {
96  llvm::errs() << llvm::Twine("JSON parse error: ")
97  << llvm::toString(Request.takeError());
98  return 1;
99  }
100  }
101 
102  dispatch_main();
103 
104  // dispatch_main() doesn't return
105  return EXIT_FAILURE;
106 }
llvm
Some operations such as code completion produce a set of candidates.
Definition: YAMLGenerator.cpp:28
Type
NodeType Type
Definition: HTMLGenerator.cpp:73
clang::clangd::xpcToJson
json::Value xpcToJson(const xpc_object_t &XPCObject)
Definition: Conversion.cpp:26
dumpXPCObject
static void dumpXPCObject(xpc_object_t Object, llvm::raw_ostream &OS)
Definition: ClangdXPCTestClient.cpp:38
Line
int Line
Definition: PreprocessorTracker.cpp:514
main
int main(int argc, char *argv[])
Definition: ClangdXPCTestClient.cpp:48
clangd_xpc_get_bundle_identifier
const char * clangd_xpc_get_bundle_identifier()
Returns the bundle identifier of the Clangd XPC service.
Definition: ClangdXPC.cpp:10
getLibraryPath
static std::string getLibraryPath()
Definition: ClangdXPCTestClient.cpp:26
Conversion.h
clang::clangd::jsonToXpc
xpc_object_t jsonToXpc(const json::Value &JSON)
Definition: Conversion.cpp:20
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
OS
llvm::raw_string_ostream OS
Definition: TraceTests.cpp:163
clang::tidy::cppcoreguidelines::toString
static llvm::StringRef toString(SpecialMemberFunctionsCheck::SpecialMemberFunctionKind K)
Definition: SpecialMemberFunctionsCheck.cpp:55
clangd_xpc_get_bundle_identifier_t
const typedef char *(* clangd_xpc_get_bundle_identifier_t)(void)
Definition: ClangdXPCTestClient.cpp:21
Value
static constexpr bool Value
Definition: SuspiciousCallArgumentCheck.cpp:72