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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits