[PATCH] D50452: [WIP] clangd XPC adapter

2018-08-08 Thread Jan Korous via Phabricator via cfe-commits
jkorous created this revision.
jkorous added reviewers: arphaman, sammccall, ilya-biryukov, simark.
Herald added subscribers: cfe-commits, dexonsmith, MaskRay, ioeric, mgorny.

Based on our internal discussions we decided to change our direction with XPC 
support for clangd. We did some extra measurements and found out that JSON 
serialized over XPC is good enough for our use-case. We also took into 
consideration that we'd have to deal with support for multiple workspaces in 
near future.

Probably the simplest solution is to keep XPC completely out of clangd binary 
and use one clangd instance per workspace. This design means it's the least 
intrusive change, it's rather simple (compared to adding support for multiple 
workspaces to clangd itself) and robust (compared to threads-based 
implementation). Long-term it's hopefully also going to be less 
maintenance-demanding since it's dependent only on LSP and not it's 
implementation.

The patch is nearly finished - I just wanted to get some feedback on the design 
early on (before finishing doxygen annotations, documentation, etc.).

Our approach to testing for the future is to reuse existing clangd lit tests 
and just send messages through our XPC code. For the time being there's just a 
single minimal testcase.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D50452

Files:
  CMakeLists.txt
  Features.inc.in
  clangd/CMakeLists.txt
  clangd/xpc/initialize.test
  lit.cfg
  lit.site.cfg.in
  xpc/CMakeLists.txt
  xpc/README.txt
  xpc/cmake/Info.plist.in
  xpc/cmake/XPCServiceInfo.plist.in
  xpc/cmake/modules/CreateClangdXPCFramework.cmake
  xpc/framework/CMakeLists.txt
  xpc/framework/ClangdXPC.cpp
  xpc/test-client/CMakeLists.txt
  xpc/test-client/ClangdXPCTestClient.cpp
  xpc/tool/CMakeLists.txt
  xpc/tool/ClangdSubprocess.cpp
  xpc/tool/ClangdSubprocess.h
  xpc/tool/ClangdWorkspaceInstances.cpp
  xpc/tool/ClangdWorkspaceInstances.h
  xpc/tool/ClangdXpcAdapter.cpp
  xpc/tool/log.h

Index: clangd/CMakeLists.txt
===
--- clangd/CMakeLists.txt
+++ clangd/CMakeLists.txt
@@ -51,4 +51,4 @@
   clangToolingInclusions
   LLVMSupport
   LLVMTestingSupport
-  )
+  )
\ No newline at end of file
Index: lit.site.cfg.in
===
--- lit.site.cfg.in
+++ lit.site.cfg.in
@@ -11,6 +11,7 @@
 config.python_executable = "@PYTHON_EXECUTABLE@"
 config.target_triple = "@TARGET_TRIPLE@"
 config.clang_staticanalyzer = @CLANG_ENABLE_STATIC_ANALYZER@
+config.clangd_xpc_support = @CLANGD_BUILD_XPC@
 
 # Support substitution of the tools and libs dirs with user parameters. This is
 # used when we can't determine the tool dir at configuration time.
Index: lit.cfg
===
--- lit.cfg
+++ lit.cfg
@@ -117,6 +117,10 @@
 if platform.system() not in ['Windows']:
 config.available_features.add('ansi-escape-sequences')
 
+# XPC support for Clangd.
+if config.clangd_xpc_support:
+config.available_features.add('clangd-xpc-support')
+
 if config.clang_staticanalyzer:
 config.available_features.add('static-analyzer')
 check_clang_tidy = os.path.join(
Index: clangd/xpc/initialize.test
===
--- /dev/null
+++ clangd/xpc/initialize.test
@@ -0,0 +1,10 @@
+# RUN: clangd-xpc-test-client < %s | FileCheck %s
+# REQUIRES: clangd-xpc-support
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootUri":"test:///workspace","capabilities":{},"trace":"off"}}
+# CHECK-DAG: {"id":0,"jsonrpc":"2.0","result":{"capabilities":{"codeActionProvider":true,"completionProvider":{"resolveProvider":false,"triggerCharacters":[".",">",":"]},"definitionProvider":true,"documentFormattingProvider":true,"documentHighlightProvider":true,"documentOnTypeFormattingProvider":{"firstTriggerCharacter":"}","moreTriggerCharacter":[]},"documentRangeFormattingProvider":true,"documentSymbolProvider":true,"executeCommandProvider":{"commands":["clangd.applyFix"]},"hoverProvider":true,"renameProvider":true,"signatureHelpProvider":{"triggerCharacters":["(",","]},"textDocumentSync":2,"workspaceSymbolProvider":true}}}
+
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+# CHECK-DAG: {"id":3,"jsonrpc":"2.0","result":null}
+
+{"jsonrpc":"2.0","method":"exit"}
Index: xpc/tool/log.h
===
--- /dev/null
+++ xpc/tool/log.h
@@ -0,0 +1,49 @@
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_XPC_LOG_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_XPC_LOG_H
+
+#include 
+#include 
+
+#include 
+
+class Logger {
+private:
+  enum class log_type { log, info, debug };
+  log_type type;
+  std::string buffer_data;
+  std::stringstream buffer;
+  Logger(log_type type) : type(type), buffer_data(), buffer(buffer_data) {}
+
+public:
+  template  Logger &operator<<(const T &in) {
+buffer << in;
+return *this;
+  }
+  friend 

[PATCH] D49548: [clangd] XPC WIP

2018-08-08 Thread Jan Korous via Phabricator via cfe-commits
jkorous abandoned this revision.
jkorous added a comment.

We decided to abandon this direction in favor of simpler solution.
https://reviews.llvm.org/D50452

One of the reasons is that there's a design fault - handling of 
server-originated messages (notifications) in this patch.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D49548



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48559: [clangd] refactoring for XPC transport layer [NFCI]

2018-08-08 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

Hi, we decided to go with a different solution:
https://reviews.llvm.org/D50452


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D48559



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48562: [clangd] XPC transport layer

2018-08-08 Thread Jan Korous via Phabricator via cfe-commits
jkorous abandoned this revision.
jkorous added a comment.

We decided to go with a different solution:
https://reviews.llvm.org/D50452


https://reviews.llvm.org/D48562



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50641: [clangd][test] Fix exit messages in tests

2018-08-13 Thread Jan Korous via Phabricator via cfe-commits
jkorous created this revision.
jkorous added reviewers: sammccall, ilya-biryukov.
jkorous added a project: clang-tools-extra.
Herald added subscribers: cfe-commits, arphaman, dexonsmith, MaskRay, ioeric.

There's a small typo in tests - causing that we aren't sending exit LSP message 
to clangd but crashing it instead with the last message not being valid JSON 
and clangd hitting unexpected EOF in runLanguageServerLoop() right after. Seems 
like this bug even managed to spawn some offsprings via copy-pasting. I just 
found it by accident since I am not closing stdin after the last message when 
using XPC adapter and my test was hanging - waiting for clangd to exit.

It's not a big deal but I got two ideas.

1. Maybe we should somehow check stderr from clangd - in this case there was 
JSON parse error present but tests didn't notice.
2. When fixing that I got surprised by shutdown-without-exit.test 
implementation. It seems more like exit-without-shutdown to me and makes sense 
that we still want to exit (with non-success return value) in such case. Was 
this the intention?

What do you think?


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D50641

Files:
  clangd/extra-flags.test
  clangd/formatting.test
  clangd/initialize-params.test
  clangd/shutdown-with-exit.test
  clangd/shutdown-without-exit.test
  clangd/unsupported-method.test


Index: clangd/unsupported-method.test
===
--- clangd/unsupported-method.test
+++ clangd/unsupported-method.test
@@ -13,4 +13,4 @@
 ---
 {"jsonrpc":"2.0","id":2,"method":"shutdown"}
 ---
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0","method":"exit"}
Index: clangd/shutdown-without-exit.test
===
--- clangd/shutdown-without-exit.test
+++ clangd/shutdown-without-exit.test
@@ -1,2 +1,2 @@
 # RUN: not clangd -lit-test < %s
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0","method":"exit"}
Index: clangd/shutdown-with-exit.test
===
--- clangd/shutdown-with-exit.test
+++ clangd/shutdown-with-exit.test
@@ -1,4 +1,4 @@
 # RUN: clangd -lit-test < %s
 {"jsonrpc":"2.0","id":3,"method":"shutdown"}
 ---
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0","method":"exit"}
Index: clangd/initialize-params.test
===
--- clangd/initialize-params.test
+++ clangd/initialize-params.test
@@ -46,4 +46,4 @@
 # CHECK-NEXT:  "jsonrpc": "2.0",
 # CHECK-NEXT:  "result": null
 ---
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0","method":"exit"}
Index: clangd/formatting.test
===
--- clangd/formatting.test
+++ clangd/formatting.test
@@ -184,4 +184,4 @@
 ---
 {"jsonrpc":"2.0","id":6,"method":"shutdown"}
 ---
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0","method":"exit"}
Index: clangd/extra-flags.test
===
--- clangd/extra-flags.test
+++ clangd/extra-flags.test
@@ -47,6 +47,6 @@
 ---
 {"jsonrpc":"2.0","id":5,"method":"shutdown"}
 ---
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0","method":"exit"}
 
 


Index: clangd/unsupported-method.test
===
--- clangd/unsupported-method.test
+++ clangd/unsupported-method.test
@@ -13,4 +13,4 @@
 ---
 {"jsonrpc":"2.0","id":2,"method":"shutdown"}
 ---
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0","method":"exit"}
Index: clangd/shutdown-without-exit.test
===
--- clangd/shutdown-without-exit.test
+++ clangd/shutdown-without-exit.test
@@ -1,2 +1,2 @@
 # RUN: not clangd -lit-test < %s
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0","method":"exit"}
Index: clangd/shutdown-with-exit.test
===
--- clangd/shutdown-with-exit.test
+++ clangd/shutdown-with-exit.test
@@ -1,4 +1,4 @@
 # RUN: clangd -lit-test < %s
 {"jsonrpc":"2.0","id":3,"method":"shutdown"}
 ---
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0","method":"exit"}
Index: clangd/initialize-params.test
===
--- clangd/initialize-params.test
+++ clangd/initialize-params.test
@@ -46,4 +46,4 @@
 # CHECK-NEXT:  "jsonrpc": "2.0",
 # CHECK-NEXT:  "result": null
 ---
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0","method":"exit"}
Index: clangd/formatting.test
===
--- clangd/formatting.test
+++ clangd/formatting.test
@@ -184,4 +184,4 @@
 ---
 {"jsonrpc":"2.0","id":6,"method":"shutdown"}
 ---
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0","method":"exit"}
Index: clangd/extra-flags.test
===
--- clangd/extra-flags.t

[PATCH] D50641: [clangd][test] Fix exit messages in tests

2018-08-14 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

I think that by introducing different codepath for testing purposes we might 
end up with fewer bugs in tests but the actual production code could become 
less tested. Actually, even the -lit-test itself might be not the theoretically 
most correct approach but I do see the practical reason for it. In general I'd 
rather keep the testing specific code to a minimum though.

What we might be able to do specifically for this case is to return false iff 
we hit unexpected EOF in clangd::runLanguageServerLoop() (currently void) and 
|| it with ShutdownRequestReceived in ClangdLSPServer::run().

I still see some value in monitoring clangd's stderr in tests in general 
though. I can imagine something simple like redirection of clangd's stderr to a 
file and just grepping the log for lines starting with "E[" and in case of some 
set of errors being expected/allowed for specific test case then grepping for 
negation (grep -v expected_error). There might be some work necessary to either 
recalibrate log levels or add allowed errors to large part of tests. For 
example clangd currently logs this error for most tests:

  E[11:24:49.910] Failed to get status for RootPath clangd: No such file or 
directory


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D50641



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50641: [clangd][test] Fix exit messages in tests

2018-08-14 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

I can see the value of getting more information in case of unexpected test 
behaviour but I still don't really like to have separate codepath for testing 
purposes.

Anyway, it's not a big deal and it looks like you guys are all in agreement 
about this.

I created a patch that I will put for review (rebuilding and running tests 
overnight).


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D50641



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50641: [clangd][test] Fix exit messages in tests

2018-08-15 Thread Jan Korous via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL339781: [clangd][tests] Fix typo in tests - invalid LSP exit 
message (authored by jkorous, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D50641?vs=160367&id=160819#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D50641

Files:
  clang-tools-extra/trunk/test/clangd/extra-flags.test
  clang-tools-extra/trunk/test/clangd/formatting.test
  clang-tools-extra/trunk/test/clangd/initialize-params.test
  clang-tools-extra/trunk/test/clangd/shutdown-with-exit.test
  clang-tools-extra/trunk/test/clangd/shutdown-without-exit.test
  clang-tools-extra/trunk/test/clangd/unsupported-method.test


Index: clang-tools-extra/trunk/test/clangd/extra-flags.test
===
--- clang-tools-extra/trunk/test/clangd/extra-flags.test
+++ clang-tools-extra/trunk/test/clangd/extra-flags.test
@@ -49,6 +49,6 @@
 ---
 {"jsonrpc":"2.0","id":5,"method":"shutdown"}
 ---
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0","method":"exit"}
 
 
Index: clang-tools-extra/trunk/test/clangd/shutdown-without-exit.test
===
--- clang-tools-extra/trunk/test/clangd/shutdown-without-exit.test
+++ clang-tools-extra/trunk/test/clangd/shutdown-without-exit.test
@@ -1,2 +1,2 @@
 # RUN: not clangd -lit-test < %s
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0","method":"exit"}
Index: clang-tools-extra/trunk/test/clangd/initialize-params.test
===
--- clang-tools-extra/trunk/test/clangd/initialize-params.test
+++ clang-tools-extra/trunk/test/clangd/initialize-params.test
@@ -46,4 +46,4 @@
 # CHECK-NEXT:  "jsonrpc": "2.0",
 # CHECK-NEXT:  "result": null
 ---
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0","method":"exit"}
Index: clang-tools-extra/trunk/test/clangd/formatting.test
===
--- clang-tools-extra/trunk/test/clangd/formatting.test
+++ clang-tools-extra/trunk/test/clangd/formatting.test
@@ -184,4 +184,4 @@
 ---
 {"jsonrpc":"2.0","id":6,"method":"shutdown"}
 ---
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0","method":"exit"}
Index: clang-tools-extra/trunk/test/clangd/unsupported-method.test
===
--- clang-tools-extra/trunk/test/clangd/unsupported-method.test
+++ clang-tools-extra/trunk/test/clangd/unsupported-method.test
@@ -13,4 +13,4 @@
 ---
 {"jsonrpc":"2.0","id":2,"method":"shutdown"}
 ---
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0","method":"exit"}
Index: clang-tools-extra/trunk/test/clangd/shutdown-with-exit.test
===
--- clang-tools-extra/trunk/test/clangd/shutdown-with-exit.test
+++ clang-tools-extra/trunk/test/clangd/shutdown-with-exit.test
@@ -1,4 +1,4 @@
 # RUN: clangd -lit-test < %s
 {"jsonrpc":"2.0","id":3,"method":"shutdown"}
 ---
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0","method":"exit"}


Index: clang-tools-extra/trunk/test/clangd/extra-flags.test
===
--- clang-tools-extra/trunk/test/clangd/extra-flags.test
+++ clang-tools-extra/trunk/test/clangd/extra-flags.test
@@ -49,6 +49,6 @@
 ---
 {"jsonrpc":"2.0","id":5,"method":"shutdown"}
 ---
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0","method":"exit"}
 
 
Index: clang-tools-extra/trunk/test/clangd/shutdown-without-exit.test
===
--- clang-tools-extra/trunk/test/clangd/shutdown-without-exit.test
+++ clang-tools-extra/trunk/test/clangd/shutdown-without-exit.test
@@ -1,2 +1,2 @@
 # RUN: not clangd -lit-test < %s
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0","method":"exit"}
Index: clang-tools-extra/trunk/test/clangd/initialize-params.test
===
--- clang-tools-extra/trunk/test/clangd/initialize-params.test
+++ clang-tools-extra/trunk/test/clangd/initialize-params.test
@@ -46,4 +46,4 @@
 # CHECK-NEXT:  "jsonrpc": "2.0",
 # CHECK-NEXT:  "result": null
 ---
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0","method":"exit"}
Index: clang-tools-extra/trunk/test/clangd/formatting.test
===
--- clang-tools-extra/trunk/test/clangd/formatting.test
+++ clang-tools-extra/trunk/test/clangd/formatting.test
@@ -184,4 +184,4 @@
 ---
 {"jsonrpc":"2.0","id":6,"method":"shutdown"}
 ---
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0","method":"exit"}
Index: clang-tools-extra/trunk/test/clangd/unsupported-method.test
===
--- clang-tools-extra/trunk/test/clangd/unsupported-method.test
+++ clang-tools-extra/trunk/test/clangd/

[PATCH] D50785: [clangd][tests] Add exit(EXIT_FAILURE) in case of JSON parsing failure in TestMode

2018-08-15 Thread Jan Korous via Phabricator via cfe-commits
jkorous created this revision.
jkorous added reviewers: arphaman, ilya-biryukov.
jkorous added a project: clang-tools-extra.
Herald added subscribers: cfe-commits, dexonsmith, MaskRay, ioeric.

This is meant to cause a visible fail when clangd gets invalid JSON payload in 
-lit-test mode.

Based on discussion in https://reviews.llvm.org/D50641 (and 
http://lists.llvm.org/pipermail/clangd-dev/2018-August/72.html).


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D50785

Files:
  ClangdLSPServer.cpp
  ClangdLSPServer.h
  JSONRPCDispatcher.cpp
  JSONRPCDispatcher.h
  tool/ClangdMain.cpp


Index: tool/ClangdMain.cpp
===
--- tool/ClangdMain.cpp
+++ tool/ClangdMain.cpp
@@ -308,5 +308,6 @@
   llvm::set_thread_name("clangd.main");
   // Change stdin to binary to not lose \r\n on windows.
   llvm::sys::ChangeStdinToBinary();
-  return LSPServer.run(stdin, InputStyle) ? 0 : NoShutdownRequestErrorCode;
+  return LSPServer.run(stdin, Test, InputStyle) ? 0
+: NoShutdownRequestErrorCode;
 }
Index: JSONRPCDispatcher.h
===
--- JSONRPCDispatcher.h
+++ JSONRPCDispatcher.h
@@ -109,7 +109,8 @@
 /// with signals, which are sent by debuggers on some OSs.
 void runLanguageServerLoop(std::FILE *In, JSONOutput &Out,
JSONStreamStyle InputStyle,
-   JSONRPCDispatcher &Dispatcher, bool &IsDone);
+   JSONRPCDispatcher &Dispatcher, bool &IsDone,
+   bool TestMode);
 
 } // namespace clangd
 } // namespace clang
Index: JSONRPCDispatcher.cpp
===
--- JSONRPCDispatcher.cpp
+++ JSONRPCDispatcher.cpp
@@ -342,8 +342,8 @@
 // The C APIs seem to be clearer in this respect.
 void clangd::runLanguageServerLoop(std::FILE *In, JSONOutput &Out,
JSONStreamStyle InputStyle,
-   JSONRPCDispatcher &Dispatcher,
-   bool &IsDone) {
+   JSONRPCDispatcher &Dispatcher, bool &IsDone,
+   bool TestMode) {
   auto &ReadMessage =
   (InputStyle == Delimited) ? readDelimitedMessage : readStandardMessage;
   while (!IsDone && !feof(In)) {
@@ -362,6 +362,8 @@
 // Parse error. Log the raw message.
 vlog("<<< {0}\n", *JSON);
 elog("JSON parse error: {0}", llvm::toString(Doc.takeError()));
+if (TestMode)
+  exit(EXIT_FAILURE);
   }
 }
   }
Index: ClangdLSPServer.h
===
--- ClangdLSPServer.h
+++ ClangdLSPServer.h
@@ -43,7 +43,7 @@
   /// each instance of ClangdLSPServer.
   ///
   /// \return Whether we received a 'shutdown' request before an 'exit' 
request.
-  bool run(std::FILE *In,
+  bool run(std::FILE *In, bool TestMode,
JSONStreamStyle InputStyle = JSONStreamStyle::Standard);
 
 private:
Index: ClangdLSPServer.cpp
===
--- ClangdLSPServer.cpp
+++ ClangdLSPServer.cpp
@@ -447,7 +447,8 @@
   CCOpts(CCOpts), SupportedSymbolKinds(defaultSymbolKinds()),
   Server(CDB.getCDB(), FSProvider, /*DiagConsumer=*/*this, Opts) {}
 
-bool ClangdLSPServer::run(std::FILE *In, JSONStreamStyle InputStyle) {
+bool ClangdLSPServer::run(std::FILE *In, bool TestMode,
+  JSONStreamStyle InputStyle) {
   assert(!IsDone && "Run was called before");
 
   // Set up JSONRPCDispatcher.
@@ -457,7 +458,7 @@
   registerCallbackHandlers(Dispatcher, /*Callbacks=*/*this);
 
   // Run the Language Server loop.
-  runLanguageServerLoop(In, Out, InputStyle, Dispatcher, IsDone);
+  runLanguageServerLoop(In, Out, InputStyle, Dispatcher, IsDone, TestMode);
 
   // Make sure IsDone is set to true after this method exits to ensure 
assertion
   // at the start of the method fires if it's ever executed again.


Index: tool/ClangdMain.cpp
===
--- tool/ClangdMain.cpp
+++ tool/ClangdMain.cpp
@@ -308,5 +308,6 @@
   llvm::set_thread_name("clangd.main");
   // Change stdin to binary to not lose \r\n on windows.
   llvm::sys::ChangeStdinToBinary();
-  return LSPServer.run(stdin, InputStyle) ? 0 : NoShutdownRequestErrorCode;
+  return LSPServer.run(stdin, Test, InputStyle) ? 0
+: NoShutdownRequestErrorCode;
 }
Index: JSONRPCDispatcher.h
===
--- JSONRPCDispatcher.h
+++ JSONRPCDispatcher.h
@@ -109,7 +109,8 @@
 /// with signals, which are sent by debuggers on some OSs.
 void runLanguageServerLoop(std::FILE *In, JSONOutput &Out,
JSONStreamStyle InputStyle,
-   JSO

[PATCH] D50462: Try building complete AST after a fatal error was emitted if further diagnostics are expected

2018-08-16 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a reviewer: vsapsai.
jkorous added a comment.

Adding Volodymyr who landed related patch recently.


Repository:
  rC Clang

https://reviews.llvm.org/D50462



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50740: [SourceManager] isPointWithin: avoid using isBeforeInTranslationUnit, compare buffer offsets directly for lexical correctness

2018-08-16 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

Hi Alex, nice work!

I am just wondering if it would be beneficial to assert Loc and End are in the 
same file. It might help to catch bugs.

I also stumbled upon this function but not sure it makes things significantly 
cleaner here:
https://clang.llvm.org/doxygen/SourceLocation_8h_source.html#l00175

LGTM otherwise.


Repository:
  rC Clang

https://reviews.llvm.org/D50740



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50785: [clangd][tests] Add exit(EXIT_FAILURE) in case of JSON parsing failure in TestMode

2018-08-16 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

Oh, I thought that what everyone wanted was test-specific behaviour. I like 
both approaches you propose much more!
If we go for the generic option we can effectively start "checking stderr" in 
tests by using the flag. That would be nice.

Just to be sure we are all on the same page:

1. Do we want to exit right after elog() call?
2. Do we consider calling exit() in elog() smart or hacky?

Based on quick grepping if we'd like to propagate errors probably the biggest 
challenge would be ASTWorker.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D50785



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46747: [Sema] Use dotted form of macOS version for unguarded availability FixIts

2018-05-11 Thread Jan Korous via Phabricator via cfe-commits
jkorous created this revision.
jkorous added reviewers: arphaman, erik.pilkington, vsapsai.
jkorous added a project: clang.
Herald added a subscriber: cfe-commits.

E. g. use "10.11" instead of "10_11".

This is just a consistency fix - the dotted format is already used everywhere 
else.

rdar://problem/39845032


Repository:
  rC Clang

https://reviews.llvm.org/D46747

Files:
  lib/Sema/SemaDeclAttr.cpp
  test/FixIt/fixit-availability-method.mm


Index: test/FixIt/fixit-availability-method.mm
===
--- /dev/null
+++ test/FixIt/fixit-availability-method.mm
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx-10.11 -Wunguarded-availability 
-fdiagnostics-parseable-fixits -fsyntax-only -verify %s
+
+@interface foo
+- (void) method_bar __attribute__((availability(macos, introduced = 10.12))); 
// expected-note {{'method_bar' has been explicitly marked partial here}}
+@end
+
+int main() {
+[foo method_bar]; // \
+// expected-warning {{'method_bar' is only available on macOS 10.12 or 
newer}} \
+// expected-note {{enclose 'method_bar' in an @available check to silence 
this warning}} \
+// CHECK: "fix-it:.*if (@available(macOS 10.12, *))"
+return 0;
+}
Index: lib/Sema/SemaDeclAttr.cpp
===
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -7467,6 +7467,7 @@
 const AvailabilityAttr *AA =
   getAttrForPlatform(SemaRef.getASTContext(), OffendingDecl);
 VersionTuple Introduced = AA->getIntroduced();
