aboutsummaryrefslogtreecommitdiff
path: root/lib/Serialization/ASTReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Serialization/ASTReader.cpp')
-rw-r--r--lib/Serialization/ASTReader.cpp155
1 files changed, 91 insertions, 64 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 48a898cb30da..3045629a333e 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -845,7 +845,7 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,
}
unsigned
-ASTDeclContextNameLookupTrait::ComputeHash(const DeclNameKey &Key) const {
+ASTDeclContextNameLookupTrait::ComputeHash(const DeclNameKey &Key) {
llvm::FoldingSetNodeID ID;
ID.AddInteger(Key.Kind);
@@ -874,7 +874,7 @@ ASTDeclContextNameLookupTrait::ComputeHash(const DeclNameKey &Key) const {
ASTDeclContextNameLookupTrait::internal_key_type
ASTDeclContextNameLookupTrait::GetInternalKey(
- const external_key_type& Name) const {
+ const external_key_type& Name) {
DeclNameKey Key;
Key.Kind = Name.getNameKind();
switch (Name.getNameKind()) {
@@ -1644,6 +1644,7 @@ namespace {
/// \brief Visitor class used to look up identifirs in an AST file.
class IdentifierLookupVisitor {
StringRef Name;
+ unsigned NameHash;
unsigned PriorGeneration;
unsigned &NumIdentifierLookups;
unsigned &NumIdentifierLookupHits;
@@ -1653,7 +1654,8 @@ namespace {
IdentifierLookupVisitor(StringRef Name, unsigned PriorGeneration,
unsigned &NumIdentifierLookups,
unsigned &NumIdentifierLookupHits)
- : Name(Name), PriorGeneration(PriorGeneration),
+ : Name(Name), NameHash(ASTIdentifierLookupTrait::ComputeHash(Name)),
+ PriorGeneration(PriorGeneration),
NumIdentifierLookups(NumIdentifierLookups),
NumIdentifierLookupHits(NumIdentifierLookupHits),
Found()
@@ -1676,7 +1678,8 @@ namespace {
ASTIdentifierLookupTrait Trait(IdTable->getInfoObj().getReader(),
M, This->Found);
++This->NumIdentifierLookups;
- ASTIdentifierLookupTable::iterator Pos = IdTable->find(This->Name,&Trait);
+ ASTIdentifierLookupTable::iterator Pos =
+ IdTable->find_hashed(This->Name, This->NameHash, &Trait);
if (Pos == IdTable->end())
return false;
@@ -3976,8 +3979,7 @@ bool ASTReader::readASTFileControlBlock(
// Initialize the stream
llvm::BitstreamReader StreamFile;
- StreamFile.init((const unsigned char *)(*Buffer)->getBufferStart(),
- (const unsigned char *)(*Buffer)->getBufferEnd());
+ PCHContainerOps.ExtractPCH((*Buffer)->getMemBufferRef(), StreamFile);
BitstreamCursor Stream(StreamFile);
// Sniff for the signature.
@@ -5263,11 +5265,16 @@ QualType ASTReader::readTypeRecord(unsigned Index) {
case TYPE_OBJC_OBJECT: {
unsigned Idx = 0;
QualType Base = readType(*Loc.F, Record, Idx);
+ unsigned NumTypeArgs = Record[Idx++];
+ SmallVector<QualType, 4> TypeArgs;
+ for (unsigned I = 0; I != NumTypeArgs; ++I)
+ TypeArgs.push_back(readType(*Loc.F, Record, Idx));
unsigned NumProtos = Record[Idx++];
SmallVector<ObjCProtocolDecl*, 4> Protos;
for (unsigned I = 0; I != NumProtos; ++I)
Protos.push_back(ReadDeclAs<ObjCProtocolDecl>(*Loc.F, Record, Idx));
- return Context.getObjCObjectType(Base, Protos.data(), NumProtos);
+ bool IsKindOf = Record[Idx++];
+ return Context.getObjCObjectType(Base, TypeArgs, Protos, IsKindOf);
}
case TYPE_OBJC_OBJECT_POINTER: {
@@ -5646,8 +5653,12 @@ void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
}
void TypeLocReader::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
TL.setHasBaseTypeAsWritten(Record[Idx++]);
- TL.setLAngleLoc(ReadSourceLocation(Record, Idx));
- TL.setRAngleLoc(ReadSourceLocation(Record, Idx));
+ TL.setTypeArgsLAngleLoc(ReadSourceLocation(Record, Idx));
+ TL.setTypeArgsRAngleLoc(ReadSourceLocation(Record, Idx));
+ for (unsigned i = 0, e = TL.getNumTypeArgs(); i != e; ++i)
+ TL.setTypeArgTInfo(i, Reader.GetTypeSourceInfo(F, Record, Idx));
+ TL.setProtocolLAngleLoc(ReadSourceLocation(Record, Idx));
+ TL.setProtocolRAngleLoc(ReadSourceLocation(Record, Idx));
for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
TL.setProtocolLoc(i, ReadSourceLocation(Record, Idx));
}
@@ -5987,9 +5998,8 @@ bool ASTReader::isDeclIDFromModule(serialization::GlobalDeclID ID,
if (ID < NUM_PREDEF_DECL_IDS)
return false;
- GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(ID);
- assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");
- return &M == I->second;
+ return ID - NUM_PREDEF_DECL_IDS >= M.BaseDeclID &&
+ ID - NUM_PREDEF_DECL_IDS < M.BaseDeclID + M.LocalNumDecls;
}
ModuleFile *ASTReader::getOwningModuleFile(const Decl *D) {
@@ -6063,7 +6073,7 @@ Decl *ASTReader::GetExistingDecl(DeclID ID) {
if (D) {
// Track that we have merged the declaration with ID \p ID into the
// pre-existing predefined declaration \p D.
- auto &Merged = MergedDecls[D->getCanonicalDecl()];
+ auto &Merged = KeyDecls[D->getCanonicalDecl()];
if (Merged.empty())
Merged.push_back(ID);
}
@@ -6288,6 +6298,27 @@ void ASTReader::FindFileRegionDecls(FileID File,
Decls.push_back(GetDecl(getGlobalDeclID(*DInfo.Mod, *DIt)));
}
+/// \brief Retrieve the "definitive" module file for the definition of the
+/// given declaration context, if there is one.
+///
+/// The "definitive" module file is the only place where we need to look to
+/// find information about the declarations within the given declaration
+/// context. For example, C++ and Objective-C classes, C structs/unions, and
+/// Objective-C protocols, categories, and extensions are all defined in a
+/// single place in the source code, so they have definitive module files
+/// associated with them. C++ namespaces, on the other hand, can have
+/// definitions in multiple different module files.
+///
+/// Note: this needs to be kept in sync with ASTWriter::AddedVisibleDecl's
+/// NDEBUG checking.
+static ModuleFile *getDefinitiveModuleFileFor(const DeclContext *DC,
+ ASTReader &Reader) {
+ if (const DeclContext *DefDC = getDefinitiveDeclContext(DC))
+ return Reader.getOwningModuleFile(cast<Decl>(DefDC));
+
+ return nullptr;
+}
+
namespace {
/// \brief ModuleFile visitor used to perform name lookup into a
/// declaration context.
@@ -6295,18 +6326,38 @@ namespace {
ASTReader &Reader;
ArrayRef<const DeclContext *> Contexts;
DeclarationName Name;
+ ASTDeclContextNameLookupTrait::DeclNameKey NameKey;
+ unsigned NameHash;
SmallVectorImpl<NamedDecl *> &Decls;
llvm::SmallPtrSetImpl<NamedDecl *> &DeclSet;
public:
DeclContextNameLookupVisitor(ASTReader &Reader,
- ArrayRef<const DeclContext *> Contexts,
DeclarationName Name,
SmallVectorImpl<NamedDecl *> &Decls,
llvm::SmallPtrSetImpl<NamedDecl *> &DeclSet)
- : Reader(Reader), Contexts(Contexts), Name(Name), Decls(Decls),
- DeclSet(DeclSet) { }
+ : Reader(Reader), Name(Name),
+ NameKey(ASTDeclContextNameLookupTrait::GetInternalKey(Name)),
+ NameHash(ASTDeclContextNameLookupTrait::ComputeHash(NameKey)),
+ Decls(Decls), DeclSet(DeclSet) {}
+
+ void visitContexts(ArrayRef<const DeclContext*> Contexts) {
+ if (Contexts.empty())
+ return;
+ this->Contexts = Contexts;
+
+ // If we can definitively determine which module file to look into,
+ // only look there. Otherwise, look in all module files.
+ ModuleFile *Definitive;
+ if (Contexts.size() == 1 &&
+ (Definitive = getDefinitiveModuleFileFor(Contexts[0], Reader))) {
+ visit(*Definitive, this);
+ } else {
+ Reader.getModuleManager().visit(&visit, this);
+ }
+ }
+ private:
static bool visit(ModuleFile &M, void *UserData) {
DeclContextNameLookupVisitor *This
= static_cast<DeclContextNameLookupVisitor *>(UserData);
@@ -6331,7 +6382,7 @@ namespace {
ASTDeclContextNameLookupTable *LookupTable =
Info->second.NameLookupTableData;
ASTDeclContextNameLookupTable::iterator Pos
- = LookupTable->find(This->Name);
+ = LookupTable->find_hashed(This->NameKey, This->NameHash);
if (Pos == LookupTable->end())
return false;
@@ -6363,27 +6414,6 @@ namespace {
};
}
-/// \brief Retrieve the "definitive" module file for the definition of the
-/// given declaration context, if there is one.
-///
-/// The "definitive" module file is the only place where we need to look to
-/// find information about the declarations within the given declaration
-/// context. For example, C++ and Objective-C classes, C structs/unions, and
-/// Objective-C protocols, categories, and extensions are all defined in a
-/// single place in the source code, so they have definitive module files
-/// associated with them. C++ namespaces, on the other hand, can have
-/// definitions in multiple different module files.
-///
-/// Note: this needs to be kept in sync with ASTWriter::AddedVisibleDecl's
-/// NDEBUG checking.
-static ModuleFile *getDefinitiveModuleFileFor(const DeclContext *DC,
- ASTReader &Reader) {
- if (const DeclContext *DefDC = getDefinitiveDeclContext(DC))
- return Reader.getOwningModuleFile(cast<Decl>(DefDC));
-
- return nullptr;
-}
-
bool
ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) {
@@ -6405,28 +6435,15 @@ ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
Contexts.push_back(DC);
if (DC->isNamespace()) {
- auto Merged = MergedDecls.find(const_cast<Decl *>(cast<Decl>(DC)));
- if (Merged != MergedDecls.end()) {
- for (unsigned I = 0, N = Merged->second.size(); I != N; ++I)
- Contexts.push_back(cast<DeclContext>(GetDecl(Merged->second[I])));
+ auto Key = KeyDecls.find(const_cast<Decl *>(cast<Decl>(DC)));
+ if (Key != KeyDecls.end()) {
+ for (unsigned I = 0, N = Key->second.size(); I != N; ++I)
+ Contexts.push_back(cast<DeclContext>(GetDecl(Key->second[I])));
}
}
- auto LookUpInContexts = [&](ArrayRef<const DeclContext*> Contexts) {
- DeclContextNameLookupVisitor Visitor(*this, Contexts, Name, Decls, DeclSet);
-
- // If we can definitively determine which module file to look into,
- // only look there. Otherwise, look in all module files.
- ModuleFile *Definitive;
- if (Contexts.size() == 1 &&
- (Definitive = getDefinitiveModuleFileFor(Contexts[0], *this))) {
- DeclContextNameLookupVisitor::visit(*Definitive, &Visitor);
- } else {
- ModuleMgr.visit(&DeclContextNameLookupVisitor::visit, &Visitor);
- }
- };
-
- LookUpInContexts(Contexts);
+ DeclContextNameLookupVisitor Visitor(*this, Name, Decls, DeclSet);
+ Visitor.visitContexts(Contexts);
// If this might be an implicit special member function, then also search
// all merged definitions of the surrounding class. We need to search them
@@ -6437,7 +6454,7 @@ ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
if (Merged != MergedLookups.end()) {
for (unsigned I = 0; I != Merged->second.size(); ++I) {
const DeclContext *Context = Merged->second[I];
- LookUpInContexts(Context);
+ Visitor.visitContexts(Context);
// We might have just added some more merged lookups. If so, our
// iterator is now invalid, so grab a fresh one before continuing.
Merged = MergedLookups.find(DC);
@@ -6525,11 +6542,11 @@ void ASTReader::completeVisibleDeclsMap(const DeclContext *DC) {
Contexts.push_back(DC);
if (DC->isNamespace()) {
- MergedDeclsMap::iterator Merged
- = MergedDecls.find(const_cast<Decl *>(cast<Decl>(DC)));
- if (Merged != MergedDecls.end()) {
- for (unsigned I = 0, N = Merged->second.size(); I != N; ++I)
- Contexts.push_back(cast<DeclContext>(GetDecl(Merged->second[I])));
+ KeyDeclsMap::iterator Key =
+ KeyDecls.find(const_cast<Decl *>(cast<Decl>(DC)));
+ if (Key != KeyDecls.end()) {
+ for (unsigned I = 0, N = Key->second.size(); I != N; ++I)
+ Contexts.push_back(cast<DeclContext>(GetDecl(Key->second[I])));
}
}
@@ -8389,6 +8406,11 @@ void ASTReader::diagnoseOdrViolations() {
}
}
+void ASTReader::StartedDeserializing() {
+ if (++NumCurrentElementsDeserializing == 1 && ReadTimer.get())
+ ReadTimer->startTimer();
+}
+
void ASTReader::FinishedDeserializing() {
assert(NumCurrentElementsDeserializing &&
"FinishedDeserializing not paired with StartedDeserializing");
@@ -8413,6 +8435,9 @@ void ASTReader::FinishedDeserializing() {
diagnoseOdrViolations();
+ if (ReadTimer)
+ ReadTimer->stopTimer();
+
// We are not in recursive loading, so it's safe to pass the "interesting"
// decls to the consumer.
if (Consumer)
@@ -8451,12 +8476,14 @@ ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context,
StringRef isysroot, bool DisableValidation,
bool AllowASTWithCompilerErrors,
bool AllowConfigurationMismatch, bool ValidateSystemInputs,
- bool UseGlobalIndex)
+ bool UseGlobalIndex,
+ std::unique_ptr<llvm::Timer> ReadTimer)
: Listener(new PCHValidator(PP, *this)), DeserializationListener(nullptr),
OwnsDeserializationListener(false), SourceMgr(PP.getSourceManager()),
FileMgr(PP.getFileManager()), PCHContainerOps(PCHContainerOps),
Diags(PP.getDiagnostics()), SemaObj(nullptr), PP(PP), Context(Context),
Consumer(nullptr), ModuleMgr(PP.getFileManager(), PCHContainerOps),
+ ReadTimer(std::move(ReadTimer)),
isysroot(isysroot), DisableValidation(DisableValidation),
AllowASTWithCompilerErrors(AllowASTWithCompilerErrors),
AllowConfigurationMismatch(AllowConfigurationMismatch),