diff options
author | Axel Naumann <Axel.Naumann@cern.ch> | 2012-10-18 19:05:02 +0000 |
---|---|---|
committer | Axel Naumann <Axel.Naumann@cern.ch> | 2012-10-18 19:05:02 +0000 |
commit | 0ec56b7add7be643f490ea9b430823570f01b4e2 (patch) | |
tree | 189684b9950f5764637688eb562141c7a0e0b288 /lib | |
parent | 39c497b6d5e99acecbe03ee173249ee21933e855 (diff) |
From Vassil Vassilev: enable Sema to deal with multiple ExternalSemaSources.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166208 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/Sema/MultiplexExternalSemaSource.cpp | 271 | ||||
-rw-r--r-- | lib/Sema/Sema.cpp | 31 | ||||
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaExprMember.cpp | 2 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 2 |
7 files changed, 307 insertions, 8 deletions
diff --git a/lib/Sema/CMakeLists.txt b/lib/Sema/CMakeLists.txt index f554b5ca9b..7cfe3ae846 100644 --- a/lib/Sema/CMakeLists.txt +++ b/lib/Sema/CMakeLists.txt @@ -13,6 +13,7 @@ add_clang_library(clangSema DelayedDiagnostic.cpp IdentifierResolver.cpp JumpDiagnostics.cpp + MultiplexExternalSemaSource.cpp Scope.cpp ScopeInfo.cpp Sema.cpp diff --git a/lib/Sema/MultiplexExternalSemaSource.cpp b/lib/Sema/MultiplexExternalSemaSource.cpp new file mode 100644 index 0000000000..f930fb348a --- /dev/null +++ b/lib/Sema/MultiplexExternalSemaSource.cpp @@ -0,0 +1,271 @@ +//===--- MultiplexExternalSemaSource.cpp ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the event dispatching to the subscribed clients. +// +//===----------------------------------------------------------------------===// +#include "clang/Sema/MultiplexExternalSemaSource.h" + +#include "clang/AST/DeclContextInternals.h" +#include "clang/Sema/Lookup.h" + +using namespace clang; + +///\brief Constructs a new multiplexing external sema source and appends the +/// given element to it. +/// +///\param[in] source - An ExternalSemaSource. +/// +MultiplexExternalSemaSource::MultiplexExternalSemaSource(ExternalSemaSource &s1, + ExternalSemaSource &s2){ + Sources.push_back(&s1); + Sources.push_back(&s2); +} + +// pin the vtable here. +MultiplexExternalSemaSource::~MultiplexExternalSemaSource() {} + +///\brief Appends new source to the source list. +/// +///\param[in] source - An ExternalSemaSource. +/// +void MultiplexExternalSemaSource::addSource(ExternalSemaSource &source) { + Sources.push_back(&source); +} + +//===----------------------------------------------------------------------===// +// ExternalASTSource. +//===----------------------------------------------------------------------===// + +Decl *MultiplexExternalSemaSource::GetExternalDecl(uint32_t ID) { + for(size_t i = 0; i < Sources.size(); ++i) + if (Decl *Result = Sources[i]->GetExternalDecl(ID)) + return Result; + return 0; +} + +Selector MultiplexExternalSemaSource::GetExternalSelector(uint32_t ID) { + Selector Sel; + for(size_t i = 0; i < Sources.size(); ++i) { + Sel = Sources[i]->GetExternalSelector(ID); + if (!Sel.isNull()) + return Sel; + } + return Sel; +} + +uint32_t MultiplexExternalSemaSource::GetNumExternalSelectors() { + uint32_t total = 0; + for(size_t i = 0; i < Sources.size(); ++i) + total += Sources[i]->GetNumExternalSelectors(); + return total; +} + +Stmt *MultiplexExternalSemaSource::GetExternalDeclStmt(uint64_t Offset) { + for(size_t i = 0; i < Sources.size(); ++i) + if (Stmt *Result = Sources[i]->GetExternalDeclStmt(Offset)) + return Result; + return 0; +} + +CXXBaseSpecifier *MultiplexExternalSemaSource::GetExternalCXXBaseSpecifiers( + uint64_t Offset){ + for(size_t i = 0; i < Sources.size(); ++i) + if (CXXBaseSpecifier *R = Sources[i]->GetExternalCXXBaseSpecifiers(Offset)) + return R; + return 0; +} + +DeclContextLookupResult MultiplexExternalSemaSource:: +FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) { + StoredDeclsList DeclsFound; + DeclContextLookupResult lookup; + for(size_t i = 0; i < Sources.size(); ++i) { + lookup = Sources[i]->FindExternalVisibleDeclsByName(DC, Name); + while(lookup.first != lookup.second) { + if (!DeclsFound.HandleRedeclaration(*lookup.first)) + DeclsFound.AddSubsequentDecl(*lookup.first); + lookup.first++; + } + } + return DeclsFound.getLookupResult(); +} + +void MultiplexExternalSemaSource::completeVisibleDeclsMap(const DeclContext *DC){ + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->completeVisibleDeclsMap(DC); +} + +ExternalLoadResult MultiplexExternalSemaSource:: +FindExternalLexicalDecls(const DeclContext *DC, + bool (*isKindWeWant)(Decl::Kind), + SmallVectorImpl<Decl*> &Result) { + for(size_t i = 0; i < Sources.size(); ++i) + // FIXME: The semantics of the return result is unclear to me... + Sources[i]->FindExternalLexicalDecls(DC, isKindWeWant, Result); + + return ELR_Success; +} + +void MultiplexExternalSemaSource::FindFileRegionDecls(FileID File, + unsigned Offset, + unsigned Length, + SmallVectorImpl<Decl *> &Decls){ + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->FindFileRegionDecls(File, Offset, Length, Decls); +} + +void MultiplexExternalSemaSource::CompleteType(TagDecl *Tag) { + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->CompleteType(Tag); +} + +void MultiplexExternalSemaSource::CompleteType(ObjCInterfaceDecl *Class) { + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->CompleteType(Class); +} + +void MultiplexExternalSemaSource::ReadComments() { + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->ReadComments(); +} + +void MultiplexExternalSemaSource::StartedDeserializing() { + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->StartedDeserializing(); +} + +void MultiplexExternalSemaSource::FinishedDeserializing() { + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->FinishedDeserializing(); +} + +void MultiplexExternalSemaSource::StartTranslationUnit(ASTConsumer *Consumer) { + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->StartTranslationUnit(Consumer); +} + +void MultiplexExternalSemaSource::PrintStats() { + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->PrintStats(); +} + +bool MultiplexExternalSemaSource::layoutRecordType(const RecordDecl *Record, + uint64_t &Size, + uint64_t &Alignment, + llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets, + llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets, + llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets){ + for(size_t i = 0; i < Sources.size(); ++i) + if (Sources[i]->layoutRecordType(Record, Size, Alignment, FieldOffsets, + BaseOffsets, VirtualBaseOffsets)) + return true; + return false; +} + +void MultiplexExternalSemaSource:: +getMemoryBufferSizes(MemoryBufferSizes &sizes) const { + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->getMemoryBufferSizes(sizes); + +} + +//===----------------------------------------------------------------------===// +// ExternalSemaSource. +//===----------------------------------------------------------------------===// + + +void MultiplexExternalSemaSource::InitializeSema(Sema &S) { + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->InitializeSema(S); +} + +void MultiplexExternalSemaSource::ForgetSema() { + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->ForgetSema(); +} + +void MultiplexExternalSemaSource::ReadMethodPool(Selector Sel) { + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->ReadMethodPool(Sel); +} + +void MultiplexExternalSemaSource::ReadKnownNamespaces( + SmallVectorImpl<NamespaceDecl*> &Namespaces){ + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->ReadKnownNamespaces(Namespaces); +} + +bool MultiplexExternalSemaSource::LookupUnqualified(LookupResult &R, Scope *S){ + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->LookupUnqualified(R, S); + + return !R.empty(); +} + +void MultiplexExternalSemaSource::ReadTentativeDefinitions( + SmallVectorImpl<VarDecl*> &TentativeDefs) { + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->ReadTentativeDefinitions(TentativeDefs); +} + +void MultiplexExternalSemaSource::ReadUnusedFileScopedDecls( + SmallVectorImpl<const DeclaratorDecl*> &Decls) { + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->ReadUnusedFileScopedDecls(Decls); +} + +void MultiplexExternalSemaSource::ReadDelegatingConstructors( + SmallVectorImpl<CXXConstructorDecl*> &Decls) { + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->ReadDelegatingConstructors(Decls); +} + +void MultiplexExternalSemaSource::ReadExtVectorDecls( + SmallVectorImpl<TypedefNameDecl*> &Decls) { + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->ReadExtVectorDecls(Decls); +} + +void MultiplexExternalSemaSource::ReadDynamicClasses( + SmallVectorImpl<CXXRecordDecl*> &Decls) { + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->ReadDynamicClasses(Decls); +} + +void MultiplexExternalSemaSource::ReadLocallyScopedExternalDecls( + SmallVectorImpl<NamedDecl*> &Decls) { + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->ReadLocallyScopedExternalDecls(Decls); +} + +void MultiplexExternalSemaSource::ReadReferencedSelectors( + SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) { + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->ReadReferencedSelectors(Sels); +} + +void MultiplexExternalSemaSource::ReadWeakUndeclaredIdentifiers( + SmallVectorImpl<std::pair<IdentifierInfo*, WeakInfo> > &WI) { + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->ReadWeakUndeclaredIdentifiers(WI); +} + +void MultiplexExternalSemaSource::ReadUsedVTables( + SmallVectorImpl<ExternalVTableUse> &VTables) { + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->ReadUsedVTables(VTables); +} + +void MultiplexExternalSemaSource::ReadPendingInstantiations( + SmallVectorImpl<std::pair<ValueDecl*, + SourceLocation> > &Pending) { + for(size_t i = 0; i < Sources.size(); ++i) + Sources[i]->ReadPendingInstantiations(Pending); +} diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 9a6cfaa761..eef5a2694a 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -22,6 +22,7 @@ #include "clang/Sema/CXXFieldCollector.h" #include "clang/Sema/TemplateDeduction.h" #include "clang/Sema/ExternalSemaSource.h" +#include "clang/Sema/MultiplexExternalSemaSource.h" #include "clang/Sema/ObjCMethodList.h" #include "clang/Sema/PrettyDeclStackTrace.h" #include "clang/Sema/Scope.h" @@ -68,10 +69,11 @@ void Sema::ActOnTranslationUnitScope(Scope *S) { Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, TranslationUnitKind TUKind, CodeCompleteConsumer *CodeCompleter) - : TheTargetAttributesSema(0), FPFeatures(pp.getLangOpts()), + : TheTargetAttributesSema(0), ExternalSource(0), + isMultiplexExternalSource(false), FPFeatures(pp.getLangOpts()), LangOpts(pp.getLangOpts()), PP(pp), Context(ctxt), Consumer(consumer), Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()), - CollectStats(false), ExternalSource(0), CodeCompleter(CodeCompleter), + CollectStats(false), CodeCompleter(CodeCompleter), CurContext(0), OriginalLexicalContext(0), PackContext(0), MSStructPragmaOn(false), VisContext(0), IsBuildingRecoveryCallExpr(false), @@ -188,6 +190,10 @@ Sema::~Sema() { if (ExternalSemaSource *ExternalSema = dyn_cast_or_null<ExternalSemaSource>(Context.getExternalSource())) ExternalSema->ForgetSema(); + + // If Sema's ExternalSource is the multiplexer - we own it. + if (isMultiplexExternalSource) + delete ExternalSource; } /// makeUnavailableInSystemHeader - There is an error in the current @@ -219,6 +225,27 @@ ASTMutationListener *Sema::getASTMutationListener() const { return getASTConsumer().GetASTMutationListener(); } +///\brief Registers an external source. If an external source already exists, +/// creates a multiplex external source and appends to it. +/// +///\param[in] E - A non-null external sema source. +/// +void Sema::addExternalSource(ExternalSemaSource *E) { + assert(E && "Cannot use with NULL ptr"); + + if (!ExternalSource) { + ExternalSource = E; + return; + } + + if (isMultiplexExternalSource) + static_cast<MultiplexExternalSemaSource*>(ExternalSource)->addSource(*E); + else { + ExternalSource = new MultiplexExternalSemaSource(*ExternalSource, *E); + isMultiplexExternalSource = true; + } +} + /// \brief Print out statistics about the semantic analysis. void Sema::PrintStats() const { llvm::errs() << "\n*** Semantic Analysis Stats:\n"; diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 7d352d0260..b1aead8f02 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -5340,11 +5340,11 @@ static void AddClassMessageCompletions(Sema &SemaRef, Scope *S, // If we have an external source, load the entire class method // pool from the AST file. - if (SemaRef.ExternalSource) { + if (SemaRef.getExternalSource()) { for (uint32_t I = 0, - N = SemaRef.ExternalSource->GetNumExternalSelectors(); + N = SemaRef.getExternalSource()->GetNumExternalSelectors(); I != N; ++I) { - Selector Sel = SemaRef.ExternalSource->GetExternalSelector(I); + Selector Sel = SemaRef.getExternalSource()->GetExternalSelector(I); if (Sel.isNull() || SemaRef.MethodPool.count(Sel)) continue; diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 38c05ff780..fa330d63c4 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -2582,7 +2582,7 @@ public: // with this selector before. Sema::GlobalMethodPool::iterator it = S.MethodPool.find(selector); if (it == S.MethodPool.end()) { - if (!S.ExternalSource) return; + if (!S.getExternalSource()) return; S.ReadMethodPool(selector); it = S.MethodPool.find(selector); diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp index 2b202ed9a1..a7fd47183a 100644 --- a/lib/Sema/SemaExprMember.cpp +++ b/lib/Sema/SemaExprMember.cpp @@ -354,7 +354,7 @@ CheckExtVectorComponent(Sema &S, QualType baseType, ExprValueKind &VK, // Now look up the TypeDefDecl from the vector type. Without this, // diagostics look bad. We want extended vector types to appear built-in. for (Sema::ExtVectorDeclsType::iterator - I = S.ExtVectorDecls.begin(S.ExternalSource), + I = S.ExtVectorDecls.begin(S.getExternalSource()), E = S.ExtVectorDecls.end(); I != E; ++I) { if ((*I)->getUnderlyingType() == VT) diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 20fa2794cc..489e0a6abd 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -5564,7 +5564,7 @@ void ASTReader::getMemoryBufferSizes(MemoryBufferSizes &sizes) const { void ASTReader::InitializeSema(Sema &S) { SemaObj = &S; - S.ExternalSource = this; + S.addExternalSource(this); // Makes sure any declarations that were deserialized "too early" // still get added to the identifier's declaration chains. |