+Introduced.UseDotAsSeparator();
 
 if (AvailabilityStack.back() >= Introduced)
   return;


Index: test/FixIt/fixit-availability-method.mm
===
--- /dev/null
+++ test/FixIt/fixit-availability-method.mm
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx-10.11 -Wunguarded-availability -fdiagnostics-parseable-fixits -fsyntax-only -verify %s
+
+@interface foo
+- (void) method_bar __attribute__((availability(macos, introduced = 10.12))); // expected-note {{'method_bar' has been explicitly marked partial here}}
+@end
+
+int main() {
+[foo method_bar]; // \
+// expected-warning {{'method_bar' is only available on macOS 10.12 or newer}} \
+// expected-note {{enclose 'method_bar' in an @available check to silence this warning}} \
+// CHECK: "fix-it:.*if (@available(macOS 10.12, *))"
+return 0;
+}
Index: lib/Sema/SemaDeclAttr.cpp
===
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -7467,6 +7467,7 @@
 const AvailabilityAttr *AA =
   getAttrForPlatform(SemaRef.getASTContext(), OffendingDecl);
 VersionTuple Introduced = AA->getIntroduced();
+Introduced.UseDotAsSeparator();
 
 if (AvailabilityStack.back() >= Introduced)
   return;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46747: [Sema] Use dotted form of macOS version for unguarded availability FixIts

2018-05-11 Thread Jan Korous via Phabricator via cfe-commits
jkorous planned changes to this revision.
jkorous added a comment.

Sorry, my bad. I tried to get rid of dependency on Foundation.h and didn't 
check the test is relevant for the fix after that.

  #import 
  
  @interface foo
  - (void) method NS_AVAILABLE_MAC(10_12);
  @end
  
  int main() {
  [foo method];
  return 0;
  }

Looks like NS_AVAILABLE_MAC is not equivalent to the attribute.

Interesting question about UsesUnderscores, thanks! It looks like it must be 
set through constructor somewhere - will figure this out.


Repository:
  rC Clang

https://reviews.llvm.org/D46747



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46747: [Sema] Use dotted form of macOS version for unguarded availability FixIts

2018-05-14 Thread Jan Korous via Phabricator via cfe-commits
jkorous updated this revision to Diff 146605.
jkorous added a comment.

Fixed the test. It turned out that version component separator for availability 
is set during parsing which is why all other tests (including my bad one) are 
passing.

The only way how to set underscore as a separator is through VersionTuple 
constructor...

https://clang.llvm.org/doxygen/classclang_1_1VersionTuple.html#a71e5354ccb617494136bdcb4d208a573

  clang::VersionTuple::VersionTuple (   unsignedMajor,
unsignedMinor,
unsignedSubminor,
unsignedBuild,
boolUsesUnderscores = false 
  )

...which is exactly what is happening during parsing version tuple...

  VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
// ...
return VersionTuple(Major, Minor, Subminor, (AfterMajorSeparator == '_'));
  }

...which function is called when parsing availability attribute:

  void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
// ...
VersionTuple Version = ParseVersionTuple(VersionRange);
// ...
  }


https://reviews.llvm.org/D46747

Files:
  lib/Sema/SemaDeclAttr.cpp
  test/FixIt/fixit-availability-method.mm


Index: test/FixIt/fixit-availability-method.mm
===
--- /dev/null
+++ test/FixIt/fixit-availability-method.mm
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx-10.11 -Wunguarded-availability 
-fdiagnostics-parseable-fixits -fsyntax-only -verify %s
+
+@interface foo
+- (void) method_bar __attribute__((availability(macosx, introduced = 10_12))); 
// expected-note {{'method_bar' has been explicitly marked partial here}}
+@end
+
+int main() {
+[foo method_bar]; // \
+// expected-warning {{'method_bar' is only available on macOS 10.12 or 
newer}} \
+// expected-note {{enclose 'method_bar' in an @available check to silence 
this warning}} \
+// CHECK: "fix-it:.*if (@available(macOS 10.12, *))"
+return 0;
+}
Index: lib/Sema/SemaDeclAttr.cpp
===
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -7467,6 +7467,7 @@
 const AvailabilityAttr *AA =
   getAttrForPlatform(SemaRef.getASTContext(), OffendingDecl);
 VersionTuple Introduced = AA->getIntroduced();
+Introduced.UseDotAsSeparator();
 
 if (AvailabilityStack.back() >= Introduced)
   return;


Index: test/FixIt/fixit-availability-method.mm
===
--- /dev/null
+++ test/FixIt/fixit-availability-method.mm
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx-10.11 -Wunguarded-availability -fdiagnostics-parseable-fixits -fsyntax-only -verify %s
+
+@interface foo
+- (void) method_bar __attribute__((availability(macosx, introduced = 10_12))); // expected-note {{'method_bar' has been explicitly marked partial here}}
+@end
+
+int main() {
+[foo method_bar]; // \
+// expected-warning {{'method_bar' is only available on macOS 10.12 or newer}} \
+// expected-note {{enclose 'method_bar' in an @available check to silence this warning}} \
+// CHECK: "fix-it:.*if (@available(macOS 10.12, *))"
+return 0;
+}
Index: lib/Sema/SemaDeclAttr.cpp
===
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -7467,6 +7467,7 @@
 const AvailabilityAttr *AA =
   getAttrForPlatform(SemaRef.getASTContext(), OffendingDecl);
 VersionTuple Introduced = AA->getIntroduced();
+Introduced.UseDotAsSeparator();
 
 if (AvailabilityStack.back() >= Introduced)
   return;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46747: [Sema] Use dotted form of macOS version for unguarded availability FixIts

2018-05-14 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

I am not 100% sure it's the best thing to set printing style at the point of 
parsing version tuples but I am not sure it's bad either. Unless someone 
convinces me otherwise I would rather not do any major changes.


https://reviews.llvm.org/D46747



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46834: [Sema][Cxx17] Error message for C++17 static_assert(pred) without string literal

2018-05-14 Thread Jan Korous via Phabricator via cfe-commits
jkorous created this revision.
jkorous added reviewers: arphaman, dexonsmith, rsmith, doug.gregor.
jkorous added a project: clang.
Herald added a subscriber: cfe-commits.

C++17 adds form of static_assert without string literal.

  static_assert ( bool_constexpr )

Currently clang produces diagnostics like this:

  assert.cpp:1:1: error: static_assert failed
  static_assert(false);
  ^ ~
  1 error generated.

This patch adds assert expression to error message in case string literal is 
missing:

  /Users/jkorous/assert.cpp:1:1: error: static_assert failed "false"
  static_assert(false);
  ^ ~
  1 error generated.

Reasons why printing assert expression in absence of string literal is useful 
are:

1. Serialized diagnostics (--serialize-diagnostics) don't contain code snippet 
and thus error message lack context.
2. No all tools scraping clang diagnostics use caret snippet provided by 
-f-caret-diagnostics.

This patch doesn't address message length limit as currently clang doesn't 
truncate messages anyway but it might be subject of another patch.

rdar://problem/38931241


Repository:
  rC Clang

https://reviews.llvm.org/D46834

Files:
  lib/Parse/ParseDeclCXX.cpp
  lib/Sema/SemaDeclCXX.cpp
  test/SemaCXX/static-assert-cxx17.cpp
  test/SemaCXX/static-assert.cpp


Index: test/SemaCXX/static-assert.cpp
===
--- test/SemaCXX/static-assert.cpp
+++ test/SemaCXX/static-assert.cpp
@@ -50,7 +50,7 @@
 StaticAssertProtected sap2; // expected-note {{instantiation}}
 
 static_assert(true); // expected-warning {{C++17 extension}}
-static_assert(false); // expected-error-re {{failed{{$ expected-warning 
{{extension}}
+static_assert(false); // expected-error {{static_assert failed "false"}} 
expected-warning {{C++17 extension}}
 
 
 // Diagnostics for static_assert with multiple conditions
Index: test/SemaCXX/static-assert-cxx17.cpp
===
--- /dev/null
+++ test/SemaCXX/static-assert-cxx17.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
+
+static_assert(false, "foo"); // expected-error {{static_assert failed "foo"}}
+static_assert(false == true); // expected-error {{static_assert failed "false 
== true"}}
+static_assert(false, "foo \"bar\" baz"); // expected-error {{static_assert 
failed "foo \"bar\" baz"}}
Index: lib/Sema/SemaDeclCXX.cpp
===
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -13736,9 +13736,16 @@
 
 if (!Failed && !Cond) {
   SmallString<256> MsgBuffer;
-  llvm::raw_svector_ostream Msg(MsgBuffer);
-  if (AssertMessage)
-AssertMessage->printPretty(Msg, nullptr, getPrintingPolicy());
+  {
+llvm::raw_svector_ostream Msg(MsgBuffer);
+if (AssertMessage)
+  AssertMessage->printPretty(Msg, nullptr, getPrintingPolicy());
+else {
+  AssertExpr->printPretty(Msg, nullptr, getPrintingPolicy());
+  MsgBuffer.insert(MsgBuffer.begin(), '\"');
+  MsgBuffer.append(1, '\"');
+}
+  }
 
   Expr *InnerCond = nullptr;
   std::string InnerCondDescription;
@@ -13747,11 +13754,12 @@
/*AllowTopLevelCond=*/false);
   if (InnerCond) {
 Diag(StaticAssertLoc, diag::err_static_assert_requirement_failed)
-  << InnerCondDescription << !AssertMessage
-  << Msg.str() << InnerCond->getSourceRange();
+  << InnerCondDescription << MsgBuffer.empty() << MsgBuffer.str()
+  << InnerCond->getSourceRange();
   } else {
 Diag(StaticAssertLoc, diag::err_static_assert_failed)
-  << !AssertMessage << Msg.str() << AssertExpr->getSourceRange();
+  << MsgBuffer.empty() << MsgBuffer.str()
+  << AssertExpr->getSourceRange();
   }
   Failed = true;
 }
Index: lib/Parse/ParseDeclCXX.cpp
===
--- lib/Parse/ParseDeclCXX.cpp
+++ lib/Parse/ParseDeclCXX.cpp
@@ -819,7 +819,10 @@
 
 /// ParseStaticAssertDeclaration - Parse C++0x or C11 
static_assert-declaration.
 ///
-/// [C++0x] static_assert-declaration:
+/// [C++17] static_assert-declaration:
+///   static_assert ( constant-expression  ) ;
+///
+/// [C++11] static_assert-declaration:
 ///   static_assert ( constant-expression  ,  string-literal  ) ;
 ///
 /// [C11]   static_assert-declaration:


Index: test/SemaCXX/static-assert.cpp
===
--- test/SemaCXX/static-assert.cpp
+++ test/SemaCXX/static-assert.cpp
@@ -50,7 +50,7 @@
 StaticAssertProtected sap2; // expected-note {{instantiation}}
 
 static_assert(true); // expected-warning {{C++17 extension}}
-static_assert(false); // expected-error-re {{failed{{$ expected-warning {{extension}}
+static_assert(false); // expected-error {{stati

[PATCH] D46485: Add python tool to dump and construct header maps

2018-05-15 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

Hi Bruno, I just noticed couple of implementation details.




Comment at: utils/hmaptool/hmaptool:55
+# The number of buckets must be a power of two.
+if num_buckets == 0 or (num_buckets & num_buckets - 1) != 0:
+raise SystemExit("error: %s: invalid number of buckets" % (

Wouldn't it be simpler to use modulo 2?

```
if num_buckets % 2 == 0
```



Comment at: utils/hmaptool/hmaptool:153
+def next_power_of_two(value):
+for i in range(32):
+power = 1 << i

This is probably not critically important but maybe we could use math functions 
instead of iteration here:


```
from math import *
return ceil( log( value + 1, 2) )
```

...or if we want to support values <1:
```
if value <= 0
raise ArgumentError
if value < 1
return 0

return ceil( log( value, 2) ) + 1
```



Comment at: utils/hmaptool/hmaptool:234
+
+if len(args) != 2:
+parser.error("invalid number of arguments")

Aren't we expecting just single argument () here?


Repository:
  rC Clang

https://reviews.llvm.org/D46485



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46747: [Sema] Use dotted form of macOS version for unguarded availability FixIts

2018-05-15 Thread Jan Korous via Phabricator via cfe-commits
jkorous planned changes to this revision.
jkorous added a comment.

Sorry for me being dense here - since the output format is determined by input 
source code there's more work to do.

I tried to change format of introduced version in couple of tests and the 
output mirrors the change. That basically means that whenever someone uses 
underscore

  __attribute__((availability(macosx, introduced = 10_12)))

instead of dot

  __attribute__((availability(macosx, introduced = 10.12)))

Warnings and FixIts get underscore as well.

I am now thinking about just switching to dot format in 
ParseAvailabilityAttribute() because it's much simpler to maintain consistency 
that way.


https://reviews.llvm.org/D46747



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46747: [Sema] Use dotted form of macOS version for unguarded availability FixIts

2018-05-16 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

Eric, thanks for the context. I am now clarifying internally and if possible 
would like to simplify the whole format business by using just one delimiter 
everywhere. Would that make sense to you or do you think we should respect 
delimiter used in sources?


https://reviews.llvm.org/D46747



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46834: [Sema][Cxx17] Error message for C++17 static_assert(pred) without string literal

2018-05-16 Thread Jan Korous via Phabricator via cfe-commits
jkorous abandoned this revision.
jkorous added a comment.

We reconsidered this in light of the policy - thanks for pointing that out 
Richard! 
Just to be sure that I understand it - the policy is meant for CLI and not 
serialized diagnostics, right?


Repository:
  rC Clang

https://reviews.llvm.org/D46834



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46485: Add python tool to dump and construct header maps

2018-05-16 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

LGTM but my review was fairly superficial.




Comment at: utils/hmaptool/hmaptool:55
+# The number of buckets must be a power of two.
+if num_buckets == 0 or (num_buckets & num_buckets - 1) != 0:
+raise SystemExit("error: %s: invalid number of buckets" % (

bruno wrote:
> jkorous wrote:
> > Wouldn't it be simpler to use modulo 2?
> > 
> > ```
> > if num_buckets % 2 == 0
> > ```
> We want it to be a power of two, not just a multiple.
Of course! Sorry, my mistake.



Comment at: utils/hmaptool/hmaptool:155
+raise ArgumentError
+return 1 if value == 0 else 2**(value - 1).bit_length()
+

Thanks for teaching me bit_length()!


https://reviews.llvm.org/D46485



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46747: [Sema] Use dotted form of macOS version for unguarded availability FixIts

2018-05-16 Thread Jan Korous via Phabricator via cfe-commits
jkorous updated this revision to Diff 147184.
jkorous added a comment.
This revision is now accepted and ready to land.

After some internal discussion we agreed that we can simplify things and get 
consistent behaviour by using dot everywhere in diagnostics.

This is pretty much revert of r219124 + update of tests.


https://reviews.llvm.org/D46747

Files:
  AST/DeclBase.cpp
  Basic/VersionTuple.cpp
  Misc/ast-print-objectivec.m
  Parse/ParseDecl.cpp
  Sema/availability-guard-format.mm
  SemaObjC/attr-availability-1.m
  clang/Basic/VersionTuple.h

Index: SemaObjC/attr-availability-1.m
===
--- SemaObjC/attr-availability-1.m
+++ SemaObjC/attr-availability-1.m
@@ -25,10 +25,10 @@
 // rdar://11475360
 @interface B : A
 - (void)method; // NOTE: we expect 'method' to *not* inherit availability.
-- (void)overridden __attribute__((availability(macosx,introduced=10_4))); // expected-warning{{overriding method introduced after overridden method on macOS (10_4 vs. 10_3)}}
+- (void)overridden __attribute__((availability(macosx,introduced=10_4))); // expected-warning{{overriding method introduced after overridden method on macOS (10.4 vs. 10.3)}}
 - (void)overridden2 __attribute__((availability(macosx,introduced=10_2)));
 - (void)overridden3 __attribute__((availability(macosx,deprecated=10_4)));
-- (void)overridden4 __attribute__((availability(macosx,deprecated=10_2))); // expected-warning{{overriding method deprecated before overridden method on macOS (10_3 vs. 10_2)}}
+- (void)overridden4 __attribute__((availability(macosx,deprecated=10_2))); // expected-warning{{overriding method deprecated before overridden method on macOS (10.3 vs. 10.2)}}
 - (void)overridden5 __attribute__((availability(macosx,introduced=10_3)));
 - (void)overridden6 __attribute__((availability(macosx,unavailable))); // expected-warning{{overriding method cannot be unavailable on macOS when its overridden method is available}}
 @end
Index: Sema/availability-guard-format.mm
===
--- /dev/null
+++ Sema/availability-guard-format.mm
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx-10.11 -Wunguarded-availability -fdiagnostics-parseable-fixits -fsyntax-only -verify %s
+
+// Testing that even for source code using '_' as a delimiter in availability version tuple '.' is actually used in diagnostic output as a delimiter.
+
+@interface foo
+- (void) method_bar __attribute__((availability(macosx, introduced = 10_12))); // expected-note {{'method_bar' has been explicitly marked partial here}}
+@end
+
+int main() {
+[foo method_bar]; // \
+// expected-warning {{'method_bar' is only available on macOS 10.12 or newer}} \
+// expected-note {{enclose 'method_bar' in an @available check to silence this warning}} \
+// CHECK: "fix-it:.*if (@available(macOS 10.12, *))"
+return 0;
+}
Index: Misc/ast-print-objectivec.m
===
--- Misc/ast-print-objectivec.m
+++ Misc/ast-print-objectivec.m
@@ -30,7 +30,7 @@
 // CHECK: @end
 
 // CHECK: @interface I(CAT)
-// CHECK: - (void)MethCAT __attribute__((availability(macos, introduced=10_1_0, deprecated=10_2)));
+// CHECK: - (void)MethCAT __attribute__((availability(macos, introduced=10.1.0, deprecated=10.2)));
 // CHECK: @end
 
 // CHECK: @implementation I
Index: Parse/ParseDecl.cpp
===
--- Parse/ParseDecl.cpp
+++ Parse/ParseDecl.cpp
@@ -762,8 +762,10 @@
 ///
 /// version:
 ///   simple-integer
-///   simple-integer ',' simple-integer
-///   simple-integer ',' simple-integer ',' simple-integer
+///   simple-integer '.' simple-integer
+///   simple-integer '_' simple-integer
+///   simple-integer '.' simple-integer '.' simple-integer
+///   simple-integer '_' simple-integer '_' simple-integer
 VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
   Range = SourceRange(Tok.getLocation(), Tok.getEndLoc());
 
@@ -841,7 +843,7 @@
   return VersionTuple();
 }
 
-return VersionTuple(Major, Minor, (AfterMajorSeparator == '_'));
+return VersionTuple(Major, Minor);
   }
 
   const char AfterMinorSeparator = ThisTokBegin[AfterMinor];
@@ -872,7 +874,7 @@
 return VersionTuple();
   }
   ConsumeToken();
-  return VersionTuple(Major, Minor, Subminor, (AfterMajorSeparator == '_'));
+  return VersionTuple(Major, Minor, Subminor);
 }
 
 /// Parse the contents of the "availability" attribute.
Index: Basic/VersionTuple.cpp
===
--- Basic/VersionTuple.cpp
+++ Basic/VersionTuple.cpp
@@ -29,11 +29,11 @@
  const VersionTuple &V) {
   Out << V.getMajor();
   if (Optional Minor = V.getMinor())
-Out << (V.usesUnderscores() ? '_' : '.') << *Minor;
+Out << '.' << *Minor;
   if (Optional Subminor = V.getSubminor())
-Out << (V.usesUndersc

[PATCH] D46747: [Sema] Use dotted form of macOS version for unguarded availability FixIts

2018-05-17 Thread Jan Korous via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL332598: Use dotted format of version tuple for availability 
diagnostics (authored by jkorous, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D46747?vs=147184&id=147295#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D46747

Files:
  cfe/trunk/include/clang/Basic/VersionTuple.h
  cfe/trunk/lib/AST/DeclBase.cpp
  cfe/trunk/lib/Basic/VersionTuple.cpp
  cfe/trunk/lib/Parse/ParseDecl.cpp
  cfe/trunk/test/Misc/ast-print-objectivec.m
  cfe/trunk/test/Sema/availability-guard-format.mm
  cfe/trunk/test/SemaObjC/attr-availability-1.m

Index: cfe/trunk/include/clang/Basic/VersionTuple.h
===
--- cfe/trunk/include/clang/Basic/VersionTuple.h
+++ cfe/trunk/include/clang/Basic/VersionTuple.h
@@ -24,9 +24,7 @@
 
 /// Represents a version number in the form major[.minor[.subminor[.build]]].
 class VersionTuple {
-  unsigned Major : 31;
-
-  unsigned UsesUnderscores : 1;
+  unsigned Major : 32;
 
   unsigned Minor : 31;
   unsigned HasMinor : 1;
@@ -39,30 +37,25 @@
 
 public:
   VersionTuple()
-  : Major(0), UsesUnderscores(false), Minor(0), HasMinor(false),
-Subminor(0), HasSubminor(false), Build(0), HasBuild(false) {}
+  : Major(0), Minor(0), HasMinor(false), Subminor(0), HasSubminor(false),
+Build(0), HasBuild(false) {}
 
   explicit VersionTuple(unsigned Major)
-  : Major(Major), UsesUnderscores(false), Minor(0), HasMinor(false),
-Subminor(0), HasSubminor(false), Build(0), HasBuild(false) {}
-
-  explicit VersionTuple(unsigned Major, unsigned Minor,
-bool UsesUnderscores = false)
-  : Major(Major), UsesUnderscores(UsesUnderscores), Minor(Minor),
-HasMinor(true), Subminor(0), HasSubminor(false), Build(0),
-HasBuild(false) {}
+  : Major(Major), Minor(0), HasMinor(false), Subminor(0),
+HasSubminor(false), Build(0), HasBuild(false) {}
 
-  explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor,
-bool UsesUnderscores = false)
-  : Major(Major), UsesUnderscores(UsesUnderscores), Minor(Minor),
-HasMinor(true), Subminor(Subminor), HasSubminor(true), Build(0),
-HasBuild(false) {}
+  explicit VersionTuple(unsigned Major, unsigned Minor)
+  : Major(Major), Minor(Minor), HasMinor(true), Subminor(0),
+HasSubminor(false), Build(0), HasBuild(false) {}
+
+  explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor)
+  : Major(Major), Minor(Minor), HasMinor(true), Subminor(Subminor),
+HasSubminor(true), Build(0), HasBuild(false) {}
 
   explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor,
-unsigned Build, bool UsesUnderscores = false)
-  : Major(Major), UsesUnderscores(UsesUnderscores), Minor(Minor),
-HasMinor(true), Subminor(Subminor), HasSubminor(true), Build(Build),
-HasBuild(true) {}
+unsigned Build)
+  : Major(Major), Minor(Minor), HasMinor(true), Subminor(Subminor),
+HasSubminor(true), Build(Build), HasBuild(true) {}
 
   /// Determine whether this version information is empty
   /// (e.g., all version components are zero).
