aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/DeclBase.cpp107
-rw-r--r--lib/Frontend/PCHReader.cpp43
-rw-r--r--lib/Sema/Sema.cpp4
-rw-r--r--lib/Sema/SemaCodeComplete.cpp12
4 files changed, 122 insertions, 44 deletions
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 225729ea69..a73d17a5ca 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -638,9 +638,8 @@ DeclContext::LoadLexicalDeclsFromExternalStorage() const {
ExternalASTSource *Source = getParentASTContext().getExternalSource();
assert(hasExternalLexicalStorage() && Source && "No external storage?");
- llvm::SmallVector<uint32_t, 64> Decls;
- if (Source->ReadDeclsLexicallyInContext(const_cast<DeclContext *>(this),
- Decls))
+ llvm::SmallVector<Decl*, 64> Decls;
+ if (Source->FindExternalLexicalDecls(this, Decls))
return;
// There is no longer any lexical storage in this context
@@ -654,7 +653,7 @@ DeclContext::LoadLexicalDeclsFromExternalStorage() const {
Decl *FirstNewDecl = 0;
Decl *PrevDecl = 0;
for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
- Decl *D = Source->GetDecl(Decls[I]);
+ Decl *D = Decls[I];
if (PrevDecl)
PrevDecl->NextDeclInContext = D;
else
@@ -671,28 +670,83 @@ DeclContext::LoadLexicalDeclsFromExternalStorage() const {
LastDecl = PrevDecl;
}
-void
-DeclContext::LoadVisibleDeclsFromExternalStorage() const {
- DeclContext *This = const_cast<DeclContext *>(this);
- ExternalASTSource *Source = getParentASTContext().getExternalSource();
- assert(hasExternalVisibleStorage() && Source && "No external storage?");
+DeclContext::lookup_result
+ExternalASTSource::SetNoExternalVisibleDeclsForName(const DeclContext *DC,
+ DeclarationName Name) {
+ ASTContext &Context = DC->getParentASTContext();
+ StoredDeclsMap *Map;
+ if (!(Map = DC->LookupPtr))
+ Map = DC->CreateStoredDeclsMap(Context);
+
+ StoredDeclsList &List = (*Map)[Name];
+ assert(List.isNull());
+ (void) List;
+
+ return DeclContext::lookup_result();
+}
- llvm::SmallVector<VisibleDeclaration, 64> Decls;
- if (Source->ReadDeclsVisibleInContext(This, Decls))
- return;
+DeclContext::lookup_result
+ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC,
+ const VisibleDeclaration &VD) {
+ ASTContext &Context = DC->getParentASTContext();
+ StoredDeclsMap *Map;
+ if (!(Map = DC->LookupPtr))
+ Map = DC->CreateStoredDeclsMap(Context);
+
+ StoredDeclsList &List = (*Map)[VD.Name];
+ List.setFromDeclIDs(VD.Declarations);
+ return List.getLookupResult(Context);
+}
- // There is no longer any visible storage in this context
- ExternalVisibleStorage = false;
+DeclContext::lookup_result
+ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC,
+ DeclarationName Name,
+ llvm::SmallVectorImpl<NamedDecl*> &Decls) {
+ ASTContext &Context = DC->getParentASTContext();;
+
+ StoredDeclsMap *Map;
+ if (!(Map = DC->LookupPtr))
+ Map = DC->CreateStoredDeclsMap(Context);
- // Load the declaration IDs for all of the names visible in this
- // context.
- assert(!LookupPtr && "Have a lookup map before de-serialization?");
- StoredDeclsMap *Map = CreateStoredDeclsMap(getParentASTContext());
+ StoredDeclsList &List = (*Map)[Name];
+ for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
+ if (List.isNull())
+ List.setOnlyValue(Decls[I]);
+ else
+ List.AddSubsequentDecl(Decls[I]);
+ }
+
+ return List.getLookupResult(Context);
+}
+
+void ExternalASTSource::SetExternalVisibleDecls(const DeclContext *DC,
+ const llvm::SmallVectorImpl<VisibleDeclaration> &Decls) {
+ // There is no longer any visible storage in this context.
+ DC->ExternalVisibleStorage = false;
+
+ assert(!DC->LookupPtr && "Have a lookup map before de-serialization?");
+ StoredDeclsMap *Map = DC->CreateStoredDeclsMap(DC->getParentASTContext());
for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
(*Map)[Decls[I].Name].setFromDeclIDs(Decls[I].Declarations);
}
}
+void ExternalASTSource::SetExternalVisibleDecls(const DeclContext *DC,
+ const llvm::SmallVectorImpl<NamedDecl*> &Decls) {
+ // There is no longer any visible storage in this context.
+ DC->ExternalVisibleStorage = false;
+
+ assert(!DC->LookupPtr && "Have a lookup map before de-serialization?");
+ StoredDeclsMap &Map = *DC->CreateStoredDeclsMap(DC->getParentASTContext());
+ for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
+ StoredDeclsList &List = Map[Decls[I]->getDeclName()];
+ if (List.isNull())
+ List.setOnlyValue(Decls[I]);
+ else
+ List.AddSubsequentDecl(Decls[I]);
+ }
+}
+
DeclContext::decl_iterator DeclContext::decls_begin() const {
if (hasExternalLexicalStorage())
LoadLexicalDeclsFromExternalStorage();
@@ -813,8 +867,17 @@ DeclContext::lookup(DeclarationName Name) {
if (PrimaryContext != this)
return PrimaryContext->lookup(Name);
- if (hasExternalVisibleStorage())
- LoadVisibleDeclsFromExternalStorage();
+ if (hasExternalVisibleStorage()) {
+ // Check to see if we've already cached the lookup results.
+ if (LookupPtr) {
+ StoredDeclsMap::iterator I = LookupPtr->find(Name);
+ if (I != LookupPtr->end())
+ return I->second.getLookupResult(getParentASTContext());
+ }
+
+ ExternalASTSource *Source = getParentASTContext().getExternalSource();
+ return Source->FindExternalVisibleDeclsByName(this, Name);
+ }
/// If there is no lookup data structure, build one now by walking
/// all of the linked DeclContexts (in declaration order!) and
@@ -944,7 +1007,7 @@ void StoredDeclsList::materializeDecls(ASTContext &Context) {
ExternalASTSource *Source = Context.getExternalSource();
assert(Source && "No external AST source available!");
- Data = reinterpret_cast<uintptr_t>(Source->GetDecl(DeclID));
+ Data = reinterpret_cast<uintptr_t>(Source->GetExternalDecl(DeclID));
break;
}
@@ -956,7 +1019,7 @@ void StoredDeclsList::materializeDecls(ASTContext &Context) {
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]));
+ Vector[I] = reinterpret_cast<uintptr_t>(Source->GetExternalDecl(Vector[I]));
Data = (Data & ~0x03) | DK_Decl_Vector;
break;
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index 88e9b9db18..2c51180afc 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -2476,6 +2476,10 @@ PCHReader::GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
return TemplateArgumentLocInfo();
}
+Decl *PCHReader::GetExternalDecl(uint32_t ID) {
+ return GetDecl(ID);
+}
+
Decl *PCHReader::GetDecl(pch::DeclID ID) {
if (ID == 0)
return 0;
@@ -2497,15 +2501,15 @@ Decl *PCHReader::GetDecl(pch::DeclID ID) {
/// This operation will read a new statement from the external
/// source each time it is called, and is meant to be used via a
/// LazyOffsetPtr (which is used by Decls for the body of functions, etc).
-Stmt *PCHReader::GetDeclStmt(uint64_t Offset) {
+Stmt *PCHReader::GetExternalDeclStmt(uint64_t Offset) {
// Since we know tha this statement is part of a decl, make sure to use the
// decl cursor to read it.
DeclsCursor.JumpToBit(Offset);
return ReadStmt(DeclsCursor);
}
-bool PCHReader::ReadDeclsLexicallyInContext(DeclContext *DC,
- llvm::SmallVectorImpl<pch::DeclID> &Decls) {
+bool PCHReader::FindExternalLexicalDecls(const DeclContext *DC,
+ llvm::SmallVectorImpl<Decl*> &Decls) {
assert(DC->hasExternalLexicalStorage() &&
"DeclContext has no lexical decls in storage");
@@ -2531,20 +2535,22 @@ bool PCHReader::ReadDeclsLexicallyInContext(DeclContext *DC,
}
// Load all of the declaration IDs
- Decls.clear();
- Decls.insert(Decls.end(), Record.begin(), Record.end());
+ for (RecordData::iterator I = Record.begin(), E = Record.end(); I != E; ++I)
+ Decls.push_back(GetDecl(*I));
++NumLexicalDeclContextsRead;
return false;
}
-bool PCHReader::ReadDeclsVisibleInContext(DeclContext *DC,
- llvm::SmallVectorImpl<VisibleDeclaration> &Decls) {
+DeclContext::lookup_result
+PCHReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
+ DeclarationName Name) {
assert(DC->hasExternalVisibleStorage() &&
"DeclContext has no visible decls in storage");
uint64_t Offset = DeclContextOffsets[DC].second;
if (Offset == 0) {
Error("DeclContext has no visible decls in storage");
- return true;
+ return DeclContext::lookup_result(DeclContext::lookup_iterator(),
+ DeclContext::lookup_iterator());
}
// Keep track of where we are in the stream, then jump back there
@@ -2559,13 +2565,16 @@ bool PCHReader::ReadDeclsVisibleInContext(DeclContext *DC,
unsigned RecCode = DeclsCursor.ReadRecord(Code, Record);
if (RecCode != pch::DECL_CONTEXT_VISIBLE) {
Error("Expected visible block");
- return true;
+ return DeclContext::lookup_result(DeclContext::lookup_iterator(),
+ DeclContext::lookup_iterator());
}
- if (Record.size() == 0)
- return false;
-
- Decls.clear();
+ llvm::SmallVector<VisibleDeclaration, 64> Decls;
+ if (Record.empty()) {
+ SetExternalVisibleDecls(DC, Decls);
+ return DeclContext::lookup_result(DeclContext::lookup_iterator(),
+ DeclContext::lookup_iterator());
+ }
unsigned Idx = 0;
while (Idx < Record.size()) {
@@ -2580,7 +2589,9 @@ bool PCHReader::ReadDeclsVisibleInContext(DeclContext *DC,
}
++NumVisibleDeclContextsRead;
- return false;
+
+ SetExternalVisibleDecls(DC, Decls);
+ return const_cast<DeclContext*>(DC)->lookup(Name);
}
void PCHReader::StartTranslationUnit(ASTConsumer *Consumer) {
@@ -2853,11 +2864,11 @@ Selector PCHReader::DecodeSelector(unsigned ID) {
return SelectorsLoaded[Index];
}
-Selector PCHReader::GetSelector(uint32_t ID) {
+Selector PCHReader::GetExternalSelector(uint32_t ID) {
return DecodeSelector(ID);
}
-uint32_t PCHReader::GetNumKnownSelectors() {
+uint32_t PCHReader::GetNumExternalSelectors() {
return TotalNumSelectors + 1;
}
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 9cc5048572..8bdf971d96 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -17,6 +17,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/APFloat.h"
+#include "clang/Sema/ExternalSemaSource.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
@@ -427,3 +428,6 @@ BlockScopeInfo *Sema::getCurBlock() {
return dyn_cast<BlockScopeInfo>(FunctionScopes.back());
}
+
+// Pin this vtable to this file.
+ExternalSemaSource::~ExternalSemaSource() {}
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index dda4fc1a80..d40853d724 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -3494,9 +3494,9 @@ void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
// If we have an external source, load the entire class method
// pool from the PCH file.
if (ExternalSource) {
- for (uint32_t I = 0, N = ExternalSource->GetNumKnownSelectors(); I != N;
- ++I) {
- Selector Sel = ExternalSource->GetSelector(I);
+ for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
+ I != N; ++I) {
+ Selector Sel = ExternalSource->GetExternalSelector(I);
if (Sel.isNull() || FactoryMethodPool.count(Sel) ||
InstanceMethodPool.count(Sel))
continue;
@@ -3595,9 +3595,9 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
// If we have an external source, load the entire class method
// pool from the PCH file.
if (ExternalSource) {
- for (uint32_t I = 0, N = ExternalSource->GetNumKnownSelectors(); I != N;
- ++I) {
- Selector Sel = ExternalSource->GetSelector(I);
+ for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
+ I != N; ++I) {
+ Selector Sel = ExternalSource->GetExternalSelector(I);
if (Sel.isNull() || InstanceMethodPool.count(Sel) ||
FactoryMethodPool.count(Sel))
continue;