blob: 614ba06b63860cdd13f7c1f2761c40231ca39275 [file] [log] [blame]
//===--- DeclID.h - ID number for deserialized declarations ----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines DeclID class family to describe the deserialized
// declarations. The DeclID is widely used in AST via LazyDeclPtr, or calls to
// `ExternalASTSource::getExternalDecl`. It will be helpful for type safety to
// require the use of `DeclID` to explicit.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_DECLID_H
#define LLVM_CLANG_AST_DECLID_H
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/iterator.h"
namespace clang {
/// Predefined declaration IDs.
///
/// These declaration IDs correspond to predefined declarations in the AST
/// context, such as the NULL declaration ID. Such declarations are never
/// actually serialized, since they will be built by the AST context when
/// it is created.
enum PredefinedDeclIDs {
/// The NULL declaration.
PREDEF_DECL_NULL_ID = 0,
/// The translation unit.
PREDEF_DECL_TRANSLATION_UNIT_ID = 1,
/// The Objective-C 'id' type.
PREDEF_DECL_OBJC_ID_ID = 2,
/// The Objective-C 'SEL' type.
PREDEF_DECL_OBJC_SEL_ID = 3,
/// The Objective-C 'Class' type.
PREDEF_DECL_OBJC_CLASS_ID = 4,
/// The Objective-C 'Protocol' type.
PREDEF_DECL_OBJC_PROTOCOL_ID = 5,
/// The signed 128-bit integer type.
PREDEF_DECL_INT_128_ID = 6,
/// The unsigned 128-bit integer type.
PREDEF_DECL_UNSIGNED_INT_128_ID = 7,
/// The internal 'instancetype' typedef.
PREDEF_DECL_OBJC_INSTANCETYPE_ID = 8,
/// The internal '__builtin_va_list' typedef.
PREDEF_DECL_BUILTIN_VA_LIST_ID = 9,
/// The internal '__va_list_tag' struct, if any.
PREDEF_DECL_VA_LIST_TAG = 10,
/// The internal '__builtin_ms_va_list' typedef.
PREDEF_DECL_BUILTIN_MS_VA_LIST_ID = 11,
/// The predeclared '_GUID' struct.
PREDEF_DECL_BUILTIN_MS_GUID_ID = 12,
/// The extern "C" context.
PREDEF_DECL_EXTERN_C_CONTEXT_ID = 13,
/// The internal '__make_integer_seq' template.
PREDEF_DECL_MAKE_INTEGER_SEQ_ID = 14,
/// The internal '__NSConstantString' typedef.
PREDEF_DECL_CF_CONSTANT_STRING_ID = 15,
/// The internal '__NSConstantString' tag type.
PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID = 16,
/// The internal '__type_pack_element' template.
PREDEF_DECL_TYPE_PACK_ELEMENT_ID = 17,
};
/// The number of declaration IDs that are predefined.
///
/// For more information about predefined declarations, see the
/// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants.
const unsigned int NUM_PREDEF_DECL_IDS = 18;
/// GlobalDeclID means DeclID in the current ASTContext and LocalDeclID means
/// DeclID specific to a certain ModuleFile. Specially, in ASTWriter, the
/// LocalDeclID to the ModuleFile been writting is equal to the GlobalDeclID.
/// Outside the serializer, all the DeclID been used should be GlobalDeclID.
/// We can translate a LocalDeclID to the GlobalDeclID by
/// `ASTReader::getGlobalDeclID()`.
class DeclIDBase {
public:
/// An ID number that refers to a declaration in an AST file.
///
/// The ID numbers of declarations are consecutive (in order of
/// discovery), with values below NUM_PREDEF_DECL_IDS being reserved.
/// At the start of a chain of precompiled headers, declaration ID 1 is
/// used for the translation unit declaration.
///
/// DeclID should only be used directly in serialization. All other users
/// should use LocalDeclID or GlobalDeclID.
using DeclID = uint32_t;
protected:
DeclIDBase() : ID(PREDEF_DECL_NULL_ID) {}
explicit DeclIDBase(DeclID ID) : ID(ID) {}
public:
DeclID get() const { return ID; }
explicit operator DeclID() const { return ID; }
explicit operator PredefinedDeclIDs() const { return (PredefinedDeclIDs)ID; }
bool isValid() const { return ID != PREDEF_DECL_NULL_ID; }
bool isInvalid() const { return ID == PREDEF_DECL_NULL_ID; }
friend bool operator==(const DeclIDBase &LHS, const DeclIDBase &RHS) {
return LHS.ID == RHS.ID;
}
friend bool operator!=(const DeclIDBase &LHS, const DeclIDBase &RHS) {
return LHS.ID != RHS.ID;
}
// We may sort the decl ID.
friend bool operator<(const DeclIDBase &LHS, const DeclIDBase &RHS) {
return LHS.ID < RHS.ID;
}
friend bool operator>(const DeclIDBase &LHS, const DeclIDBase &RHS) {
return LHS.ID > RHS.ID;
}
friend bool operator<=(const DeclIDBase &LHS, const DeclIDBase &RHS) {
return LHS.ID <= RHS.ID;
}
friend bool operator>=(const DeclIDBase &LHS, const DeclIDBase &RHS) {
return LHS.ID >= RHS.ID;
}
protected:
DeclID ID;
};
class LocalDeclID : public DeclIDBase {
using Base = DeclIDBase;
public:
LocalDeclID() : Base() {}
LocalDeclID(PredefinedDeclIDs ID) : Base(ID) {}
explicit LocalDeclID(DeclID ID) : Base(ID) {}
LocalDeclID &operator++() {
++ID;
return *this;
}
LocalDeclID operator++(int) {
LocalDeclID Ret = *this;
++(*this);
return Ret;
}
};
class GlobalDeclID : public DeclIDBase {
using Base = DeclIDBase;
public:
GlobalDeclID() : Base() {}
explicit GlobalDeclID(DeclID ID) : Base(ID) {}
// For DeclIDIterator<GlobalDeclID> to be able to convert a GlobalDeclID
// to a LocalDeclID.
explicit operator LocalDeclID() const { return LocalDeclID(this->ID); }
};
/// A helper iterator adaptor to convert the iterators to
/// `SmallVector<SomeDeclID>` to the iterators to `SmallVector<OtherDeclID>`.
template <class FromTy, class ToTy>
class DeclIDIterator
: public llvm::iterator_adaptor_base<DeclIDIterator<FromTy, ToTy>,
const FromTy *,
std::forward_iterator_tag, ToTy> {
public:
DeclIDIterator() : DeclIDIterator::iterator_adaptor_base(nullptr) {}
DeclIDIterator(const FromTy *ID)
: DeclIDIterator::iterator_adaptor_base(ID) {}
ToTy operator*() const { return ToTy(*this->I); }
bool operator==(const DeclIDIterator &RHS) const { return this->I == RHS.I; }
};
} // namespace clang
namespace llvm {
template <> struct DenseMapInfo<clang::GlobalDeclID> {
using GlobalDeclID = clang::GlobalDeclID;
using DeclID = GlobalDeclID::DeclID;
static GlobalDeclID getEmptyKey() {
return GlobalDeclID(DenseMapInfo<DeclID>::getEmptyKey());
}
static GlobalDeclID getTombstoneKey() {
return GlobalDeclID(DenseMapInfo<DeclID>::getTombstoneKey());
}
static unsigned getHashValue(const GlobalDeclID &Key) {
return DenseMapInfo<DeclID>::getHashValue(Key.get());
}
static bool isEqual(const GlobalDeclID &L, const GlobalDeclID &R) {
return L == R;
}
};
} // namespace llvm
#endif