@@ -93,14 +86,6 @@
   return None;
 return Build;
   }
-
-  bool usesUnderscores() const {
-return UsesUnderscores;
-  }
-
-  void UseDotAsSeparator() {
-UsesUnderscores = false;
-  }
   
   /// Determine if two version numbers are equivalent. If not
   /// provided, minor and subminor version numbers are considered to be zero.
Index: cfe/trunk/test/Misc/ast-print-objectivec.m
===
--- cfe/trunk/test/Misc/ast-print-objectivec.m
+++ cfe/trunk/test/Misc/ast-print-objectivec.m
@@ -30,7 +30,7 @@
 // CHECK: @end
 
 // CHECK: @interface I(CAT)
-// CHECK: - (void)MethCAT __attribute__((availability(macos, introduced=10_1_0, deprecated=10_2)));
+// CHECK: - (void)MethCAT __attribute__((availability(macos, introduced=10.1.0, deprecated=10.2)));
 // CHECK: @end
 
 // CHECK: @implementation I
Index: cfe/trunk/test/Sema/availability-guard-format.mm
===
--- cfe/trunk/test/Sema/availability-guard-format.mm
+++ cfe/trunk/test/Sema/availability-guard-format.mm
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx-10.11 -Wunguarded-availability -fdiagnostics-parseable-fixits -fsyntax-only -verify %s
+
+// Testing that even for source code using '_' as a delimiter in availability version tuple '.' is actually used in diagnostic output as a delimiter.
+
+@interface foo
+- (void) method_bar __attribute__((availability(macosx, introduced = 10_12))); // expected-note {{'method_bar' has been explicitly marked partial here}}
+@end
+
+int main() {
+[foo method_bar]; // \
+  

[PATCH] D38643: PR13575: Fix USR mangling for fixed-size arrays.

2017-10-06 Thread Jan Korous via Phabricator via cfe-commits
jkorous-apple created this revision.

Added array type mangling to USR generation. Included test from bug report.


Repository:
  rL LLVM

https://reviews.llvm.org/D38643

Files:
  lib/Index/USRGeneration.cpp
  test/Index/USR/array-type.cpp


Index: test/Index/USR/array-type.cpp
===
--- /dev/null
+++ test/Index/USR/array-type.cpp
@@ -0,0 +1,8 @@
+// RUN: c-index-test core -print-source-symbols -- %s | grep 
"function(Gen,TS)/C++" | grep foo | cut -s -d "|" -f 4 | uniq | wc -l | grep 3
+
+// Function template specializations differing in array type parameter should 
have unique USRs.
+
+template void foo(buffer);
+template<> void foo(char[16]);
+template<> void foo(char[32]);
+template<> void foo(char[64]);
Index: lib/Index/USRGeneration.cpp
===
--- lib/Index/USRGeneration.cpp
+++ lib/Index/USRGeneration.cpp
@@ -816,6 +816,22 @@
   T = VT->getElementType();
   continue;
 }
+if (const ArrayType *const AT = dyn_cast(T)) {
+  VisitType(AT->getElementType());
+  Out << "[";
+
+  switch( AT->getSizeModifier() ) {
+case ArrayType::Static  : Out << "s"; break;
+case ArrayType::Star: Out << "*"; break;
+default : ;
+  }
+  if (const ConstantArrayType* const CAT = dyn_cast(T)) 
{
+Out << CAT->getSize();
+  }
+
+  Out << "]";
+  return;
+}
 
 // Unhandled type.
 Out << ' ';


Index: test/Index/USR/array-type.cpp
===
--- /dev/null
+++ test/Index/USR/array-type.cpp
@@ -0,0 +1,8 @@
+// RUN: c-index-test core -print-source-symbols -- %s | grep "function(Gen,TS)/C++" | grep foo | cut -s -d "|" -f 4 | uniq | wc -l | grep 3
+
+// Function template specializations differing in array type parameter should have unique USRs.
+
+template void foo(buffer);
+template<> void foo(char[16]);
+template<> void foo(char[32]);
+template<> void foo(char[64]);
Index: lib/Index/USRGeneration.cpp
===
--- lib/Index/USRGeneration.cpp
+++ lib/Index/USRGeneration.cpp
@@ -816,6 +816,22 @@
   T = VT->getElementType();
   continue;
 }
+if (const ArrayType *const AT = dyn_cast(T)) {
+  VisitType(AT->getElementType());
+  Out << "[";
+
+  switch( AT->getSizeModifier() ) {
+case ArrayType::Static  : Out << "s"; break;
+case ArrayType::Star: Out << "*"; break;
+default : ;
+  }
+  if (const ConstantArrayType* const CAT = dyn_cast(T)) {
+Out << CAT->getSize();
+  }
+
+  Out << "]";
+  return;
+}
 
 // Unhandled type.
 Out << ' ';
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38643: PR13575: Fix USR mangling for fixed-size arrays.

2017-10-06 Thread Jan Korous via Phabricator via cfe-commits
jkorous-apple updated this revision to Diff 118066.
jkorous-apple added a comment.

Uploaded full diff.


https://reviews.llvm.org/D38643

Files:
  lib/Index/USRGeneration.cpp
  test/Index/USR/array-type.cpp


Index: test/Index/USR/array-type.cpp
===
--- /dev/null
+++ test/Index/USR/array-type.cpp
@@ -0,0 +1,8 @@
+// RUN: c-index-test core -print-source-symbols -- %s | grep 
"function(Gen,TS)/C++" | grep foo | cut -s -d "|" -f 4 | uniq | wc -l | grep 3
+
+// Function template specializations differing in array type parameter should 
have unique USRs.
+
+template void foo(buffer);
+template<> void foo(char[16]);
+template<> void foo(char[32]);
+template<> void foo(char[64]);
Index: lib/Index/USRGeneration.cpp
===
--- lib/Index/USRGeneration.cpp
+++ lib/Index/USRGeneration.cpp
@@ -816,6 +816,22 @@
   T = VT->getElementType();
   continue;
 }
+if (const ArrayType *const AT = dyn_cast(T)) {
+  VisitType(AT->getElementType());
+  Out << "[";
+
+  switch( AT->getSizeModifier() ) {
+case ArrayType::Static  : Out << "s"; break;
+case ArrayType::Star: Out << "*"; break;
+default : ;
+  }
+  if (const ConstantArrayType* const CAT = dyn_cast(T)) 
{
+Out << CAT->getSize();
+  }
+
+  Out << "]";
+  return;
+}
 
 // Unhandled type.
 Out << ' ';


Index: test/Index/USR/array-type.cpp
===
--- /dev/null
+++ test/Index/USR/array-type.cpp
@@ -0,0 +1,8 @@
+// RUN: c-index-test core -print-source-symbols -- %s | grep "function(Gen,TS)/C++" | grep foo | cut -s -d "|" -f 4 | uniq | wc -l | grep 3
+
+// Function template specializations differing in array type parameter should have unique USRs.
+
+template void foo(buffer);
+template<> void foo(char[16]);
+template<> void foo(char[32]);
+template<> void foo(char[64]);
Index: lib/Index/USRGeneration.cpp
===
--- lib/Index/USRGeneration.cpp
+++ lib/Index/USRGeneration.cpp
@@ -816,6 +816,22 @@
   T = VT->getElementType();
   continue;
 }
+if (const ArrayType *const AT = dyn_cast(T)) {
+  VisitType(AT->getElementType());
+  Out << "[";
+
+  switch( AT->getSizeModifier() ) {
+case ArrayType::Static  : Out << "s"; break;
+case ArrayType::Star: Out << "*"; break;
+default : ;
+  }
+  if (const ConstantArrayType* const CAT = dyn_cast(T)) {
+Out << CAT->getSize();
+  }
+
+  Out << "]";
+  return;
+}
 
 // Unhandled type.
 Out << ' ';
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38643: PR13575: Fix USR mangling for fixed-size arrays.

2017-10-06 Thread Jan Korous via Phabricator via cfe-commits
jkorous-apple updated this revision to Diff 118104.
jkorous-apple added a comment.

Ammenended as suggested.


https://reviews.llvm.org/D38643

Files:
  lib/Index/USRGeneration.cpp
  test/Index/USR/array-type.cpp


Index: test/Index/USR/array-type.cpp
===
--- /dev/null
+++ test/Index/USR/array-type.cpp
@@ -0,0 +1,8 @@
+// RUN: c-index-test core -print-source-symbols -- %s | grep 
"function(Gen,TS)/C++" | grep foo | cut -s -d "|" -f 4 | uniq | wc -l | grep 3
+
+// Function template specializations differing in array type parameter should 
have unique USRs.
+
+template void foo(buffer);
+template<> void foo(char[16]);
+template<> void foo(char[32]);
+template<> void foo(char[64]);
Index: lib/Index/USRGeneration.cpp
===
--- lib/Index/USRGeneration.cpp
+++ lib/Index/USRGeneration.cpp
@@ -816,6 +816,20 @@
   T = VT->getElementType();
   continue;
 }
+if (const ArrayType *const AT = dyn_cast(T)) {
+  Out << "{";
+  switch( AT->getSizeModifier() ) {
+case ArrayType::Static  : Out << "s"; break;
+case ArrayType::Star: Out << "*"; break;
+case ArrayType::Normal  : Out << "n"; break;
+  }
+  if (const ConstantArrayType* const CAT = dyn_cast(T)) 
{
+Out << CAT->getSize();
+  }
+  Out << "}";
+  T = AT->getElementType();
+  continue;
+}
 
 // Unhandled type.
 Out << ' ';


Index: test/Index/USR/array-type.cpp
===
--- /dev/null
+++ test/Index/USR/array-type.cpp
@@ -0,0 +1,8 @@
+// RUN: c-index-test core -print-source-symbols -- %s | grep "function(Gen,TS)/C++" | grep foo | cut -s -d "|" -f 4 | uniq | wc -l | grep 3
+
+// Function template specializations differing in array type parameter should have unique USRs.
+
+template void foo(buffer);
+template<> void foo(char[16]);
+template<> void foo(char[32]);
+template<> void foo(char[64]);
Index: lib/Index/USRGeneration.cpp
===
--- lib/Index/USRGeneration.cpp
+++ lib/Index/USRGeneration.cpp
@@ -816,6 +816,20 @@
   T = VT->getElementType();
   continue;
 }
+if (const ArrayType *const AT = dyn_cast(T)) {
+  Out << "{";
+  switch( AT->getSizeModifier() ) {
+case ArrayType::Static  : Out << "s"; break;
+case ArrayType::Star: Out << "*"; break;
+case ArrayType::Normal  : Out << "n"; break;
+  }
+  if (const ConstantArrayType* const CAT = dyn_cast(T)) {
+Out << CAT->getSize();
+  }
+  Out << "}";
+  T = AT->getElementType();
+  continue;
+}
 
 // Unhandled type.
 Out << ' ';
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38643: PR13575: Fix USR mangling for fixed-size arrays.

2017-10-06 Thread Jan Korous via Phabricator via cfe-commits
jkorous-apple added a comment.

Replied and going to delete the end delimiter.




Comment at: lib/Index/USRGeneration.cpp:819
 }
+if (const ArrayType *const AT = dyn_cast(T)) {
+  Out << "{";

arphaman wrote:
> You can use `const auto *` here.
That's what I wanted to do in the first place but decided against it because of 
consistency - see other if conditions around. Do you still advice to use auto?



Comment at: lib/Index/USRGeneration.cpp:826
+  }
+  if (const ConstantArrayType* const CAT = dyn_cast(T)) 
{
+Out << CAT->getSize();

arphaman wrote:
> Ditto. Also, the braces are redundant.
Braces might be redundant yet I use them intentionally even for such cases 
(think the infamous goto bug). But I can definitely delete those if you insist. 
BTW Is there some consensus about this?



Comment at: lib/Index/USRGeneration.cpp:829
+  }
+  Out << "}";
+  T = AT->getElementType();

arphaman wrote:
> I don't think we need the terminating character.
I agree, going to delete that.



Comment at: test/Index/USR/array-type.cpp:1
+// RUN: c-index-test core -print-source-symbols -- %s | grep 
"function(Gen,TS)/C++" | grep foo | cut -s -d "|" -f 4 | uniq | wc -l | grep 3
+

arphaman wrote:
> Please use `FileCheck` and verify the exact USR strings. This way you'll know 
> that they're unique without actually trying to verify if they're unique in 
> the test.
Since the USR format doesn't seem to be really stable I wanted to avoid 
hard-coding USR values in tests. Wouldn't those tests be unnecessary brittle in 
the sense that hard-coded values would have to be modified in case of future 
changes?


https://reviews.llvm.org/D38643



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38643: PR13575: Fix USR mangling for fixed-size arrays.

2017-10-06 Thread Jan Korous via Phabricator via cfe-commits
jkorous-apple updated this revision to Diff 118115.
jkorous-apple added a comment.

Solved issues from CR.


https://reviews.llvm.org/D38643

Files:
  lib/Index/USRGeneration.cpp
  test/Index/USR/array-type.cpp


Index: test/Index/USR/array-type.cpp
===
--- /dev/null
+++ test/Index/USR/array-type.cpp
@@ -0,0 +1,11 @@
+// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s
+
+// Function template specializations differing in array type parameter should 
have unique USRs.
+
+template void foo(buffer);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n16C>#*C# | 
__Z3fooIA16_cEvT_ | Decl,RelSpecialization | rel: 1
+template<> void foo(char[16]);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n32C>#*C# | 
__Z3fooIA32_cEvT_ | Decl,RelSpecialization | rel: 1
+template<> void foo(char[32]);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n64C>#*C# | 
__Z3fooIA64_cEvT_ | Decl,RelSpecialization | rel: 1
+template<> void foo(char[64]);
Index: lib/Index/USRGeneration.cpp
===
--- lib/Index/USRGeneration.cpp
+++ lib/Index/USRGeneration.cpp
@@ -816,6 +816,19 @@
   T = VT->getElementType();
   continue;
 }
+if (const auto *const AT = dyn_cast(T)) {
+  Out << "{";
+  switch( AT->getSizeModifier() ) {
+case ArrayType::Static  : Out << "s"; break;
+case ArrayType::Star: Out << "*"; break;
+case ArrayType::Normal  : Out << "n"; break;
+  }
+  if (const auto* const CAT = dyn_cast(T))
+Out << CAT->getSize();
+
+  T = AT->getElementType();
+  continue;
+}
 
 // Unhandled type.
 Out << ' ';


Index: test/Index/USR/array-type.cpp
===
--- /dev/null
+++ test/Index/USR/array-type.cpp
@@ -0,0 +1,11 @@
+// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s
+
+// Function template specializations differing in array type parameter should have unique USRs.
+
+template void foo(buffer);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n16C>#*C# | __Z3fooIA16_cEvT_ | Decl,RelSpecialization | rel: 1
+template<> void foo(char[16]);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n32C>#*C# | __Z3fooIA32_cEvT_ | Decl,RelSpecialization | rel: 1
+template<> void foo(char[32]);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n64C>#*C# | __Z3fooIA64_cEvT_ | Decl,RelSpecialization | rel: 1
+template<> void foo(char[64]);
Index: lib/Index/USRGeneration.cpp
===
--- lib/Index/USRGeneration.cpp
+++ lib/Index/USRGeneration.cpp
@@ -816,6 +816,19 @@
   T = VT->getElementType();
   continue;
 }
+if (const auto *const AT = dyn_cast(T)) {
+  Out << "{";
+  switch( AT->getSizeModifier() ) {
+case ArrayType::Static  : Out << "s"; break;
+case ArrayType::Star: Out << "*"; break;
+case ArrayType::Normal  : Out << "n"; break;
+  }
+  if (const auto* const CAT = dyn_cast(T))
+Out << CAT->getSize();
+
+  T = AT->getElementType();
+  continue;
+}
 
 // Unhandled type.
 Out << ' ';
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38643: PR13575: Fix USR mangling for fixed-size arrays.

2017-10-09 Thread Jan Korous via Phabricator via cfe-commits
jkorous-apple updated this revision to Diff 118231.
jkorous-apple added a comment.

clang-format


https://reviews.llvm.org/D38643

Files:
  lib/Index/USRGeneration.cpp
  test/Index/USR/array-type.cpp


Index: test/Index/USR/array-type.cpp
===
--- /dev/null
+++ test/Index/USR/array-type.cpp
@@ -0,0 +1,11 @@
+// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s
+
+// Function template specializations differing in array type parameter should 
have unique USRs.
+
+template void foo(buffer);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n16C>#*C# | 
__Z3fooIA16_cEvT_ | Decl,RelSpecialization | rel: 1
+template<> void foo(char[16]);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n32C>#*C# | 
__Z3fooIA32_cEvT_ | Decl,RelSpecialization | rel: 1
+template<> void foo(char[32]);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n64C>#*C# | 
__Z3fooIA64_cEvT_ | Decl,RelSpecialization | rel: 1
+template<> void foo(char[64]);
Index: lib/Index/USRGeneration.cpp
===
--- lib/Index/USRGeneration.cpp
+++ lib/Index/USRGeneration.cpp
@@ -816,6 +816,25 @@
   T = VT->getElementType();
   continue;
 }
+if (const auto *const AT = dyn_cast(T)) {
+  Out << "{";
+  switch (AT->getSizeModifier()) {
+  case ArrayType::Static:
+Out << "s";
+break;
+  case ArrayType::Star:
+Out << "*";
+break;
+  case ArrayType::Normal:
+Out << "n";
+break;
+  }
+  if (const auto *const CAT = dyn_cast(T))
+Out << CAT->getSize();
+
+  T = AT->getElementType();
+  continue;
+}
 
 // Unhandled type.
 Out << ' ';


Index: test/Index/USR/array-type.cpp
===
--- /dev/null
+++ test/Index/USR/array-type.cpp
@@ -0,0 +1,11 @@
+// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s
+
+// Function template specializations differing in array type parameter should have unique USRs.
+
+template void foo(buffer);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n16C>#*C# | __Z3fooIA16_cEvT_ | Decl,RelSpecialization | rel: 1
+template<> void foo(char[16]);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n32C>#*C# | __Z3fooIA32_cEvT_ | Decl,RelSpecialization | rel: 1
+template<> void foo(char[32]);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n64C>#*C# | __Z3fooIA64_cEvT_ | Decl,RelSpecialization | rel: 1
+template<> void foo(char[64]);
Index: lib/Index/USRGeneration.cpp
===
--- lib/Index/USRGeneration.cpp
+++ lib/Index/USRGeneration.cpp
@@ -816,6 +816,25 @@
   T = VT->getElementType();
   continue;
 }
+if (const auto *const AT = dyn_cast(T)) {
+  Out << "{";
+  switch (AT->getSizeModifier()) {
+  case ArrayType::Static:
+Out << "s";
+break;
+  case ArrayType::Star:
+Out << "*";
+break;
+  case ArrayType::Normal:
+Out << "n";
+break;
+  }
+  if (const auto *const CAT = dyn_cast(T))
+Out << CAT->getSize();
+
+  T = AT->getElementType();
+  continue;
+}
 
 // Unhandled type.
 Out << ' ';
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38643: PR13575: Fix USR mangling for fixed-size arrays.

2017-10-09 Thread Jan Korous via Phabricator via cfe-commits
jkorous-apple updated this revision to Diff 118247.
jkorous-apple added a comment.

Single char constants don't need to be c-strings.


https://reviews.llvm.org/D38643

Files:
  lib/Index/USRGeneration.cpp
  test/Index/USR/array-type.cpp


Index: test/Index/USR/array-type.cpp
===
--- /dev/null
+++ test/Index/USR/array-type.cpp
@@ -0,0 +1,11 @@
+// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s
+
+// Function template specializations differing in array type parameter should 
have unique USRs.
+
+template void foo(buffer);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n16C>#*C# | 
__Z3fooIA16_cEvT_ | Decl,RelSpecialization | rel: 1
+template<> void foo(char[16]);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n32C>#*C# | 
__Z3fooIA32_cEvT_ | Decl,RelSpecialization | rel: 1
+template<> void foo(char[32]);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n64C>#*C# | 
__Z3fooIA64_cEvT_ | Decl,RelSpecialization | rel: 1
+template<> void foo(char[64]);
Index: lib/Index/USRGeneration.cpp
===
--- lib/Index/USRGeneration.cpp
+++ lib/Index/USRGeneration.cpp
@@ -816,6 +816,25 @@
   T = VT->getElementType();
   continue;
 }
+if (const auto *const AT = dyn_cast(T)) {
+  Out << '{';
+  switch (AT->getSizeModifier()) {
+  case ArrayType::Static:
+Out << 's';
+break;
+  case ArrayType::Star:
+Out << '*';
+break;
+  case ArrayType::Normal:
+Out << 'n';
+break;
+  }
+  if (const auto *const CAT = dyn_cast(T))
+Out << CAT->getSize();
+
+  T = AT->getElementType();
+  continue;
+}
 
 // Unhandled type.
 Out << ' ';


Index: test/Index/USR/array-type.cpp
===
--- /dev/null
+++ test/Index/USR/array-type.cpp
@@ -0,0 +1,11 @@
+// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s
+
+// Function template specializations differing in array type parameter should have unique USRs.
+
+template void foo(buffer);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n16C>#*C# | __Z3fooIA16_cEvT_ | Decl,RelSpecialization | rel: 1
+template<> void foo(char[16]);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n32C>#*C# | __Z3fooIA32_cEvT_ | Decl,RelSpecialization | rel: 1
+template<> void foo(char[32]);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n64C>#*C# | __Z3fooIA64_cEvT_ | Decl,RelSpecialization | rel: 1
+template<> void foo(char[64]);
Index: lib/Index/USRGeneration.cpp
===
--- lib/Index/USRGeneration.cpp
+++ lib/Index/USRGeneration.cpp
@@ -816,6 +816,25 @@
   T = VT->getElementType();
   continue;
 }
+if (const auto *const AT = dyn_cast(T)) {
+  Out << '{';
+  switch (AT->getSizeModifier()) {
+  case ArrayType::Static:
+Out << 's';
+break;
+  case ArrayType::Star:
+Out << '*';
+break;
+  case ArrayType::Normal:
+Out << 'n';
+break;
+  }
+  if (const auto *const CAT = dyn_cast(T))
+Out << CAT->getSize();
+
+  T = AT->getElementType();
+  continue;
+}
 
 // Unhandled type.
 Out << ' ';
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38707: PR13575: Fix USR mangling for functions taking function pointers as arguments.

2017-10-09 Thread Jan Korous via Phabricator via cfe-commits
jkorous-apple created this revision.

https://reviews.llvm.org/D38707

Files:
  lib/Index/USRGeneration.cpp
  test/Index/USR/func-type.cpp


