[PATCH] D159519: [clang][AST][ASTImporter] improve AST comparasion on VarDecl & GotoStmt

2023-09-19 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky added a comment.

ping~ @donat.nagy  @steakhal  @balazske


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D159519

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


[PATCH] D159519: [clang][AST][ASTImporter] improve AST comparasion on VarDecl & GotoStmt

2023-09-15 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky updated this revision to Diff 556861.
jcsxky added a comment.

update according to llvm convention.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D159519

Files:
  clang/lib/AST/ASTStructuralEquivalence.cpp
  clang/unittests/AST/StructuralEquivalenceTest.cpp

Index: clang/unittests/AST/StructuralEquivalenceTest.cpp
===
--- clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -1,5 +1,6 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTStructuralEquivalence.h"
+#include "clang/AST/Decl.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Frontend/ASTUnit.h"
@@ -1801,10 +1802,10 @@
 TEST_F(StructuralEquivalenceCacheTest, ReturnStmtNonEq) {
   auto TU = makeTuDecls(
   R"(
-  bool x(){ return true; }
+  bool x() { return true; }
   )",
   R"(
-  bool x(){ return false; }
+  bool x() { return false; }
   )",
   Lang_CXX03);
 
@@ -1817,6 +1818,60 @@
 
 }
 
+TEST_F(StructuralEquivalenceCacheTest, VarDeclNoEq) {
+  auto TU = makeTuDecls(
+  R"(
+  int p;
+  )",
+  R"(
+  int q;
+  )",
+  Lang_CXX03);
+
+  StructuralEquivalenceContext Ctx(
+  get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
+  NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
+
+  auto Var = findDeclPair(TU, varDecl());
+  EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
+}
+
+TEST_F(StructuralEquivalenceCacheTest, VarDeclWithDifferentStorageClassNoEq) {
+  auto TU = makeTuDecls(
+  R"(
+  int p;
+  )",
+  R"(
+  static int p;
+  )",
+  Lang_CXX03);
+
+  StructuralEquivalenceContext Ctx(
+  get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
+  NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
+
+  auto Var = findDeclPair(TU, varDecl());
+  EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
+}
+
+TEST_F(StructuralEquivalenceCacheTest, VarDeclWithInitNoEq) {
+  auto TU = makeTuDecls(
+  R"(
+  int p = 1;
+  )",
+  R"(
+  int p = 2;
+  )",
+  Lang_CXX03);
+
+  StructuralEquivalenceContext Ctx(
+  get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
+  NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
+
+  auto Var = findDeclPair(TU, varDecl());
+  EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
+}
+
 TEST_F(StructuralEquivalenceCacheTest, SpecialNonEq) {
   auto TU = makeTuDecls(
   R"(
@@ -2320,5 +2375,23 @@
   EXPECT_TRUE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceCacheTest, GotoStmtNoEq) {
+  auto S = makeStmts(
+  R"(
+  void foo() {
+goto L1;
+L1: foo();
+  }
+  )",
+  R"(
+  void foo() {
+goto L2;
+L2: foo();
+  }
+  )",
+  Lang_CXX03, gotoStmt());
+  EXPECT_FALSE(testStructuralMatch(S));
+}
+
 } // end namespace ast_matchers
 } // end namespace clang
Index: clang/lib/AST/ASTStructuralEquivalence.cpp
===
--- clang/lib/AST/ASTStructuralEquivalence.cpp
+++ clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -277,6 +277,17 @@
 
   bool IsStmtEquivalent(const Stmt *S1, const Stmt *S2) { return true; }
 
+  bool IsStmtEquivalent(const GotoStmt *S1, const GotoStmt *S2) {
+LabelDecl *L1 = S1->getLabel();
+LabelDecl *L2 = S2->getLabel();
+if (!L1 || !L2)
+  return L1 == L2;
+
+IdentifierInfo *Name1 = L1->getIdentifier();
+IdentifierInfo *Name2 = L2->getIdentifier();
+return ::IsStructurallyEquivalent(Name1, Name2);
+  }
+
   bool IsStmtEquivalent(const SourceLocExpr *E1, const SourceLocExpr *E2) {
 return E1->getIdentKind() == E2->getIdentKind();
   }
@@ -1295,6 +1306,22 @@
   return true;
 }
 
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext ,
+ VarDecl *D1, VarDecl *D2) {
+  if (D1->getStorageClass() != D2->getStorageClass())
+return false;
+
+  IdentifierInfo *Name1 = D1->getIdentifier();
+  IdentifierInfo *Name2 = D2->getIdentifier();
+  if (!::IsStructurallyEquivalent(Name1, Name2))
+return false;
+
+  if (!IsStructurallyEquivalent(Context, D1->getType(), D2->getType()))
+return false;
+
+  return IsStructurallyEquivalent(Context, D1->getInit(), D2->getInit());
+}
+
 static bool IsStructurallyEquivalent(StructuralEquivalenceContext ,
  FieldDecl *Field1, FieldDecl *Field2,
  QualType Owner2Type) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D159519: [clang][ASTImport] improve ast comparation

2023-09-14 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky created this revision.
jcsxky added reviewers: donat.nagy, steakhal, balazske.
jcsxky added projects: clang, clang-c.
Herald added subscribers: ChuanqiXu, martong.
Herald added a project: All.
jcsxky requested review of this revision.
Herald added a subscriber: cfe-commits.

1. VarDecl should not be ignored.
2. GotoStmt has no children, it should be handle explicitly.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D159519

Files:
  clang/lib/AST/ASTStructuralEquivalence.cpp
  clang/unittests/AST/StructuralEquivalenceTest.cpp

Index: clang/unittests/AST/StructuralEquivalenceTest.cpp
===
--- clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -1,5 +1,6 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTStructuralEquivalence.h"
+#include "clang/AST/Decl.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Frontend/ASTUnit.h"
@@ -1801,10 +1802,10 @@
 TEST_F(StructuralEquivalenceCacheTest, ReturnStmtNonEq) {
   auto TU = makeTuDecls(
   R"(
-  bool x(){ return true; }
+  bool x() { return true; }
   )",
   R"(
-  bool x(){ return false; }
+  bool x() { return false; }
   )",
   Lang_CXX03);
 
@@ -1817,6 +1818,60 @@
 
 }
 
+TEST_F(StructuralEquivalenceCacheTest, VarDeclNoEq) {
+  auto TU = makeTuDecls(
+  R"(
+  int p;
+  )",
+  R"(
+  int q;
+  )",
+  Lang_CXX03);
+
+  StructuralEquivalenceContext Ctx(
+  get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
+  NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
+
+  auto X = findDeclPair(TU, varDecl());
+  EXPECT_FALSE(Ctx.IsEquivalent(X.first, X.second));
+}
+
+TEST_F(StructuralEquivalenceCacheTest, VarDeclWithDifferentStorageClassNoEq) {
+  auto TU = makeTuDecls(
+  R"(
+  int p;
+  )",
+  R"(
+  static int p;
+  )",
+  Lang_CXX03);
+
+  StructuralEquivalenceContext Ctx(
+  get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
+  NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
+
+  auto X = findDeclPair(TU, varDecl());
+  EXPECT_FALSE(Ctx.IsEquivalent(X.first, X.second));
+}
+
+TEST_F(StructuralEquivalenceCacheTest, VarDeclWithInitNoEq) {
+  auto TU = makeTuDecls(
+  R"(
+  int p = 1;
+  )",
+  R"(
+  int p = 2;
+  )",
+  Lang_CXX03);
+
+  StructuralEquivalenceContext Ctx(
+  get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
+  NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
+
+  auto X = findDeclPair(TU, varDecl());
+  EXPECT_FALSE(Ctx.IsEquivalent(X.first, X.second));
+}
+
 TEST_F(StructuralEquivalenceCacheTest, SpecialNonEq) {
   auto TU = makeTuDecls(
   R"(
@@ -2320,5 +2375,23 @@
   EXPECT_TRUE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceCacheTest, GotoStmtNoEq) {
+  auto t = makeStmts(
+  R"(
+  void foo() {
+goto L1;
+L1: foo();
+  }
+  )",
+  R"(
+  void foo() {
+goto L2;
+L2: foo();
+  }
+  )",
+  Lang_CXX03, gotoStmt());
+  EXPECT_FALSE(testStructuralMatch(t));
+}
+
 } // end namespace ast_matchers
 } // end namespace clang
Index: clang/lib/AST/ASTStructuralEquivalence.cpp
===
--- clang/lib/AST/ASTStructuralEquivalence.cpp
+++ clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -277,6 +277,17 @@
 
   bool IsStmtEquivalent(const Stmt *S1, const Stmt *S2) { return true; }
 
+  bool IsStmtEquivalent(const GotoStmt *S1, const GotoStmt *S2) {
+auto *L1 = S1->getLabel();
+auto *L2 = S2->getLabel();
+if (!L1 || !L2) {
+  return L1 == L2;
+}
+IdentifierInfo *Name1 = L1->getIdentifier();
+IdentifierInfo *Name2 = L2->getIdentifier();
+return ::IsStructurallyEquivalent(Name1, Name2);
+  }
+
   bool IsStmtEquivalent(const SourceLocExpr *E1, const SourceLocExpr *E2) {
 return E1->getIdentKind() == E2->getIdentKind();
   }
