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/DeclarationName.h" 00019 #include "clang/AST/DeclCXX.h" 00020 #include "llvm/ADT/PointerUnion.h" 00021 #include "llvm/ADT/SmallMap.h" 00022 #include "llvm/ADT/SmallVector.h" 00023 #include <algorithm> 00024 00025 namespace clang { 00026 00027 class DependentDiagnostic; 00028 00029 /// StoredDeclsList - This is an array of decls optimized a common case of only 00030 /// containing one entry. 00031 struct StoredDeclsList { 00032 00033 /// DeclsTy - When in vector form, this is what the Data pointer points to. 00034 typedef SmallVector<NamedDecl *, 4> DeclsTy; 00035 00036 /// \brief The stored data, which will be either a pointer to a NamedDecl, 00037 /// or a pointer to a vector. 00038 llvm::PointerUnion<NamedDecl *, DeclsTy *> Data; 00039 00040 public: 00041 StoredDeclsList() {} 00042 00043 StoredDeclsList(const StoredDeclsList &RHS) : Data(RHS.Data) { 00044 if (DeclsTy *RHSVec = RHS.getAsVector()) 00045 Data = new DeclsTy(*RHSVec); 00046 } 00047 00048 ~StoredDeclsList() { 00049 // If this is a vector-form, free the vector. 00050 if (DeclsTy *Vector = getAsVector()) 00051 delete Vector; 00052 } 00053 00054 StoredDeclsList &operator=(const StoredDeclsList &RHS) { 00055 if (DeclsTy *Vector = getAsVector()) 00056 delete Vector; 00057 Data = RHS.Data; 00058 if (DeclsTy *RHSVec = RHS.getAsVector()) 00059 Data = new DeclsTy(*RHSVec); 00060 return *this; 00061 } 00062 00063 bool isNull() const { return Data.isNull(); } 00064 00065 NamedDecl *getAsDecl() const { 00066 return Data.dyn_cast<NamedDecl *>(); 00067 } 00068 00069 DeclsTy *getAsVector() const { 00070 return Data.dyn_cast<DeclsTy *>(); 00071 } 00072 00073 void setOnlyValue(NamedDecl *ND) { 00074 assert(!getAsVector() && "Not inline"); 00075 Data = ND; 00076 // Make sure that Data is a plain NamedDecl* so we can use its address 00077 // at getLookupResult. 00078 assert(*(NamedDecl **)&Data == ND && 00079 "PointerUnion mangles the NamedDecl pointer!"); 00080 } 00081 00082 void remove(NamedDecl *D) { 00083 assert(!isNull() && "removing from empty list"); 00084 if (NamedDecl *Singleton = getAsDecl()) { 00085 assert(Singleton == D && "list is different singleton"); 00086 (void)Singleton; 00087 Data = (NamedDecl *)0; 00088 return; 00089 } 00090 00091 DeclsTy &Vec = *getAsVector(); 00092 DeclsTy::iterator I = std::find(Vec.begin(), Vec.end(), D); 00093 assert(I != Vec.end() && "list does not contain decl"); 00094 Vec.erase(I); 00095 00096 assert(std::find(Vec.begin(), Vec.end(), D) 00097 == Vec.end() && "list still contains decl"); 00098 } 00099 00100 /// getLookupResult - Return an array of all the decls that this list 00101 /// represents. 00102 DeclContext::lookup_result getLookupResult() { 00103 if (isNull()) 00104 return DeclContext::lookup_result(DeclContext::lookup_iterator(0), 00105 DeclContext::lookup_iterator(0)); 00106 00107 // If we have a single NamedDecl, return it. 00108 if (getAsDecl()) { 00109 assert(!isNull() && "Empty list isn't allowed"); 00110 00111 // Data is a raw pointer to a NamedDecl*, return it. 00112 void *Ptr = &Data; 00113 return DeclContext::lookup_result((NamedDecl**)Ptr, (NamedDecl**)Ptr+1); 00114 } 00115 00116 assert(getAsVector() && "Must have a vector at this point"); 00117 DeclsTy &Vector = *getAsVector(); 00118 00119 // Otherwise, we have a range result. 00120 return DeclContext::lookup_result(&Vector[0], &Vector[0]+Vector.size()); 00121 } 00122 00123 /// HandleRedeclaration - If this is a redeclaration of an existing decl, 00124 /// replace the old one with D and return true. Otherwise return false. 00125 bool HandleRedeclaration(NamedDecl *D) { 00126 // Most decls only have one entry in their list, special case it. 00127 if (NamedDecl *OldD = getAsDecl()) { 00128 if (!D->declarationReplaces(OldD)) 00129 return false; 00130 setOnlyValue(D); 00131 return true; 00132 } 00133 00134 // Determine if this declaration is actually a redeclaration. 00135 DeclsTy &Vec = *getAsVector(); 00136 for (DeclsTy::iterator OD = Vec.begin(), ODEnd = Vec.end(); 00137 OD != ODEnd; ++OD) { 00138 NamedDecl *OldD = *OD; 00139 if (D->declarationReplaces(OldD)) { 00140 *OD = D; 00141 return true; 00142 } 00143 } 00144 00145 return false; 00146 } 00147 00148 /// AddSubsequentDecl - This is called on the second and later decl when it is 00149 /// not a redeclaration to merge it into the appropriate place in our list. 00150 /// 00151 void AddSubsequentDecl(NamedDecl *D) { 00152 // If this is the second decl added to the list, convert this to vector 00153 // form. 00154 if (NamedDecl *OldD = getAsDecl()) { 00155 DeclsTy *VT = new DeclsTy(); 00156 VT->push_back(OldD); 00157 Data = VT; 00158 } 00159 00160 DeclsTy &Vec = *getAsVector(); 00161 00162 // Using directives end up in a special entry which contains only 00163 // other using directives, so all this logic is wasted for them. 00164 // But avoiding the logic wastes time in the far-more-common case 00165 // that we're *not* adding a new using directive. 00166 00167 // Tag declarations always go at the end of the list so that an 00168 // iterator which points at the first tag will start a span of 00169 // decls that only contains tags. 00170 if (D->hasTagIdentifierNamespace()) 00171 Vec.push_back(D); 00172 00173 // Resolved using declarations go at the front of the list so that 00174 // they won't show up in other lookup results. Unresolved using 00175 // declarations (which are always in IDNS_Using | IDNS_Ordinary) 00176 // follow that so that the using declarations will be contiguous. 00177 else if (D->getIdentifierNamespace() & Decl::IDNS_Using) { 00178 DeclsTy::iterator I = Vec.begin(); 00179 if (D->getIdentifierNamespace() != Decl::IDNS_Using) { 00180 while (I != Vec.end() && 00181 (*I)->getIdentifierNamespace() == Decl::IDNS_Using) 00182 ++I; 00183 } 00184 Vec.insert(I, D); 00185 00186 // All other declarations go at the end of the list, but before any 00187 // tag declarations. But we can be clever about tag declarations 00188 // because there can only ever be one in a scope. 00189 } else if (Vec.back()->hasTagIdentifierNamespace()) { 00190 NamedDecl *TagD = Vec.back(); 00191 Vec.back() = D; 00192 Vec.push_back(TagD); 00193 } else 00194 Vec.push_back(D); 00195 } 00196 }; 00197 00198 class StoredDeclsMap 00199 : public llvm::SmallMap<DeclarationName, StoredDeclsList, 4> { 00200 00201 public: 00202 static void DestroyAll(StoredDeclsMap *Map, bool Dependent); 00203 00204 private: 00205 friend class ASTContext; // walks the chain deleting these 00206 friend class DeclContext; 00207 llvm::PointerIntPair<StoredDeclsMap*, 1> Previous; 00208 }; 00209 00210 class DependentStoredDeclsMap : public StoredDeclsMap { 00211 public: 00212 DependentStoredDeclsMap() : FirstDiagnostic(0) {} 00213 00214 private: 00215 friend class DependentDiagnostic; 00216 friend class DeclContext; // iterates over diagnostics 00217 00218 DependentDiagnostic *FirstDiagnostic; 00219 }; 00220 00221 } // end namespace clang 00222 00223 #endif