[PATCH] D46940: [ASTImporter] make sure that ACtx::getParents still works

2019-04-08 Thread Rafael Stahl via Phabricator via cfe-commits
r.stahl abandoned this revision.
r.stahl added a comment.
Herald added a reviewer: shafik.

ASTContext::getParents should not be used this way. This use-case is solved by 
function-scoped ParentMaps or AnalysisDeclContext::getParentMap. Discussion: 
http://lists.llvm.org/pipermail/cfe-dev/2019-April/061944.html


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D46940/new/

https://reviews.llvm.org/D46940



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46940: [ASTImporter] make sure that ACtx::getParents still works

2018-08-11 Thread Aleksei Sidorin via Phabricator via cfe-commits
a_sidorin added a comment.

Hello Richard,

Thank you for clarification. However, I think that moving ParentMap into 
libTooling is out of scope for this patch. Are you OK if this change will be 
committed with adding a TODO or FIXME for this move?


https://reviews.llvm.org/D46940



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46940: [ASTImporter] make sure that ACtx::getParents still works

2018-07-11 Thread Rafael Stahl via Phabricator via cfe-commits
r.stahl added a comment.

@rsmith Yes, this should generally better be handled outside of the ASTContext. 
That would be out of scope of this patch. Is it fine to proceed with this one 
for now?

For my usage scenario it actually is convenient this way. In my checker I use 
getParents, but if I would replace this with some tooling functions I wouldn't 
know when the maps become invalid since the invalidation happens on a lower 
level within the analyzer. I'd have to search the parents on every callback 
invocation which would be a massive performance issue.

Once an external parent utility exists, we would still need some invalidation 
notification. If anyone uses the analyzer and parent maps he'd want to know 
when they become invalid for performance reasons. Ideally only when necessary 
like the invalidateParents calls in this patch.


https://reviews.llvm.org/D46940



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46940: [ASTImporter] make sure that ACtx::getParents still works

2018-06-28 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added a comment.

This is not specific to the `ASTImporter`; any change to the AST after a call 
to `getParents` would have similar problems. Generally, responsibility for 
dealing with this must lie with the consumer of the parent map, not with the 
`ASTContext`, since the `ASTContext` generally doesn't even know when the AST 
gets mutated.

I think that the parent map should not be a member of the `ASTContext` at all. 
That'd make it much clearer that the responsibility for not reusing it across 
AST mutations lies with the consumer, not with the mutator of the AST. (Also, 
having it in `ASTContext` invites bugs; we do not want the parent map to ever 
be used by anything in `Sema`, for instance, largely due to the invalidation 
problems. In fact, I don't think the `clang` binary needs the parent map code 
at all; it really belongs in libTooling.)


https://reviews.llvm.org/D46940



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46940: [ASTImporter] make sure that ACtx::getParents still works

2018-06-26 Thread Rafael Stahl via Phabricator via cfe-commits
r.stahl added a comment.

@rsmith do you have a chance to take a look or assign someone else?


https://reviews.llvm.org/D46940



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46940: [ASTImporter] make sure that ACtx::getParents still works

2018-05-18 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a reviewer: rsmith.
aaron.ballman added a comment.

Adding Richard as he has more background in this area. In general, I think it's 
okay - if we invalidate too often, we do lose some performance, but the 
correctness should still be there. I'll let Richard provide the final sign-off, 
however.


https://reviews.llvm.org/D46940



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46940: [ASTImporter] make sure that ACtx::getParents still works

2018-05-18 Thread Aleksei Sidorin via Phabricator via cfe-commits
a.sidorin accepted this revision.
a.sidorin added a comment.

LGTM. Aaron, could you please confirm that AST changes are fine?




Comment at: include/clang/AST/ASTContext.h:638
+ReleaseParentMapEntries();
+PointerParents = nullptr;
+  }

I'd prefer to call reset(), but I won't insist on it.


https://reviews.llvm.org/D46940



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46940: [ASTImporter] make sure that ACtx::getParents still works

2018-05-18 Thread Gabor Marton via Phabricator via cfe-commits
martong accepted this revision.
martong added a comment.
This revision is now accepted and ready to land.
Herald added a subscriber: rnkovacs.

Ok, thanks for the explanation. Now it looks good to me.


https://reviews.llvm.org/D46940



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46940: [ASTImporter] make sure that ACtx::getParents still works

2018-05-18 Thread Rafael Stahl via Phabricator via cfe-commits
r.stahl added inline comments.



Comment at: lib/AST/ASTImporter.cpp:6776
+  // been invalidated to avoid repeatedly calling this.
+  ToContext.invalidateParents();
+

martong wrote:
> Can an `Expr` has a parent too? If yes, why not invalidate the parents in 
> `Import(Expr*)` ?
> I am also a bit concerned to call the invalidation during the import of all 
> `Stmt` (and possible during the import of `Expr`s too).
> Isn't it enough to invalidate only during `Import(Decl*)`?
The Import(Expr) function just defers to Import(Stmt) so a call there would be 
redundant as Alexey commented.

I don't think it would be enough to invalidate in Import(Decl), because 
Import(Stmt) is part of the public API. I don't know if it makes sense to just 
import Stmts and if there is any user code doing that, but it is theoretically 
possible. In that case we should make Import(Stmt) and Import(Expr) private.

I wouldn't be too concerned about too many calls to invalidate, since the 
function doesn't do anything once the parent info has been released and it will 
only be rebuilt once someone calls ACtx::getParents - which is not the case 
while importing.


https://reviews.llvm.org/D46940



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46940: [ASTImporter] make sure that ACtx::getParents still works

