aboutsummaryrefslogtreecommitdiff
path: root/build2/diagnostics.hxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-02-16 16:24:07 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2018-02-16 16:40:45 +0200
commit6293ede7a742866a713050737cc2b43d51161b6f (patch)
treef259845f47c2e03432bdd98b4b665e1a3de85d55 /build2/diagnostics.hxx
parentad9cb7fec5cc74697322620909e0ff1ba9ecb61b (diff)
Add support for detecting dependency cycles
Diffstat (limited to 'build2/diagnostics.hxx')
-rw-r--r--build2/diagnostics.hxx45
1 files changed, 37 insertions, 8 deletions
diff --git a/build2/diagnostics.hxx b/build2/diagnostics.hxx
index 653d9a6..b9757d6 100644
--- a/build2/diagnostics.hxx
+++ b/build2/diagnostics.hxx
@@ -160,13 +160,37 @@ namespace build2
{
explicit
diag_frame (void (*f) (const diag_frame&, const diag_record&))
- : func_ (f), prev_ (stack) {stack = this;}
+ : func_ (f)
+ {
+ if (func_ != nullptr)
+ {
+ prev_ = stack;
+ stack = this;
+ }
+ }
- // Start with an existing stack, for example, from another thread.
- //
- explicit
- diag_frame (const diag_frame* prev)
- : prev_ (stack) {stack = prev;} // Just a restore guard.
+ diag_frame (diag_frame&& x)
+ : func_ (x.func_)
+ {
+ if (func_ != nullptr)
+ {
+ prev_ = x.prev_;
+ stack = this;
+
+ x.func_ = nullptr;
+ }
+ }
+
+ diag_frame& operator= (diag_frame&&) = delete;
+
+ diag_frame (const diag_frame&) = delete;
+ diag_frame& operator= (const diag_frame&) = delete;
+
+ ~diag_frame ()
+ {
+ if (func_ != nullptr )
+ stack = prev_;
+ }
static void
apply (const diag_record& r)
@@ -175,8 +199,6 @@ namespace build2
f->func_ (*f, r);
}
- ~diag_frame () {stack = prev_;}
-
static
#ifdef __cpp_thread_local
thread_local
@@ -185,6 +207,13 @@ namespace build2
#endif
const diag_frame* stack; // Tip of the stack.
+ struct stack_guard
+ {
+ explicit stack_guard (const diag_frame* s): s_ (stack) {stack = s;}
+ ~stack_guard () {stack = s_;}
+ const diag_frame* s_;
+ };
+
private:
void (*func_) (const diag_frame&, const diag_record&);
const diag_frame* prev_;