@@ -1295,6 +1306,24 @@
   return true;
 }
 
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext ,
+ VarDecl *D1, VarDecl *D2) {
+  if (D1->getStorageClass() != D2->getStorageClass()) {
+return false;
+  }
+  IdentifierInfo *Name1 = D1->getIdentifier();
+  IdentifierInfo *Name2 = D2->getIdentifier();
+  if (!::IsStructurallyEquivalent(Name1, Name2)) {
+return false;
+  }
+
+  if (!IsStructurallyEquivalent(Context, D1->getType(), D2->getType())) {
+return false;
+  }
+
+  return IsStructurallyEquivalent(Context, D1->getInit(), D2->getInit());
+}
+
 static bool IsStructurallyEquivalent(StructuralEquivalenceContext ,
  FieldDecl *Field1, FieldDecl *Field2,
  QualType Owner2Type) {

[PATCH] D159479: [ASTImport]CXXBoolLiteralExpr should be handled explicitly in statement comparation

2023-09-07 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky added a comment.

In D159479#4640590 , @donat.nagy 
wrote:

> Today we learned that truth is different from falsehood...
>
> LGTM, nice catch!

Thanks for your quick review.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D159479

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


[PATCH] D159479: [ASTImport]CXXBoolLiteralExpr should be handled explicitly in statement comparation

2023-09-07 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky added a comment.

In D159479#4640607 , @steakhal wrote:

> Make sure the commit message complies with the guidelines.

Fix title and summary.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D159479

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


[PATCH] D159479: [ASTImport]enhance statement comparing

2023-09-07 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky created this revision.
jcsxky added projects: clang, clang-c.
Herald added a subscriber: martong.
Herald added a project: All.
jcsxky requested review of this revision.
Herald added a subscriber: cfe-commits.

Return statement comparing should consider return value.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D159479

Files:
  clang/lib/AST/ASTStructuralEquivalence.cpp
  clang/unittests/AST/StructuralEquivalenceTest.cpp


Index: clang/unittests/AST/StructuralEquivalenceTest.cpp
===
--- clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -1798,6 +1798,25 @@
   TU, cxxRecordDecl(hasName("B"), unless(isImplicit());
 }
 
+TEST_F(StructuralEquivalenceCacheTest, ReturnStmtNonEq) {
+  auto TU = makeTuDecls(
+  R"(
+  bool x(){ return true; }
+  )",
+  R"(
+  bool x(){ return false; }
+  )",
+  Lang_CXX03);
+
+  StructuralEquivalenceContext Ctx(
+  get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
+  NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
+
+  auto X = findDeclPair(TU, functionDecl(hasName("x")));
+  EXPECT_FALSE(Ctx.IsEquivalent(X.first->getBody(), X.second->getBody()));
+
+}
+
 TEST_F(StructuralEquivalenceCacheTest, SpecialNonEq) {
   auto TU = makeTuDecls(
   R"(
Index: clang/lib/AST/ASTStructuralEquivalence.cpp
===
--- clang/lib/AST/ASTStructuralEquivalence.cpp
+++ clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -366,6 +366,10 @@
 return true;
   }
 
+  bool IsStmtEquivalent(const CXXBoolLiteralExpr *E1, const CXXBoolLiteralExpr 
*E2) {
+return E1->getValue() == E2->getValue();
+  }
+
   /// End point of the traversal chain.
   bool TraverseStmt(const Stmt *S1, const Stmt *S2) { return true; }
 


Index: clang/unittests/AST/StructuralEquivalenceTest.cpp
===
--- clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -1798,6 +1798,25 @@
   TU, cxxRecordDecl(hasName("B"), unless(isImplicit());
 }
 
+TEST_F(StructuralEquivalenceCacheTest, ReturnStmtNonEq) {
+  auto TU = makeTuDecls(
+  R"(
+  bool x(){ return true; }
+  )",
+  R"(
+  bool x(){ return false; }
+  )",
+  Lang_CXX03);
+
+  StructuralEquivalenceContext Ctx(
+  get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
+  NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
+
+  auto X = findDeclPair(TU, functionDecl(hasName("x")));
+  EXPECT_FALSE(Ctx.IsEquivalent(X.first->getBody(), X.second->getBody()));
+
+}
+
 TEST_F(StructuralEquivalenceCacheTest, SpecialNonEq) {
   auto TU = makeTuDecls(
   R"(
Index: clang/lib/AST/ASTStructuralEquivalence.cpp
===
--- clang/lib/AST/ASTStructuralEquivalence.cpp
+++ clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -366,6 +366,10 @@
 return true;
   }
 
+  bool IsStmtEquivalent(const CXXBoolLiteralExpr *E1, const CXXBoolLiteralExpr *E2) {
+return E1->getValue() == E2->getValue();
+  }
+
   /// End point of the traversal chain.
   bool TraverseStmt(const Stmt *S1, const Stmt *S2) { return true; }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D159412: [analyzer]FieldRegion in getStaticSize should return size of pointee type

2023-09-04 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky added a comment.

In D159412#4636813 , @donat.nagy 
wrote:

> Please add a testcase that demonstrates this issue (fails when your change in 
> MemRegion.cpp isn't added) and shows that your commit fixes it.

Thanks for your advice.  We use this api in our own project and miss some cases 
which leads the incorrect result. I will abandon this patch later.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D159412

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


[PATCH] D159412: [analyzer]FieldRegion in getStaticSize should return size of pointee type

2023-09-03 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky created this revision.
jcsxky added reviewers: steakhal, balazske, aaron.ballman, NoQ.
jcsxky added projects: clang, clang-c.
Herald added subscribers: manas, ASDenysPetrov, martong, dkrupp, donat.nagy, 
Szelethus, mikhail.ramalho, a.sidorin, szepet, baloghadamsoftware, xazax.hun.
Herald added a project: All.
jcsxky requested review of this revision.
Herald added a subscriber: cfe-commits.

In `getStaticSize`, case of FieldRegionKind should return size of pointee type 
of the member. In the following example:

  struct B {
int x;
int y;
int z;
  };
  
  class A{
  public:
void foo(){
m++;
}
  private:
B *m;
  };

`getDynamicElementCount` of `m` region, if `getDynamicExtent` return the 
pointer size, `getDynamicElementCount` returns 0 in 64bit architecture(since 
pointer size is 8 while size of pointee type is 12). Use pointee type instead, 
it will return 1.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D159412

Files:
  clang/lib/StaticAnalyzer/Core/MemRegion.cpp


Index: clang/lib/StaticAnalyzer/Core/MemRegion.cpp
===
--- clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ clang/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -800,6 +800,12 @@
   return UnknownVal();
 
 QualType Ty = cast(SR)->getDesugaredValueType(Ctx);
+if (Ty->isPointerType()) {
+  QualType PointeeTy = Ty->getPointeeType();
+  if(!PointeeTy->isIncompleteType() && PointeeTy->isObjectType()){
+Ty = PointeeTy;
+  }
+}
 const DefinedOrUnknownSVal Size = getElementExtent(Ty, SVB);
 
 // We currently don't model flexible array members (FAMs), which are:


Index: clang/lib/StaticAnalyzer/Core/MemRegion.cpp
===
--- clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ clang/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -800,6 +800,12 @@
   return UnknownVal();
 
 QualType Ty = cast(SR)->getDesugaredValueType(Ctx);
+if (Ty->isPointerType()) {
+  QualType PointeeTy = Ty->getPointeeType();
+  if(!PointeeTy->isIncompleteType() && PointeeTy->isObjectType()){
+Ty = PointeeTy;
+  }
+}
 const DefinedOrUnknownSVal Size = getElementExtent(Ty, SVB);
 
 // We currently don't model flexible array members (FAMs), which are:
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D156693: [clang][ASTImporter]Skip check depth of friend template parameter

2023-08-21 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky added inline comments.



Comment at: clang/unittests/AST/StructuralEquivalenceTest.cpp:140
+D0->getASTContext(), D1->getASTContext(), NonEquivalentDecls01,
+StructuralEquivalenceKind::Default, false, false, false,
+IgnoreTemplateParmDepth);

shafik wrote:
> See 
> [bugprone-argument-comment](https://clang.llvm.org/extra/clang-tidy/checks/bugprone/argument-comment.html)
>  for details of this format. 
> 
> We use this everywhere we have literals without clear meaning being used as 
> arguments. 
argument comment has been added.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156693

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


[PATCH] D156693: [clang][ASTImporter]Skip check depth of friend template parameter

2023-08-21 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky updated this revision to Diff 552179.
jcsxky added a comment.

add argument comment according to bugprone-argument-comment 
.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156693

Files:
  clang/include/clang/AST/ASTStructuralEquivalence.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/ASTStructuralEquivalence.cpp
  clang/unittests/AST/ASTImporterTest.cpp
  clang/unittests/AST/StructuralEquivalenceTest.cpp

Index: clang/unittests/AST/StructuralEquivalenceTest.cpp
===
--- clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -1,5 +1,6 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTStructuralEquivalence.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Testing/CommandLineArgs.h"
@@ -130,15 +131,20 @@
 return makeStmts(Wrap(SrcCode0), Wrap(SrcCode1), Lang, AMatcher);
   }
 
-  bool testStructuralMatch(Decl *D0, Decl *D1) {
+  bool testStructuralMatch(Decl *D0, Decl *D1,
+   bool IgnoreTemplateParmDepth = false) {
 llvm::DenseSet> NonEquivalentDecls01;
 llvm::DenseSet> NonEquivalentDecls10;
 StructuralEquivalenceContext Ctx01(
-D0->getASTContext(), D1->getASTContext(),
-NonEquivalentDecls01, StructuralEquivalenceKind::Default, false, false);
+D0->getASTContext(), D1->getASTContext(), NonEquivalentDecls01,
+StructuralEquivalenceKind::Default, /*StrictTypeSpelling=*/false,
+/*Complain=*/false, /*ErrorOnTagTypeMismatch=*/false,
+IgnoreTemplateParmDepth);
 StructuralEquivalenceContext Ctx10(
-D1->getASTContext(), D0->getASTContext(),
-NonEquivalentDecls10, StructuralEquivalenceKind::Default, false, false);
+D1->getASTContext(), D0->getASTContext(), NonEquivalentDecls10,
+StructuralEquivalenceKind::Default, /*StrictTypeSpelling=*/false,
+/*Complain=*/false, /*ErrorOnTagTypeMismatch=*/false,
+IgnoreTemplateParmDepth);
 bool Eq01 = Ctx01.IsEquivalent(D0, D1);
 bool Eq10 = Ctx10.IsEquivalent(D1, D0);
 EXPECT_EQ(Eq01, Eq10);
@@ -165,8 +171,9 @@
 return testStructuralMatch(get<0>(t), get<1>(t));
   }
 
-  bool testStructuralMatch(std::tuple t) {
-return testStructuralMatch(get<0>(t), get<1>(t));
+  bool testStructuralMatch(std::tuple t,
+   bool IgnoreTemplateParmDepth = false) {
+return testStructuralMatch(get<0>(t), get<1>(t), IgnoreTemplateParmDepth);
   }
 };
 
@@ -1689,6 +1696,40 @@
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceTemplateTest,
+   IgnoreTemplateParmDepthAtTemplateTypeParmDecl) {
+  auto Decls = makeDecls(
+  R"(
+template struct A;
+  )",
+  R"(
+template struct S {
+  template friend struct A;
+};
+  )",
+  Lang_CXX03, classTemplateDecl(hasName("A")),
+  classTemplateDecl(hasName("A")));
+  EXPECT_TRUE(testStructuralMatch(Decls));
+  EXPECT_TRUE(testStructuralMatch(Decls, true));
+}
+
+TEST_F(StructuralEquivalenceTemplateTest,
+   IgnoreTemplateParmDepthAtNonTypeTemplateParmDecl) {
+  auto Decls = makeDecls(
+  R"(
+template struct A;
+  )",
+  R"(
+template struct S {
+  template friend struct A;
+};
+  )",
+  Lang_CXX03, classTemplateDecl(hasName("A")),
+  classTemplateDecl(hasName("A")));
+  EXPECT_FALSE(testStructuralMatch(Decls));
+  EXPECT_TRUE(testStructuralMatch(Decls, /*IgnoreTemplateParmDepth=*/true));
+}
+
 TEST_F(
 StructuralEquivalenceTemplateTest,
 ClassTemplSpecWithInequivalentShadowedTemplArg) {
Index: clang/unittests/AST/ASTImporterTest.cpp
===
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -4246,6 +4246,58 @@
   EXPECT_TRUE(Imported->getPreviousDecl());
 }
 
+TEST_P(ImportFriendClasses, SkipComparingFriendTemplateDepth) {
+  Decl *ToTU = getToTuDecl(
+  R"(
+  template 
+  class A;
+
+  template 
+  class A {
+  public:
+template 
+friend class A;
+
+A(T x)  :x(x) {}
+
+  private:
+T x;
+  };
+  )",
+  Lang_CXX11);
+
+  auto *Fwd = FirstDeclMatcher().match(
+  ToTU,
+  classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A");
+  Decl *FromTU = getTuDecl(
+  R"(
+  template 
+  class A;
+
+  template 
+  class A {
+  public:
+template 
+friend class A;
+
+A(T x) : x(x) {}
+
+  private:
+T x;
+  };
+
+  A a1(0);
+  )",
+  Lang_CXX11, "input1.cc");
+  auto *FromA = 

[PATCH] D156693: [clang][ASTImporter]Skip check depth of friend template parameter

2023-08-21 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky added a comment.

In D156693#4603537 , @balazske wrote:

> My concern was related to nested namespaces or nested classes with friend 
> declarations that are equivalent and differ only in the nesting level. It may 
> be possible to construct code where a declaration at an inner (nested) level 
> is found to be equivalent with a similar looking class at an outer level. But 
> I now do not have time to look for an example to test it, and I am not fully 
> familiar with exact rules of friend declarations, so I accept this fix.



- The same declcontext will make the template class and friend template class 
in the same namespace.
- Namespace will not change the depth of template class parameter. So, the 
equvalence will not be changed whether ignore the depth or not.
- Declcontext of friend tempalte class is outer namespace (if exists), So, 
classes in this declcontext are equvalent with identical name.

According the the conclusion above, the nested namespace or nested class will 
not affect the equvalence of the two classes (as far as I concerned).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156693

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


[PATCH] D156693: [clang][ASTImporter]Skip check depth of friend template parameter

2023-08-18 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky added a comment.

In D156693#4584657 , @balazske wrote:

> A simple test should be added to StructuralEquivalenceTest.cpp too to check 
> if ignore (and not ignore) depth works.
>
> I think this solution is not always correct, but is still an improvement.

As a friend template declaration, compared to the template class definition, 
the only difference is the depth of the `NonTypeTemplateParam`. If the template 
class definition is equivalent to the class in `From` context, there is no 
probelm. Otherwise, the friend template declaration is also can't equivalent  
to it. Because the friend template declaration is equivalent to its definition 
when ignore the depth. To make a counterexample, we should put the friend 
declaration in different depth, but they are all equivalent in these cases.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156693

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


[PATCH] D156693: [clang][ASTImporter]Skip check depth of friend template parameter

2023-08-15 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky updated this revision to Diff 550352.
jcsxky added a comment.

Fix variable names according to the convention.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156693

Files:
  clang/include/clang/AST/ASTStructuralEquivalence.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/ASTStructuralEquivalence.cpp
  clang/unittests/AST/ASTImporterTest.cpp
  clang/unittests/AST/StructuralEquivalenceTest.cpp

Index: clang/unittests/AST/StructuralEquivalenceTest.cpp
===
--- clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -1,5 +1,6 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTStructuralEquivalence.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Testing/CommandLineArgs.h"
@@ -130,15 +131,18 @@
 return makeStmts(Wrap(SrcCode0), Wrap(SrcCode1), Lang, AMatcher);
   }
 
-  bool testStructuralMatch(Decl *D0, Decl *D1) {
+  bool testStructuralMatch(Decl *D0, Decl *D1,
+   bool IgnoreTemplateParmDepth = false) {
 llvm::DenseSet> NonEquivalentDecls01;
 llvm::DenseSet> NonEquivalentDecls10;
 StructuralEquivalenceContext Ctx01(
-D0->getASTContext(), D1->getASTContext(),
-NonEquivalentDecls01, StructuralEquivalenceKind::Default, false, false);
+D0->getASTContext(), D1->getASTContext(), NonEquivalentDecls01,
+StructuralEquivalenceKind::Default, false, false, false,
+IgnoreTemplateParmDepth);
 StructuralEquivalenceContext Ctx10(
-D1->getASTContext(), D0->getASTContext(),
-NonEquivalentDecls10, StructuralEquivalenceKind::Default, false, false);
+D1->getASTContext(), D0->getASTContext(), NonEquivalentDecls10,
+StructuralEquivalenceKind::Default, false, false, false,
+IgnoreTemplateParmDepth);
 bool Eq01 = Ctx01.IsEquivalent(D0, D1);
 bool Eq10 = Ctx10.IsEquivalent(D1, D0);
 EXPECT_EQ(Eq01, Eq10);
@@ -165,8 +169,9 @@
 return testStructuralMatch(get<0>(t), get<1>(t));
   }
 
-  bool testStructuralMatch(std::tuple t) {
-return testStructuralMatch(get<0>(t), get<1>(t));
+  bool testStructuralMatch(std::tuple t,
+   bool IgnoreTemplateParmDepth = false) {
+return testStructuralMatch(get<0>(t), get<1>(t), IgnoreTemplateParmDepth);
   }
 };
 
@@ -1689,6 +1694,40 @@
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceTemplateTest,
+   IgnoreTemplateParmDepthAtTemplateTypeParmDecl) {
+  auto Decls = makeDecls(
+  R"(
+template struct A;
+  )",
+  R"(
+template struct S {
+  template friend struct A;
+};
+  )",
+  Lang_CXX03, classTemplateDecl(hasName("A")),
+  classTemplateDecl(hasName("A")));
+  EXPECT_TRUE(testStructuralMatch(Decls));
+  EXPECT_TRUE(testStructuralMatch(Decls, true));
+}
+
+TEST_F(StructuralEquivalenceTemplateTest,
+   IgnoreTemplateParmDepthAtNonTypeTemplateParmDecl) {
+  auto Decls = makeDecls(
+  R"(
+template struct A;
+  )",
+  R"(
+template struct S {
+  template friend struct A;
+};
+  )",
+  Lang_CXX03, classTemplateDecl(hasName("A")),
+  classTemplateDecl(hasName("A")));
+  EXPECT_FALSE(testStructuralMatch(Decls));
+  EXPECT_TRUE(testStructuralMatch(Decls, true));
+}
+
 TEST_F(
 StructuralEquivalenceTemplateTest,
 ClassTemplSpecWithInequivalentShadowedTemplArg) {
Index: clang/unittests/AST/ASTImporterTest.cpp
===
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -4246,6 +4246,58 @@
   EXPECT_TRUE(Imported->getPreviousDecl());
 }
 
+TEST_P(ImportFriendClasses, SkipComparingFriendTemplateDepth) {
+  Decl *ToTU = getToTuDecl(
+  R"(
+  template 
+  class A;
+
+  template 
+  class A {
+  public:
+template 
+friend class A;
+
+A(T x)  :x(x) {}
+
+  private:
+T x;
+  };
+  )",
+  Lang_CXX11);
+
+  auto *Fwd = FirstDeclMatcher().match(
+  ToTU,
+  classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A");
+  Decl *FromTU = getTuDecl(
+  R"(
+  template 
+  class A;
+
+  template 
+  class A {
+  public:
+template 
+friend class A;
+
+A(T x) : x(x) {}
+
+  private:
+T x;
+  };
+
+  A a1(0);
+  )",
+  Lang_CXX11, "input1.cc");
+  auto *FromA = FirstDeclMatcher().match(
+  FromTU,
+  classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A");
+  auto *ToA = Import(FromA, Lang_CXX11);
+  EXPECT_TRUE(ToA);
+  EXPECT_EQ(Fwd->getTemplatedDecl()->getTypeForDecl(),
+

[PATCH] D156693: [clang][ASTImporter]Skip check depth of friend template parameter

2023-08-15 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky updated this revision to Diff 550214.
jcsxky added a comment.

Add testcase to illustrate the difference between `TemplateTypeParm` and 
`NonTypeTemplateParm` in detecting by structural equivalence.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156693

Files:
  clang/include/clang/AST/ASTStructuralEquivalence.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/ASTStructuralEquivalence.cpp
  clang/unittests/AST/ASTImporterTest.cpp
  clang/unittests/AST/StructuralEquivalenceTest.cpp

Index: clang/unittests/AST/StructuralEquivalenceTest.cpp
===
--- clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -1,5 +1,6 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTStructuralEquivalence.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Testing/CommandLineArgs.h"
@@ -130,15 +131,18 @@
 return makeStmts(Wrap(SrcCode0), Wrap(SrcCode1), Lang, AMatcher);
   }
 
-  bool testStructuralMatch(Decl *D0, Decl *D1) {
+  bool testStructuralMatch(Decl *D0, Decl *D1,
+   bool IgnoreTemplateParmDepth = false) {
 llvm::DenseSet> NonEquivalentDecls01;
 llvm::DenseSet> NonEquivalentDecls10;
 StructuralEquivalenceContext Ctx01(
-D0->getASTContext(), D1->getASTContext(),
-NonEquivalentDecls01, StructuralEquivalenceKind::Default, false, false);
+D0->getASTContext(), D1->getASTContext(), NonEquivalentDecls01,
+StructuralEquivalenceKind::Default, false, false, false,
+IgnoreTemplateParmDepth);
 StructuralEquivalenceContext Ctx10(
-D1->getASTContext(), D0->getASTContext(),
-NonEquivalentDecls10, StructuralEquivalenceKind::Default, false, false);
+D1->getASTContext(), D0->getASTContext(), NonEquivalentDecls10,
+StructuralEquivalenceKind::Default, false, false, false,
+IgnoreTemplateParmDepth);
 bool Eq01 = Ctx01.IsEquivalent(D0, D1);
 bool Eq10 = Ctx10.IsEquivalent(D1, D0);
 EXPECT_EQ(Eq01, Eq10);
@@ -165,8 +169,9 @@
 return testStructuralMatch(get<0>(t), get<1>(t));
   }
 
-  bool testStructuralMatch(std::tuple t) {
-return testStructuralMatch(get<0>(t), get<1>(t));
+  bool testStructuralMatch(std::tuple t,
+   bool IgnoreTemplateParmDepth = false) {
+return testStructuralMatch(get<0>(t), get<1>(t), IgnoreTemplateParmDepth);
   }
 };
 
@@ -1689,6 +1694,40 @@
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceTemplateTest,
+   IgnoreTemplateParmDepthAtTemplateTypeParmDecl) {
+  auto t = makeDecls(
+  R"(
+template struct A;
+  )",
+  R"(
+template struct S {
+  template friend struct A;
+};
+  )",
+  Lang_CXX03, classTemplateDecl(hasName("A")),
+  classTemplateDecl(hasName("A")));
+  EXPECT_TRUE(testStructuralMatch(t));
+  EXPECT_TRUE(testStructuralMatch(t, true));
+}
+
+TEST_F(StructuralEquivalenceTemplateTest,
+   IgnoreTemplateParmDepthAtNonTypeTemplateParmDecl) {
+  auto t = makeDecls(
+  R"(
+template struct A;
+  )",
+  R"(
+template struct S {
+  template friend struct A;
+};
+  )",
+  Lang_CXX03, classTemplateDecl(hasName("A")),
+  classTemplateDecl(hasName("A")));
+  EXPECT_FALSE(testStructuralMatch(t));
+  EXPECT_TRUE(testStructuralMatch(t, true));
+}
+
 TEST_F(
 StructuralEquivalenceTemplateTest,
 ClassTemplSpecWithInequivalentShadowedTemplArg) {
Index: clang/unittests/AST/ASTImporterTest.cpp
===
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -4246,6 +4246,58 @@
   EXPECT_TRUE(Imported->getPreviousDecl());
 }
 
+TEST_P(ImportFriendClasses, SkipComparingFriendTemplateDepth) {
+  Decl *ToTU = getToTuDecl(
+  R"(
+  template 
+  class A;
+
+  template 
+  class A {
+  public:
+template 
+friend class A;
+
+A(T x)  :x(x) {}
+
+  private:
+T x;
+  };
+  )",
+  Lang_CXX11);
+
+  auto *Fwd = FirstDeclMatcher().match(
+  ToTU,
+  classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A");
+  Decl *FromTU = getTuDecl(
+  R"(
+  template 
+  class A;
+
+  template 
+  class A {
+  public:
+template 
+friend class A;
+
+A(T x) : x(x) {}
+
+  private:
+T x;
+  };
+
+  A a1(0);
+  )",
+  Lang_CXX11, "input1.cc");
+  auto *FromA = FirstDeclMatcher().match(
+  FromTU,
+  classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A");
+  auto *ToA = Import(FromA, Lang_CXX11);
+  EXPECT_TRUE(ToA);
+  

[PATCH] D156693: [clang][ASTImporter]Skip check depth of friend template parameter

2023-08-15 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky added inline comments.



Comment at: clang/unittests/AST/StructuralEquivalenceTest.cpp:1709
+  classTemplateDecl(hasName("A")));
+  EXPECT_TRUE(testStructuralMatch(t));
+  EXPECT_TRUE(testStructuralMatch(t, true));

balazske wrote:
> The intent was to have `EXPECT_FALSE` without ignore depth, and the next test 
> would be not needed. If it does not work with this code a different code can 
> be found. The depth of the (unnamed) template parameter is really different 
> in these cases too, but it is probably not detected by structural 
> equivalence. Maybe `template` or `template` is needed. 
> But to document this behavior the current test can be added too, with name 
> `IgnoreTemplateParmDepthAtTemplateTypeParmDecl`, and the new one with name 
> `IgnoreTemplateParmDepthAtNonTypeTemplateParmDecl`.
1. The reason why it's true without ignore depth is that template parameter is 
'TemplateTypeParm' in this case. So 
```
IsStructurallyEquivalent(StructuralEquivalenceContext ,
 TemplateTypeParmDecl *D1,
 TemplateTypeParmDecl *D2)
```
will be called and return true. 
2. When process 'NonTypeTemplateParm', 
```
IsStructurallyEquivalent(StructuralEquivalenceContext ,
 QualType T1, QualType T2)
```
is called and return false as the different depth.
I will add `IgnoreTemplateParmDepthAtNonTypeTemplateParmDecl` to illustrate the 
difference. Also, next test will be removed.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156693

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


[PATCH] D156693: [clang][ASTImporter]Skip check depth of friend template parameter

2023-08-15 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky updated this revision to Diff 550208.
jcsxky added a comment.

Add more simple testcase to StructuralEquivalenceTest.cpp.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156693

Files:
  clang/include/clang/AST/ASTStructuralEquivalence.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/ASTStructuralEquivalence.cpp
  clang/unittests/AST/ASTImporterTest.cpp
  clang/unittests/AST/StructuralEquivalenceTest.cpp

Index: clang/unittests/AST/StructuralEquivalenceTest.cpp
===
--- clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -1,5 +1,6 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTStructuralEquivalence.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Testing/CommandLineArgs.h"
@@ -130,15 +131,18 @@
 return makeStmts(Wrap(SrcCode0), Wrap(SrcCode1), Lang, AMatcher);
   }
 