2018-05-18 Thread Gabor Marton via Phabricator via cfe-commits
martong added inline comments.



Comment at: lib/AST/ASTImporter.cpp:6776
+  // been invalidated to avoid repeatedly calling this.
+  ToContext.invalidateParents();
+

Can an `Expr` has a parent too? If yes, why not invalidate the parents in 
`Import(Expr*)` ?
I am also a bit concerned to call the invalidation during the import of all 
`Stmt` (and possible during the import of `Expr`s too).
Isn't it enough to invalidate only during `Import(Decl*)`?


https://reviews.llvm.org/D46940



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46940: [ASTImporter] make sure that ACtx::getParents still works

2018-05-17 Thread Rafael Stahl via Phabricator via cfe-commits
r.stahl updated this revision to Diff 147268.
r.stahl marked 2 inline comments as done.
r.stahl added a comment.

addressed review comments


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{}.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().match(PreTU, recordDecl());
+  auto ToRD = cast(Import(FromRD, Lang_CXX));
+  auto  = ToAST->getASTContext();
+  ToACtx.getParents(*ToRD);
+
+  Decl *FromTU = getTuDecl("void f() {}", Lang_CXX);
+  CompoundStmt *FromCS = FirstDeclMatcher().match(FromTU,
+compoundStmt());
+  FunctionDecl *FromFD = FirstDeclMatcher().match(FromTU,
+functionDecl());
+
+  auto FromPs = FromFD->getASTContext().getParents(*FromCS);
+  ASSERT_TRUE(!FromPs.empty());
+  auto FromP = FromPs[0].get();
+  EXPECT_EQ(FromP, FromFD);
+
+  auto ToFD = cast(Import(FromFD, Lang_CXX));
+
+  Decl *ToTU = ToACtx.getTranslationUnitDecl();
+  auto ToCS = FirstDeclMatcher().match(ToTU, compoundStmt());
+
+  auto ToPs = ToACtx.getParents(*ToCS);
+  ASSERT_TRUE(!ToPs.empty());
+  auto ToP = ToPs[0].get();
+  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
@@ -6686,6 +6686,8 @@
   if (!ToD)
 return nullptr;
 
+  ToContext.invalidateParents();
+
   // Record the imported declaration.
   ImportedDecls[FromD] = ToD;
   ToD->IdentifierNamespace = FromD->IdentifierNamespace;
@@ -6762,13 +6764,17 @@
   llvm::DenseMap::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;
 
+  // FIXME: We could add a separate function that assumes parents have already
+  // been invalidated to avoid repeatedly calling this.
+  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(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(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(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 

[PATCH] D46940: [ASTImporter] make sure that ACtx::getParents still works

2018-05-16 Thread Rafael Stahl via Phabricator via cfe-commits
r.stahl added inline comments.



Comment at: lib/AST/ASTImporter.cpp:6755
+  auto ToE = cast_or_null(Import(cast(FromE)));
+  if (ToE)
+ToContext.invalidateParents();

a.sidorin wrote:
> We already do the invalidation in Import(Stmt), so it looks redundant here.
Yes, sorry this should actually be in Import(Decl) as I wrote in the 
description!


Repository:
  rC Clang

https://reviews.llvm.org/D46940



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46940: [ASTImporter] make sure that ACtx::getParents still works

2018-05-16 Thread Aleksei Sidorin via Phabricator via cfe-commits
a.sidorin added a comment.

Hello Rafael,

The patch is awesome. The only thing I'm uncomfortable with is that we call 
invalidation on every stmt import - not only during the top-level one. Fixing 
this requires separating entry point from internal imports and is out of scope 
of this patch, but adding some FIXMEs is very appreciated.




Comment at: lib/AST/ASTImporter.cpp:6755
+  auto ToE = cast_or_null(Import(cast(FromE)));
+  if (ToE)
+ToContext.invalidateParents();

We already do the invalidation in Import(Stmt), so it looks redundant here.


Repository:
  rC Clang

https://reviews.llvm.org/D46940



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46940: [ASTImporter] make sure that ACtx::getParents still works

2018-05-16 Thread Rafael Stahl via Phabricator via cfe-commits
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{}.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().match(PreTU, recordDecl());
+  auto ToRD = cast(Import(FromRD, Lang_CXX));
+  auto  = ToAST->getASTContext();
+  ToACtx.getParents(*ToRD);
+
+  Decl *FromTU = getTuDecl("void f() {}", Lang_CXX);
+  CompoundStmt *FromCS = FirstDeclMatcher().match(FromTU,
+compoundStmt());
+  FunctionDecl *FromFD = FirstDeclMatcher().match(FromTU,
+functionDecl());
+
+  auto FromPs = FromFD->getASTContext().getParents(*FromCS);
+  ASSERT_TRUE(!FromPs.empty());
+  auto FromP = FromPs[0].get();
+  EXPECT_EQ(FromP, FromFD);
+
+  auto ToFD = cast(Import(FromFD, Lang_CXX));
+
+  Decl *ToTU = ToACtx.getTranslationUnitDecl();
+  auto ToCS = FirstDeclMatcher().match(ToTU, compoundStmt());
+
+  auto ToPs = ToACtx.getParents(*ToCS);
+  ASSERT_TRUE(!ToPs.empty());
+  auto ToP = ToPs[0].get();
+  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(Import(cast(FromE)));
+  auto ToE = cast_or_null(Import(cast(FromE)));
+  if (ToE)
+ToContext.invalidateParents();
+
+  return ToE;
 }
 
 Stmt *ASTImporter::Import(Stmt *FromS) {
@@ -6762,13 +6766,15 @@
   llvm::DenseMap::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(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(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(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,