Index: test/Index/USR/func-type.cpp
===
--- /dev/null
+++ test/Index/USR/func-type.cpp
@@ -0,0 +1,13 @@
+// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s
+
+// Functions taking function pointer parameters with different signatures 
should result in unique USRs.
+
+typedef void (*_VoidToVoidPtr_)();
+typedef void (*_IntToVoidPtr_)( int );
+typedef _VoidToVoidPtr_ (*IntTo_VoidToVoidPtr_Ptr)( int );
+typedef _IntToVoidPtr_ (*VoidTo_IntToVoidPtr_Ptr)();
+
+void Func( IntTo_VoidToVoidPtr_Ptr );
+// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv()(#I)# |
+void Func( VoidTo_IntToVoidPtr_Ptr );
+// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I)()# |
Index: lib/Index/USRGeneration.cpp
===
--- lib/Index/USRGeneration.cpp
+++ lib/Index/USRGeneration.cpp
@@ -754,8 +754,12 @@
 if (const FunctionProtoType *FT = T->getAs()) {
   Out << 'F';
   VisitType(FT->getReturnType());
-  for (const auto &I : FT->param_types())
+  Out << '(';
+  for (const auto &I : FT->param_types()) {
+Out << '#';
 VisitType(I);
+  }
+  Out << ')';
   if (FT->isVariadic())
 Out << '.';
   return;


Index: test/Index/USR/func-type.cpp
===
--- /dev/null
+++ test/Index/USR/func-type.cpp
@@ -0,0 +1,13 @@
+// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s
+
+// Functions taking function pointer parameters with different signatures should result in unique USRs.
+
+typedef void (*_VoidToVoidPtr_)();
+typedef void (*_IntToVoidPtr_)( int );
+typedef _VoidToVoidPtr_ (*IntTo_VoidToVoidPtr_Ptr)( int );
+typedef _IntToVoidPtr_ (*VoidTo_IntToVoidPtr_Ptr)();
+
+void Func( IntTo_VoidToVoidPtr_Ptr );
+// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv()(#I)# |
+void Func( VoidTo_IntToVoidPtr_Ptr );
+// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I)()# |
Index: lib/Index/USRGeneration.cpp
===
--- lib/Index/USRGeneration.cpp
+++ lib/Index/USRGeneration.cpp
@@ -754,8 +754,12 @@
 if (const FunctionProtoType *FT = T->getAs()) {
   Out << 'F';
   VisitType(FT->getReturnType());
-  for (const auto &I : FT->param_types())
+  Out << '(';
+  for (const auto &I : FT->param_types()) {
+Out << '#';
 VisitType(I);
+  }
+  Out << ')';
   if (FT->isVariadic())
 Out << '.';
   return;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38707: PR13575: Fix USR mangling for functions taking function pointers as arguments.

2017-10-09 Thread Jan Korous via Phabricator via cfe-commits
jkorous-apple updated this revision to Diff 118287.
jkorous-apple added a comment.

added another test


https://reviews.llvm.org/D38707

Files:
  lib/Index/USRGeneration.cpp
  test/Index/USR/func-type.cpp


Index: test/Index/USR/func-type.cpp
===
--- /dev/null
+++ test/Index/USR/func-type.cpp
@@ -0,0 +1,18 @@
+// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s
+
+// Functions taking function pointer parameters with different signatures 
should result in unique USRs.
+
+typedef void (*_VoidToVoidPtr_)();
+typedef void (*_IntToVoidPtr_)( int );
+typedef _VoidToVoidPtr_ (*IntTo_VoidToVoidPtr_Ptr)( int );
+typedef _IntToVoidPtr_ (*VoidTo_IntToVoidPtr_Ptr)();
+
+void Func( IntTo_VoidToVoidPtr_Ptr );
+// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv()(#I)# |
+void Func( VoidTo_IntToVoidPtr_Ptr );
+// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I)()# |
+
+void Func( void (* (*)(int, int))(int, int) );
+// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I#I)(#I#I)# |
+void Func( void (* (*)(int, int, int))(int) );
+// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I)(#I#I#I)# |
Index: lib/Index/USRGeneration.cpp
===
--- lib/Index/USRGeneration.cpp
+++ lib/Index/USRGeneration.cpp
@@ -754,8 +754,12 @@
 if (const FunctionProtoType *FT = T->getAs()) {
   Out << 'F';
   VisitType(FT->getReturnType());
-  for (const auto &I : FT->param_types())
+  Out << '(';
+  for (const auto &I : FT->param_types()) {
+Out << '#';
 VisitType(I);
+  }
+  Out << ')';
   if (FT->isVariadic())
 Out << '.';
   return;


Index: test/Index/USR/func-type.cpp
===
--- /dev/null
+++ test/Index/USR/func-type.cpp
@@ -0,0 +1,18 @@
+// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s
+
+// Functions taking function pointer parameters with different signatures should result in unique USRs.
+
+typedef void (*_VoidToVoidPtr_)();
+typedef void (*_IntToVoidPtr_)( int );
+typedef _VoidToVoidPtr_ (*IntTo_VoidToVoidPtr_Ptr)( int );
+typedef _IntToVoidPtr_ (*VoidTo_IntToVoidPtr_Ptr)();
+
+void Func( IntTo_VoidToVoidPtr_Ptr );
+// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv()(#I)# |
+void Func( VoidTo_IntToVoidPtr_Ptr );
+// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I)()# |
+
+void Func( void (* (*)(int, int))(int, int) );
+// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I#I)(#I#I)# |
+void Func( void (* (*)(int, int, int))(int) );
+// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I)(#I#I#I)# |
Index: lib/Index/USRGeneration.cpp
===
--- lib/Index/USRGeneration.cpp
+++ lib/Index/USRGeneration.cpp
@@ -754,8 +754,12 @@
 if (const FunctionProtoType *FT = T->getAs()) {
   Out << 'F';
   VisitType(FT->getReturnType());
-  for (const auto &I : FT->param_types())
+  Out << '(';
+  for (const auto &I : FT->param_types()) {
+Out << '#';
 VisitType(I);
+  }
+  Out << ')';
   if (FT->isVariadic())
 Out << '.';
   return;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38707: PR13575: Fix USR mangling for functions taking function pointers as arguments.

2017-10-09 Thread Jan Korous via Phabricator via cfe-commits
jkorous-apple added inline comments.



Comment at: lib/Index/USRGeneration.cpp:757
   VisitType(FT->getReturnType());
-  for (const auto &I : FT->param_types())
+  Out << '(';
+  for (const auto &I : FT->param_types()) {

arphaman wrote:
> I believe you can drop the '(' and ')'. The '#' should be enough to prevent 
> the USR collision.
Actually, this is a great question!

I was worried it might not be the case so I created two more test cases. 
Let's try to imagine there are no parentheses in those USRs.
First two test cases could be solved by using 'v' or something for functions 
taking no arguments. But 3rd and 4th test cases would definitely need some 
disambiguation then.

I am not saying this is the only possible way how to represent function 
pointers but for proposed solution those parentheses are needed.


https://reviews.llvm.org/D38707



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38711: typos in documentation?

2017-10-09 Thread Jan Korous via Phabricator via cfe-commits
jkorous-apple created this revision.

I have found two possible typos in documentation. Since English is not my first 
language I would like to ask for verification.


https://reviews.llvm.org/D38711

Files:
  docs/InternalsManual.rst


Index: docs/InternalsManual.rst
===
--- docs/InternalsManual.rst
+++ docs/InternalsManual.rst
@@ -1540,7 +1540,7 @@
 After trying several different approaches, we've finally converged on a design
 (Note, at the time of this writing, not all of this has been implemented,
 consider this a design goal!).  Our basic approach is to define a single
-recursive method evaluation method (``Expr::Evaluate``), which is implemented
+recursive evaluation method (``Expr::Evaluate``), which is implemented
 in ``AST/ExprConstant.cpp``.  Given an expression with "scalar" type (integer,
 fp, complex, or pointer) this method returns the following information:
 
@@ -2037,7 +2037,7 @@
* ``CodeGenFunction`` contains functions ``ConvertType`` and
  ``ConvertTypeForMem`` that convert Clang's types (``clang::Type*`` or
  ``clang::QualType``) to LLVM types.  Use the former for values, and the
- later for memory locations: test with the C++ "``bool``" type to check
+ latter for memory locations: test with the C++ "``bool``" type to check
  this.  If you find that you are having to use LLVM bitcasts to make the
  subexpressions of your expression have the type that your expression
  expects, STOP!  Go fix semantic analysis and the AST so that you don't


Index: docs/InternalsManual.rst
===
--- docs/InternalsManual.rst
+++ docs/InternalsManual.rst
@@ -1540,7 +1540,7 @@
 After trying several different approaches, we've finally converged on a design
 (Note, at the time of this writing, not all of this has been implemented,
 consider this a design goal!).  Our basic approach is to define a single
-recursive method evaluation method (``Expr::Evaluate``), which is implemented
+recursive evaluation method (``Expr::Evaluate``), which is implemented
 in ``AST/ExprConstant.cpp``.  Given an expression with "scalar" type (integer,
 fp, complex, or pointer) this method returns the following information:
 
@@ -2037,7 +2037,7 @@
* ``CodeGenFunction`` contains functions ``ConvertType`` and
  ``ConvertTypeForMem`` that convert Clang's types (``clang::Type*`` or
  ``clang::QualType``) to LLVM types.  Use the former for values, and the
- later for memory locations: test with the C++ "``bool``" type to check
+ latter for memory locations: test with the C++ "``bool``" type to check
  this.  If you find that you are having to use LLVM bitcasts to make the
  subexpressions of your expression have the type that your expression
  expects, STOP!  Go fix semantic analysis and the AST so that you don't
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38755: Fixed crash during indexing default template template param

2017-10-10 Thread Jan Korous via Phabricator via cfe-commits
jkorous-apple created this revision.

fix + testcase


https://reviews.llvm.org/D38755

Files:
  lib/Index/IndexDecl.cpp
  test/Index/index-template-template-param.cpp


Index: test/Index/index-template-template-param.cpp
===
--- /dev/null
+++ test/Index/index-template-template-param.cpp
@@ -0,0 +1,7 @@
+// RUN: c-index-test -index-file %s -x objective-c++ | FileCheck %s
+
+template  class Template1 {};
+
+template  class TMPL = Template1> class Template2;
+
+// CHECK: [indexEntityReference]: kind: c++-class-template | name: Template1 |
Index: lib/Index/IndexDecl.cpp
===
--- lib/Index/IndexDecl.cpp
+++ lib/Index/IndexDecl.cpp
@@ -666,7 +666,6 @@
   }
 
   bool VisitTemplateDecl(const TemplateDecl *D) {
-// FIXME: Template parameters.
 
 // Index the default values for the template parameters.
 const NamedDecl *Parent = D->getTemplatedDecl();
@@ -683,7 +682,7 @@
 } else if (const auto *TTPD = dyn_cast(TP)) {
   if (TTPD->hasDefaultArgument())
 handleTemplateArgumentLoc(TTPD->getDefaultArgument(), Parent,
-  /*DC=*/nullptr);
+  TP->getLexicalDeclContext());
 }
   }
 }


Index: test/Index/index-template-template-param.cpp
===
--- /dev/null
+++ test/Index/index-template-template-param.cpp
@@ -0,0 +1,7 @@
+// RUN: c-index-test -index-file %s -x objective-c++ | FileCheck %s
+
+template  class Template1 {};
+
+template  class TMPL = Template1> class Template2;
+
+// CHECK: [indexEntityReference]: kind: c++-class-template | name: Template1 |
Index: lib/Index/IndexDecl.cpp
===
--- lib/Index/IndexDecl.cpp
+++ lib/Index/IndexDecl.cpp
@@ -666,7 +666,6 @@
   }
 
   bool VisitTemplateDecl(const TemplateDecl *D) {
-// FIXME: Template parameters.
 
 // Index the default values for the template parameters.
 const NamedDecl *Parent = D->getTemplatedDecl();
@@ -683,7 +682,7 @@
 } else if (const auto *TTPD = dyn_cast(TP)) {
   if (TTPD->hasDefaultArgument())
 handleTemplateArgumentLoc(TTPD->getDefaultArgument(), Parent,
-  /*DC=*/nullptr);
+  TP->getLexicalDeclContext());
 }
   }
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38863: Typos in tutorial

2017-10-12 Thread Jan Korous via Phabricator via cfe-commits
jkorous-apple created this revision.

https://reviews.llvm.org/D38863

Files:
  www/hacking.html


Index: www/hacking.html
===
--- www/hacking.html
+++ www/hacking.html
@@ -246,9 +246,9 @@
   For example:
 
   
-  python C:\Tool\llvm\utils\lit\lit.py -sv
+  python C:\Tools\llvm\utils\lit\lit.py -sv
   --param=build_mode=Win32 --param=build_config=Debug
-  --param=clang_site_config=c:\Tools\build\tools\clang\test\lit.site.cfg
+  --param=clang_site_config=C:\Tools\build\tools\clang\test\lit.site.cfg
   C:\Tools\llvm\tools\clang\test\Sema\wchar.c
 
 


Index: www/hacking.html
===
--- www/hacking.html
+++ www/hacking.html
@@ -246,9 +246,9 @@
   For example:
 
   
-  python C:\Tool\llvm\utils\lit\lit.py -sv
+  python C:\Tools\llvm\utils\lit\lit.py -sv
   --param=build_mode=Win32 --param=build_config=Debug
-  --param=clang_site_config=c:\Tools\build\tools\clang\test\lit.site.cfg
+  --param=clang_site_config=C:\Tools\build\tools\clang\test\lit.site.cfg
   C:\Tools\llvm\tools\clang\test\Sema\wchar.c
 
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D51485: [Sema][NFC] Trivial cleanup in ActOnCallExpr

2018-08-30 Thread Jan Korous via Phabricator via cfe-commits
jkorous created this revision.
jkorous added reviewers: rsmith, doug.gregor, JDevlieghere, thegameg.
jkorous added a project: clang.
Herald added subscribers: cfe-commits, dexonsmith.

Use logical or operator instead of a bool variable and if/else.


Repository:
  rC Clang

https://reviews.llvm.org/D51485

Files:
  lib/Sema/SemaExpr.cpp


Index: lib/Sema/SemaExpr.cpp
===
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -5330,13 +5330,7 @@
 
 // Determine whether this is a dependent call inside a C++ template,
 // in which case we won't do any semantic analysis now.
