DeclContextInternals.h revision 207619
1//===-- DeclContextInternals.h - DeclContext Representation -----*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines the data structures used in the implementation 11// of DeclContext. 12// 13//===----------------------------------------------------------------------===// 14#ifndef LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H 15#define LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H 16 17#include "clang/AST/Decl.h" 18#include "clang/AST/DeclarationName.h" 19#include "clang/AST/DeclCXX.h" 20#include "llvm/ADT/DenseMap.h" 21#include "llvm/ADT/PointerUnion.h" 22#include "llvm/ADT/SmallVector.h" 23#include <algorithm> 24 25namespace clang { 26 27class DependentDiagnostic; 28 29/// StoredDeclsList - This is an array of decls optimized a common case of only 30/// containing one entry. 31struct StoredDeclsList { 32 /// The kind of data encoded in this list. 33 enum DataKind { 34 /// \brief The data is a NamedDecl*. 35 DK_Decl = 0, 36 /// \brief The data is a declaration ID (an unsigned value), 37 /// shifted left by 2 bits. 38 DK_DeclID = 1, 39 /// \brief The data is a pointer to a vector (of type VectorTy) 40 /// that contains declarations. 41 DK_Decl_Vector = 2, 42 /// \brief The data is a pointer to a vector (of type VectorTy) 43 /// that contains declaration ID. 44 DK_ID_Vector = 3 45 }; 46 47 /// VectorTy - When in vector form, this is what the Data pointer points to. 48 typedef llvm::SmallVector<uintptr_t, 4> VectorTy; 49 50 /// \brief The stored data, which will be either a declaration ID, a 51 /// pointer to a NamedDecl, or a pointer to a vector. 52 uintptr_t Data; 53 54public: 55 StoredDeclsList() : Data(0) {} 56 57 StoredDeclsList(const StoredDeclsList &RHS) : Data(RHS.Data) { 58 if (VectorTy *RHSVec = RHS.getAsVector()) { 59 VectorTy *New = new VectorTy(*RHSVec); 60 Data = reinterpret_cast<uintptr_t>(New) | (Data & 0x03); 61 } 62 } 63 64 ~StoredDeclsList() { 65 // If this is a vector-form, free the vector. 66 if (VectorTy *Vector = getAsVector()) 67 delete Vector; 68 } 69 70 StoredDeclsList &operator=(const StoredDeclsList &RHS) { 71 if (VectorTy *Vector = getAsVector()) 72 delete Vector; 73 Data = RHS.Data; 74 if (VectorTy *RHSVec = RHS.getAsVector()) { 75 VectorTy *New = new VectorTy(*RHSVec); 76 Data = reinterpret_cast<uintptr_t>(New) | (Data & 0x03); 77 } 78 return *this; 79 } 80 81 bool isNull() const { return (Data & ~0x03) == 0; } 82 83 NamedDecl *getAsDecl() const { 84 if ((Data & 0x03) != DK_Decl) 85 return 0; 86 87 return reinterpret_cast<NamedDecl *>(Data & ~0x03); 88 } 89 90 VectorTy *getAsVector() const { 91 if ((Data & 0x03) != DK_ID_Vector && (Data & 0x03) != DK_Decl_Vector) 92 return 0; 93 94 return reinterpret_cast<VectorTy *>(Data & ~0x03); 95 } 96 97 void setOnlyValue(NamedDecl *ND) { 98 assert(!getAsVector() && "Not inline"); 99 Data = reinterpret_cast<uintptr_t>(ND); 100 } 101 102 void setFromDeclIDs(const llvm::SmallVectorImpl<unsigned> &Vec) { 103 if (Vec.size() > 1) { 104 VectorTy *Vector = getAsVector(); 105 if (!Vector) { 106 Vector = new VectorTy; 107 Data = reinterpret_cast<uintptr_t>(Vector) | DK_ID_Vector; 108 } 109 110 Vector->resize(Vec.size()); 111 std::copy(Vec.begin(), Vec.end(), Vector->begin()); 112 return; 113 } 114 115 if (VectorTy *Vector = getAsVector()) 116 delete Vector; 117 118 if (Vec.empty()) 119 Data = 0; 120 else 121 Data = (Vec[0] << 2) | DK_DeclID; 122 } 123 124 /// \brief Force the stored declarations list to contain actual 125 /// declarations. 126 /// 127 /// This routine will resolve any declaration IDs for declarations 128 /// that may not yet have been loaded from external storage. 129 void materializeDecls(ASTContext &Context); 130 131 bool hasDeclarationIDs() const { 132 DataKind DK = (DataKind)(Data & 0x03); 133 return DK == DK_DeclID || DK == DK_ID_Vector; 134 } 135 136 void remove(NamedDecl *D) { 137 assert(!isNull() && "removing from empty list"); 138 if (NamedDecl *Singleton = getAsDecl()) { 139 assert(Singleton == D && "list is different singleton"); 140 (void)Singleton; 141 Data = 0; 142 return; 143 } 144 145 VectorTy &Vec = *getAsVector(); 146 VectorTy::iterator I = std::find(Vec.begin(), Vec.end(), 147 reinterpret_cast<uintptr_t>(D)); 148 assert(I != Vec.end() && "list does not contain decl"); 149 Vec.erase(I); 150 151 assert(std::find(Vec.begin(), Vec.end(), reinterpret_cast<uintptr_t>(D)) 152 == Vec.end() && "list still contains decl"); 153 } 154 155 /// getLookupResult - Return an array of all the decls that this list 156 /// represents. 157 DeclContext::lookup_result getLookupResult(ASTContext &Context) { 158 if (isNull()) 159 return DeclContext::lookup_result(0, 0); 160 161 if (hasDeclarationIDs()) 162 materializeDecls(Context); 163 164 // If we have a single NamedDecl, return it. 165 if (getAsDecl()) { 166 assert(!isNull() && "Empty list isn't allowed"); 167 168 // Data is a raw pointer to a NamedDecl*, return it. 169 void *Ptr = &Data; 170 return DeclContext::lookup_result((NamedDecl**)Ptr, (NamedDecl**)Ptr+1); 171 } 172 173 assert(getAsVector() && "Must have a vector at this point"); 174 VectorTy &Vector = *getAsVector(); 175 176 // Otherwise, we have a range result. 177 return DeclContext::lookup_result((NamedDecl **)&Vector[0], 178 (NamedDecl **)&Vector[0]+Vector.size()); 179 } 180 181 /// HandleRedeclaration - If this is a redeclaration of an existing decl, 182 /// replace the old one with D and return true. Otherwise return false. 183 bool HandleRedeclaration(ASTContext &Context, NamedDecl *D) { 184 if (hasDeclarationIDs()) 185 materializeDecls(Context); 186 187 // Most decls only have one entry in their list, special case it. 188 if (NamedDecl *OldD = getAsDecl()) { 189 if (!D->declarationReplaces(OldD)) 190 return false; 191 setOnlyValue(D); 192 return true; 193 } 194 195 // Determine if this declaration is actually a redeclaration. 196 VectorTy &Vec = *getAsVector(); 197 for (VectorTy::iterator OD = Vec.begin(), ODEnd = Vec.end(); 198 OD != ODEnd; ++OD) { 199 NamedDecl *OldD = reinterpret_cast<NamedDecl *>(*OD); 200 if (D->declarationReplaces(OldD)) { 201 *OD = reinterpret_cast<uintptr_t>(D); 202 return true; 203 } 204 } 205 206 return false; 207 } 208 209 /// AddSubsequentDecl - This is called on the second and later decl when it is 210 /// not a redeclaration to merge it into the appropriate place in our list. 211 /// 212 void AddSubsequentDecl(NamedDecl *D) { 213 assert(!hasDeclarationIDs() && "Must materialize before adding decls"); 214 215 // If this is the second decl added to the list, convert this to vector 216 // form. 217 if (NamedDecl *OldD = getAsDecl()) { 218 VectorTy *VT = new VectorTy(); 219 VT->push_back(reinterpret_cast<uintptr_t>(OldD)); 220 Data = reinterpret_cast<uintptr_t>(VT) | DK_Decl_Vector; 221 } 222 223 VectorTy &Vec = *getAsVector(); 224 225 // Using directives end up in a special entry which contains only 226 // other using directives, so all this logic is wasted for them. 227 // But avoiding the logic wastes time in the far-more-common case 228 // that we're *not* adding a new using directive. 229 230 // Tag declarations always go at the end of the list so that an 231 // iterator which points at the first tag will start a span of 232 // decls that only contains tags. 233 if (D->hasTagIdentifierNamespace()) 234 Vec.push_back(reinterpret_cast<uintptr_t>(D)); 235 236 // Resolved using declarations go at the front of the list so that 237 // they won't show up in other lookup results. Unresolved using 238 // declarations (which are always in IDNS_Using | IDNS_Ordinary) 239 // follow that so that the using declarations will be contiguous. 240 else if (D->getIdentifierNamespace() & Decl::IDNS_Using) { 241 VectorTy::iterator I = Vec.begin(); 242 if (D->getIdentifierNamespace() != Decl::IDNS_Using) { 243 while (I != Vec.end() && 244 reinterpret_cast<NamedDecl *>(*I) 245 ->getIdentifierNamespace() == Decl::IDNS_Using) 246 ++I; 247 } 248 Vec.insert(I, reinterpret_cast<uintptr_t>(D)); 249 250 // All other declarations go at the end of the list, but before any 251 // tag declarations. But we can be clever about tag declarations 252 // because there can only ever be one in a scope. 253 } else if (reinterpret_cast<NamedDecl *>(Vec.back()) 254 ->hasTagIdentifierNamespace()) { 255 uintptr_t TagD = Vec.back(); 256 Vec.back() = reinterpret_cast<uintptr_t>(D); 257 Vec.push_back(TagD); 258 } else 259 Vec.push_back(reinterpret_cast<uintptr_t>(D)); 260 } 261}; 262 263class StoredDeclsMap 264 : public llvm::DenseMap<DeclarationName, StoredDeclsList> { 265 266public: 267 static void DestroyAll(StoredDeclsMap *Map, bool Dependent); 268 269private: 270 friend class ASTContext; // walks the chain deleting these 271 friend class DeclContext; 272 llvm::PointerIntPair<StoredDeclsMap*, 1> Previous; 273}; 274 275class DependentStoredDeclsMap : public StoredDeclsMap { 276public: 277 DependentStoredDeclsMap() : FirstDiagnostic(0) {} 278 279private: 280 friend class DependentDiagnostic; 281 friend class DeclContext; // iterates over diagnostics 282 283 DependentDiagnostic *FirstDiagnostic; 284}; 285 286} // end namespace clang 287 288#endif 289