/usr/include/llvm-4.0/llvm/ADT/EpochTracker.h is in llvm-4.0-dev 1:4.0.1-10.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | //===- 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/abi-breaking.h"
#include "llvm/Config/llvm-config.h"
#include <cstdint>
namespace llvm {
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
/// \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; }
};
};
#else
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; }
};
};
#endif // LLVM_ENABLE_ABI_BREAKING_CHECKS
} // namespace llvm
#endif
|