From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- build/clang-plugin/RecurseGuard.h | 56 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 build/clang-plugin/RecurseGuard.h (limited to 'build/clang-plugin/RecurseGuard.h') diff --git a/build/clang-plugin/RecurseGuard.h b/build/clang-plugin/RecurseGuard.h new file mode 100644 index 0000000000..5daf55a9e8 --- /dev/null +++ b/build/clang-plugin/RecurseGuard.h @@ -0,0 +1,56 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef RecurseGuard_h__ +#define RecurseGuard_h__ + +#include "Utils.h" + +// This class acts as a tracker for avoiding infinite recursion when traversing +// chains in CFGs etc. +// +// Constructing a RecurseGuard sets up a shared backing store which tracks the +// currently observed objects. Whenever recursing, use RecurseGuard.recurse(T) +// to construct another RecurseGuard with the same backing store. +// +// The RecurseGuard object will unregister its object when it is destroyed, and +// has a method `isRepeat()` which will return `true` if the item was already +// seen. +template class RecurseGuard { +public: + RecurseGuard(T Thing) : Thing(Thing), Set(new DenseSet()), Repeat(false) { + Set->insert(Thing); + } + RecurseGuard(T Thing, std::shared_ptr> &Set) + : Thing(Thing), Set(Set), Repeat(false) { + Repeat = !Set->insert(Thing).second; + } + RecurseGuard(const RecurseGuard &) = delete; + RecurseGuard(RecurseGuard &&Other) + : Thing(Other.Thing), Set(Other.Set), Repeat(Other.Repeat) { + Other.Repeat = true; + } + ~RecurseGuard() { + if (!Repeat) { + Set->erase(Thing); + } + } + + bool isRepeat() { return Repeat; } + + T get() { return Thing; } + + operator T() { return Thing; } + + T operator->() { return Thing; } + + RecurseGuard recurse(T NewThing) { return RecurseGuard(NewThing, Set); } + +private: + T Thing; + std::shared_ptr> Set; + bool Repeat; +}; + +#endif // RecurseGuard_h__ -- cgit v1.2.3