[PATCH] D40488: [clangd] Implemented tracing using Context

2017-12-14 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL320706: [clangd] Implemented tracing using Context (authored 
by ibiryukov, committed by ).

Repository:
  rL LLVM

https://reviews.llvm.org/D40488

Files:
  clang-tools-extra/trunk/clangd/ClangdUnit.cpp
  clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp
  clang-tools-extra/trunk/clangd/Trace.cpp
  clang-tools-extra/trunk/clangd/Trace.h
  clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp
  clang-tools-extra/trunk/unittests/clangd/TraceTests.cpp

Index: clang-tools-extra/trunk/clangd/Trace.h
===
--- clang-tools-extra/trunk/clangd/Trace.h
+++ clang-tools-extra/trunk/clangd/Trace.h
@@ -8,60 +8,74 @@
 //===--===//
 //
 // Supports writing performance traces describing clangd's behavior.
-// Traces are written in the Trace Event format supported by chrome's trace
-// viewer (chrome://tracing).
+// Traces are consumed by implementations of the EventTracer interface.
 //
-// The format is documented here:
-// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
 //
 // All APIs are no-ops unless a Session is active (created by ClangdMain).
 //
 //===--===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
 
+#include "Context.h"
 #include "JSONExpr.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/raw_ostream.h"
 
 namespace clang {
 namespace clangd {
 namespace trace {
 
-// A session directs the output of trace events. Only one Session can exist.
-// It should be created before clangd threads are spawned, and destroyed after
-// they exit.
-// TODO: we may want to add pluggable support for other tracing backends.
+/// A consumer of trace events. The events are produced by Spans and trace::log.
+class EventTracer {
+public:
+  virtual ~EventTracer() = default;
+  /// Consume a trace event.
+  virtual void event(const Context , llvm::StringRef Phase,
+ json::obj &) = 0;
+};
+
+/// Sets up a global EventTracer that consumes events produced by Span and
+/// trace::log. Only one TracingSession can be active at a time and it should be
+/// set up before calling any clangd-specific functions.
 class Session {
 public:
-  // Starts a sessions capturing trace events and writing Trace Event JSON.
-  static std::unique_ptr create(llvm::raw_ostream ,
- bool Pretty = false);
+  Session(EventTracer );
   ~Session();
-
-private:
-  Session() = default;
 };
 
-// Records a single instant event, associated with the current thread.
-void log(const llvm::Twine );
-
-// Records an event whose duration is the lifetime of the Span object.
-//
-// Arbitrary JSON metadata can be attached while this span is active:
-//   SPAN_ATTACH(MySpan, "Payload", SomeJSONExpr);
-// SomeJSONExpr is evaluated and copied only if actually needed.
+/// Create an instance of EventTracer that produces an output in the Trace Event
+/// format supported by Chrome's trace viewer (chrome://tracing).
+///
+/// The format is documented here:
+/// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
+///
+/// The implementation supports concurrent calls and can be used as a global
+/// tracer (i.e., can be put into a global Context).
+std::unique_ptr createJSONTracer(llvm::raw_ostream ,
+  bool Pretty = false);
+
+/// Records a single instant event, associated with the current thread.
+void log(const Context , const llvm::Twine );
+
+/// Records an event whose duration is the lifetime of the Span object.
+/// This is the main public interface for producing tracing events.
+///
+/// Arbitrary JSON metadata can be attached while this span is active:
+///   SPAN_ATTACH(MySpan, "Payload", SomeJSONExpr);
+/// SomeJSONExpr is evaluated and copied only if actually needed.
 class Span {
 public:
-  Span(std::string Name);
+  Span(const Context , std::string Name);
   ~Span();
 
-  // Returns mutable span metadata if this span is interested.
-  // Prefer to use SPAN_ATTACH rather than accessing this directly.
+  /// Returns mutable span metadata if this span is interested.
+  /// Prefer to use SPAN_ATTACH rather than accessing this directly.
   json::obj *args() { return Args.get(); }
 
 private:
+  llvm::Optional Ctx;
   std::unique_ptr Args;
 };
 
Index: clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp
===
--- clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp
+++ clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp
@@ -115,19 +115,25 @@
<< EC.message();
 }
   }
+
+  // Setup tracing facilities.
   llvm::Optional TraceStream;
-  std::unique_ptr TraceSession;
+  

[PATCH] D40488: [clangd] Implemented tracing using Context

2017-12-14 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov updated this revision to Diff 126951.
ilya-biryukov added a comment.

- Renamed TracingSession to Session (it is always used qualified via 
trace::Session anyway)


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D40488

Files:
  clangd/ClangdUnit.cpp
  clangd/JSONRPCDispatcher.cpp
  clangd/Trace.cpp
  clangd/Trace.h
  clangd/tool/ClangdMain.cpp
  unittests/clangd/TraceTests.cpp

Index: unittests/clangd/TraceTests.cpp
===
--- unittests/clangd/TraceTests.cpp
+++ unittests/clangd/TraceTests.cpp
@@ -7,6 +7,7 @@
 //
 //===--===//
 
+#include "Context.h"
 #include "Trace.h"
 
 #include "llvm/ADT/DenseMap.h"
@@ -74,10 +75,11 @@
   std::string JSON;
   {
 raw_string_ostream OS(JSON);
-auto Session = trace::Session::create(OS);
+auto JSONTracer = trace::createJSONTracer(OS);
+trace::Session Session(*JSONTracer);
 {
-  trace::Span S("A");
-  trace::log("B");
+  trace::Span S(Context::empty(), "A");
+  trace::log(Context::empty(), "B");
 }
   }
 
Index: clangd/tool/ClangdMain.cpp
===
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -115,19 +115,25 @@
<< EC.message();
 }
   }
