summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization/ASTReaderDecl.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2015-02-12 23:21:45 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2015-02-12 23:21:45 +0000
commit8807e830373233ac31be4bf4ddbe6e854e8ebae5 (patch)
tree48f1f961ca1921e7d9030a014b0d6e9d333b8a54 /clang/lib/Serialization/ASTReaderDecl.cpp
parent5779f840005af201df8f60dfab514e4cafdebd8e (diff)
downloadbcm5719-llvm-8807e830373233ac31be4bf4ddbe6e854e8ebae5.tar.gz
bcm5719-llvm-8807e830373233ac31be4bf4ddbe6e854e8ebae5.zip
[modules] When collecting declarations to complete a redeclaration chain for an
entity, put the originally-canonical decl IDs in the right places in the redecl chain rather than reordering them all to the start. If we don't ensure that the redecl chain order is consistent with the topological module order, we can fail to make a declaration visible if later declarations are in more IDNSs than earlier ones (for instance, because the earlier decls are invisible friends). llvm-svn: 228978
Diffstat (limited to 'clang/lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp30
1 files changed, 18 insertions, 12 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 5fc99b53122..8c16dfde872 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -3264,47 +3264,53 @@ void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) {
}
namespace {
- /// \brief Module visitor class that finds all of the redeclarations of a
- ///
+ /// \brief Module visitor class that finds all of the redeclarations of a
+ /// redeclarable declaration.
class RedeclChainVisitor {
ASTReader &Reader;
SmallVectorImpl<DeclID> &SearchDecls;
llvm::SmallPtrSetImpl<Decl *> &Deserialized;
GlobalDeclID CanonID;
SmallVector<Decl *, 4> Chain;
-
+
public:
RedeclChainVisitor(ASTReader &Reader, SmallVectorImpl<DeclID> &SearchDecls,
llvm::SmallPtrSetImpl<Decl *> &Deserialized,
GlobalDeclID CanonID)
: Reader(Reader), SearchDecls(SearchDecls), Deserialized(Deserialized),
- CanonID(CanonID) {
- for (unsigned I = 0, N = SearchDecls.size(); I != N; ++I)
- addToChain(Reader.GetDecl(SearchDecls[I]));
+ CanonID(CanonID) {
+ // Ensure that the canonical ID goes at the start of the chain.
+ addToChain(Reader.GetDecl(CanonID));
}
-
+
static bool visit(ModuleFile &M, bool Preorder, void *UserData) {
if (Preorder)
return false;
-
+
return static_cast<RedeclChainVisitor *>(UserData)->visit(M);
}
-
+
void addToChain(Decl *D) {
if (!D)
return;
-
+
if (Deserialized.erase(D))
Chain.push_back(D);
}
-
+
void searchForID(ModuleFile &M, GlobalDeclID GlobalID) {
// Map global ID of the first declaration down to the local ID
// used in this module file.
DeclID ID = Reader.mapGlobalIDToModuleFileGlobalID(M, GlobalID);
if (!ID)
return;
-
+
+ // If the search decl was from this module, add it to the chain before any
+ // of its redeclarations in this module or users of it, and after any from
+ // imported modules.
+ if (CanonID != GlobalID && Reader.isDeclIDFromModule(GlobalID, M))
+ addToChain(Reader.GetDecl(GlobalID));
+
// Perform a binary search to find the local redeclarations for this
// declaration (if any).
const LocalRedeclarationsInfo Compare = { ID, 0 };
OpenPOWER on IntegriCloud