1 //===--- DeclID.h - ID number for deserialized declarations ----*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines DeclID class family to describe the deserialized 10 // declarations. The DeclID is widely used in AST via LazyDeclPtr, or calls to 11 // `ExternalASTSource::getExternalDecl`. It will be helpful for type safety to 12 // require the use of `DeclID` to explicit. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #ifndef LLVM_CLANG_AST_DECLID_H 17 #define LLVM_CLANG_AST_DECLID_H 18 19 #include "llvm/ADT/DenseMapInfo.h" 20 #include "llvm/ADT/iterator.h" 21 22 namespace clang { 23 24 /// Predefined declaration IDs. 25 /// 26 /// These declaration IDs correspond to predefined declarations in the AST 27 /// context, such as the NULL declaration ID. Such declarations are never 28 /// actually serialized, since they will be built by the AST context when 29 /// it is created. 30 enum PredefinedDeclIDs { 31 /// The NULL declaration. 32 PREDEF_DECL_NULL_ID = 0, 33 34 /// The translation unit. 35 PREDEF_DECL_TRANSLATION_UNIT_ID = 1, 36 37 /// The Objective-C 'id' type. 38 PREDEF_DECL_OBJC_ID_ID = 2, 39 40 /// The Objective-C 'SEL' type. 41 PREDEF_DECL_OBJC_SEL_ID = 3, 42 43 /// The Objective-C 'Class' type. 44 PREDEF_DECL_OBJC_CLASS_ID = 4, 45 46 /// The Objective-C 'Protocol' type. 47 PREDEF_DECL_OBJC_PROTOCOL_ID = 5, 48 49 /// The signed 128-bit integer type. 50 PREDEF_DECL_INT_128_ID = 6, 51 52 /// The unsigned 128-bit integer type. 53 PREDEF_DECL_UNSIGNED_INT_128_ID = 7, 54 55 /// The internal 'instancetype' typedef. 56 PREDEF_DECL_OBJC_INSTANCETYPE_ID = 8, 57 58 /// The internal '__builtin_va_list' typedef. 59 PREDEF_DECL_BUILTIN_VA_LIST_ID = 9, 60 61 /// The internal '__va_list_tag' struct, if any. 62 PREDEF_DECL_VA_LIST_TAG = 10, 63 64 /// The internal '__builtin_ms_va_list' typedef. 65 PREDEF_DECL_BUILTIN_MS_VA_LIST_ID = 11, 66 67 /// The predeclared '_GUID' struct. 68 PREDEF_DECL_BUILTIN_MS_GUID_ID = 12, 69 70 /// The extern "C" context. 71 PREDEF_DECL_EXTERN_C_CONTEXT_ID = 13, 72 73 /// The internal '__make_integer_seq' template. 74 PREDEF_DECL_MAKE_INTEGER_SEQ_ID = 14, 75 76 /// The internal '__NSConstantString' typedef. 77 PREDEF_DECL_CF_CONSTANT_STRING_ID = 15, 78 79 /// The internal '__NSConstantString' tag type. 80 PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID = 16, 81 82 /// The internal '__type_pack_element' template. 83 PREDEF_DECL_TYPE_PACK_ELEMENT_ID = 17, 84 }; 85 86 /// The number of declaration IDs that are predefined. 87 /// 88 /// For more information about predefined declarations, see the 89 /// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants. 90 const unsigned int NUM_PREDEF_DECL_IDS = 18; 91 92 /// GlobalDeclID means DeclID in the current ASTContext and LocalDeclID means 93 /// DeclID specific to a certain ModuleFile. Specially, in ASTWriter, the 94 /// LocalDeclID to the ModuleFile been writting is equal to the GlobalDeclID. 95 /// Outside the serializer, all the DeclID been used should be GlobalDeclID. 96 /// We can translate a LocalDeclID to the GlobalDeclID by 97 /// `ASTReader::getGlobalDeclID()`. 98 99 class DeclIDBase { 100 public: 101 /// An ID number that refers to a declaration in an AST file. 102 /// 103 /// The ID numbers of declarations are consecutive (in order of 104 /// discovery), with values below NUM_PREDEF_DECL_IDS being reserved. 105 /// At the start of a chain of precompiled headers, declaration ID 1 is 106 /// used for the translation unit declaration. 107 /// 108 /// DeclID should only be used directly in serialization. All other users 109 /// should use LocalDeclID or GlobalDeclID. 110 using DeclID = uint32_t; 111 112 protected: DeclIDBase()113 DeclIDBase() : ID(PREDEF_DECL_NULL_ID) {} DeclIDBase(DeclID ID)114 explicit DeclIDBase(DeclID ID) : ID(ID) {} 115 116 public: get()117 DeclID get() const { return ID; } 118 DeclID()119 explicit operator DeclID() const { return ID; } 120 PredefinedDeclIDs()121 explicit operator PredefinedDeclIDs() const { return (PredefinedDeclIDs)ID; } 122 isValid()123 bool isValid() const { return ID != PREDEF_DECL_NULL_ID; } 124 isInvalid()125 bool isInvalid() const { return ID == PREDEF_DECL_NULL_ID; } 126 127 friend bool operator==(const DeclIDBase &LHS, const DeclIDBase &RHS) { 128 return LHS.ID == RHS.ID; 129 } 130 friend bool operator!=(const DeclIDBase &LHS, const DeclIDBase &RHS) { 131 return LHS.ID != RHS.ID; 132 } 133 // We may sort the decl ID. 134 friend bool operator<(const DeclIDBase &LHS, const DeclIDBase &RHS) { 135 return LHS.ID < RHS.ID; 136 } 137 friend bool operator>(const DeclIDBase &LHS, const DeclIDBase &RHS) { 138 return LHS.ID > RHS.ID; 139 } 140 friend bool operator<=(const DeclIDBase &LHS, const DeclIDBase &RHS) { 141 return LHS.ID <= RHS.ID; 142 } 143 friend bool operator>=(const DeclIDBase &LHS, const DeclIDBase &RHS) { 144 return LHS.ID >= RHS.ID; 145 } 146 147 protected: 148 DeclID ID; 149 }; 150 151 class LocalDeclID : public DeclIDBase { 152 using Base = DeclIDBase; 153 154 public: LocalDeclID()155 LocalDeclID() : Base() {} LocalDeclID(PredefinedDeclIDs ID)156 LocalDeclID(PredefinedDeclIDs ID) : Base(ID) {} LocalDeclID(DeclID ID)157 explicit LocalDeclID(DeclID ID) : Base(ID) {} 158 159 LocalDeclID &operator++() { 160 ++ID; 161 return *this; 162 } 163 164 LocalDeclID operator++(int) { 165 LocalDeclID Ret = *this; 166 ++(*this); 167 return Ret; 168 } 169 }; 170 171 class GlobalDeclID : public DeclIDBase { 172 using Base = DeclIDBase; 173 174 public: GlobalDeclID()175 GlobalDeclID() : Base() {} GlobalDeclID(DeclID ID)176 explicit GlobalDeclID(DeclID ID) : Base(ID) {} 177 178 // For DeclIDIterator<GlobalDeclID> to be able to convert a GlobalDeclID 179 // to a LocalDeclID. LocalDeclID()180 explicit operator LocalDeclID() const { return LocalDeclID(this->ID); } 181 }; 182 183 /// A helper iterator adaptor to convert the iterators to 184 /// `SmallVector<SomeDeclID>` to the iterators to `SmallVector<OtherDeclID>`. 185 template <class FromTy, class ToTy> 186 class DeclIDIterator 187 : public llvm::iterator_adaptor_base<DeclIDIterator<FromTy, ToTy>, 188 const FromTy *, 189 std::forward_iterator_tag, ToTy> { 190 public: DeclIDIterator()191 DeclIDIterator() : DeclIDIterator::iterator_adaptor_base(nullptr) {} 192 DeclIDIterator(const FromTy * ID)193 DeclIDIterator(const FromTy *ID) 194 : DeclIDIterator::iterator_adaptor_base(ID) {} 195 196 ToTy operator*() const { return ToTy(*this->I); } 197 198 bool operator==(const DeclIDIterator &RHS) const { return this->I == RHS.I; } 199 }; 200 201 } // namespace clang 202 203 namespace llvm { 204 template <> struct DenseMapInfo<clang::GlobalDeclID> { 205 using GlobalDeclID = clang::GlobalDeclID; 206 using DeclID = GlobalDeclID::DeclID; 207 208 static GlobalDeclID getEmptyKey() { 209 return GlobalDeclID(DenseMapInfo<DeclID>::getEmptyKey()); 210 } 211 212 static GlobalDeclID getTombstoneKey() { 213 return GlobalDeclID(DenseMapInfo<DeclID>::getTombstoneKey()); 214 } 215 216 static unsigned getHashValue(const GlobalDeclID &Key) { 217 return DenseMapInfo<DeclID>::getHashValue(Key.get()); 218 } 219 220 static bool isEqual(const GlobalDeclID &L, const GlobalDeclID &R) { 221 return L == R; 222 } 223 }; 224 225 } // namespace llvm 226 227 #endif 228