| // Part of the Crubit project, under the Apache License v2.0 with LLVM |
| // Exceptions. See /LICENSE for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| |
| #ifndef CRUBIT_LIFETIME_ANNOTATIONS_LIFETIME_H_ |
| #define CRUBIT_LIFETIME_ANNOTATIONS_LIFETIME_H_ |
| |
| #include <atomic> |
| #include <cassert> |
| #include <functional> |
| #include <ostream> |
| #include <string> |
| |
| #include "llvm/ADT/Hashing.h" |
| |
| namespace clang { |
| namespace tidy { |
| namespace lifetimes { |
| |
| // A lifetime variable or constant lifetime. |
| class Lifetime { |
| public: |
| // Creates an invalid lifetime. |
| // |
| // This is provided because containers need default constructors. It is not |
| // legal to perform any operations on an invalid lifetime except to copy or |
| // delete it. |
| // |
| // Use one of the static member functions below to create a valid lifetime. |
| Lifetime(); |
| |
| Lifetime(const Lifetime&) = default; |
| Lifetime& operator=(const Lifetime&) = default; |
| |
| // Creates a new lifetime variable. |
| static Lifetime CreateVariable(); |
| |
| // Returns the 'static lifetime constant. |
| static Lifetime Static(); |
| |
| // Creates a new local lifetime constant. |
| static Lifetime CreateLocal(); |
| |
| // Returns whether this lifetime is a lifetime variable. |
| bool IsVariable() const; |
| |
| // Returns whether this lifetime is a constant lifetime. |
| bool IsConstant() const; |
| |
| // Returns whether this lifetime is a local lifetime. |
| bool IsLocal() const; |
| |
| // Returns a unique numeric ID for the lifetime. |
| int Id() const { return id_; } |
| |
| // Returns a textual representation of the lifetime for debug logging. |
| std::string DebugString() const; |
| |
| bool operator==(Lifetime other) const { |
| assert(IsValid()); |
| assert(other.IsValid()); |
| return id_ == other.id_; |
| } |
| |
| bool operator!=(Lifetime other) const { return !(*this == other); } |
| |
| private: |
| explicit Lifetime(int id); |
| |
| static Lifetime InvalidEmpty(); |
| static Lifetime InvalidTombstone(); |
| |
| bool IsValid() const; |
| |
| friend class llvm::DenseMapInfo<Lifetime, void>; |
| friend class std::less<Lifetime>; |
| |
| int id_; |
| static std::atomic<int> next_variable_id_; |
| static std::atomic<int> next_local_id_; |
| }; |
| |
| std::ostream& operator<<(std::ostream& os, Lifetime lifetime); |
| |
| } // namespace lifetimes |
| } // namespace tidy |
| } // namespace clang |
| |
| namespace llvm { |
| |
| template <> |
| struct DenseMapInfo<clang::tidy::lifetimes::Lifetime, void> { |
| static clang::tidy::lifetimes::Lifetime getEmptyKey() { |
| return clang::tidy::lifetimes::Lifetime::InvalidEmpty(); |
| } |
| |
| static clang::tidy::lifetimes::Lifetime getTombstoneKey() { |
| return clang::tidy::lifetimes::Lifetime::InvalidTombstone(); |
| } |
| |
| static unsigned getHashValue(clang::tidy::lifetimes::Lifetime lifetime) { |
| return llvm::hash_value(lifetime.id_); |
| } |
| |
| static bool isEqual(clang::tidy::lifetimes::Lifetime lhs, |
| clang::tidy::lifetimes::Lifetime rhs) { |
| return lhs.id_ == rhs.id_; |
| } |
| }; |
| |
| } // namespace llvm |
| |
| namespace std { |
| |
| template <> |
| struct less<clang::tidy::lifetimes::Lifetime> { |
| bool operator()(const clang::tidy::lifetimes::Lifetime& l1, |
| const clang::tidy::lifetimes::Lifetime& l2) const { |
| return l1.id_ < l2.id_; |
| } |
| }; |
| |
| } // namespace std |
| |
| #endif // CRUBIT_LIFETIME_ANNOTATIONS_LIFETIME_H_ |