aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm12/include/llvm/Support/Registry.h
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /contrib/libs/llvm12/include/llvm/Support/Registry.h
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'contrib/libs/llvm12/include/llvm/Support/Registry.h')
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/Registry.h170
1 files changed, 170 insertions, 0 deletions
diff --git a/contrib/libs/llvm12/include/llvm/Support/Registry.h b/contrib/libs/llvm12/include/llvm/Support/Registry.h
new file mode 100644
index 0000000000..720f352856
--- /dev/null
+++ b/contrib/libs/llvm12/include/llvm/Support/Registry.h
@@ -0,0 +1,170 @@
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//=== Registry.h - Linker-supported plugin registries -----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines a registry template for discovering pluggable modules.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_REGISTRY_H
+#define LLVM_SUPPORT_REGISTRY_H
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include <memory>
+
+namespace llvm {
+ /// A simple registry entry which provides only a name, description, and
+ /// no-argument constructor.
+ template <typename T>
+ class SimpleRegistryEntry {
+ StringRef Name, Desc;
+ std::unique_ptr<T> (*Ctor)();
+
+ public:
+ SimpleRegistryEntry(StringRef N, StringRef D, std::unique_ptr<T> (*C)())
+ : Name(N), Desc(D), Ctor(C) {}
+
+ StringRef getName() const { return Name; }
+ StringRef getDesc() const { return Desc; }
+ std::unique_ptr<T> instantiate() const { return Ctor(); }
+ };
+
+ /// A global registry used in conjunction with static constructors to make
+ /// pluggable components (like targets or garbage collectors) "just work" when
+ /// linked with an executable.
+ template <typename T>
+ class Registry {
+ public:
+ typedef T type;
+ typedef SimpleRegistryEntry<T> entry;
+
+ class node;
+ class iterator;
+
+ private:
+ Registry() = delete;
+
+ friend class node;
+ static node *Head, *Tail;
+
+ public:
+ /// Node in linked list of entries.
+ ///
+ class node {
+ friend class iterator;
+ friend Registry<T>;
+
+ node *Next;
+ const entry& Val;
+
+ public:
+ node(const entry &V) : Next(nullptr), Val(V) {}
+ };
+
+ /// Add a node to the Registry: this is the interface between the plugin and
+ /// the executable.
+ ///
+ /// This function is exported by the executable and called by the plugin to
+ /// add a node to the executable's registry. Therefore it's not defined here
+ /// to avoid it being instantiated in the plugin and is instead defined in
+ /// the executable (see LLVM_INSTANTIATE_REGISTRY below).
+ static void add_node(node *N);
+
+ /// Iterators for registry entries.
+ ///
+ class iterator
+ : public llvm::iterator_facade_base<iterator, std::forward_iterator_tag,
+ const entry> {
+ const node *Cur;
+
+ public:
+ explicit iterator(const node *N) : Cur(N) {}
+
+ bool operator==(const iterator &That) const { return Cur == That.Cur; }
+ iterator &operator++() { Cur = Cur->Next; return *this; }
+ const entry &operator*() const { return Cur->Val; }
+ };
+
+ // begin is not defined here in order to avoid usage of an undefined static
+ // data member, instead it's instantiated by LLVM_INSTANTIATE_REGISTRY.
+ static iterator begin();
+ static iterator end() { return iterator(nullptr); }
+
+ static iterator_range<iterator> entries() {
+ return make_range(begin(), end());
+ }
+
+ /// A static registration template. Use like such:
+ ///
+ /// Registry<Collector>::Add<FancyGC>
+ /// X("fancy-gc", "Newfangled garbage collector.");
+ ///
+ /// Use of this template requires that:
+ ///
+ /// 1. The registered subclass has a default constructor.
+ template <typename V>
+ class Add {
+ entry Entry;
+ node Node;
+
+ static std::unique_ptr<T> CtorFn() { return std::make_unique<V>(); }
+
+ public:
+ Add(StringRef Name, StringRef Desc)
+ : Entry(Name, Desc, CtorFn), Node(Entry) {
+ add_node(&Node);
+ }
+ };
+ };
+} // end namespace llvm
+
+/// Instantiate a registry class.
+///
+/// This provides template definitions of add_node, begin, and the Head and Tail
+/// pointers, then explicitly instantiates them. We could explicitly specialize
+/// them, instead of the two-step process of define then instantiate, but
+/// strictly speaking that's not allowed by the C++ standard (we would need to
+/// have explicit specialization declarations in all translation units where the
+/// specialization is used) so we don't.
+#define LLVM_INSTANTIATE_REGISTRY(REGISTRY_CLASS) \
+ namespace llvm { \
+ template<typename T> typename Registry<T>::node *Registry<T>::Head = nullptr;\
+ template<typename T> typename Registry<T>::node *Registry<T>::Tail = nullptr;\
+ template<typename T> \
+ void Registry<T>::add_node(typename Registry<T>::node *N) { \
+ if (Tail) \
+ Tail->Next = N; \
+ else \
+ Head = N; \
+ Tail = N; \
+ } \
+ template<typename T> typename Registry<T>::iterator Registry<T>::begin() { \
+ return iterator(Head); \
+ } \
+ template REGISTRY_CLASS::node *Registry<REGISTRY_CLASS::type>::Head; \
+ template REGISTRY_CLASS::node *Registry<REGISTRY_CLASS::type>::Tail; \
+ template \
+ void Registry<REGISTRY_CLASS::type>::add_node(REGISTRY_CLASS::node*); \
+ template REGISTRY_CLASS::iterator Registry<REGISTRY_CLASS::type>::begin(); \
+ }
+
+#endif // LLVM_SUPPORT_REGISTRY_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif