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