Commit 0cf20069 by Nicolas Capens

Add LLVM dependencies for Subzero.

Change-Id: I5ab054a5622c9f9dee099f5a3a30c3bb4079ffeb Reviewed-on: https://swiftshader-review.googlesource.com/7291Tested-by: 's avatarNicolas Capens <capn@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent d4613cb4
==============================================================================
LLVM Release License
==============================================================================
University of Illinois/NCSA
Open Source License
Copyright (c) 2003-2016 University of Illinois at Urbana-Champaign.
All rights reserved.
Developed by:
LLVM Team
University of Illinois at Urbana-Champaign
http://llvm.org
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal with
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimers.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimers in the
documentation and/or other materials provided with the distribution.
* Neither the names of the LLVM Team, University of Illinois at
Urbana-Champaign, nor the names of its contributors may be used to
endorse or promote products derived from this Software without specific
prior written permission.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
SOFTWARE.
==============================================================================
Copyrights and Licenses for Third Party Software Distributed with LLVM:
==============================================================================
The LLVM software contains code written by third parties. Such software will
have its own individual LICENSE.TXT file in the directory in which it appears.
This file will describe the copyrights, license, and restrictions which apply
to that code.
The disclaimer of warranty in the University of Illinois Open Source License
applies to all code in the LLVM Distribution, and nothing in any of the
other licenses gives permission to use the names of the LLVM Team or the
University of Illinois to endorse or promote products derived from this
Software.
The following pieces of software have additional or alternate copyrights,
licenses, and/or restrictions:
Program Directory
------- ---------
Google Test llvm/utils/unittest/googletest
OpenBSD regex llvm/lib/Support/{reg*, COPYRIGHT.regex}
pyyaml tests llvm/test/YAMLParser/{*.data, LICENSE.TXT}
ARM contributions llvm/lib/Target/ARM/LICENSE.TXT
md5 contributions llvm/lib/Support/MD5.cpp llvm/include/llvm/Support/MD5.h
llvm-subzero
============
This directory and its subdirectories contain a subset of the source code for
LLVM, required by Subzero.
The original README.txt content follows:
Low Level Virtual Machine (LLVM)
================================
This directory and its subdirectories contain source code for LLVM,
a toolkit for the construction of highly optimized compilers,
optimizers, and runtime environments.
LLVM is open source software. You may freely distribute it under the terms of
the license agreement found in LICENSE.txt.
Please see the documentation provided in docs/ for further
assistance with LLVM, and in particular docs/GettingStarted.rst for getting
started with LLVM and docs/README.txt for an overview of LLVM's
documentation setup.
If you are writing a package for LLVM, see docs/Packaging.rst for our
suggestions.
/*===-- llvm-c/ErrorHandling.h - Error Handling C Interface -------*- C -*-===*\
|* *|
|* The LLVM Compiler Infrastructure *|
|* *|
|* This file is distributed under the University of Illinois Open Source *|
|* License. See LICENSE.TXT for details. *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
|* This file defines the C interface to LLVM's error handling mechanism. *|
|* *|
\*===----------------------------------------------------------------------===*/
#ifndef LLVM_C_ERROR_HANDLING_H
#define LLVM_C_ERROR_HANDLING_H
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*LLVMFatalErrorHandler)(const char *Reason);
/**
* Install a fatal error handler. By default, if LLVM detects a fatal error, it
* will call exit(1). This may not be appropriate in many contexts. For example,
* doing exit(1) will bypass many crash reporting/tracing system tools. This
* function allows you to install a callback that will be invoked prior to the
* call to exit(1).
*/
void LLVMInstallFatalErrorHandler(LLVMFatalErrorHandler Handler);
/**
* Reset the fatal error handler. This resets LLVM's fatal error handling
* behavior to the default.
*/
void LLVMResetFatalErrorHandler(void);
/**
* Enable LLVM's built-in stack trace code. This intercepts the OS's crash
* signals and prints which component of LLVM you were in at the time if the
* crash.
*/
void LLVMEnablePrettyStackTrace(void);
#ifdef __cplusplus
}
#endif
#endif
/*===-- llvm-c/Support.h - Support C Interface --------------------*- C -*-===*\
|* *|
|* The LLVM Compiler Infrastructure *|
|* *|
|* This file is distributed under the University of Illinois Open Source *|
|* License. See LICENSE.TXT for details. *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
|* This file defines the C interface to the LLVM support library. *|
|* *|
\*===----------------------------------------------------------------------===*/
#ifndef LLVM_C_SUPPORT_H
#define LLVM_C_SUPPORT_H
#include "llvm/Support/DataTypes.h"
#include "llvm-c/Types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* This function permanently loads the dynamic library at the given path.
* It is safe to call this function multiple times for the same library.
*
* @see sys::DynamicLibrary::LoadLibraryPermanently()
*/
LLVMBool LLVMLoadLibraryPermanently(const char* Filename);
/**
* This function parses the given arguments using the LLVM command line parser.
* Note that the only stable thing about this function is its signature; you
* cannot rely on any particular set of command line arguments being interpreted
* the same way across LLVM versions.
*
* @see llvm::cl::ParseCommandLineOptions()
*/
void LLVMParseCommandLineOptions(int argc, const char *const *argv,
const char *Overview);
/**
* This function will search through all previously loaded dynamic
* libraries for the symbol \p symbolName. If it is found, the address of
* that symbol is returned. If not, null is returned.
*
* @see sys::DynamicLibrary::SearchForAddressOfSymbol()
*/
void *LLVMSearchForAddressOfSymbol(const char *symbolName);
/**
* This functions permanently adds the symbol \p symbolName with the
* value \p symbolValue. These symbols are searched before any
* libraries.
*
* @see sys::DynamicLibrary::AddSymbol()
*/
void LLVMAddSymbol(const char *symbolName, void *symbolValue);
#ifdef __cplusplus
}
#endif
#endif
/*===-- llvm-c/Support.h - C Interface Types declarations ---------*- C -*-===*\
|* *|
|* The LLVM Compiler Infrastructure *|
|* *|
|* This file is distributed under the University of Illinois Open Source *|
|* License. See LICENSE.TXT for details. *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
|* This file defines types used by the the C interface to LLVM. *|
|* *|
\*===----------------------------------------------------------------------===*/
#ifndef LLVM_C_TYPES_H
#define LLVM_C_TYPES_H
#include "llvm/Support/DataTypes.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup LLVMCSupportTypes Types and Enumerations
*
* @{
*/
typedef int LLVMBool;
/* Opaque types. */
/**
* LLVM uses a polymorphic type hierarchy which C cannot represent, therefore
* parameters must be passed as base types. Despite the declared types, most
* of the functions provided operate only on branches of the type hierarchy.
* The declared parameter names are descriptive and specify which type is
* required. Additionally, each type hierarchy is documented along with the
* functions that operate upon it. For more detail, refer to LLVM's C++ code.
* If in doubt, refer to Core.cpp, which performs parameter downcasts in the
* form unwrap<RequiredType>(Param).
*/
/**
* Used to pass regions of memory through LLVM interfaces.
*
* @see llvm::MemoryBuffer
*/
typedef struct LLVMOpaqueMemoryBuffer *LLVMMemoryBufferRef;
/**
* The top-level container for all LLVM global data. See the LLVMContext class.
*/
typedef struct LLVMOpaqueContext *LLVMContextRef;
/**
* The top-level container for all other LLVM Intermediate Representation (IR)
* objects.
*
* @see llvm::Module
*/
typedef struct LLVMOpaqueModule *LLVMModuleRef;
/**
* Each value in the LLVM IR has a type, an LLVMTypeRef.
*
* @see llvm::Type
*/
typedef struct LLVMOpaqueType *LLVMTypeRef;
/**
* Represents an individual value in LLVM IR.
*
* This models llvm::Value.
*/
typedef struct LLVMOpaqueValue *LLVMValueRef;
/**
* Represents a basic block of instructions in LLVM IR.
*
* This models llvm::BasicBlock.
*/
typedef struct LLVMOpaqueBasicBlock *LLVMBasicBlockRef;
/**
* Represents an LLVM basic block builder.
*
* This models llvm::IRBuilder.
*/
typedef struct LLVMOpaqueBuilder *LLVMBuilderRef;
/**
* Interface used to provide a module to JIT or interpreter.
* This is now just a synonym for llvm::Module, but we have to keep using the
* different type to keep binary compatibility.
*/
typedef struct LLVMOpaqueModuleProvider *LLVMModuleProviderRef;
/** @see llvm::PassManagerBase */
typedef struct LLVMOpaquePassManager *LLVMPassManagerRef;
/** @see llvm::PassRegistry */
typedef struct LLVMOpaquePassRegistry *LLVMPassRegistryRef;
/**
* Used to get the users and usees of a Value.
*
* @see llvm::Use */
typedef struct LLVMOpaqueUse *LLVMUseRef;
/**
* Used to represent an attributes.
*
* @see llvm::Attribute
*/
typedef struct LLVMOpaqueAttributeRef *LLVMAttributeRef;
/**
* @see llvm::DiagnosticInfo
*/
typedef struct LLVMOpaqueDiagnosticInfo *LLVMDiagnosticInfoRef;
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif
//===- llvm/ADT/DenseMapInfo.h - Type traits for DenseMap -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines DenseMapInfo traits for DenseMap.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_DENSEMAPINFO_H
#define LLVM_ADT_DENSEMAPINFO_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
#include "llvm/Support/type_traits.h"
namespace llvm {
template<typename T>
struct DenseMapInfo {
//static inline T getEmptyKey();
//static inline T getTombstoneKey();
//static unsigned getHashValue(const T &Val);
//static bool isEqual(const T &LHS, const T &RHS);
};
template <typename T> struct CachedHash {
CachedHash(T Val) : Val(std::move(Val)) {
Hash = DenseMapInfo<T>::getHashValue(Val);
}
CachedHash(T Val, unsigned Hash) : Val(std::move(Val)), Hash(Hash) {}
T Val;
unsigned Hash;
};
// Provide DenseMapInfo for all CachedHash<T>.
template <typename T> struct DenseMapInfo<CachedHash<T>> {
static CachedHash<T> getEmptyKey() {
T N = DenseMapInfo<T>::getEmptyKey();
return {N, 0};
}
static CachedHash<T> getTombstoneKey() {
T N = DenseMapInfo<T>::getTombstoneKey();
return {N, 0};
}
static unsigned getHashValue(CachedHash<T> Val) {
assert(!isEqual(Val, getEmptyKey()) && "Cannot hash the empty key!");
assert(!isEqual(Val, getTombstoneKey()) &&
"Cannot hash the tombstone key!");
return Val.Hash;
}
static bool isEqual(CachedHash<T> A, CachedHash<T> B) {
return DenseMapInfo<T>::isEqual(A.Val, B.Val);
}
};
// Provide DenseMapInfo for all pointers.
template<typename T>
struct DenseMapInfo<T*> {
static inline T* getEmptyKey() {
uintptr_t Val = static_cast<uintptr_t>(-1);
Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable;
return reinterpret_cast<T*>(Val);
}
static inline T* getTombstoneKey() {
uintptr_t Val = static_cast<uintptr_t>(-2);
Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable;
return reinterpret_cast<T*>(Val);
}
static unsigned getHashValue(const T *PtrVal) {
return (unsigned((uintptr_t)PtrVal) >> 4) ^
(unsigned((uintptr_t)PtrVal) >> 9);
}
static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; }
};
// Provide DenseMapInfo for chars.
template<> struct DenseMapInfo<char> {
static inline char getEmptyKey() { return ~0; }
static inline char getTombstoneKey() { return ~0 - 1; }
static unsigned getHashValue(const char& Val) { return Val * 37U; }
static bool isEqual(const char &LHS, const char &RHS) {
return LHS == RHS;
}
};
// Provide DenseMapInfo for unsigned ints.
template<> struct DenseMapInfo<unsigned> {
static inline unsigned getEmptyKey() { return ~0U; }
static inline unsigned getTombstoneKey() { return ~0U - 1; }
static unsigned getHashValue(const unsigned& Val) { return Val * 37U; }
static bool isEqual(const unsigned& LHS, const unsigned& RHS) {
return LHS == RHS;
}
};
// Provide DenseMapInfo for unsigned longs.
template<> struct DenseMapInfo<unsigned long> {
static inline unsigned long getEmptyKey() { return ~0UL; }
static inline unsigned long getTombstoneKey() { return ~0UL - 1L; }
static unsigned getHashValue(const unsigned long& Val) {
return (unsigned)(Val * 37UL);
}
static bool isEqual(const unsigned long& LHS, const unsigned long& RHS) {
return LHS == RHS;
}
};
// Provide DenseMapInfo for unsigned long longs.
template<> struct DenseMapInfo<unsigned long long> {
static inline unsigned long long getEmptyKey() { return ~0ULL; }
static inline unsigned long long getTombstoneKey() { return ~0ULL - 1ULL; }
static unsigned getHashValue(const unsigned long long& Val) {
return (unsigned)(Val * 37ULL);
}
static bool isEqual(const unsigned long long& LHS,
const unsigned long long& RHS) {
return LHS == RHS;
}
};
// Provide DenseMapInfo for ints.
template<> struct DenseMapInfo<int> {
static inline int getEmptyKey() { return 0x7fffffff; }
static inline int getTombstoneKey() { return -0x7fffffff - 1; }
static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37U); }
static bool isEqual(const int& LHS, const int& RHS) {
return LHS == RHS;
}
};
// Provide DenseMapInfo for longs.
template<> struct DenseMapInfo<long> {
static inline long getEmptyKey() {
return (1UL << (sizeof(long) * 8 - 1)) - 1UL;
}
static inline long getTombstoneKey() { return getEmptyKey() - 1L; }
static unsigned getHashValue(const long& Val) {
return (unsigned)(Val * 37UL);
}
static bool isEqual(const long& LHS, const long& RHS) {
return LHS == RHS;
}
};
// Provide DenseMapInfo for long longs.
template<> struct DenseMapInfo<long long> {
static inline long long getEmptyKey() { return 0x7fffffffffffffffLL; }
static inline long long getTombstoneKey() { return -0x7fffffffffffffffLL-1; }
static unsigned getHashValue(const long long& Val) {
return (unsigned)(Val * 37ULL);
}
static bool isEqual(const long long& LHS,
const long long& RHS) {
return LHS == RHS;
}
};
// Provide DenseMapInfo for all pairs whose members have info.
template<typename T, typename U>
struct DenseMapInfo<std::pair<T, U> > {
typedef std::pair<T, U> Pair;
typedef DenseMapInfo<T> FirstInfo;
typedef DenseMapInfo<U> SecondInfo;
static inline Pair getEmptyKey() {
return std::make_pair(FirstInfo::getEmptyKey(),
SecondInfo::getEmptyKey());
}
static inline Pair getTombstoneKey() {
return std::make_pair(FirstInfo::getTombstoneKey(),
SecondInfo::getTombstoneKey());
}
static unsigned getHashValue(const Pair& PairVal) {
uint64_t key = (uint64_t)FirstInfo::getHashValue(PairVal.first) << 32
| (uint64_t)SecondInfo::getHashValue(PairVal.second);
key += ~(key << 32);
key ^= (key >> 22);
key += ~(key << 13);
key ^= (key >> 8);
key += (key << 3);
key ^= (key >> 15);
key += ~(key << 27);
key ^= (key >> 31);
return (unsigned)key;
}
static bool isEqual(const Pair &LHS, const Pair &RHS) {
return FirstInfo::isEqual(LHS.first, RHS.first) &&
SecondInfo::isEqual(LHS.second, RHS.second);
}
};
// Provide DenseMapInfo for StringRefs.
template <> struct DenseMapInfo<StringRef> {
static inline StringRef getEmptyKey() {
return StringRef(reinterpret_cast<const char *>(~static_cast<uintptr_t>(0)),
0);
}
static inline StringRef getTombstoneKey() {
return StringRef(reinterpret_cast<const char *>(~static_cast<uintptr_t>(1)),
0);
}
static unsigned getHashValue(StringRef Val) {
assert(Val.data() != getEmptyKey().data() && "Cannot hash the empty key!");
assert(Val.data() != getTombstoneKey().data() &&
"Cannot hash the tombstone key!");
return (unsigned)(hash_value(Val));
}
static bool isEqual(StringRef LHS, StringRef RHS) {
if (RHS.data() == getEmptyKey().data())
return LHS.data() == getEmptyKey().data();
if (RHS.data() == getTombstoneKey().data())
return LHS.data() == getTombstoneKey().data();
return LHS == RHS;
}
};
// Provide DenseMapInfo for ArrayRefs.
template <typename T> struct DenseMapInfo<ArrayRef<T>> {
static inline ArrayRef<T> getEmptyKey() {
return ArrayRef<T>(reinterpret_cast<const T *>(~static_cast<uintptr_t>(0)),
size_t(0));
}
static inline ArrayRef<T> getTombstoneKey() {
return ArrayRef<T>(reinterpret_cast<const T *>(~static_cast<uintptr_t>(1)),
size_t(0));
}
static unsigned getHashValue(ArrayRef<T> Val) {
assert(Val.data() != getEmptyKey().data() && "Cannot hash the empty key!");
assert(Val.data() != getTombstoneKey().data() &&
"Cannot hash the tombstone key!");
return (unsigned)(hash_value(Val));
}
static bool isEqual(ArrayRef<T> LHS, ArrayRef<T> RHS) {
if (RHS.data() == getEmptyKey().data())
return LHS.data() == getEmptyKey().data();
if (RHS.data() == getTombstoneKey().data())
return LHS.data() == getTombstoneKey().data();
return LHS == RHS;
}
};
} // end namespace llvm
#endif
//===- llvm/ADT/EpochTracker.h - ADT epoch tracking --------------*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the DebugEpochBase and DebugEpochBase::HandleBase classes.
// These can be used to write iterators that are fail-fast when LLVM is built
// with asserts enabled.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_EPOCH_TRACKER_H
#define LLVM_ADT_EPOCH_TRACKER_H
#include "llvm/Config/llvm-config.h"
#include <cstdint>
namespace llvm {
#ifndef LLVM_ENABLE_ABI_BREAKING_CHECKS
class DebugEpochBase {
public:
void incrementEpoch() {}
class HandleBase {
public:
HandleBase() = default;
explicit HandleBase(const DebugEpochBase *) {}
bool isHandleInSync() const { return true; }
const void *getEpochAddress() const { return nullptr; }
};
};
#else
/// \brief A base class for data structure classes wishing to make iterators
/// ("handles") pointing into themselves fail-fast. When building without
/// asserts, this class is empty and does nothing.
///
/// DebugEpochBase does not by itself track handles pointing into itself. The
/// expectation is that routines touching the handles will poll on
/// isHandleInSync at appropriate points to assert that the handle they're using
/// is still valid.
///
class DebugEpochBase {
uint64_t Epoch;
public:
DebugEpochBase() : Epoch(0) {}
/// \brief Calling incrementEpoch invalidates all handles pointing into the
/// calling instance.
void incrementEpoch() { ++Epoch; }
/// \brief The destructor calls incrementEpoch to make use-after-free bugs
/// more likely to crash deterministically.
~DebugEpochBase() { incrementEpoch(); }
/// \brief A base class for iterator classes ("handles") that wish to poll for
/// iterator invalidating modifications in the underlying data structure.
/// When LLVM is built without asserts, this class is empty and does nothing.
///
/// HandleBase does not track the parent data structure by itself. It expects
/// the routines modifying the data structure to call incrementEpoch when they
/// make an iterator-invalidating modification.
///
class HandleBase {
const uint64_t *EpochAddress;
uint64_t EpochAtCreation;
public:
HandleBase() : EpochAddress(nullptr), EpochAtCreation(UINT64_MAX) {}
explicit HandleBase(const DebugEpochBase *Parent)
: EpochAddress(&Parent->Epoch), EpochAtCreation(Parent->Epoch) {}
/// \brief Returns true if the DebugEpochBase this Handle is linked to has
/// not called incrementEpoch on itself since the creation of this
/// HandleBase instance.
bool isHandleInSync() const { return *EpochAddress == EpochAtCreation; }
/// \brief Returns a pointer to the epoch word stored in the data structure
/// this handle points into. Can be used to check if two iterators point
/// into the same data structure.
const void *getEpochAddress() const { return EpochAddress; }
};
};
#endif // LLVM_ENABLE_ABI_BREAKING_CHECKS
} // namespace llvm
#endif
//== llvm/ADT/IntrusiveRefCntPtr.h - Smart Refcounting Pointer ---*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines IntrusiveRefCntPtr, a template class that
// implements a "smart" pointer for objects that maintain their own
// internal reference count, and RefCountedBase/RefCountedBaseVPTR, two
// generic base classes for objects that wish to have their lifetimes
// managed using reference counting.
//
// IntrusiveRefCntPtr is similar to Boost's intrusive_ptr with added
// LLVM-style casting.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_INTRUSIVEREFCNTPTR_H
#define LLVM_ADT_INTRUSIVEREFCNTPTR_H
#include <atomic>
#include <cassert>
#include <cstddef>
namespace llvm {
template <class T>
class IntrusiveRefCntPtr;
//===----------------------------------------------------------------------===//
/// RefCountedBase - A generic base class for objects that wish to
/// have their lifetimes managed using reference counts. Classes
/// subclass RefCountedBase to obtain such functionality, and are
/// typically handled with IntrusiveRefCntPtr "smart pointers" (see below)
/// which automatically handle the management of reference counts.
/// Objects that subclass RefCountedBase should not be allocated on
/// the stack, as invoking "delete" (which is called when the
/// reference count hits 0) on such objects is an error.
//===----------------------------------------------------------------------===//
template <class Derived>
class RefCountedBase {
mutable unsigned ref_cnt;
public:
RefCountedBase() : ref_cnt(0) {}
RefCountedBase(const RefCountedBase &) : ref_cnt(0) {}
void Retain() const { ++ref_cnt; }
void Release() const {
assert (ref_cnt > 0 && "Reference count is already zero.");
if (--ref_cnt == 0) delete static_cast<const Derived*>(this);
}
};
//===----------------------------------------------------------------------===//
/// RefCountedBaseVPTR - A class that has the same function as
/// RefCountedBase, but with a virtual destructor. Should be used
/// instead of RefCountedBase for classes that already have virtual
/// methods to enforce dynamic allocation via 'new'. Classes that
/// inherit from RefCountedBaseVPTR can't be allocated on stack -
/// attempting to do this will produce a compile error.
//===----------------------------------------------------------------------===//
class RefCountedBaseVPTR {
mutable unsigned ref_cnt;
virtual void anchor();
protected:
RefCountedBaseVPTR() : ref_cnt(0) {}
RefCountedBaseVPTR(const RefCountedBaseVPTR &) : ref_cnt(0) {}
virtual ~RefCountedBaseVPTR() {}
void Retain() const { ++ref_cnt; }
void Release() const {
assert (ref_cnt > 0 && "Reference count is already zero.");
if (--ref_cnt == 0) delete this;
}
template <typename T>
friend struct IntrusiveRefCntPtrInfo;
};
template <typename T> struct IntrusiveRefCntPtrInfo {
static void retain(T *obj) { obj->Retain(); }
static void release(T *obj) { obj->Release(); }
};
/// \brief A thread-safe version of \c llvm::RefCountedBase.
///
/// A generic base class for objects that wish to have their lifetimes managed
/// using reference counts. Classes subclass \c ThreadSafeRefCountedBase to
/// obtain such functionality, and are typically handled with
/// \c IntrusiveRefCntPtr "smart pointers" which automatically handle the
/// management of reference counts.
template <class Derived>
class ThreadSafeRefCountedBase {
mutable std::atomic<int> RefCount;
protected:
ThreadSafeRefCountedBase() : RefCount(0) {}
public:
void Retain() const { RefCount.fetch_add(1, std::memory_order_relaxed); }
void Release() const {
int NewRefCount = RefCount.fetch_sub(1, std::memory_order_acq_rel) - 1;
assert(NewRefCount >= 0 && "Reference count was already zero.");
if (NewRefCount == 0)
delete static_cast<const Derived*>(this);
}
};
//===----------------------------------------------------------------------===//
/// IntrusiveRefCntPtr - A template class that implements a "smart pointer"
/// that assumes the wrapped object has a reference count associated
/// with it that can be managed via calls to
/// IntrusivePtrAddRef/IntrusivePtrRelease. The smart pointers
/// manage reference counts via the RAII idiom: upon creation of
/// smart pointer the reference count of the wrapped object is
/// incremented and upon destruction of the smart pointer the
/// reference count is decremented. This class also safely handles
/// wrapping NULL pointers.
///
/// Reference counting is implemented via calls to
/// Obj->Retain()/Obj->Release(). Release() is required to destroy
/// the object when the reference count reaches zero. Inheriting from
/// RefCountedBase/RefCountedBaseVPTR takes care of this
/// automatically.
//===----------------------------------------------------------------------===//
template <typename T>
class IntrusiveRefCntPtr {
T* Obj;
public:
typedef T element_type;
explicit IntrusiveRefCntPtr() : Obj(nullptr) {}
IntrusiveRefCntPtr(T* obj) : Obj(obj) {
retain();
}
IntrusiveRefCntPtr(const IntrusiveRefCntPtr& S) : Obj(S.Obj) {
retain();
}
IntrusiveRefCntPtr(IntrusiveRefCntPtr&& S) : Obj(S.Obj) {
S.Obj = nullptr;
}
template <class X>
IntrusiveRefCntPtr(IntrusiveRefCntPtr<X>&& S) : Obj(S.get()) {
S.Obj = nullptr;
}
template <class X>
IntrusiveRefCntPtr(const IntrusiveRefCntPtr<X>& S)
: Obj(S.get()) {
retain();
}
IntrusiveRefCntPtr& operator=(IntrusiveRefCntPtr S) {
swap(S);
return *this;
}
~IntrusiveRefCntPtr() { release(); }
T& operator*() const { return *Obj; }
T* operator->() const { return Obj; }
T* get() const { return Obj; }
explicit operator bool() const { return Obj; }
void swap(IntrusiveRefCntPtr& other) {
T* tmp = other.Obj;
other.Obj = Obj;
Obj = tmp;
}
void reset() {
release();
Obj = nullptr;
}
void resetWithoutRelease() {
Obj = nullptr;
}
private:
void retain() { if (Obj) IntrusiveRefCntPtrInfo<T>::retain(Obj); }
void release() { if (Obj) IntrusiveRefCntPtrInfo<T>::release(Obj); }
template <typename X>
friend class IntrusiveRefCntPtr;
};
template<class T, class U>
inline bool operator==(const IntrusiveRefCntPtr<T>& A,
const IntrusiveRefCntPtr<U>& B)
{
return A.get() == B.get();
}
template<class T, class U>
inline bool operator!=(const IntrusiveRefCntPtr<T>& A,
const IntrusiveRefCntPtr<U>& B)
{
return A.get() != B.get();
}
template<class T, class U>
inline bool operator==(const IntrusiveRefCntPtr<T>& A,
U* B)
{
return A.get() == B;
}
template<class T, class U>
inline bool operator!=(const IntrusiveRefCntPtr<T>& A,
U* B)
{
return A.get() != B;
}
template<class T, class U>
inline bool operator==(T* A,
const IntrusiveRefCntPtr<U>& B)
{
return A == B.get();
}
template<class T, class U>
inline bool operator!=(T* A,
const IntrusiveRefCntPtr<U>& B)
{
return A != B.get();
}
template <class T>
bool operator==(std::nullptr_t A, const IntrusiveRefCntPtr<T> &B) {
return !B;
}
template <class T>
bool operator==(const IntrusiveRefCntPtr<T> &A, std::nullptr_t B) {
return B == A;
}
template <class T>
bool operator!=(std::nullptr_t A, const IntrusiveRefCntPtr<T> &B) {
return !(A == B);
}
template <class T>
bool operator!=(const IntrusiveRefCntPtr<T> &A, std::nullptr_t B) {
return !(A == B);
}
//===----------------------------------------------------------------------===//
// LLVM-style downcasting support for IntrusiveRefCntPtr objects
//===----------------------------------------------------------------------===//
template <typename From> struct simplify_type;
template<class T> struct simplify_type<IntrusiveRefCntPtr<T> > {
typedef T* SimpleType;
static SimpleType getSimplifiedValue(IntrusiveRefCntPtr<T>& Val) {
return Val.get();
}
};
template<class T> struct simplify_type<const IntrusiveRefCntPtr<T> > {
typedef /*const*/ T* SimpleType;
static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T>& Val) {
return Val.get();
}
};
} // end namespace llvm
#endif // LLVM_ADT_INTRUSIVEREFCNTPTR_H
//===-- None.h - Simple null value for implicit construction ------*- C++ -*-=//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file provides None, an enumerator for use in implicit constructors
// of various (usually templated) types to make such construction more
// terse.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_NONE_H
#define LLVM_ADT_NONE_H
namespace llvm {
/// \brief A simple null object to allow implicit construction of Optional<T>
/// and similar types without having to spell out the specialization's name.
enum class NoneType { None };
const NoneType None = None;
}
#endif
//===-- Optional.h - Simple variant for passing optional values ---*- C++ -*-=//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file provides Optional, a template class modeled in the spirit of
// OCaml's 'opt' variant. The idea is to strongly type whether or not
// a value can be optional.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_OPTIONAL_H
#define LLVM_ADT_OPTIONAL_H
#include "llvm/ADT/None.h"
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Compiler.h"
#include <cassert>
#include <new>
#include <utility>
namespace llvm {
template<typename T>
class Optional {
AlignedCharArrayUnion<T> storage;
bool hasVal;
public:
typedef T value_type;
Optional(NoneType) : hasVal(false) {}
explicit Optional() : hasVal(false) {}
Optional(const T &y) : hasVal(true) {
new (storage.buffer) T(y);
}
Optional(const Optional &O) : hasVal(O.hasVal) {
if (hasVal)
new (storage.buffer) T(*O);
}
Optional(T &&y) : hasVal(true) {
new (storage.buffer) T(std::forward<T>(y));
}
Optional(Optional<T> &&O) : hasVal(O) {
if (O) {
new (storage.buffer) T(std::move(*O));
O.reset();
}
}
Optional &operator=(T &&y) {
if (hasVal)
**this = std::move(y);
else {
new (storage.buffer) T(std::move(y));
hasVal = true;
}
return *this;
}
Optional &operator=(Optional &&O) {
if (!O)
reset();
else {
*this = std::move(*O);
O.reset();
}
return *this;
}
/// Create a new object by constructing it in place with the given arguments.
template<typename ...ArgTypes>
void emplace(ArgTypes &&...Args) {
reset();
hasVal = true;
new (storage.buffer) T(std::forward<ArgTypes>(Args)...);
}
static inline Optional create(const T* y) {
return y ? Optional(*y) : Optional();
}
// FIXME: these assignments (& the equivalent const T&/const Optional& ctors)
// could be made more efficient by passing by value, possibly unifying them
// with the rvalue versions above - but this could place a different set of
// requirements (notably: the existence of a default ctor) when implemented
// in that way. Careful SFINAE to avoid such pitfalls would be required.
Optional &operator=(const T &y) {
if (hasVal)
**this = y;
else {
new (storage.buffer) T(y);
hasVal = true;
}
return *this;
}
Optional &operator=(const Optional &O) {
if (!O)
reset();
else
*this = *O;
return *this;
}
void reset() {
if (hasVal) {
(**this).~T();
hasVal = false;
}
}
~Optional() {
reset();
}
const T* getPointer() const { assert(hasVal); return reinterpret_cast<const T*>(storage.buffer); }
T* getPointer() { assert(hasVal); return reinterpret_cast<T*>(storage.buffer); }
const T& getValue() const LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
T& getValue() LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
explicit operator bool() const { return hasVal; }
bool hasValue() const { return hasVal; }
const T* operator->() const { return getPointer(); }
T* operator->() { return getPointer(); }
const T& operator*() const LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
T& operator*() LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
template <typename U>
LLVM_CONSTEXPR T getValueOr(U &&value) const LLVM_LVALUE_FUNCTION {
return hasValue() ? getValue() : std::forward<U>(value);
}
#if LLVM_HAS_RVALUE_REFERENCE_THIS
T&& getValue() && { assert(hasVal); return std::move(*getPointer()); }
T&& operator*() && { assert(hasVal); return std::move(*getPointer()); }
template <typename U>
T getValueOr(U &&value) && {
return hasValue() ? std::move(getValue()) : std::forward<U>(value);
}
#endif
};
template <typename T> struct isPodLike;
template <typename T> struct isPodLike<Optional<T> > {
// An Optional<T> is pod-like if T is.
static const bool value = isPodLike<T>::value;
};
template <typename T, typename U>
bool operator==(const Optional<T> &X, const Optional<U> &Y) {
if (X && Y)
return *X == *Y;
return X.hasValue() == Y.hasValue();
}
template <typename T, typename U>
bool operator!=(const Optional<T> &X, const Optional<U> &Y) {
return !(X == Y);
}
template <typename T, typename U>
bool operator<(const Optional<T> &X, const Optional<U> &Y) {
if (X && Y)
return *X < *Y;
return X.hasValue() < Y.hasValue();
}
template <typename T, typename U>
bool operator<=(const Optional<T> &X, const Optional<U> &Y) {
return !(Y < X);
}
template <typename T, typename U>
bool operator>(const Optional<T> &X, const Optional<U> &Y) {
return Y < X;
}
template <typename T, typename U>
bool operator>=(const Optional<T> &X, const Optional<U> &Y) {
return !(X < Y);
}
template<typename T>
bool operator==(const Optional<T> &X, NoneType) {
return !X;
}
template<typename T>
bool operator==(NoneType, const Optional<T> &X) {
return X == None;
}
template<typename T>
bool operator!=(const Optional<T> &X, NoneType) {
return !(X == None);
}
template<typename T>
bool operator!=(NoneType, const Optional<T> &X) {
return X != None;
}
template <typename T> bool operator<(const Optional<T> &X, NoneType) {
return false;
}
template <typename T> bool operator<(NoneType, const Optional<T> &X) {
return X.hasValue();
}
template <typename T> bool operator<=(const Optional<T> &X, NoneType) {
return !(None < X);
}
template <typename T> bool operator<=(NoneType, const Optional<T> &X) {
return !(X < None);
}
template <typename T> bool operator>(const Optional<T> &X, NoneType) {
return None < X;
}
template <typename T> bool operator>(NoneType, const Optional<T> &X) {
return X < None;
}
template <typename T> bool operator>=(const Optional<T> &X, NoneType) {
return None <= X;
}
template <typename T> bool operator>=(NoneType, const Optional<T> &X) {
return X <= None;
}
template <typename T> bool operator==(const Optional<T> &X, const T &Y) {
return X && *X == Y;
}
template <typename T> bool operator==(const T &X, const Optional<T> &Y) {
return Y && X == *Y;
}
template <typename T> bool operator!=(const Optional<T> &X, const T &Y) {
return !(X == Y);
}
template <typename T> bool operator!=(const T &X, const Optional<T> &Y) {
return !(X == Y);
}
template <typename T> bool operator<(const Optional<T> &X, const T &Y) {
return !X || *X < Y;
}
template <typename T> bool operator<(const T &X, const Optional<T> &Y) {
return Y && X < *Y;
}
template <typename T> bool operator<=(const Optional<T> &X, const T &Y) {
return !(Y < X);
}
template <typename T> bool operator<=(const T &X, const Optional<T> &Y) {
return !(Y < X);
}
template <typename T> bool operator>(const Optional<T> &X, const T &Y) {
return Y < X;
}
template <typename T> bool operator>(const T &X, const Optional<T> &Y) {
return Y < X;
}
template <typename T> bool operator>=(const Optional<T> &X, const T &Y) {
return !(X < Y);
}
template <typename T> bool operator>=(const T &X, const Optional<T> &Y) {
return !(X < Y);
}
} // end llvm namespace
#endif
//===- llvm/ADT/PointerIntPair.h - Pair for pointer and int -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the PointerIntPair class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_POINTERINTPAIR_H
#define LLVM_ADT_POINTERINTPAIR_H
#include "llvm/Support/Compiler.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
#include <cassert>
#include <limits>
namespace llvm {
template <typename T> struct DenseMapInfo;
template <typename PointerT, unsigned IntBits, typename PtrTraits>
struct PointerIntPairInfo;
/// PointerIntPair - This class implements a pair of a pointer and small
/// integer. It is designed to represent this in the space required by one
/// pointer by bitmangling the integer into the low part of the pointer. This
/// can only be done for small integers: typically up to 3 bits, but it depends
/// on the number of bits available according to PointerLikeTypeTraits for the
/// type.
///
/// Note that PointerIntPair always puts the IntVal part in the highest bits
/// possible. For example, PointerIntPair<void*, 1, bool> will put the bit for
/// the bool into bit #2, not bit #0, which allows the low two bits to be used
/// for something else. For example, this allows:
/// PointerIntPair<PointerIntPair<void*, 1, bool>, 1, bool>
/// ... and the two bools will land in different bits.
///
template <typename PointerTy, unsigned IntBits, typename IntType = unsigned,
typename PtrTraits = PointerLikeTypeTraits<PointerTy>,
typename Info = PointerIntPairInfo<PointerTy, IntBits, PtrTraits>>
class PointerIntPair {
intptr_t Value;
public:
PointerIntPair() : Value(0) {}
PointerIntPair(PointerTy PtrVal, IntType IntVal) {
setPointerAndInt(PtrVal, IntVal);
}
explicit PointerIntPair(PointerTy PtrVal) { initWithPointer(PtrVal); }
PointerTy getPointer() const { return Info::getPointer(Value); }
IntType getInt() const {
return (IntType)Info::getInt(Value);
}
void setPointer(PointerTy PtrVal) {
Value = Info::updatePointer(Value, PtrVal);
}
void setInt(IntType IntVal) {
Value = Info::updateInt(Value, static_cast<intptr_t>(IntVal));
}
void initWithPointer(PointerTy PtrVal) {
Value = Info::updatePointer(0, PtrVal);
}
void setPointerAndInt(PointerTy PtrVal, IntType IntVal) {
Value = Info::updateInt(Info::updatePointer(0, PtrVal),
static_cast<intptr_t>(IntVal));
}
PointerTy const *getAddrOfPointer() const {
return const_cast<PointerIntPair *>(this)->getAddrOfPointer();
}
PointerTy *getAddrOfPointer() {
assert(Value == reinterpret_cast<intptr_t>(getPointer()) &&
"Can only return the address if IntBits is cleared and "
"PtrTraits doesn't change the pointer");
return reinterpret_cast<PointerTy *>(&Value);
}
void *getOpaqueValue() const { return reinterpret_cast<void *>(Value); }
void setFromOpaqueValue(void *Val) {
Value = reinterpret_cast<intptr_t>(Val);
}
static PointerIntPair getFromOpaqueValue(void *V) {
PointerIntPair P;
P.setFromOpaqueValue(V);
return P;
}
// Allow PointerIntPairs to be created from const void * if and only if the
// pointer type could be created from a const void *.
static PointerIntPair getFromOpaqueValue(const void *V) {
(void)PtrTraits::getFromVoidPointer(V);
return getFromOpaqueValue(const_cast<void *>(V));
}
bool operator==(const PointerIntPair &RHS) const {
return Value == RHS.Value;
}
bool operator!=(const PointerIntPair &RHS) const {
return Value != RHS.Value;
}
bool operator<(const PointerIntPair &RHS) const { return Value < RHS.Value; }
bool operator>(const PointerIntPair &RHS) const { return Value > RHS.Value; }
bool operator<=(const PointerIntPair &RHS) const {
return Value <= RHS.Value;
}
bool operator>=(const PointerIntPair &RHS) const {
return Value >= RHS.Value;
}
};
template <typename PointerT, unsigned IntBits, typename PtrTraits>
struct PointerIntPairInfo {
static_assert(PtrTraits::NumLowBitsAvailable <
std::numeric_limits<uintptr_t>::digits,
"cannot use a pointer type that has all bits free");
static_assert(IntBits <= PtrTraits::NumLowBitsAvailable,
"PointerIntPair with integer size too large for pointer");
enum : uintptr_t {
/// PointerBitMask - The bits that come from the pointer.
PointerBitMask =
~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable) - 1),
/// IntShift - The number of low bits that we reserve for other uses, and
/// keep zero.
IntShift = (uintptr_t)PtrTraits::NumLowBitsAvailable - IntBits,
/// IntMask - This is the unshifted mask for valid bits of the int type.
IntMask = (uintptr_t)(((intptr_t)1 << IntBits) - 1),
// ShiftedIntMask - This is the bits for the integer shifted in place.
ShiftedIntMask = (uintptr_t)(IntMask << IntShift)
};
static PointerT getPointer(intptr_t Value) {
return PtrTraits::getFromVoidPointer(
reinterpret_cast<void *>(Value & PointerBitMask));
}
static intptr_t getInt(intptr_t Value) {
return (Value >> IntShift) & IntMask;
}
static intptr_t updatePointer(intptr_t OrigValue, PointerT Ptr) {
intptr_t PtrWord =
reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr));
assert((PtrWord & ~PointerBitMask) == 0 &&
"Pointer is not sufficiently aligned");
// Preserve all low bits, just update the pointer.
return PtrWord | (OrigValue & ~PointerBitMask);
}
static intptr_t updateInt(intptr_t OrigValue, intptr_t Int) {
intptr_t IntWord = static_cast<intptr_t>(Int);
assert((IntWord & ~IntMask) == 0 && "Integer too large for field");
// Preserve all bits other than the ones we are updating.
return (OrigValue & ~ShiftedIntMask) | IntWord << IntShift;
}
};
template <typename T> struct isPodLike;
template <typename PointerTy, unsigned IntBits, typename IntType>
struct isPodLike<PointerIntPair<PointerTy, IntBits, IntType>> {
static const bool value = true;
};
// Provide specialization of DenseMapInfo for PointerIntPair.
template <typename PointerTy, unsigned IntBits, typename IntType>
struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType>> {
typedef PointerIntPair<PointerTy, IntBits, IntType> Ty;
static Ty getEmptyKey() {
uintptr_t Val = static_cast<uintptr_t>(-1);
Val <<= PointerLikeTypeTraits<Ty>::NumLowBitsAvailable;
return Ty::getFromOpaqueValue(reinterpret_cast<void *>(Val));
}
static Ty getTombstoneKey() {
uintptr_t Val = static_cast<uintptr_t>(-2);
Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
return Ty::getFromOpaqueValue(reinterpret_cast<void *>(Val));
}
static unsigned getHashValue(Ty V) {
uintptr_t IV = reinterpret_cast<uintptr_t>(V.getOpaqueValue());
return unsigned(IV) ^ unsigned(IV >> 9);
}
static bool isEqual(const Ty &LHS, const Ty &RHS) { return LHS == RHS; }
};
// Teach SmallPtrSet that PointerIntPair is "basically a pointer".
template <typename PointerTy, unsigned IntBits, typename IntType,
typename PtrTraits>
class PointerLikeTypeTraits<
PointerIntPair<PointerTy, IntBits, IntType, PtrTraits>> {
public:
static inline void *
getAsVoidPointer(const PointerIntPair<PointerTy, IntBits, IntType> &P) {
return P.getOpaqueValue();
}
static inline PointerIntPair<PointerTy, IntBits, IntType>
getFromVoidPointer(void *P) {
return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P);
}
static inline PointerIntPair<PointerTy, IntBits, IntType>
getFromVoidPointer(const void *P) {
return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P);
}
enum { NumLowBitsAvailable = PtrTraits::NumLowBitsAvailable - IntBits };
};
} // end namespace llvm
#endif
//===- llvm/ADT/SmallString.h - 'Normally small' strings --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the SmallString class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_SMALLSTRING_H
#define LLVM_ADT_SMALLSTRING_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
namespace llvm {
/// SmallString - A SmallString is just a SmallVector with methods and accessors
/// that make it work better as a string (e.g. operator+ etc).
template<unsigned InternalLen>
class SmallString : public SmallVector<char, InternalLen> {
public:
/// Default ctor - Initialize to empty.
SmallString() {}
/// Initialize from a StringRef.
SmallString(StringRef S) : SmallVector<char, InternalLen>(S.begin(), S.end()) {}
/// Initialize with a range.
template<typename ItTy>
SmallString(ItTy S, ItTy E) : SmallVector<char, InternalLen>(S, E) {}
// Note that in order to add new overloads for append & assign, we have to
// duplicate the inherited versions so as not to inadvertently hide them.
/// @}
/// @name String Assignment
/// @{
/// Assign from a repeated element.
void assign(size_t NumElts, char Elt) {
this->SmallVectorImpl<char>::assign(NumElts, Elt);
}
/// Assign from an iterator pair.
template<typename in_iter>
void assign(in_iter S, in_iter E) {
this->clear();
SmallVectorImpl<char>::append(S, E);
}
/// Assign from a StringRef.
void assign(StringRef RHS) {
this->clear();
SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
}
/// Assign from a SmallVector.
void assign(const SmallVectorImpl<char> &RHS) {
this->clear();
SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
}
/// @}
/// @name String Concatenation
/// @{
/// Append from an iterator pair.
template<typename in_iter>
void append(in_iter S, in_iter E) {
SmallVectorImpl<char>::append(S, E);
}
void append(size_t NumInputs, char Elt) {
SmallVectorImpl<char>::append(NumInputs, Elt);
}
/// Append from a StringRef.
void append(StringRef RHS) {
SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
}
/// Append from a SmallVector.
void append(const SmallVectorImpl<char> &RHS) {
SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
}
/// @}
/// @name String Comparison
/// @{
/// Check for string equality. This is more efficient than compare() when
/// the relative ordering of inequal strings isn't needed.
bool equals(StringRef RHS) const {
return str().equals(RHS);
}
/// Check for string equality, ignoring case.
bool equals_lower(StringRef RHS) const {
return str().equals_lower(RHS);
}
/// Compare two strings; the result is -1, 0, or 1 if this string is
/// lexicographically less than, equal to, or greater than the \p RHS.
int compare(StringRef RHS) const {
return str().compare(RHS);
}
/// compare_lower - Compare two strings, ignoring case.
int compare_lower(StringRef RHS) const {
return str().compare_lower(RHS);
}
/// compare_numeric - Compare two strings, treating sequences of digits as
/// numbers.
int compare_numeric(StringRef RHS) const {
return str().compare_numeric(RHS);
}
/// @}
/// @name String Predicates
/// @{
/// startswith - Check if this string starts with the given \p Prefix.
bool startswith(StringRef Prefix) const {
return str().startswith(Prefix);
}
/// endswith - Check if this string ends with the given \p Suffix.
bool endswith(StringRef Suffix) const {
return str().endswith(Suffix);
}
/// @}
/// @name String Searching
/// @{
/// find - Search for the first character \p C in the string.
///
/// \return - The index of the first occurrence of \p C, or npos if not
/// found.
size_t find(char C, size_t From = 0) const {
return str().find(C, From);
}
/// Search for the first string \p Str in the string.
///
/// \returns The index of the first occurrence of \p Str, or npos if not
/// found.
size_t find(StringRef Str, size_t From = 0) const {
return str().find(Str, From);
}
/// Search for the last character \p C in the string.
///
/// \returns The index of the last occurrence of \p C, or npos if not
/// found.
size_t rfind(char C, size_t From = StringRef::npos) const {
return str().rfind(C, From);
}
/// Search for the last string \p Str in the string.
///
/// \returns The index of the last occurrence of \p Str, or npos if not
/// found.
size_t rfind(StringRef Str) const {
return str().rfind(Str);
}
/// Find the first character in the string that is \p C, or npos if not
/// found. Same as find.
size_t find_first_of(char C, size_t From = 0) const {
return str().find_first_of(C, From);
}
/// Find the first character in the string that is in \p Chars, or npos if
/// not found.
///
/// Complexity: O(size() + Chars.size())
size_t find_first_of(StringRef Chars, size_t From = 0) const {
return str().find_first_of(Chars, From);
}
/// Find the first character in the string that is not \p C or npos if not
/// found.
size_t find_first_not_of(char C, size_t From = 0) const {
return str().find_first_not_of(C, From);
}
/// Find the first character in the string that is not in the string
/// \p Chars, or npos if not found.
///
/// Complexity: O(size() + Chars.size())
size_t find_first_not_of(StringRef Chars, size_t From = 0) const {
return str().find_first_not_of(Chars, From);
}
/// Find the last character in the string that is \p C, or npos if not
/// found.
size_t find_last_of(char C, size_t From = StringRef::npos) const {
return str().find_last_of(C, From);
}
/// Find the last character in the string that is in \p C, or npos if not
/// found.
///
/// Complexity: O(size() + Chars.size())
size_t find_last_of(
StringRef Chars, size_t From = StringRef::npos) const {
return str().find_last_of(Chars, From);
}
/// @}
/// @name Helpful Algorithms
/// @{
/// Return the number of occurrences of \p C in the string.
size_t count(char C) const {
return str().count(C);
}
/// Return the number of non-overlapped occurrences of \p Str in the
/// string.
size_t count(StringRef Str) const {
return str().count(Str);
}
/// @}
/// @name Substring Operations
/// @{
/// Return a reference to the substring from [Start, Start + N).
///
/// \param Start The index of the starting character in the substring; if
/// the index is npos or greater than the length of the string then the
/// empty substring will be returned.
///
/// \param N The number of characters to included in the substring. If \p N
/// exceeds the number of characters remaining in the string, the string
/// suffix (starting with \p Start) will be returned.
StringRef substr(size_t Start, size_t N = StringRef::npos) const {
return str().substr(Start, N);
}
/// Return a reference to the substring from [Start, End).
///
/// \param Start The index of the starting character in the substring; if
/// the index is npos or greater than the length of the string then the
/// empty substring will be returned.
///
/// \param End The index following the last character to include in the
/// substring. If this is npos, or less than \p Start, or exceeds the
/// number of characters remaining in the string, the string suffix
/// (starting with \p Start) will be returned.
StringRef slice(size_t Start, size_t End) const {
return str().slice(Start, End);
}
// Extra methods.
/// Explicit conversion to StringRef.
StringRef str() const { return StringRef(this->begin(), this->size()); }
// TODO: Make this const, if it's safe...
const char* c_str() {
this->push_back(0);
this->pop_back();
return this->data();
}
/// Implicit conversion to StringRef.
operator StringRef() const { return str(); }
// Extra operators.
const SmallString &operator=(StringRef RHS) {
this->clear();
return *this += RHS;
}
SmallString &operator+=(StringRef RHS) {
this->append(RHS.begin(), RHS.end());
return *this;
}
SmallString &operator+=(char C) {
this->push_back(C);
return *this;
}
};
}
#endif
//===-- llvm/ADT/Statistic.h - Easy way to expose stats ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the 'Statistic' class, which is designed to be an easy way
// to expose various metrics from passes. These statistics are printed at the
// end of a run (from llvm_shutdown), when the -stats command line option is
// passed on the command line.
//
// This is useful for reporting information like the number of instructions
// simplified, optimized or removed by various transformations, like this:
//
// static Statistic NumInstsKilled("gcse", "Number of instructions killed");
//
// Later, in the code: ++NumInstsKilled;
//
// NOTE: Statistics *must* be declared as global variables.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_STATISTIC_H
#define LLVM_ADT_STATISTIC_H
#include "llvm/Support/Atomic.h"
#include "llvm/Support/Compiler.h"
#include <atomic>
#include <memory>
namespace llvm {
class raw_ostream;
class raw_fd_ostream;
class Statistic {
public:
const char *DebugType;
const char *Name;
const char *Desc;
std::atomic<unsigned> Value;
bool Initialized;
unsigned getValue() const { return Value.load(std::memory_order_relaxed); }
const char *getDebugType() const { return DebugType; }
const char *getName() const { return Name; }
const char *getDesc() const { return Desc; }
/// construct - This should only be called for non-global statistics.
void construct(const char *debugtype, const char *name, const char *desc) {
DebugType = debugtype;
Name = name;
Desc = desc;
Value = 0;
Initialized = false;
}
// Allow use of this class as the value itself.
operator unsigned() const { return getValue(); }
#if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
const Statistic &operator=(unsigned Val) {
Value.store(Val, std::memory_order_relaxed);
return init();
}
const Statistic &operator++() {
Value.fetch_add(1, std::memory_order_relaxed);
return init();
}
unsigned operator++(int) {
init();
return Value.fetch_add(1, std::memory_order_relaxed);
}
const Statistic &operator--() {
Value.fetch_sub(1, std::memory_order_relaxed);
return init();
}
unsigned operator--(int) {
init();
return Value.fetch_sub(1, std::memory_order_relaxed);
}
const Statistic &operator+=(unsigned V) {
if (V == 0)
return *this;
Value.fetch_add(V, std::memory_order_relaxed);
return init();
}
const Statistic &operator-=(unsigned V) {
if (V == 0)
return *this;
Value.fetch_sub(V, std::memory_order_relaxed);
return init();
}
#else // Statistics are disabled in release builds.
const Statistic &operator=(unsigned Val) {
return *this;
}
const Statistic &operator++() {
return *this;
}
unsigned operator++(int) {
return 0;
}
const Statistic &operator--() {
return *this;
}
unsigned operator--(int) {
return 0;
}
const Statistic &operator+=(const unsigned &V) {
return *this;
}
const Statistic &operator-=(const unsigned &V) {
return *this;
}
#endif // !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
protected:
Statistic &init() {
bool tmp = Initialized;
sys::MemoryFence();
if (!tmp) RegisterStatistic();
TsanHappensAfter(this);
return *this;
}
void RegisterStatistic();
};
// STATISTIC - A macro to make definition of statistics really simple. This
// automatically passes the DEBUG_TYPE of the file into the statistic.
#define STATISTIC(VARNAME, DESC) \
static llvm::Statistic VARNAME = {DEBUG_TYPE, #VARNAME, DESC, {0}, false}
/// \brief Enable the collection and printing of statistics.
void EnableStatistics();
/// \brief Check if statistics are enabled.
bool AreStatisticsEnabled();
/// \brief Return a file stream to print our output on.
std::unique_ptr<raw_fd_ostream> CreateInfoOutputFile();
/// \brief Print statistics to the file returned by CreateInfoOutputFile().
void PrintStatistics();
/// \brief Print statistics to the given output stream.
void PrintStatistics(raw_ostream &OS);
/// Print statistics in JSON format.
void PrintStatisticsJSON(raw_ostream &OS);
} // end namespace llvm
#endif // LLVM_ADT_STATISTIC_H
//===-- llvm/ADT/StringExtras.h - Useful string functions -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains some functions that are useful when dealing with strings.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_STRINGEXTRAS_H
#define LLVM_ADT_STRINGEXTRAS_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
#include <iterator>
namespace llvm {
class raw_ostream;
template<typename T> class SmallVectorImpl;
/// hexdigit - Return the hexadecimal character for the
/// given number \p X (which should be less than 16).
static inline char hexdigit(unsigned X, bool LowerCase = false) {
const char HexChar = LowerCase ? 'a' : 'A';
return X < 10 ? '0' + X : HexChar + X - 10;
}
/// Construct a string ref from a boolean.
static inline StringRef toStringRef(bool B) {
return StringRef(B ? "true" : "false");
}
/// Interpret the given character \p C as a hexadecimal digit and return its
/// value.
///
/// If \p C is not a valid hex digit, -1U is returned.
static inline unsigned hexDigitValue(char C) {
if (C >= '0' && C <= '9') return C-'0';
if (C >= 'a' && C <= 'f') return C-'a'+10U;
if (C >= 'A' && C <= 'F') return C-'A'+10U;
return -1U;
}
static inline std::string utohexstr(uint64_t X, bool LowerCase = false) {
char Buffer[17];
char *BufPtr = std::end(Buffer);
if (X == 0) *--BufPtr = '0';
while (X) {
unsigned char Mod = static_cast<unsigned char>(X) & 15;
*--BufPtr = hexdigit(Mod, LowerCase);
X >>= 4;
}
return std::string(BufPtr, std::end(Buffer));
}
/// Convert buffer \p Input to its hexadecimal representation.
/// The returned string is double the size of \p Input.
static inline std::string toHex(StringRef Input) {
static const char *const LUT = "0123456789ABCDEF";
size_t Length = Input.size();
std::string Output;
Output.reserve(2 * Length);
for (size_t i = 0; i < Length; ++i) {
const unsigned char c = Input[i];
Output.push_back(LUT[c >> 4]);
Output.push_back(LUT[c & 15]);
}
return Output;
}
static inline std::string utostr(uint64_t X, bool isNeg = false) {
char Buffer[21];
char *BufPtr = std::end(Buffer);
if (X == 0) *--BufPtr = '0'; // Handle special case...
while (X) {
*--BufPtr = '0' + char(X % 10);
X /= 10;
}
if (isNeg) *--BufPtr = '-'; // Add negative sign...
return std::string(BufPtr, std::end(Buffer));
}
static inline std::string itostr(int64_t X) {
if (X < 0)
return utostr(static_cast<uint64_t>(-X), true);
else
return utostr(static_cast<uint64_t>(X));
}
/// StrInStrNoCase - Portable version of strcasestr. Locates the first
/// occurrence of string 's1' in string 's2', ignoring case. Returns
/// the offset of s2 in s1 or npos if s2 cannot be found.
StringRef::size_type StrInStrNoCase(StringRef s1, StringRef s2);
/// getToken - This function extracts one token from source, ignoring any
/// leading characters that appear in the Delimiters string, and ending the
/// token at any of the characters that appear in the Delimiters string. If
/// there are no tokens in the source string, an empty string is returned.
/// The function returns a pair containing the extracted token and the
/// remaining tail string.
std::pair<StringRef, StringRef> getToken(StringRef Source,
StringRef Delimiters = " \t\n\v\f\r");
/// SplitString - Split up the specified string according to the specified
/// delimiters, appending the result fragments to the output list.
void SplitString(StringRef Source,
SmallVectorImpl<StringRef> &OutFragments,
StringRef Delimiters = " \t\n\v\f\r");
/// HashString - Hash function for strings.
///
/// This is the Bernstein hash function.
//
// FIXME: Investigate whether a modified bernstein hash function performs
// better: http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx
// X*33+c -> X*33^c
static inline unsigned HashString(StringRef Str, unsigned Result = 0) {
for (StringRef::size_type i = 0, e = Str.size(); i != e; ++i)
Result = Result * 33 + (unsigned char)Str[i];
return Result;
}
/// Returns the English suffix for an ordinal integer (-st, -nd, -rd, -th).
static inline StringRef getOrdinalSuffix(unsigned Val) {
// It is critically important that we do this perfectly for
// user-written sequences with over 100 elements.
switch (Val % 100) {
case 11:
case 12:
case 13:
return "th";
default:
switch (Val % 10) {
case 1: return "st";
case 2: return "nd";
case 3: return "rd";
default: return "th";
}
}
}
/// PrintEscapedString - Print each character of the specified string, escaping
/// it if it is not printable or if it is an escape char.
void PrintEscapedString(StringRef Name, raw_ostream &Out);
template <typename IteratorT>
inline std::string join_impl(IteratorT Begin, IteratorT End,
StringRef Separator, std::input_iterator_tag) {
std::string S;
if (Begin == End)
return S;
S += (*Begin);
while (++Begin != End) {
S += Separator;
S += (*Begin);
}
return S;
}
template <typename IteratorT>
inline std::string join_impl(IteratorT Begin, IteratorT End,
StringRef Separator, std::forward_iterator_tag) {
std::string S;
if (Begin == End)
return S;
size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
for (IteratorT I = Begin; I != End; ++I)
Len += (*Begin).size();
S.reserve(Len);
S += (*Begin);
while (++Begin != End) {
S += Separator;
S += (*Begin);
}
return S;
}
/// Joins the strings in the range [Begin, End), adding Separator between
/// the elements.
template <typename IteratorT>
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
typedef typename std::iterator_traits<IteratorT>::iterator_category tag;
return join_impl(Begin, End, Separator, tag());
}
} // End llvm namespace
#endif
//===--- StringSwitch.h - Switch-on-literal-string Construct --------------===/
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//===----------------------------------------------------------------------===/
//
// This file implements the StringSwitch template, which mimics a switch()
// statement whose cases are string literals.
//
//===----------------------------------------------------------------------===/
#ifndef LLVM_ADT_STRINGSWITCH_H
#define LLVM_ADT_STRINGSWITCH_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include <cassert>
#include <cstring>
namespace llvm {
/// \brief A switch()-like statement whose cases are string literals.
///
/// The StringSwitch class is a simple form of a switch() statement that
/// determines whether the given string matches one of the given string
/// literals. The template type parameter \p T is the type of the value that
/// will be returned from the string-switch expression. For example,
/// the following code switches on the name of a color in \c argv[i]:
///
/// \code
/// Color color = StringSwitch<Color>(argv[i])
/// .Case("red", Red)
/// .Case("orange", Orange)
/// .Case("yellow", Yellow)
/// .Case("green", Green)
/// .Case("blue", Blue)
/// .Case("indigo", Indigo)
/// .Cases("violet", "purple", Violet)
/// .Default(UnknownColor);
/// \endcode
template<typename T, typename R = T>
class StringSwitch {
/// \brief The string we are matching.
StringRef Str;
/// \brief The pointer to the result of this switch statement, once known,
/// null before that.
const T *Result;
public:
LLVM_ATTRIBUTE_ALWAYS_INLINE
explicit StringSwitch(StringRef S)
: Str(S), Result(nullptr) { }
// StringSwitch is not copyable.
StringSwitch(const StringSwitch &) = delete;
void operator=(const StringSwitch &) = delete;
StringSwitch(StringSwitch &&other) {
*this = std::move(other);
}
StringSwitch &operator=(StringSwitch &&other) {
Str = other.Str;
Result = other.Result;
return *this;
}
~StringSwitch() = default;
template<unsigned N>
LLVM_ATTRIBUTE_ALWAYS_INLINE
StringSwitch& Case(const char (&S)[N], const T& Value) {
if (!Result && N-1 == Str.size() &&
(std::memcmp(S, Str.data(), N-1) == 0)) {
Result = &Value;
}
return *this;
}
template<unsigned N>
LLVM_ATTRIBUTE_ALWAYS_INLINE
StringSwitch& EndsWith(const char (&S)[N], const T &Value) {
if (!Result && Str.size() >= N-1 &&
std::memcmp(S, Str.data() + Str.size() + 1 - N, N-1) == 0) {
Result = &Value;
}
return *this;
}
template<unsigned N>
LLVM_ATTRIBUTE_ALWAYS_INLINE
StringSwitch& StartsWith(const char (&S)[N], const T &Value) {
if (!Result && Str.size() >= N-1 &&
std::memcmp(S, Str.data(), N-1) == 0) {
Result = &Value;
}
return *this;
}
template<unsigned N0, unsigned N1>
LLVM_ATTRIBUTE_ALWAYS_INLINE
StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
const T& Value) {
if (!Result && (
(N0-1 == Str.size() && std::memcmp(S0, Str.data(), N0-1) == 0) ||
(N1-1 == Str.size() && std::memcmp(S1, Str.data(), N1-1) == 0))) {
Result = &Value;
}
return *this;
}
template<unsigned N0, unsigned N1, unsigned N2>
LLVM_ATTRIBUTE_ALWAYS_INLINE
StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
const char (&S2)[N2], const T& Value) {
if (!Result && (
(N0-1 == Str.size() && std::memcmp(S0, Str.data(), N0-1) == 0) ||
(N1-1 == Str.size() && std::memcmp(S1, Str.data(), N1-1) == 0) ||
(N2-1 == Str.size() && std::memcmp(S2, Str.data(), N2-1) == 0))) {
Result = &Value;
}
return *this;
}
template<unsigned N0, unsigned N1, unsigned N2, unsigned N3>
LLVM_ATTRIBUTE_ALWAYS_INLINE
StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
const char (&S2)[N2], const char (&S3)[N3],
const T& Value) {
if (!Result && (
(N0-1 == Str.size() && std::memcmp(S0, Str.data(), N0-1) == 0) ||
(N1-1 == Str.size() && std::memcmp(S1, Str.data(), N1-1) == 0) ||
(N2-1 == Str.size() && std::memcmp(S2, Str.data(), N2-1) == 0) ||
(N3-1 == Str.size() && std::memcmp(S3, Str.data(), N3-1) == 0))) {
Result = &Value;
}
return *this;
}
template<unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4>
LLVM_ATTRIBUTE_ALWAYS_INLINE
StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
const char (&S2)[N2], const char (&S3)[N3],
const char (&S4)[N4], const T& Value) {
if (!Result && (
(N0-1 == Str.size() && std::memcmp(S0, Str.data(), N0-1) == 0) ||
(N1-1 == Str.size() && std::memcmp(S1, Str.data(), N1-1) == 0) ||
(N2-1 == Str.size() && std::memcmp(S2, Str.data(), N2-1) == 0) ||
(N3-1 == Str.size() && std::memcmp(S3, Str.data(), N3-1) == 0) ||
(N4-1 == Str.size() && std::memcmp(S4, Str.data(), N4-1) == 0))) {
Result = &Value;
}
return *this;
}
LLVM_ATTRIBUTE_ALWAYS_INLINE
R Default(const T& Value) const {
if (Result)
return *Result;
return Value;
}
LLVM_ATTRIBUTE_ALWAYS_INLINE
operator R() const {
assert(Result && "Fell off the end of a string-switch");
return *Result;
}
};
} // end namespace llvm
#endif // LLVM_ADT_STRINGSWITCH_H
//===-- llvm/ADT/edit_distance.h - Array edit distance function --- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines a Levenshtein distance function that works for any two
// sequences, with each element of each sequence being analogous to a character
// in a string.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_EDIT_DISTANCE_H
#define LLVM_ADT_EDIT_DISTANCE_H
#include "llvm/ADT/ArrayRef.h"
#include <algorithm>
#include <memory>
namespace llvm {
/// \brief Determine the edit distance between two sequences.
///
/// \param FromArray the first sequence to compare.
///
/// \param ToArray the second sequence to compare.
///
/// \param AllowReplacements whether to allow element replacements (change one
/// element into another) as a single operation, rather than as two operations
/// (an insertion and a removal).
///
/// \param MaxEditDistance If non-zero, the maximum edit distance that this
/// routine is allowed to compute. If the edit distance will exceed that
/// maximum, returns \c MaxEditDistance+1.
///
/// \returns the minimum number of element insertions, removals, or (if
/// \p AllowReplacements is \c true) replacements needed to transform one of
/// the given sequences into the other. If zero, the sequences are identical.
template<typename T>
unsigned ComputeEditDistance(ArrayRef<T> FromArray, ArrayRef<T> ToArray,
bool AllowReplacements = true,
unsigned MaxEditDistance = 0) {
// The algorithm implemented below is the "classic"
// dynamic-programming algorithm for computing the Levenshtein
// distance, which is described here:
//
// http://en.wikipedia.org/wiki/Levenshtein_distance
//
// Although the algorithm is typically described using an m x n
// array, only one row plus one element are used at a time, so this
// implementation just keeps one vector for the row. To update one entry,
// only the entries to the left, top, and top-left are needed. The left
// entry is in Row[x-1], the top entry is what's in Row[x] from the last
// iteration, and the top-left entry is stored in Previous.
typename ArrayRef<T>::size_type m = FromArray.size();
typename ArrayRef<T>::size_type n = ToArray.size();
const unsigned SmallBufferSize = 64;
unsigned SmallBuffer[SmallBufferSize];
std::unique_ptr<unsigned[]> Allocated;
unsigned *Row = SmallBuffer;
if (n + 1 > SmallBufferSize) {
Row = new unsigned[n + 1];
Allocated.reset(Row);
}
for (unsigned i = 1; i <= n; ++i)
Row[i] = i;
for (typename ArrayRef<T>::size_type y = 1; y <= m; ++y) {
Row[0] = y;
unsigned BestThisRow = Row[0];
unsigned Previous = y - 1;
for (typename ArrayRef<T>::size_type x = 1; x <= n; ++x) {
int OldRow = Row[x];
if (AllowReplacements) {
Row[x] = std::min(
Previous + (FromArray[y-1] == ToArray[x-1] ? 0u : 1u),
std::min(Row[x-1], Row[x])+1);
}
else {
if (FromArray[y-1] == ToArray[x-1]) Row[x] = Previous;
else Row[x] = std::min(Row[x-1], Row[x]) + 1;
}
Previous = OldRow;
BestThisRow = std::min(BestThisRow, Row[x]);
}
if (MaxEditDistance && BestThisRow > MaxEditDistance)
return MaxEditDistance + 1;
}
unsigned Result = Row[n];
return Result;
}
} // End llvm namespace
#endif
//===- llvm/ADT/ilist_base.h - Intrusive List Base ---------------*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_ILIST_BASE_H
#define LLVM_ADT_ILIST_BASE_H
#include "llvm/ADT/ilist_node_base.h"
#include <cassert>
#include <cstddef>
#include <type_traits>
namespace llvm {
/// Implementations of list algorithms using ilist_node_base.
class ilist_base {
public:
static void insertBeforeImpl(ilist_node_base &Next, ilist_node_base &N) {
ilist_node_base &Prev = *Next.getPrev();
N.setNext(&Next);
N.setPrev(&Prev);
Prev.setNext(&N);
Next.setPrev(&N);
}
static void removeImpl(ilist_node_base &N) {
ilist_node_base *Prev = N.getPrev();
ilist_node_base *Next = N.getNext();
Next->setPrev(Prev);
Prev->setNext(Next);
// Not strictly necessary, but helps catch a class of bugs.
N.setPrev(nullptr);
N.setNext(nullptr);
}
static void removeRangeImpl(ilist_node_base &First, ilist_node_base &Last) {
ilist_node_base *Prev = First.getPrev();
ilist_node_base *Final = Last.getPrev();
Last.setPrev(Prev);
Prev->setNext(&Last);
// Not strictly necessary, but helps catch a class of bugs.
First.setPrev(nullptr);
Final->setNext(nullptr);
}
static void transferBeforeImpl(ilist_node_base &Next, ilist_node_base &First,
ilist_node_base &Last) {
if (&Next == &Last || &First == &Last)
return;
// Position cannot be contained in the range to be transferred.
assert(&Next != &First &&
// Check for the most common mistake.
"Insertion point can't be one of the transferred nodes");
ilist_node_base &Final = *Last.getPrev();
// Detach from old list/position.
First.getPrev()->setNext(&Last);
Last.setPrev(First.getPrev());
// Splice [First, Final] into its new list/position.
ilist_node_base &Prev = *Next.getPrev();
Final.setNext(&Next);
First.setPrev(&Prev);
Prev.setNext(&First);
Next.setPrev(&Final);
}
template <class T> static void insertBefore(T &Next, T &N) {
insertBeforeImpl(Next, N);
}
template <class T> static void remove(T &N) { removeImpl(N); }
template <class T> static void removeRange(T &First, T &Last) {
removeRangeImpl(First, Last);
}
template <class T> static void transferBefore(T &Next, T &First, T &Last) {
transferBeforeImpl(Next, First, Last);
}
};
} // end namespace llvm
#endif // LLVM_ADT_ILIST_BASE_H
//===- llvm/ADT/ilist_iterator.h - Intrusive List Iterator -------*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_ILIST_ITERATOR_H
#define LLVM_ADT_ILIST_ITERATOR_H
#include "llvm/ADT/ilist_node.h"
#include <cassert>
#include <cstddef>
#include <iterator>
#include <type_traits>
namespace llvm {
namespace ilist_detail {
template <class NodeTy> struct ConstCorrectNodeType {
typedef ilist_node<NodeTy> type;
};
template <class NodeTy> struct ConstCorrectNodeType<const NodeTy> {
typedef const ilist_node<NodeTy> type;
};
template <bool IsReverse = false> struct IteratorHelper {
template <class T> static void increment(T *&I) {
I = ilist_node_access::getNext(*I);
}
template <class T> static void decrement(T *&I) {
I = ilist_node_access::getPrev(*I);
}
};
template <> struct IteratorHelper<true> {
template <class T> static void increment(T *&I) {
IteratorHelper<false>::decrement(I);
}
template <class T> static void decrement(T *&I) {
IteratorHelper<false>::increment(I);
}
};
} // end namespace ilist_detail
/// Iterator for intrusive lists based on ilist_node.
template <typename NodeTy, bool IsReverse> class ilist_iterator {
public:
typedef NodeTy value_type;
typedef value_type *pointer;
typedef value_type &reference;
typedef ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category;
typedef typename std::add_const<value_type>::type *const_pointer;
typedef typename std::add_const<value_type>::type &const_reference;
typedef typename ilist_detail::ConstCorrectNodeType<NodeTy>::type node_type;
typedef node_type *node_pointer;
typedef node_type &node_reference;
private:
node_pointer NodePtr;
public:
/// Create from an ilist_node.
explicit ilist_iterator(node_reference N) : NodePtr(&N) {}
explicit ilist_iterator(pointer NP)
: NodePtr(ilist_node_access::getNodePtr(NP)) {}
explicit ilist_iterator(reference NR)
: NodePtr(ilist_node_access::getNodePtr(&NR)) {}
ilist_iterator() : NodePtr(nullptr) {}
// This is templated so that we can allow constructing a const iterator from
// a nonconst iterator...
template <class node_ty>
ilist_iterator(
const ilist_iterator<node_ty, IsReverse> &RHS,
typename std::enable_if<std::is_convertible<node_ty *, NodeTy *>::value,
void *>::type = nullptr)
: NodePtr(RHS.getNodePtr()) {}
// This is templated so that we can allow assigning to a const iterator from
// a nonconst iterator...
template <class node_ty>
const ilist_iterator &
operator=(const ilist_iterator<node_ty, IsReverse> &RHS) {
NodePtr = RHS.getNodePtr();
return *this;
}
/// Convert from an iterator to its reverse.
///
/// TODO: Roll this into the implicit constructor once we're sure that no one
/// is relying on the std::reverse_iterator off-by-one semantics.
ilist_iterator<NodeTy, !IsReverse> getReverse() const {
if (NodePtr)
return ilist_iterator<NodeTy, !IsReverse>(*NodePtr);
return ilist_iterator<NodeTy, !IsReverse>();
}
void reset(pointer NP) { NodePtr = NP; }
// Accessors...
reference operator*() const {
assert(!NodePtr->isKnownSentinel());
return *ilist_node_access::getValuePtr(NodePtr);
}
pointer operator->() const { return &operator*(); }
// Comparison operators
friend bool operator==(const ilist_iterator &LHS, const ilist_iterator &RHS) {
return LHS.NodePtr == RHS.NodePtr;
}
friend bool operator!=(const ilist_iterator &LHS, const ilist_iterator &RHS) {
return LHS.NodePtr != RHS.NodePtr;
}
// Increment and decrement operators...
ilist_iterator &operator--() {
ilist_detail::IteratorHelper<IsReverse>::decrement(NodePtr);
return *this;
}
ilist_iterator &operator++() {
ilist_detail::IteratorHelper<IsReverse>::increment(NodePtr);
return *this;
}
ilist_iterator operator--(int) {
ilist_iterator tmp = *this;
--*this;
return tmp;
}
ilist_iterator operator++(int) {
ilist_iterator tmp = *this;
++*this;
return tmp;
}
/// Get the underlying ilist_node.
node_pointer getNodePtr() const { return static_cast<node_pointer>(NodePtr); }
};
template <typename From> struct simplify_type;
/// Allow ilist_iterators to convert into pointers to a node automatically when
/// used by the dyn_cast, cast, isa mechanisms...
///
/// FIXME: remove this, since there is no implicit conversion to NodeTy.
template <typename NodeTy> struct simplify_type<ilist_iterator<NodeTy>> {
typedef NodeTy *SimpleType;
static SimpleType getSimplifiedValue(ilist_iterator<NodeTy> &Node) {
return &*Node;
}
};
template <typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy>> {
typedef /*const*/ NodeTy *SimpleType;
static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
return &*Node;
}
};
} // end namespace llvm
#endif // LLVM_ADT_ILIST_ITERATOR_H
//==-- llvm/ADT/ilist_node.h - Intrusive Linked List Helper ------*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the ilist_node class template, which is a convenient
// base class for creating classes that can be used with ilists.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_ILIST_NODE_H
#define LLVM_ADT_ILIST_NODE_H
#include "llvm/ADT/ilist_node_base.h"
namespace llvm {
template<typename NodeTy>
struct ilist_traits;
struct ilist_node_access;
template <typename NodeTy, bool IsReverse = false> class ilist_iterator;
template <typename NodeTy> class ilist_sentinel;
/// Templated wrapper class.
template <typename NodeTy> class ilist_node : ilist_node_base {
friend class ilist_base;
friend struct ilist_node_access;
friend struct ilist_traits<NodeTy>;
friend class ilist_iterator<NodeTy, false>;
friend class ilist_iterator<NodeTy, true>;
friend class ilist_sentinel<NodeTy>;
protected:
ilist_node() = default;
private:
ilist_node *getPrev() {
return static_cast<ilist_node *>(ilist_node_base::getPrev());
}
ilist_node *getNext() {
return static_cast<ilist_node *>(ilist_node_base::getNext());
}
const ilist_node *getPrev() const {
return static_cast<ilist_node *>(ilist_node_base::getPrev());
}
const ilist_node *getNext() const {
return static_cast<ilist_node *>(ilist_node_base::getNext());
}
void setPrev(ilist_node *N) { ilist_node_base::setPrev(N); }
void setNext(ilist_node *N) { ilist_node_base::setNext(N); }
public:
ilist_iterator<NodeTy> getIterator() { return ilist_iterator<NodeTy>(*this); }
ilist_iterator<const NodeTy> getIterator() const {
return ilist_iterator<const NodeTy>(*this);
}
using ilist_node_base::isKnownSentinel;
};
/// An access class for ilist_node private API.
///
/// This gives access to the private parts of ilist nodes. Nodes for an ilist
/// should friend this class if they inherit privately from ilist_node.
///
/// Using this class outside of the ilist implementation is unsupported.
struct ilist_node_access {
template <typename T> static ilist_node<T> *getNodePtr(T *N) { return N; }
template <typename T> static const ilist_node<T> *getNodePtr(const T *N) {
return N;
}
template <typename T> static T *getValuePtr(ilist_node<T> *N) {
return static_cast<T *>(N);
}
template <typename T> static const T *getValuePtr(const ilist_node<T> *N) {
return static_cast<const T *>(N);
}
template <typename T> static ilist_node<T> *getPrev(ilist_node<T> &N) {
return N.getPrev();
}
template <typename T> static ilist_node<T> *getNext(ilist_node<T> &N) {
return N.getNext();
}
template <typename T>
static const ilist_node<T> *getPrev(const ilist_node<T> &N) {
return N.getPrev();
}
template <typename T>
static const ilist_node<T> *getNext(const ilist_node<T> &N) {
return N.getNext();
}
};
template <typename NodeTy> class ilist_sentinel : public ilist_node<NodeTy> {
public:
ilist_sentinel() {
ilist_node_base::initializeSentinel();
reset();
}
void reset() {
this->setPrev(this);
this->setNext(this);
}
bool empty() const { return this == this->getPrev(); }
};
/// An ilist node that can access its parent list.
///
/// Requires \c NodeTy to have \a getParent() to find the parent node, and the
/// \c ParentTy to have \a getSublistAccess() to get a reference to the list.
template <typename NodeTy, typename ParentTy>
class ilist_node_with_parent : public ilist_node<NodeTy> {
protected:
ilist_node_with_parent() = default;
private:
/// Forward to NodeTy::getParent().
///
/// Note: do not use the name "getParent()". We want a compile error
/// (instead of recursion) when the subclass fails to implement \a
/// getParent().
const ParentTy *getNodeParent() const {
return static_cast<const NodeTy *>(this)->getParent();
}
public:
/// @name Adjacent Node Accessors
/// @{
/// \brief Get the previous node, or \c nullptr for the list head.
NodeTy *getPrevNode() {
// Should be separated to a reused function, but then we couldn't use auto
// (and would need the type of the list).
const auto &List =
getNodeParent()->*(ParentTy::getSublistAccess((NodeTy *)nullptr));
return List.getPrevNode(*static_cast<NodeTy *>(this));
}
/// \brief Get the previous node, or \c nullptr for the list head.
const NodeTy *getPrevNode() const {
return const_cast<ilist_node_with_parent *>(this)->getPrevNode();
}
/// \brief Get the next node, or \c nullptr for the list tail.
NodeTy *getNextNode() {
// Should be separated to a reused function, but then we couldn't use auto
// (and would need the type of the list).
const auto &List =
getNodeParent()->*(ParentTy::getSublistAccess((NodeTy *)nullptr));
return List.getNextNode(*static_cast<NodeTy *>(this));
}
/// \brief Get the next node, or \c nullptr for the list tail.
const NodeTy *getNextNode() const {
return const_cast<ilist_node_with_parent *>(this)->getNextNode();
}
/// @}
};
} // End llvm namespace
#endif
//===- llvm/ADT/ilist_node_base.h - Intrusive List Node Base -----*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_ILIST_NODE_BASE_H
#define LLVM_ADT_ILIST_NODE_BASE_H
#include "llvm/ADT/PointerIntPair.h"
namespace llvm {
/// Base class for ilist nodes.
class ilist_node_base {
#ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS
PointerIntPair<ilist_node_base *, 1> PrevAndSentinel;
#else
ilist_node_base *Prev = nullptr;
#endif
ilist_node_base *Next = nullptr;
public:
#ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS
void setPrev(ilist_node_base *Prev) { PrevAndSentinel.setPointer(Prev); }
ilist_node_base *getPrev() const { return PrevAndSentinel.getPointer(); }
bool isKnownSentinel() const { return PrevAndSentinel.getInt(); }
void initializeSentinel() { PrevAndSentinel.setInt(true); }
#else
void setPrev(ilist_node_base *Prev) { this->Prev = Prev; }
ilist_node_base *getPrev() const { return Prev; }
bool isKnownSentinel() const { return false; }
void initializeSentinel() {}
#endif
void setNext(ilist_node_base *Next) { this->Next = Next; }
ilist_node_base *getNext() const { return Next; }
};
} // end namespace llvm
#endif // LLVM_ADT_ILIST_NODE_BASE_H
//===- iterator_range.h - A range adaptor for iterators ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
/// \file
/// This provides a very simple, boring adaptor for a begin and end iterator
/// into a range type. This should be used to build range views that work well
/// with range based for loops and range based constructors.
///
/// Note that code here follows more standards-based coding conventions as it
/// is mirroring proposed interfaces for standardization.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_ITERATOR_RANGE_H
#define LLVM_ADT_ITERATOR_RANGE_H
#include <utility>
#include <iterator>
namespace llvm {
/// \brief A range adaptor for a pair of iterators.
///
/// This just wraps two iterators into a range-compatible interface. Nothing
/// fancy at all.
template <typename IteratorT>
class iterator_range {
IteratorT begin_iterator, end_iterator;
public:
//TODO: Add SFINAE to test that the Container's iterators match the range's
// iterators.
template <typename Container>
iterator_range(Container &&c)
//TODO: Consider ADL/non-member begin/end calls.
: begin_iterator(c.begin()), end_iterator(c.end()) {}
iterator_range(IteratorT begin_iterator, IteratorT end_iterator)
: begin_iterator(std::move(begin_iterator)),
end_iterator(std::move(end_iterator)) {}
IteratorT begin() const { return begin_iterator; }
IteratorT end() const { return end_iterator; }
};
/// \brief Convenience function for iterating over sub-ranges.
///
/// This provides a bit of syntactic sugar to make using sub-ranges
/// in for loops a bit easier. Analogous to std::make_pair().
template <class T> iterator_range<T> make_range(T x, T y) {
return iterator_range<T>(std::move(x), std::move(y));
}
template <typename T> iterator_range<T> make_range(std::pair<T, T> p) {
return iterator_range<T>(std::move(p.first), std::move(p.second));
}
template<typename T>
iterator_range<decltype(begin(std::declval<T>()))> drop_begin(T &&t, int n) {
return make_range(std::next(begin(t), n), end(t));
}
}
#endif
//===- llvm/ADT/simple_ilist.h - Simple Intrusive List ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_SIMPLE_ILIST_H
#define LLVM_ADT_SIMPLE_ILIST_H
#include "llvm/ADT/ilist_base.h"
#include "llvm/ADT/ilist_iterator.h"
#include "llvm/ADT/ilist_node.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
namespace llvm {
/// A simple intrusive list implementation.
///
/// This is a simple intrusive list for a \c T that inherits from \c
/// ilist_node<T>. The list never takes ownership of anything inserted in it.
///
/// Unlike \a iplist<T> and \a ilist<T>, \a simple_ilist<T> never allocates or
/// deletes values, and has no callback traits.
///
/// The API for adding nodes include \a push_front(), \a push_back(), and \a
/// insert(). These all take values by reference (not by pointer), except for
/// the range version of \a insert().
///
/// There are three sets of API for discarding nodes from the list: \a
/// remove(), which takes a reference to the node to remove, \a erase(), which
/// takes an iterator or iterator range and returns the next one, and \a
/// clear(), which empties out the container. All three are constant time
/// operations. None of these deletes any nodes; in particular, if there is a
/// single node in the list, then these have identical semantics:
/// \li \c L.remove(L.front());
/// \li \c L.erase(L.begin());
/// \li \c L.clear();
///
/// As a convenience for callers, there are parallel APIs that take a \c
/// Disposer (such as \c std::default_delete<T>): \a removeAndDispose(), \a
/// eraseAndDispose(), and \a clearAndDispose(). These have different names
/// because the extra semantic is otherwise non-obvious. They are equivalent
/// to calling \a std::for_each() on the range to be discarded.
template <typename T> class simple_ilist : ilist_base, ilist_node_access {
ilist_sentinel<T> Sentinel;
public:
typedef T value_type;
typedef T *pointer;
typedef T &reference;
typedef const T *const_pointer;
typedef const T &const_reference;
typedef ilist_iterator<T> iterator;
typedef ilist_iterator<const T> const_iterator;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef ilist_iterator<const T, true> const_reverse_iterator;
typedef ilist_iterator<T, true> reverse_iterator;
simple_ilist() = default;
~simple_ilist() = default;
// No copy constructors.
simple_ilist(const simple_ilist &) = delete;
simple_ilist &operator=(const simple_ilist &) = delete;
// Move constructors.
simple_ilist(simple_ilist &&X) { splice(end(), X); }
simple_ilist &operator=(simple_ilist &&X) {
clear();
splice(end(), X);
return *this;
}
iterator begin() { return ++iterator(Sentinel); }
const_iterator begin() const { return ++const_iterator(Sentinel); }
iterator end() { return iterator(Sentinel); }
const_iterator end() const { return const_iterator(Sentinel); }
reverse_iterator rbegin() { return ++reverse_iterator(Sentinel); }
const_reverse_iterator rbegin() const {
return ++const_reverse_iterator(Sentinel);
}
reverse_iterator rend() { return reverse_iterator(Sentinel); }
const_reverse_iterator rend() const {
return const_reverse_iterator(Sentinel);
}
/// Check if the list is empty in constant time.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { return Sentinel.empty(); }
/// Calculate the size of the list in linear time.
size_type LLVM_ATTRIBUTE_UNUSED_RESULT size() const {
return std::distance(begin(), end());
}
reference front() { return *begin(); }
const_reference front() const { return *begin(); }
reference back() { return *rbegin(); }
const_reference back() const { return *rbegin(); }
/// Insert a node at the front; never copies.
void push_front(reference Node) { insert(begin(), Node); }
/// Insert a node at the back; never copies.
void push_back(reference Node) { insert(end(), Node); }
/// Remove the node at the front; never deletes.
void pop_front() { erase(begin()); }
/// Remove the node at the back; never deletes.
void pop_back() { erase(--end()); }
/// Swap with another list in place using std::swap.
void swap(simple_ilist &X) { std::swap(*this, X); }
/// Insert a node by reference; never copies.
iterator insert(iterator I, reference Node) {
ilist_base::insertBefore(*I.getNodePtr(), *this->getNodePtr(&Node));
return iterator(&Node);
}
/// Insert a range of nodes; never copies.
template <class Iterator>
void insert(iterator I, Iterator First, Iterator Last) {
for (; First != Last; ++First)
insert(I, *First);
}
/// Remove a node by reference; never deletes.
///
/// \see \a erase() for removing by iterator.
/// \see \a removeAndDispose() if the node should be deleted.
void remove(reference N) { ilist_base::remove(*this->getNodePtr(&N)); }
/// Remove a node by reference and dispose of it.
template <class Disposer>
void removeAndDispose(reference N, Disposer dispose) {
remove(N);
dispose(&N);
}
/// Remove a node by iterator; never deletes.
///
/// \see \a remove() for removing by reference.
/// \see \a eraseAndDispose() it the node should be deleted.
iterator erase(iterator I) {
assert(I != end() && "Cannot remove end of list!");
remove(*I++);
return I;
}
/// Remove a range of nodes; never deletes.
///
/// \see \a eraseAndDispose() if the nodes should be deleted.
iterator erase(iterator First, iterator Last) {
ilist_base::removeRange(*First.getNodePtr(), *Last.getNodePtr());
return Last;
}
/// Remove a node by iterator and dispose of it.
template <class Disposer>
iterator eraseAndDispose(iterator I, Disposer dispose) {
auto Next = std::next(I);
erase(I);
dispose(&*I);
return Next;
}
/// Remove a range of nodes and dispose of them.
template <class Disposer>
iterator eraseAndDispose(iterator First, iterator Last, Disposer dispose) {
while (First != Last)
First = eraseAndDispose(First, dispose);
return Last;
}
/// Clear the list; never deletes.
///
/// \see \a clearAndDispose() if the nodes should be deleted.
void clear() { Sentinel.reset(); }
/// Clear the list and dispose of the nodes.
template <class Disposer> void clearAndDispose(Disposer dispose) {
eraseAndDispose(begin(), end(), dispose);
}
/// Splice in another list.
void splice(iterator I, simple_ilist &L2) {
splice(I, L2, L2.begin(), L2.end());
}
/// Splice in a node from another list.
void splice(iterator I, simple_ilist &L2, iterator Node) {
splice(I, L2, Node, std::next(Node));
}
/// Splice in a range of nodes from another list.
void splice(iterator I, simple_ilist &, iterator First, iterator Last) {
ilist_base::transferBefore(*I.getNodePtr(), *First.getNodePtr(),
*Last.getNodePtr());
}
/// Merge in another list.
///
/// \pre \c this and \p RHS are sorted.
///@{
void merge(simple_ilist &RHS) { merge(RHS, std::less<T>()); }
template <class Compare> void merge(simple_ilist &RHS, Compare comp);
///@}
/// Sort the list.
///@{
void sort() { sort(std::less<T>()); }
template <class Compare> void sort(Compare comp);
///@}
};
template <class T>
template <class Compare>
void simple_ilist<T>::merge(simple_ilist<T> &RHS, Compare comp) {
if (this == &RHS || RHS.empty())
return;
iterator LI = begin(), LE = end();
iterator RI = RHS.begin(), RE = RHS.end();
while (LI != LE) {
if (comp(*RI, *LI)) {
// Transfer a run of at least size 1 from RHS to LHS.
iterator RunStart = RI++;
RI = std::find_if(RI, RE, [&](reference RV) { return !comp(RV, *LI); });
splice(LI, RHS, RunStart, RI);
if (RI == RE)
return;
}
++LI;
}
// Transfer the remaining RHS nodes once LHS is finished.
splice(LE, RHS, RI, RE);
}
template <class T>
template <class Compare>
void simple_ilist<T>::sort(Compare comp) {
// Vacuously sorted.
if (empty() || std::next(begin()) == end())
return;
// Split the list in the middle.
iterator Center = begin(), End = begin();
while (End != end() && ++End != end()) {
++Center;
++End;
}
simple_ilist<T> RHS;
RHS.splice(RHS.end(), *this, Center, end());
// Sort the sublists and merge back together.
sort(comp);
RHS.sort(comp);
merge(RHS, comp);
}
} // end namespace llvm
#endif // LLVM_ADT_SIMPLE_ILIST_H
/*===-- llvm/config/llvm-config.h - llvm configure variable -------*- C -*-===*/
/* */
/* The LLVM Compiler Infrastructure */
/* */
/* This file is distributed under the University of Illinois Open Source */
/* License. See LICENSE.TXT for details. */
/* */
/*===----------------------------------------------------------------------===*/
/* This file enumerates all of the llvm variables from configure so that
they can be in exported headers and won't override package specific
directives. This is a C file so we can include it in the llvm-c headers. */
/* To avoid multiple inclusions of these variables when we include the exported
headers and config.h, conditionally include these. */
/* TODO: This is a bit of a hack. */
#ifndef CONFIG_H
/* Installation directory for binary executables */
/* #undef LLVM_BINDIR */
/* Time at which LLVM was configured */
/* #undef LLVM_CONFIGTIME */
/* Installation directory for data files */
/* #undef LLVM_DATADIR */
/* Installation directory for documentation */
/* #undef LLVM_DOCSDIR */
/* Installation directory for config files */
/* #undef LLVM_ETCDIR */
/* Has gcc/MSVC atomic intrinsics */
#define LLVM_HAS_ATOMICS 1
/* Host triple we were built on */
#define LLVM_HOSTTRIPLE "i686-pc-win32"
/* Installation directory for include files */
/* #undef LLVM_INCLUDEDIR */
/* Installation directory for .info files */
/* #undef LLVM_INFODIR */
/* Installation directory for libraries */
/* #undef LLVM_LIBDIR */
/* Installation directory for man pages */
/* #undef LLVM_MANDIR */
/* LLVM architecture name for the native architecture, if available */
#define LLVM_NATIVE_ARCH X86
/* LLVM name for the native AsmParser init function, if available */
/* #undef LLVM_NATIVE_ASMPARSER */
/* LLVM name for the native AsmPrinter init function, if available */
#define LLVM_NATIVE_ASMPRINTER LLVMInitializeX86AsmPrinter
/* LLVM name for the native Target init function, if available */
#define LLVM_NATIVE_TARGET LLVMInitializeX86Target
/* LLVM name for the native TargetInfo init function, if available */
#define LLVM_NATIVE_TARGETINFO LLVMInitializeX86TargetInfo
/* LLVM name for the native target MC init function, if available */
#define LLVM_NATIVE_TARGETMC LLVMInitializeX86TargetMC
/* Define if this is Unixish platform */
/* #undef LLVM_ON_UNIX */
/* Define if this is Win32ish platform */
#define LLVM_ON_WIN32 1
/* Define to path to circo program if found or 'echo circo' otherwise */
/* #undef LLVM_PATH_CIRCO */
/* Define to path to dot program if found or 'echo dot' otherwise */
/* #undef LLVM_PATH_DOT */
/* Define to path to dotty program if found or 'echo dotty' otherwise */
/* #undef LLVM_PATH_DOTTY */
/* Define to path to fdp program if found or 'echo fdp' otherwise */
/* #undef LLVM_PATH_FDP */
/* Define to path to Graphviz program if found or 'echo Graphviz' otherwise */
/* #undef LLVM_PATH_GRAPHVIZ */
/* Define to path to gv program if found or 'echo gv' otherwise */
/* #undef LLVM_PATH_GV */
/* Define to path to neato program if found or 'echo neato' otherwise */
/* #undef LLVM_PATH_NEATO */
/* Define to path to twopi program if found or 'echo twopi' otherwise */
/* #undef LLVM_PATH_TWOPI */
/* Define to path to xdot.py program if found or 'echo xdot.py' otherwise */
/* #undef LLVM_PATH_XDOT_PY */
/* Installation prefix directory */
#define LLVM_PREFIX "C:/Program Files (x86)/LLVM"
#endif
//===-- llvm/Argument.h - Definition of the Argument class ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares the Argument class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_IR_ARGUMENT_H
#define LLVM_IR_ARGUMENT_H
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Value.h"
namespace llvm {
template <typename NodeTy> class SymbolTableListTraits;
/// \brief LLVM Argument representation
///
/// This class represents an incoming formal argument to a Function. A formal
/// argument, since it is ``formal'', does not contain an actual value but
/// instead represents the type, argument number, and attributes of an argument
/// for a specific function. When used in the body of said function, the
/// argument of course represents the value of the actual argument that the
/// function was called with.
class Argument : public Value, public ilist_node<Argument> {
virtual void anchor();
Function *Parent;
friend class SymbolTableListTraits<Argument>;
void setParent(Function *parent);
public:
/// \brief Constructor.
///
/// If \p F is specified, the argument is inserted at the end of the argument
/// list for \p F.
explicit Argument(Type *Ty, const Twine &Name = "", Function *F = nullptr);
inline const Function *getParent() const { return Parent; }
inline Function *getParent() { return Parent; }
/// \brief Return the index of this formal argument in its containing
/// function.
///
/// For example in "void foo(int a, float b)" a is 0 and b is 1.
unsigned getArgNo() const;
/// \brief Return true if this argument has the nonnull attribute on it in
/// its containing function. Also returns true if at least one byte is known
/// to be dereferenceable and the pointer is in addrspace(0).
bool hasNonNullAttr() const;
/// \brief If this argument has the dereferenceable attribute on it in its
/// containing function, return the number of bytes known to be
/// dereferenceable. Otherwise, zero is returned.
uint64_t getDereferenceableBytes() const;
/// \brief If this argument has the dereferenceable_or_null attribute on
/// it in its containing function, return the number of bytes known to be
/// dereferenceable. Otherwise, zero is returned.
uint64_t getDereferenceableOrNullBytes() const;
/// \brief Return true if this argument has the byval attribute on it in its
/// containing function.
bool hasByValAttr() const;
/// \brief Return true if this argument has the swiftself attribute.
bool hasSwiftSelfAttr() const;
/// \brief Return true if this argument has the swifterror attribute.
bool hasSwiftErrorAttr() const;
/// \brief Return true if this argument has the byval attribute or inalloca
/// attribute on it in its containing function. These attributes both
/// represent arguments being passed by value.
bool hasByValOrInAllocaAttr() const;
/// \brief If this is a byval or inalloca argument, return its alignment.
unsigned getParamAlignment() const;
/// \brief Return true if this argument has the nest attribute on it in its
/// containing function.
bool hasNestAttr() const;
/// \brief Return true if this argument has the noalias attribute on it in its
/// containing function.
bool hasNoAliasAttr() const;
/// \brief Return true if this argument has the nocapture attribute on it in
/// its containing function.
bool hasNoCaptureAttr() const;
/// \brief Return true if this argument has the sret attribute on it in its
/// containing function.
bool hasStructRetAttr() const;
/// \brief Return true if this argument has the returned attribute on it in
/// its containing function.
bool hasReturnedAttr() const;
/// \brief Return true if this argument has the readonly or readnone attribute
/// on it in its containing function.
bool onlyReadsMemory() const;
/// \brief Return true if this argument has the inalloca attribute on it in
/// its containing function.
bool hasInAllocaAttr() const;
/// \brief Return true if this argument has the zext attribute on it in its
/// containing function.
bool hasZExtAttr() const;
/// \brief Return true if this argument has the sext attribute on it in its
/// containing function.
bool hasSExtAttr() const;
/// \brief Add a Attribute to an argument.
void addAttr(AttributeSet AS);
void addAttr(Attribute::AttrKind Kind) {
addAttr(AttributeSet::get(getContext(), getArgNo() + 1, Kind));
}
/// \brief Remove a Attribute from an argument.
void removeAttr(AttributeSet AS);
void removeAttr(Attribute::AttrKind Kind) {
removeAttr(AttributeSet::get(getContext(), getArgNo() + 1, Kind));
}
/// \brief Checks if an argument has a given attribute.
bool hasAttribute(Attribute::AttrKind Kind) const;
/// \brief Method for support type inquiry through isa, cast, and
/// dyn_cast.
static inline bool classof(const Value *V) {
return V->getValueID() == ArgumentVal;
}
};
} // End llvm namespace
#endif
//===-- llvm/CallingConv.h - LLVM Calling Conventions -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines LLVM's set of calling conventions.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_IR_CALLINGCONV_H
#define LLVM_IR_CALLINGCONV_H
namespace llvm {
/// CallingConv Namespace - This namespace contains an enum with a value for
/// the well-known calling conventions.
///
namespace CallingConv {
/// LLVM IR allows to use arbitrary numbers as calling convention identifiers.
typedef unsigned ID;
/// A set of enums which specify the assigned numeric values for known llvm
/// calling conventions.
/// @brief LLVM Calling Convention Representation
enum {
/// C - The default llvm calling convention, compatible with C. This
/// convention is the only calling convention that supports varargs calls.
/// As with typical C calling conventions, the callee/caller have to
/// tolerate certain amounts of prototype mismatch.
C = 0,
// Generic LLVM calling conventions. None of these calling conventions
// support varargs calls, and all assume that the caller and callee
// prototype exactly match.
/// Fast - This calling convention attempts to make calls as fast as
/// possible (e.g. by passing things in registers).
Fast = 8,
// Cold - This calling convention attempts to make code in the caller as
// efficient as possible under the assumption that the call is not commonly
// executed. As such, these calls often preserve all registers so that the
// call does not break any live ranges in the caller side.
Cold = 9,
// GHC - Calling convention used by the Glasgow Haskell Compiler (GHC).
GHC = 10,
// HiPE - Calling convention used by the High-Performance Erlang Compiler
// (HiPE).
HiPE = 11,
// WebKit JS - Calling convention for stack based JavaScript calls
WebKit_JS = 12,
// AnyReg - Calling convention for dynamic register based calls (e.g.
// stackmap and patchpoint intrinsics).
AnyReg = 13,
// PreserveMost - Calling convention for runtime calls that preserves most
// registers.
PreserveMost = 14,
// PreserveAll - Calling convention for runtime calls that preserves
// (almost) all registers.
PreserveAll = 15,
// Swift - Calling convention for Swift.
Swift = 16,
// CXX_FAST_TLS - Calling convention for access functions.
CXX_FAST_TLS = 17,
// Target - This is the start of the target-specific calling conventions,
// e.g. fastcall and thiscall on X86.
FirstTargetCC = 64,
/// X86_StdCall - stdcall is the calling conventions mostly used by the
/// Win32 API. It is basically the same as the C convention with the
/// difference in that the callee is responsible for popping the arguments
/// from the stack.
X86_StdCall = 64,
/// X86_FastCall - 'fast' analog of X86_StdCall. Passes first two arguments
/// in ECX:EDX registers, others - via stack. Callee is responsible for
/// stack cleaning.
X86_FastCall = 65,
/// ARM_APCS - ARM Procedure Calling Standard calling convention (obsolete,
/// but still used on some targets).
ARM_APCS = 66,
/// ARM_AAPCS - ARM Architecture Procedure Calling Standard calling
/// convention (aka EABI). Soft float variant.
ARM_AAPCS = 67,
/// ARM_AAPCS_VFP - Same as ARM_AAPCS, but uses hard floating point ABI.
ARM_AAPCS_VFP = 68,
/// MSP430_INTR - Calling convention used for MSP430 interrupt routines.
MSP430_INTR = 69,
/// X86_ThisCall - Similar to X86_StdCall. Passes first argument in ECX,
/// others via stack. Callee is responsible for stack cleaning. MSVC uses
/// this by default for methods in its ABI.
X86_ThisCall = 70,
/// PTX_Kernel - Call to a PTX kernel.
/// Passes all arguments in parameter space.
PTX_Kernel = 71,
/// PTX_Device - Call to a PTX device function.
/// Passes all arguments in register or parameter space.
PTX_Device = 72,
/// SPIR_FUNC - Calling convention for SPIR non-kernel device functions.
/// No lowering or expansion of arguments.
/// Structures are passed as a pointer to a struct with the byval attribute.
/// Functions can only call SPIR_FUNC and SPIR_KERNEL functions.
/// Functions can only have zero or one return values.
/// Variable arguments are not allowed, except for printf.
/// How arguments/return values are lowered are not specified.
/// Functions are only visible to the devices.
SPIR_FUNC = 75,
/// SPIR_KERNEL - Calling convention for SPIR kernel functions.
/// Inherits the restrictions of SPIR_FUNC, except
/// Cannot have non-void return values.
/// Cannot have variable arguments.
/// Can also be called by the host.
/// Is externally visible.
SPIR_KERNEL = 76,
/// Intel_OCL_BI - Calling conventions for Intel OpenCL built-ins
Intel_OCL_BI = 77,
/// \brief The C convention as specified in the x86-64 supplement to the
/// System V ABI, used on most non-Windows systems.
X86_64_SysV = 78,
/// \brief The C convention as implemented on Windows/x86-64. This
/// convention differs from the more common \c X86_64_SysV convention
/// in a number of ways, most notably in that XMM registers used to pass
/// arguments are shadowed by GPRs, and vice versa.
X86_64_Win64 = 79,
/// \brief MSVC calling convention that passes vectors and vector aggregates
/// in SSE registers.
X86_VectorCall = 80,
/// \brief Calling convention used by HipHop Virtual Machine (HHVM) to
/// perform calls to and from translation cache, and for calling PHP
/// functions.
/// HHVM calling convention supports tail/sibling call elimination.
HHVM = 81,
/// \brief HHVM calling convention for invoking C/C++ helpers.
HHVM_C = 82,
/// X86_INTR - x86 hardware interrupt context. Callee may take one or two
/// parameters, where the 1st represents a pointer to hardware context frame
/// and the 2nd represents hardware error code, the presence of the later
/// depends on the interrupt vector taken. Valid for both 32- and 64-bit
/// subtargets.
X86_INTR = 83,
/// Used for AVR interrupt routines.
AVR_INTR = 84,
/// Calling convention used for AVR signal routines.
AVR_SIGNAL = 85,
/// Calling convention used for special AVR rtlib functions
/// which have an "optimized" convention to preserve registers.
AVR_BUILTIN = 86,
/// Calling convention used for Mesa vertex shaders.
AMDGPU_VS = 87,
/// Calling convention used for Mesa geometry shaders.
AMDGPU_GS = 88,
/// Calling convention used for Mesa pixel shaders.
AMDGPU_PS = 89,
/// Calling convention used for Mesa compute shaders.
AMDGPU_CS = 90,
/// Calling convention for AMDGPU code object kernels.
AMDGPU_KERNEL = 91,
/// The highest possible calling convention ID. Must be some 2^k - 1.
MaxID = 1023
};
} // End CallingConv namespace
} // End llvm namespace
#endif
//===-- llvm/Constant.h - Constant class definition -------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the declaration of the Constant class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_IR_CONSTANT_H
#define LLVM_IR_CONSTANT_H
#include "llvm/IR/User.h"
namespace llvm {
class APInt;
template<typename T> class SmallVectorImpl;
/// This is an important base class in LLVM. It provides the common facilities
/// of all constant values in an LLVM program. A constant is a value that is
/// immutable at runtime. Functions are constants because their address is
/// immutable. Same with global variables.
///
/// All constants share the capabilities provided in this class. All constants
/// can have a null value. They can have an operand list. Constants can be
/// simple (integer and floating point values), complex (arrays and structures),
/// or expression based (computations yielding a constant value composed of
/// only certain operators and other constant values).
///
/// Note that Constants are immutable (once created they never change)
/// and are fully shared by structural equivalence. This means that two
/// structurally equivalent constants will always have the same address.
/// Constants are created on demand as needed and never deleted: thus clients
/// don't have to worry about the lifetime of the objects.
/// @brief LLVM Constant Representation
class Constant : public User {
void operator=(const Constant &) = delete;
Constant(const Constant &) = delete;
void anchor() override;
protected:
Constant(Type *ty, ValueTy vty, Use *Ops, unsigned NumOps)
: User(ty, vty, Ops, NumOps) {}
public:
/// Return true if this is the value that would be returned by getNullValue.
bool isNullValue() const;
/// Returns true if the value is one.
bool isOneValue() const;
/// Return true if this is the value that would be returned by
/// getAllOnesValue.
bool isAllOnesValue() const;
/// Return true if the value is what would be returned by
/// getZeroValueForNegation.
bool isNegativeZeroValue() const;
/// Return true if the value is negative zero or null value.
bool isZeroValue() const;
/// Return true if the value is not the smallest signed value.
bool isNotMinSignedValue() const;
/// Return true if the value is the smallest signed value.
bool isMinSignedValue() const;
/// Return true if evaluation of this constant could trap. This is true for
/// things like constant expressions that could divide by zero.
bool canTrap() const;
/// Return true if the value can vary between threads.
bool isThreadDependent() const;
/// Return true if the value is dependent on a dllimport variable.
bool isDLLImportDependent() const;
/// Return true if the constant has users other than constant expressions and
/// other dangling things.
bool isConstantUsed() const;
/// This method classifies the entry according to whether or not it may
/// generate a relocation entry. This must be conservative, so if it might
/// codegen to a relocatable entry, it should say so.
///
/// FIXME: This really should not be in IR.
bool needsRelocation() const;
/// For aggregates (struct/array/vector) return the constant that corresponds
/// to the specified element if possible, or null if not. This can return null
/// if the element index is a ConstantExpr, or if 'this' is a constant expr.
Constant *getAggregateElement(unsigned Elt) const;
Constant *getAggregateElement(Constant *Elt) const;
/// If this is a splat vector constant, meaning that all of the elements have
/// the same value, return that value. Otherwise return 0.
Constant *getSplatValue() const;
/// If C is a constant integer then return its value, otherwise C must be a
/// vector of constant integers, all equal, and the common value is returned.
const APInt &getUniqueInteger() const;
/// Called if some element of this constant is no longer valid.
/// At this point only other constants may be on the use_list for this
/// constant. Any constants on our Use list must also be destroy'd. The
/// implementation must be sure to remove the constant from the list of
/// available cached constants. Implementations should implement
/// destroyConstantImpl to remove constants from any pools/maps they are
/// contained it.
void destroyConstant();
//// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Value *V) {
return V->getValueID() >= ConstantFirstVal &&
V->getValueID() <= ConstantLastVal;
}
/// This method is a special form of User::replaceUsesOfWith
/// (which does not work on constants) that does work
/// on constants. Basically this method goes through the trouble of building
/// a new constant that is equivalent to the current one, with all uses of
/// From replaced with uses of To. After this construction is completed, all
/// of the users of 'this' are replaced to use the new constant, and then
/// 'this' is deleted. In general, you should not call this method, instead,
/// use Value::replaceAllUsesWith, which automatically dispatches to this
/// method as needed.
///
void handleOperandChange(Value *, Value *);
static Constant *getNullValue(Type* Ty);
/// @returns the value for an integer or vector of integer constant of the
/// given type that has all its bits set to true.
/// @brief Get the all ones value
static Constant *getAllOnesValue(Type* Ty);
/// Return the value for an integer or pointer constant, or a vector thereof,
/// with the given scalar value.
static Constant *getIntegerValue(Type *Ty, const APInt &V);
/// If there are any dead constant users dangling off of this constant, remove
/// them. This method is useful for clients that want to check to see if a
/// global is unused, but don't want to deal with potentially dead constants
/// hanging off of the globals.
void removeDeadConstantUsers() const;
Constant *stripPointerCasts() {
return cast<Constant>(Value::stripPointerCasts());
}
const Constant *stripPointerCasts() const {
return const_cast<Constant*>(this)->stripPointerCasts();
}
};
} // End llvm namespace
#endif
//===- DebugLoc.h - Debug Location Information ------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines a number of light weight data structures used
// to describe and track debug location information.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_IR_DEBUGLOC_H
#define LLVM_IR_DEBUGLOC_H
#include "llvm/IR/TrackingMDRef.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
class LLVMContext;
class raw_ostream;
class DILocation;
/// \brief A debug info location.
///
/// This class is a wrapper around a tracking reference to an \a DILocation
/// pointer.
///
/// To avoid extra includes, \a DebugLoc doubles the \a DILocation API with a
/// one based on relatively opaque \a MDNode pointers.
class DebugLoc {
TrackingMDNodeRef Loc;
public:
DebugLoc() {}
DebugLoc(DebugLoc &&X) : Loc(std::move(X.Loc)) {}
DebugLoc(const DebugLoc &X) : Loc(X.Loc) {}
DebugLoc &operator=(DebugLoc &&X) {
Loc = std::move(X.Loc);
return *this;
}
DebugLoc &operator=(const DebugLoc &X) {
Loc = X.Loc;
return *this;
}
/// \brief Construct from an \a DILocation.
DebugLoc(const DILocation *L);
/// \brief Construct from an \a MDNode.
///
/// Note: if \c N is not an \a DILocation, a verifier check will fail, and
/// accessors will crash. However, construction from other nodes is
/// supported in order to handle forward references when reading textual
/// IR.
explicit DebugLoc(const MDNode *N);
/// \brief Get the underlying \a DILocation.
///
/// \pre !*this or \c isa<DILocation>(getAsMDNode()).
/// @{
DILocation *get() const;
operator DILocation *() const { return get(); }
DILocation *operator->() const { return get(); }
DILocation &operator*() const { return *get(); }
/// @}
/// \brief Check for null.
///
/// Check for null in a way that is safe with broken debug info. Unlike
/// the conversion to \c DILocation, this doesn't require that \c Loc is of
/// the right type. Important for cases like \a llvm::StripDebugInfo() and
/// \a Instruction::hasMetadata().
explicit operator bool() const { return Loc; }
/// \brief Check whether this has a trivial destructor.
bool hasTrivialDestructor() const { return Loc.hasTrivialDestructor(); }
/// \brief Create a new DebugLoc.
///
/// Create a new DebugLoc at the specified line/col and scope/inline. This
/// forwards to \a DILocation::get().
///
/// If \c !Scope, returns a default-constructed \a DebugLoc.
///
/// FIXME: Remove this. Users should use DILocation::get().
static DebugLoc get(unsigned Line, unsigned Col, const MDNode *Scope,
const MDNode *InlinedAt = nullptr);
unsigned getLine() const;
unsigned getCol() const;
MDNode *getScope() const;
DILocation *getInlinedAt() const;
/// \brief Get the fully inlined-at scope for a DebugLoc.
///
/// Gets the inlined-at scope for a DebugLoc.
MDNode *getInlinedAtScope() const;
/// \brief Find the debug info location for the start of the function.
///
/// Walk up the scope chain of given debug loc and find line number info
/// for the function.
///
/// FIXME: Remove this. Users should use DILocation/DILocalScope API to
/// find the subprogram, and then DILocation::get().
DebugLoc getFnDebugLoc() const;
/// \brief Return \c this as a bar \a MDNode.
MDNode *getAsMDNode() const { return Loc; }
bool operator==(const DebugLoc &DL) const { return Loc == DL.Loc; }
bool operator!=(const DebugLoc &DL) const { return Loc != DL.Loc; }
void dump() const;
/// \brief prints source location /path/to/file.exe:line:col @[inlined at]
void print(raw_ostream &OS) const;
};
} // end namespace llvm
#endif /* LLVM_SUPPORT_DEBUGLOC_H */
//===-- llvm/GlobalObject.h - Class to represent global objects -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This represents an independent object. That is, a function or a global
// variable, but not an alias.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_IR_GLOBALOBJECT_H
#define LLVM_IR_GLOBALOBJECT_H
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/GlobalValue.h"
namespace llvm {
class Comdat;
class MDNode;
class Metadata;
class Module;
class GlobalObject : public GlobalValue {
GlobalObject(const GlobalObject &) = delete;
protected:
GlobalObject(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps,
LinkageTypes Linkage, const Twine &Name,
unsigned AddressSpace = 0)
: GlobalValue(Ty, VTy, Ops, NumOps, Linkage, Name, AddressSpace),
ObjComdat(nullptr) {
setGlobalValueSubClassData(0);
}
std::string Section; // Section to emit this into, empty means default
Comdat *ObjComdat;
enum {
LastAlignmentBit = 4,
HasMetadataHashEntryBit,
GlobalObjectBits,
};
static const unsigned GlobalObjectSubClassDataBits =
GlobalValueSubClassDataBits - GlobalObjectBits;
private:
static const unsigned AlignmentBits = LastAlignmentBit + 1;
static const unsigned AlignmentMask = (1 << AlignmentBits) - 1;
static const unsigned GlobalObjectMask = (1 << GlobalObjectBits) - 1;
public:
unsigned getAlignment() const {
unsigned Data = getGlobalValueSubClassData();
unsigned AlignmentData = Data & AlignmentMask;
return (1u << AlignmentData) >> 1;
}
void setAlignment(unsigned Align);
unsigned getGlobalObjectSubClassData() const;
void setGlobalObjectSubClassData(unsigned Val);
bool hasSection() const { return !getSection().empty(); }
StringRef getSection() const { return Section; }
void setSection(StringRef S);
bool hasComdat() const { return getComdat() != nullptr; }
const Comdat *getComdat() const { return ObjComdat; }
Comdat *getComdat() { return ObjComdat; }
void setComdat(Comdat *C) { ObjComdat = C; }
/// Check if this has any metadata.
bool hasMetadata() const { return hasMetadataHashEntry(); }
/// Get the current metadata attachments for the given kind, if any.
///
/// These functions require that the function have at most a single attachment
/// of the given kind, and return \c nullptr if such an attachment is missing.
/// @{
MDNode *getMetadata(unsigned KindID) const;
MDNode *getMetadata(StringRef Kind) const;
/// @}
/// Appends all attachments with the given ID to \c MDs in insertion order.
/// If the global has no attachments with the given ID, or if ID is invalid,
/// leaves MDs unchanged.
/// @{
void getMetadata(unsigned KindID, SmallVectorImpl<MDNode *> &MDs) const;
void getMetadata(StringRef Kind, SmallVectorImpl<MDNode *> &MDs) const;
/// @}
/// Set a particular kind of metadata attachment.
///
/// Sets the given attachment to \c MD, erasing it if \c MD is \c nullptr or
/// replacing it if it already exists.
/// @{
void setMetadata(unsigned KindID, MDNode *MD);
void setMetadata(StringRef Kind, MDNode *MD);
/// @}
/// Add a metadata attachment.
/// @{
void addMetadata(unsigned KindID, MDNode &MD);
void addMetadata(StringRef Kind, MDNode &MD);
/// @}
/// Appends all attachments for the global to \c MDs, sorting by attachment
/// ID. Attachments with the same ID appear in insertion order.
void
getAllMetadata(SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs) const;
/// Erase all metadata attachments with the given kind.
void eraseMetadata(unsigned KindID);
/// Copy metadata from Src, adjusting offsets by Offset.
void copyMetadata(const GlobalObject *Src, unsigned Offset);
void addTypeMetadata(unsigned Offset, Metadata *TypeID);
void copyAttributesFrom(const GlobalValue *Src) override;
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Value *V) {
return V->getValueID() == Value::FunctionVal ||
V->getValueID() == Value::GlobalVariableVal;
}
void clearMetadata();
private:
bool hasMetadataHashEntry() const {
return getGlobalValueSubClassData() & (1 << HasMetadataHashEntryBit);
}
void setHasMetadataHashEntry(bool HasEntry) {
unsigned Mask = 1 << HasMetadataHashEntryBit;
setGlobalValueSubClassData((~Mask & getGlobalValueSubClassData()) |
(HasEntry ? Mask : 0u));
}
};
} // End llvm namespace
#endif
//===-- llvm/Instruction.def - File that describes Instructions -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains descriptions of the various LLVM instructions. This is
// used as a central place for enumerating the different instructions and
// should eventually be the place to put comments about the instructions.
//
//===----------------------------------------------------------------------===//
// NOTE: NO INCLUDE GUARD DESIRED!
// Provide definitions of macros so that users of this file do not have to
// define everything to use it...
//
#ifndef FIRST_TERM_INST
#define FIRST_TERM_INST(num)
#endif
#ifndef HANDLE_TERM_INST
#ifndef HANDLE_INST
#define HANDLE_TERM_INST(num, opcode, Class)
#else
#define HANDLE_TERM_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class)
#endif
#endif
#ifndef LAST_TERM_INST
#define LAST_TERM_INST(num)
#endif
#ifndef FIRST_BINARY_INST
#define FIRST_BINARY_INST(num)
#endif
#ifndef HANDLE_BINARY_INST
#ifndef HANDLE_INST
#define HANDLE_BINARY_INST(num, opcode, instclass)
#else
#define HANDLE_BINARY_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class)
#endif
#endif
#ifndef LAST_BINARY_INST
#define LAST_BINARY_INST(num)
#endif
#ifndef FIRST_MEMORY_INST
#define FIRST_MEMORY_INST(num)
#endif
#ifndef HANDLE_MEMORY_INST
#ifndef HANDLE_INST
#define HANDLE_MEMORY_INST(num, opcode, Class)
#else
#define HANDLE_MEMORY_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class)
#endif
#endif
#ifndef LAST_MEMORY_INST
#define LAST_MEMORY_INST(num)
#endif
#ifndef FIRST_CAST_INST
#define FIRST_CAST_INST(num)
#endif
#ifndef HANDLE_CAST_INST
#ifndef HANDLE_INST
#define HANDLE_CAST_INST(num, opcode, Class)
#else
#define HANDLE_CAST_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class)
#endif
#endif
#ifndef LAST_CAST_INST
#define LAST_CAST_INST(num)
#endif
#ifndef FIRST_FUNCLETPAD_INST
#define FIRST_FUNCLETPAD_INST(num)
#endif
#ifndef HANDLE_FUNCLETPAD_INST
#ifndef HANDLE_INST
#define HANDLE_FUNCLETPAD_INST(num, opcode, Class)
#else
#define HANDLE_FUNCLETPAD_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class)
#endif
#endif
#ifndef LAST_FUNCLETPAD_INST
#define LAST_FUNCLETPAD_INST(num)
#endif
#ifndef FIRST_OTHER_INST
#define FIRST_OTHER_INST(num)
#endif
#ifndef HANDLE_OTHER_INST
#ifndef HANDLE_INST
#define HANDLE_OTHER_INST(num, opcode, Class)
#else
#define HANDLE_OTHER_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class)
#endif
#endif
#ifndef LAST_OTHER_INST
#define LAST_OTHER_INST(num)
#endif
// Terminator Instructions - These instructions are used to terminate a basic
// block of the program. Every basic block must end with one of these
// instructions for it to be a well formed basic block.
//
FIRST_TERM_INST ( 1)
HANDLE_TERM_INST ( 1, Ret , ReturnInst)
HANDLE_TERM_INST ( 2, Br , BranchInst)
HANDLE_TERM_INST ( 3, Switch , SwitchInst)
HANDLE_TERM_INST ( 4, IndirectBr , IndirectBrInst)
HANDLE_TERM_INST ( 5, Invoke , InvokeInst)
HANDLE_TERM_INST ( 6, Resume , ResumeInst)
HANDLE_TERM_INST ( 7, Unreachable , UnreachableInst)
HANDLE_TERM_INST ( 8, CleanupRet , CleanupReturnInst)
HANDLE_TERM_INST ( 9, CatchRet , CatchReturnInst)
HANDLE_TERM_INST (10, CatchSwitch , CatchSwitchInst)
LAST_TERM_INST (10)
// Standard binary operators...
FIRST_BINARY_INST(11)
HANDLE_BINARY_INST(11, Add , BinaryOperator)
HANDLE_BINARY_INST(12, FAdd , BinaryOperator)
HANDLE_BINARY_INST(13, Sub , BinaryOperator)
HANDLE_BINARY_INST(14, FSub , BinaryOperator)
HANDLE_BINARY_INST(15, Mul , BinaryOperator)
HANDLE_BINARY_INST(16, FMul , BinaryOperator)
HANDLE_BINARY_INST(17, UDiv , BinaryOperator)
HANDLE_BINARY_INST(18, SDiv , BinaryOperator)
HANDLE_BINARY_INST(19, FDiv , BinaryOperator)
HANDLE_BINARY_INST(20, URem , BinaryOperator)
HANDLE_BINARY_INST(21, SRem , BinaryOperator)
HANDLE_BINARY_INST(22, FRem , BinaryOperator)
// Logical operators (integer operands)
HANDLE_BINARY_INST(23, Shl , BinaryOperator) // Shift left (logical)
HANDLE_BINARY_INST(24, LShr , BinaryOperator) // Shift right (logical)
HANDLE_BINARY_INST(25, AShr , BinaryOperator) // Shift right (arithmetic)
HANDLE_BINARY_INST(26, And , BinaryOperator)
HANDLE_BINARY_INST(27, Or , BinaryOperator)
HANDLE_BINARY_INST(28, Xor , BinaryOperator)
LAST_BINARY_INST(28)
// Memory operators...
FIRST_MEMORY_INST(29)
HANDLE_MEMORY_INST(29, Alloca, AllocaInst) // Stack management
HANDLE_MEMORY_INST(30, Load , LoadInst ) // Memory manipulation instrs
HANDLE_MEMORY_INST(31, Store , StoreInst )
HANDLE_MEMORY_INST(32, GetElementPtr, GetElementPtrInst)
HANDLE_MEMORY_INST(33, Fence , FenceInst )
HANDLE_MEMORY_INST(34, AtomicCmpXchg , AtomicCmpXchgInst )
HANDLE_MEMORY_INST(35, AtomicRMW , AtomicRMWInst )
LAST_MEMORY_INST(35)
// Cast operators ...
// NOTE: The order matters here because CastInst::isEliminableCastPair
// NOTE: (see Instructions.cpp) encodes a table based on this ordering.
FIRST_CAST_INST(36)
HANDLE_CAST_INST(36, Trunc , TruncInst ) // Truncate integers
HANDLE_CAST_INST(37, ZExt , ZExtInst ) // Zero extend integers
HANDLE_CAST_INST(38, SExt , SExtInst ) // Sign extend integers
HANDLE_CAST_INST(39, FPToUI , FPToUIInst ) // floating point -> UInt
HANDLE_CAST_INST(40, FPToSI , FPToSIInst ) // floating point -> SInt
HANDLE_CAST_INST(41, UIToFP , UIToFPInst ) // UInt -> floating point
HANDLE_CAST_INST(42, SIToFP , SIToFPInst ) // SInt -> floating point
HANDLE_CAST_INST(43, FPTrunc , FPTruncInst ) // Truncate floating point
HANDLE_CAST_INST(44, FPExt , FPExtInst ) // Extend floating point
HANDLE_CAST_INST(45, PtrToInt, PtrToIntInst) // Pointer -> Integer
HANDLE_CAST_INST(46, IntToPtr, IntToPtrInst) // Integer -> Pointer
HANDLE_CAST_INST(47, BitCast , BitCastInst ) // Type cast
HANDLE_CAST_INST(48, AddrSpaceCast, AddrSpaceCastInst) // addrspace cast
LAST_CAST_INST(48)
FIRST_FUNCLETPAD_INST(49)
HANDLE_FUNCLETPAD_INST(49, CleanupPad, CleanupPadInst)
HANDLE_FUNCLETPAD_INST(50, CatchPad , CatchPadInst)
LAST_FUNCLETPAD_INST(50)
// Other operators...
FIRST_OTHER_INST(51)
HANDLE_OTHER_INST(51, ICmp , ICmpInst ) // Integer comparison instruction
HANDLE_OTHER_INST(52, FCmp , FCmpInst ) // Floating point comparison instr.
HANDLE_OTHER_INST(53, PHI , PHINode ) // PHI node instruction
HANDLE_OTHER_INST(54, Call , CallInst ) // Call a function
HANDLE_OTHER_INST(55, Select , SelectInst ) // select instruction
HANDLE_OTHER_INST(56, UserOp1, Instruction) // May be used internally in a pass
HANDLE_OTHER_INST(57, UserOp2, Instruction) // Internal to passes only
HANDLE_OTHER_INST(58, VAArg , VAArgInst ) // vaarg instruction
HANDLE_OTHER_INST(59, ExtractElement, ExtractElementInst)// extract from vector
HANDLE_OTHER_INST(60, InsertElement, InsertElementInst) // insert into vector
HANDLE_OTHER_INST(61, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
HANDLE_OTHER_INST(62, ExtractValue, ExtractValueInst)// extract from aggregate
HANDLE_OTHER_INST(63, InsertValue, InsertValueInst) // insert into aggregate
HANDLE_OTHER_INST(64, LandingPad, LandingPadInst) // Landing pad instruction.
LAST_OTHER_INST(64)
#undef FIRST_TERM_INST
#undef HANDLE_TERM_INST
#undef LAST_TERM_INST
#undef FIRST_BINARY_INST
#undef HANDLE_BINARY_INST
#undef LAST_BINARY_INST
#undef FIRST_MEMORY_INST
#undef HANDLE_MEMORY_INST
#undef LAST_MEMORY_INST
#undef FIRST_CAST_INST
#undef HANDLE_CAST_INST
#undef LAST_CAST_INST
#undef FIRST_FUNCLETPAD_INST
#undef HANDLE_FUNCLETPAD_INST
#undef LAST_FUNCLETPAD_INST
#undef FIRST_OTHER_INST
#undef HANDLE_OTHER_INST
#undef LAST_OTHER_INST
#ifdef HANDLE_INST
#undef HANDLE_INST
#endif
//===- llvm/IR/Metadata.def - Metadata definitions --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Macros for running through all types of metadata.
//
//===----------------------------------------------------------------------===//
#if !(defined HANDLE_METADATA || defined HANDLE_METADATA_LEAF || \
defined HANDLE_METADATA_BRANCH || defined HANDLE_MDNODE_LEAF || \
defined HANDLE_MDNODE_LEAF_UNIQUABLE || defined HANDLE_MDNODE_BRANCH || \
defined HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE || \
defined HANDLE_SPECIALIZED_MDNODE_LEAF || \
defined HANDLE_SPECIALIZED_MDNODE_BRANCH)
#error "Missing macro definition of HANDLE_METADATA*"
#endif
// Handler for all types of metadata.
#ifndef HANDLE_METADATA
#define HANDLE_METADATA(CLASS)
#endif
// Handler for leaf nodes in the class hierarchy.
#ifndef HANDLE_METADATA_LEAF
#define HANDLE_METADATA_LEAF(CLASS) HANDLE_METADATA(CLASS)
#endif
// Handler for non-leaf nodes in the class hierarchy.
#ifndef HANDLE_METADATA_BRANCH
#define HANDLE_METADATA_BRANCH(CLASS) HANDLE_METADATA(CLASS)
#endif
// Handler for specialized and uniquable leaf nodes under MDNode. Defers to
// HANDLE_MDNODE_LEAF_UNIQUABLE if it's defined, otherwise to
// HANDLE_SPECIALIZED_MDNODE_LEAF.
#ifndef HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE
#ifdef HANDLE_MDNODE_LEAF_UNIQUABLE
#define HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(CLASS) \
HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS)
#else
#define HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(CLASS) \
HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS)
#endif
#endif
// Handler for leaf nodes under MDNode.
#ifndef HANDLE_MDNODE_LEAF_UNIQUABLE
#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) HANDLE_MDNODE_LEAF(CLASS)
#endif
// Handler for leaf nodes under MDNode.
#ifndef HANDLE_MDNODE_LEAF
#define HANDLE_MDNODE_LEAF(CLASS) HANDLE_METADATA_LEAF(CLASS)
#endif
// Handler for non-leaf nodes under MDNode.
#ifndef HANDLE_MDNODE_BRANCH
#define HANDLE_MDNODE_BRANCH(CLASS) HANDLE_METADATA_BRANCH(CLASS)
#endif
// Handler for specialized leaf nodes under MDNode.
#ifndef HANDLE_SPECIALIZED_MDNODE_LEAF
#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) HANDLE_MDNODE_LEAF(CLASS)
#endif
// Handler for specialized non-leaf nodes under MDNode.
#ifndef HANDLE_SPECIALIZED_MDNODE_BRANCH
#define HANDLE_SPECIALIZED_MDNODE_BRANCH(CLASS) HANDLE_MDNODE_BRANCH(CLASS)
#endif
HANDLE_METADATA_LEAF(MDString)
HANDLE_METADATA_BRANCH(ValueAsMetadata)
HANDLE_METADATA_LEAF(ConstantAsMetadata)
HANDLE_METADATA_LEAF(LocalAsMetadata)
HANDLE_METADATA_LEAF(DistinctMDOperandPlaceholder)
HANDLE_MDNODE_BRANCH(MDNode)
HANDLE_MDNODE_LEAF_UNIQUABLE(MDTuple)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DILocation)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIExpression)
HANDLE_SPECIALIZED_MDNODE_BRANCH(DINode)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(GenericDINode)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DISubrange)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIEnumerator)
HANDLE_SPECIALIZED_MDNODE_BRANCH(DIScope)
HANDLE_SPECIALIZED_MDNODE_BRANCH(DIType)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIBasicType)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIDerivedType)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DICompositeType)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DISubroutineType)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIFile)
HANDLE_SPECIALIZED_MDNODE_LEAF(DICompileUnit)
HANDLE_SPECIALIZED_MDNODE_BRANCH(DILocalScope)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DISubprogram)
HANDLE_SPECIALIZED_MDNODE_BRANCH(DILexicalBlockBase)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DILexicalBlock)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DILexicalBlockFile)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DINamespace)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIModule)
HANDLE_SPECIALIZED_MDNODE_BRANCH(DITemplateParameter)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DITemplateTypeParameter)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DITemplateValueParameter)
HANDLE_SPECIALIZED_MDNODE_BRANCH(DIVariable)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIGlobalVariable)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DILocalVariable)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIObjCProperty)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIImportedEntity)
HANDLE_SPECIALIZED_MDNODE_BRANCH(DIMacroNode)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacro)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacroFile)
#undef HANDLE_METADATA
#undef HANDLE_METADATA_LEAF
#undef HANDLE_METADATA_BRANCH
#undef HANDLE_MDNODE_LEAF
#undef HANDLE_MDNODE_LEAF_UNIQUABLE
#undef HANDLE_MDNODE_BRANCH
#undef HANDLE_SPECIALIZED_MDNODE_LEAF
#undef HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE
#undef HANDLE_SPECIALIZED_MDNODE_BRANCH
//===-- llvm/OperandTraits.h - OperandTraits class definition ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the traits classes that are handy for enforcing the correct
// layout of various User subclasses. It also provides the means for accessing
// the operands in the most efficient manner.
//
#ifndef LLVM_IR_OPERANDTRAITS_H
#define LLVM_IR_OPERANDTRAITS_H
#include "llvm/IR/User.h"
namespace llvm {
//===----------------------------------------------------------------------===//
// FixedNumOperand Trait Class
//===----------------------------------------------------------------------===//
/// FixedNumOperandTraits - determine the allocation regime of the Use array
/// when it is a prefix to the User object, and the number of Use objects is
/// known at compile time.
template <typename SubClass, unsigned ARITY>
struct FixedNumOperandTraits {
static Use *op_begin(SubClass* U) {
return reinterpret_cast<Use*>(U) - ARITY;
}
static Use *op_end(SubClass* U) {
return reinterpret_cast<Use*>(U);
}
static unsigned operands(const User*) {
return ARITY;
}
};
//===----------------------------------------------------------------------===//
// OptionalOperand Trait Class
//===----------------------------------------------------------------------===//
/// OptionalOperandTraits - when the number of operands may change at runtime.
/// Naturally it may only decrease, because the allocations may not change.
template <typename SubClass, unsigned ARITY = 1>
struct OptionalOperandTraits : public FixedNumOperandTraits<SubClass, ARITY> {
static unsigned operands(const User *U) {
return U->getNumOperands();
}
};
//===----------------------------------------------------------------------===//
// VariadicOperand Trait Class
//===----------------------------------------------------------------------===//
/// VariadicOperandTraits - determine the allocation regime of the Use array
/// when it is a prefix to the User object, and the number of Use objects is
/// only known at allocation time.
template <typename SubClass, unsigned MINARITY = 0>
struct VariadicOperandTraits {
static Use *op_begin(SubClass* U) {
return reinterpret_cast<Use*>(U) - static_cast<User*>(U)->getNumOperands();
}
static Use *op_end(SubClass* U) {
return reinterpret_cast<Use*>(U);
}
static unsigned operands(const User *U) {
return U->getNumOperands();
}
};
//===----------------------------------------------------------------------===//
// HungoffOperand Trait Class
//===----------------------------------------------------------------------===//
/// HungoffOperandTraits - determine the allocation regime of the Use array
/// when it is not a prefix to the User object, but allocated at an unrelated
/// heap address.
/// Assumes that the User subclass that is determined by this traits class
/// has an OperandList member of type User::op_iterator. [Note: this is now
/// trivially satisfied, because User has that member for historic reasons.]
///
/// This is the traits class that is needed when the Use array must be
/// resizable.
template <unsigned MINARITY = 1>
struct HungoffOperandTraits {
static Use *op_begin(User* U) {
return U->getOperandList();
}
static Use *op_end(User* U) {
return U->getOperandList() + U->getNumOperands();
}
static unsigned operands(const User *U) {
return U->getNumOperands();
}
};
/// Macro for generating in-class operand accessor declarations.
/// It should only be called in the public section of the interface.
///
#define DECLARE_TRANSPARENT_OPERAND_ACCESSORS(VALUECLASS) \
public: \
inline VALUECLASS *getOperand(unsigned) const; \
inline void setOperand(unsigned, VALUECLASS*); \
inline op_iterator op_begin(); \
inline const_op_iterator op_begin() const; \
inline op_iterator op_end(); \
inline const_op_iterator op_end() const; \
protected: \
template <int> inline Use &Op(); \
template <int> inline const Use &Op() const; \
public: \
inline unsigned getNumOperands() const
/// Macro for generating out-of-class operand accessor definitions
#define DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CLASS, VALUECLASS) \
CLASS::op_iterator CLASS::op_begin() { \
return OperandTraits<CLASS>::op_begin(this); \
} \
CLASS::const_op_iterator CLASS::op_begin() const { \
return OperandTraits<CLASS>::op_begin(const_cast<CLASS*>(this)); \
} \
CLASS::op_iterator CLASS::op_end() { \
return OperandTraits<CLASS>::op_end(this); \
} \
CLASS::const_op_iterator CLASS::op_end() const { \
return OperandTraits<CLASS>::op_end(const_cast<CLASS*>(this)); \
} \
VALUECLASS *CLASS::getOperand(unsigned i_nocapture) const { \
assert(i_nocapture < OperandTraits<CLASS>::operands(this) \
&& "getOperand() out of range!"); \
return cast_or_null<VALUECLASS>( \
OperandTraits<CLASS>::op_begin(const_cast<CLASS*>(this))[i_nocapture].get()); \
} \
void CLASS::setOperand(unsigned i_nocapture, VALUECLASS *Val_nocapture) { \
assert(i_nocapture < OperandTraits<CLASS>::operands(this) \
&& "setOperand() out of range!"); \
OperandTraits<CLASS>::op_begin(this)[i_nocapture] = Val_nocapture; \
} \
unsigned CLASS::getNumOperands() const { \
return OperandTraits<CLASS>::operands(this); \
} \
template <int Idx_nocapture> Use &CLASS::Op() { \
return this->OpFrom<Idx_nocapture>(this); \
} \
template <int Idx_nocapture> const Use &CLASS::Op() const { \
return this->OpFrom<Idx_nocapture>(this); \
}
} // End llvm namespace
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment