diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp | 155 |
1 files changed, 91 insertions, 64 deletions
diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp index 48a898c..3045629 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp +++ b/contrib/llvm/tools/clang/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), |