//===- Any.h - Generic type erased holder of any type -----------*- 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 // //===----------------------------------------------------------------------===// /// /// \file /// This file provides Any, a non-template class modeled in the spirit of /// std::any. The idea is to provide a type-safe replacement for C's void*. /// It can hold a value of any copy-constructible copy-assignable type /// //===----------------------------------------------------------------------===// #ifndef LLVM_ADT_ANY_H #define LLVM_ADT_ANY_H #include "llvm/ADT/STLForwardCompat.h" #include "llvm/Support/Compiler.h" #include <cassert> #include <memory> #include <type_traits> namespace llvm { class LLVM_EXTERNAL_VISIBILITY Any { … }; // Define the type id and initialize with a non-zero value. // Initializing with a zero value means the variable can end up in either the // .data or the .bss section. This can lead to multiple definition linker errors // when some object files are compiled with a compiler that puts the variable // into .data but they are linked to object files from a different compiler that // put the variable into .bss. To prevent this issue from happening, initialize // the variable with a non-zero value, which forces it to land in .data (because // .bss is zero-initialized). // See also https://github.com/llvm/llvm-project/issues/62270 template <typename T> char Any::TypeId<T>::Id = …; template <class T> T any_cast(const Any &Value) { … } template <class T> T any_cast(Any &Value) { … } template <class T> T any_cast(Any &&Value) { … } template <class T> const T *any_cast(const Any *Value) { … } template <class T> T *any_cast(Any *Value) { … } } // end namespace llvm #endif // LLVM_ADT_ANY_H