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