-bool Dependent = false;
-if (Fn->isTypeDependent())
-  Dependent = true;
-else if (Expr::hasAnyTypeDependentArguments(ArgExprs))
-  Dependent = true;
-
-if (Dependent) {
+if (Fn->isTypeDependent() || Expr::hasAnyTypeDependentArguments(ArgExprs)) 
{
   if (ExecConfig) {
 return new (Context) CUDAKernelCallExpr(
 Context, Fn, cast(ExecConfig), ArgExprs,


Index: lib/Sema/SemaExpr.cpp
===
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -5330,13 +5330,7 @@
 
 // Determine whether this is a dependent call inside a C++ template,
 // in which case we won't do any semantic analysis now.
-bool Dependent = false;
-if (Fn->isTypeDependent())
-  Dependent = true;
-else if (Expr::hasAnyTypeDependentArguments(ArgExprs))
-  Dependent = true;
-
-if (Dependent) {
+if (Fn->isTypeDependent() || Expr::hasAnyTypeDependentArguments(ArgExprs)) {
   if (ExecConfig) {
 return new (Context) CUDAKernelCallExpr(
 Context, Fn, cast(ExecConfig), ArgExprs,
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D51485: [Sema][NFC] Trivial cleanup in ActOnCallExpr

2018-08-30 Thread Jan Korous via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL341074: [Sema][NFC] Trivial cleanup in ActOnCallExpr 
(authored by jkorous, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D51485?vs=163304&id=163327#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D51485

Files:
  cfe/trunk/lib/Sema/SemaExpr.cpp


Index: cfe/trunk/lib/Sema/SemaExpr.cpp
===
--- cfe/trunk/lib/Sema/SemaExpr.cpp
+++ cfe/trunk/lib/Sema/SemaExpr.cpp
@@ -5330,13 +5330,7 @@
 
 // Determine whether this is a dependent call inside a C++ template,
 // in which case we won't do any semantic analysis now.
-bool Dependent = false;
-if (Fn->isTypeDependent())
-  Dependent = true;
-else if (Expr::hasAnyTypeDependentArguments(ArgExprs))
-  Dependent = true;
-
-if (Dependent) {
+if (Fn->isTypeDependent() || Expr::hasAnyTypeDependentArguments(ArgExprs)) 
{
   if (ExecConfig) {
 return new (Context) CUDAKernelCallExpr(
 Context, Fn, cast(ExecConfig), ArgExprs,


Index: cfe/trunk/lib/Sema/SemaExpr.cpp
===
--- cfe/trunk/lib/Sema/SemaExpr.cpp
+++ cfe/trunk/lib/Sema/SemaExpr.cpp
@@ -5330,13 +5330,7 @@
 
 // Determine whether this is a dependent call inside a C++ template,
 // in which case we won't do any semantic analysis now.
-bool Dependent = false;
-if (Fn->isTypeDependent())
-  Dependent = true;
-else if (Expr::hasAnyTypeDependentArguments(ArgExprs))
-  Dependent = true;
-
-if (Dependent) {
+if (Fn->isTypeDependent() || Expr::hasAnyTypeDependentArguments(ArgExprs)) {
   if (ExecConfig) {
 return new (Context) CUDAKernelCallExpr(
 Context, Fn, cast(ExecConfig), ArgExprs,
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D51488: [Sema][NFC] Small cleanup - remove dead code from ActOnCallExpr() ?

2018-08-30 Thread Jan Korous via Phabricator via cfe-commits
jkorous created this revision.
jkorous added reviewers: rsmith, vsapsai, JDevlieghere.
jkorous added a project: clang.
Herald added subscribers: cfe-commits, dexonsmith.

Since there's no change to ArgExprs between here and the previous early exit 
starting at L 5333 it's effectively a dead code.

On the other hand a possible counter-argument is that code gets a bit more 
brittle.

WDYT?


Repository:
  rC Clang

https://reviews.llvm.org/D51488

Files:
  Sema/SemaExpr.cpp


Index: Sema/SemaExpr.cpp
===
--- Sema/SemaExpr.cpp
+++ Sema/SemaExpr.cpp
@@ -5369,9 +5369,6 @@
 
 // We aren't supposed to apply this logic if there's an '&' involved.
 if (!find.HasFormOfMemberPointer) {
-  if (Expr::hasAnyTypeDependentArguments(ArgExprs))
-return new (Context) CallExpr(
-Context, Fn, ArgExprs, Context.DependentTy, VK_RValue, RParenLoc);
   OverloadExpr *ovl = find.Expression;
   if (UnresolvedLookupExpr *ULE = dyn_cast(ovl))
 return BuildOverloadedCallExpr(


Index: Sema/SemaExpr.cpp
===
--- Sema/SemaExpr.cpp
+++ Sema/SemaExpr.cpp
@@ -5369,9 +5369,6 @@
 
 // We aren't supposed to apply this logic if there's an '&' involved.
 if (!find.HasFormOfMemberPointer) {
-  if (Expr::hasAnyTypeDependentArguments(ArgExprs))
-return new (Context) CallExpr(
-Context, Fn, ArgExprs, Context.DependentTy, VK_RValue, RParenLoc);
   OverloadExpr *ovl = find.Expression;
   if (UnresolvedLookupExpr *ULE = dyn_cast(ovl))
 return BuildOverloadedCallExpr(
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D51543: [Sema] Fix uninitialized OverloadCandidate::FoundDecl member

2018-08-31 Thread Jan Korous via Phabricator via cfe-commits
jkorous created this revision.
jkorous added reviewers: arphaman, vsapsai, dexonsmith, rsmith.
jkorous added a project: clang.
Herald added subscribers: cfe-commits, mgorny.

It's rather error-prone to leave that member variable uninitialized. The 
DeclAccessPair seems to be intentionally POD and it seems the make() method is 
supposed to be called as a constructor.

I take DeclAccessPair interface as given so the only options are to either 
change OverloadCandidate interface or actually initialize the member variable 
it to some sane default. I suggest the easiest option.


Repository:
  rC Clang

https://reviews.llvm.org/D51543

Files:
  Sema/CMakeLists.txt
  Sema/OverloadTest.cpp
  clang/Sema/Overload.h


Index: Sema/OverloadTest.cpp
===
--- /dev/null
+++ Sema/OverloadTest.cpp
@@ -0,0 +1,21 @@
+//=== unittests/Sema/CodeCompleteTest.cpp - Code Complete tests 
==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "clang/Sema/Overload.h"
+#include "gtest/gtest.h"
+
+namespace {
+
+TEST(SemaOverloadTest, FoundDeclIsInitializedInOverloadCandidate) {
+  clang::OverloadCandidate foo;
+  EXPECT_EQ(foo.FoundDecl.getDecl(), nullptr);
+  EXPECT_EQ(foo.FoundDecl.getAccess(), clang::AS_none);
+}
+
+} // namespace
Index: Sema/CMakeLists.txt
===
--- Sema/CMakeLists.txt
+++ Sema/CMakeLists.txt
@@ -5,6 +5,7 @@
 add_clang_unittest(SemaTests
   ExternalSemaSourceTest.cpp
   CodeCompleteTest.cpp
+  OverloadTest.cpp
   )
 
 target_link_libraries(SemaTests
Index: clang/Sema/Overload.h
===
--- clang/Sema/Overload.h
+++ clang/Sema/Overload.h
@@ -728,6 +728,11 @@
 
   /// OverloadCandidate - A single candidate in an overload set (C++ 13.3).
   struct OverloadCandidate {
+
+OverloadCandidate()
+: FoundDecl( DeclAccessPair::make(nullptr, AS_none))
+{ }
+
 /// Function - The actual function that this candidate
 /// represents. When NULL, this is a built-in candidate
 /// (C++ [over.oper]) or a surrogate for a conversion to a


Index: Sema/OverloadTest.cpp
===
--- /dev/null
+++ Sema/OverloadTest.cpp
@@ -0,0 +1,21 @@
+//=== unittests/Sema/CodeCompleteTest.cpp - Code Complete tests ==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "clang/Sema/Overload.h"
+#include "gtest/gtest.h"
+
+namespace {
+
+TEST(SemaOverloadTest, FoundDeclIsInitializedInOverloadCandidate) {
+  clang::OverloadCandidate foo;
+  EXPECT_EQ(foo.FoundDecl.getDecl(), nullptr);
+  EXPECT_EQ(foo.FoundDecl.getAccess(), clang::AS_none);
+}
+
+} // namespace
Index: Sema/CMakeLists.txt
===
--- Sema/CMakeLists.txt
+++ Sema/CMakeLists.txt
@@ -5,6 +5,7 @@
 add_clang_unittest(SemaTests
   ExternalSemaSourceTest.cpp
   CodeCompleteTest.cpp
+  OverloadTest.cpp
   )
 
 target_link_libraries(SemaTests
Index: clang/Sema/Overload.h
===
--- clang/Sema/Overload.h
+++ clang/Sema/Overload.h
@@ -728,6 +728,11 @@
 
   /// OverloadCandidate - A single candidate in an overload set (C++ 13.3).
   struct OverloadCandidate {
+
+OverloadCandidate()
+: FoundDecl( DeclAccessPair::make(nullptr, AS_none))
+{ }
+
 /// Function - The actual function that this candidate
 /// represents. When NULL, this is a built-in candidate
 /// (C++ [over.oper]) or a surrogate for a conversion to a
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D51488: [Sema][NFC] Small cleanup - remove dead code from ActOnCallExpr() ?

2018-09-10 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

Sorry for the delay - I was busy with other things for past two weeks.




Comment at: Sema/SemaExpr.cpp:5338
 Context.DependentTy, VK_RValue, RParenLoc);
   } else {
 

JDevlieghere wrote:
> While you're at it you might as well remove the else branch here.
Sorry, I am not following. Do you mean just refactoring?

```
if a
  foo
else
  bar

```
->
```
if a
  foo

bar
```

Or do you really mean removing the else branch? I don't see how that would be 
NFC.


Repository:
  rC Clang

https://reviews.llvm.org/D51488



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D51867: [Diagnostics][NFC] Add error handling to FormatDiagnostic()

2018-09-10 Thread Jan Korous via Phabricator via cfe-commits
jkorous created this revision.
jkorous added reviewers: arphaman, vsapsai.
jkorous added a project: clang.
Herald added subscribers: cfe-commits, dexonsmith.

There seem to be couple implicit assumptions that might be better represented 
explicitly by asserts.


Repository:
  rC Clang

https://reviews.llvm.org/D51867

Files:
  lib/Basic/Diagnostic.cpp


Index: lib/Basic/Diagnostic.cpp
===
--- lib/Basic/Diagnostic.cpp
+++ lib/Basic/Diagnostic.cpp
@@ -768,6 +768,7 @@
 void Diagnostic::
 FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
  SmallVectorImpl &OutStr) const {
+  assert(DiagStr <= DiagEnd && "Invalid DiagStr-DiagEnd range");
   // When the diagnostic string is only "%0", the entire string is being given
   // by an outside source.  Remove unprintable characters from this string
   // and skip all the other string processing.
@@ -798,17 +799,22 @@
 if (getArgKind(i) == DiagnosticsEngine::ak_qualtype)
   QualTypeVals.push_back(getRawArg(i));
 
-  while (DiagStr != DiagEnd) {
+  assert(DiagStr != nullptr && "DiagStr is nullptr");
+
+  while (DiagStr < DiagEnd) {
 if (DiagStr[0] != '%') {
   // Append non-%0 substrings to Str if we have one.
   const char *StrEnd = std::find(DiagStr, DiagEnd, '%');
   OutStr.append(DiagStr, StrEnd);
   DiagStr = StrEnd;
   continue;
-} else if (isPunctuation(DiagStr[1])) {
+} else if ((DiagStr + 1) < DiagEnd && isPunctuation(DiagStr[1])) {
   OutStr.push_back(DiagStr[1]);  // %% -> %.
   DiagStr += 2;
   continue;
+} else if ((DiagStr + 1) >= DiagEnd) {
+  llvm_unreachable("DiagStr ends with '%'");
+  return;
 }
 
 // Skip the %.
@@ -825,34 +831,40 @@
 // Check to see if we have a modifier.  If so eat it.
 if (!isDigit(DiagStr[0])) {
   Modifier = DiagStr;
-  while (DiagStr[0] == '-' ||
- (DiagStr[0] >= 'a' && DiagStr[0] <= 'z'))
+  while (DiagStr < DiagEnd &&
+ (DiagStr[0] == '-' || (DiagStr[0] >= 'a' && DiagStr[0] <= 'z')))
 ++DiagStr;
   ModifierLen = DiagStr-Modifier;
 
   // If we have an argument, get it next.
   if (DiagStr[0] == '{') {
 ++DiagStr; // Skip {.
+assert(DiagStr < DiagEnd && "Invalid DiagStr");
 Argument = DiagStr;
 
 DiagStr = ScanFormat(DiagStr, DiagEnd, '}');
 assert(DiagStr != DiagEnd && "Mismatched {}'s in diagnostic string!");
 ArgumentLen = DiagStr-Argument;
 ++DiagStr;  // Skip }.
+assert(DiagStr < DiagEnd && "Invalid DiagStr");
   }
 }
 
 assert(isDigit(*DiagStr) && "Invalid format for argument in diagnostic");
-unsigned ArgNo = *DiagStr++ - '0';
+
+unsigned ArgNo = *DiagStr - '0';
 
 // Only used for type diffing.
 unsigned ArgNo2 = ArgNo;
+++DiagStr;
 
 DiagnosticsEngine::ArgumentKind Kind = getArgKind(ArgNo);
 if (ModifierIs(Modifier, ModifierLen, "diff")) {
+  assert(DiagStr + 1 < DiagEnd && "Invalid diff modifier in DiagStr");
   assert(*DiagStr == ',' && isDigit(*(DiagStr + 1)) &&
  "Invalid format for diff modifier");
   ++DiagStr;  // Comma.
+  assert(DiagStr < DiagEnd && "Invalid DiagStr");
   ArgNo2 = *DiagStr++ - '0';
   DiagnosticsEngine::ArgumentKind Kind2 = getArgKind(ArgNo2);
   if (Kind == DiagnosticsEngine::ak_qualtype &&


Index: lib/Basic/Diagnostic.cpp
===
--- lib/Basic/Diagnostic.cpp
+++ lib/Basic/Diagnostic.cpp
@@ -768,6 +768,7 @@
 void Diagnostic::
 FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
  SmallVectorImpl &OutStr) const {
+  assert(DiagStr <= DiagEnd && "Invalid DiagStr-DiagEnd range");
   // When the diagnostic string is only "%0", the entire string is being given
   // by an outside source.  Remove unprintable characters from this string
   // and skip all the other string processing.
@@ -798,17 +799,22 @@
 if (getArgKind(i) == DiagnosticsEngine::ak_qualtype)
   QualTypeVals.push_back(getRawArg(i));
 
-  while (DiagStr != DiagEnd) {
+  assert(DiagStr != nullptr && "DiagStr is nullptr");
+
+  while (DiagStr < DiagEnd) {
 if (DiagStr[0] != '%') {
   // Append non-%0 substrings to Str if we have one.
   const char *StrEnd = std::find(DiagStr, DiagEnd, '%');
   OutStr.append(DiagStr, StrEnd);
   DiagStr = StrEnd;
   continue;
-} else if (isPunctuation(DiagStr[1])) {
+} else if ((DiagStr + 1) < DiagEnd && isPunctuation(DiagStr[1])) {
   OutStr.push_back(DiagStr[1]);  // %% -> %.
   DiagStr += 2;
   continue;
+} else if ((DiagStr + 1) >= DiagEnd) {
+  llvm_unreachable("DiagStr ends with '%'");
+  return;
 }
 
 // Skip the %.
@@ -825,34 +831,40 @@
 // Check to see if we have a modifier.  If so eat it.
 if (!isDigit(DiagStr[0])) {
   Modifier = DiagStr;
-  while (DiagStr[0] == 

[PATCH] D51867: [Diagnostics] Add error handling to FormatDiagnostic()

2018-09-10 Thread Jan Korous via Phabricator via cfe-commits
jkorous planned changes to this revision.
jkorous added a comment.

Hi Volodymyr, 
Thanks for the feedback - interesting points!

I see your point regarding NFC - I am going to drop it as you are right.

Two things about sanitizers come to mind:

1. You'd need to guarantee that you have all possible code paths (or at least 
those you are able to cover with asserts) covered in tests to be able to 
replace asserts with sanitizers. (I think that even if that would be feasible 
asserts would prove to be way simpler.)
2. I prefer explicit assert right in the place where an assumption is made to 
test somewhere else as it make understanding the code much easier.

> Those change loop iteration from "iterator != end" to "iterator < end". As it 
> is functionality change, I'd like to have tests to cover that.

Technically you are right but I assume (ok, busted) that without any bug in the 
iteration this is NFC. I will try to look if I can find some simple input that 
would break current implementation.

> Also I've fixed a few bugs with going past the end of buffer and bugs were 
> actually inside the loop, not with buffer range check. It is tempting to play 
> safe but it has a risk of hiding real bugs.

But that almost sounds as that we should write fragile code so bugs from other 
parts of codebase show up... Anyway, I will think about this a bit more, it's 
an interesting point.




Comment at: lib/Basic/Diagnostic.cpp:804
+
+  while (DiagStr < DiagEnd) {
 if (DiagStr[0] != '%') {

vsapsai wrote:
> For example, I wouldn't call this one NFC.
You are right, I am gonna drop the NFC.


Repository:
  rC Clang

https://reviews.llvm.org/D51867



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D51867: [Diagnostics] Add error handling to FormatDiagnostic()

2018-09-10 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

I tried to come up with some input that breaks current implementation so I 
could add the test. Problem is that invalid memory read doesn't guarantee 
deterministic crash.  
E. g. with this input the current implementation is definitely reading way past 
the buffer:

  SmallVector IgnoreMe;
  const char* Foo = "foo%";
  const char* FooEnd = Foo + 4;
  Diag.FormatDiagnostic(Foo, FooEnd, IgnoreMe);

...and it actually found some string there yet it didn't crash until it hit 
some unrelated assert

  (lldb) p DiagStr
  (const char *) $0 = 0x000100adc53b " SplatSizeInBits == 0 && 
\"SplatSizeInBits must divide width!\""
  (lldb) p *DiagStr
  (const char) $1 = ' '
  (lldb) p DiagEnd
  (const char *) $2 = 0x000100ad4155 "0"

The only reliable fail is passing nullptr which currently leads to SIGABRT 
(nullptr dereferenced)

  SmallVector IgnoreMe;
  const char* Foo = "foo";
  Diag.FormatDiagnostic(Foo, nullptr, IgnoreMe);

I am reconsidering the necessity of such tests here. WDYT?


Repository:
  rC Clang

https://reviews.llvm.org/D51867



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D51488: [Sema][NFC] Small cleanup - remove dead code from ActOnCallExpr() ?

2018-09-12 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

I got some test failure with the patch, still investigating the issue.


Repository:
  rC Clang

https://reviews.llvm.org/D51488



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48560: [clangd] JSON <-> XPC conversions

2018-07-19 Thread Jan Korous via Phabricator via cfe-commits
jkorous marked 12 inline comments as done.
jkorous added inline comments.



Comment at: xpc/XPCJSONConversions.cpp:62
+  if (objType == XPC_TYPE_UINT64)
+return json::Expr(xpc_uint64_get_value(xpcObj));
+  if (objType == XPC_TYPE_STRING)

sammccall wrote:
> hmm, I think this shouldn't compile anymore, rather require you to explicitly 
> do the narrowing conversion to int64 or double.
Explicitly narroving now. Thanks.



Comment at: xpc/XPCJSONConversions.cpp:69
+  xpcObj,
+  ^bool(size_t /* index */, xpc_object_t value) {
+result.emplace_back(xpcToJson(value));

jkorous wrote:
> sammccall wrote:
> > this looks like objC syntax, I'm not familiar with it, but should this file 
> > be `.mm`?
> > 
> > Alternatively, it seems like you could write a C++ loop with 
> > `xpc_array_get_value` (though I don't know if there are performance 
> > concerns).
> > 
> > (and dictionary)
> Oh, sorry. These are actually C blocks - a nonstandard C extension.
> https://en.wikipedia.org/wiki/Blocks_(C_language_extension)
> https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html
> 
> There was no performance concern on my side - just liked this approach 
> better. Didn't realize how confusing it might be, will rewrite this.
Allright, by trying to get rid of C block in dictionary conversion I remembered 
that there's unfortunately no sane reason how to iterate XPC dictionary without 
using xpc_dictionary_apply() which uses C block for functor parameter.

https://developer.apple.com/documentation/xpc/1505404-xpc_dictionary_apply?language=objc
https://developer.apple.com/documentation/xpc/xpc_dictionary_applier_t?language=objc

Anyway, even had we succeeded in removing C blocks from conversion they still 
would be necessary for dispatch as xpc_connection_set_event_handler() is 
another part of XPC API that uses it.

I guess that there's no point in removing the xpc_array_apply() then. Is that 
ok with you?


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D48560



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48562: [clangd] XPC transport layer

2018-07-19 Thread Jan Korous via Phabricator via cfe-commits
jkorous marked 7 inline comments as done.
jkorous added inline comments.



Comment at: xpc/test-client/ClangdXPCTestClient.cpp:51
+  dlHandle, "clangd_xpc_get_bundle_identifier");
+  xpc_connection_t conn =
+  xpc_connection_create(clangd_xpc_get_bundle_identifier(), NULL);

arphaman wrote:
> jkorous wrote:
> > arphaman wrote:
> > > We should probably use the main queue here too to ensure that we don't 
> > > get bit by concurrent handler invocations. 
> > As far as I understand it this is taken care of by calling dispatch_main().
> > 
> > Per man dispatch_main:
> > "MAIN QUEUE
> > [...]
> >  Programs must call dispatch_main() at the end of main() in order to 
> > process blocks submitted to the main queue."
> > 
> Not really. The documentation for the parameter states the following: 
> 
> The GCD queue to which the event handler block will be submitted. This 
> parameter may be NULL, in which case the connection's target queue will be 
> libdispatch's default target queue, defined as DISPATCH_TARGET_QUEUE_DEFAULT. 
> The target queue may be changed later with a call to 
> xpc_connection_set_target_queue(). 
> 
> So the handler blocks will be submitted to the concurrent queue 
> (DISPATCH_TARGET_QUEUE_DEFAULT) which means that they might end up running 
> concurrently.
Sorry, my bad.


https://reviews.llvm.org/D48562



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49548: [clangd] XPC WIP

2018-07-19 Thread Jan Korous via Phabricator via cfe-commits
jkorous created this revision.
jkorous added reviewers: sammccall, arphaman.
Herald added subscribers: cfe-commits, dexonsmith, MaskRay, ioeric, 
ilya-biryukov, mgorny.

Combined, rebased and modified original XPC patches.

- https://reviews.llvm.org/D48559 [clangd] refactoring for XPC transport layer 
[NFCI]
- https://reviews.llvm.org/D48560 [clangd] JSON <-> XPC conversions
- https://reviews.llvm.org/D48562 [clangd] XPC transport layer

- Rebased on TOT.
- Made changes according to review.

Couple of questions are still open in reviews of original patches and more 
importantly the discussion about transport abstraction just started:
https://reviews.llvm.org/D48559#1167340
https://reviews.llvm.org/D49389

I thought it would be useful to have current state of our original approach 
online as it will be foundation for our implementation anyway (implementing 
whatever interface we converge to).


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D49548

Files:
  CMakeLists.txt
  ClangdLSPServer.cpp
  ClangdLSPServer.h
  DispatcherCommon.cpp
  DispatcherCommon.h
  Features.inc.in
  JSONRPCDispatcher.cpp
  JSONRPCDispatcher.h
  LSPOutput.h
  ProtocolHandlers.cpp
  ProtocolHandlers.h
  clangd/CMakeLists.txt
  clangd/xpc/CMakeLists.txt
  clangd/xpc/ConversionTests.cpp
  clangd/xpc/initialize.test
  lit.cfg
  lit.site.cfg.in
  tool/CMakeLists.txt
  tool/ClangdMain.cpp
  xpc/CMakeLists.txt
  xpc/Conversion.cpp
  xpc/Conversion.h
  xpc/README.txt
  xpc/XPCDispatcher.cpp
  xpc/XPCDispatcher.h
  xpc/cmake/Info.plist.in
  xpc/cmake/XPCServiceInfo.plist.in
  xpc/cmake/modules/CreateClangdXPCFramework.cmake
  xpc/framework/CMakeLists.txt
  xpc/framework/ClangdXPC.cpp
  xpc/test-client/CMakeLists.txt
  xpc/test-client/ClangdXPCTestClient.cpp

Index: clangd/xpc/ConversionTests.cpp
===
--- /dev/null
+++ clangd/xpc/ConversionTests.cpp
@@ -0,0 +1,454 @@
+//===-- ConversionTests.cpp  --*- C++ -*---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "xpc/Conversion.h"
+#include "gtest/gtest.h"
+
+#include 
+
+namespace clang {
+namespace clangd {
+namespace {
+
+using namespace llvm;
+
+TEST(JsonXpcConversionTest, Null) {
+  EXPECT_TRUE(
+xpc_equal(
+  jsonToXpc(json::Value(nullptr)),
+  xpc_null_create()
+)
+  );
+  EXPECT_TRUE(
+json::Value(nullptr) == xpcToJson(xpc_null_create())
+  );
+}
+
+TEST(JsonXpcConversionTest, Bool) {
+  EXPECT_TRUE(
+xpc_equal(
+  jsonToXpc(json::Value(true)),
+  xpc_bool_create(true)
+)
+  );
+  EXPECT_TRUE(
+json::Value(false) == xpcToJson(xpc_bool_create(false))
+  );
+}
+
+TEST(JsonXpcConversionTest, Number) {
+  EXPECT_TRUE(
+xpc_equal(
+  jsonToXpc(json::Value(3.14)),
+  xpc_double_create(3.14)
+)
+  );
+  EXPECT_TRUE(
+json::Value(3.14) == xpcToJson(xpc_double_create(3.14))
+  );
+
+  EXPECT_TRUE(
+xpc_equal(
+  jsonToXpc(json::Value(42)),
+  xpc_double_create(42)
+)
+  );
+  EXPECT_TRUE(
+json::Value(42) == xpcToJson(xpc_double_create(42))
+  );
+  EXPECT_TRUE(
+json::Value(42) == xpcToJson(xpc_int64_create(42))
+  );
+
+  EXPECT_TRUE(
+xpc_equal(
+  jsonToXpc(json::Value(-100)),
+  xpc_double_create(-100)
+)
+  );
+  EXPECT_TRUE(
+json::Value(-100) == xpcToJson(xpc_double_create(-100))
+  );
+
+  int64_t bigPositiveValue = std::numeric_limits::max();
+  ++bigPositiveValue;
+  int64_t bigNegativeValue = std::numeric_limits::min();
+  --bigNegativeValue;
+
+  EXPECT_TRUE(
+xpc_equal(
+  jsonToXpc(json::Value(bigPositiveValue)),
+  xpc_double_create(bigPositiveValue)
+)
+  );
+  EXPECT_TRUE(
+json::Value(bigPositiveValue) == xpcToJson(xpc_double_create(bigPositiveValue))
+  );
+
+  EXPECT_TRUE(
+xpc_equal(
+  jsonToXpc(json::Value(bigNegativeValue)),
+  xpc_double_create(bigNegativeValue)
+)
+  );
+  EXPECT_TRUE(
+json::Value(bigNegativeValue) == xpcToJson(xpc_double_create(bigNegativeValue))
+  );
+}
+
+TEST(JsonXpcConversionTest, String) {
+  EXPECT_TRUE(
+xpc_equal(
+  jsonToXpc(json::Value("foo")),
+  xpc_string_create("foo")
+)
+  );
+  EXPECT_TRUE(
+json::Value("foo") == xpcToJson(xpc_string_create("foo"))
+  );
+
+  EXPECT_TRUE(
+xpc_equal(
+  jsonToXpc(json::Value("")),
+  xpc_string_create("")
+)
+  );
+  EXPECT_TRUE(
+json::Value("") == xpcToJson(xpc_string_create(""))
+  );
+
+  EXPECT_TRUE(
+xpc_equal(
+  jsonToXpc(json::Value("123")),
+  xpc_string_create("123")
+)
+  );
+  EXPECT_TRUE(
+json::Value("123") == xpcToJson(xpc_string_create("123"))
+  );
+
+  EXPECT_TRUE(
+xpc_equal(
+  jsonToXpc(json::Value(" ")),
+  xpc_string_create

[PATCH] D48559: [clangd] refactoring for XPC transport layer [NFCI]

2018-07-19 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

Sam, just out of curiosity - would it be possible for you to share any relevant 
experience gained by using porting clangd to protobuf-based transport layer?


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D48559



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49523: [clangd] Add support for per-file override compilation command

2018-07-20 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

Hi Marc-Andre, what is a structure of data you are passing as parameter of 
didChangeConfiguration message? All we need is to pass per-file compilation 
command to clangd. Maybe we could send didChangeConfiguration message right 
after didOpen.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D49523



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49523: [clangd] Add support for per-file override compilation command

2018-07-20 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

Alex, I am just wondering if we shouldn't rather create another implementation 
of GlobalCompilationDatabase interface (something like 
InMemoryGlobalCompilationDatabase), add it to ClangdServer and use it as the 
first place to be searched in ClangdServer::getCompileCommand(PathRef File). 
What do you think?


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D49523



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48559: [clangd] refactoring for XPC transport layer [NFCI]

2018-07-20 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

Hi Sam, we discussed a bit more with Alex offline. Ultimately we don't mind 
using JSON as part of the generic interface but we'd like to optimize specific 
cases in the future (thinking only about code completion so far) which might 
need to "work-around" the abstraction. What is your opinion about this - does 
it ruin the whole point of having the abstraction or do you consider pragmatic 
to have abstraction covering most of the functionality with maybe couple 
exceptions? I kind of assume (please correct me if I am wrong) that you might 
have done something similar with profobuf interface so we're definitely happy 
to discuss.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D48559



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48560: [clangd] JSON <-> XPC conversions

2018-07-20 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

BTW Just for the record - I put the rebased & updated patch here: [clangd] XPC 
WIP https://reviews.llvm.org/D49548


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D48560



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48562: [clangd] XPC transport layer

2018-07-20 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

BTW Just for the record - I put the rebased & updated patch here: [clangd] XPC 
WIP https://reviews.llvm.org/D49548


https://reviews.llvm.org/D48562



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48559: [clangd] refactoring for XPC transport layer [NFCI]

2018-07-20 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

BTW Just for the record - I put the rebased & updated patch here: [clangd] XPC 
WIP https://reviews.llvm.org/D49548


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D48559



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49523: [clangd] Add support for per-file override compilation command

2018-07-20 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

BTW it looks like we already had kind of support for compilation command before 
(extra flags).

commit 5ec1f7ca32eb85077a22ce81d41aa02a017d4852
Author: Krasimir Georgiev 
Date:   Thu Jul 6 08:44:54 2017 +

  [clangd] Add support for per-file extra flags

There is even an LSP extension proposal:

https://github.com/Microsoft/language-server-protocol/issues/255

But it seems as if we lost access to it here:

commit aa49372548ff984ae9c48879a0d05833538a76b3
Author: Sam McCall 
Date:   Mon Dec 4 10:08:45 2017 +

  [clangd] GlobalCompilationDatabase interface changes


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D49523



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49736: [Basic] Emit warning flag suggestion only in case there's *similar* existing flag for given unknown one

2018-07-24 Thread Jan Korous via Phabricator via cfe-commits
jkorous created this revision.
jkorous added reviewers: arphaman, vsapsai, bruno, JDevlieghere.
Herald added subscribers: cfe-commits, dexonsmith.

In case user specified non-existent warning flag clang was suggesting an 
existing on that was in some cased very different. This patch should ensure 
that either a relevant warning flag is suggested or none (which is in line with 
unknown generic command line option handling).

  Examples:
  warning: unknown warning option '-Whiskey'; did you mean '-Wpacked'?
  warning: unknown warning option '-Weverthin'; did you mean '-Wsection'?
  
  rdar://problem/37755482

I changed interface of DiagnosticIDs::getNearestOption() to return the edit 
distance between nonexistent flag and the closest exiting one. In principle 
this code is analogous to OptTable::findNearest() for generic command line 
options but I don't find them similar enough in order to factor out some shared 
implementation. I tentatively selected maximum edit distance as 2 
(CompilerInvocation::CreateFromArgs() uses maximum edit distance of 1 for 
generic case).


Repository:
  rC Clang

https://reviews.llvm.org/D49736

Files:
  Basic/DiagnosticIDs.cpp
  Basic/Warnings.cpp
  Driver/cc-log-diagnostics.c
  Frontend/warning-options.cpp
  clang/Basic/DiagnosticIDs.h

Index: Frontend/warning-options.cpp
===
--- Frontend/warning-options.cpp
+++ Frontend/warning-options.cpp
@@ -3,5 +3,5 @@
 // CHECK: unknown warning option '-Wmonkey'
 // CHECK: unknown warning option '-Wno-monkey'
 // CHECK: unknown warning option '-Wno-unused-command-line-arguments'; did you mean '-Wno-unused-command-line-argument'?
-// CHECK: unknown warning option '-Wmodule-build'; did you mean '-Wmodule-conflict'?
+// CHECK: unknown warning option '-Wmodule-build'
 // CHECK: unknown remark option '-Rmodule-built'; did you mean '-Rmodule-build'?
Index: Driver/cc-log-diagnostics.c
===
--- Driver/cc-log-diagnostics.c
+++ Driver/cc-log-diagnostics.c
@@ -17,7 +17,7 @@
 // CHECK:   level
 // CHECK:   warning
 // CHECK:   message
-// CHECK:   unknown warning option '-Wfoobar'; did you mean '-W{{.*}}'?
+// CHECK:   unknown warning option '-Wfoobar'
 // CHECK: 
 // CHECK: 
 // CHECK:   level
Index: Basic/Warnings.cpp
===
--- Basic/Warnings.cpp
+++ Basic/Warnings.cpp
@@ -30,15 +30,24 @@
 #include 
 using namespace clang;
 
+namespace {
+  constexpr unsigned MaxLevenshteinDistForWarningSuggestion = 2;
+}
+
 // EmitUnknownDiagWarning - Emit a warning and typo hint for unknown warning
 // opts
 static void EmitUnknownDiagWarning(DiagnosticsEngine &Diags,
diag::Flavor Flavor, StringRef Prefix,
StringRef Opt) {
-  StringRef Suggestion = DiagnosticIDs::getNearestOption(Flavor, Opt);
+  std::string Suggestion;
+  const unsigned OptToSuggestionEditDist
+= DiagnosticIDs::getNearestOption(Flavor, Opt, Suggestion);
   Diags.Report(diag::warn_unknown_diag_option)
 << (Flavor == diag::Flavor::WarningOrError ? 0 : 1) << (Prefix.str() += Opt)
-<< !Suggestion.empty() << (Prefix.str() += Suggestion);
+<< (!Suggestion.empty()
+  && OptToSuggestionEditDist > 0
+  && OptToSuggestionEditDist <= MaxLevenshteinDistForWarningSuggestion)
+<< (Prefix.str() += Suggestion);
 }
 
 void clang::ProcessWarningOptions(DiagnosticsEngine &Diags,
Index: Basic/DiagnosticIDs.cpp
===
--- Basic/DiagnosticIDs.cpp
+++ Basic/DiagnosticIDs.cpp
@@ -589,9 +589,9 @@
   Diags.push_back(StaticDiagInfo[i].DiagID);
 }
 
-StringRef DiagnosticIDs::getNearestOption(diag::Flavor Flavor,
-  StringRef Group) {
-  StringRef Best;
+unsigned DiagnosticIDs::getNearestOption(diag::Flavor Flavor,
+  StringRef Group,
+  std::string& NearestOption) {
   unsigned BestDistance = Group.size() + 1; // Sanity threshold.
   for (const WarningOption &O : OptionTable) {
 // Don't suggest ignored warning flags.
@@ -609,15 +609,15 @@
 
 if (Distance == BestDistance) {
   // Two matches with the same distance, don't prefer one over the other.
-  Best = "";
+  NearestOption = "";
 } else if (Distance < BestDistance) {
   // This is a better match.
-  Best = O.getName();
+  NearestOption = O.getName();
   BestDistance = Distance;
 }
   }
 
-  return Best;
+  return BestDistance;
 }
 
 /// ProcessDiag - This is the method used to report a diagnostic that is
Index: clang/Basic/DiagnosticIDs.h
===
--- clang/Basic/DiagnosticIDs.h
+++ clang/Basic/DiagnosticIDs.h
@@ -300,8 +300,12 @@
 std::v

[PATCH] D48559: [clangd] refactoring for XPC transport layer [NFCI]

2018-07-25 Thread Jan Korous via Phabricator via cfe-commits
jkorous planned changes to this revision.
jkorous added a comment.

Hi Sam, we are still discussing internally how to fit clangd and XPC together. 
Please bear with us and ignore our patches until we decide.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D48559



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49736: [Basic] Emit warning flag suggestion only in case there's existing flag *similar* to the unknown one

2018-07-26 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

I like that idea! It looks like it's living in a wrong place anyway as it 
doesn't need access to any of implementation details (private members) of 
DiagnosticID. I would still like to preserve it as a function so this block of 
code has clear semantics and interface. 
How about I refactor it to a static free function in Warnings.cpp?


Repository:
  rC Clang

https://reviews.llvm.org/D49736



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43230: [clangd] Explicitly initialize all primitive fields in Protocol.h

2018-02-13 Thread Jan Korous via Phabricator via cfe-commits
jkorous-apple added inline comments.



Comment at: clangd/Protocol.h:190
   /// (see exit notification) its process.
-  llvm::Optional processId;
+  llvm::Optional processId = 0;
 

Sorry if I am asking stupid question but since the type is Optional<> isn't 
it's default-constructed value more appropriate here?



Comment at: clangd/Protocol.h:211
   /// The initial trace setting. If omitted trace is disabled ('off').
-  llvm::Optional trace;
+  llvm::Optional trace = TraceLevel::Off;
 };

Does it still make more sense to use Optional than plain TraceLevel?


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D43230



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43331: [WIP][Parser][FixIt] Better diagnostics for omitted template keyword (type dependent template names)

2018-02-15 Thread Jan Korous via Phabricator via cfe-commits
jkorous-apple created this revision.

What I would love to have is FixIt for this kind of situation:

  template  void foo() {
  T::bar(); /* missing template keyword */
  }

which currently gets not that helpful diagnostics:

  > clang misleading.cpp
  misleading.cpp:2:15: error: expected '(' for function-style cast or type 
construction
  T::bar();
 ~~~^
  misleading.cpp:2:16: error: expected expression
  T::bar();
 ^
  misleading.cpp:2:18: error: expected expression
  T::bar();
   ^
  3 errors generated.

while

  template  void foo() {
  T::bar();
  }

gets a good one:

  good.cpp:2:8: error: use 'template' keyword to treat 'bar' as a dependent 
template name
  T::bar();
 ^
 template
  1 error generated.

If I understand it correctly than current implementation of

  bool Parser::IsTemplateArgumentList(unsigned Skip)

relies on the fact that if there's a '<' token followed by declaration 
specifier it has to be a template. Which is true but produces false negatives 
for non-type parameters (array<1>) or pointer type parameters (vector) 
(among others).

One particular thing to keep on mind is that there's the [over.over] rule about 
resolving names to function pointers - best explained by test 
test/SemaTemplate/dependent-template-recover.cpp (look for snippet below):

  // Note: no diagnostic here, this is actually valid as a comparison between
  // the decayed pointer to Y::g<> and mb!
  T::g(0);

What I did so far is that in case the simple approach doesn't validate there's 
a template I try to use speculative parsing. The only problem remaining is 
diagnostics - I am able to use TentativeParsingAction which is later reverted 
but I still get all the diagnostics which is incorrect in case my speculation 
about how to parse the code was wrong.


https://reviews.llvm.org/D43331

Files:
  FixIt/fixit-template-for-dependent-name.cpp
  Parse/ParseTemplate.cpp
  SemaTemplate/dependent-template-recover.cpp


Index: SemaTemplate/dependent-template-recover.cpp
===
--- SemaTemplate/dependent-template-recover.cpp
+++ SemaTemplate/dependent-template-recover.cpp
@@ -6,6 +6,7 @@
 t->f0(); // expected-error{{use 'template' keyword to treat 'f0' as a 
dependent template name}}
 
 t->operator+(); // expected-error{{use 'template' keyword to 
treat 'operator +' as a dependent template name}}
+t->operator+<1, U const>(); // expected-error{{use 'template' keyword to 
treat 'operator +' as a dependent template name}}
 t->f1(); // expected-error{{use 'template' keyword to treat 
'f1' as a dependent template name}}
 
 T::getAs(); // expected-error{{use 'template' keyword to treat 'getAs' 
as a dependent template name}}
Index: FixIt/fixit-template-for-dependent-name.cpp
===
--- /dev/null
+++ FixIt/fixit-template-for-dependent-name.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template  void foo() {
+T::bar(); // expected-error {{use 'template' keyword to treat 'bar' 
as a dependent template name}}
+T::baz(); // expected-error {{use 'template' keyword to treat 'baz' 
as a dependent template name}}
+}
+
+// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | 
FileCheck %s
+// CHECK: fix-it:{{.*}}:{4:8-4:8}:"template "
+// CHECK: fix-it:{{.*}}:{5:8-5:8}:"template "
Index: Parse/ParseTemplate.cpp
===
--- Parse/ParseTemplate.cpp
+++ Parse/ParseTemplate.cpp
@@ -1247,30 +1247,45 @@
 /// template argument list (starting with the '<') and never as a '<' 
 /// expression.
 bool Parser::IsTemplateArgumentList(unsigned Skip) {
-  struct AlwaysRevertAction : TentativeParsingAction {
-AlwaysRevertAction(Parser &P) : TentativeParsingAction(P) { }
-~AlwaysRevertAction() { Revert(); }
-  } Tentative(*this);
-  
-  while (Skip) {
-ConsumeAnyToken();
---Skip;
+  {
+RevertingTentativeParsingAction AutoRevertScopeGuard(*this);
+
+for (; Skip > 0; --Skip) {
+  ConsumeToken();
+}
+
+if (!TryConsumeToken(tok::less))
+  return false;
+
+// If the first wannabe template argument consists only of decl specs
+// it's a template argument list indeed.
+
+// See whether we have declaration specifiers, which indicate a type.
+while (isCXXDeclarationSpecifier() == TPResult::True)
+  ConsumeAnyToken();
+
+// If we have a '>' or a ',' then this is a template argument list.
+if (Tok.isOneOf(tok::greater, tok::comma))
+  return true;
   }
-  
-  // '<'
+
+  RevertingTentativeParsingAction AutoRevertScopeGuard(*this);
+
+  for (; Skip > 0; --Skip) {
+ConsumeToken();
+  }
+
   if (!TryConsumeToken(tok::less))
 return false;
 
-  // An empty template argument list.
-  if (Tok.is(tok::greater))
-return true;
-  
-  // See whether we have

[PATCH] D41306: [clangd] Update documentation page with new features, instructions

2017-12-16 Thread Jan Korous via Phabricator via cfe-commits
jkorous-apple accepted this revision.
jkorous-apple added a comment.
This revision is now accepted and ready to land.

LGTM


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D41306



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41897: Fixing a crash in Sema.

2018-01-10 Thread Jan Korous via Phabricator via cfe-commits
jkorous-apple created this revision.
jkorous-apple added a reviewer: arphaman.

The original code is checking for inaccessible base classes but does not expect 
inheriting from template parameters (or dependent types in general) as these 
are not modelled by CXXRecord.

Issue was at this line since getAsCXXRecord() returned nullptr:

  bool found
  = Class->isDerivedFrom(CanonicalBase->getAsCXXRecordDecl(), Paths);


https://reviews.llvm.org/D41897

Files:
  Sema/SemaDeclCXX.cpp
  SemaCXX/base-class-ambiguity-check.cpp


Index: SemaCXX/base-class-ambiguity-check.cpp
===
--- /dev/null
+++ SemaCXX/base-class-ambiguity-check.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+template
+class Foo
+{
+struct Base : T
+{ };
+
+struct Derived : Base, T
+{ };
+};
\ No newline at end of file
Index: Sema/SemaDeclCXX.cpp
===
--- Sema/SemaDeclCXX.cpp
+++ Sema/SemaDeclCXX.cpp
@@ -2417,9 +2417,17 @@
   // Attach the remaining base class specifiers to the derived class.
   Class->setBases(Bases.data(), NumGoodBases);
 
+  // Check that the only base classes that are duplicate are virtual.
   for (unsigned idx = 0; idx < NumGoodBases; ++idx) {
 // Check whether this direct base is inaccessible due to ambiguity.
 QualType BaseType = Bases[idx]->getType();
+
+// Skip all dependent types in templates being used as base specifiers.
+// Checks below assume that base specifier is a CXXRecord.
+if (BaseType->isDependentType()) {
+  continue;
+}
+
 CanQualType CanonicalBase = Context.getCanonicalType(BaseType)
   .getUnqualifiedType();
 


Index: SemaCXX/base-class-ambiguity-check.cpp
===
--- /dev/null
+++ SemaCXX/base-class-ambiguity-check.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+template
+class Foo
+{
+struct Base : T
+{ };
+
+struct Derived : Base, T
+{ };
+};
\ No newline at end of file
Index: Sema/SemaDeclCXX.cpp
===
--- Sema/SemaDeclCXX.cpp
+++ Sema/SemaDeclCXX.cpp
@@ -2417,9 +2417,17 @@
   // Attach the remaining base class specifiers to the derived class.
   Class->setBases(Bases.data(), NumGoodBases);
 
+  // Check that the only base classes that are duplicate are virtual.
   for (unsigned idx = 0; idx < NumGoodBases; ++idx) {
 // Check whether this direct base is inaccessible due to ambiguity.
 QualType BaseType = Bases[idx]->getType();
+
+// Skip all dependent types in templates being used as base specifiers.
+// Checks below assume that base specifier is a CXXRecord.
+if (BaseType->isDependentType()) {
+  continue;
+}
+
 CanQualType CanonicalBase = Context.getCanonicalType(BaseType)
   .getUnqualifiedType();
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41897: Fixing a crash in Sema.

2018-01-11 Thread Jan Korous via Phabricator via cfe-commits
jkorous-apple updated this revision to Diff 129284.
jkorous-apple added a comment.

Changes based on Aaron's feedback.


https://reviews.llvm.org/D41897

Files:
  Sema/SemaDeclCXX.cpp
  SemaCXX/base-class-ambiguity-check.cpp


Index: SemaCXX/base-class-ambiguity-check.cpp
===
--- /dev/null
+++ SemaCXX/base-class-ambiguity-check.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+template  class Foo {
+  struct Base : T {};
+
+  // Up to commit 680b3a8619 (2018-01-10) this produced a crash in Sema.
+  struct Derived : Base, T {};
+};
Index: Sema/SemaDeclCXX.cpp
===
--- Sema/SemaDeclCXX.cpp
+++ Sema/SemaDeclCXX.cpp
@@ -2417,9 +2417,16 @@
   // Attach the remaining base class specifiers to the derived class.
   Class->setBases(Bases.data(), NumGoodBases);
 
+  // Check that the only base classes that are duplicate are virtual.
   for (unsigned idx = 0; idx < NumGoodBases; ++idx) {
 // Check whether this direct base is inaccessible due to ambiguity.
 QualType BaseType = Bases[idx]->getType();
+
+// Skip all dependent types in templates being used as base specifiers.
+// Checks below assume that the base specifier is a CXXRecord.
+if (BaseType->isDependentType())
+  continue;
+
 CanQualType CanonicalBase = Context.getCanonicalType(BaseType)
   .getUnqualifiedType();
 


Index: SemaCXX/base-class-ambiguity-check.cpp
===
--- /dev/null
+++ SemaCXX/base-class-ambiguity-check.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+template  class Foo {
+  struct Base : T {};
+
+  // Up to commit 680b3a8619 (2018-01-10) this produced a crash in Sema.
+  struct Derived : Base, T {};
+};
Index: Sema/SemaDeclCXX.cpp
===
--- Sema/SemaDeclCXX.cpp
+++ Sema/SemaDeclCXX.cpp
@@ -2417,9 +2417,16 @@
   // Attach the remaining base class specifiers to the derived class.
   Class->setBases(Bases.data(), NumGoodBases);
 
+  // Check that the only base classes that are duplicate are virtual.
   for (unsigned idx = 0; idx < NumGoodBases; ++idx) {
 // Check whether this direct base is inaccessible due to ambiguity.
 QualType BaseType = Bases[idx]->getType();
+
+// Skip all dependent types in templates being used as base specifiers.
+// Checks below assume that the base specifier is a CXXRecord.
+if (BaseType->isDependentType())
+  continue;
+
 CanQualType CanonicalBase = Context.getCanonicalType(BaseType)
   .getUnqualifiedType();
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D42938: [Sema] Emit -Winteger-overflow for arguments in function calls, ObjC messages.

2018-03-02 Thread Jan Korous via Phabricator via cfe-commits
jkorous-apple added a comment.

Maybe a stupid idea but in case it makes sense to add these expression types 
could we also add integer template arguments?


https://reviews.llvm.org/D42938



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D42938: [Sema] Emit -Winteger-overflow for arguments in function calls, ObjC messages.

2018-03-02 Thread Jan Korous via Phabricator via cfe-commits
jkorous-apple added a comment.

Sorry, my bad, I tried just older clang version which didn't produce any error.

With reasonably up to date clang I get these:

  > cat tmpl_overflow.hpp



  template struct foo { short a; };
  
  template<> struct foo<100 * 10240> { bool a; };
  
  int main() {
  foo<100 * 10240> a;
  }



  > ~/src/oss/llvm@master/build/bin/clang++ tmpl_overflow.hpp
  tmpl_overflow.hpp:3:23: error: non-type template argument is not a constant 
expression
  template<> struct foo<100 * 10240> { bool a; };
^~~
  tmpl_overflow.hpp:3:43: note: value 1024000 is outside the 
range of representable values of type 'long'
  template<> struct foo<100 * 10240> { bool a; };
^
  tmpl_overflow.hpp:6:9: error: non-type template argument is not a constant 
expression
  foo<100 * 10240> a;
  ^~~
  tmpl_overflow.hpp:6:29: note: value 1024000 is outside the 
range of representable values of type 'long'
  foo<100 * 10240> a;
  ^
  2 errors generated.

I am not actually sure those error messages are correct (not constant? type 
'long'?) but I am not sure it's still within the scope of your patch either.

What is interesting is that by using lower value (which is still to big for 
short) I probably hit different diagnostic check and get different error:

  > cat tmpl_overflow.hpp

  template struct foo { short a; };
  
  template<> struct foo<100 * 10240> { bool a; };
  
  int main() {
  foo<100 * 10240> a;
  }






  
jankorous @ jans-imac /Users/jankorous/tmp
  > ~/src/oss/llvm@master/build/bin/clang++ tmpl_overflow.hpp
  tmpl_overflow.hpp:3:23: error: non-type template argument evaluates to 
1024000, which cannot be narrowed to type 'int' [-Wc++11-narrowing]
  template<> struct foo<100 * 10240> { bool a; };
^
  tmpl_overflow.hpp:6:9: error: non-type template argument evaluates to 
1024000, which cannot be narrowed to type 'int' [-Wc++11-narrowing]
  foo<100 * 10240> a;
  ^
  2 errors generated.


https://reviews.llvm.org/D42938



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D44088: [clangd] Extract ClangdServer::Options struct.

2018-03-08 Thread Jan Korous via Phabricator via cfe-commits
jkorous-apple added inline comments.



Comment at: clang-tools-extra/trunk/clangd/ClangdServer.h:131
+  // Features like indexing must be enabled if desired.
+  static Options optsForTest();
+

Shouldn't this be better implemented as a utility function in tests?

Also what is the purpose of making global function in header file static?




Repository:
  rL LLVM

https://reviews.llvm.org/D44088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D44575: [clangd][nfc] Give name to a magic constant

2018-03-16 Thread Jan Korous via Phabricator via cfe-commits
jkorous-apple created this revision.
jkorous-apple added a project: clang-tools-extra.
Herald added subscribers: cfe-commits, ioeric, ilya-biryukov.

Since I was reading this code I decided I might just as well polish it a 
little. It is just preliminary commit for a bug-fix.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D44575

Files:
  clangd/index/Index.h


Index: clangd/index/Index.h
===
--- clangd/index/Index.h
+++ clangd/index/Index.h
@@ -54,16 +54,18 @@
   }
 
 private:
+  static constexpr unsigned HashByteLength = 20;
+
   friend llvm::hash_code hash_value(const SymbolID &ID) {
 // We already have a good hash, just return the first bytes.
-static_assert(sizeof(size_t) <= 20, "size_t longer than SHA1!");
+static_assert(sizeof(size_t) <= HashByteLength, "size_t longer than 
SHA1!");
 return *reinterpret_cast(ID.HashValue.data());
   }
   friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const SymbolID &ID);
   friend void operator>>(llvm::StringRef Str, SymbolID &ID);
 
-  std::array HashValue;
+  std::array HashValue;
 };
 
 // Write SymbolID into the given stream. SymbolID is encoded as a 40-bytes


Index: clangd/index/Index.h
===
--- clangd/index/Index.h
+++ clangd/index/Index.h
@@ -54,16 +54,18 @@
   }
 
 private:
+  static constexpr unsigned HashByteLength = 20;
+
   friend llvm::hash_code hash_value(const SymbolID &ID) {
 // We already have a good hash, just return the first bytes.
-static_assert(sizeof(size_t) <= 20, "size_t longer than SHA1!");
+static_assert(sizeof(size_t) <= HashByteLength, "size_t longer than SHA1!");
 return *reinterpret_cast(ID.HashValue.data());
   }
   friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const SymbolID &ID);
   friend void operator>>(llvm::StringRef Str, SymbolID &ID);
 
-  std::array HashValue;
+  std::array HashValue;
 };
 
 // Write SymbolID into the given stream. SymbolID is encoded as a 40-bytes
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D44576: [clangd] Fix undefined behavior due to misaligned type cast

2018-03-16 Thread Jan Korous via Phabricator via cfe-commits
jkorous-apple created this revision.
jkorous-apple added a project: clang-tools-extra.
Herald added subscribers: cfe-commits, ioeric, ilya-biryukov.

The current code is casting pointer to a misaligned type which is undefined 
behavior.

Found by compiling with Undefined Behavior Sanitizer and running tests 
(check-clang-tools).

AFAIK clang produces the same code for reinterpret_cast<>() and memcpy().

Follow-up to: https://reviews.llvm.org/D44575


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D44576

Files:
  clangd/index/Index.h


Index: clangd/index/Index.h
===
--- clangd/index/Index.h
+++ clangd/index/Index.h
@@ -59,7 +59,9 @@
   friend llvm::hash_code hash_value(const SymbolID &ID) {
 // We already have a good hash, just return the first bytes.
 static_assert(sizeof(size_t) <= HashByteLength, "size_t longer than 
SHA1!");
-return *reinterpret_cast(ID.HashValue.data());
+size_t Result;
+memcpy(&Result, ID.HashValue.data(), sizeof(size_t));
+return llvm::hash_code(Result);
   }
   friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const SymbolID &ID);


Index: clangd/index/Index.h
===
--- clangd/index/Index.h
+++ clangd/index/Index.h
@@ -59,7 +59,9 @@
   friend llvm::hash_code hash_value(const SymbolID &ID) {
 // We already have a good hash, just return the first bytes.
 static_assert(sizeof(size_t) <= HashByteLength, "size_t longer than SHA1!");
-return *reinterpret_cast(ID.HashValue.data());
+size_t Result;
+memcpy(&Result, ID.HashValue.data(), sizeof(size_t));
+return llvm::hash_code(Result);
   }
   friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const SymbolID &ID);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D36918: [Sema] Take into account the current context when checking the accessibility of a member function pointer

2018-05-31 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

I don't particularly like that between setting the DeclContext 
(SemaTemplateDeduction.cpp:3814) and actually using it (CheckAccess() in 
SemaAccess.cpp:1459) are some 20 stack frames but it looks like you already 
tried fixing this "locally" in your initial approach.

I assume we can't get the appropriate DeclContext from Expr *OvlExpr in 
CheckAddressOfMemberAccess(), right?


Repository:
  rC Clang

https://reviews.llvm.org/D36918



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D36918: [Sema] Take into account the current context when checking the accessibility of a member function pointer

2018-06-04 Thread Jan Korous via Phabricator via cfe-commits
jkorous accepted this revision.
jkorous added a comment.

LGTM.

Thank you for the explanation!


Repository:
  rC Clang

https://reviews.llvm.org/D36918



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D45884: [Sema] Fix parsing of anonymous union in language linkage specification

2018-06-05 Thread Jan Korous via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC334062: [Sema] Fix parsing of anonymous union in language 
linkage specification (authored by jkorous, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D45884?vs=143736&id=150069#toc

Repository:
  rC Clang

https://reviews.llvm.org/D45884

Files:
  lib/Sema/SemaDecl.cpp
  test/SemaCXX/anonymous-union-export.cpp
  test/SemaCXX/anonymous-union.cpp


Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -4642,12 +4642,14 @@
 unsigned DiagID;
 if (Record->isUnion()) {
   // C++ [class.union]p6:
+  // C++17 [class.union.anon]p2:
   //   Anonymous unions declared in a named namespace or in the
   //   global namespace shall be declared static.
+  DeclContext *OwnerScope = Owner->getRedeclContext();
   if (DS.getStorageClassSpec() != DeclSpec::SCS_static &&
-  (isa(Owner) ||
-   (isa(Owner) &&
-cast(Owner)->getDeclName( {
+  (OwnerScope->isTranslationUnit() ||
+   (OwnerScope->isNamespace() &&
+!cast(OwnerScope)->isAnonymousNamespace( {
 Diag(Record->getLocation(), diag::err_anonymous_union_not_static)
   << FixItHint::CreateInsertion(Record->getLocation(), "static ");
 
Index: test/SemaCXX/anonymous-union.cpp
===
--- test/SemaCXX/anonymous-union.cpp
+++ test/SemaCXX/anonymous-union.cpp
@@ -80,6 +80,10 @@
   float float_val;
 };
 
+extern "C++" {
+union { }; // expected-error{{anonymous unions at namespace or global scope 
must be declared 'static'}}
+}
+
 static union {
   int int_val2; // expected-note{{previous definition is here}}
   float float_val2;
Index: test/SemaCXX/anonymous-union-export.cpp
===
--- test/SemaCXX/anonymous-union-export.cpp
+++ test/SemaCXX/anonymous-union-export.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -std=c++17 -fmodules-ts -emit-obj -verify %s
+
+export module M;
+export {
+union { bool a; }; // expected-error{{anonymous unions at namespace or 
global scope must be declared 'static'}}
+}


Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -4642,12 +4642,14 @@
 unsigned DiagID;
 if (Record->isUnion()) {
   // C++ [class.union]p6:
+  // C++17 [class.union.anon]p2:
   //   Anonymous unions declared in a named namespace or in the
   //   global namespace shall be declared static.
+  DeclContext *OwnerScope = Owner->getRedeclContext();
   if (DS.getStorageClassSpec() != DeclSpec::SCS_static &&
-  (isa(Owner) ||
-   (isa(Owner) &&
-cast(Owner)->getDeclName( {
+  (OwnerScope->isTranslationUnit() ||
+   (OwnerScope->isNamespace() &&
+!cast(OwnerScope)->isAnonymousNamespace( {
 Diag(Record->getLocation(), diag::err_anonymous_union_not_static)
   << FixItHint::CreateInsertion(Record->getLocation(), "static ");
 
Index: test/SemaCXX/anonymous-union.cpp
===
--- test/SemaCXX/anonymous-union.cpp
+++ test/SemaCXX/anonymous-union.cpp
@@ -80,6 +80,10 @@
   float float_val;
 };
 
+extern "C++" {
+union { }; // expected-error{{anonymous unions at namespace or global scope must be declared 'static'}}
+}
+
 static union {
   int int_val2; // expected-note{{previous definition is here}}
   float float_val2;
Index: test/SemaCXX/anonymous-union-export.cpp
===
--- test/SemaCXX/anonymous-union-export.cpp
+++ test/SemaCXX/anonymous-union-export.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -std=c++17 -fmodules-ts -emit-obj -verify %s
+
+export module M;
+export {
+union { bool a; }; // expected-error{{anonymous unions at namespace or global scope must be declared 'static'}}
+}
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53290: [WIP] clangd Transport layer

2018-10-15 Thread Jan Korous via Phabricator via cfe-commits
jkorous created this revision.
jkorous added a reviewer: sammccall.
Herald added subscribers: cfe-commits, kadircet, jfb, arphaman, dexonsmith, 
MaskRay, ioeric, ilya-biryukov, mgorny.

Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53290

Files:
  clangd/CMakeLists.txt
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/JSONRPCDispatcher.cpp
  clangd/JSONRPCDispatcher.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  clangd/Transport.cpp
  clangd/Transport.h
  clangd/tool/ClangdMain.cpp

Index: clangd/tool/ClangdMain.cpp
===
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -315,13 +315,20 @@
   CCOpts.EnableFunctionArgSnippets = EnableFunctionArgSnippets;
   CCOpts.AllScopes = AllScopesCompletion;
 
+  // TODO
+  std::unique_ptr TransportLayer = newJSONTransport(stdin, llvm::outs(), InputStyle);
+  if (!TransportLayer.get()) {
+  // TODO
+  return 42;
+  }
+
   // Initialize and run ClangdLSPServer.
   ClangdLSPServer LSPServer(
-  Out, CCOpts, CompileCommandsDirPath,
+  *TransportLayer.get(), CCOpts, CompileCommandsDirPath,
   /*ShouldUseInMemoryCDB=*/CompileArgsFrom == LSPCompileArgs, Opts);
   constexpr int NoShutdownRequestErrorCode = 1;
   llvm::set_thread_name("clangd.main");
   // Change stdin to binary to not lose \r\n on windows.
   llvm::sys::ChangeStdinToBinary();
-  return LSPServer.run(stdin, InputStyle) ? 0 : NoShutdownRequestErrorCode;
+  return LSPServer.run() ? 0 : NoShutdownRequestErrorCode;
 }
Index: clangd/Transport.h
===
--- /dev/null
+++ clangd/Transport.h
@@ -0,0 +1,94 @@
+//===--- Transport.h - sending and receiving LSP messages ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+// The language server protocol is usually implemented by writing messages as
+// JSON-RPC over the stdin/stdout of a subprocess. However other communications
+// mechanisms are possible, such as XPC on mac (see xpc/ directory).
+//
+// The Transport interface allows the mechanism to be replaced, and the JSONRPC
+// Transport is the standard implementation.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRANSPORT_H_
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRANSPORT_H_
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/JSON.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+namespace clangd {
+
+// A transport is responsible for maintaining the connection to a client
+// application, and reading/writing structured messages to it.
+//
+// Transports have limited thread safety requirements:
+//  - messages will not be sent concurrently
+//  - messages MAY be sent while loop() is reading, or its callback is active
+class Transport {
+public:
+  Transport() : shouldTerminateLoop(false) { }
+  virtual ~Transport() = default;
+
+  // Called by Clangd to send messages to the client.
+  // (Because JSON and XPC are so similar, these are concrete and delegate to
+  // sendMessage. We could change this to support more diverse transports).
+  void notifyClient(llvm::StringRef Method, llvm::json::Value Params);
+  void callClient(llvm::StringRef Method, llvm::json::Value Params,
+llvm::json::Value ID);
+  void replyToClient(llvm::json::Value ID, llvm::Expected Result);
+
+  // Implemented by Clangd to handle incoming messages. (See loop() below).
+  class MessageHandler {
+  public:
+// TODO was originally abstract
+virtual ~MessageHandler() {}
+virtual bool notifyServer(llvm::StringRef Method, llvm::json::Value ) = 0;
+virtual bool callServer(llvm::StringRef Method, llvm::json::Value Params,
+  llvm::json::Value ID) = 0;
+virtual bool replyToServer(llvm::json::Value ID,
+   llvm::Expected Result) = 0;
+  };
+  // Called by Clangd to receive messages from the client.
+  // The transport should in turn invoke the handler to process messages.
+  // If handler returns true, the transport should immedately return success.
+  // Otherwise, it returns an error when the transport becomes unusable.
+  // (Because JSON and XPC are so similar, they share handleMessage()).
+  virtual bool loop(MessageHandler &) = 0;
+
+  std::atomic shouldTerminateLoop;
+
+protected:
+  // Common implementation for notify(), call(), and reply().
+  virtual void sendMessage(llvm::json::Value) = 0;
+  // Delegates to notify(), call(), and reply().
+  bool handleMessage(llvm::json::Value, MessageHandler&);
+};
+
+// Controls the way JSON-RPC messages are encoded (both input and output).
+enum JSONSt

[PATCH] D56611: [clangd] A code action to swap branches of an if statement

2019-01-14 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

Hi Ilya, this seems really useful for people learning how to implement their 
custom actions!




Comment at: clangd/refactor/actions/SwapIfBranches.cpp:36
+
+  bool VisitIfStmt(IfStmt *If) {
+auto R = toHalfOpenFileRange(Ctx.getSourceManager(), Ctx.getLangOpts(),

It seems to me we don't find If token whenever
CursorLoc == location of 'f' of the If token

For example if there's "if" starting at location 1:1 I think we proceed like 
this (hope my pseudocode is clear):

1. `If->getIfLoc()` returns `SourceLocation{1:1}`
2. we construct `SourceRange{begin = 1:1, end = 1:1}`
3. `toHalfOpenFileRange()` returns `SourceRange{1:1, 1:2}`
4. the condition for `SourceLocation L` in `halfOpenRangeContains()` is `1:1 <= 
LOffset && LOffset < 1:2` which is only ever true for L == 1:1

Do I understand it right?



Comment at: clangd/refactor/actions/SwapIfBranches.cpp:62
+
+  // avoid dealing with single-statement brances, they require careful handling
+  // to avoid changing semantics of the code (i.e. dangling else).

Just a typo in comment `s/brances/branches/`


Repository:
  rCTE Clang Tools Extra

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D56611/new/

https://reviews.llvm.org/D56611



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D56610: [clangd] A code action to qualify an unqualified name

2019-01-14 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

Hi Ilya, I got here from reading your other patch 
(https://reviews.llvm.org/D56611). I'm wondering if we could make those range 
utility functions more understandable.




Comment at: clangd/SourceCode.h:64
 
+/// Turns a token range into a half-open range and checks its correctness.
+/// The resulting range will have only valid source location on both sides, 
both

It seems to me the range is actually closed on both sides.
Do I get it right that the result is?

```
[begin of first token : end of last token]
```

Wouldn't some name like `toWholeTokenRange` be easier to understand?



Comment at: clangd/SourceCode.h:81
+/// Preconditions: isValidFileRange(R) == true, L is a file location.
+bool halfOpenRangeContains(const SourceManager &Mgr, SourceRange R,
+   SourceLocation L);

I'd find it helpful to mention that the range is actually interpreted as 
closed-open (knowing which half is which).


Repository:
  rCTE Clang Tools Extra

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D56610/new/

https://reviews.llvm.org/D56610



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54428: [clangd] XPC transport layer, framework, test-client

2019-01-15 Thread Jan Korous via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rCTE351280: [clangd] XPC transport layer (authored by jkorous, 
committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D54428?vs=180809&id=181925#toc

Repository:
  rCTE Clang Tools Extra

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D54428/new/

https://reviews.llvm.org/D54428

Files:
  CMakeLists.txt
  clangd/CMakeLists.txt
  clangd/Features.inc.in
  clangd/Transport.h
  clangd/tool/CMakeLists.txt
  clangd/tool/ClangdMain.cpp
  clangd/xpc/CMakeLists.txt
  clangd/xpc/Conversion.cpp
  clangd/xpc/Conversion.h
  clangd/xpc/README.txt
  clangd/xpc/XPCTransport.cpp
  clangd/xpc/cmake/Info.plist.in
  clangd/xpc/cmake/XPCServiceInfo.plist.in
  clangd/xpc/cmake/modules/CreateClangdXPCFramework.cmake
  clangd/xpc/framework/CMakeLists.txt
  clangd/xpc/framework/ClangdXPC.cpp
  clangd/xpc/test-client/CMakeLists.txt
  clangd/xpc/test-client/ClangdXPCTestClient.cpp
  test/CMakeLists.txt
  test/clangd/xpc/initialize.test
  test/lit.cfg
  test/lit.site.cfg.in
  unittests/clangd/CMakeLists.txt
  unittests/clangd/xpc/CMakeLists.txt
  unittests/clangd/xpc/ConversionTests.cpp

Index: unittests/clangd/xpc/ConversionTests.cpp
===
--- unittests/clangd/xpc/ConversionTests.cpp
+++ unittests/clangd/xpc/ConversionTests.cpp
@@ -0,0 +1,36 @@
+//===-- ConversionTests.cpp  --*- C++ -*---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "xpc/Conversion.h"
+#include "gtest/gtest.h"
+
+#include 
+
+namespace clang {
+namespace clangd {
+namespace {
+
+using namespace llvm;
+
+TEST(JsonXpcConversionTest, JsonToXpcToJson) {
+
+  for (auto &testcase :
+   {json::Value(false), json::Value(3.14), json::Value(42),
+json::Value(-100), json::Value("foo"), json::Value(""),
+json::Value("123"), json::Value(" "),
+json::Value{true, "foo", nullptr, 42},
+json::Value(json::Object{
+{"a", true}, {"b", "foo"}, {"c", nullptr}, {"d", 42}})}) {
+EXPECT_TRUE(testcase == xpcToJson(jsonToXpc(testcase))) << testcase;
+  }
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang
Index: unittests/clangd/xpc/CMakeLists.txt
===
--- unittests/clangd/xpc/CMakeLists.txt
+++ unittests/clangd/xpc/CMakeLists.txt
@@ -0,0 +1,21 @@
+set(LLVM_LINK_COMPONENTS
+  support
+  )
+
+get_filename_component(CLANGD_SOURCE_DIR
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../clangd REALPATH)
+include_directories(
+  ${CLANGD_SOURCE_DIR}
+  )
+
+add_extra_unittest(ClangdXpcTests
+  ConversionTests.cpp
+  )
+
+target_link_libraries(ClangdXpcTests
+  PRIVATE
+  clangdXpcJsonConversions
+  clangDaemon
+  LLVMSupport
+  LLVMTestingSupport
+  )
Index: unittests/clangd/CMakeLists.txt
===
--- unittests/clangd/CMakeLists.txt
+++ unittests/clangd/CMakeLists.txt
@@ -65,3 +65,7 @@
   LLVMSupport
   LLVMTestingSupport
   )
+
+if (CLANGD_BUILD_XPC)
+  add_subdirectory(xpc)
+endif ()
Index: clangd/Features.inc.in
===
--- clangd/Features.inc.in
+++ clangd/Features.inc.in
@@ -0,0 +1 @@
+#define CLANGD_BUILD_XPC @CLANGD_BUILD_XPC@
Index: clangd/xpc/framework/ClangdXPC.cpp
===
--- clangd/xpc/framework/ClangdXPC.cpp
+++ clangd/xpc/framework/ClangdXPC.cpp
@@ -0,0 +1,5 @@
+
+/// Returns the bundle identifier of the Clangd XPC service.
+extern "C" const char *clangd_xpc_get_bundle_identifier() {
+  return "org.llvm.clangd";
+}
Index: clangd/xpc/framework/CMakeLists.txt
===
--- clangd/xpc/framework/CMakeLists.txt
+++ clangd/xpc/framework/CMakeLists.txt
@@ -0,0 +1,9 @@
+
+set(SOURCES
+ClangdXPC.cpp)
+add_clang_library(ClangdXPCLib SHARED
+  ${SOURCES}
+  DEPENDS
+  clangd
+)
+create_clangd_xpc_framework(ClangdXPCLib "ClangdXPC")
Index: clangd/xpc/CMakeLists.txt
===
--- clangd/xpc/CMakeLists.txt
+++ clangd/xpc/CMakeLists.txt
@@ -0,0 +1,29 @@
+set(CLANGD_XPC_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+set(CLANGD_XPC_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
+include(CreateClangdXPCFramework)
+
+add_subdirectory(framework)
+add_subdirectory(test-client)
+
+include_directories(
+  ${CMAKE_CURRENT_SOURCE_DIR}/../
+)
+
+set(LLVM_LINK_COMPONENTS
+  Support
+  )
+
+# Needed by LLVM's CMake checks because this file defines multiple targets.
+set(LLVM_OPTIONAL_SOURCES Conversio

[PATCH] D50452: [WIP] clangd XPC adapter

2019-01-24 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

Abandonned in favor of https://reviews.llvm.org/D54428


Repository:
  rCTE Clang Tools Extra

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D50452/new/

https://reviews.llvm.org/D50452



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D56561: [Preprocessor] For missing file in framework add note about framework location.

2019-01-24 Thread Jan Korous via Phabricator via cfe-commits
jkorous accepted this revision.
jkorous added a comment.
This revision is now accepted and ready to land.

LGTM with nits about doxygen annotations.




Comment at: clang/include/clang/Lex/DirectoryLookup.h:175
+  /// \param [out] IsFrameworkFound For a framework directory set to true if
+  /// specified '.framework' directory is found.
+  ///

We might make this easier to understand by explaining where/how the 
'.framework' directory is specified.



Comment at: clang/include/clang/Lex/HeaderSearch.h:396
+  /// \param IsFrameworkFound If non-null, will be set to true for a framework
+  /// include and if corresponding '.framework' directory was found. Doesn't
+  /// guarantee the requested file is found.

We might try to explain what exactly is meant by corresponding .framework 
directory.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D56561/new/

https://reviews.llvm.org/D56561



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D57057: [clangd] Log clang-tidy configuration, NFC

2019-01-24 Thread Jan Korous via Phabricator via cfe-commits
jkorous accepted this revision.
jkorous added a comment.
This revision is now accepted and ready to land.

LGTM


Repository:
  rCTE Clang Tools Extra

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D57057/new/

https://reviews.llvm.org/D57057



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D57228: [clangd] Make USRs for macros to be position independent

2019-01-25 Thread Jan Korous via Phabricator via cfe-commits
jkorous accepted this revision.
jkorous added a comment.
This revision is now accepted and ready to land.

Thanks for fixing this Kadir!

LGTM


Repository:
  rCTE Clang Tools Extra

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D57228/new/

https://reviews.llvm.org/D57228



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49736: [Basic] Emit warning flag suggestion only in case there's existing flag *similar* to the unknown one

2018-11-06 Thread Jan Korous via Phabricator via cfe-commits
jkorous requested review of this revision.
jkorous added a comment.

I tried to move the getNearestOption() to it's only client - 
EmitUnknownDiagWarning() but it turned out to be a significant change because 
of clang/Basic/DiagnosticGroups.inc use in DiagnosticIDs.cpp.
I suggest we leave that for eventual future refactoring since it would blow up 
scope of this patch a lot.


Repository:
  rC Clang

https://reviews.llvm.org/D49736



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50926: [SourceManager] Extract 'findFileIDsForFile' from 'translateFile' to allow mapping from one file entry to multiple FileIDs

2018-11-07 Thread Jan Korous via Phabricator via cfe-commits
jkorous accepted this revision.
jkorous added a comment.
This revision is now accepted and ready to land.

LGTM and it seems like all of Eric's comments were answered too.


Repository:
  rC Clang

https://reviews.llvm.org/D50926



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50801: [rename] Use isPointWithin when looking for a declaration at location

2018-11-07 Thread Jan Korous via Phabricator via cfe-commits
jkorous accepted this revision.
jkorous added a comment.
This revision is now accepted and ready to land.

LGTM Thanks for fixing this!


Repository:
  rC Clang

https://reviews.llvm.org/D50801



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D52554: [WIP] [clangd] Tests for special methods code-completion

2018-11-07 Thread Jan Korous via Phabricator via cfe-commits
jkorous marked 6 inline comments as done.
jkorous added inline comments.



Comment at: clangd/CodeCompleteTests.cpp:2043
 
+TEST(CompletionTestNoExplicitMembers, Struct) {
+  clangd::CodeCompleteOptions Opts;

sammccall wrote:
> sammccall wrote:
> > (Should this be ImplicitMembers?)
> nit: these cases should probably be moved up with the other code completion 
> ones, and called something like `TEST(CompletionTest, NoExplicitMembers)` or 
> so for consistency.
> 
> It's OK to have related tests in one test case.
> 
> In fact, this large set of closely-related cases seems like a good place for 
> Go-style table-driven tests.
Ultimately got rid of the name completely.



Comment at: clangd/CodeCompleteTests.cpp:2043
 
+TEST(CompletionTestNoExplicitMembers, Struct) {
+  clangd::CodeCompleteOptions Opts;

jkorous wrote:
> sammccall wrote:
> > sammccall wrote:
> > > (Should this be ImplicitMembers?)
> > nit: these cases should probably be moved up with the other code completion 
> > ones, and called something like `TEST(CompletionTest, NoExplicitMembers)` 
> > or so for consistency.
> > 
> > It's OK to have related tests in one test case.
> > 
> > In fact, this large set of closely-related cases seems like a good place 
> > for Go-style table-driven tests.
> Ultimately got rid of the name completely.
I reconsidered the simple yet verbatim approach.



Comment at: clangd/CodeCompleteTests.cpp:2054
+
+  EXPECT_TRUE(ResultsDot.Completions.empty());
+

sammccall wrote:
> EXPECT_THAT(ResultsDot.Completions, IsEmpty())
> 
> (when the assertion fails, the failure message will print the contents of the 
> container)
I didn't know this. It's pretty neat. Thanks!



Comment at: clangd/CodeCompleteTests.cpp:2139
+
+TEST(CompletionTestMethodDeclared, Struct) {
+  clangd::CodeCompleteOptions Opts;

sammccall wrote:
> doesn't this test a strict superset of what CompletionTestNoTestMembers tests?
> i.e. this also asserts that the implicit members are not included.
> 
> ISTM we could combine many of these tests (and that in fact many of them are 
> covered by TestAfterDotCompletion.
You are right, I pruned the list of testcases a bit.



Comment at: clangd/CodeCompleteTests.cpp:2338
+
+TEST(CompletionTestSpecialMethodsDeclared, 
ExplicitStructTemplateSpecialization) {
+  clangd::CodeCompleteOptions Opts;

sammccall wrote:
> (I think we could get away with a representative set of cases, rather than 
> testing the intersection of every feature. e.g. test an explicitly declared 
> operator= on a struct, but combining that with an explicitly specialized 
> struct template seems unneccesary)
I simplified the whole test and removed some cases that were not really unique. 
Do you think the rest is still too exhaustive? (Asking before deleting.)


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D52554



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D52554: [WIP] [clangd] Tests for special methods code-completion

2018-11-07 Thread Jan Korous via Phabricator via cfe-commits
jkorous updated this revision to Diff 172951.
jkorous marked 4 inline comments as done.
jkorous added a comment.

Rewritten tests to shared implementation different cases.


https://reviews.llvm.org/D52554

Files:
  unittests/clangd/CodeCompleteTests.cpp

Index: unittests/clangd/CodeCompleteTests.cpp
===
--- unittests/clangd/CodeCompleteTests.cpp
+++ unittests/clangd/CodeCompleteTests.cpp
@@ -2204,6 +2204,115 @@
  {cls("naber"), cls("nx::naber")}, Opts);
   EXPECT_THAT(Results.Completions, UnorderedElementsAre());
 }
+
+TEST(CompletionTest, NoCompletionForSpecialMembers) {
+  clangd::CodeCompleteOptions Opts;
+  for( auto& testcase : { 
+R"cpp(
+  struct foo {};
+  void bar() {
+foo a;
+a.^
+)cpp",
+R"cpp(
+  template struct foo {};
+  void bar() {
+foo a;
+a.^
+)cpp",
+R"cpp(
+template struct foo {}; template<> struct foo {};
+void bar() {
+  foo a;
+  a.^
+)cpp",
+R"cpp(
+  struct foo {};
+  void bar() {
+foo* b;
+b->^
+)cpp",
+R"cpp(
+  template struct foo {};
+  void bar() {
+foo* b;
+b->^
+)cpp",
+R"cpp(
+  template struct foo {}; template<> struct foo {};
+  void bar() {
+foo* b;
+b->^
+)cpp",
+R"cpp(
+  struct foo {};
+  foo::^
+)cpp",
+R"cpp(
+  template struct foo {};
+  foo::^
+)cpp",
+R"cpp(
+  template struct foo {}; template<> struct foo {};
+  foo::^
+)cpp",
+R"cpp(
+  struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); };
+  void bar() {
+foo a;
+a.^
+)cpp",
+R"cpp(
+  struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); };
+  void bar() {
+foo* b;
+b->^
+)cpp",
+R"cpp(
+  struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); };
+  foo::^
+)cpp",
+R"cpp(
+  template struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); };
+  void bar() {
+foo a;
+a.^
+)cpp",
+R"cpp(
+  template struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); };
+  void bar() {
+foo* b;
+b->^
+)cpp",
+R"cpp(
+  template struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); };
+  foo::^
+)cpp",
+R"cpp(
+  template struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); };
+  template<> struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); };
+  void bar() {
+foo a;
+a.^
+)cpp",
+R"cpp(
+  template struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); };
+  template<> struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); };
+  void bar() {
+foo* b;
+b->^
+)cpp",
+R"cpp(
+  template struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); };
+  template<> struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); };
+  foo::^
+)cpp"
+  }) {
+auto Results = completions(testcase, /*IndexSymbols=*/{}, Opts);
+EXPECT_THAT(Results.Completions, IsEmpty()) << testcase;
+  }
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54428: [clangd] XPC transport layer, framework, test-client

2018-11-12 Thread Jan Korous via Phabricator via cfe-commits
jkorous created this revision.
jkorous added reviewers: arphaman, sammccall.
Herald added subscribers: cfe-commits, kadircet, dexonsmith, MaskRay, ioeric, 
ilya-biryukov, mgorny.

Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D54428

Files:
  CMakeLists.txt
  Features.inc.in
  clangd/CMakeLists.txt
  clangd/xpc/CMakeLists.txt
  clangd/xpc/ConversionTests.cpp
  clangd/xpc/initialize.test
  lit.cfg
  lit.site.cfg.in
  tool/CMakeLists.txt
  tool/ClangdMain.cpp
  xpc/CMakeLists.txt
  xpc/Conversion.cpp
  xpc/Conversion.h
  xpc/README.txt
  xpc/XPCTransport.cpp
  xpc/XPCTransport.h
  xpc/cmake/Info.plist.in
  xpc/cmake/XPCServiceInfo.plist.in
  xpc/cmake/modules/CreateClangdXPCFramework.cmake
  xpc/framework/CMakeLists.txt
  xpc/framework/ClangdXPC.cpp
  xpc/test-client/CMakeLists.txt
  xpc/test-client/ClangdXPCTestClient.cpp

Index: clangd/xpc/ConversionTests.cpp
===
--- /dev/null
+++ clangd/xpc/ConversionTests.cpp
@@ -0,0 +1,36 @@
+//===-- ConversionTests.cpp  --*- C++ -*---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "xpc/Conversion.h"
+#include "gtest/gtest.h"
+
+#include 
+
+namespace clang {
+namespace clangd {
+namespace {
+
+using namespace llvm;
+
+TEST(JsonXpcConversionTest, JsonToXpcToJson) {
+
+  for (auto &testcase :
+   {json::Value(false), json::Value(3.14), json::Value(42),
+json::Value(-100), json::Value("foo"), json::Value(""),
+json::Value("123"), json::Value(" "),
+json::Value{true, "foo", nullptr, 42},
+json::Value(json::Object{
+{"a", true}, {"b", "foo"}, {"c", nullptr}, {"d", 42}})}) {
+EXPECT_TRUE(testcase == xpcToJson(jsonToXpc(testcase))) << testcase;
+  }
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang
Index: clangd/xpc/CMakeLists.txt
===
--- /dev/null
+++ clangd/xpc/CMakeLists.txt
@@ -0,0 +1,21 @@
+set(LLVM_LINK_COMPONENTS
+  support
+  )
+
+get_filename_component(CLANGD_SOURCE_DIR
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../clangd REALPATH)
+include_directories(
+  ${CLANGD_SOURCE_DIR}
+  )
+
+add_extra_unittest(ClangdXpcTests
+  ConversionTests.cpp
+  )
+
+target_link_libraries(ClangdXpcTests
+  PRIVATE
+  clangdXpcJsonConversions
+  clangDaemon
+  LLVMSupport
+  LLVMTestingSupport
+  )
Index: clangd/CMakeLists.txt
===
--- clangd/CMakeLists.txt
+++ clangd/CMakeLists.txt
@@ -60,3 +60,7 @@
   LLVMSupport
   LLVMTestingSupport
   )
+
+if (CLANGD_BUILD_XPC)
+  add_subdirectory(xpc)
+endif ()
Index: lit.site.cfg.in
===
--- lit.site.cfg.in
+++ lit.site.cfg.in
@@ -11,6 +11,7 @@
 config.python_executable = "@PYTHON_EXECUTABLE@"
 config.target_triple = "@TARGET_TRIPLE@"
 config.clang_staticanalyzer = @CLANG_ENABLE_STATIC_ANALYZER@
+config.clangd_xpc_support = @CLANGD_BUILD_XPC_SUPPORT@
 
 # Support substitution of the tools and libs dirs with user parameters. This is
 # used when we can't determine the tool dir at configuration time.
Index: lit.cfg
===
--- lit.cfg
+++ lit.cfg
@@ -117,6 +117,10 @@
 if platform.system() not in ['Windows']:
 config.available_features.add('ansi-escape-sequences')
 
+# XPC support for Clangd.
+if config.clangd_xpc_support:
+config.available_features.add('clangd-xpc-support')
+
 if config.clang_staticanalyzer:
 config.available_features.add('static-analyzer')
 
Index: clangd/xpc/initialize.test
===
--- /dev/null
+++ clangd/xpc/initialize.test
@@ -0,0 +1,10 @@
+# RUN: clangd-xpc-test-client < %s | FileCheck %s
+# REQUIRES: clangd-xpc-support
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootUri":"test:///workspace","capabilities":{},"trace":"off"}}
+# CHECK: {"id":0,"jsonrpc":"2.0","result":{"capabilities"
+
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+# CHECK: {"id":3,"jsonrpc":"2.0","result":null}
+
+{"jsonrpc":"2.0","method":"exit"}
Index: xpc/test-client/ClangdXPCTestClient.cpp
===
--- /dev/null
+++ xpc/test-client/ClangdXPCTestClient.cpp
@@ -0,0 +1,96 @@
+#include "xpc/Conversion.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/LineIterator.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
+#include 
+#include 
+#include 
+
+typedef const char *(*clangd_xpc_get_bundle_identifier_t)(void);
+
+using namespace llvm;
+

[PATCH] D54529: [clangd] Add USR to textDocument/definition response

2018-11-14 Thread Jan Korous via Phabricator via cfe-commits
jkorous created this revision.
jkorous added reviewers: sammccall, ilya-biryukov, arphaman, benlangmuir.
jkorous added a project: clang-tools-extra.
Herald added subscribers: cfe-commits, kadircet, dexonsmith, MaskRay, ioeric.

We need a way for given code position to get the best definition/declaration 
location in given translation unit and it's USR.

Since the first element in list returned by textDocument/definition is meeting 
the def/decl location requirement we'd just need to add the USR. Other option 
would be to split this to a separate method. I thought this patch to be a 
better fit from protocol perspective but I am happy to go the other way if 
that's preferred.

I'd like to ask if someone more familiar with gtest matchers could take a look 
at changes I made in unit-tests. I am not sure it's exactly the idiomatic way. 
I was trying to use Property() matchers first but gave up since I wasn't able 
to debug it (got lost in template error messages).


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D54529

Files:
  ClangdLSPServer.cpp
  ClangdLSPServer.h
  ClangdServer.cpp
  ClangdServer.h
  Protocol.cpp
  Protocol.h
  XRefs.cpp
  XRefs.h
  clangd/ClangdTests.cpp
  clangd/SyncAPI.cpp
  clangd/SyncAPI.h
  clangd/XRefsTests.cpp
  clangd/textdocument-didchange-fail.test
  clangd/xrefs.test

Index: clangd/XRefsTests.cpp
===
--- clangd/XRefsTests.cpp
+++ clangd/XRefsTests.cpp
@@ -94,6 +94,11 @@
 }
 
 MATCHER_P(RangeIs, R, "") { return arg.range == R; }
+MATCHER_P(RangeInLocationIs, R, "") { return arg.DefOrDeclLocation.range == R; }
+MATCHER_P(RangeInLocationIsRH, R, "") {
+  return arg == R.DefOrDeclLocation.range;
+}
+MATCHER_P(LocationIs, R, "") { return arg.DefOrDeclLocation == R; }
 
 TEST(GoToDefinition, WithIndex) {
   Annotations SymbolHeader(R"cpp(
@@ -124,35 +129,39 @@
   ^f1();
 }
   )cpp");
-  EXPECT_THAT(runFindDefinitionsWithIndex(Test),
-  testing::ElementsAreArray(
-  {RangeIs(SymbolCpp.range("f1")), RangeIs(Test.range())}));
+  EXPECT_THAT(
+  runFindDefinitionsWithIndex(Test),
+  testing::ElementsAreArray({RangeInLocationIs(SymbolCpp.range("f1")),
+ RangeInLocationIs(Test.range())}));
 
   Test = Annotations(R"cpp(// definition in AST.
 void [[f1]]() {}
 int main() {
   ^f1();
 }
   )cpp");
-  EXPECT_THAT(runFindDefinitionsWithIndex(Test),
-  testing::ElementsAreArray(
-  {RangeIs(Test.range()), RangeIs(SymbolHeader.range("f1"))}));
+  EXPECT_THAT(
+  runFindDefinitionsWithIndex(Test),
+  testing::ElementsAreArray({RangeInLocationIs(Test.range()),
+ RangeInLocationIs(SymbolHeader.range("f1"))}));
 
   Test = Annotations(R"cpp(// forward declaration in AST.
 class [[Foo]];
 F^oo* create();
   )cpp");
-  EXPECT_THAT(runFindDefinitionsWithIndex(Test),
-  testing::ElementsAreArray(
-  {RangeIs(SymbolHeader.range("foo")), RangeIs(Test.range())}));
+  EXPECT_THAT(
+  runFindDefinitionsWithIndex(Test),
+  testing::ElementsAreArray({RangeInLocationIs(SymbolHeader.range("foo")),
+ RangeInLocationIs(Test.range())}));
 
   Test = Annotations(R"cpp(// defintion in AST.
 class [[Forward]] {};
 F^orward create();
   )cpp");
   EXPECT_THAT(runFindDefinitionsWithIndex(Test),
   testing::ElementsAreArray({
-  RangeIs(Test.range()), RangeIs(SymbolHeader.range("forward")),
+  RangeInLocationIs(Test.range()),
+  RangeInLocationIs(SymbolHeader.range("forward")),
   }));
 }
 
@@ -302,12 +311,13 @@
   for (const char *Test : Tests) {
 Annotations T(Test);
 auto AST = TestTU::withCode(T.code()).build();
-std::vector> ExpectedLocations;
-for (const auto &R : T.ranges())
-  ExpectedLocations.push_back(RangeIs(R));
-EXPECT_THAT(findDefinitions(AST, T.point()),
-ElementsAreArray(ExpectedLocations))
-<< Test;
+
+auto definitions = findDefinitions(AST, T.point());
+std::vector> Assertions;
+for (const auto &D : definitions)
+  Assertions.push_back(RangeInLocationIsRH(D));
+
+EXPECT_THAT(T.ranges(), ElementsAreArray(Assertions)) << Test;
   }
 }
 
@@ -334,22 +344,27 @@
   )cpp");
   auto AST = TestTU::withCode(T.code()).build();
   EXPECT_THAT(findDefinitions(AST, T.point("1")),
-  ElementsAre(RangeIs(T.range("str")), RangeIs(T.range("foo4";
+  ElementsAre(RangeInLocationIs(T.range("str")),
+  RangeInLocationIs(T.range("foo4";
   EXPECT_THAT(findDefinitions(AST, T.point("2")),
-  ElementsAre(RangeIs(T.range("str";
+  ElementsAre(RangeInLocationIs(T.range("str";
   EXPECT_THAT(findDefinitions(AST, T.point("3")),
- 

[PATCH] D54529: [clangd] Add USR to textDocument/definition response

2018-11-14 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

One more thing - shall I create new client capability flag for this?


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D54529



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54529: [clangd] Add USR to textDocument/definition response

2018-11-14 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

Hi Sam!

I am aware of clangd using SymbolID. We basically need USR for integration with 
our external indexing service. We don't plan to systematically use it in the 
protocol and I am not aware of any other requirement for using USR in LSP - 
will double check that to be sure.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D54529



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54529: [clangd] Add USR to textDocument/definition response

2018-11-14 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

We are also discussing creating separate method as we'll likely want to add 
other data to the response in the future. Would you prefer USR not to be in the 
standard part of LSP but only in our extension?


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D54529



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54529: [clangd] Add USR to textDocument/definition response

2018-11-14 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

Correction - I asked offline about our intended use of USR in LSP and it seems 
we might want to receive it as part of other responses too. Nothing specific 
for now but it's probable that it won't be just this singular case.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D54529



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53900: [CodeComplete] Penalize inherited ObjC properties for auto-completion

2018-11-15 Thread Jan Korous via Phabricator via cfe-commits
jkorous added reviewers: arphaman, benlangmuir.
jkorous added a comment.

This looks reasonable to me but asked people with more context to take a look.


Repository:
  rC Clang

https://reviews.llvm.org/D53900



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54428: [clangd] XPC transport layer, framework, test-client

2018-11-15 Thread Jan Korous via Phabricator via cfe-commits
jkorous planned changes to this revision.
jkorous added a comment.

In https://reviews.llvm.org/D54428#1297147, @sammccall wrote:

> A question about the high-level build target setup (I don't know much about 
> XPC services/frameworks, bear with me...):
>
> This is set up so that the clangd binary (ClangdMain) can run unmodified as 
> an XPC service, all flags and options are still respected etc.
>  At the same time, the framework plist seems like it is designed to invoke 
> the clangd binary in a very specific configuration (no flags will be plumbed 
> through).
>
> Is it actually important that the `clangd` binary itself can be used with 
> XPC, rather than defining another binary that spawns a 
> `ClangdServer+XPCTransport` with the right config? If you strip out all of 
> `ClangdMain` that's not related to flag parsing and options, there's almost 
> nothing left...


I don't really expect you to be familiar with XPC - feel free to ask about 
anything and I'll do my best explaining.

It's more like that configuration isn't implemented in this initial patch but 
as we can't use command line options (launchd doesn't pass these to XPC 
service) we'll have to duplicate these as environment variables. We discusse 
internally and we prefer to have just single binary as that would make 
integration and testing easier for us.




Comment at: tool/ClangdMain.cpp:30
+#ifdef CLANGD_BUILD_XPC
+#include "xpc/XPCTransport.h"
+#endif

sammccall wrote:
> WDYT about putting `newXPCTransport()` in `Transport.h` behind an ifdef?
> 
> That will be consistent with JSON, allow the `XPCTransport.h` to be removed 
> entirely, and remove one #ifdef here.
> 
> I find the #ifdefs easier to understand if they surround functional code, 
> rather than #includes - might be just me.
Ok, sounds reasonable.



Comment at: tool/ClangdMain.cpp:328
+#ifdef CLANGD_BUILD_XPC
+if (getenv("CLANGD_AS_XPC_SERVICE"))
+  return newXPCransport();

sammccall wrote:
> I'd consider putting this outside the #ifdef, so we can print an error and 
> exit if it's requested but not built.
> 
> In fact, can this just be a regular flag instead? `-transport={xpc|json}`
Unfortunately it's not possible to have launchd pass flags when spawning XPC 
services (otherwise it would be my first choice too).



Comment at: tool/ClangdMain.cpp:329
+if (getenv("CLANGD_AS_XPC_SERVICE"))
+  return newXPCransport();
+#endif

sammccall wrote:
> no support for `-input-mirror` or pretty-printing in the logs - deliberate?
I was thinking this could be added later.



Comment at: xpc/CMakeLists.txt:21
+
+add_clang_library(clangdXpcJsonConversions
+  Conversion.cpp

sammccall wrote:
> why is conversions a separate library from transport?
> 
> No problem with fine-grained targets per se, but it's inconsistent with much 
> of the rest of clang-tools-extra.
Guilty of YAGNI violation here - was thinking about eventual use by XPC 
clients. I'll stick to consistency for now and would separate it if needed.



Comment at: xpc/Conversion.cpp:16
+
+using namespace clang;
+using namespace clangd;

sammccall wrote:
> nit:
> ```
> using namespace llvm;
> namespace clang {
> namespace clangd {
> ```
> (we're finally consistent about this)
Ok. Thanks.



Comment at: xpc/Conversion.cpp:22
+xpc_object_t clangd::jsonToXpc(const json::Value &json) {
+  const char *const key = "LSP";
+  std::string payload_string;

sammccall wrote:
> Key, PayloadString, etc
Thanks. Somehow I was always working on projects with different naming 
conventions and still struggle with this.



Comment at: xpc/Conversion.cpp:23
+  const char *const key = "LSP";
+  std::string payload_string;
+  raw_string_ostream payload_stream(payload_string);

sammccall wrote:
> nit: you can #include ScopedPrinter, and then this is just 
> llvm::to_string(json)
I'll take a look at ScopedPrinter. Thanks.



Comment at: xpc/Conversion.cpp:28
+  xpc_object_t payload_obj = xpc_string_create(payload_string.c_str());
+  return xpc_dictionary_create(&key, &payload_obj, 1);
+}

sammccall wrote:
> ah, this encoding is a little sad vs the "native" encoding of object -> 
> xpc_dictionary, array -> xpc_array etc which looked promising...
> 
> Totally your call, but out of curiosity - why the change?
I know. At first we didn't even think of anything else than 1:1 mapping between 
JSON and XPC dictionary as it's just natural. But later we learned about 
performance issues with construction of XPC dictionaries with lots of elements 
which would be a problem for code completion.



Comment at: xpc/Conversion.h:19
+
+xpc_object_t jsonToXpc(const llvm::json::Value &json);
+llvm::json::Value xpcToJson(const xpc_object_t &json);

sammccall wrote:
> param nam

[PATCH] D54047: Check TUScope is valid before use

2018-11-16 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

Could you please add a test? I'd suggest minimizing the testcase you linked and 
placing it to `clang/test`.


Repository:
  rC Clang

https://reviews.llvm.org/D54047



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49736: [Basic] Emit warning flag suggestion only in case there's existing flag *similar* to the unknown one

2018-11-16 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

Ping.


Repository:
  rC Clang

https://reviews.llvm.org/D49736



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53807: Create a diagnostic group for warn_call_to_pure_virtual_member_function_from_ctor_dtor, so it can be turned into an error using Werror

2018-11-16 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a reviewer: jkorous.
jkorous accepted this revision.
jkorous added a comment.
This revision is now accepted and ready to land.

LGTM. Thanks for the patch!


Repository:
  rC Clang

https://reviews.llvm.org/D53807



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54047: Check TUScope is valid before use

2018-11-19 Thread Jan Korous via Phabricator via cfe-commits
jkorous added reviewers: rjmccall, doug.gregor.
jkorous added subscribers: rjmccall, doug.gregor.
jkorous added a comment.

Adding @rjmccall and @doug.gregor who might have some insight.

Honestly, I don't know how IWYU works and my familiarity with Sema is limited 
so bear with me.

From what I see `TUScope` is set only in one place in clang and that is `void 
Sema::ActOnTranslationUnitScope(Scope *S)`.

  > grep -nr --exclude="*/test/*" "TUScope\s\+=" .
  ./lib/Sema/Sema.cpp:70:  TUScope = S;
  ./lib/Sema/Sema.cpp:149:  TUScope = nullptr;
  ./lib/Sema/Sema.cpp:946:  TUScope = nullptr;
  ./lib/Sema/Sema.cpp:1168:TUScope = nullptr;

(TUScope seems not to be copied anywhere.)

  > grep -nr --exclude="*/test/*" "=\s\+TUScope" .

`ActOnTranslationUnitScope` itself is called only from `void 
Parser::Initialize()`.

Just an idea - can't your code mimic behavior of `Parser::Initialize()`?

Other than that it seems that:

1. The code obviously assumes `TUScope != nullptr`.
2. We aren't aware of hitting this case in clang.

So even with my limited insight I would be inclined to make the assumption 
explicit. The whole block of code after `if (isValidVarArgType(E->getType()) == 
VAK_Undefined)` seems to be mostly checks for errors so `ExprError()` seems 
like the right error reporting mechanism here as it's part of this method's 
interface and randomly picked caller's code in `SemaOverload.cpp` seems to 
handle such case.

Re: tests Since you are using Sema from your code I assume you should be able 
to create a regression test (with a suitable code input) as a minimal 
reproducer. You might take a look how is `Sema` set up in unittests.


Repository:
  rC Clang

https://reviews.llvm.org/D54047



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54693: [clangd] Store source file hash in IndexFile{In,Out}

2018-11-19 Thread Jan Korous via Phabricator via cfe-commits
jkorous added a comment.

Hi Kadir, I have one small nit otherwise LGTM.




Comment at: clangd/index/Serialization.cpp:368
+Reader Hash(Chunks.lookup("hash"));
+llvm::StringRef Digest = Hash.consume(20);
+Result.Digest.emplace();

Nit: Maybe we could use `Result.Digest.size()` and avoid having `20` hardcoded 
here?


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D54693



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54799: [clangd][WIP] textDocument/CursorInfo method

2018-11-21 Thread Jan Korous via Phabricator via cfe-commits
jkorous created this revision.
jkorous added reviewers: sammccall, arphaman, benlangmuir.
Herald added subscribers: cfe-commits, kadircet, dexonsmith, MaskRay, ioeric, 
ilya-biryukov.

Hi,

I implemented `textDocument/cursorInfo` method based on consensus in 
https://reviews.llvm.org/D54529.
I'd like to ask for early feedback - what's still missing is relevant client 
capability.

Couple things that I'd love to hear opinions about are:

- conditional return in `getCursorInfo` - Should we return for example data 
with empty `USR`?
- `containerName` of local variables - It's currently empty even if semantic 
parent has a name (say it's a function). (Please search for local.cpp in the 
test.) Is that what we want?
- For now I used `getSymbolAtPosition()` as it's simpler and fits the context 
better. However I assume I could use this optimization from 
`tooling::getNamedDeclAt()` (in a separate patch): 
https://github.com/llvm-mirror/clang/blob/master/lib/Tooling/Refactoring/Rename/USRFinder.cpp#L82
- One thing I am wondering about is whether we could use (and whether it's a 
significant improvement) some early return in `indexTopLevelDecls` (using 
`DeclarationAndMacrosFinder`) also for hover and definition use-cases. Is it 
correct to assume that at a given `Location` there can be maximum of one 
declaration and one definition?

P. S. Alex and Ben have thanksgiving break now so they'll probably add any 
feedback next week.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D54799

Files:
  ClangdLSPServer.cpp
  ClangdLSPServer.h
  ClangdServer.cpp
  ClangdServer.h
  Protocol.cpp
  Protocol.h
  XRefs.cpp
  XRefs.h
  clangd/cursor-info.test

Index: clangd/cursor-info.test
===
--- /dev/null
+++ clangd/cursor-info.test
@@ -0,0 +1,46 @@
+# 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/cursorInfo","params":{"textDocument":{"uri":"test:///simple.cpp"},"position":{"line":0,"character":27}}}
+#  CHECK:"containerName": "",
+# CHECK-NEXT:"id": "CA2EBE44A1D76D2A1547D47BC6D51EBF",
+# CHECK-NEXT:"name": "foo",
+# CHECK-NEXT:"usr": "c:@F@foo#"
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///nested-decl.cpp","languageId":"cpp","version":1,"text":"namespace nnn { struct aaa {}; void foo() { aaa a; }; }"}}}
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/cursorInfo","params":{"textDocument":{"uri":"test:///nested-decl.cpp"},"position":{"line":0,"character":46}}}
+#  CHECK:"containerName": "nnn::",
+# CHECK-NEXT:"id": "20237FF18EB405D842456DC5D578426D",
+# CHECK-NEXT:"name": "aaa",
+# CHECK-NEXT:"usr": "c:@N@nnn@S@aaa"
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///reference.cpp","languageId":"cpp","version":1,"text":"int value; void foo(int) {} void bar() { foo(value); }"}}}
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/cursorInfo","params":{"textDocument":{"uri":"test:///reference.cpp"},"position":{"line":0,"character":48}}}
+#  CHECK:"containerName": "",
+# CHECK-NEXT:"id": "844613FB2393C9D40A2AFF25D5D316A1",
+# CHECK-NEXT:"name": "value",
+# CHECK-NEXT:"usr": "c:@value"
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///local.cpp","languageId":"cpp","version":1,"text":"void foo() { int aaa; int bbb = aaa; }"}}}
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/cursorInfo","params":{"textDocument":{"uri":"test:///local.cpp"},"position":{"line":0,"character":33}}}
+#  CHECK:"containerName": "",
+# CHECK-NEXT:"id": "C05589F2664B06F392C2C438568E55E0",
+# CHECK-NEXT:"name": "aaa",
+# CHECK-NEXT:"usr": "c:local.cpp@13@F@foo#@aaa"
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///macro.cpp","languageId":"cpp","version":1,"text":"#define MACRO 5\nint i = MACRO;"}}}
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/cursorInfo","params":{"textDocument":{"uri":"test:///macro.cpp"},"position":{"line":1,"character":11}}}
+#  CHECK:"containerName": "",
+# CHECK-NEXT:"id": "29EB506CBDF1BA6D1B6EC203FF03B384",
+# CHECK-NEXT:"name": "MACRO",
+# CHECK-NEXT:"usr": "c:macro.cpp@24@macro@MACRO"
+---
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
Index: XRefs.h
===
--- XRefs.h
+++ XRefs.h
@@ -38,6 +38,9 @@
 std::vector findReferences(ParsedAST &AST, Position Pos,
  const Symbo

  1   2   3   4   5   >