ExternalASTSource.h revision ca2ab45341c448284cf93770018c717810575f86
1f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org//===--- ExternalASTSource.h - Abstract External AST Interface --*- C++ -*-===//
2f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org//
3f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org//                     The LLVM Compiler Infrastructure
4f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org//
5f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org// This file is distributed under the University of Illinois Open Source
6f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org// License. See LICENSE.TXT for details.
7f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org//
8f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org//===----------------------------------------------------------------------===//
9f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org//
10f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org//  This file defines the ExternalASTSource interface, which enables
11f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org//  construction of AST nodes from some external source.
12f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org//
13f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org//===----------------------------------------------------------------------===//
14f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifndef LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
15f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#define LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
16f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
17f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#include "clang/AST/CharUnits.h"
18f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#include "clang/AST/DeclBase.h"
19f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#include "llvm/ADT/DenseMap.h"
20f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
21f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgnamespace clang {
22f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
23f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgclass ASTConsumer;
24f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgclass CXXBaseSpecifier;
25f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgclass DeclarationName;
26f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgclass ExternalSemaSource; // layering violation required for downcasting
27f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgclass FieldDecl;
28f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgclass Module;
29f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgclass NamedDecl;
30f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgclass RecordDecl;
31f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgclass Selector;
32f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgclass Stmt;
33f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgclass TagDecl;
34f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
35f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/// \brief Enumeration describing the result of loading information from
36f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/// an external source.
37f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgenum ExternalLoadResult {
38f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Loading the external information has succeeded.
39f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ELR_Success,
40f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
41f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Loading the external information has failed.
42f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ELR_Failure,
43f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
44f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief The external information has already been loaded, and therefore
45f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// no additional processing is required.
46f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ELR_AlreadyLoaded
47f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org};
48f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
49f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/// \brief Abstract interface for external sources of AST nodes.
50f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org///
51f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/// External AST sources provide AST nodes constructed from some
52f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/// external source, such as a precompiled header. External AST
53f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/// sources can resolve types and declarations from abstract IDs into
54f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/// actual type and declaration nodes, and read parts of declaration
55f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/// contexts.
56f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgclass ExternalASTSource {
57f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Whether this AST source also provides information for
58f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// semantic analysis.
59f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  bool SemaSource;
60f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
61f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  friend class ExternalSemaSource;
62f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
63f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgpublic:
64f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ExternalASTSource() : SemaSource(false) { }
65f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
66f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  virtual ~ExternalASTSource();
67f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
68f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief RAII class for safely pairing a StartedDeserializing call
69f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// with FinishedDeserializing.
70f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  class Deserializing {
71f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    ExternalASTSource *Source;
72f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  public:
73f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    explicit Deserializing(ExternalASTSource *source) : Source(source) {
74f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      assert(Source);
75f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      Source->StartedDeserializing();
76f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
77f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    ~Deserializing() {
78f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      Source->FinishedDeserializing();
79f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
80f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  };
81f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
82f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Resolve a declaration ID into a declaration, potentially
83f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// building a new declaration.
84f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
85f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// This method only needs to be implemented if the AST source ever
86f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// passes back decl sets as VisibleDeclaration objects.
87f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
88f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// The default implementation of this method is a no-op.
89f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  virtual Decl *GetExternalDecl(uint32_t ID);
90f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
91f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Resolve a selector ID into a selector.
92f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
93f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// This operation only needs to be implemented if the AST source
94f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// returns non-zero for GetNumKnownSelectors().
95f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
96f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// The default implementation of this method is a no-op.
97f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  virtual Selector GetExternalSelector(uint32_t ID);
98f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
99f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Returns the number of selectors known to the external AST
100f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// source.
101f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
102f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// The default implementation of this method is a no-op.
103f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  virtual uint32_t GetNumExternalSelectors();
104f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
105f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Resolve the offset of a statement in the decl stream into
106f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// a statement.
107f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
108f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// This operation is meant to be used via a LazyOffsetPtr.  It only
109f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// needs to be implemented if the AST source uses methods like
110f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// FunctionDecl::setLazyBody when building decls.
111f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
112f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// The default implementation of this method is a no-op.
113f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  virtual Stmt *GetExternalDeclStmt(uint64_t Offset);
114f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
115f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Resolve the offset of a set of C++ base specifiers in the decl
116f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// stream into an array of specifiers.
117f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
118f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// The default implementation of this method is a no-op.
119f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);
120f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
121f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Finds all declarations with the given name in the
122f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// given context.
123f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
124f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// Generally the final step of this method is either to call
125f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// SetExternalVisibleDeclsForName or to recursively call lookup on
126f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// the DeclContext after calling SetExternalVisibleDecls.
127f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
128f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// The default implementation of this method is a no-op.
129f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  virtual DeclContextLookupResult
130f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name);
131f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
132f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Ensures that the table of all visible declarations inside this
133f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// context is up to date.
134f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
135f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// The default implementation of this function is a no-op.
136f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  virtual void completeVisibleDeclsMap(const DeclContext *DC);
137f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
138f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Retrieve the module that corresponds to the given module ID.
139f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  virtual Module *getModule(unsigned ID) { return 0; }
140f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
141f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Finds all declarations lexically contained within the given
142f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// DeclContext, after applying an optional filter predicate.
143f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
144f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \param isKindWeWant a predicate function that returns true if the passed
145f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// declaration kind is one we are looking for. If NULL, all declarations
146f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// are returned.
147f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
148f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \return an indication of whether the load succeeded or failed.
149f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
150f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// The default implementation of this method is a no-op.
151f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
152f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org                                        bool (*isKindWeWant)(Decl::Kind),
153f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org                                        SmallVectorImpl<Decl*> &Result);
154f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
155f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Finds all declarations lexically contained within the given
156f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// DeclContext.
157f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
158f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \return true if an error occurred
159f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
160f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org                                SmallVectorImpl<Decl*> &Result) {
161f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    return FindExternalLexicalDecls(DC, 0, Result);
162f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
163f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
164f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  template <typename DeclTy>
165f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ExternalLoadResult FindExternalLexicalDeclsBy(const DeclContext *DC,
166f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org                                  SmallVectorImpl<Decl*> &Result) {
167f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    return FindExternalLexicalDecls(DC, DeclTy::classofKind, Result);
168f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
169f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
170f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Get the decls that are contained in a file in the Offset/Length
171f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// range. \p Length can be 0 to indicate a point at \p Offset instead of
172f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// a range.
173f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  virtual void FindFileRegionDecls(FileID File, unsigned Offset,unsigned Length,
174f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org                                   SmallVectorImpl<Decl *> &Decls) {}
175f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
176f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Gives the external AST source an opportunity to complete
177f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// an incomplete type.
178f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  virtual void CompleteType(TagDecl *Tag) {}
179f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
180f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Gives the external AST source an opportunity to complete an
181f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// incomplete Objective-C class.
182f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
183f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// This routine will only be invoked if the "externally completed" bit is
184f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// set on the ObjCInterfaceDecl via the function
185f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \c ObjCInterfaceDecl::setExternallyCompleted().
186f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  virtual void CompleteType(ObjCInterfaceDecl *Class) { }
187f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
188f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Loads comment ranges.
189f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  virtual void ReadComments() { }
190f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
191f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Notify ExternalASTSource that we started deserialization of
192f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// a decl or type so until FinishedDeserializing is called there may be
193f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// decls that are initializing. Must be paired with FinishedDeserializing.
194f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
195f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// The default implementation of this method is a no-op.
196f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  virtual void StartedDeserializing() { }
197f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
198f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Notify ExternalASTSource that we finished the deserialization of
199f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// a decl or type. Must be paired with StartedDeserializing.
200f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
201f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// The default implementation of this method is a no-op.
202f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  virtual void FinishedDeserializing() { }
203f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
204f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Function that will be invoked when we begin parsing a new
205f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// translation unit involving this external AST source.
206f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
207f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// The default implementation of this method is a no-op.
208f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  virtual void StartTranslationUnit(ASTConsumer *Consumer) { }
209f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
210f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Print any statistics that have been gathered regarding
211f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// the external AST source.
212f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
213f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// The default implementation of this method is a no-op.
214f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  virtual void PrintStats();
215f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
216f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
217f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Perform layout on the given record.
218f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
219f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// This routine allows the external AST source to provide an specific
220f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// layout for a record, overriding the layout that would normally be
221f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// constructed. It is intended for clients who receive specific layout
222f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// details rather than source code (such as LLDB). The client is expected
223f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// to fill in the field offsets, base offsets, virtual base offsets, and
224f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// complete object size.
225f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
226f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \param Record The record whose layout is being requested.
227f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
228f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \param Size The final size of the record, in bits.
229f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
230f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \param Alignment The final alignment of the record, in bits.
231f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
232f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \param FieldOffsets The offset of each of the fields within the record,
233f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// expressed in bits. All of the fields must be provided with offsets.
234f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
235f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \param BaseOffsets The offset of each of the direct, non-virtual base
236f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// classes. If any bases are not given offsets, the bases will be laid
237f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// out according to the ABI.
238f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
239f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \param VirtualBaseOffsets The offset of each of the virtual base classes
240f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// (either direct or not). If any bases are not given offsets, the bases will be laid
241f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// out according to the ABI.
242f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
243f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \returns true if the record layout was provided, false otherwise.
244f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  virtual bool
245f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  layoutRecordType(const RecordDecl *Record,
246f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org                   uint64_t &Size, uint64_t &Alignment,
247f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org                   llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
248f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org                 llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
249f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org          llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets)
250f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  {
251f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    return false;
252f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
253f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
254f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  //===--------------------------------------------------------------------===//
255f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  // Queries for performance analysis.
256f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  //===--------------------------------------------------------------------===//
257f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
258f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  struct MemoryBufferSizes {
259f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    size_t malloc_bytes;
260f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    size_t mmap_bytes;
261f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
262f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes)
263f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {}
264f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  };
265f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
266f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// Return the amount of memory used by memory buffers, breaking down
267f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// by heap-backed versus mmap'ed memory.
268f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  MemoryBufferSizes getMemoryBufferSizes() const {
269f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    MemoryBufferSizes sizes(0, 0);
270f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    getMemoryBufferSizes(sizes);
271f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    return sizes;
272f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
273f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
274f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const;
275f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
276f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgprotected:
277f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  static DeclContextLookupResult
278f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  SetExternalVisibleDeclsForName(const DeclContext *DC,
279f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org                                 DeclarationName Name,
280f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org                                 ArrayRef<NamedDecl*> Decls);
281f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
282f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  static DeclContextLookupResult
283f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  SetNoExternalVisibleDeclsForName(const DeclContext *DC,
284f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org                                   DeclarationName Name);
285f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org};
286f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
287f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/// \brief A lazy pointer to an AST node (of base type T) that resides
288f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/// within an external AST source.
289f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org///
290f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/// The AST node is identified within the external AST source by a
291f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/// 63-bit offset, and can be retrieved via an operation on the
292f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/// external AST source itself.
293f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgtemplate<typename T, typename OffsT, T* (ExternalASTSource::*Get)(OffsT Offset)>
294f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgstruct LazyOffsetPtr {
295f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Either a pointer to an AST node or the offset within the
296f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// external AST source where the AST node can be found.
297f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
298f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// If the low bit is clear, a pointer to the AST node. If the low
299f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// bit is set, the upper 63 bits are the offset.
300f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  mutable uint64_t Ptr;
301f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
302f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgpublic:
303f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  LazyOffsetPtr() : Ptr(0) { }
304f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
305f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) { }
306f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  explicit LazyOffsetPtr(uint64_t Offset) : Ptr((Offset << 1) | 0x01) {
307f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
308f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    if (Offset == 0)
309f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      Ptr = 0;
310f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
311f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
312f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  LazyOffsetPtr &operator=(T *Ptr) {
313f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    this->Ptr = reinterpret_cast<uint64_t>(Ptr);
314f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    return *this;
315f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
316f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
317f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  LazyOffsetPtr &operator=(uint64_t Offset) {
318f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
319f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    if (Offset == 0)
320f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      Ptr = 0;
321f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    else
322f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      Ptr = (Offset << 1) | 0x01;
323f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
324f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    return *this;
325f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
326f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
327f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Whether this pointer is non-NULL.
328f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
329f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// This operation does not require the AST node to be deserialized.
330f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  operator bool() const { return Ptr != 0; }
331f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
332f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Whether this pointer is currently stored as an offset.
333f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  bool isOffset() const { return Ptr & 0x01; }
334f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
335f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \brief Retrieve the pointer to the AST node that this lazy pointer
336f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
337f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \param Source the external AST source.
338f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  ///
339f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /// \returns a pointer to the AST node.
340f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  T* get(ExternalASTSource *Source) const {
341f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    if (isOffset()) {
342f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      assert(Source &&
343f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org             "Cannot deserialize a lazy pointer without an AST source");
344f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      Ptr = reinterpret_cast<uint64_t>((Source->*Get)(Ptr >> 1));
345f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
346f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    return reinterpret_cast<T*>(Ptr);
347f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
348f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org};
349f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
350f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/// \brief Represents a lazily-loaded vector of data.
351f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org///
352f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/// The lazily-loaded vector of data contains data that is partially loaded
353f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/// from an external source and partially added by local translation. The
354f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/// items loaded from the external source are loaded lazily, when needed for
355f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/// iteration over the complete vector.
356f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgtemplate<typename T, typename Source,
357f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org         void (Source::*Loader)(SmallVectorImpl<T>&),
358f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org         unsigned LoadedStorage = 2, unsigned LocalStorage = 4>
359f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgclass LazyVector {
360f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  SmallVector<T, LoadedStorage> Loaded;
361f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  SmallVector<T, LocalStorage> Local;
362f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
363f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgpublic:
364f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  // Iteration over the elements in the vector.
365f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  class iterator {
366f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    LazyVector *Self;
367f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
368f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    /// \brief Position within the vector..
369f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    ///
370f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    /// In a complete iteration, the Position field walks the range [-M, N),
371f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    /// where negative values are used to indicate elements
372f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    /// loaded from the external source while non-negative values are used to
373f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    /// indicate elements added via \c push_back().
374f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    /// However, to provide iteration in source order (for, e.g., chained
375f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    /// precompiled headers), dereferencing the iterator flips the negative
376f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    /// values (corresponding to loaded entities), so that position -M
377f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    /// corresponds to element 0 in the loaded entities vector, position -M+1
378f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    /// corresponds to element 1 in the loaded entities vector, etc. This
379f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    /// gives us a reasonably efficient, source-order walk.
380f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    int Position;
381f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
382f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    friend class LazyVector;
383f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
384f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  public:
385f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    typedef T                   value_type;
386f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    typedef value_type&         reference;
387f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    typedef value_type*         pointer;
388f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    typedef std::random_access_iterator_tag iterator_category;
389f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    typedef int                 difference_type;
390f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
391f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    iterator() : Self(0), Position(0) { }
392f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
393f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    iterator(LazyVector *Self, int Position)
394f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      : Self(Self), Position(Position) { }
395f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
396f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    reference operator*() const {
397f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      if (Position < 0)
398f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org        return Self->Loaded.end()[Position];
399f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      return Self->Local[Position];
400f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
401f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
402f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    pointer operator->() const {
403f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      if (Position < 0)
404f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org        return &Self->Loaded.end()[Position];
405f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
406f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      return &Self->Local[Position];
407f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
408f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
409f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    reference operator[](difference_type D) {
410f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      return *(*this + D);
411f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
412f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
413f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    iterator &operator++() {
414f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      ++Position;
415f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      return *this;
416f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
417f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
418f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    iterator operator++(int) {
419f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      iterator Prev(*this);
420f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      ++Position;
421f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      return Prev;
422f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
423f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
424f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    iterator &operator--() {
425f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      --Position;
426f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      return *this;
427f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
428f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
429f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    iterator operator--(int) {
430f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      iterator Prev(*this);
431f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      --Position;
432f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      return Prev;
433f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
434f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
435f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    friend bool operator==(const iterator &X, const iterator &Y) {
436f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      return X.Position == Y.Position;
437f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
438f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
439f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    friend bool operator!=(const iterator &X, const iterator &Y) {
440f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      return X.Position != Y.Position;
441f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
442f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
443f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    friend bool operator<(const iterator &X, const iterator &Y) {
444f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      return X.Position < Y.Position;
445f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
446f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
447f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    friend bool operator>(const iterator &X, const iterator &Y) {
448f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      return X.Position > Y.Position;
449f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
450f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
451f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    friend bool operator<=(const iterator &X, const iterator &Y) {
452f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      return X.Position < Y.Position;
453f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
454f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
455f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    friend bool operator>=(const iterator &X, const iterator &Y) {
456f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      return X.Position > Y.Position;
457f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
458f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
459f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    friend iterator& operator+=(iterator &X, difference_type D) {
460f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      X.Position += D;
461f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      return X;
462f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
463f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
464f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    friend iterator& operator-=(iterator &X, difference_type D) {
465f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      X.Position -= D;
466f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      return X;
467f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
468f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
469f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    friend iterator operator+(iterator X, difference_type D) {
470f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      X.Position += D;
471f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      return X;
472f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
473f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
474f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    friend iterator operator+(difference_type D, iterator X) {
475f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      X.Position += D;
476f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      return X;
477f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
478f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
479f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    friend difference_type operator-(const iterator &X, const iterator &Y) {
480f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      return X.Position - Y.Position;
481f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
482f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
483f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    friend iterator operator-(iterator X, difference_type D) {
484f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      X.Position -= D;
485f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      return X;
486f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
487f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  };
488f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  friend class iterator;
489f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
490f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  iterator begin(Source *source, bool LocalOnly = false) {
491f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    if (LocalOnly)
492f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      return iterator(this, 0);
493f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
494f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    if (source)
495f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      (source->*Loader)(Loaded);
496f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    return iterator(this, -(int)Loaded.size());
497f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
498f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
499f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  iterator end() {
500f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    return iterator(this, Local.size());
501f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
502f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
503f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  void push_back(const T& LocalValue) {
504f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    Local.push_back(LocalValue);
505f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
506f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
507f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  void erase(iterator From, iterator To) {
508f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    if (From.Position < 0 && To.Position < 0) {
509f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      Loaded.erase(Loaded.end() + From.Position, Loaded.end() + To.Position);
510f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      return;
511f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
512f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
513f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    if (From.Position < 0) {
514f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      Loaded.erase(Loaded.end() + From.Position, Loaded.end());
515f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      From = begin(0, true);
516f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
517f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
518f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    Local.erase(Local.begin() + From.Position, Local.begin() + To.Position);
519f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
520f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org};
521f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
522f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/// \brief A lazy pointer to a statement.
523f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgtypedef LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>
524f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  LazyDeclStmtPtr;
525f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
526f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/// \brief A lazy pointer to a declaration.
527f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgtypedef LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl>
528f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  LazyDeclPtr;
529f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
530f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/// \brief A lazy pointer to a set of CXXBaseSpecifiers.
531f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgtypedef LazyOffsetPtr<CXXBaseSpecifier, uint64_t,
532f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org                      &ExternalASTSource::GetExternalCXXBaseSpecifiers>
533f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  LazyCXXBaseSpecifiersPtr;
534f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
535f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} // end namespace clang
536f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
537f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif // LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
538f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org