summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-06-01 09:23:16 +0000
committerJohn McCall <rjmccall@apple.com>2010-06-01 09:23:16 +0000
commit75b960e5eed19935820b32c192d5de65a8ffda76 (patch)
tree99bd8c4b8697d5eb19e26abdc5b5d8f63ba8ffed /clang/lib
parentce83656f97819b440313622c06df4ad3449edc39 (diff)
downloadbcm5719-llvm-75b960e5eed19935820b32c192d5de65a8ffda76.tar.gz
bcm5719-llvm-75b960e5eed19935820b32c192d5de65a8ffda76.zip
Alter the ExternalASTSource interface to permit by-name lookups. PCH continues to
bring in the entire lookup table at once. Also, give ExternalSemaSource's vtable a home. This is important because otherwise any reference to it will cause RTTI to be emitted, and since clang is compiled with -fno-rtti, that RTTI will contain unresolved references (to ExternalASTSource's RTTI). So this change makes it possible to subclass ExternalSemaSource from projects compiled with RTTI, as long as the subclass's home is compiled with -fno-rtti. llvm-svn: 105268
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/DeclBase.cpp107
-rw-r--r--clang/lib/Frontend/PCHReader.cpp43
-rw-r--r--clang/lib/Sema/Sema.cpp4
-rw-r--r--clang/lib/Sema/SemaCodeComplete.cpp12
4 files changed, 122 insertions, 44 deletions
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 225729ea699..a73d17a5ca2 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/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/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp
index 88e9b9db180..2c51180afc9 100644
--- a/clang/lib/Frontend/PCHReader.cpp
+++ b/clang/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/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 9cc50485729..8bdf971d965 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/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/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index dda4fc1a803..d40853d724b 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/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;
OpenPOWER on IntegriCloud