[cfe-commits] r111636 - in /cfe/trunk: include/clang/AST/DeclContextInternals.h include/clang/AST/ExternalASTSource.h include/clang/Serialization/ASTReader.h include/clang/Serialization/ASTWriter.h lib/AST/DeclBase.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriter.cpp lib/Serialization/ASTWriterDecl.cpp
Argyrios Kyrtzidis
akyrtzi at gmail.com
Fri Aug 20 09:04:35 PDT 2010
Author: akirtzidis
Date: Fri Aug 20 11:04:35 2010
New Revision: 111636
URL: http://llvm.org/viewvc/llvm-project?rev=111636&view=rev
Log:
Use the AST on-disk hash table for name lookup inside a DeclContext.
*Huge* improvement over the amount of deserializing that we do for C++ lookup.
e.g, if he have the Carbon header precompiled and include it on a file containing this:
int x;
these are the before/after stats:
BEFORE:
*** AST File Statistics:
578 stat cache hits
4 stat cache misses
548/30654 source location entries read (1.787695%)
15907/16501 types read (96.400223%)
53525/59955 declarations read (89.275291%)
33993/43525 identifiers read (78.099945%)
41516/51891 statements read (80.006165%)
77/5317 macros read (1.448185%)
0/6335 lexical declcontexts read (0.000000%)
1/5424 visible declcontexts read (0.018437%)
AFTER using the on-disk table:
*** AST File Statistics:
578 stat cache hits
4 stat cache misses
548/30654 source location entries read (1.787695%)
10/16501 types read (0.060602%)
9/59955 declarations read (0.015011%)
161/43525 identifiers read (0.369902%)
20/51891 statements read (0.038542%)
6/5317 macros read (0.112846%)
0/6335 lexical declcontexts read (0.000000%)
2/5424 visible declcontexts read (0.036873%)
There's only one issue affecting mostly the precompiled preambles which I will address soon.
Modified:
cfe/trunk/include/clang/AST/DeclContextInternals.h
cfe/trunk/include/clang/AST/ExternalASTSource.h
cfe/trunk/include/clang/Serialization/ASTReader.h
cfe/trunk/include/clang/Serialization/ASTWriter.h
cfe/trunk/lib/AST/DeclBase.cpp
cfe/trunk/lib/Serialization/ASTReader.cpp
cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp
cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
Modified: cfe/trunk/include/clang/AST/DeclContextInternals.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclContextInternals.h?rev=111636&r1=111635&r2=111636&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclContextInternals.h (original)
+++ cfe/trunk/include/clang/AST/DeclContextInternals.h Fri Aug 20 11:04:35 2010
@@ -29,108 +29,54 @@
/// StoredDeclsList - This is an array of decls optimized a common case of only
/// containing one entry.
struct StoredDeclsList {
- /// The kind of data encoded in this list.
- enum DataKind {
- /// \brief The data is a NamedDecl*.
- DK_Decl = 0,
- /// \brief The data is a declaration ID (an unsigned value),
- /// shifted left by 2 bits.
- DK_DeclID = 1,
- /// \brief The data is a pointer to a vector (of type VectorTy)
- /// that contains declarations.
- DK_Decl_Vector = 2,
- /// \brief The data is a pointer to a vector (of type VectorTy)
- /// that contains declaration ID.
- DK_ID_Vector = 3
- };
-
- /// VectorTy - When in vector form, this is what the Data pointer points to.
- typedef llvm::SmallVector<uintptr_t, 4> VectorTy;
-
- /// \brief The stored data, which will be either a declaration ID, a
- /// pointer to a NamedDecl, or a pointer to a vector.
- uintptr_t Data;
+
+ /// DeclsTy - When in vector form, this is what the Data pointer points to.
+ typedef llvm::SmallVector<NamedDecl *, 4> DeclsTy;
+
+ /// \brief The stored data, which will be either a pointer to a NamedDecl,
+ /// or a pointer to a vector.
+ llvm::PointerUnion<NamedDecl *, DeclsTy *> Data;
public:
- StoredDeclsList() : Data(0) {}
+ StoredDeclsList() {}
StoredDeclsList(const StoredDeclsList &RHS) : Data(RHS.Data) {
- if (VectorTy *RHSVec = RHS.getAsVector()) {
- VectorTy *New = new VectorTy(*RHSVec);
- Data = reinterpret_cast<uintptr_t>(New) | (Data & 0x03);
- }
+ if (DeclsTy *RHSVec = RHS.getAsVector())
+ Data = new DeclsTy(*RHSVec);
}
~StoredDeclsList() {
// If this is a vector-form, free the vector.
- if (VectorTy *Vector = getAsVector())
+ if (DeclsTy *Vector = getAsVector())
delete Vector;
}
StoredDeclsList &operator=(const StoredDeclsList &RHS) {
- if (VectorTy *Vector = getAsVector())
+ if (DeclsTy *Vector = getAsVector())
delete Vector;
Data = RHS.Data;
- if (VectorTy *RHSVec = RHS.getAsVector()) {
- VectorTy *New = new VectorTy(*RHSVec);
- Data = reinterpret_cast<uintptr_t>(New) | (Data & 0x03);
- }
+ if (DeclsTy *RHSVec = RHS.getAsVector())
+ Data = new DeclsTy(*RHSVec);
return *this;
}
- bool isNull() const { return (Data & ~0x03) == 0; }
+ bool isNull() const { return Data.isNull(); }
NamedDecl *getAsDecl() const {
- if ((Data & 0x03) != DK_Decl)
- return 0;
-
- return reinterpret_cast<NamedDecl *>(Data & ~0x03);
+ return Data.dyn_cast<NamedDecl *>();
}
- VectorTy *getAsVector() const {
- if ((Data & 0x03) != DK_ID_Vector && (Data & 0x03) != DK_Decl_Vector)
- return 0;
-
- return reinterpret_cast<VectorTy *>(Data & ~0x03);
+ DeclsTy *getAsVector() const {
+ return Data.dyn_cast<DeclsTy *>();
}
void setOnlyValue(NamedDecl *ND) {
assert(!getAsVector() && "Not inline");
- Data = reinterpret_cast<uintptr_t>(ND);
- }
-
- void setFromDeclIDs(const llvm::SmallVectorImpl<unsigned> &Vec) {
- if (Vec.size() > 1) {
- VectorTy *Vector = getAsVector();
- if (!Vector) {
- Vector = new VectorTy;
- Data = reinterpret_cast<uintptr_t>(Vector) | DK_ID_Vector;
- }
-
- Vector->resize(Vec.size());
- std::copy(Vec.begin(), Vec.end(), Vector->begin());
- return;
- }
-
- if (VectorTy *Vector = getAsVector())
- delete Vector;
-
- if (Vec.empty())
- Data = 0;
- else
- Data = (Vec[0] << 2) | DK_DeclID;
- }
-
- /// \brief Force the stored declarations list to contain actual
- /// declarations.
- ///
- /// This routine will resolve any declaration IDs for declarations
- /// that may not yet have been loaded from external storage.
- void materializeDecls(ASTContext &Context);
-
- bool hasDeclarationIDs() const {
- DataKind DK = (DataKind)(Data & 0x03);
- return DK == DK_DeclID || DK == DK_ID_Vector;
+ Data = ND;
+ // Make sure that Data is a plain NamedDecl* so we can use its address
+ // at getLookupResult.
+ assert(*(NamedDecl **)&Data == ND &&
+ "PointerUnion mangles the NamedDecl pointer!");
}
void remove(NamedDecl *D) {
@@ -138,30 +84,26 @@
if (NamedDecl *Singleton = getAsDecl()) {
assert(Singleton == D && "list is different singleton");
(void)Singleton;
- Data = 0;
+ Data = (NamedDecl *)0;
return;
}
- VectorTy &Vec = *getAsVector();
- VectorTy::iterator I = std::find(Vec.begin(), Vec.end(),
- reinterpret_cast<uintptr_t>(D));
+ DeclsTy &Vec = *getAsVector();
+ DeclsTy::iterator I = std::find(Vec.begin(), Vec.end(), D);
assert(I != Vec.end() && "list does not contain decl");
Vec.erase(I);
- assert(std::find(Vec.begin(), Vec.end(), reinterpret_cast<uintptr_t>(D))
+ assert(std::find(Vec.begin(), Vec.end(), D)
== Vec.end() && "list still contains decl");
}
/// getLookupResult - Return an array of all the decls that this list
/// represents.
- DeclContext::lookup_result getLookupResult(ASTContext &Context) {
+ DeclContext::lookup_result getLookupResult() {
if (isNull())
return DeclContext::lookup_result(DeclContext::lookup_iterator(0),
DeclContext::lookup_iterator(0));
- if (hasDeclarationIDs())
- materializeDecls(Context);
-
// If we have a single NamedDecl, return it.
if (getAsDecl()) {
assert(!isNull() && "Empty list isn't allowed");
@@ -172,19 +114,15 @@
}
assert(getAsVector() && "Must have a vector at this point");
- VectorTy &Vector = *getAsVector();
+ DeclsTy &Vector = *getAsVector();
// Otherwise, we have a range result.
- return DeclContext::lookup_result((NamedDecl **)&Vector[0],
- (NamedDecl **)&Vector[0]+Vector.size());
+ return DeclContext::lookup_result(&Vector[0], &Vector[0]+Vector.size());
}
/// HandleRedeclaration - If this is a redeclaration of an existing decl,
/// replace the old one with D and return true. Otherwise return false.
- bool HandleRedeclaration(ASTContext &Context, NamedDecl *D) {
- if (hasDeclarationIDs())
- materializeDecls(Context);
-
+ bool HandleRedeclaration(NamedDecl *D) {
// Most decls only have one entry in their list, special case it.
if (NamedDecl *OldD = getAsDecl()) {
if (!D->declarationReplaces(OldD))
@@ -194,12 +132,12 @@
}
// Determine if this declaration is actually a redeclaration.
- VectorTy &Vec = *getAsVector();
- for (VectorTy::iterator OD = Vec.begin(), ODEnd = Vec.end();
+ DeclsTy &Vec = *getAsVector();
+ for (DeclsTy::iterator OD = Vec.begin(), ODEnd = Vec.end();
OD != ODEnd; ++OD) {
- NamedDecl *OldD = reinterpret_cast<NamedDecl *>(*OD);
+ NamedDecl *OldD = *OD;
if (D->declarationReplaces(OldD)) {
- *OD = reinterpret_cast<uintptr_t>(D);
+ *OD = D;
return true;
}
}
@@ -211,17 +149,15 @@
/// not a redeclaration to merge it into the appropriate place in our list.
///
void AddSubsequentDecl(NamedDecl *D) {
- assert(!hasDeclarationIDs() && "Must materialize before adding decls");
-
// If this is the second decl added to the list, convert this to vector
// form.
if (NamedDecl *OldD = getAsDecl()) {
- VectorTy *VT = new VectorTy();
- VT->push_back(reinterpret_cast<uintptr_t>(OldD));
- Data = reinterpret_cast<uintptr_t>(VT) | DK_Decl_Vector;
+ DeclsTy *VT = new DeclsTy();
+ VT->push_back(OldD);
+ Data = VT;
}
- VectorTy &Vec = *getAsVector();
+ DeclsTy &Vec = *getAsVector();
// Using directives end up in a special entry which contains only
// other using directives, so all this logic is wasted for them.
@@ -232,32 +168,30 @@
// iterator which points at the first tag will start a span of
// decls that only contains tags.
if (D->hasTagIdentifierNamespace())
- Vec.push_back(reinterpret_cast<uintptr_t>(D));
+ Vec.push_back(D);
// Resolved using declarations go at the front of the list so that
// they won't show up in other lookup results. Unresolved using
// declarations (which are always in IDNS_Using | IDNS_Ordinary)
// follow that so that the using declarations will be contiguous.
else if (D->getIdentifierNamespace() & Decl::IDNS_Using) {
- VectorTy::iterator I = Vec.begin();
+ DeclsTy::iterator I = Vec.begin();
if (D->getIdentifierNamespace() != Decl::IDNS_Using) {
while (I != Vec.end() &&
- reinterpret_cast<NamedDecl *>(*I)
- ->getIdentifierNamespace() == Decl::IDNS_Using)
+ (*I)->getIdentifierNamespace() == Decl::IDNS_Using)
++I;
}
- Vec.insert(I, reinterpret_cast<uintptr_t>(D));
+ Vec.insert(I, D);
// All other declarations go at the end of the list, but before any
// tag declarations. But we can be clever about tag declarations
// because there can only ever be one in a scope.
- } else if (reinterpret_cast<NamedDecl *>(Vec.back())
- ->hasTagIdentifierNamespace()) {
- uintptr_t TagD = Vec.back();
- Vec.back() = reinterpret_cast<uintptr_t>(D);
+ } else if (Vec.back()->hasTagIdentifierNamespace()) {
+ NamedDecl *TagD = Vec.back();
+ Vec.back() = D;
Vec.push_back(TagD);
} else
- Vec.push_back(reinterpret_cast<uintptr_t>(D));
+ Vec.push_back(D);
}
};
Modified: cfe/trunk/include/clang/AST/ExternalASTSource.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExternalASTSource.h?rev=111636&r1=111635&r2=111636&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExternalASTSource.h (original)
+++ cfe/trunk/include/clang/AST/ExternalASTSource.h Fri Aug 20 11:04:35 2010
@@ -27,18 +27,6 @@
class ExternalSemaSource; // layering violation required for downcasting
class Stmt;
-/// \brief The deserialized representation of a set of declarations
-/// with the same name that are visible in a given context.
-struct VisibleDeclaration {
- /// \brief The name of the declarations.
- DeclarationName Name;
-
- /// \brief The ID numbers of all of the declarations with this name.
- ///
- /// These declarations have not necessarily been de-serialized.
- llvm::SmallVector<unsigned, 4> Declarations;
-};
-
/// \brief Abstract interface for external sources of AST nodes.
///
/// External AST sources provide AST nodes constructed from some
@@ -140,22 +128,6 @@
virtual void PrintStats();
protected:
- /// \brief Initialize the context's lookup map with the given decls.
- /// It is assumed that none of the declarations are redeclarations of
- /// each other.
- static void SetExternalVisibleDecls(const DeclContext *DC,
- const llvm::SmallVectorImpl<VisibleDeclaration> &Decls);
-
- /// \brief Initialize the context's lookup map with the given decls.
- /// It is assumed that none of the declarations are redeclarations of
- /// each other.
- static void SetExternalVisibleDecls(const DeclContext *DC,
- const llvm::SmallVectorImpl<NamedDecl*> &Decls);
-
- static DeclContext::lookup_result
- SetExternalVisibleDeclsForName(const DeclContext *DC,
- const VisibleDeclaration &VD);
-
static DeclContext::lookup_result
SetExternalVisibleDeclsForName(const DeclContext *DC,
DeclarationName Name,
Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=111636&r1=111635&r2=111636&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Fri Aug 20 11:04:35 2010
@@ -339,8 +339,7 @@
/// \brief Information about the contents of a DeclContext.
struct DeclContextInfo {
- llvm::BitstreamCursor *Stream;
- uint64_t OffsetToVisibleDecls;
+ void *NameLookupTableData; // a ASTDeclContextNameLookupTable.
const serialization::DeclID *LexicalDecls;
unsigned NumLexicalDecls;
};
Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=111636&r1=111635&r2=111636&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTWriter.h Fri Aug 20 11:04:35 2010
@@ -268,6 +268,7 @@
unsigned ParmVarDeclAbbrev;
unsigned DeclContextLexicalAbbrev;
+ unsigned DeclContextVisibleLookupAbbrev;
void WriteDeclsBlockAbbrevs();
void WriteDecl(ASTContext &Context, Decl *D);
Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=111636&r1=111635&r2=111636&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Fri Aug 20 11:04:35 2010
@@ -648,19 +648,6 @@
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);
-}
-
-DeclContext::lookup_result
-ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC,
DeclarationName Name,
llvm::SmallVectorImpl<NamedDecl*> &Decls) {
ASTContext &Context = DC->getParentASTContext();;
@@ -677,35 +664,7 @@
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]);
- }
+ return List.getLookupResult();
}
DeclContext::decl_iterator DeclContext::noload_decls_begin() const {
@@ -841,7 +800,7 @@
if (LookupPtr) {
StoredDeclsMap::iterator I = LookupPtr->find(Name);
if (I != LookupPtr->end())
- return I->second.getLookupResult(getParentASTContext());
+ return I->second.getLookupResult();
}
ExternalASTSource *Source = getParentASTContext().getExternalSource();
@@ -861,7 +820,7 @@
StoredDeclsMap::iterator Pos = LookupPtr->find(Name);
if (Pos == LookupPtr->end())
return lookup_result(lookup_iterator(0), lookup_iterator(0));
- return Pos->second.getLookupResult(getParentASTContext());
+ return Pos->second.getLookupResult();
}
DeclContext::lookup_const_result
@@ -925,18 +884,21 @@
if (isa<ClassTemplateSpecializationDecl>(D))
return;
- // If there is an external AST source, load any declarations it knows about
- // with this declaration's name.
- if (ExternalASTSource *Source = getParentASTContext().getExternalSource())
- if (hasExternalVisibleStorage())
- Source->FindExternalVisibleDeclsByName(this, D->getDeclName());
-
ASTContext *C = 0;
if (!LookupPtr) {
C = &getParentASTContext();
CreateStoredDeclsMap(*C);
}
+ // If there is an external AST source, load any declarations it knows about
+ // with this declaration's name.
+ // If the lookup table contains an entry about this name it means that we
+ // have already checked the external source.
+ if (ExternalASTSource *Source = getParentASTContext().getExternalSource())
+ if (hasExternalVisibleStorage() &&
+ LookupPtr->find(D->getDeclName()) == LookupPtr->end())
+ Source->FindExternalVisibleDeclsByName(this, D->getDeclName());
+
// Insert this declaration into the map.
StoredDeclsList &DeclNameEntries = (*LookupPtr)[D->getDeclName()];
if (DeclNameEntries.isNull()) {
@@ -947,10 +909,7 @@
// If it is possible that this is a redeclaration, check to see if there is
// already a decl for which declarationReplaces returns true. If there is
// one, just replace it and return.
- if (!C)
- C = &getParentASTContext();
-
- if (DeclNameEntries.HandleRedeclaration(*C, D))
+ if (DeclNameEntries.HandleRedeclaration(D))
return;
// Put this declaration into the appropriate slot.
@@ -966,43 +925,6 @@
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->GetExternalDecl(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->GetExternalDecl(Vector[I]));
-
- Data = (Data & ~0x03) | DK_Decl_Vector;
- break;
- }
- }
-}
-
//===----------------------------------------------------------------------===//
// Creation and Destruction of StoredDeclsMaps. //
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=111636&r1=111635&r2=111636&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri Aug 20 11:04:35 2010
@@ -846,6 +846,54 @@
typedef OnDiskChainedHashTable<ASTDeclContextNameLookupTrait>
ASTDeclContextNameLookupTable;
+bool ASTReader::ReadDeclContextStorage(llvm::BitstreamCursor &Cursor,
+ const std::pair<uint64_t, uint64_t> &Offsets,
+ DeclContextInfo &Info) {
+ SavedStreamPosition SavedPosition(Cursor);
+ // First the lexical decls.
+ if (Offsets.first != 0) {
+ Cursor.JumpToBit(Offsets.first);
+
+ RecordData Record;
+ const char *Blob;
+ unsigned BlobLen;
+ unsigned Code = Cursor.ReadCode();
+ unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen);
+ if (RecCode != DECL_CONTEXT_LEXICAL) {
+ Error("Expected lexical block");
+ return true;
+ }
+
+ Info.LexicalDecls = reinterpret_cast<const DeclID*>(Blob);
+ Info.NumLexicalDecls = BlobLen / sizeof(DeclID);
+ } else {
+ Info.LexicalDecls = 0;
+ Info.NumLexicalDecls = 0;
+ }
+
+ // Now the lookup table.
+ if (Offsets.second != 0) {
+ Cursor.JumpToBit(Offsets.second);
+
+ RecordData Record;
+ const char *Blob;
+ unsigned BlobLen;
+ unsigned Code = Cursor.ReadCode();
+ unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen);
+ if (RecCode != DECL_CONTEXT_VISIBLE) {
+ Error("Expected visible lookup table block");
+ return true;
+ }
+ Info.NameLookupTableData
+ = ASTDeclContextNameLookupTable::Create(
+ (const unsigned char *)Blob + Record[0],
+ (const unsigned char *)Blob,
+ ASTDeclContextNameLookupTrait(*this));
+ }
+
+ return false;
+}
+
void ASTReader::Error(const char *Msg) {
Diag(diag::err_fe_pch_malformed) << Msg;
}
@@ -1674,7 +1722,7 @@
case TU_UPDATE_LEXICAL: {
DeclContextInfo Info = {
- /* No visible information */ 0, 0,
+ /* No visible information */ 0,
reinterpret_cast<const DeclID *>(BlobStart),
BlobLen / sizeof(DeclID)
};
@@ -3119,54 +3167,33 @@
DeclarationName Name) {
assert(DC->hasExternalVisibleStorage() &&
"DeclContext has no visible decls in storage");
+ if (!Name)
+ return DeclContext::lookup_result(DeclContext::lookup_iterator(0),
+ DeclContext::lookup_iterator(0));
- llvm::SmallVector<VisibleDeclaration, 64> Decls;
+ llvm::SmallVector<NamedDecl *, 64> Decls;
// There might be lexical decls in multiple parts of the chain, for the TU
// and namespaces.
DeclContextInfos &Infos = DeclContextOffsets[DC];
for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end();
I != E; ++I) {
- uint64_t Offset = I->OffsetToVisibleDecls;
- if (Offset == 0)
+ if (!I->NameLookupTableData)
continue;
- llvm::BitstreamCursor &DeclsCursor = *I->Stream;
-
- // Keep track of where we are in the stream, then jump back there
- // after reading this context.
- SavedStreamPosition SavedPosition(DeclsCursor);
-
- // Load the record containing all of the declarations visible in
- // this context.
- DeclsCursor.JumpToBit(Offset);
- RecordData Record;
- unsigned Code = DeclsCursor.ReadCode();
- unsigned RecCode = DeclsCursor.ReadRecord(Code, Record);
- if (RecCode != DECL_CONTEXT_VISIBLE) {
- Error("Expected visible block");
- return DeclContext::lookup_result(DeclContext::lookup_iterator(),
- DeclContext::lookup_iterator());
- }
-
- if (Record.empty())
+ ASTDeclContextNameLookupTable *LookupTable =
+ (ASTDeclContextNameLookupTable*)I->NameLookupTableData;
+ ASTDeclContextNameLookupTable::iterator Pos = LookupTable->find(Name);
+ if (Pos == LookupTable->end())
continue;
- unsigned Idx = 0;
- while (Idx < Record.size()) {
- Decls.push_back(VisibleDeclaration());
- Decls.back().Name = ReadDeclarationName(Record, Idx);
-
- unsigned Size = Record[Idx++];
- llvm::SmallVector<unsigned, 4> &LoadedDecls = Decls.back().Declarations;
- LoadedDecls.reserve(Size);
- for (unsigned J = 0; J < Size; ++J)
- LoadedDecls.push_back(Record[Idx++]);
- }
+ ASTDeclContextNameLookupTrait::data_type Data = *Pos;
+ for (; Data.first != Data.second; ++Data.first)
+ Decls.push_back(cast<NamedDecl>(GetDecl(*Data.first)));
}
++NumVisibleDeclContextsRead;
- SetExternalVisibleDecls(DC, Decls);
+ SetExternalVisibleDeclsForName(DC, Name, Decls);
return const_cast<DeclContext*>(DC)->lookup(Name);
}
Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=111636&r1=111635&r2=111636&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Fri Aug 20 11:04:35 2010
@@ -1413,35 +1413,3 @@
return D;
}
-
-bool ASTReader::ReadDeclContextStorage(llvm::BitstreamCursor &Cursor,
- const std::pair<uint64_t, uint64_t> &Offsets,
- DeclContextInfo &Info) {
- SavedStreamPosition SavedPosition(Cursor);
- // First the lexical decls.
- if (Offsets.first != 0) {
- Cursor.JumpToBit(Offsets.first);
-
- RecordData Record;
- const char *Blob;
- unsigned BlobLen;
- unsigned Code = Cursor.ReadCode();
- unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen);
- if (RecCode != DECL_CONTEXT_LEXICAL) {
- Error("Expected lexical block");
- return true;
- }
-
- Info.LexicalDecls = reinterpret_cast<const DeclID*>(Blob);
- Info.NumLexicalDecls = BlobLen / sizeof(DeclID);
- } else {
- Info.LexicalDecls = 0;
- Info.NumLexicalDecls = 0;
- }
-
- // Now the visible decls.
- Info.Stream = &Cursor;
- Info.OffsetToVisibleDecls = Offsets.second;
-
- return false;
-}
Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=111636&r1=111635&r2=111636&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Fri Aug 20 11:04:35 2010
@@ -1466,59 +1466,6 @@
return Offset;
}
-/// \brief Write the block containing all of the declaration IDs
-/// visible from the given DeclContext.
-///
-/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the
-/// bistream, or 0 if no block was written.
-uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
- DeclContext *DC) {
- if (DC->getPrimaryContext() != DC)
- return 0;
-
- // Since there is no name lookup into functions or methods, don't bother to
- // build a visible-declarations table for these entities.
- if (DC->isFunctionOrMethod())
- return 0;
-
- // If not in C++, we perform name lookup for the translation unit via the
- // IdentifierInfo chains, don't bother to build a visible-declarations table.
- // FIXME: In C++ we need the visible declarations in order to "see" the
- // friend declarations, is there a way to do this without writing the table ?
- if (DC->isTranslationUnit() && !Context.getLangOptions().CPlusPlus)
- return 0;
-
- // Force the DeclContext to build a its name-lookup table.
- DC->lookup(DeclarationName());
-
- // Serialize the contents of the mapping used for lookup. Note that,
- // although we have two very different code paths, the serialized
- // representation is the same for both cases: a declaration name,
- // followed by a size, followed by references to the visible
- // declarations that have that name.
- uint64_t Offset = Stream.GetCurrentBitNo();
- RecordData Record;
- StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr());
- if (!Map)
- return 0;
-
- for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
- D != DEnd; ++D) {
- AddDeclarationName(D->first, Record);
- DeclContext::lookup_result Result = D->second.getLookupResult(Context);
- Record.push_back(Result.second - Result.first);
- for (; Result.first != Result.second; ++Result.first)
- AddDeclRef(*Result.first, Record);
- }
-
- if (Record.size() == 0)
- return 0;
-
- Stream.EmitRecord(DECL_CONTEXT_VISIBLE, Record);
- ++NumVisibleDeclContexts;
- return Offset;
-}
-
void ASTWriter::WriteTypeDeclOffsets() {
using namespace llvm;
RecordData Record;
@@ -2062,6 +2009,74 @@
};
} // end anonymous namespace
+/// \brief Write the block containing all of the declaration IDs
+/// visible from the given DeclContext.
+///
+/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the
+/// bistream, or 0 if no block was written.
+uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
+ DeclContext *DC) {
+ if (DC->getPrimaryContext() != DC)
+ return 0;
+
+ // Since there is no name lookup into functions or methods, don't bother to
+ // build a visible-declarations table for these entities.
+ if (DC->isFunctionOrMethod())
+ return 0;
+
+ // If not in C++, we perform name lookup for the translation unit via the
+ // IdentifierInfo chains, don't bother to build a visible-declarations table.
+ // FIXME: In C++ we need the visible declarations in order to "see" the
+ // friend declarations, is there a way to do this without writing the table ?
+ if (DC->isTranslationUnit() && !Context.getLangOptions().CPlusPlus)
+ return 0;
+
+ // Force the DeclContext to build a its name-lookup table.
+ DC->lookup(DeclarationName());
+
+ // Serialize the contents of the mapping used for lookup. Note that,
+ // although we have two very different code paths, the serialized
+ // representation is the same for both cases: a declaration name,
+ // followed by a size, followed by references to the visible
+ // declarations that have that name.
+ uint64_t Offset = Stream.GetCurrentBitNo();
+ StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr());
+ if (!Map || Map->empty())
+ return 0;
+
+ OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait> Generator;
+ ASTDeclContextNameLookupTrait Trait(*this);
+
+ // Create the on-disk hash table representation.
+ for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
+ D != DEnd; ++D) {
+ DeclarationName Name = D->first;
+ DeclContext::lookup_result Result = D->second.getLookupResult();
+ Generator.insert(Name, Result, Trait);
+ }
+
+ // Create the on-disk hash table in a buffer.
+ llvm::SmallString<4096> LookupTable;
+ uint32_t BucketOffset;
+ {
+ llvm::raw_svector_ostream Out(LookupTable);
+ // Make sure that no bucket is at offset 0
+ clang::io::Emit32(Out, 0);
+ BucketOffset = Generator.Emit(Out, Trait);
+ }
+
+ // Write the lookup table
+ RecordData Record;
+ Record.push_back(DECL_CONTEXT_VISIBLE);
+ Record.push_back(BucketOffset);
+ Stream.EmitRecordWithBlob(DeclContextVisibleLookupAbbrev, Record,
+ LookupTable.str());
+
+ Stream.EmitRecord(DECL_CONTEXT_VISIBLE, Record);
+ ++NumVisibleDeclContexts;
+ return Offset;
+}
+
//===----------------------------------------------------------------------===//
// General Serialization Routines
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=111636&r1=111635&r2=111636&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Fri Aug 20 11:04:35 2010
@@ -1086,6 +1086,12 @@
Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_LEXICAL));
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
DeclContextLexicalAbbrev = Stream.EmitAbbrev(Abv);
+
+ Abv = new BitCodeAbbrev();
+ Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_VISIBLE));
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
+ DeclContextVisibleLookupAbbrev = Stream.EmitAbbrev(Abv);
}
/// isRequiredDecl - Check if this is a "required" Decl, which must be seen by
More information about the cfe-commits
mailing list