Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:32

0001 //===--- DeclID.h - ID number for deserialized declarations  ----*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines DeclID class family to describe the deserialized
0010 // declarations. The DeclID is widely used in AST via LazyDeclPtr, or calls to
0011 // `ExternalASTSource::getExternalDecl`. It will be helpful for type safety to
0012 // require the use of `DeclID` to explicit.
0013 //
0014 //===----------------------------------------------------------------------===//
0015 
0016 #ifndef LLVM_CLANG_AST_DECLID_H
0017 #define LLVM_CLANG_AST_DECLID_H
0018 
0019 #include "llvm/ADT/DenseMapInfo.h"
0020 #include "llvm/ADT/Hashing.h"
0021 #include "llvm/ADT/iterator.h"
0022 
0023 namespace clang {
0024 
0025 /// Predefined declaration IDs.
0026 ///
0027 /// These declaration IDs correspond to predefined declarations in the AST
0028 /// context, such as the NULL declaration ID. Such declarations are never
0029 /// actually serialized, since they will be built by the AST context when
0030 /// it is created.
0031 enum PredefinedDeclIDs {
0032   /// The NULL declaration.
0033   PREDEF_DECL_NULL_ID,
0034 
0035   /// The translation unit.
0036   PREDEF_DECL_TRANSLATION_UNIT_ID,
0037 
0038   /// The Objective-C 'id' type.
0039   PREDEF_DECL_OBJC_ID_ID,
0040 
0041   /// The Objective-C 'SEL' type.
0042   PREDEF_DECL_OBJC_SEL_ID,
0043 
0044   /// The Objective-C 'Class' type.
0045   PREDEF_DECL_OBJC_CLASS_ID,
0046 
0047   /// The Objective-C 'Protocol' type.
0048   PREDEF_DECL_OBJC_PROTOCOL_ID,
0049 
0050   /// The signed 128-bit integer type.
0051   PREDEF_DECL_INT_128_ID,
0052 
0053   /// The unsigned 128-bit integer type.
0054   PREDEF_DECL_UNSIGNED_INT_128_ID,
0055 
0056   /// The internal 'instancetype' typedef.
0057   PREDEF_DECL_OBJC_INSTANCETYPE_ID,
0058 
0059   /// The internal '__builtin_va_list' typedef.
0060   PREDEF_DECL_BUILTIN_VA_LIST_ID,
0061 
0062   /// The internal '__va_list_tag' struct, if any.
0063   PREDEF_DECL_VA_LIST_TAG,
0064 
0065   /// The internal '__builtin_ms_va_list' typedef.
0066   PREDEF_DECL_BUILTIN_MS_VA_LIST_ID,
0067 
0068   /// The predeclared '_GUID' struct.
0069   PREDEF_DECL_BUILTIN_MS_GUID_ID,
0070 
0071   /// The extern "C" context.
0072   PREDEF_DECL_EXTERN_C_CONTEXT_ID,
0073 
0074   /// The internal '__make_integer_seq' template.
0075   PREDEF_DECL_MAKE_INTEGER_SEQ_ID,
0076 
0077   /// The internal '__NSConstantString' typedef.
0078   PREDEF_DECL_CF_CONSTANT_STRING_ID,
0079 
0080   /// The internal '__NSConstantString' tag type.
0081   PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID,
0082 
0083   /// The internal '__type_pack_element' template.
0084   PREDEF_DECL_TYPE_PACK_ELEMENT_ID,
0085 
0086   /// The internal '__builtin_common_type' template.
0087   PREDEF_DECL_COMMON_TYPE_ID,
0088 
0089   /// The number of declaration IDs that are predefined.
0090   NUM_PREDEF_DECL_IDS
0091 };
0092 
0093 /// GlobalDeclID means DeclID in the current ASTContext and LocalDeclID means
0094 /// DeclID specific to a certain ModuleFile. Specially, in ASTWriter, the
0095 /// LocalDeclID to the ModuleFile been writting is equal to the GlobalDeclID.
0096 /// Outside the serializer, all the DeclID been used should be GlobalDeclID.
0097 /// We can translate a LocalDeclID to the GlobalDeclID by
0098 /// `ASTReader::getGlobalDeclID()`.
0099 
0100 class DeclIDBase {
0101 public:
0102   /// An ID number that refers to a declaration in an AST file.
0103   ///
0104   /// The ID numbers of declarations are consecutive (in order of
0105   /// discovery), with values below NUM_PREDEF_DECL_IDS being reserved.
0106   /// At the start of a chain of precompiled headers, declaration ID 1 is
0107   /// used for the translation unit declaration.
0108   ///
0109   /// DeclID should only be used directly in serialization. All other users
0110   /// should use LocalDeclID or GlobalDeclID.
0111   using DeclID = uint64_t;
0112 
0113 protected:
0114   DeclIDBase() : ID(PREDEF_DECL_NULL_ID) {}
0115   explicit DeclIDBase(DeclID ID) : ID(ID) {}
0116 
0117 public:
0118   DeclID getRawValue() const { return ID; }
0119 
0120   explicit operator DeclID() const { return ID; }
0121 
0122   explicit operator PredefinedDeclIDs() const { return (PredefinedDeclIDs)ID; }
0123 
0124   bool isValid() const { return ID != PREDEF_DECL_NULL_ID; }
0125 
0126   bool isInvalid() const { return ID == PREDEF_DECL_NULL_ID; }
0127 
0128   unsigned getModuleFileIndex() const { return ID >> 32; }
0129 
0130   unsigned getLocalDeclIndex() const;
0131 
0132   // The DeclID may be compared with predefined decl ID.
0133   friend bool operator==(const DeclIDBase &LHS, const DeclID &RHS) {
0134     return LHS.ID == RHS;
0135   }
0136   friend bool operator!=(const DeclIDBase &LHS, const DeclID &RHS) {
0137     return !operator==(LHS, RHS);
0138   }
0139   friend bool operator<(const DeclIDBase &LHS, const DeclID &RHS) {
0140     return LHS.ID < RHS;
0141   }
0142   friend bool operator<=(const DeclIDBase &LHS, const DeclID &RHS) {
0143     return LHS.ID <= RHS;
0144   }
0145   friend bool operator>(const DeclIDBase &LHS, const DeclID &RHS) {
0146     return LHS.ID > RHS;
0147   }
0148   friend bool operator>=(const DeclIDBase &LHS, const DeclID &RHS) {
0149     return LHS.ID >= RHS;
0150   }
0151 
0152   friend bool operator==(const DeclIDBase &LHS, const DeclIDBase &RHS) {
0153     return LHS.ID == RHS.ID;
0154   }
0155   friend bool operator!=(const DeclIDBase &LHS, const DeclIDBase &RHS) {
0156     return LHS.ID != RHS.ID;
0157   }
0158 
0159   // We may sort the decl ID.
0160   friend bool operator<(const DeclIDBase &LHS, const DeclIDBase &RHS) {
0161     return LHS.ID < RHS.ID;
0162   }
0163   friend bool operator>(const DeclIDBase &LHS, const DeclIDBase &RHS) {
0164     return LHS.ID > RHS.ID;
0165   }
0166   friend bool operator<=(const DeclIDBase &LHS, const DeclIDBase &RHS) {
0167     return LHS.ID <= RHS.ID;
0168   }
0169   friend bool operator>=(const DeclIDBase &LHS, const DeclIDBase &RHS) {
0170     return LHS.ID >= RHS.ID;
0171   }
0172 
0173 protected:
0174   DeclID ID;
0175 };
0176 
0177 class ASTWriter;
0178 class ASTReader;
0179 namespace serialization {
0180 class ModuleFile;
0181 } // namespace serialization
0182 
0183 class LocalDeclID : public DeclIDBase {
0184   using Base = DeclIDBase;
0185 
0186   LocalDeclID(PredefinedDeclIDs ID) : Base(ID) {}
0187   explicit LocalDeclID(DeclID ID) : Base(ID) {}
0188 
0189   // Every Decl ID is a local decl ID to the module being writing in ASTWriter.
0190   friend class ASTWriter;
0191   friend class GlobalDeclID;
0192   friend struct llvm::DenseMapInfo<clang::LocalDeclID>;
0193 
0194 public:
0195   LocalDeclID() : Base() {}
0196 
0197   static LocalDeclID get(ASTReader &Reader, serialization::ModuleFile &MF,
0198                          DeclID ID);
0199   static LocalDeclID get(ASTReader &Reader, serialization::ModuleFile &MF,
0200                          unsigned ModuleFileIndex, unsigned LocalDeclID);
0201 
0202   LocalDeclID &operator++() {
0203     ++ID;
0204     return *this;
0205   }
0206 
0207   LocalDeclID operator++(int) {
0208     LocalDeclID Ret = *this;
0209     ++(*this);
0210     return Ret;
0211   }
0212 };
0213 
0214 class GlobalDeclID : public DeclIDBase {
0215   using Base = DeclIDBase;
0216 
0217 public:
0218   GlobalDeclID() : Base() {}
0219   explicit GlobalDeclID(DeclID ID) : Base(ID) {}
0220 
0221   explicit GlobalDeclID(unsigned ModuleFileIndex, unsigned LocalID)
0222       : Base((DeclID)ModuleFileIndex << 32 | (DeclID)LocalID) {}
0223 
0224   // For DeclIDIterator<GlobalDeclID> to be able to convert a GlobalDeclID
0225   // to a LocalDeclID.
0226   explicit operator LocalDeclID() const { return LocalDeclID(this->ID); }
0227 };
0228 
0229 /// A helper iterator adaptor to convert the iterators to
0230 /// `SmallVector<SomeDeclID>` to the iterators to `SmallVector<OtherDeclID>`.
0231 template <class FromTy, class ToTy>
0232 class DeclIDIterator
0233     : public llvm::iterator_adaptor_base<DeclIDIterator<FromTy, ToTy>,
0234                                          const FromTy *,
0235                                          std::forward_iterator_tag, ToTy> {
0236 public:
0237   DeclIDIterator() : DeclIDIterator::iterator_adaptor_base(nullptr) {}
0238 
0239   DeclIDIterator(const FromTy *ID)
0240       : DeclIDIterator::iterator_adaptor_base(ID) {}
0241 
0242   ToTy operator*() const { return ToTy(*this->I); }
0243 
0244   bool operator==(const DeclIDIterator &RHS) const { return this->I == RHS.I; }
0245 };
0246 
0247 } // namespace clang
0248 
0249 namespace llvm {
0250 template <> struct DenseMapInfo<clang::GlobalDeclID> {
0251   using GlobalDeclID = clang::GlobalDeclID;
0252   using DeclID = GlobalDeclID::DeclID;
0253 
0254   static GlobalDeclID getEmptyKey() {
0255     return GlobalDeclID(DenseMapInfo<DeclID>::getEmptyKey());
0256   }
0257 
0258   static GlobalDeclID getTombstoneKey() {
0259     return GlobalDeclID(DenseMapInfo<DeclID>::getTombstoneKey());
0260   }
0261 
0262   static unsigned getHashValue(const GlobalDeclID &Key) {
0263     return DenseMapInfo<DeclID>::getHashValue(Key.getRawValue());
0264   }
0265 
0266   static bool isEqual(const GlobalDeclID &L, const GlobalDeclID &R) {
0267     return L == R;
0268   }
0269 };
0270 
0271 template <> struct DenseMapInfo<clang::LocalDeclID> {
0272   using LocalDeclID = clang::LocalDeclID;
0273   using DeclID = LocalDeclID::DeclID;
0274 
0275   static LocalDeclID getEmptyKey() {
0276     return LocalDeclID(DenseMapInfo<DeclID>::getEmptyKey());
0277   }
0278 
0279   static LocalDeclID getTombstoneKey() {
0280     return LocalDeclID(DenseMapInfo<DeclID>::getTombstoneKey());
0281   }
0282 
0283   static unsigned getHashValue(const LocalDeclID &Key) {
0284     return DenseMapInfo<DeclID>::getHashValue(Key.getRawValue());
0285   }
0286 
0287   static bool isEqual(const LocalDeclID &L, const LocalDeclID &R) {
0288     return L == R;
0289   }
0290 };
0291 
0292 } // namespace llvm
0293 
0294 #endif