[PATCH] D131685: [clang][AST] RecursiveASTVisitor should visit owned TagDecl of friend type.

Balázs Kéri via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 23 00:16:47 PDT 2022


This revision was automatically updated to reflect the committed changes.
Closed by commit rG23fbfb3f725b: [clang][AST] RecursiveASTVisitor should visit owned TagDecl of friend type. (authored by balazske).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D131685

Files:
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/unittests/AST/ASTContextParentMapTest.cpp


Index: clang/unittests/AST/ASTContextParentMapTest.cpp
===================================================================
--- clang/unittests/AST/ASTContextParentMapTest.cpp
+++ clang/unittests/AST/ASTContextParentMapTest.cpp
@@ -119,5 +119,34 @@
       Lang_CXX11));
 }
 
+TEST(GetParents, FriendTypeLoc) {
+  auto AST = tooling::buildASTFromCode("struct A { friend struct Fr; };"
+                                       "struct B { friend struct Fr; };"
+                                       "struct Fr;");
+  auto &Ctx = AST->getASTContext();
+  auto &TU = *Ctx.getTranslationUnitDecl();
+  auto &A = *TU.lookup(&Ctx.Idents.get("A")).front();
+  auto &B = *TU.lookup(&Ctx.Idents.get("B")).front();
+  auto &FrA = *cast<FriendDecl>(*++(cast<CXXRecordDecl>(A).decls_begin()));
+  auto &FrB = *cast<FriendDecl>(*++(cast<CXXRecordDecl>(B).decls_begin()));
+  TypeLoc FrALoc = FrA.getFriendType()->getTypeLoc();
+  TypeLoc FrBLoc = FrB.getFriendType()->getTypeLoc();
+  TagDecl *FrATagDecl =
+      FrALoc.getTypePtr()->getAs<ElaboratedType>()->getOwnedTagDecl();
+  TagDecl *FrBTagDecl =
+      FrBLoc.getTypePtr()->getAs<ElaboratedType>()->getOwnedTagDecl();
+
+  EXPECT_THAT(Ctx.getParents(A), ElementsAre(DynTypedNode::create(TU)));
+  EXPECT_THAT(Ctx.getParents(B), ElementsAre(DynTypedNode::create(TU)));
+  EXPECT_THAT(Ctx.getParents(FrA), ElementsAre(DynTypedNode::create(A)));
+  EXPECT_THAT(Ctx.getParents(FrB), ElementsAre(DynTypedNode::create(B)));
+  EXPECT_THAT(Ctx.getParents(FrALoc), ElementsAre(DynTypedNode::create(FrA)));
+  EXPECT_THAT(Ctx.getParents(FrBLoc), ElementsAre(DynTypedNode::create(FrB)));
+  EXPECT_TRUE(FrATagDecl);
+  EXPECT_FALSE(FrBTagDecl);
+  EXPECT_THAT(Ctx.getParents(*FrATagDecl),
+              ElementsAre(DynTypedNode::create(FrA)));
+}
+
 } // end namespace ast_matchers
 } // end namespace clang
Index: clang/include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- clang/include/clang/AST/RecursiveASTVisitor.h
+++ clang/include/clang/AST/RecursiveASTVisitor.h
@@ -1549,10 +1549,15 @@
 
 DEF_TRAVERSE_DECL(FriendDecl, {
   // Friend is either decl or a type.
-  if (D->getFriendType())
+  if (D->getFriendType()) {
     TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
-  else
+    // Traverse any CXXRecordDecl owned by this type, since
+    // it will not be in the parent context:
+    if (auto *ET = D->getFriendType()->getType()->getAs<ElaboratedType>())
+      TRY_TO(TraverseDecl(ET->getOwnedTagDecl()));
+  } else {
     TRY_TO(TraverseDecl(D->getFriendDecl()));
+  }
 })
 
 DEF_TRAVERSE_DECL(FriendTemplateDecl, {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D131685.454714.patch
Type: text/x-patch
Size: 2636 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220823/26d211b6/attachment.bin>


More information about the cfe-commits mailing list