saqut-compiler/llvm/include/clang/AST/DeclID.h

292 lines
8.5 KiB
C++

//===--- 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/Hashing.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,
/// The translation unit.
PREDEF_DECL_TRANSLATION_UNIT_ID,
/// The Objective-C 'id' type.
PREDEF_DECL_OBJC_ID_ID,
/// The Objective-C 'SEL' type.
PREDEF_DECL_OBJC_SEL_ID,
/// The Objective-C 'Class' type.
PREDEF_DECL_OBJC_CLASS_ID,
/// The Objective-C 'Protocol' type.
PREDEF_DECL_OBJC_PROTOCOL_ID,
/// The signed 128-bit integer type.
PREDEF_DECL_INT_128_ID,
/// The unsigned 128-bit integer type.
PREDEF_DECL_UNSIGNED_INT_128_ID,
/// The internal 'instancetype' typedef.
PREDEF_DECL_OBJC_INSTANCETYPE_ID,
/// The internal '__builtin_va_list' typedef.
PREDEF_DECL_BUILTIN_VA_LIST_ID,
/// The internal '__va_list_tag' struct, if any.
PREDEF_DECL_VA_LIST_TAG,
/// The internal '__builtin_ms_va_list' typedef.
PREDEF_DECL_BUILTIN_MS_VA_LIST_ID,
/// The predeclared '_GUID' struct.
PREDEF_DECL_BUILTIN_MS_GUID_ID,
/// The extern "C" context.
PREDEF_DECL_EXTERN_C_CONTEXT_ID,
/// The internal '__NSConstantString' typedef.
PREDEF_DECL_CF_CONSTANT_STRING_ID,
/// The internal '__NSConstantString' tag type.
PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID,
/// The predeclared 'type_info' struct.
PREDEF_DECL_BUILTIN_MS_TYPE_INFO_TAG_ID,
#define BuiltinTemplate(BTName) PREDEF_DECL##BTName##_ID,
#include "clang/Basic/BuiltinTemplates.inc"
/// The number of declaration IDs that are predefined.
NUM_PREDEF_DECL_IDS
};
/// 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 = uint64_t;
protected:
DeclIDBase() : ID(PREDEF_DECL_NULL_ID) {}
explicit DeclIDBase(DeclID ID) : ID(ID) {}
public:
DeclID getRawValue() 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; }
unsigned getModuleFileIndex() const { return ID >> 32; }
unsigned getLocalDeclIndex() const;
// The DeclID may be compared with predefined decl ID.
friend bool operator==(const DeclIDBase &LHS, const DeclID &RHS) {
return LHS.ID == RHS;
}
friend bool operator!=(const DeclIDBase &LHS, const DeclID &RHS) {
return !operator==(LHS, RHS);
}
friend bool operator<(const DeclIDBase &LHS, const DeclID &RHS) {
return LHS.ID < RHS;
}
friend bool operator<=(const DeclIDBase &LHS, const DeclID &RHS) {
return LHS.ID <= RHS;
}
friend bool operator>(const DeclIDBase &LHS, const DeclID &RHS) {
return LHS.ID > RHS;
}
friend bool operator>=(const DeclIDBase &LHS, const DeclID &RHS) {
return LHS.ID >= RHS;
}
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 ASTWriter;
class ASTReader;
namespace serialization {
class ModuleFile;
} // namespace serialization
class LocalDeclID : public DeclIDBase {
using Base = DeclIDBase;
LocalDeclID(PredefinedDeclIDs ID) : Base(ID) {}
explicit LocalDeclID(DeclID ID) : Base(ID) {}
// Every Decl ID is a local decl ID to the module being writing in ASTWriter.
friend class ASTWriter;
friend class GlobalDeclID;
friend struct llvm::DenseMapInfo<clang::LocalDeclID>;
public:
LocalDeclID() : Base() {}
static LocalDeclID get(ASTReader &Reader, serialization::ModuleFile &MF,
DeclID ID);
static LocalDeclID get(ASTReader &Reader, serialization::ModuleFile &MF,
unsigned ModuleFileIndex, unsigned LocalDeclID);
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) {}
explicit GlobalDeclID(unsigned ModuleFileIndex, unsigned LocalID)
: Base((DeclID)ModuleFileIndex << 32 | (DeclID)LocalID) {}
// 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.getRawValue());
}
static bool isEqual(const GlobalDeclID &L, const GlobalDeclID &R) {
return L == R;
}
};
template <> struct DenseMapInfo<clang::LocalDeclID> {
using LocalDeclID = clang::LocalDeclID;
using DeclID = LocalDeclID::DeclID;
static LocalDeclID getEmptyKey() {
return LocalDeclID(DenseMapInfo<DeclID>::getEmptyKey());
}
static LocalDeclID getTombstoneKey() {
return LocalDeclID(DenseMapInfo<DeclID>::getTombstoneKey());
}
static unsigned getHashValue(const LocalDeclID &Key) {
return DenseMapInfo<DeclID>::getHashValue(Key.getRawValue());
}
static bool isEqual(const LocalDeclID &L, const LocalDeclID &R) {
return L == R;
}
};
} // namespace llvm
#endif