r.stahl created this revision. r.stahl added reviewers: a.sidorin, klimek. Herald added subscribers: cfe-commits, martong.
If an AST node is imported after a call to getParents in the ToCtx, it was no longer possible to retrieve its parents since the old results were cached. Valid types for getParents: - Decl, Stmt, NestedNameSpecifier: handled explicitly - Type: not supported by ast importer - TypeLoc: not imported - NestedNameSpecifierLoc: calls import for NNS Repository: rC Clang https://reviews.llvm.org/D46940 Files: include/clang/AST/ASTContext.h lib/AST/ASTImporter.cpp unittests/AST/ASTImporterTest.cpp
Index: unittests/AST/ASTImporterTest.cpp =================================================================== --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -1431,6 +1431,36 @@ MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern)); } +TEST_P(ASTImporterTestBase, ValidParents) { + // Create parent cache in To context. + Decl *PreTU = getTuDecl("struct S {};", Lang_CXX, "pre.cc"); + RecordDecl *FromRD = FirstDeclMatcher<RecordDecl>().match(PreTU, recordDecl()); + auto ToRD = cast<RecordDecl>(Import(FromRD, Lang_CXX)); + auto &ToACtx = ToAST->getASTContext(); + ToACtx.getParents(*ToRD); + + Decl *FromTU = getTuDecl("void f() {}", Lang_CXX); + CompoundStmt *FromCS = FirstDeclMatcher<CompoundStmt>().match(FromTU, + compoundStmt()); + FunctionDecl *FromFD = FirstDeclMatcher<FunctionDecl>().match(FromTU, + functionDecl()); + + auto FromPs = FromFD->getASTContext().getParents(*FromCS); + ASSERT_TRUE(!FromPs.empty()); + auto FromP = FromPs[0].get<FunctionDecl>(); + EXPECT_EQ(FromP, FromFD); + + auto ToFD = cast<FunctionDecl>(Import(FromFD, Lang_CXX)); + + Decl *ToTU = ToACtx.getTranslationUnitDecl(); + auto ToCS = FirstDeclMatcher<CompoundStmt>().match(ToTU, compoundStmt()); + + auto ToPs = ToACtx.getParents(*ToCS); + ASSERT_TRUE(!ToPs.empty()); + auto ToP = ToPs[0].get<FunctionDecl>(); + EXPECT_EQ(ToP, ToFD); +} + INSTANTIATE_TEST_CASE_P( ParameterizedTests, ASTImporterTestBase, ::testing::Values(ArgVector(), ArgVector{"-fdelayed-template-parsing"}),); Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -6751,7 +6751,11 @@ if (!FromE) return nullptr; - return cast_or_null<Expr>(Import(cast<Stmt>(FromE))); + auto ToE = cast_or_null<Expr>(Import(cast<Stmt>(FromE))); + if (ToE) + ToContext.invalidateParents(); + + return ToE; } Stmt *ASTImporter::Import(Stmt *FromS) { @@ -6762,13 +6766,15 @@ llvm::DenseMap<Stmt *, Stmt *>::iterator Pos = ImportedStmts.find(FromS); if (Pos != ImportedStmts.end()) return Pos->second; - + // Import the type ASTNodeImporter Importer(*this); Stmt *ToS = Importer.Visit(FromS); if (!ToS) return nullptr; + ToContext.invalidateParents(); + // Record the imported declaration. ImportedStmts[FromS] = ToS; return ToS; @@ -6779,52 +6785,60 @@ return nullptr; NestedNameSpecifier *prefix = Import(FromNNS->getPrefix()); + NestedNameSpecifier *ToNNS = nullptr; switch (FromNNS->getKind()) { case NestedNameSpecifier::Identifier: if (IdentifierInfo *II = Import(FromNNS->getAsIdentifier())) { - return NestedNameSpecifier::Create(ToContext, prefix, II); + ToNNS = NestedNameSpecifier::Create(ToContext, prefix, II); } - return nullptr; + break; case NestedNameSpecifier::Namespace: if (auto *NS = cast_or_null<NamespaceDecl>(Import(FromNNS->getAsNamespace()))) { - return NestedNameSpecifier::Create(ToContext, prefix, NS); + ToNNS = NestedNameSpecifier::Create(ToContext, prefix, NS); } - return nullptr; + break; case NestedNameSpecifier::NamespaceAlias: if (auto *NSAD = cast_or_null<NamespaceAliasDecl>(Import(FromNNS->getAsNamespaceAlias()))) { - return NestedNameSpecifier::Create(ToContext, prefix, NSAD); + ToNNS = NestedNameSpecifier::Create(ToContext, prefix, NSAD); } - return nullptr; + break; case NestedNameSpecifier::Global: - return NestedNameSpecifier::GlobalSpecifier(ToContext); + ToNNS = NestedNameSpecifier::GlobalSpecifier(ToContext); + break; case NestedNameSpecifier::Super: if (auto *RD = cast_or_null<CXXRecordDecl>(Import(FromNNS->getAsRecordDecl()))) { - return NestedNameSpecifier::SuperSpecifier(ToContext, RD); + ToNNS = NestedNameSpecifier::SuperSpecifier(ToContext, RD); } - return nullptr; + break; case NestedNameSpecifier::TypeSpec: case NestedNameSpecifier::TypeSpecWithTemplate: { QualType T = Import(QualType(FromNNS->getAsType(), 0u)); if (!T.isNull()) { bool bTemplate = FromNNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate; - return NestedNameSpecifier::Create(ToContext, prefix, + ToNNS = NestedNameSpecifier::Create(ToContext, prefix, bTemplate, T.getTypePtr()); } + break; } - return nullptr; + + default: + llvm_unreachable("Invalid nested name specifier kind"); } - llvm_unreachable("Invalid nested name specifier kind"); + if (ToNNS) + ToContext.invalidateParents(); + + return ToNNS; } NestedNameSpecifierLoc ASTImporter::Import(NestedNameSpecifierLoc FromNNS) { Index: include/clang/AST/ASTContext.h =================================================================== --- include/clang/AST/ASTContext.h +++ include/clang/AST/ASTContext.h @@ -633,6 +633,11 @@ DynTypedNodeList getParents(const ast_type_traits::DynTypedNode &Node); + void invalidateParents() { + ReleaseParentMapEntries(); + PointerParents = nullptr; + } + const clang::PrintingPolicy &getPrintingPolicy() const { return PrintingPolicy; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits