diff --git a/clang/lib/CrossTU/CrossTranslationUnit.cpp b/clang/lib/CrossTU/CrossTranslationUnit.cpp --- a/clang/lib/CrossTU/CrossTranslationUnit.cpp +++ b/clang/lib/CrossTU/CrossTranslationUnit.cpp @@ -12,6 +12,7 @@ #include "clang/CrossTU/CrossTranslationUnit.h" #include "clang/AST/ASTImporter.h" #include "clang/AST/Decl.h" +#include "clang/AST/ParentMapContext.h" #include "clang/Basic/TargetInfo.h" #include "clang/CrossTU/CrossTUDiagnostic.h" #include "clang/Frontend/ASTUnit.h" @@ -718,6 +719,9 @@ assert(hasBodyOrInit(ToDecl) && "Imported Decl should have body or init."); ++NumGetCTUSuccess; + // Parent map is invalidated after changing the AST. + ToDecl->getASTContext().getParentMapContext().clear(); + return ToDecl; } diff --git a/clang/unittests/CrossTU/CrossTranslationUnitTest.cpp b/clang/unittests/CrossTU/CrossTranslationUnitTest.cpp --- a/clang/unittests/CrossTU/CrossTranslationUnitTest.cpp +++ b/clang/unittests/CrossTU/CrossTranslationUnitTest.cpp @@ -8,6 +8,7 @@ #include "clang/CrossTU/CrossTranslationUnit.h" #include "clang/AST/ASTConsumer.h" +#include "clang/AST/ParentMapContext.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendAction.h" #include "clang/Tooling/Tooling.h" @@ -44,6 +45,10 @@ assert(FD && FD->getName() == "f"); bool OrigFDHasBody = FD->hasBody(); + const DynTypedNodeList ParentsBeforeImport = + Ctx.getParentMapContext().getParents(*FD); + ASSERT_FALSE(ParentsBeforeImport.empty()); + // Prepare the index file and the AST file. int ASTFD; llvm::SmallString<256> ASTFileName; @@ -105,10 +110,29 @@ EXPECT_EQ(OrigSLoc, FDWithDefinition->getLocation()); } } + + // Check parent map. + const DynTypedNodeList ParentsAfterImport = + Ctx.getParentMapContext().getParents(*FD); + const DynTypedNodeList ParentsOfImported = + Ctx.getParentMapContext().getParents(*NewFD); + EXPECT_TRUE( + checkParentListsEq(ParentsBeforeImport, ParentsAfterImport)); + EXPECT_FALSE(ParentsOfImported.empty()); } } } + static bool checkParentListsEq(const DynTypedNodeList &L1, + const DynTypedNodeList &L2) { + if (L1.size() != L2.size()) + return false; + for (unsigned int I = 0; I < L1.size(); ++I) + if (L1[I] != L2[I]) + return false; + return true; + } + private: CrossTranslationUnitContext CTU; bool *Success;