aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Sema/ExternalSemaSource.h10
-rw-r--r--include/clang/Sema/Sema.h6
-rw-r--r--include/clang/Serialization/ASTReader.h3
-rw-r--r--lib/Sema/SemaDecl.cpp23
-rw-r--r--lib/Serialization/ASTReader.cpp21
-rw-r--r--lib/Serialization/ASTWriter.cpp8
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);