clang-tools 8.0.0

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