clang API Documentation

DeclContextInternals.h
Go to the documentation of this file.
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