clang API Documentation
00001 //===-- DeclContextInternals.h - DeclContext Representation -----*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the data structures used in the implementation 00011 // of DeclContext. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 #ifndef LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H 00015 #define LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H 00016 00017 #include "clang/AST/Decl.h" 00018 #include "clang/AST/DeclCXX.h" 00019 #include "clang/AST/DeclarationName.h" 00020 #include "llvm/ADT/DenseMap.h" 00021 #include "llvm/ADT/PointerIntPair.h" 00022 #include "llvm/ADT/PointerUnion.h" 00023 #include "llvm/ADT/SmallVector.h" 00024 #include <algorithm> 00025 00026 namespace clang { 00027 00028 class DependentDiagnostic; 00029 00030 /// \brief An array of decls optimized for the common case of only containing 00031 /// one entry. 00032 struct StoredDeclsList { 00033 00034 /// \brief When in vector form, this is what the Data pointer points to. 00035 typedef SmallVector<NamedDecl *, 4> DeclsTy; 00036 00037 /// \brief A collection of declarations, with a flag to indicate if we have 00038 /// further external declarations. 00039 typedef llvm::PointerIntPair<DeclsTy *, 1, bool> DeclsAndHasExternalTy; 00040 00041 /// \brief The stored data, which will be either a pointer to a NamedDecl, 00042 /// or a pointer to a vector with a flag to indicate if there are further 00043 /// external declarations. 00044 llvm::PointerUnion<NamedDecl*, DeclsAndHasExternalTy> Data; 00045 00046 public: 00047 StoredDeclsList() {} 00048 00049 StoredDeclsList(StoredDeclsList &&RHS) : Data(RHS.Data) { 00050 RHS.Data = (NamedDecl *)nullptr; 00051 } 00052 00053 ~StoredDeclsList() { 00054 // If this is a vector-form, free the vector. 00055 if (DeclsTy *Vector = getAsVector()) 00056 delete Vector; 00057 } 00058 00059 StoredDeclsList &operator=(StoredDeclsList &&RHS) { 00060 if (DeclsTy *Vector = getAsVector()) 00061 delete Vector; 00062 Data = RHS.Data; 00063 RHS.Data = (NamedDecl *)nullptr; 00064 return *this; 00065 } 00066 00067 bool isNull() const { return Data.isNull(); } 00068 00069 NamedDecl *getAsDecl() const { 00070 return Data.dyn_cast<NamedDecl *>(); 00071 } 00072 00073 DeclsAndHasExternalTy getAsVectorAndHasExternal() const { 00074 return Data.dyn_cast<DeclsAndHasExternalTy>(); 00075 } 00076 00077 DeclsTy *getAsVector() const { 00078 return getAsVectorAndHasExternal().getPointer(); 00079 } 00080 00081 bool hasExternalDecls() const { 00082 return getAsVectorAndHasExternal().getInt(); 00083 } 00084 00085 void setHasExternalDecls() { 00086 if (DeclsTy *Vec = getAsVector()) 00087 Data = DeclsAndHasExternalTy(Vec, true); 00088 else { 00089 DeclsTy *VT = new DeclsTy(); 00090 if (NamedDecl *OldD = getAsDecl()) 00091 VT->push_back(OldD); 00092 Data = DeclsAndHasExternalTy(VT, true); 00093 } 00094 } 00095 00096 void setOnlyValue(NamedDecl *ND) { 00097 assert(!getAsVector() && "Not inline"); 00098 Data = ND; 00099 // Make sure that Data is a plain NamedDecl* so we can use its address 00100 // at getLookupResult. 00101 assert(*(NamedDecl **)&Data == ND && 00102 "PointerUnion mangles the NamedDecl pointer!"); 00103 } 00104 00105 void remove(NamedDecl *D) { 00106 assert(!isNull() && "removing from empty list"); 00107 if (NamedDecl *Singleton = getAsDecl()) { 00108 assert(Singleton == D && "list is different singleton"); 00109 (void)Singleton; 00110 Data = (NamedDecl *)nullptr; 00111 return; 00112 } 00113 00114 DeclsTy &Vec = *getAsVector(); 00115 DeclsTy::iterator I = std::find(Vec.begin(), Vec.end(), D); 00116 assert(I != Vec.end() && "list does not contain decl"); 00117 Vec.erase(I); 00118 00119 assert(std::find(Vec.begin(), Vec.end(), D) 00120 == Vec.end() && "list still contains decl"); 00121 } 00122 00123 /// \brief Remove any declarations which were imported from an external 00124 /// AST source. 00125 void removeExternalDecls() { 00126 if (isNull()) { 00127 // Nothing to do. 00128 } else if (NamedDecl *Singleton = getAsDecl()) { 00129 if (Singleton->isFromASTFile()) 00130 *this = StoredDeclsList(); 00131 } else { 00132 DeclsTy &Vec = *getAsVector(); 00133 Vec.erase(std::remove_if(Vec.begin(), Vec.end(), 00134 std::mem_fun(&Decl::isFromASTFile)), 00135 Vec.end()); 00136 // Don't have any external decls any more. 00137 Data = DeclsAndHasExternalTy(&Vec, false); 00138 } 00139 } 00140 00141 /// getLookupResult - Return an array of all the decls that this list 00142 /// represents. 00143 DeclContext::lookup_result getLookupResult() { 00144 if (isNull()) 00145 return DeclContext::lookup_result(DeclContext::lookup_iterator(nullptr), 00146 DeclContext::lookup_iterator(nullptr)); 00147 00148 // If we have a single NamedDecl, return it. 00149 if (getAsDecl()) { 00150 assert(!isNull() && "Empty list isn't allowed"); 00151 00152 // Data is a raw pointer to a NamedDecl*, return it. 00153 void *Ptr = &Data; 00154 return DeclContext::lookup_result((NamedDecl**)Ptr, (NamedDecl**)Ptr+1); 00155 } 00156 00157 assert(getAsVector() && "Must have a vector at this point"); 00158 DeclsTy &Vector = *getAsVector(); 00159 00160 // Otherwise, we have a range result. 00161 return DeclContext::lookup_result(Vector.begin(), Vector.end()); 00162 } 00163 00164 /// HandleRedeclaration - If this is a redeclaration of an existing decl, 00165 /// replace the old one with D and return true. Otherwise return false. 00166 bool HandleRedeclaration(NamedDecl *D) { 00167 // Most decls only have one entry in their list, special case it. 00168 if (NamedDecl *OldD = getAsDecl()) { 00169 if (!D->declarationReplaces(OldD)) 00170 return false; 00171 setOnlyValue(D); 00172 return true; 00173 } 00174 00175 // Determine if this declaration is actually a redeclaration. 00176 DeclsTy &Vec = *getAsVector(); 00177 for (DeclsTy::iterator OD = Vec.begin(), ODEnd = Vec.end(); 00178 OD != ODEnd; ++OD) { 00179 NamedDecl *OldD = *OD; 00180 if (D->declarationReplaces(OldD)) { 00181 *OD = D; 00182 return true; 00183 } 00184 } 00185 00186 return false; 00187 } 00188 00189 /// AddSubsequentDecl - This is called on the second and later decl when it is 00190 /// not a redeclaration to merge it into the appropriate place in our list. 00191 /// 00192 void AddSubsequentDecl(NamedDecl *D) { 00193 assert(!isNull() && "don't AddSubsequentDecl when we have no decls"); 00194 00195 // If this is the second decl added to the list, convert this to vector 00196 // form. 00197 if (NamedDecl *OldD = getAsDecl()) { 00198 DeclsTy *VT = new DeclsTy(); 00199 VT->push_back(OldD); 00200 Data = DeclsAndHasExternalTy(VT, false); 00201 } 00202 00203 DeclsTy &Vec = *getAsVector(); 00204 00205 // Using directives end up in a special entry which contains only 00206 // other using directives, so all this logic is wasted for them. 00207 // But avoiding the logic wastes time in the far-more-common case 00208 // that we're *not* adding a new using directive. 00209 00210 // Tag declarations always go at the end of the list so that an 00211 // iterator which points at the first tag will start a span of 00212 // decls that only contains tags. 00213 if (D->hasTagIdentifierNamespace()) 00214 Vec.push_back(D); 00215 00216 // Resolved using declarations go at the front of the list so that 00217 // they won't show up in other lookup results. Unresolved using 00218 // declarations (which are always in IDNS_Using | IDNS_Ordinary) 00219 // follow that so that the using declarations will be contiguous. 00220 else if (D->getIdentifierNamespace() & Decl::IDNS_Using) { 00221 DeclsTy::iterator I = Vec.begin(); 00222 if (D->getIdentifierNamespace() != Decl::IDNS_Using) { 00223 while (I != Vec.end() && 00224 (*I)->getIdentifierNamespace() == Decl::IDNS_Using) 00225 ++I; 00226 } 00227 Vec.insert(I, D); 00228 00229 // All other declarations go at the end of the list, but before any 00230 // tag declarations. But we can be clever about tag declarations 00231 // because there can only ever be one in a scope. 00232 } else if (!Vec.empty() && Vec.back()->hasTagIdentifierNamespace()) { 00233 NamedDecl *TagD = Vec.back(); 00234 Vec.back() = D; 00235 Vec.push_back(TagD); 00236 } else 00237 Vec.push_back(D); 00238 } 00239 }; 00240 00241 class StoredDeclsMap 00242 : public llvm::SmallDenseMap<DeclarationName, StoredDeclsList, 4> { 00243 00244 public: 00245 static void DestroyAll(StoredDeclsMap *Map, bool Dependent); 00246 00247 private: 00248 friend class ASTContext; // walks the chain deleting these 00249 friend class DeclContext; 00250 llvm::PointerIntPair<StoredDeclsMap*, 1> Previous; 00251 }; 00252 00253 class DependentStoredDeclsMap : public StoredDeclsMap { 00254 public: 00255 DependentStoredDeclsMap() : FirstDiagnostic(nullptr) {} 00256 00257 private: 00258 friend class DependentDiagnostic; 00259 friend class DeclContext; // iterates over diagnostics 00260 00261 DependentDiagnostic *FirstDiagnostic; 00262 }; 00263 00264 } // end namespace clang 00265 00266 #endif