-  bool testStructuralMatch(Decl *D0, Decl *D1) {
+  bool testStructuralMatch(Decl *D0, Decl *D1,
+   bool IgnoreTemplateParmDepth = false) {
 llvm::DenseSet> NonEquivalentDecls01;
 llvm::DenseSet> NonEquivalentDecls10;
 StructuralEquivalenceContext Ctx01(
-D0->getASTContext(), D1->getASTContext(),
-NonEquivalentDecls01, StructuralEquivalenceKind::Default, false, false);
+D0->getASTContext(), D1->getASTContext(), NonEquivalentDecls01,
+StructuralEquivalenceKind::Default, false, false, false,
+IgnoreTemplateParmDepth);
 StructuralEquivalenceContext Ctx10(
-D1->getASTContext(), D0->getASTContext(),
-NonEquivalentDecls10, StructuralEquivalenceKind::Default, false, false);
+D1->getASTContext(), D0->getASTContext(), NonEquivalentDecls10,
+StructuralEquivalenceKind::Default, false, false, false,
+IgnoreTemplateParmDepth);
 bool Eq01 = Ctx01.IsEquivalent(D0, D1);
 bool Eq10 = Ctx10.IsEquivalent(D1, D0);
 EXPECT_EQ(Eq01, Eq10);
@@ -165,8 +169,9 @@
 return testStructuralMatch(get<0>(t), get<1>(t));
   }
 
-  bool testStructuralMatch(std::tuple t) {
-return testStructuralMatch(get<0>(t), get<1>(t));
+  bool testStructuralMatch(std::tuple t,
+   bool IgnoreTemplateParmDepth = false) {
+return testStructuralMatch(get<0>(t), get<1>(t), IgnoreTemplateParmDepth);
   }
 };
 
@@ -1689,6 +1694,61 @@
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceTemplateTest, IgnoreTemplateParmDepthEquivalent) {
+  auto t = makeDecls(
+  R"(
+template struct A;
+  )",
+  R"(
+template struct S {
+  template friend struct A;
+};
+  )",
+  Lang_CXX03, classTemplateDecl(hasName("A")),
+  classTemplateDecl(hasName("A")));
+  EXPECT_TRUE(testStructuralMatch(t));
+  EXPECT_TRUE(testStructuralMatch(t, true));
+}
+
+TEST_F(StructuralEquivalenceTemplateTest,
+   ClassTemplateEquivalentFriendClassTemplate) {
+  auto t = makeDecls(
+  R"(
+  template 
+  class A {
+  public:
+template 
+friend class A;
+
+A(T x)  :x(x) {}
+
+  private:
+T x;
+  };
+  )",
+
+  R"(
+  template 
+  class A {
+  public:
+template 
+friend class A;
+
+A(T x) : x(x) {}
+
+  private:
+T x;
+  };
+
+  A a1(0);
+  )",
+  Lang_CXX03, friendDecl(),
+  classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A");
+  auto *Friend = cast(get<0>(t));
+  EXPECT_FALSE(testStructuralMatch(Friend->getFriendDecl(), get<1>(t)));
+  EXPECT_TRUE(testStructuralMatch(Friend->getFriendDecl(), get<1>(t), true));
+}
+
 TEST_F(
 StructuralEquivalenceTemplateTest,
 ClassTemplSpecWithInequivalentShadowedTemplArg) {
Index: clang/unittests/AST/ASTImporterTest.cpp
===
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -4246,6 +4246,58 @@
   EXPECT_TRUE(Imported->getPreviousDecl());
 }
 
+TEST_P(ImportFriendClasses, SkipComparingFriendTemplateDepth) {
+  Decl *ToTU = getToTuDecl(
+  R"(
+  template 
+  class A;
+
+  template 
+  class A {
+  public:
+template 
+friend class A;
+
+A(T x)  :x(x) {}
+
+  private:
+T x;
+  };
+  )",
+  Lang_CXX11);
+
+  auto *Fwd = FirstDeclMatcher().match(
+  ToTU,
+  classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A");
+  Decl *FromTU = getTuDecl(
+  R"(
+  template 
+  class A;
+
+  template 
+  class A {
+  public:
+template 
+friend class A;
+
+A(T x) : x(x) {}
+
+  private:
+T x;
+  };
+
+  A a1(0);
+  )",
+  

[PATCH] D156693: [clang][ASTImporter]Skip check depth of friend template parameter

2023-08-14 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky added inline comments.



Comment at: clang/lib/AST/ASTImporter.cpp:5831
+FoundTemplate->getFriendObjectKind() != Decl::FOK_None &&
+!D->specializations().empty();
+if (IsStructuralMatch(D, FoundTemplate, true, IgnoreDepth)) {

balazske wrote:
> Probably add `IsFriendTemplate`?
I think this is not needed because D is not always a friend template class 
according to the testcase (IsFriendTemplate is false in testcase).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156693

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


[PATCH] D156693: [clang][ASTImporter]Skip check depth of friend template parameter

2023-08-14 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky updated this revision to Diff 550030.
jcsxky added a comment.

fixed according to the review and add testcase to StructuralEquivalenceTest.cpp.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156693

Files:
  clang/include/clang/AST/ASTStructuralEquivalence.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/ASTStructuralEquivalence.cpp
  clang/unittests/AST/ASTImporterTest.cpp
  clang/unittests/AST/StructuralEquivalenceTest.cpp

Index: clang/unittests/AST/StructuralEquivalenceTest.cpp
===
--- clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -1,5 +1,6 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTStructuralEquivalence.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Testing/CommandLineArgs.h"
@@ -130,15 +131,18 @@
 return makeStmts(Wrap(SrcCode0), Wrap(SrcCode1), Lang, AMatcher);
   }
 
-  bool testStructuralMatch(Decl *D0, Decl *D1) {
+  bool testStructuralMatch(Decl *D0, Decl *D1,
+   bool IgnoreTemplateParmDepth = false) {
 llvm::DenseSet> NonEquivalentDecls01;
 llvm::DenseSet> NonEquivalentDecls10;
 StructuralEquivalenceContext Ctx01(
-D0->getASTContext(), D1->getASTContext(),
-NonEquivalentDecls01, StructuralEquivalenceKind::Default, false, false);
+D0->getASTContext(), D1->getASTContext(), NonEquivalentDecls01,
+StructuralEquivalenceKind::Default, false, false, false,
+IgnoreTemplateParmDepth);
 StructuralEquivalenceContext Ctx10(
-D1->getASTContext(), D0->getASTContext(),
-NonEquivalentDecls10, StructuralEquivalenceKind::Default, false, false);
+D1->getASTContext(), D0->getASTContext(), NonEquivalentDecls10,
+StructuralEquivalenceKind::Default, false, false, false,
+IgnoreTemplateParmDepth);
 bool Eq01 = Ctx01.IsEquivalent(D0, D1);
 bool Eq10 = Ctx10.IsEquivalent(D1, D0);
 EXPECT_EQ(Eq01, Eq10);
@@ -1689,6 +1693,45 @@
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceTemplateTest,
+   ClassTemplateEquivalentFriendClassTemplate) {
+  auto t = makeDecls(
+  R"(
+  template 
+  class A {
+  public:
+template 
+friend class A;
+
+A(T x)  :x(x) {}
+
+  private:
+T x;
+  };
+  )",
+
+  R"(
+  template 
+  class A {
+  public:
+template 
+friend class A;
+
+A(T x) : x(x) {}
+
+  private:
+T x;
+  };
+
+  A a1(0);
+  )",
+  Lang_CXX03, friendDecl(),
+  classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A");
+  auto *Friend = cast(get<0>(t));
+  EXPECT_FALSE(testStructuralMatch(Friend->getFriendDecl(), get<1>(t)));
+  EXPECT_TRUE(testStructuralMatch(Friend->getFriendDecl(), get<1>(t), true));
+}
+
 TEST_F(
 StructuralEquivalenceTemplateTest,
 ClassTemplSpecWithInequivalentShadowedTemplArg) {
Index: clang/unittests/AST/ASTImporterTest.cpp
===
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -4246,6 +4246,58 @@
   EXPECT_TRUE(Imported->getPreviousDecl());
 }
 
