diff options
Diffstat (limited to 'clang/lib/AST')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 18 | ||||
-rw-r--r-- | clang/lib/AST/DeclBase.cpp | 112 |
2 files changed, 129 insertions, 1 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index deeb7631917..7da1bf080c4 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -16,6 +16,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" +#include "clang/AST/ExternalASTSource.h" #include "clang/AST/RecordLayout.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" @@ -36,7 +37,8 @@ ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM, bool FreeMem, unsigned size_reserve) : GlobalNestedNameSpecifier(0), CFConstantStringTypeDecl(0), ObjCFastEnumerationStateTypeDecl(0), SourceMgr(SM), LangOpts(LOpts), - FreeMemory(FreeMem), Target(t), Idents(idents), Selectors(sels) { + FreeMemory(FreeMem), Target(t), Idents(idents), Selectors(sels), + ExternalSource(0) { if (size_reserve > 0) Types.reserve(size_reserve); InitBuiltinTypes(); BuiltinInfo.InitializeBuiltins(idents, Target, LangOpts.NoBuiltin); @@ -91,6 +93,11 @@ ASTContext::~ASTContext() { TUDecl->Destroy(*this); } +void +ASTContext::setExternalSource(llvm::OwningPtr<ExternalASTSource> &Source) { + ExternalSource.reset(Source.take()); +} + void ASTContext::PrintStats() const { fprintf(stderr, "*** AST Context Stats:\n"); fprintf(stderr, " %d types total.\n", (int)Types.size()); @@ -195,6 +202,11 @@ void ASTContext::PrintStats() const { NumTypeName*sizeof(TypedefType)+NumTagged*sizeof(TagType)+ NumTypeOfTypes*sizeof(TypeOfType)+NumTypeOfExprTypes*sizeof(TypeOfExprType)+ NumExtQual*sizeof(ExtQualType))); + + if (ExternalSource.get()) { + fprintf(stderr, "\n"); + ExternalSource->PrintStats(); + } } @@ -3359,3 +3371,7 @@ ASTContext* ASTContext::Create(llvm::Deserializer& D) { return A; } + +ExternalASTSource::~ExternalASTSource() { } + +void ExternalASTSource::PrintStats() { } diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 763998e852e..be349428ecf 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -17,6 +17,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/ExternalASTSource.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Type.h" #include "llvm/ADT/DenseMap.h" @@ -439,11 +440,82 @@ DeclContext *DeclContext::getNextContext() { } } +/// \brief Load the declarations within this lexical storage from an +/// external source. +void +DeclContext::LoadLexicalDeclsFromExternalStorage(ASTContext &Context) const { + ExternalASTSource *Source = Context.getExternalSource(); + assert(hasExternalLexicalStorage() && Source && "No external storage?"); + + llvm::SmallVector<unsigned, 64> Decls; + if (Source->ReadDeclsLexicallyInContext(const_cast<DeclContext *>(this), + Decls)) + return; + + // There is no longer any lexical storage in this context + ExternalLexicalStorage = false; + + if (Decls.empty()) + return; + + // Resolve all of the declaration IDs into declarations, building up + // a chain of declarations via the Decl::NextDeclInContext field. + Decl *FirstNewDecl = 0; + Decl *PrevDecl = 0; + for (unsigned I = 0, N = Decls.size(); I != N; ++I) { + Decl *D = Source->GetDecl(Decls[I]); + if (PrevDecl) + PrevDecl->NextDeclInContext = D; + else + FirstNewDecl = D; + + PrevDecl = D; + } + + // Splice the newly-read declarations into the beginning of the list + // of declarations. + PrevDecl->NextDeclInContext = FirstDecl; + FirstDecl = FirstNewDecl; + if (!LastDecl) + LastDecl = PrevDecl; +} + +void +DeclContext::LoadVisibleDeclsFromExternalStorage(ASTContext &Context) const { + DeclContext *This = const_cast<DeclContext *>(this); + ExternalASTSource *Source = Context.getExternalSource(); + assert(hasExternalVisibleStorage() && Source && "No external storage?"); + + llvm::SmallVector<VisibleDeclaration, 64> Decls; + if (Source->ReadDeclsVisibleInContext(This, Decls)) + return; + + // There is no longer any visible storage in this context + ExternalVisibleStorage = false; + + // Load the declaration IDs for all of the names visible in this + // context. + assert(!LookupPtr && "Have a lookup map before de-serialization?"); + StoredDeclsMap *Map = new StoredDeclsMap; + LookupPtr = Map; + for (unsigned I = 0, N = Decls.size(); I != N; ++I) { + (*Map)[Decls[I].Name].setFromDeclIDs(Decls[I].Declarations); + } +} + DeclContext::decl_iterator DeclContext::decls_begin(ASTContext &Context) const { + if (hasExternalLexicalStorage()) + LoadLexicalDeclsFromExternalStorage(Context); + + // FIXME: Check whether we need to load some declarations from + // external storage. return decl_iterator(FirstDecl); } DeclContext::decl_iterator DeclContext::decls_end(ASTContext &Context) const { + if (hasExternalLexicalStorage()) + LoadLexicalDeclsFromExternalStorage(Context); + return decl_iterator(); } @@ -491,6 +563,9 @@ DeclContext::lookup(ASTContext &Context, DeclarationName Name) { if (PrimaryContext != this) return PrimaryContext->lookup(Context, Name); + if (hasExternalVisibleStorage()) + LoadVisibleDeclsFromExternalStorage(Context); + /// If there is no lookup data structure, build one now by walking /// all of the linked DeclContexts (in declaration order!) and /// inserting their values. @@ -595,3 +670,40 @@ DeclContext::getUsingDirectives(ASTContext &Context) const { return udir_iterator_range(reinterpret_cast<udir_iterator>(Result.first), reinterpret_cast<udir_iterator>(Result.second)); } + +void StoredDeclsList::materializeDecls(ASTContext &Context) { + if (isNull()) + return; + + switch ((DataKind)(Data & 0x03)) { + case DK_Decl: + case DK_Decl_Vector: + break; + + case DK_DeclID: { + // Resolve this declaration ID to an actual declaration by + // querying the external AST source. + unsigned DeclID = Data >> 2; + + ExternalASTSource *Source = Context.getExternalSource(); + assert(Source && "No external AST source available!"); + + Data = reinterpret_cast<uintptr_t>(Source->GetDecl(DeclID)); + break; + } + + case DK_ID_Vector: { + // We have a vector of declaration IDs. Resolve all of them to + // actual declarations. + VectorTy &Vector = *getAsVector(); + ExternalASTSource *Source = Context.getExternalSource(); + assert(Source && "No external AST source available!"); + + for (unsigned I = 0, N = Vector.size(); I != N; ++I) + Vector[I] = reinterpret_cast<uintptr_t>(Source->GetDecl(Vector[I])); + + Data = (Data & ~0x03) | DK_Decl_Vector; + break; + } + } +} |