+
+  // Setup tracing facilities.
   llvm::Optional TraceStream;
-  std::unique_ptr TraceSession;
+  std::unique_ptr Tracer;
   if (!TraceFile.empty()) {
 std::error_code EC;
 TraceStream.emplace(TraceFile, /*ref*/ EC, llvm::sys::fs::F_RW);
 if (EC) {
   TraceFile.reset();
   llvm::errs() << "Error while opening trace file: " << EC.message();
 } else {
-  TraceSession = trace::Session::create(*TraceStream, PrettyPrint);
+  Tracer = trace::createJSONTracer(*TraceStream, PrettyPrint);
 }
   }
 
+  llvm::Optional TracingSession;
+  if (Tracer)
+TracingSession.emplace(*Tracer);
+
   llvm::raw_ostream  = llvm::outs();
   llvm::raw_ostream  = llvm::errs();
   JSONOutput Out(Outs, Logs,
Index: clangd/Trace.h
===
--- clangd/Trace.h
+++ clangd/Trace.h
@@ -8,60 +8,74 @@
 //===--===//
 //
 // Supports writing performance traces describing clangd's behavior.
-// Traces are written in the Trace Event format supported by chrome's trace
-// viewer (chrome://tracing).
+// Traces are consumed by implementations of the EventTracer interface.
 //
-// The format is documented here:
-// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
 //
 // All APIs are no-ops unless a Session is active (created by ClangdMain).
 //
 //===--===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
 
+#include "Context.h"
 #include "JSONExpr.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/raw_ostream.h"
 
 namespace clang {
 namespace clangd {
 namespace trace {
 
-// A session directs the output of trace events. Only one Session can exist.
-// It should be created before clangd threads are spawned, and destroyed after
-// they exit.
-// TODO: we may want to add pluggable support for other tracing backends.
+/// A consumer of trace events. The events are produced by Spans and trace::log.
+class EventTracer {
+public:
+  virtual ~EventTracer() = default;
+  /// Consume a trace event.
+  virtual void event(const Context , llvm::StringRef Phase,
+ json::obj &) = 0;
+};
+
+/// Sets up a global EventTracer that consumes events produced by Span and
+/// trace::log. Only one TracingSession can be active at a time and it should be
+/// set up before calling any clangd-specific functions.
 class Session {
 public:
-  // Starts a sessions capturing trace events and writing Trace Event JSON.
-  static std::unique_ptr create(llvm::raw_ostream ,
- bool Pretty = false);
+  Session(EventTracer );
   ~Session();
-
-private:
-  Session() = default;
 };
 
-// Records a single instant event, associated with the current thread.
-void log(const llvm::Twine );
+/// Create an instance of EventTracer that produces an output in the Trace Event
+/// format supported by Chrome's trace viewer (chrome://tracing).
+///
+/// The format is documented here:
+/// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
+///
+/// The implementation supports concurrent calls and can be used as a global
+/// tracer (i.e., can be put into a global Context).
+std::unique_ptr createJSONTracer(llvm::raw_ostream ,
+  bool Pretty = false);
 
-// Records an event whose duration is the lifetime of the Span object.
-//
-// Arbitrary JSON metadata can be attached while 

[PATCH] D40488: [clangd] Implemented tracing using Context

2017-12-14 Thread Sam McCall via Phabricator via cfe-commits
sammccall accepted this revision.
sammccall added inline comments.
This revision is now accepted and ready to land.



Comment at: clangd/Trace.cpp:123
+  // Clone the context, so that the original Context can be moved.
+  this->Ctx.emplace(Ctx.clone());
+

This is a little unfortunate. Oh, well.



Comment at: clangd/Trace.h:42
+/// set up before calling any clangd-specific functions.
+class TracingSession {
+public:

hmm, `trace::TracingSession` seems redundant? Up to you


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D40488



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


[PATCH] D40488: [clangd] Implemented tracing using Context

2017-12-13 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov updated this revision to Diff 126748.
ilya-biryukov added a comment.

Merged with head


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D40488

Files:
  clangd/ClangdUnit.cpp
  clangd/JSONRPCDispatcher.cpp
  clangd/Trace.cpp
  clangd/Trace.h
  clangd/tool/ClangdMain.cpp
  unittests/clangd/TraceTests.cpp

Index: unittests/clangd/TraceTests.cpp
===
--- unittests/clangd/TraceTests.cpp
+++ unittests/clangd/TraceTests.cpp
@@ -7,6 +7,7 @@
 //
 //===--===//
 
+#include "Context.h"
 #include "Trace.h"
 
 #include "llvm/ADT/DenseMap.h"
@@ -74,10 +75,11 @@
   std::string JSON;
   {
 raw_string_ostream OS(JSON);
-auto Session = trace::Session::create(OS);
+auto JSONTracer = trace::createJSONTracer(OS);
+trace::TracingSession Session(*JSONTracer);
 {
-  trace::Span S("A");
-  trace::log("B");
+  trace::Span S(Context::empty(), "A");
+  trace::log(Context::empty(), "B");
 }
   }
 
Index: clangd/tool/ClangdMain.cpp
===
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -115,19 +115,25 @@
<< EC.message();
 }
   }
+
+  // Setup tracing facilities.
   llvm::Optional TraceStream;
-  std::unique_ptr TraceSession;
+  std::unique_ptr Tracer;
   if (!TraceFile.empty()) {
 std::error_code EC;
 TraceStream.emplace(TraceFile, /*ref*/ EC, llvm::sys::fs::F_RW);
 if (EC) {
   TraceFile.reset();
   llvm::errs() << "Error while opening trace file: " << EC.message();
 } else {
-  TraceSession = trace::Session::create(*TraceStream, PrettyPrint);
+  Tracer = trace::createJSONTracer(*TraceStream, PrettyPrint);
 }
   }
 
+  llvm::Optional TracingSession;
+  if (Tracer)
+TracingSession.emplace(*Tracer);
+
   llvm::raw_ostream  = llvm::outs();
   llvm::raw_ostream  = llvm::errs();
   JSONOutput Out(Outs, Logs,
Index: clangd/Trace.h
===
--- clangd/Trace.h
+++ clangd/Trace.h
@@ -8,60 +8,74 @@
 //===--===//
 //
 // Supports writing performance traces describing clangd's behavior.
-// Traces are written in the Trace Event format supported by chrome's trace
-// viewer (chrome://tracing).
+// Traces are consumed by implementations of the EventTracer interface.
 //
-// The format is documented here:
-// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
 //
 // All APIs are no-ops unless a Session is active (created by ClangdMain).
 //
 //===--===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
 
+#include "Context.h"
 #include "JSONExpr.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/raw_ostream.h"
 
 namespace clang {
 namespace clangd {
 namespace trace {
 
-// A session directs the output of trace events. Only one Session can exist.
-// It should be created before clangd threads are spawned, and destroyed after
-// they exit.
-// TODO: we may want to add pluggable support for other tracing backends.
-class Session {
+/// A consumer of trace events. The events are produced by Spans and trace::log.
+class EventTracer {
 public:
-  // Starts a sessions capturing trace events and writing Trace Event JSON.
-  static std::unique_ptr create(llvm::raw_ostream ,
- bool Pretty = false);
-  ~Session();
+  virtual ~EventTracer() = default;
+  /// Consume a trace event.
+  virtual void event(const Context , llvm::StringRef Phase,
+ json::obj &) = 0;
+};
 
-private:
-  Session() = default;
+/// Sets up a global EventTracer that consumes events produced by Span and
+/// trace::log. Only one TracingSession can be active at a time and it should be
+/// set up before calling any clangd-specific functions.
+class TracingSession {
+public:
+  TracingSession(EventTracer );
+  ~TracingSession();
 };
 
-// Records a single instant event, associated with the current thread.
-void log(const llvm::Twine );
+/// Create an instance of EventTracer that produces an output in the Trace Event
+/// format supported by Chrome's trace viewer (chrome://tracing).
+///
+/// The format is documented here:
+/// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
+///
+/// The implementation supports concurrent calls and can be used as a global
+/// tracer (i.e., can be put into a global Context).
+std::unique_ptr createJSONTracer(llvm::raw_ostream ,
+  bool Pretty = false);
 
-// Records an event whose duration is the lifetime of the Span object.
-//
-// Arbitrary JSON metadata can be attached while this span is 

[PATCH] D40488: [clangd] Implemented tracing using Context

2017-12-11 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov updated this revision to Diff 126376.
ilya-biryukov added a comment.

- Use derive(key, value) instead of derive().add(key, value).


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D40488

Files:
  clangd/ClangdUnit.cpp
  clangd/JSONRPCDispatcher.cpp
  clangd/Trace.cpp
  clangd/Trace.h
  clangd/tool/ClangdMain.cpp
  unittests/clangd/TraceTests.cpp

Index: unittests/clangd/TraceTests.cpp
===
--- unittests/clangd/TraceTests.cpp
+++ unittests/clangd/TraceTests.cpp
@@ -7,6 +7,7 @@
 //
 //===--===//
 
+#include "Context.h"
 #include "Trace.h"
 
 #include "llvm/ADT/DenseMap.h"
@@ -74,10 +75,11 @@
   std::string JSON;
   {
 raw_string_ostream OS(JSON);
-auto Session = trace::Session::create(OS);
+auto JSONTracer = trace::createJSONTracer(OS);
+trace::TracingSession Session(*JSONTracer);
 {
-  trace::Span S("A");
-  trace::log("B");
+  trace::Span S(Context::empty(), "A");
+  trace::log(Context::empty(), "B");
 }
   }
 
Index: clangd/tool/ClangdMain.cpp
===
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -115,19 +115,25 @@
<< EC.message();
 }
   }
+
+  // Setup tracing facilities.
   llvm::Optional TraceStream;
-  std::unique_ptr TraceSession;
+  std::unique_ptr Tracer;
   if (!TraceFile.empty()) {
 std::error_code EC;
 TraceStream.emplace(TraceFile, /*ref*/ EC, llvm::sys::fs::F_RW);
 if (EC) {
   TraceFile.reset();
   llvm::errs() << "Error while opening trace file: " << EC.message();
 } else {
-  TraceSession = trace::Session::create(*TraceStream, PrettyPrint);
+  Tracer = trace::createJSONTracer(*TraceStream, PrettyPrint);
 }
   }
 
+  llvm::Optional TracingSession;
+  if (Tracer)
+TracingSession.emplace(*Tracer);
+
   llvm::raw_ostream  = llvm::outs();
   llvm::raw_ostream  = llvm::errs();
   JSONOutput Out(Outs, Logs,
Index: clangd/Trace.h
===
--- clangd/Trace.h
+++ clangd/Trace.h
@@ -8,60 +8,74 @@
 //===--===//
 //
 // Supports writing performance traces describing clangd's behavior.
-// Traces are written in the Trace Event format supported by chrome's trace
-// viewer (chrome://tracing).
+// Traces are consumed by implementations of the EventTracer interface.
 //
-// The format is documented here:
-// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
 //
 // All APIs are no-ops unless a Session is active (created by ClangdMain).
 //
 //===--===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
 
+#include "Context.h"
 #include "JSONExpr.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/raw_ostream.h"
 
 namespace clang {
 namespace clangd {
 namespace trace {
 
-// A session directs the output of trace events. Only one Session can exist.
-// It should be created before clangd threads are spawned, and destroyed after
-// they exit.
-// TODO: we may want to add pluggable support for other tracing backends.
-class Session {
+/// A consumer of trace events. The events are produced by Spans and trace::log.
+class EventTracer {
 public:
-  // Starts a sessions capturing trace events and writing Trace Event JSON.
-  static std::unique_ptr create(llvm::raw_ostream ,
- bool Pretty = false);
-  ~Session();
+  virtual ~EventTracer() = default;
+  /// Consume a trace event.
+  virtual void event(const Context , llvm::StringRef Phase,
+ json::obj &) = 0;
+};
 
-private:
-  Session() = default;
+/// Sets up a global EventTracer that consumes events produced by Span and
+/// trace::log. Only one TracingSession can be active at a time and it should be
+/// set up before calling any clangd-specific functions.
+class TracingSession {
+public:
+  TracingSession(EventTracer );
+  ~TracingSession();
 };
 
-// Records a single instant event, associated with the current thread.
-void log(const llvm::Twine );
+/// Create an instance of EventTracer that produces an output in the Trace Event
+/// format supported by Chrome's trace viewer (chrome://tracing).
+///
+/// The format is documented here:
+/// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
+///
+/// The implementation supports concurrent calls and can be used as a global
+/// tracer (i.e., can be put into a global Context).
+std::unique_ptr createJSONTracer(llvm::raw_ostream ,
+  bool Pretty = false);
 
-// Records an event whose duration is the lifetime of the Span object.
-//
-// Arbitrary JSON 

[PATCH] D40488: [clangd] Implemented tracing using Context

2017-12-11 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov updated this revision to Diff 126328.
ilya-biryukov added a comment.

Updated the patch after changes to Context


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D40488

Files:
  clangd/ClangdUnit.cpp
  clangd/JSONRPCDispatcher.cpp
  clangd/Trace.cpp
  clangd/Trace.h
  clangd/tool/ClangdMain.cpp
  unittests/clangd/TraceTests.cpp

Index: unittests/clangd/TraceTests.cpp
===
--- unittests/clangd/TraceTests.cpp
+++ unittests/clangd/TraceTests.cpp
@@ -7,6 +7,7 @@
 //
 //===--===//
 
+#include "Context.h"
 #include "Trace.h"
 
 #include "llvm/ADT/DenseMap.h"
@@ -74,10 +75,11 @@
   std::string JSON;
   {
 raw_string_ostream OS(JSON);
-auto Session = trace::Session::create(OS);
+auto JSONTracer = trace::createJSONTracer(OS);
+trace::TracingSession Session(*JSONTracer);
 {
-  trace::Span S("A");
-  trace::log("B");
+  trace::Span S(Context::empty(), "A");
+  trace::log(Context::empty(), "B");
 }
   }
 
Index: clangd/tool/ClangdMain.cpp
===
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -115,19 +115,25 @@
<< EC.message();
 }
   }
+
+  // Setup tracing facilities.
   llvm::Optional TraceStream;
-  std::unique_ptr TraceSession;
+  std::unique_ptr Tracer;
   if (!TraceFile.empty()) {
 std::error_code EC;
 TraceStream.emplace(TraceFile, /*ref*/ EC, llvm::sys::fs::F_RW);
 if (EC) {
   TraceFile.reset();
   llvm::errs() << "Error while opening trace file: " << EC.message();
 } else {
-  TraceSession = trace::Session::create(*TraceStream, PrettyPrint);
+  Tracer = trace::createJSONTracer(*TraceStream, PrettyPrint);
 }
   }
 
+  llvm::Optional TracingSession;
+  if (Tracer)
+TracingSession.emplace(*Tracer);
+
   llvm::raw_ostream  = llvm::outs();
   llvm::raw_ostream  = llvm::errs();
   JSONOutput Out(Outs, Logs,
Index: clangd/Trace.h
===
--- clangd/Trace.h
+++ clangd/Trace.h
@@ -8,60 +8,74 @@
 //===--===//
 //
 // Supports writing performance traces describing clangd's behavior.
-// Traces are written in the Trace Event format supported by chrome's trace
-// viewer (chrome://tracing).
+// Traces are consumed by implementations of the EventTracer interface.
 //
-// The format is documented here:
-// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
 //
 // All APIs are no-ops unless a Session is active (created by ClangdMain).
 //
 //===--===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
 
+#include "Context.h"
 #include "JSONExpr.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/raw_ostream.h"
 
 namespace clang {
 namespace clangd {
 namespace trace {
 
-// A session directs the output of trace events. Only one Session can exist.
-// It should be created before clangd threads are spawned, and destroyed after
-// they exit.
-// TODO: we may want to add pluggable support for other tracing backends.
-class Session {
+/// A consumer of trace events. The events are produced by Spans and trace::log.
+class EventTracer {
 public:
-  // Starts a sessions capturing trace events and writing Trace Event JSON.
-  static std::unique_ptr create(llvm::raw_ostream ,
- bool Pretty = false);
-  ~Session();
+  virtual ~EventTracer() = default;
+  /// Consume a trace event.
+  virtual void event(const Context , llvm::StringRef Phase,
+ json::obj &) = 0;
+};
 
-private:
-  Session() = default;
+/// Sets up a global EventTracer that consumes events produced by Span and
+/// trace::log. Only one TracingSession can be active at a time and it should be
+/// set up before calling any clangd-specific functions.
+class TracingSession {
+public:
+  TracingSession(EventTracer );
+  ~TracingSession();
 };
 
-// Records a single instant event, associated with the current thread.
-void log(const llvm::Twine );
+/// Create an instance of EventTracer that produces an output in the Trace Event
+/// format supported by Chrome's trace viewer (chrome://tracing).
+///
+/// The format is documented here:
+/// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
+///
+/// The implementation supports concurrent calls and can be used as a global
+/// tracer (i.e., can be put into a global Context).
+std::unique_ptr createJSONTracer(llvm::raw_ostream ,
+  bool Pretty = false);
 
-// Records an event whose duration is the lifetime of the Span object.
-//
-// Arbitrary JSON metadata can be 

[PATCH] D40488: [clangd] Implemented tracing using Context

2017-12-06 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov updated this revision to Diff 125713.
ilya-biryukov added a comment.

- Use getExistingKey instead of getPtr in JSONRPCDispatcher.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D40488

Files:
  clangd/ClangdUnit.cpp
  clangd/JSONRPCDispatcher.cpp
  clangd/Trace.cpp
  clangd/Trace.h
  clangd/tool/ClangdMain.cpp
  unittests/clangd/TraceTests.cpp

Index: unittests/clangd/TraceTests.cpp
===
--- unittests/clangd/TraceTests.cpp
+++ unittests/clangd/TraceTests.cpp
@@ -7,6 +7,7 @@
 //
 //===--===//
 
+#include "Context.h"
 #include "Trace.h"
 
 #include "llvm/ADT/DenseMap.h"
@@ -74,10 +75,11 @@
   std::string JSON;
   {
 raw_string_ostream OS(JSON);
-auto Session = trace::Session::create(OS);
+auto JSONTracer = trace::createJSONTracer(OS);
+trace::TracingSession Session(*JSONTracer);
 {
-  trace::Span S("A");
-  trace::log("B");
+  trace::Span S(emptyCtx(), "A");
+  trace::log(emptyCtx(), "B");
 }
   }
 
Index: clangd/tool/ClangdMain.cpp
===
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -115,19 +115,25 @@
<< EC.message();
 }
   }
+
+  // Setup tracing facilities.
   llvm::Optional TraceStream;
-  std::unique_ptr TraceSession;
+  std::unique_ptr Tracer;
   if (!TraceFile.empty()) {
 std::error_code EC;
 TraceStream.emplace(TraceFile, /*ref*/ EC, llvm::sys::fs::F_RW);
 if (EC) {
   TraceFile.reset();
   llvm::errs() << "Error while opening trace file: " << EC.message();
 } else {
-  TraceSession = trace::Session::create(*TraceStream, PrettyPrint);
+  Tracer = trace::createJSONTracer(*TraceStream, PrettyPrint);
 }
   }
 
+  llvm::Optional TracingSession;
+  if (Tracer)
+TracingSession.emplace(*Tracer);
+
   llvm::raw_ostream  = llvm::outs();
   llvm::raw_ostream  = llvm::errs();
   JSONOutput Out(Outs, Logs,
Index: clangd/Trace.h
===
--- clangd/Trace.h
+++ clangd/Trace.h
@@ -8,60 +8,74 @@
 //===--===//
 //
 // Supports writing performance traces describing clangd's behavior.
-// Traces are written in the Trace Event format supported by chrome's trace
-// viewer (chrome://tracing).
+// Traces are consumed by implementations of the EventTracer interface.
 //
-// The format is documented here:
-// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
 //
 // All APIs are no-ops unless a Session is active (created by ClangdMain).
 //
 //===--===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
 
+#include "Context.h"
 #include "JSONExpr.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/raw_ostream.h"
 
 namespace clang {
 namespace clangd {
 namespace trace {
 
-// A session directs the output of trace events. Only one Session can exist.
-// It should be created before clangd threads are spawned, and destroyed after
-// they exit.
-// TODO: we may want to add pluggable support for other tracing backends.
-class Session {
+/// A consumer of trace events. The events are produced by Spans and trace::log.
+class EventTracer {
 public:
-  // Starts a sessions capturing trace events and writing Trace Event JSON.
-  static std::unique_ptr create(llvm::raw_ostream ,
- bool Pretty = false);
-  ~Session();
+  virtual ~EventTracer() = default;
+  /// Consume a trace event.
+  virtual void event(const ContextData , llvm::StringRef Phase,
+ json::obj &) = 0;
+};
 
-private:
-  Session() = default;
+/// Sets up a global EventTracer that consumes events produced by Span and
+/// trace::log. Only one TracingSession can be active at a time and it should be
+/// set up before calling any clangd-specific functions.
+class TracingSession {
+public:
+  TracingSession(EventTracer );
+  ~TracingSession();
 };
 
-// Records a single instant event, associated with the current thread.
-void log(const llvm::Twine );
+/// Create an instance of EventTracer that produces an output in the Trace Event
+/// format supported by Chrome's trace viewer (chrome://tracing).
+///
+/// The format is documented here:
+/// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
+///
+/// The implementation supports concurrent calls and can be used as a global
+/// tracer (i.e., can be put into a global Context).
+std::unique_ptr createJSONTracer(llvm::raw_ostream ,
+  bool Pretty = false);
 
-// Records an event whose duration is the lifetime of the Span object.
-//
-// Arbitrary JSON metadata can 

[PATCH] D40488: [clangd] Implemented tracing using Context

2017-12-06 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov updated this revision to Diff 125690.
ilya-biryukov added a comment.
Herald added a subscriber: klimek.

- Updated tracing to use the new Context implementation.
- Restored global tracer.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D40488

Files:
  clangd/ClangdUnit.cpp
  clangd/JSONRPCDispatcher.cpp
  clangd/Trace.cpp
  clangd/Trace.h
  clangd/tool/ClangdMain.cpp
  unittests/clangd/TraceTests.cpp

Index: unittests/clangd/TraceTests.cpp
===
--- unittests/clangd/TraceTests.cpp
+++ unittests/clangd/TraceTests.cpp
@@ -7,6 +7,7 @@
 //
 //===--===//
 
+#include "Context.h"
 #include "Trace.h"
 
 #include "llvm/ADT/DenseMap.h"
@@ -74,10 +75,11 @@
   std::string JSON;
   {
 raw_string_ostream OS(JSON);
-auto Session = trace::Session::create(OS);
+auto JSONTracer = trace::createJSONTracer(OS);
+trace::TracingSession Session(*JSONTracer);
 {
-  trace::Span S("A");
-  trace::log("B");
+  trace::Span S(emptyCtx(), "A");
+  trace::log(emptyCtx(), "B");
 }
   }
 
Index: clangd/tool/ClangdMain.cpp
===
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -115,19 +115,25 @@
<< EC.message();
 }
   }
+
+  // Setup tracing facilities.
   llvm::Optional TraceStream;
-  std::unique_ptr TraceSession;
+  std::unique_ptr Tracer;
   if (!TraceFile.empty()) {
 std::error_code EC;
 TraceStream.emplace(TraceFile, /*ref*/ EC, llvm::sys::fs::F_RW);
 if (EC) {
   TraceFile.reset();
   llvm::errs() << "Error while opening trace file: " << EC.message();
 } else {
-  TraceSession = trace::Session::create(*TraceStream, PrettyPrint);
+  Tracer = trace::createJSONTracer(*TraceStream, PrettyPrint);
 }
   }
 
+  llvm::Optional TracingSession;
+  if (Tracer)
+TracingSession.emplace(*Tracer);
+
   llvm::raw_ostream  = llvm::outs();
   llvm::raw_ostream  = llvm::errs();
   JSONOutput Out(Outs, Logs,
Index: clangd/Trace.h
===
--- clangd/Trace.h
+++ clangd/Trace.h
@@ -8,60 +8,74 @@
 //===--===//
 //
 // Supports writing performance traces describing clangd's behavior.
-// Traces are written in the Trace Event format supported by chrome's trace
-// viewer (chrome://tracing).
+// Traces are consumed by implementations of the EventTracer interface.
 //
-// The format is documented here:
-// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
 //
 // All APIs are no-ops unless a Session is active (created by ClangdMain).
 //
 //===--===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
 
+#include "Context.h"
 #include "JSONExpr.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/raw_ostream.h"
 
 namespace clang {
 namespace clangd {
 namespace trace {
 
-// A session directs the output of trace events. Only one Session can exist.
-// It should be created before clangd threads are spawned, and destroyed after
-// they exit.
-// TODO: we may want to add pluggable support for other tracing backends.
-class Session {
+/// A consumer of trace events. The events are produced by Spans and trace::log.
+class EventTracer {
 public:
-  // Starts a sessions capturing trace events and writing Trace Event JSON.
-  static std::unique_ptr create(llvm::raw_ostream ,
- bool Pretty = false);
-  ~Session();
+  virtual ~EventTracer() = default;
+  /// Consume a trace event.
+  virtual void event(const ContextData , llvm::StringRef Phase,
+ json::obj &) = 0;
+};
 
-private:
-  Session() = default;
+/// Sets up a global EventTracer that consumes events produced by Span and
+/// trace::log. Only one TracingSession can be active at a time and it should be
+/// set up before calling any clangd-specific functions.
+class TracingSession {
+public:
+  TracingSession(EventTracer );
+  ~TracingSession();
 };
 
-// Records a single instant event, associated with the current thread.
-void log(const llvm::Twine );
+/// Create an instance of EventTracer that produces an output in the Trace Event
+/// format supported by Chrome's trace viewer (chrome://tracing).
+///
+/// The format is documented here:
+/// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
+///
+/// The implementation supports concurrent calls and can be used as a global
+/// tracer (i.e., can be put into a global Context).
+std::unique_ptr createJSONTracer(llvm::raw_ostream ,
+  bool Pretty = false);
 
-// Records an event whose duration is the lifetime 

[PATCH] D40488: [clangd] Implemented tracing using Context

2017-11-27 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov planned changes to this revision.
ilya-biryukov added inline comments.



Comment at: clangd/JSONRPCDispatcher.h:80
+  // Ctx must be before Tracer!
   Context Ctx;
   JSONOutput 

This is still wrong, `Context` is used by `Tracer` internally and should not be 
moved.


https://reviews.llvm.org/D40488



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


[PATCH] D40488: [clangd] Implemented tracing using Context

2017-11-27 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov created this revision.

https://reviews.llvm.org/D40488

Files:
  clangd/ClangdUnit.cpp
  clangd/JSONRPCDispatcher.cpp
  clangd/JSONRPCDispatcher.h
  clangd/ProtocolHandlers.cpp
  clangd/Trace.cpp
  clangd/Trace.h
  clangd/tool/ClangdMain.cpp
  unittests/clangd/TraceTests.cpp

Index: unittests/clangd/TraceTests.cpp
===
--- unittests/clangd/TraceTests.cpp
+++ unittests/clangd/TraceTests.cpp
@@ -7,6 +7,7 @@
 //
 //===--===//
 
+#include "Context.h"
 #include "Trace.h"
 
 #include "llvm/ADT/DenseMap.h"
@@ -74,10 +75,12 @@
   std::string JSON;
   {
 raw_string_ostream OS(JSON);
-auto Session = trace::Session::create(OS);
+auto JSONTracer = trace::createJSONTracer(OS);
+Context TraceCtx =
+buildCtx().add(trace::EventTracer::CtxKey, JSONTracer.get());
 {
-  trace::Span S("A");
-  trace::log("B");
+  trace::Span S(TraceCtx, "A");
+  trace::log(TraceCtx, "B");
 }
   }
 
Index: clangd/tool/ClangdMain.cpp
===
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -116,15 +116,15 @@
 }
   }
   llvm::Optional TraceStream;
-  std::unique_ptr TraceSession;
+  std::unique_ptr TraceSession;
   if (!TraceFile.empty()) {
 std::error_code EC;
 TraceStream.emplace(TraceFile, /*ref*/ EC, llvm::sys::fs::F_RW);
 if (EC) {
   TraceFile.reset();
   llvm::errs() << "Error while opening trace file: " << EC.message();
 } else {
-  TraceSession = trace::Session::create(*TraceStream, PrettyPrint);
+  TraceSession = trace::createJSONTracer(*TraceStream, PrettyPrint);
 }
   }
 
@@ -134,7 +134,11 @@
  InputMirrorStream ? InputMirrorStream.getPointer() : nullptr,
  PrettyPrint);
 
-  GlobalSession Session(buildCtx().add(Logger::CtxKey, ));
+  TypedValueMap ContextMap;
+  ContextMap.emplace(Logger::CtxKey, );
+  if (TraceSession)
+ContextMap.emplace(trace::EventTracer::CtxKey, TraceSession.get());
+  GlobalSession Session(Context(/*Parent=*/nullptr, std::move(ContextMap)));
 
   // If --compile-commands-dir arg was invoked, check value and override default
   // path.
Index: clangd/Trace.h
===
--- clangd/Trace.h
+++ clangd/Trace.h
@@ -8,60 +8,64 @@
 //===--===//
 //
 // Supports writing performance traces describing clangd's behavior.
-// Traces are written in the Trace Event format supported by chrome's trace
-// viewer (chrome://tracing).
+// Traces are consumed by implementations of the EventTracer interface.
 //
-// The format is documented here:
-// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
 //
 // All APIs are no-ops unless a Session is active (created by ClangdMain).
 //
 //===--===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
 
+#include "Context.h"
 #include "JSONExpr.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/raw_ostream.h"
 
 namespace clang {
 namespace clangd {
 namespace trace {
 
-// A session directs the output of trace events. Only one Session can exist.
-// It should be created before clangd threads are spawned, and destroyed after
-// they exit.
-// TODO: we may want to add pluggable support for other tracing backends.
-class Session {
+class EventTracer {
 public:
-  // Starts a sessions capturing trace events and writing Trace Event JSON.
-  static std::unique_ptr create(llvm::raw_ostream ,
- bool Pretty = false);
-  ~Session();
+  static PtrKey CtxKey;
 
-private:
-  Session() = default;
+  virtual ~EventTracer() = default;
+  virtual void event(llvm::StringRef Phase, json::obj &) = 0;
 };
 
-// Records a single instant event, associated with the current thread.
-void log(const llvm::Twine );
+/// Create an instance of EventTracer that produces an output in the Trace Event
+/// format supported by Chrome's trace viewer (chrome://tracing).
+///
+/// The format is documented here:
+/// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
+///
+/// The implementation supports concurrent calls and can be used as a global
+/// tracer (i.e., can be put into a global Context).
+std::unique_ptr createJSONTracer(llvm::raw_ostream ,
+  bool Pretty = false);
 
-// Records an event whose duration is the lifetime of the Span object.
-//
-// Arbitrary JSON metadata can be attached while this span is active:
-//   SPAN_ATTACH(MySpan, "Payload", SomeJSONExpr);
-// SomeJSONExpr is evaluated and copied only if actually needed.
+/// Records a single instant event, associated