+TEST_P(ImportFriendClasses, SkipComparingFriendTemplateDepth) {
+  Decl *ToTU = getToTuDecl(
+  R"(
+  template 
+  class A;
+
+  template 
+  class A {
+  public:
+template 
+friend class A;
+
+A(T x)  :x(x) {}
+
+  private:
+T x;
+  };
+  )",
+  Lang_CXX11);
+
+  auto *Fwd = FirstDeclMatcher().match(
+  ToTU,
+  classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A");
+  Decl *FromTU = getTuDecl(
+  R"(
+  template 
+  class A;
+
+  template 
+  class A {
+  public:
+template 
+friend class A;
+
+A(T x) : x(x) {}
+
+  private:
+T x;
+  };
+
+  A a1(0);
+  )",
+  Lang_CXX11, "input1.cc");
+  auto *FromA = FirstDeclMatcher().match(
+  FromTU,
+  classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A");
+  auto *ToA = Import(FromA, Lang_CXX11);
+  EXPECT_TRUE(ToA);
+  EXPECT_EQ(Fwd->getTemplatedDecl()->getTypeForDecl(),
+ToA->getTemplatedDecl()->getTypeForDecl());
+}
+
 TEST_P(ImportFriendClasses,
ImportOfClassTemplateDefinitionShouldConnectToFwdFriend) {
   Decl *ToTU = getToTuDecl(
Index: clang/lib/AST/ASTStructuralEquivalence.cpp
===
--- clang/lib/AST/ASTStructuralEquivalence.cpp
+++ clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -1092,7 +1092,8 @@
   case Type::TemplateTypeParm: {
 const auto *Parm1 = cast(T1);
 const auto *Parm2 = cast(T2);
- 

[PATCH] D156693: [clang][ASTImporter]Skip check friend template depth

2023-08-08 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky added a comment.

In D156693#4568941 , @balazske wrote:

> This fix can cause problems because the depth comparison is omitted all 
> times. It would be better to omit depth check if the imported template is a 
> friend, and has a `ClassTemplateSpecializationDecl` as context. Probably even 
> then it is possible to construct cases where the checked template has 
> references to other templates with different "depth" which should not omitted 
> in the check. But I have no idea of a better solution, only to pass a 
> `ClassTemplateDecl` or `ClassTemplateSpecializationDecl` to 
> `StructuralEquivalenceContext` and omit the depth check only at this object.

Thanks for your advice. More conditions are added to check when to ignore the 
comparison and minimize the influence to other.
Also I have tried to not increase depth in friend declaration in the template 
class, but the code affects others a lot. Only to skip the comparison can pass 
this special case.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156693

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


[PATCH] D156693: [clang][ASTImporter]Skip check friend template depth

2023-08-08 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky updated this revision to Diff 548166.
jcsxky edited the summary of this revision.
jcsxky added a comment.

update diff: add more conditions on when to ignore comparing depth of two 
template classes to minimize influence to others and fix name of test case to 
make easy understanding


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156693

Files:
  clang/include/clang/AST/ASTStructuralEquivalence.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/ASTStructuralEquivalence.cpp
  clang/unittests/AST/ASTImporterTest.cpp

Index: clang/unittests/AST/ASTImporterTest.cpp
===
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -4212,6 +4212,56 @@
   EXPECT_TRUE(Imported->getPreviousDecl());
 }
 
+TEST_P(ImportFriendClasses, SkipComparingFriendTemplateDepth) {
+  Decl *ToTU = getToTuDecl(
+  R"(
+  template 
+  class A;
+
+  template 
+  class A {
+  public:
+template 
+friend class A;
+
+A(T x)  :x(x) {}
+
+  private:
+T x;
+  };
+  )",
+  Lang_CXX11);
+
+  auto *Fwd = FirstDeclMatcher().match(
+  ToTU, classTemplateDecl(hasName("A")));
+  Decl *FromTU = getTuDecl(
+  R"(
+  template 
+  class A;
+
+  template 
+  class A {
+  public:
+template 
+friend class A;
+
+A(T x) : x(x) {}
+
+  private:
+T x;
+  };
+
+  A a1(0);
+  )",
+  Lang_CXX11, "input1.cc");
+  auto *FromA = FirstDeclMatcher().match(
+  FromTU, classTemplateDecl(hasName("A")));
+  auto *ToA = Import(FromA, Lang_CXX11);
+  EXPECT_TRUE(ToA);
+  EXPECT_EQ(Fwd->getTemplatedDecl()->getTypeForDecl(),
+ToA->getTemplatedDecl()->getTypeForDecl());
+}
+
 TEST_P(ImportFriendClasses,
ImportOfClassTemplateDefinitionShouldConnectToFwdFriend) {
   Decl *ToTU = getToTuDecl(
Index: clang/lib/AST/ASTStructuralEquivalence.cpp
===
--- clang/lib/AST/ASTStructuralEquivalence.cpp
+++ clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -1092,7 +1092,7 @@
   case Type::TemplateTypeParm: {
 const auto *Parm1 = cast(T1);
 const auto *Parm2 = cast(T2);
-if (Parm1->getDepth() != Parm2->getDepth())
+if (!Context.IgnoreDepth && Parm1->getDepth() != Parm2->getDepth())
   return false;
 if (Parm1->getIndex() != Parm2->getIndex())
   return false;
Index: clang/lib/AST/ASTImporter.cpp
===
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -34,6 +34,7 @@
 #include "clang/AST/LambdaCapture.h"
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/OperationKinds.h"
+#include "clang/AST/ParentMapContext.h"
 #include "clang/AST/Stmt.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
@@ -506,7 +507,8 @@
 template 
 bool hasSameVisibilityContextAndLinkage(T *Found, T *From);
 
-bool IsStructuralMatch(Decl *From, Decl *To, bool Complain = true);
+bool IsStructuralMatch(Decl *From, Decl *To, bool Complain = true,
+   bool IgnoreDepth = true);
 ExpectedDecl VisitDecl(Decl *D);
 ExpectedDecl VisitImportDecl(ImportDecl *D);
 ExpectedDecl VisitEmptyDecl(EmptyDecl *D);
@@ -2243,7 +2245,8 @@
 : StructuralEquivalenceKind::Default;
 }
 
-bool ASTNodeImporter::IsStructuralMatch(Decl *From, Decl *To, bool Complain) {
+bool ASTNodeImporter::IsStructuralMatch(Decl *From, Decl *To, bool Complain,
+bool IgnoreDepth) {
   // Eliminate a potential failure point where we attempt to re-import
   // something we're trying to import while completing ToRecord.
   Decl *ToOrigin = Importer.GetOriginalDecl(To);
@@ -2254,7 +2257,7 @@
   StructuralEquivalenceContext Ctx(
   Importer.getFromContext(), Importer.getToContext(),
   Importer.getNonEquivalentDecls(), getStructuralEquivalenceKind(Importer),
-  false, Complain);
+  false, Complain, false, IgnoreDepth);
   return Ctx.IsEquivalent(From, To);
 }
 
@@ -5822,7 +5825,11 @@
 if (!hasSameVisibilityContextAndLinkage(FoundTemplate, D))
   continue;
 
-if (IsStructuralMatch(D, FoundTemplate)) {
+// FIXME: sufficient conditon for 'IgnoreDepth'?
+bool IgnoreDepth =
+FoundTemplate->getFriendObjectKind() != Decl::FOK_None &&
+!D->specializations().empty();
+if (IsStructuralMatch(D, FoundTemplate, true, IgnoreDepth)) {
   ClassTemplateDecl *TemplateWithDef =
   getTemplateDefinition(FoundTemplate);
   if (D->isThisDeclarationADefinition() && TemplateWithDef)
Index: clang/include/clang/AST/ASTStructuralEquivalence.h

[PATCH] D156693: [clang][ASTImporter]Skip check friend template depth

2023-08-05 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky updated this revision to Diff 547505.
jcsxky added a comment.

clean unittest


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156693

Files:
  clang/include/clang/AST/ASTStructuralEquivalence.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/ASTStructuralEquivalence.cpp
  clang/unittests/AST/ASTImporterTest.cpp

Index: clang/unittests/AST/ASTImporterTest.cpp
===
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -4212,6 +4212,56 @@
   EXPECT_TRUE(Imported->getPreviousDecl());
 }
 
+TEST_P(ImportFriendClasses, SkipFriendTemplateDeclaration) {
+  Decl *ToTU = getToTuDecl(
+  R"(
+  template 
+  class A;
+
+  template 
+  class A {
+  public:
+template 
+friend class A;
+
+A(T x)  :x(x) {}
+
+  private:
+T x;
+  };
+  )",
+  Lang_CXX11);
+
+  auto *Fwd = FirstDeclMatcher().match(
+  ToTU, classTemplateDecl(hasName("A")));
+  Decl *FromTU = getTuDecl(
+  R"(
+  template 
+  class A;
+
+  template 
+  class A {
+  public:
+template 
+friend class A;
+
+A(T x) : x(x) {}
+
+  private:
+T x;
+  };
+
+  A a1(0);
+  )",
+  Lang_CXX11, "input1.cc");
+  auto *FromA = FirstDeclMatcher().match(
+  FromTU, classTemplateDecl(hasName("A")));
+  auto *ToA = Import(FromA, Lang_CXX11);
+  EXPECT_TRUE(ToA);
+  EXPECT_EQ(Fwd->getTemplatedDecl()->getTypeForDecl(),
+ToA->getTemplatedDecl()->getTypeForDecl());
+}
+
 TEST_P(ImportFriendClasses,
ImportOfClassTemplateDefinitionShouldConnectToFwdFriend) {
   Decl *ToTU = getToTuDecl(
Index: clang/lib/AST/ASTStructuralEquivalence.cpp
===
--- clang/lib/AST/ASTStructuralEquivalence.cpp
+++ clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -1092,7 +1092,7 @@
   case Type::TemplateTypeParm: {
 const auto *Parm1 = cast(T1);
 const auto *Parm2 = cast(T2);
-if (Parm1->getDepth() != Parm2->getDepth())
+if (!Context.IgnoreDepth && Parm1->getDepth() != Parm2->getDepth())
   return false;
 if (Parm1->getIndex() != Parm2->getIndex())
   return false;
Index: clang/lib/AST/ASTImporter.cpp
===
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -34,6 +34,7 @@
 #include "clang/AST/LambdaCapture.h"
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/OperationKinds.h"
+#include "clang/AST/ParentMapContext.h"
 #include "clang/AST/Stmt.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
@@ -506,7 +507,8 @@
 template 
 bool hasSameVisibilityContextAndLinkage(T *Found, T *From);
 
-bool IsStructuralMatch(Decl *From, Decl *To, bool Complain = true);
+bool IsStructuralMatch(Decl *From, Decl *To, bool Complain = true,
+   bool IgnoreDepth = true);
 ExpectedDecl VisitDecl(Decl *D);
 ExpectedDecl VisitImportDecl(ImportDecl *D);
 ExpectedDecl VisitEmptyDecl(EmptyDecl *D);
@@ -2243,7 +2245,8 @@
 : StructuralEquivalenceKind::Default;
 }
 
-bool ASTNodeImporter::IsStructuralMatch(Decl *From, Decl *To, bool Complain) {
+bool ASTNodeImporter::IsStructuralMatch(Decl *From, Decl *To, bool Complain,
+bool IgnoreDepth) {
   // Eliminate a potential failure point where we attempt to re-import
   // something we're trying to import while completing ToRecord.
   Decl *ToOrigin = Importer.GetOriginalDecl(To);
@@ -2254,7 +2257,7 @@
   StructuralEquivalenceContext Ctx(
   Importer.getFromContext(), Importer.getToContext(),
   Importer.getNonEquivalentDecls(), getStructuralEquivalenceKind(Importer),
-  false, Complain);
+  false, Complain, false, IgnoreDepth);
   return Ctx.IsEquivalent(From, To);
 }
 
@@ -5822,7 +5825,7 @@
 if (!hasSameVisibilityContextAndLinkage(FoundTemplate, D))
   continue;
 
-if (IsStructuralMatch(D, FoundTemplate)) {
+if (IsStructuralMatch(D, FoundTemplate, true, true)) {
   ClassTemplateDecl *TemplateWithDef =
   getTemplateDefinition(FoundTemplate);
   if (D->isThisDeclarationADefinition() && TemplateWithDef)
Index: clang/include/clang/AST/ASTStructuralEquivalence.h
===
--- clang/include/clang/AST/ASTStructuralEquivalence.h
+++ clang/include/clang/AST/ASTStructuralEquivalence.h
@@ -69,15 +69,19 @@
   /// \c true if the last diagnostic came from ToCtx.
   bool LastDiagFromC2 = false;
 
+  /// Whether to ignore comparing the depth of NonTypeParmDecl
+  bool IgnoreDepth;
+
   StructuralEquivalenceContext(
   ASTContext , ASTContext ,
   llvm::DenseSet> ,
-  

[PATCH] D156693: [clang][ASTImporter]Skip check friend template declaration in VisitClassTemplateDecl

2023-08-05 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky updated this revision to Diff 547501.
jcsxky edited the summary of this revision.
jcsxky added a comment.

update diff: ignore compare depth in friend class template


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156693

Files:
  clang/include/clang/AST/ASTStructuralEquivalence.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/ASTStructuralEquivalence.cpp
  clang/unittests/AST/ASTImporterTest.cpp

Index: clang/unittests/AST/ASTImporterTest.cpp
===
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -4212,6 +4212,57 @@
   EXPECT_TRUE(Imported->getPreviousDecl());
 }
 
+TEST_P(ImportFriendClasses, SkipFriendTemplateDeclaration) {
+  Decl *ToTU = getToTuDecl(
+  R"(
+  template 
+  class A;
+
+  template 
+  class A {
+  public:
+template 
+friend class A;
+
+A(T x)  :x(x) {}
+
+  private:
+T x;
+  };
+  )",
+  Lang_CXX11);
+
+  auto *Fwd = FirstDeclMatcher().match(
+  ToTU, classTemplateDecl(hasName("A")));
+  Decl *FromTU = getTuDecl(
+  R"(
+  template 
+  class A;
+
+  template 
+  class A {
+  public:
+template 
+friend class A;
+
+A(T x) : x(x) {}
+
+  private:
+T x;
+  };
+
+  A a1(0);
+  )",
+  Lang_CXX11, "input1.cc");
+  auto *Definition = FirstDeclMatcher().match(
+  FromTU, classTemplateDecl(hasName("A")));
+  auto *Template = Import(Definition, Lang_CXX11);
+  EXPECT_TRUE(Template);
+  auto *TemplateClass = cast(Template);
+  EXPECT_EQ(Fwd->getTemplatedDecl()->getTypeForDecl(),
+TemplateClass->getTemplatedDecl()->getTypeForDecl());
+}
+
 TEST_P(ImportFriendClasses,
ImportOfClassTemplateDefinitionShouldConnectToFwdFriend) {
   Decl *ToTU = getToTuDecl(
Index: clang/lib/AST/ASTStructuralEquivalence.cpp
===
--- clang/lib/AST/ASTStructuralEquivalence.cpp
+++ clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -1092,7 +1092,7 @@
   case Type::TemplateTypeParm: {
 const auto *Parm1 = cast(T1);
 const auto *Parm2 = cast(T2);
-if (Parm1->getDepth() != Parm2->getDepth())
+if (!Context.IgnoreDepth && Parm1->getDepth() != Parm2->getDepth())
   return false;
 if (Parm1->getIndex() != Parm2->getIndex())
   return false;
Index: clang/lib/AST/ASTImporter.cpp
===
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -34,6 +34,7 @@
 #include "clang/AST/LambdaCapture.h"
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/OperationKinds.h"
+#include "clang/AST/ParentMapContext.h"
 #include "clang/AST/Stmt.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
@@ -506,7 +507,8 @@
 template 
 bool hasSameVisibilityContextAndLinkage(T *Found, T *From);
 
-bool IsStructuralMatch(Decl *From, Decl *To, bool Complain = true);
+bool IsStructuralMatch(Decl *From, Decl *To, bool Complain = true,
+   bool IgnoreDepth = true);
 ExpectedDecl VisitDecl(Decl *D);
 ExpectedDecl VisitImportDecl(ImportDecl *D);
 ExpectedDecl VisitEmptyDecl(EmptyDecl *D);
@@ -2243,7 +2245,8 @@
 : StructuralEquivalenceKind::Default;
 }
 
-bool ASTNodeImporter::IsStructuralMatch(Decl *From, Decl *To, bool Complain) {
+bool ASTNodeImporter::IsStructuralMatch(Decl *From, Decl *To, bool Complain,
+bool IgnoreDepth) {
   // Eliminate a potential failure point where we attempt to re-import
   // something we're trying to import while completing ToRecord.
   Decl *ToOrigin = Importer.GetOriginalDecl(To);
@@ -2254,7 +2257,7 @@
   StructuralEquivalenceContext Ctx(
   Importer.getFromContext(), Importer.getToContext(),
   Importer.getNonEquivalentDecls(), getStructuralEquivalenceKind(Importer),
-  false, Complain);
+  false, Complain, false, IgnoreDepth);
   return Ctx.IsEquivalent(From, To);
 }
 
@@ -5822,7 +5825,7 @@
 if (!hasSameVisibilityContextAndLinkage(FoundTemplate, D))
   continue;
 
-if (IsStructuralMatch(D, FoundTemplate)) {
+if (IsStructuralMatch(D, FoundTemplate, true, true)) {
   ClassTemplateDecl *TemplateWithDef =
   getTemplateDefinition(FoundTemplate);
   if (D->isThisDeclarationADefinition() && TemplateWithDef)
Index: clang/include/clang/AST/ASTStructuralEquivalence.h
===
--- clang/include/clang/AST/ASTStructuralEquivalence.h
+++ clang/include/clang/AST/ASTStructuralEquivalence.h
@@ -69,15 +69,19 @@
   /// \c true if the last diagnostic came from ToCtx.
   bool LastDiagFromC2 = false;
 
+  /// Whether to 

[PATCH] D156693: [clang][ASTImporter]Skip check friend template declaration in VisitClassTemplateDecl

2023-08-05 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky added a comment.

In D156693#4560110 , @balazske wrote:

> The summary tells nothing about what is the real problem to fix here. In the 
> lit test I see that an error message is displayed, this causes the test 
> failure. The problem is that the structural equivalence check is not good for 
> this special case. The imported AST contains a class template specialization 
> for `A`, in this specialization the friend class template `A` has a previous 
> decl that points to the original friend class template that is in a 
> `ClassTemplateDecl`. In the specialization the "depth" of template arguments 
> is 0, but in the original template it is 1 (the "to" code at import contains 
> only the "original template", no specialization). This difference in the 
> "depth" causes the type mismatch when the specialization is imported.
> AST dump of this code can show the problem:
>
>   template
>   class A;
>   
>   template
>   class A {
>   public:
> template
> friend class A;
>   
> A(T x):x(x){}
>   
>   private:
> T x;
>   };
>   
>   A a1(0);
>
> It is really interesting that at friend templates the depth is 1 but friend 
> declarations point to objects outside the class, so really the depth should 
> not increase in a friend template from this point of view. But this is an AST 
> issue.

Depth of specialization friend template is 0 while it is 1 in class declaration 
 is reasonable, because after template class specialization there not exists 
template parameter and the friend template becomes outermost scope, thus depth 
is 0. Thanks to the different of depth causes the non equivalence of the two 
'NonTypeTemplateParm', I think there should ignore comparing the depth in this 
special case to make two types equivalence.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156693

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


[PATCH] D157170: [clang][AST]Don't increase depth in friend tempalte class declaration

2023-08-04 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky created this revision.
jcsxky added reviewers: a.sidorin, shafik, balazske, steakhal, aaron.ballman, 
Michael137.
jcsxky added projects: clang, clang-c.
Herald added a project: All.
jcsxky requested review of this revision.
Herald added a subscriber: cfe-commits.

Don't increase template parameter's depth when it's a friend declaration in 
template class. The reason is that this member(template class) should match the 
previous class definition and when import from external ast file, type of them 
should be equivalence.
See import issue 


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D157170

Files:
  clang/lib/Parse/ParseTemplate.cpp
  clang/unittests/AST/ASTImporterTest.cpp


Index: clang/unittests/AST/ASTImporterTest.cpp
===
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -4212,6 +4212,56 @@
   EXPECT_TRUE(Imported->getPreviousDecl());
 }
 
+TEST_P(ImportFriendClasses, SkipFriendTemplateDeclaration) {
+  Decl *ToTU = getToTuDecl(
+  R"(
+  template 
+  class A;
+
+  template 
+  class A {
+  public:
+template 
+friend class A;
+
+A(T x):x(x) {}
+
+  private:
+T x;
+  };
+  )",
+  Lang_CXX11);
+
+  auto *Fwd = FirstDeclMatcher().match(
+  ToTU, classTemplateDecl(hasName("A")));
+  Decl *FromTU = getTuDecl(
+  R"(
+  template 
+  class A;
+
+  template 
+  class A {
+  public:
+template 
+friend class A;
+
+A(T x):x(x) {}
+
+  private:
+T x;
+  };
+
+  A a1(0);
+  )",
+  Lang_CXX11, "input1.cc");
+  auto *FromA = FirstDeclMatcher().match(
+  FromTU, classTemplateDecl(hasName("A")));
+  auto *ToA = Import(FromA, Lang_CXX11);
+  EXPECT_TRUE(ToA);
+  EXPECT_EQ(Fwd->getTemplatedDecl()->getTypeForDecl(),
+ToA->getTemplatedDecl()->getTypeForDecl());
+}
+
 TEST_P(ImportFriendClasses,
ImportOfClassTemplateDefinitionShouldConnectToFwdFriend) {
   Decl *ToTU = getToTuDecl(
Index: clang/lib/Parse/ParseTemplate.cpp
===
--- clang/lib/Parse/ParseTemplate.cpp
+++ clang/lib/Parse/ParseTemplate.cpp
@@ -127,8 +127,30 @@
 // Parse the '<' template-parameter-list '>'
 SourceLocation LAngleLoc, RAngleLoc;
 SmallVector TemplateParams;
+
+bool SeeFriendKeyWord = false;
+{
+  SmallVector TemplateParams;
+  SourceLocation LAngleLoc, RAngleLoc;
+  RevertingTentativeParsingAction TPA(*this);
+  MultiParseScope TemplateParamScopesTmp(*this);
+  if (ParseTemplateParameters(TemplateParamScopesTmp,
+  CurTemplateDepthTracker.getDepth(),
+  TemplateParams, LAngleLoc, RAngleLoc)) {
+// returns true don't need process
+// returns false, blowe 'ParseTemplateParameters' will do it after
+// revert
+  }
+  // skip outmost declaration
+  if (Tok.is(tok::kw_friend) && CurTemplateDepthTracker.getDepth() > 0) {
+SeeFriendKeyWord = true;
+  }
+}
+
 if (ParseTemplateParameters(TemplateParamScopes,
-CurTemplateDepthTracker.getDepth(),
+SeeFriendKeyWord
+? CurTemplateDepthTracker.getDepth() - 1
+: CurTemplateDepthTracker.getDepth(),
 TemplateParams, LAngleLoc, RAngleLoc)) {
   // Skip until the semi-colon or a '}'.
   SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);


Index: clang/unittests/AST/ASTImporterTest.cpp
===
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -4212,6 +4212,56 @@
   EXPECT_TRUE(Imported->getPreviousDecl());
 }
 
+TEST_P(ImportFriendClasses, SkipFriendTemplateDeclaration) {
+  Decl *ToTU = getToTuDecl(
+  R"(
+  template 
+  class A;
+
+  template 
+  class A {
+  public:
+template 
+friend class A;
+
+A(T x):x(x) {}
+
+  private:
+T x;
+  };
+  )",
+  Lang_CXX11);
+
+  auto *Fwd = FirstDeclMatcher().match(
+  ToTU, classTemplateDecl(hasName("A")));
+  Decl *FromTU = getTuDecl(
+  R"(
+  template 
+  class A;
+
+  template 
+  class A {
+  public:
+template 
+friend class A;
+
+A(T x):x(x) {}
+
+  private:
+T x;
+  };
+
+  A a1(0);
+  )",
+  Lang_CXX11, "input1.cc");
+  auto *FromA = FirstDeclMatcher().match(
+  FromTU, classTemplateDecl(hasName("A")));
+ 

[PATCH] D156693: [clang][ASTImporter]Skip check friend template declaration in VisitClassTemplateDecl

2023-08-04 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky added a comment.

In D156693#4560023 , @Michael137 
wrote:

> Could you please elaborate in the commit message what exactly the issue 
> currently is and how the patch addresses it?



In D156693#4560023 , @Michael137 
wrote:

> Could you please elaborate in the commit message what exactly the issue 
> currently is and how the patch addresses it?

details are added to commit message


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156693

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


[PATCH] D156693: [clang][ASTImporter]Skip check friend template declaration in VisitClassTemplateDecl

2023-08-04 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky updated this revision to Diff 547124.
jcsxky added a comment.

add unittest


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156693

Files:
  clang/lib/AST/ASTImporter.cpp
  clang/test/Analysis/Inputs/ctu-friend-template-other.cpp
  clang/test/Analysis/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt
  clang/test/Analysis/Inputs/ctu-friend-template.h
  clang/test/Analysis/ctu-friend-template.cpp
  clang/unittests/AST/ASTImporterTest.cpp

Index: clang/unittests/AST/ASTImporterTest.cpp
===
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -4212,6 +4212,84 @@
   EXPECT_TRUE(Imported->getPreviousDecl());
 }
 
+TEST_P(ImportFriendClasses, SkipFriendTemplateDeclaration) {
+  Decl *ToTU = getToTuDecl(
+  R"(
+namespace __1{
+
+  template
+  class A;
+
+  template
+  class A{
+  public:
+template
+friend class A;
+
+A(T x):x(x){}
+
+void foo(){
+  int i=0;
+  int j=1/i;
+  (void)j;
+}
+
+  private:
+T x;
+  };
+
+  }
+  void bar();
+
+  int main(){
+bar();
+  }
+  )",
+  Lang_CXX11);
+
+  auto *Fwd = FirstDeclMatcher().match(
+  ToTU, classTemplateDecl(hasName("A")));
+  Decl *FromTU = getTuDecl(
+  R"(
+  namespace __1{
+
+  template
+  class A;
+
+  template
+  class A{
+  public:
+template
+friend class A;
+
+A(T x):x(x){}
+
+void foo(){
+  int i=0;
+  int j=1/i;
+  (void)j;
+}
+
+  private:
+T x;
+  };
+
+}
+void bar(){
+  __1::A a1(0);
+  a1.foo();
+}
+  )",
+  Lang_CXX11, "input1.cc");
+  auto *Definition = FirstDeclMatcher().match(
+  FromTU, classTemplateDecl(hasName("A")));
+  auto *Template = Import(Definition, Lang_CXX11);
+  EXPECT_TRUE(Template);
+  auto *TemplateClass = cast(Template);
+  EXPECT_EQ(Fwd->getTemplatedDecl()->getTypeForDecl(),
+TemplateClass->getTemplatedDecl()->getTypeForDecl());
+}
+
 TEST_P(ImportFriendClasses,
ImportOfClassTemplateDefinitionShouldConnectToFwdFriend) {
   Decl *ToTU = getToTuDecl(
Index: clang/test/Analysis/ctu-friend-template.cpp
===
--- /dev/null
+++ clang/test/Analysis/ctu-friend-template.cpp
@@ -0,0 +1,21 @@
+// RUN: rm -rf %t && mkdir %t
+// RUN: mkdir -p %t/ctudir
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \
+// RUN:   -emit-pch -o %t/ctudir/ctu-friend-template-other.cpp.ast %S/Inputs/ctu-friend-template-other.cpp
+// RUN: cp %S/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt %t/ctudir/externalDefMap.txt
+// RUN: %clang_analyze_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \
+// RUN:   -analyzer-checker=core,debug.ExprInspection \
+// RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
+// RUN:   -analyzer-config ctu-dir=%t/ctudir \
+// RUN:   -Werror=ctu \
+// RUN:   -verify %s
+
+// CHECK: CTU loaded AST file
+
+#include "Inputs/ctu-friend-template.h"
+
+void bar();
+
+int main(){
+	bar(); // expected-no-diagnostics
+}
Index: clang/test/Analysis/Inputs/ctu-friend-template.h
===
--- /dev/null
+++ clang/test/Analysis/Inputs/ctu-friend-template.h
@@ -0,0 +1,20 @@
+namespace __1{
+
+template
+class A;
+
+template
+class A{
+public:
+	template
+	friend class A;
+
+	A(T x):x(x){}
+	
+	void foo(){}
+	
+private:
+	T x;
+};
+
+}
Index: clang/test/Analysis/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt
===
--- /dev/null
+++ clang/test/Analysis/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt
@@ -0,0 +1 @@
+9:c:@F@bar# ctu-friend-template-other.cpp.ast
Index: clang/test/Analysis/Inputs/ctu-friend-template-other.cpp
===
--- /dev/null
+++ clang/test/Analysis/Inputs/ctu-friend-template-other.cpp
@@ -0,0 +1,6 @@
+#include "ctu-friend-template.h"
+
+void bar(){
+	__1::A a1(0);
+	a1.foo();
+}
Index: clang/lib/AST/ASTImporter.cpp
===
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -34,6 +34,7 @@
 #include "clang/AST/LambdaCapture.h"
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/OperationKinds.h"
+#include "clang/AST/ParentMapContext.h"
 #include "clang/AST/Stmt.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
@@ -5821,7 +5822,11 @@
   if (FoundTemplate) 

[PATCH] D156693: [clang][ASTImporter]Skip check friend template declaration in VisitClassTemplateDecl

2023-08-02 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky updated this revision to Diff 546698.
jcsxky added a comment.

format code


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156693

Files:
  clang/lib/AST/ASTImporter.cpp
  clang/test/Analysis/Inputs/ctu-friend-template-other.cpp
  clang/test/Analysis/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt
  clang/test/Analysis/Inputs/ctu-friend-template.h
  clang/test/Analysis/ctu-friend-template.cpp


Index: clang/test/Analysis/ctu-friend-template.cpp
===
--- /dev/null
+++ clang/test/Analysis/ctu-friend-template.cpp
@@ -0,0 +1,21 @@
+// RUN: rm -rf %t && mkdir %t
+// RUN: mkdir -p %t/ctudir
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \
+// RUN:   -emit-pch -o %t/ctudir/ctu-friend-template-other.cpp.ast 
%S/Inputs/ctu-friend-template-other.cpp
+// RUN: cp %S/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt 
%t/ctudir/externalDefMap.txt
+// RUN: %clang_analyze_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \
+// RUN:   -analyzer-checker=core,debug.ExprInspection \
+// RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
+// RUN:   -analyzer-config ctu-dir=%t/ctudir \
+// RUN:   -Werror=ctu \
+// RUN:   -verify %s
+
+// CHECK: CTU loaded AST file
+
+#include "Inputs/ctu-friend-template.h"
+
+void bar();
+
+int main(){
+   bar(); // expected-no-diagnostics
+}
Index: clang/test/Analysis/Inputs/ctu-friend-template.h
===
--- /dev/null
+++ clang/test/Analysis/Inputs/ctu-friend-template.h
@@ -0,0 +1,20 @@
+namespace __1{
+
+template
+class A;
+
+template
+class A{
+public:
+   template
+   friend class A;
+
+   A(T x):x(x){}
+   
+   void foo(){}
+   
+private:
+   T x;
+};
+
+}
Index: 
clang/test/Analysis/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt
===
--- /dev/null
+++ clang/test/Analysis/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt
@@ -0,0 +1 @@
+9:c:@F@bar# ctu-friend-template-other.cpp.ast
Index: clang/test/Analysis/Inputs/ctu-friend-template-other.cpp
===
--- /dev/null
+++ clang/test/Analysis/Inputs/ctu-friend-template-other.cpp
@@ -0,0 +1,6 @@
+#include "ctu-friend-template.h"
+
+void bar(){
+   __1::A a1(0);
+   a1.foo();
+}
Index: clang/lib/AST/ASTImporter.cpp
===
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -34,6 +34,7 @@
 #include "clang/AST/LambdaCapture.h"
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/OperationKinds.h"
+#include "clang/AST/ParentMapContext.h"
 #include "clang/AST/Stmt.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
@@ -5821,7 +5822,11 @@
   if (FoundTemplate) {
 if (!hasSameVisibilityContextAndLinkage(FoundTemplate, D))
   continue;
-
+auto Parents = FoundDecl->getASTContext().getParents(*FoundDecl);
+if (!Parents.empty() && nullptr != Parents.begin()->get() 
&&
+FoundTemplate->getName() == D->getName() &&
+!IsStructuralMatch(D, FoundTemplate, false))
+  continue;
 if (IsStructuralMatch(D, FoundTemplate)) {
   ClassTemplateDecl *TemplateWithDef =
   getTemplateDefinition(FoundTemplate);


Index: clang/test/Analysis/ctu-friend-template.cpp
===
--- /dev/null
+++ clang/test/Analysis/ctu-friend-template.cpp
@@ -0,0 +1,21 @@
+// RUN: rm -rf %t && mkdir %t
+// RUN: mkdir -p %t/ctudir
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \
+// RUN:   -emit-pch -o %t/ctudir/ctu-friend-template-other.cpp.ast %S/Inputs/ctu-friend-template-other.cpp
+// RUN: cp %S/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt %t/ctudir/externalDefMap.txt
+// RUN: %clang_analyze_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \
+// RUN:   -analyzer-checker=core,debug.ExprInspection \
+// RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
+// RUN:   -analyzer-config ctu-dir=%t/ctudir \
+// RUN:   -Werror=ctu \
+// RUN:   -verify %s
+
+// CHECK: CTU loaded AST file
+
+#include "Inputs/ctu-friend-template.h"
+
+void bar();
+
+int main(){
+	bar(); // expected-no-diagnostics
+}
Index: clang/test/Analysis/Inputs/ctu-friend-template.h
===
--- /dev/null
+++ clang/test/Analysis/Inputs/ctu-friend-template.h
@@ -0,0 +1,20 @@
+namespace __1{
+
+template
+class A;
+
+template
+class A{
+public:
+	template
+	friend class A;
+
+	A(T x):x(x){}
+	
+	void foo(){}
+	
+private:
+	T x;
+};
+
+}
Index: clang/test/Analysis/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt

[PATCH] D156693: [clang][ASTImporter]Skip check friend template declaration in VisitClassTemplateDecl

2023-08-01 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky updated this revision to Diff 546309.
jcsxky added a comment.

update patch for pass unittests and test


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156693

Files:
  clang/lib/AST/ASTImporter.cpp
  clang/test/Analysis/Inputs/ctu-friend-template-other.cpp
  clang/test/Analysis/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt
  clang/test/Analysis/Inputs/ctu-friend-template.h
  clang/test/Analysis/ctu-friend-template.cpp


Index: clang/test/Analysis/ctu-friend-template.cpp
===
--- /dev/null
+++ clang/test/Analysis/ctu-friend-template.cpp
@@ -0,0 +1,21 @@
+// RUN: rm -rf %t && mkdir %t
+// RUN: mkdir -p %t/ctudir
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \
+// RUN:   -emit-pch -o %t/ctudir/ctu-friend-template-other.cpp.ast 
%S/Inputs/ctu-friend-template-other.cpp
+// RUN: cp %S/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt 
%t/ctudir/externalDefMap.txt
+// RUN: %clang_analyze_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \
+// RUN:   -analyzer-checker=core,debug.ExprInspection \
+// RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
+// RUN:   -analyzer-config ctu-dir=%t/ctudir \
+// RUN:   -Werror=ctu \
+// RUN:   -verify %s
+
+// CHECK: CTU loaded AST file
+
+#include "Inputs/ctu-friend-template.h"
+
+void bar();
+
+int main(){
+   bar(); // expected-no-diagnostics
+}
Index: clang/test/Analysis/Inputs/ctu-friend-template.h
===
--- /dev/null
+++ clang/test/Analysis/Inputs/ctu-friend-template.h
@@ -0,0 +1,20 @@
+namespace __1{
+
+template
+class A;
+
+template
+class A{
+public:
+   template
+   friend class A;
+
+   A(T x):x(x){}
+   
+   void foo(){}
+   
+private:
+   T x;
+};
+
+}
Index: 
clang/test/Analysis/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt
===
--- /dev/null
+++ clang/test/Analysis/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt
@@ -0,0 +1 @@
+9:c:@F@bar# ctu-friend-template-other.cpp.ast
Index: clang/test/Analysis/Inputs/ctu-friend-template-other.cpp
===
--- /dev/null
+++ clang/test/Analysis/Inputs/ctu-friend-template-other.cpp
@@ -0,0 +1,6 @@
+#include "ctu-friend-template.h"
+
+void bar(){
+   __1::A a1(0);
+   a1.foo();
+}
Index: clang/lib/AST/ASTImporter.cpp
===
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -44,6 +44,7 @@
 #include "clang/AST/TypeLoc.h"
 #include "clang/AST/TypeVisitor.h"
 #include "clang/AST/UnresolvedSet.h"
+#include "clang/AST/ParentMapContext.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/ExceptionSpecificationType.h"
 #include "clang/Basic/FileManager.h"
@@ -5812,6 +5813,11 @@
   if (FoundTemplate) {
 if (!hasSameVisibilityContextAndLinkage(FoundTemplate, D))
   continue;
+auto Parents = FoundDecl->getASTContext().getParents(*FoundDecl);
+if (!Parents.empty() && nullptr != Parents.begin()->get() 
&&
+FoundTemplate->getName() == D->getName() &&
+!IsStructuralMatch(D, FoundTemplate, false))
+  continue;
 
 if (IsStructuralMatch(D, FoundTemplate)) {
   ClassTemplateDecl *TemplateWithDef =


Index: clang/test/Analysis/ctu-friend-template.cpp
===
--- /dev/null
+++ clang/test/Analysis/ctu-friend-template.cpp
@@ -0,0 +1,21 @@
+// RUN: rm -rf %t && mkdir %t
+// RUN: mkdir -p %t/ctudir
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \
+// RUN:   -emit-pch -o %t/ctudir/ctu-friend-template-other.cpp.ast %S/Inputs/ctu-friend-template-other.cpp
+// RUN: cp %S/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt %t/ctudir/externalDefMap.txt
+// RUN: %clang_analyze_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \
+// RUN:   -analyzer-checker=core,debug.ExprInspection \
+// RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
+// RUN:   -analyzer-config ctu-dir=%t/ctudir \
+// RUN:   -Werror=ctu \
+// RUN:   -verify %s
+
+// CHECK: CTU loaded AST file
+
+#include "Inputs/ctu-friend-template.h"
+
+void bar();
+
+int main(){
+	bar(); // expected-no-diagnostics
+}
Index: clang/test/Analysis/Inputs/ctu-friend-template.h
===
--- /dev/null
+++ clang/test/Analysis/Inputs/ctu-friend-template.h
@@ -0,0 +1,20 @@
+namespace __1{
+
+template
+class A;
+
+template
+class A{
+public:
+	template
+	friend class A;
+
+	A(T x):x(x){}
+	
+	void foo(){}
+	
+private:
+	T x;
+};
+
+}
Index: clang/test/Analysis/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt

[PATCH] D156693: [clang][ASTImporter]Skip check friend template declaration in VisitClassTemplateDecl

2023-08-01 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky updated this revision to Diff 546301.
jcsxky added a comment.

update patch for pass unittests


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156693

Files:
  clang/lib/AST/ASTImporter.cpp
  clang/test/Analysis/Inputs/ctu-friend-template-other.cpp
  clang/test/Analysis/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt
  clang/test/Analysis/Inputs/ctu-friend-template.h
  clang/test/Analysis/ctu-friend-template.cpp


Index: clang/test/Analysis/ctu-friend-template.cpp
===
--- /dev/null
+++ clang/test/Analysis/ctu-friend-template.cpp
@@ -0,0 +1,21 @@
+// RUN: rm -rf %t && mkdir %t
+// RUN: mkdir -p %t/ctudir
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \
+// RUN:   -emit-pch -o %t/ctudir/ctu-friend-template-other.cpp.ast 
%S/Inputs/ctu-friend-template-other.cpp
+// RUN: cp %S/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt 
%t/ctudir/externalDefMap.txt
+// RUN: %clang_analyze_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \
+// RUN:   -analyzer-checker=core,debug.ExprInspection \
+// RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
+// RUN:   -analyzer-config ctu-dir=%t/ctudir \
+// RUN:   -Werror=ctu \
+// RUN:   -verify %s
+
+// CHECK: CTU loaded AST file
+
+#include "Inputs/ctu-friend-template.h"
+
+void bar();
+
+int main(){
+   bar(); // expected-no-diagnostics
+}
Index: clang/test/Analysis/Inputs/ctu-friend-template.h
===
--- /dev/null
+++ clang/test/Analysis/Inputs/ctu-friend-template.h
@@ -0,0 +1,20 @@
+namespace __1{
+
+template
+class A;
+
+template
+class A{
+public:
+   template
+   friend class A;
+
+   A(T x):x(x){}
+   
+   void foo(){}
+   
+private:
+   T x;
+};
+
+}
Index: 
clang/test/Analysis/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt
===
--- /dev/null
+++ clang/test/Analysis/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt
@@ -0,0 +1 @@
+9:c:@F@bar# ctu-friend-template-other.cpp.ast
Index: clang/test/Analysis/Inputs/ctu-friend-template-other.cpp
===
--- /dev/null
+++ clang/test/Analysis/Inputs/ctu-friend-template-other.cpp
@@ -0,0 +1,6 @@
+#include "ctu-friend-template.h"
+
+void bar(){
+   __1::A a1(0);
+   a1.foo();
+}
Index: clang/lib/AST/ASTImporter.cpp
===
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -44,6 +44,7 @@
 #include "clang/AST/TypeLoc.h"
 #include "clang/AST/TypeVisitor.h"
 #include "clang/AST/UnresolvedSet.h"
+#include "clang/AST/ParentMapContext.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/ExceptionSpecificationType.h"
 #include "clang/Basic/FileManager.h"
@@ -5812,7 +5813,6 @@
   if (FoundTemplate) {
 if (!hasSameVisibilityContextAndLinkage(FoundTemplate, D))
   continue;
-
 if (IsStructuralMatch(D, FoundTemplate)) {
   ClassTemplateDecl *TemplateWithDef =
   getTemplateDefinition(FoundTemplate);
@@ -5824,6 +5824,11 @@
   // see ASTTests test ImportExistingFriendClassTemplateDef.
   continue;
 }
+auto Parents = FoundDecl->getASTContext().getParents(*FoundDecl);
+if (!Parents.empty() && nullptr != Parents.begin()->get() 
&&
+FoundTemplate->getName() == D->getName()) {
+  continue;
+}
 ConflictingDecls.push_back(FoundDecl);
   }
 }


Index: clang/test/Analysis/ctu-friend-template.cpp
===
--- /dev/null
+++ clang/test/Analysis/ctu-friend-template.cpp
@@ -0,0 +1,21 @@
+// RUN: rm -rf %t && mkdir %t
+// RUN: mkdir -p %t/ctudir
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \
+// RUN:   -emit-pch -o %t/ctudir/ctu-friend-template-other.cpp.ast %S/Inputs/ctu-friend-template-other.cpp
+// RUN: cp %S/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt %t/ctudir/externalDefMap.txt
+// RUN: %clang_analyze_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \
+// RUN:   -analyzer-checker=core,debug.ExprInspection \
+// RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
+// RUN:   -analyzer-config ctu-dir=%t/ctudir \
+// RUN:   -Werror=ctu \
+// RUN:   -verify %s
+
+// CHECK: CTU loaded AST file
+
+#include "Inputs/ctu-friend-template.h"
+
+void bar();
+
+int main(){
+	bar(); // expected-no-diagnostics
+}
Index: clang/test/Analysis/Inputs/ctu-friend-template.h
===
--- /dev/null
+++ clang/test/Analysis/Inputs/ctu-friend-template.h
@@ -0,0 +1,20 @@
+namespace __1{
+
+template
+class A;
+
+template
+class A{
+public:
+	template
+	friend class A;
+
+	A(T x):x(x){}
+	

[PATCH] D156693: [clang][ASTImporter]Don't add template decl as in friend decl

2023-07-31 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky created this revision.
jcsxky added reviewers: a.sidorin, shafik, balazske, steakhal.
jcsxky added a project: clang.
Herald added a subscriber: martong.
Herald added a project: All.
jcsxky requested review of this revision.
Herald added subscribers: cfe-commits, wangpc.

There is no need to add a ``` NameDecl ``` into ``` LookupTable ```when it is 
declared in friend declaration located in the template class definition. If 
it's ``` FriendType ```, then ``` VisitFriendDecl ``` can help us do it, or it 
is in declaring in current class definition, this has been processed by ``` 
VisitNamedDecl ``` before.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D156693

Files:
  clang/lib/AST/ASTImporterLookupTable.cpp
  clang/test/Analysis/Inputs/ctu-friend-template-other.cpp
  clang/test/Analysis/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt
  clang/test/Analysis/Inputs/ctu-friend-template.h
  clang/test/Analysis/ctu-friend-template.cpp


Index: clang/test/Analysis/ctu-friend-template.cpp
===
--- /dev/null
+++ clang/test/Analysis/ctu-friend-template.cpp
@@ -0,0 +1,21 @@
+// RUN: rm -rf %t && mkdir %t
+// RUN: mkdir -p %t/ctudir
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \
+// RUN:   -emit-pch -o %t/ctudir/ctu-friend-template-other.cpp.ast 
%S/Inputs/ctu-friend-template-other.cpp
+// RUN: cp %S/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt 
%t/ctudir/externalDefMap.txt
+// RUN: %clang_analyze_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \
+// RUN:   -analyzer-checker=core,debug.ExprInspection \
+// RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
+// RUN:   -analyzer-config ctu-dir=%t/ctudir \
+// RUN:   -Werror=ctu \
+// RUN:   -verify %s
+
+// CHECK: CTU loaded AST file
+
+#include "Inputs/ctu-friend-template.h"
+
+void bar();
+
+int main(){
+   bar(); // expected-no-diagnostics
+}
Index: clang/test/Analysis/Inputs/ctu-friend-template.h
===
--- /dev/null
+++ clang/test/Analysis/Inputs/ctu-friend-template.h
@@ -0,0 +1,20 @@
+namespace __1{
+
+template
+class A;
+
+template
+class A{
+public:
+   template
+   friend class A;
+
+   A(T x):x(x){}
+   
+   void foo(){}
+   
+private:
+   T x;
+};
+
+}
Index: 
clang/test/Analysis/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt
===
--- /dev/null
+++ clang/test/Analysis/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt
@@ -0,0 +1 @@
+9:c:@F@bar# ctu-friend-template-other.cpp.ast
Index: clang/test/Analysis/Inputs/ctu-friend-template-other.cpp
===
--- /dev/null
+++ clang/test/Analysis/Inputs/ctu-friend-template-other.cpp
@@ -0,0 +1,6 @@
+#include "ctu-friend-template.h"
+
+void bar(){
+   __1::A a1(0);
+   a1.foo();
+}
Index: clang/lib/AST/ASTImporterLookupTable.cpp
===
--- clang/lib/AST/ASTImporterLookupTable.cpp
+++ clang/lib/AST/ASTImporterLookupTable.cpp
@@ -14,6 +14,7 @@
 #include "clang/AST/ASTImporterLookupTable.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/ParentMapContext.h"
 #include "llvm/Support/FormatVariadic.h"
 
 namespace clang {
@@ -38,6 +39,10 @@
   }
 
   bool VisitNamedDecl(NamedDecl *D) {
+auto Parents = D->getASTContext().getParents(*D);
+if (!Parents.empty() && nullptr != Parents.begin()->get()) {
+  return true;
+}
 LT.add(D);
 return true;
   }


Index: clang/test/Analysis/ctu-friend-template.cpp
===
--- /dev/null
+++ clang/test/Analysis/ctu-friend-template.cpp
@@ -0,0 +1,21 @@
+// RUN: rm -rf %t && mkdir %t
+// RUN: mkdir -p %t/ctudir
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \
+// RUN:   -emit-pch -o %t/ctudir/ctu-friend-template-other.cpp.ast %S/Inputs/ctu-friend-template-other.cpp
+// RUN: cp %S/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt %t/ctudir/externalDefMap.txt
+// RUN: %clang_analyze_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \
+// RUN:   -analyzer-checker=core,debug.ExprInspection \
+// RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
+// RUN:   -analyzer-config ctu-dir=%t/ctudir \
+// RUN:   -Werror=ctu \
+// RUN:   -verify %s
+
+// CHECK: CTU loaded AST file
+
+#include "Inputs/ctu-friend-template.h"
+
+void bar();
+
+int main(){
+	bar(); // expected-no-diagnostics
+}
Index: clang/test/Analysis/Inputs/ctu-friend-template.h
===
--- /dev/null
+++ clang/test/Analysis/Inputs/ctu-friend-template.h
@@ -0,0 +1,20 @@
+namespace __1{
+
+template
+class A;
+
+template
+class A{
+public:
+	template
+	friend class A;
+
+	A(T x):x(x){}
+	
+	void foo(){}
+	

[PATCH] D155537: [ASTImporter] Fix import failed when anonymous union defined in class

2023-07-17 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky created this revision.
jcsxky added a reviewer: danix800.
jcsxky added a project: clang.
Herald added a subscriber: martong.
Herald added a reviewer: a.sidorin.
Herald added a reviewer: shafik.
Herald added a project: All.
jcsxky requested review of this revision.
Herald added a subscriber: cfe-commits.

when import a class contains two anonymous unions, constructor accesses member 
in the second union would lead to import the second union, after that, import 
the first union will lead to conflict, skip when two union are both anonymous.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D155537

Files:
  clang/lib/AST/ASTImporter.cpp
  clang/unittests/AST/ASTImporterTest.cpp


Index: clang/unittests/AST/ASTImporterTest.cpp
===
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -2462,6 +2462,36 @@
 functionDecl(hasName("f"), hasDescendant(declRefExpr()));
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase,
+   ImportAnnonymousUnionInClassTest) {
+  const char *Code =
+  R"(
+  class B{
+
+  public:
+
+B(){
+  c=1;
+}
+
+void foo1(){}
+
+  private:
+union{
+  int a;
+  int b;
+};
+union {
+  int c;
+  int d;
+};
+  };
+  )";
+  Decl *FromTU = getTuDecl(Code, Lang_CXX11);
+  EXPECT_TRUE(FromTU);
+}
+
+
 struct ImportFunctionTemplates : ASTImporterOptionSpecificTestBase {};
 
 TEST_P(ImportFunctionTemplates, ImportFunctionTemplateInRecordDeclTwice) {
Index: clang/lib/AST/ASTImporter.cpp
===
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -3861,7 +3861,9 @@
   ASTImporter::getFieldIndex(D) !=
   ASTImporter::getFieldIndex(FoundField))
 continue;
-
+  if (D->isAnonymousStructOrUnion() && 
FoundField->isAnonymousStructOrUnion()) {
+continue;
+  }
   if (Importer.IsStructurallyEquivalent(D->getType(),
 FoundField->getType())) {
 Importer.MapImported(D, FoundField);


Index: clang/unittests/AST/ASTImporterTest.cpp
===
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -2462,6 +2462,36 @@
 functionDecl(hasName("f"), hasDescendant(declRefExpr()));
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase,
+   ImportAnnonymousUnionInClassTest) {
+  const char *Code =
+  R"(
+  class B{
+
+  public:
+
+B(){
+  c=1;
+}
+
+void foo1(){}
+
+  private:
+union{
+  int a;
+  int b;
+};
+union {
+  int c;
+  int d;
+};
+  };
+  )";
+  Decl *FromTU = getTuDecl(Code, Lang_CXX11);
+  EXPECT_TRUE(FromTU);
+}
+
+
 struct ImportFunctionTemplates : ASTImporterOptionSpecificTestBase {};
 
 TEST_P(ImportFunctionTemplates, ImportFunctionTemplateInRecordDeclTwice) {
Index: clang/lib/AST/ASTImporter.cpp
===
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -3861,7 +3861,9 @@
   ASTImporter::getFieldIndex(D) !=
   ASTImporter::getFieldIndex(FoundField))
 continue;
-
+  if (D->isAnonymousStructOrUnion() && FoundField->isAnonymousStructOrUnion()) {
+continue;
+  }
   if (Importer.IsStructurallyEquivalent(D->getType(),
 FoundField->getType())) {
 Importer.MapImported(D, FoundField);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits