clang API Documentation

ExternalASTSource.h
Go to the documentation of this file.
00001 //===--- ExternalASTSource.h - Abstract External AST Interface --*- 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 ExternalASTSource interface, which enables
00011 //  construction of AST nodes from some external source.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 #ifndef LLVM_CLANG_AST_EXTERNALASTSOURCE_H
00015 #define LLVM_CLANG_AST_EXTERNALASTSOURCE_H
00016 
00017 #include "clang/AST/CharUnits.h"
00018 #include "clang/AST/DeclBase.h"
00019 #include "llvm/ADT/DenseMap.h"
00020 
00021 namespace clang {
00022 
00023 class ASTConsumer;
00024 class CXXBaseSpecifier;
00025 class DeclarationName;
00026 class ExternalSemaSource; // layering violation required for downcasting
00027 class FieldDecl;
00028 class Module;
00029 class NamedDecl;
00030 class RecordDecl;
00031 class Selector;
00032 class Stmt;
00033 class TagDecl;
00034 
00035 /// \brief Enumeration describing the result of loading information from
00036 /// an external source.
00037 enum ExternalLoadResult {
00038   /// \brief Loading the external information has succeeded.
00039   ELR_Success,
00040   
00041   /// \brief Loading the external information has failed.
00042   ELR_Failure,
00043   
00044   /// \brief The external information has already been loaded, and therefore
00045   /// no additional processing is required.
00046   ELR_AlreadyLoaded
00047 };
00048 
00049 /// \brief Abstract interface for external sources of AST nodes.
00050 ///
00051 /// External AST sources provide AST nodes constructed from some
00052 /// external source, such as a precompiled header. External AST
00053 /// sources can resolve types and declarations from abstract IDs into
00054 /// actual type and declaration nodes, and read parts of declaration
00055 /// contexts.
00056 class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
00057   /// Generation number for this external AST source. Must be increased
00058   /// whenever we might have added new redeclarations for existing decls.
00059   uint32_t CurrentGeneration;
00060 
00061   /// \brief Whether this AST source also provides information for
00062   /// semantic analysis.
00063   bool SemaSource;
00064 
00065   friend class ExternalSemaSource;
00066 
00067 public:
00068   ExternalASTSource() : CurrentGeneration(0), SemaSource(false) { }
00069 
00070   virtual ~ExternalASTSource();
00071 
00072   /// \brief RAII class for safely pairing a StartedDeserializing call
00073   /// with FinishedDeserializing.
00074   class Deserializing {
00075     ExternalASTSource *Source;
00076   public:
00077     explicit Deserializing(ExternalASTSource *source) : Source(source) {
00078       assert(Source);
00079       Source->StartedDeserializing();
00080     }
00081     ~Deserializing() {
00082       Source->FinishedDeserializing();
00083     }
00084   };
00085 
00086   /// \brief Get the current generation of this AST source. This number
00087   /// is incremented each time the AST source lazily extends an existing
00088   /// entity.
00089   uint32_t getGeneration() const { return CurrentGeneration; }
00090 
00091   /// \brief Resolve a declaration ID into a declaration, potentially
00092   /// building a new declaration.
00093   ///
00094   /// This method only needs to be implemented if the AST source ever
00095   /// passes back decl sets as VisibleDeclaration objects.
00096   ///
00097   /// The default implementation of this method is a no-op.
00098   virtual Decl *GetExternalDecl(uint32_t ID);
00099 
00100   /// \brief Resolve a selector ID into a selector.
00101   ///
00102   /// This operation only needs to be implemented if the AST source
00103   /// returns non-zero for GetNumKnownSelectors().
00104   ///
00105   /// The default implementation of this method is a no-op.
00106   virtual Selector GetExternalSelector(uint32_t ID);
00107 
00108   /// \brief Returns the number of selectors known to the external AST
00109   /// source.
00110   ///
00111   /// The default implementation of this method is a no-op.
00112   virtual uint32_t GetNumExternalSelectors();
00113 
00114   /// \brief Resolve the offset of a statement in the decl stream into
00115   /// a statement.
00116   ///
00117   /// This operation is meant to be used via a LazyOffsetPtr.  It only
00118   /// needs to be implemented if the AST source uses methods like
00119   /// FunctionDecl::setLazyBody when building decls.
00120   ///
00121   /// The default implementation of this method is a no-op.
00122   virtual Stmt *GetExternalDeclStmt(uint64_t Offset);
00123 
00124   /// \brief Resolve the offset of a set of C++ base specifiers in the decl
00125   /// stream into an array of specifiers.
00126   ///
00127   /// The default implementation of this method is a no-op.
00128   virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);
00129 
00130   /// \brief Update an out-of-date identifier.
00131   virtual void updateOutOfDateIdentifier(IdentifierInfo &II) { }
00132 
00133   /// \brief Find all declarations with the given name in the given context,
00134   /// and add them to the context by calling SetExternalVisibleDeclsForName
00135   /// or SetNoExternalVisibleDeclsForName.
00136   /// \return \c true if any declarations might have been found, \c false if
00137   /// we definitely have no declarations with tbis name.
00138   ///
00139   /// The default implementation of this method is a no-op returning \c false.
00140   virtual bool
00141   FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name);
00142 
00143   /// \brief Ensures that the table of all visible declarations inside this
00144   /// context is up to date.
00145   ///
00146   /// The default implementation of this function is a no-op.
00147   virtual void completeVisibleDeclsMap(const DeclContext *DC);
00148 
00149   /// \brief Retrieve the module that corresponds to the given module ID.
00150   virtual Module *getModule(unsigned ID) { return nullptr; }
00151 
00152   /// \brief Finds all declarations lexically contained within the given
00153   /// DeclContext, after applying an optional filter predicate.
00154   ///
00155   /// \param isKindWeWant a predicate function that returns true if the passed
00156   /// declaration kind is one we are looking for. If NULL, all declarations
00157   /// are returned.
00158   ///
00159   /// \return an indication of whether the load succeeded or failed.
00160   ///
00161   /// The default implementation of this method is a no-op.
00162   virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
00163                                         bool (*isKindWeWant)(Decl::Kind),
00164                                         SmallVectorImpl<Decl*> &Result);
00165 
00166   /// \brief Finds all declarations lexically contained within the given
00167   /// DeclContext.
00168   ///
00169   /// \return true if an error occurred
00170   ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
00171                                 SmallVectorImpl<Decl*> &Result) {
00172     return FindExternalLexicalDecls(DC, nullptr, Result);
00173   }
00174 
00175   template <typename DeclTy>
00176   ExternalLoadResult FindExternalLexicalDeclsBy(const DeclContext *DC,
00177                                   SmallVectorImpl<Decl*> &Result) {
00178     return FindExternalLexicalDecls(DC, DeclTy::classofKind, Result);
00179   }
00180 
00181   /// \brief Get the decls that are contained in a file in the Offset/Length
00182   /// range. \p Length can be 0 to indicate a point at \p Offset instead of
00183   /// a range.
00184   virtual void FindFileRegionDecls(FileID File, unsigned Offset,
00185                                    unsigned Length,
00186                                    SmallVectorImpl<Decl *> &Decls);
00187 
00188   /// \brief Gives the external AST source an opportunity to complete
00189   /// the redeclaration chain for a declaration. Called each time we
00190   /// need the most recent declaration of a declaration after the
00191   /// generation count is incremented.
00192   virtual void CompleteRedeclChain(const Decl *D);
00193 
00194   /// \brief Gives the external AST source an opportunity to complete
00195   /// an incomplete type.
00196   virtual void CompleteType(TagDecl *Tag);
00197 
00198   /// \brief Gives the external AST source an opportunity to complete an
00199   /// incomplete Objective-C class.
00200   ///
00201   /// This routine will only be invoked if the "externally completed" bit is
00202   /// set on the ObjCInterfaceDecl via the function
00203   /// \c ObjCInterfaceDecl::setExternallyCompleted().
00204   virtual void CompleteType(ObjCInterfaceDecl *Class);
00205 
00206   /// \brief Loads comment ranges.
00207   virtual void ReadComments();
00208 
00209   /// \brief Notify ExternalASTSource that we started deserialization of
00210   /// a decl or type so until FinishedDeserializing is called there may be
00211   /// decls that are initializing. Must be paired with FinishedDeserializing.
00212   ///
00213   /// The default implementation of this method is a no-op.
00214   virtual void StartedDeserializing();
00215 
00216   /// \brief Notify ExternalASTSource that we finished the deserialization of
00217   /// a decl or type. Must be paired with StartedDeserializing.
00218   ///
00219   /// The default implementation of this method is a no-op.
00220   virtual void FinishedDeserializing();
00221 
00222   /// \brief Function that will be invoked when we begin parsing a new
00223   /// translation unit involving this external AST source.
00224   ///
00225   /// The default implementation of this method is a no-op.
00226   virtual void StartTranslationUnit(ASTConsumer *Consumer);
00227 
00228   /// \brief Print any statistics that have been gathered regarding
00229   /// the external AST source.
00230   ///
00231   /// The default implementation of this method is a no-op.
00232   virtual void PrintStats();
00233   
00234   
00235   /// \brief Perform layout on the given record.
00236   ///
00237   /// This routine allows the external AST source to provide an specific 
00238   /// layout for a record, overriding the layout that would normally be
00239   /// constructed. It is intended for clients who receive specific layout
00240   /// details rather than source code (such as LLDB). The client is expected
00241   /// to fill in the field offsets, base offsets, virtual base offsets, and
00242   /// complete object size.
00243   ///
00244   /// \param Record The record whose layout is being requested.
00245   ///
00246   /// \param Size The final size of the record, in bits.
00247   ///
00248   /// \param Alignment The final alignment of the record, in bits.
00249   ///
00250   /// \param FieldOffsets The offset of each of the fields within the record,
00251   /// expressed in bits. All of the fields must be provided with offsets.
00252   ///
00253   /// \param BaseOffsets The offset of each of the direct, non-virtual base
00254   /// classes. If any bases are not given offsets, the bases will be laid 
00255   /// out according to the ABI.
00256   ///
00257   /// \param VirtualBaseOffsets The offset of each of the virtual base classes
00258   /// (either direct or not). If any bases are not given offsets, the bases will be laid 
00259   /// out according to the ABI.
00260   /// 
00261   /// \returns true if the record layout was provided, false otherwise.
00262   virtual bool layoutRecordType(
00263       const RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
00264       llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
00265       llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
00266       llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets);
00267 
00268   //===--------------------------------------------------------------------===//
00269   // Queries for performance analysis.
00270   //===--------------------------------------------------------------------===//
00271   
00272   struct MemoryBufferSizes {
00273     size_t malloc_bytes;
00274     size_t mmap_bytes;
00275     
00276     MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes)
00277     : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {}
00278   };
00279   
00280   /// Return the amount of memory used by memory buffers, breaking down
00281   /// by heap-backed versus mmap'ed memory.
00282   MemoryBufferSizes getMemoryBufferSizes() const {
00283     MemoryBufferSizes sizes(0, 0);
00284     getMemoryBufferSizes(sizes);
00285     return sizes;
00286   }
00287 
00288   virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const;
00289 
00290 protected:
00291   static DeclContextLookupResult
00292   SetExternalVisibleDeclsForName(const DeclContext *DC,
00293                                  DeclarationName Name,
00294                                  ArrayRef<NamedDecl*> Decls);
00295 
00296   static DeclContextLookupResult
00297   SetNoExternalVisibleDeclsForName(const DeclContext *DC,
00298                                    DeclarationName Name);
00299 
00300   /// \brief Increment the current generation.
00301   uint32_t incrementGeneration(ASTContext &C);
00302 };
00303 
00304 /// \brief A lazy pointer to an AST node (of base type T) that resides
00305 /// within an external AST source.
00306 ///
00307 /// The AST node is identified within the external AST source by a
00308 /// 63-bit offset, and can be retrieved via an operation on the
00309 /// external AST source itself.
00310 template<typename T, typename OffsT, T* (ExternalASTSource::*Get)(OffsT Offset)>
00311 struct LazyOffsetPtr {
00312   /// \brief Either a pointer to an AST node or the offset within the
00313   /// external AST source where the AST node can be found.
00314   ///
00315   /// If the low bit is clear, a pointer to the AST node. If the low
00316   /// bit is set, the upper 63 bits are the offset.
00317   mutable uint64_t Ptr;
00318 
00319 public:
00320   LazyOffsetPtr() : Ptr(0) { }
00321 
00322   explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) { }
00323   explicit LazyOffsetPtr(uint64_t Offset) : Ptr((Offset << 1) | 0x01) {
00324     assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
00325     if (Offset == 0)
00326       Ptr = 0;
00327   }
00328 
00329   LazyOffsetPtr &operator=(T *Ptr) {
00330     this->Ptr = reinterpret_cast<uint64_t>(Ptr);
00331     return *this;
00332   }
00333 
00334   LazyOffsetPtr &operator=(uint64_t Offset) {
00335     assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
00336     if (Offset == 0)
00337       Ptr = 0;
00338     else
00339       Ptr = (Offset << 1) | 0x01;
00340 
00341     return *this;
00342   }
00343 
00344   /// \brief Whether this pointer is non-NULL.
00345   ///
00346   /// This operation does not require the AST node to be deserialized.
00347   LLVM_EXPLICIT operator bool() const { return Ptr != 0; }
00348 
00349   /// \brief Whether this pointer is non-NULL.
00350   ///
00351   /// This operation does not require the AST node to be deserialized.
00352   bool isValid() const { return Ptr != 0; }
00353 
00354   /// \brief Whether this pointer is currently stored as an offset.
00355   bool isOffset() const { return Ptr & 0x01; }
00356 
00357   /// \brief Retrieve the pointer to the AST node that this lazy pointer
00358   ///
00359   /// \param Source the external AST source.
00360   ///
00361   /// \returns a pointer to the AST node.
00362   T* get(ExternalASTSource *Source) const {
00363     if (isOffset()) {
00364       assert(Source &&
00365              "Cannot deserialize a lazy pointer without an AST source");
00366       Ptr = reinterpret_cast<uint64_t>((Source->*Get)(Ptr >> 1));
00367     }
00368     return reinterpret_cast<T*>(Ptr);
00369   }
00370 };
00371 
00372 /// \brief A lazy value (of type T) that is within an AST node of type Owner,
00373 /// where the value might change in later generations of the external AST
00374 /// source.
00375 template<typename Owner, typename T, void (ExternalASTSource::*Update)(Owner)>
00376 struct LazyGenerationalUpdatePtr {
00377   /// A cache of the value of this pointer, in the most recent generation in
00378   /// which we queried it.
00379   struct LazyData {
00380     LazyData(ExternalASTSource *Source, T Value)
00381         : ExternalSource(Source), LastGeneration(0), LastValue(Value) {}
00382     ExternalASTSource *ExternalSource;
00383     uint32_t LastGeneration;
00384     T LastValue;
00385   };
00386 
00387   // Our value is represented as simply T if there is no external AST source.
00388   typedef llvm::PointerUnion<T, LazyData*> ValueType;
00389   ValueType Value;
00390 
00391   LazyGenerationalUpdatePtr(ValueType V) : Value(V) {}
00392 
00393   // Defined in ASTContext.h
00394   static ValueType makeValue(const ASTContext &Ctx, T Value);
00395 
00396 public:
00397   explicit LazyGenerationalUpdatePtr(const ASTContext &Ctx, T Value = T())
00398       : Value(makeValue(Ctx, Value)) {}
00399 
00400   /// Create a pointer that is not potentially updated by later generations of
00401   /// the external AST source.
00402   enum NotUpdatedTag { NotUpdated };
00403   LazyGenerationalUpdatePtr(NotUpdatedTag, T Value = T())
00404       : Value(Value) {}
00405 
00406   /// Forcibly set this pointer (which must be lazy) as needing updates.
00407   void markIncomplete() {
00408     Value.template get<LazyData *>()->LastGeneration = 0;
00409   }
00410 
00411   /// Set the value of this pointer, in the current generation.
00412   void set(T NewValue) {
00413     if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>()) {
00414       LazyVal->LastValue = NewValue;
00415       return;
00416     }
00417     Value = NewValue;
00418   }
00419 
00420   /// Set the value of this pointer, for this and all future generations.
00421   void setNotUpdated(T NewValue) { Value = NewValue; }
00422 
00423   /// Get the value of this pointer, updating its owner if necessary.
00424   T get(Owner O) {
00425     if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>()) {
00426       if (LazyVal->LastGeneration != LazyVal->ExternalSource->getGeneration()) {
00427         LazyVal->LastGeneration = LazyVal->ExternalSource->getGeneration();
00428         (LazyVal->ExternalSource->*Update)(O);
00429       }
00430       return LazyVal->LastValue;
00431     }
00432     return Value.template get<T>();
00433   }
00434 
00435   /// Get the most recently computed value of this pointer without updating it.
00436   T getNotUpdated() const {
00437     if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>())
00438       return LazyVal->LastValue;
00439     return Value.template get<T>();
00440   }
00441 
00442   void *getOpaqueValue() { return Value.getOpaqueValue(); }
00443   static LazyGenerationalUpdatePtr getFromOpaqueValue(void *Ptr) {
00444     return LazyGenerationalUpdatePtr(ValueType::getFromOpaqueValue(Ptr));
00445   }
00446 };
00447 } // end namespace clang
00448 
00449 /// Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be
00450 /// placed into a PointerUnion.
00451 namespace llvm {
00452 template<typename Owner, typename T,
00453          void (clang::ExternalASTSource::*Update)(Owner)>
00454 struct PointerLikeTypeTraits<
00455     clang::LazyGenerationalUpdatePtr<Owner, T, Update>> {
00456   typedef clang::LazyGenerationalUpdatePtr<Owner, T, Update> Ptr;
00457   static void *getAsVoidPointer(Ptr P) { return P.getOpaqueValue(); }
00458   static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); }
00459   enum {
00460     NumLowBitsAvailable = PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1
00461   };
00462 };
00463 }
00464 
00465 namespace clang {
00466 /// \brief Represents a lazily-loaded vector of data.
00467 ///
00468 /// The lazily-loaded vector of data contains data that is partially loaded
00469 /// from an external source and partially added by local translation. The 
00470 /// items loaded from the external source are loaded lazily, when needed for
00471 /// iteration over the complete vector.
00472 template<typename T, typename Source, 
00473          void (Source::*Loader)(SmallVectorImpl<T>&),
00474          unsigned LoadedStorage = 2, unsigned LocalStorage = 4>
00475 class LazyVector {
00476   SmallVector<T, LoadedStorage> Loaded;
00477   SmallVector<T, LocalStorage> Local;
00478 
00479 public:
00480   // Iteration over the elements in the vector.
00481   class iterator {
00482     LazyVector *Self;
00483     
00484     /// \brief Position within the vector..
00485     ///
00486     /// In a complete iteration, the Position field walks the range [-M, N),
00487     /// where negative values are used to indicate elements
00488     /// loaded from the external source while non-negative values are used to
00489     /// indicate elements added via \c push_back().
00490     /// However, to provide iteration in source order (for, e.g., chained
00491     /// precompiled headers), dereferencing the iterator flips the negative
00492     /// values (corresponding to loaded entities), so that position -M 
00493     /// corresponds to element 0 in the loaded entities vector, position -M+1
00494     /// corresponds to element 1 in the loaded entities vector, etc. This
00495     /// gives us a reasonably efficient, source-order walk.
00496     int Position;
00497     
00498     friend class LazyVector;
00499     
00500   public:
00501     typedef T                   value_type;
00502     typedef value_type&         reference;
00503     typedef value_type*         pointer;
00504     typedef std::random_access_iterator_tag iterator_category;
00505     typedef int                 difference_type;
00506     
00507     iterator() : Self(0), Position(0) { }
00508     
00509     iterator(LazyVector *Self, int Position) 
00510       : Self(Self), Position(Position) { }
00511     
00512     reference operator*() const {
00513       if (Position < 0)
00514         return Self->Loaded.end()[Position];
00515       return Self->Local[Position];
00516     }
00517     
00518     pointer operator->() const {
00519       if (Position < 0)
00520         return &Self->Loaded.end()[Position];
00521       
00522       return &Self->Local[Position];        
00523     }
00524     
00525     reference operator[](difference_type D) {
00526       return *(*this + D);
00527     }
00528     
00529     iterator &operator++() {
00530       ++Position;
00531       return *this;
00532     }
00533     
00534     iterator operator++(int) {
00535       iterator Prev(*this);
00536       ++Position;
00537       return Prev;
00538     }
00539     
00540     iterator &operator--() {
00541       --Position;
00542       return *this;
00543     }
00544     
00545     iterator operator--(int) {
00546       iterator Prev(*this);
00547       --Position;
00548       return Prev;
00549     }
00550     
00551     friend bool operator==(const iterator &X, const iterator &Y) {
00552       return X.Position == Y.Position;
00553     }
00554     
00555     friend bool operator!=(const iterator &X, const iterator &Y) {
00556       return X.Position != Y.Position;
00557     }
00558     
00559     friend bool operator<(const iterator &X, const iterator &Y) {
00560       return X.Position < Y.Position;
00561     }
00562     
00563     friend bool operator>(const iterator &X, const iterator &Y) {
00564       return X.Position > Y.Position;
00565     }
00566     
00567     friend bool operator<=(const iterator &X, const iterator &Y) {
00568       return X.Position < Y.Position;
00569     }
00570     
00571     friend bool operator>=(const iterator &X, const iterator &Y) {
00572       return X.Position > Y.Position;
00573     }
00574     
00575     friend iterator& operator+=(iterator &X, difference_type D) {
00576       X.Position += D;
00577       return X;
00578     }
00579     
00580     friend iterator& operator-=(iterator &X, difference_type D) {
00581       X.Position -= D;
00582       return X;
00583     }
00584     
00585     friend iterator operator+(iterator X, difference_type D) {
00586       X.Position += D;
00587       return X;
00588     }
00589     
00590     friend iterator operator+(difference_type D, iterator X) {
00591       X.Position += D;
00592       return X;
00593     }
00594     
00595     friend difference_type operator-(const iterator &X, const iterator &Y) {
00596       return X.Position - Y.Position;
00597     }
00598     
00599     friend iterator operator-(iterator X, difference_type D) {
00600       X.Position -= D;
00601       return X;
00602     }
00603   };
00604   friend class iterator;
00605   
00606   iterator begin(Source *source, bool LocalOnly = false) {
00607     if (LocalOnly)
00608       return iterator(this, 0);
00609     
00610     if (source)
00611       (source->*Loader)(Loaded);
00612     return iterator(this, -(int)Loaded.size());
00613   }
00614   
00615   iterator end() {
00616     return iterator(this, Local.size());
00617   }
00618   
00619   void push_back(const T& LocalValue) {
00620     Local.push_back(LocalValue);
00621   }
00622   
00623   void erase(iterator From, iterator To) {
00624     if (From.Position < 0 && To.Position < 0) {
00625       Loaded.erase(Loaded.end() + From.Position, Loaded.end() + To.Position);
00626       return;
00627     }
00628     
00629     if (From.Position < 0) {
00630       Loaded.erase(Loaded.end() + From.Position, Loaded.end());
00631       From = begin(nullptr, true);
00632     }
00633     
00634     Local.erase(Local.begin() + From.Position, Local.begin() + To.Position);
00635   }
00636 };
00637 
00638 /// \brief A lazy pointer to a statement.
00639 typedef LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>
00640   LazyDeclStmtPtr;
00641 
00642 /// \brief A lazy pointer to a declaration.
00643 typedef LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl>
00644   LazyDeclPtr;
00645 
00646 /// \brief A lazy pointer to a set of CXXBaseSpecifiers.
00647 typedef LazyOffsetPtr<CXXBaseSpecifier, uint64_t, 
00648                       &ExternalASTSource::GetExternalCXXBaseSpecifiers>
00649   LazyCXXBaseSpecifiersPtr;
00650 
00651 } // end namespace clang
00652 
00653 #endif