diff options
-rw-r--r-- | include/clang/Sema/ExternalSemaSource.h | 10 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 6 | ||||
-rw-r--r-- | include/clang/Serialization/ASTReader.h | 3 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 23 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 21 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 8 |
6 files changed, 55 insertions, 16 deletions
diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h index a4c869b07e..c9da3fefbb 100644 --- a/include/clang/Sema/ExternalSemaSource.h +++ b/include/clang/Sema/ExternalSemaSource.h @@ -116,6 +116,16 @@ public: /// introduce the same declarations repeatedly. virtual void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls) {} + /// \brief Read the set of locally-scoped external declarations known to the + /// external Sema source. + /// + /// The external source should append its own locally-scoped external + /// declarations to the given vector of declarations. Note that this routine + /// may be invoked multiple times; the external source should take care not + /// to introduce the same declarations repeatedly. + virtual void ReadLocallyScopedExternalDecls( + SmallVectorImpl<NamedDecl *> &Decls) {} + // isa/cast/dyn_cast support static bool classof(const ExternalASTSource *Source) { return Source->SemaSource; diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index f38fdff9ed..c68852b20a 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -284,7 +284,11 @@ public: /// we find this declaration of "foo" and complain that it is /// not visible. llvm::DenseMap<DeclarationName, NamedDecl *> LocallyScopedExternalDecls; - + + /// \brief Look for a locally scoped external declaration by the given name. + llvm::DenseMap<DeclarationName, NamedDecl *>::iterator + findLocallyScopedExternalDecl(DeclarationName Name); + typedef LazyVector<VarDecl *, ExternalSemaSource, &ExternalSemaSource::ReadTentativeDefinitions, 2, 2> TentativeDefinitionsType; diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index df1251c54f..d39f2c0c20 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -1388,6 +1388,9 @@ public: virtual void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls); + virtual void ReadLocallyScopedExternalDecls( + SmallVectorImpl<NamedDecl *> &Decls); + /// \brief Load a selector from disk, registering its ID if it exists. void LoadSelector(Selector Sel); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index cb82b0c489..321ab780d4 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -3330,6 +3330,23 @@ Sema::RegisterLocallyScopedExternCDecl(NamedDecl *ND, } } +llvm::DenseMap<DeclarationName, NamedDecl *>::iterator +Sema::findLocallyScopedExternalDecl(DeclarationName Name) { + if (ExternalSource) { + // Load locally-scoped external decls from the external source. + SmallVector<NamedDecl *, 4> Decls; + ExternalSource->ReadLocallyScopedExternalDecls(Decls); + for (unsigned I = 0, N = Decls.size(); I != N; ++I) { + llvm::DenseMap<DeclarationName, NamedDecl *>::iterator Pos + = LocallyScopedExternalDecls.find(Decls[I]->getDeclName()); + if (Pos == LocallyScopedExternalDecls.end()) + LocallyScopedExternalDecls[Decls[I]->getDeclName()] = Decls[I]; + } + } + + return LocallyScopedExternalDecls.find(Name); +} + /// \brief Diagnose function specifiers on a declaration of an identifier that /// does not identify a function. void Sema::DiagnoseFunctionSpecifiers(Declarator& D) { @@ -4008,7 +4025,7 @@ void Sema::CheckVariableDeclaration(VarDecl *NewVD, // an extern "C" variable, look for a non-visible extern "C" // declaration with the same name. llvm::DenseMap<DeclarationName, NamedDecl *>::iterator Pos - = LocallyScopedExternalDecls.find(NewVD->getDeclName()); + = findLocallyScopedExternalDecl(NewVD->getDeclName()); if (Pos != LocallyScopedExternalDecls.end()) Previous.addDecl(Pos->second); } @@ -4970,7 +4987,7 @@ void Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, // an extern "C" function, look for a non-visible extern "C" // declaration with the same name. llvm::DenseMap<DeclarationName, NamedDecl *>::iterator Pos - = LocallyScopedExternalDecls.find(NewFD->getDeclName()); + = findLocallyScopedExternalDecl(NewFD->getDeclName()); if (Pos != LocallyScopedExternalDecls.end()) Previous.addDecl(Pos->second); } @@ -6584,7 +6601,7 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, // this name as a function or variable. If so, use that // (non-visible) declaration, and complain about it. llvm::DenseMap<DeclarationName, NamedDecl *>::iterator Pos - = LocallyScopedExternalDecls.find(&II); + = findLocallyScopedExternalDecl(&II); if (Pos != LocallyScopedExternalDecls.end()) { Diag(Loc, diag::warn_use_out_of_scope_declaration) << Pos->second; Diag(Pos->second->getLocation(), diag::note_previous_declaration); diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 6883f44880..4b4432e46d 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -2062,7 +2062,7 @@ ASTReader::ReadASTBlock(Module &F) { &F, /* No visible information */ 0, reinterpret_cast<const KindDeclIDPair *>(BlobStart), - BlobLen / sizeof(KindDeclIDPair) + static_cast<unsigned int>(BlobLen / sizeof(KindDeclIDPair)) }; DeclContextOffsets[Context ? Context->getTranslationUnitDecl() : 0] .push_back(Info); @@ -4349,14 +4349,6 @@ void ASTReader::InitializeSema(Sema &S) { } PreloadedDecls.clear(); - // If there were any locally-scoped external declarations, - // deserialize them and add them to Sema's table of locally-scoped - // external declarations. - for (unsigned I = 0, N = LocallyScopedExternalDecls.size(); I != N; ++I) { - NamedDecl *D = cast<NamedDecl>(GetDecl(LocallyScopedExternalDecls[I])); - SemaObj->LocallyScopedExternalDecls[D->getDeclName()] = D; - } - // FIXME: Do VTable uses and dynamic classes deserialize too much ? // Can we cut them down before writing them ? @@ -4616,6 +4608,17 @@ void ASTReader::ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls) { DynamicClasses.clear(); } +void +ASTReader::ReadLocallyScopedExternalDecls(SmallVectorImpl<NamedDecl *> &Decls) { + for (unsigned I = 0, N = LocallyScopedExternalDecls.size(); I != N; ++I) { + NamedDecl *D + = dyn_cast_or_null<NamedDecl>(GetDecl(LocallyScopedExternalDecls[I])); + if (D) + Decls.push_back(D); + } + LocallyScopedExternalDecls.clear(); +} + void ASTReader::LoadSelector(Selector Sel) { // It would be complicated to avoid reading the methods anyway. So don't. ReadMethodPool(Sel); diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 9a666910b5..e63950e826 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -2876,9 +2876,11 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, for (llvm::DenseMap<DeclarationName, NamedDecl *>::iterator TD = SemaRef.LocallyScopedExternalDecls.begin(), TDEnd = SemaRef.LocallyScopedExternalDecls.end(); - TD != TDEnd; ++TD) - AddDeclRef(TD->second, LocallyScopedExternalDecls); - + TD != TDEnd; ++TD) { + if (TD->second->getPCHLevel() == 0) + AddDeclRef(TD->second, LocallyScopedExternalDecls); + } + // Build a record containing all of the ext_vector declarations. RecordData ExtVectorDecls; AddLazyVectorDecls(*this, SemaRef.ExtVectorDecls, ExtVectorDecls); |