[clang] f3b3446 - [clang][CrossTU] Invalidate parent map after get cross TU definition.

Balázs Kéri via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 1 00:10:56 PDT 2020


Author: Balázs Kéri
Date: 2020-07-01T09:13:05+02:00
New Revision: f3b34466104877b024e168cac054bded6b9279a0

URL: https://github.com/llvm/llvm-project/commit/f3b34466104877b024e168cac054bded6b9279a0
DIFF: https://github.com/llvm/llvm-project/commit/f3b34466104877b024e168cac054bded6b9279a0.diff

LOG: [clang][CrossTU] Invalidate parent map after get cross TU definition.

Summary:
Parent map of ASTContext is built once. If this happens and later
the TU is modified by getCrossTUDefinition the parent map does not
contain the newly imported objects and has to be re-created.

Invalidation of the parent map is added to the CrossTranslationUnitContext.
It could be added to ASTImporter as well but for now this task remains the
responsibility of the user of ASTImporter. Reason for this is mostly that
ASTImporter calls itself recursively.

Reviewers: gamesh411, martong

Reviewed By: gamesh411

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, martong, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D82568

Added: 
    

Modified: 
    clang/lib/CrossTU/CrossTranslationUnit.cpp
    clang/unittests/CrossTU/CrossTranslationUnitTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CrossTU/CrossTranslationUnit.cpp b/clang/lib/CrossTU/CrossTranslationUnit.cpp
index 24c3143db410..11cc2afbc36d 100644
--- 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 @@ CrossTranslationUnitContext::importDefinitionImpl(const T *D, ASTUnit *Unit) {
   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
index 36a697d54c8a..ceb1437f2520 100644
--- 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 @@ class CTUASTConsumer : public clang::ASTConsumer {
     assert(FD && FD->getName() == "f");
     bool OrigFDHasBody = FD->hasBody();
 
+    const DynTypedNodeList ParentsBeforeImport =
+        Ctx.getParentMapContext().getParents<Decl>(*FD);
+    ASSERT_FALSE(ParentsBeforeImport.empty());
+
     // Prepare the index file and the AST file.
     int ASTFD;
     llvm::SmallString<256> ASTFileName;
@@ -105,10 +110,29 @@ class CTUASTConsumer : public clang::ASTConsumer {
             EXPECT_EQ(OrigSLoc, FDWithDefinition->getLocation());
           }
         }
+
+        // Check parent map.
+        const DynTypedNodeList ParentsAfterImport =
+            Ctx.getParentMapContext().getParents<Decl>(*FD);
+        const DynTypedNodeList ParentsOfImported =
+            Ctx.getParentMapContext().getParents<Decl>(*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;


        


More information about the cfe-commits mailing list