diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-04-26 21:33:35 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-04-26 21:33:35 +0000 |
commit | 0532df02a72a32a6042e961b71989db73d0d0a22 (patch) | |
tree | adf9f00a1bb2bbfdd5c6abb317db926c951d51ff /lib/Serialization/ASTWriter.cpp | |
parent | cbdbbd1ba105e65c5c1afa30c6c64f44adf56ad4 (diff) |
[Modules] Fix an issue where the reconstructed redeclaration chain was incomplete, missing the definition from a module.
-Make sure that a deserialized external decl gets added to the TU scope.
-When associating an identifier with a set of decls, use the most recent local ones,
if they exist, otherwise associating decls from modules (that came after a local one)
will lead to an incomplete reconstructed re-declaration chain.
rdar://13712705
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@180634 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization/ASTWriter.cpp')
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index c5a055072d..ba53bdaffb 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -3106,7 +3106,28 @@ public: for (SmallVector<Decl *, 16>::reverse_iterator D = Decls.rbegin(), DEnd = Decls.rend(); D != DEnd; ++D) - clang::io::Emit32(Out, Writer.getDeclID(*D)); + clang::io::Emit32(Out, Writer.getDeclID(getMostRecentLocalDecl(*D))); + } + + /// \brief Returns the most recent local decl or the given decl if there are + /// no local ones. The given decl is assumed to be the most recent one. + Decl *getMostRecentLocalDecl(Decl *Orig) { + // The only way a "from AST file" decl would be more recent from a local one + // is if it came from a module. + if (!PP.getLangOpts().Modules) + return Orig; + + // Look for a local in the decl chain. + for (Decl *D = Orig; D; D = D->getPreviousDecl()) { + if (!D->isFromASTFile()) + return D; + // If we come up a decl from a (chained-)PCH stop since we won't find a + // local one. + if (D->getOwningModuleID() == 0) + break; + } + + return Orig; } }; } // end anonymous namespace |