xref: /freebsd/contrib/llvm-project/clang/include/clang/AST/DeclID.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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