"union" filtering rule should recurse into nested structs.

This CL opportunistically uses the |typeWithEmbeddedFieldDecl| matcher
introduced in a previous CL (in https://crrev.com/c/2492464) to fix the
"union" filtering rule, so that it not only covers pointers stored
directly as union fields, but also covers pointers stored in structs
that are nested as a union field.  This is motivated by the following
examples:
- flags_ui::FeatureEntry::(anonymous union)::(anonymous struct)::feature
- ui::NativeTheme::MenuSeparatorExtraParams::paint_rect
  (MenuSeparatorExtraParams struct is embedded as a field of ExtraParams
  union).
(the two examples above are currently excluded via
manual-fields-to-ignore.txt)

Bug: 1069567
Change-Id: I05fd59d0c93b7954321b375bce40d5325e3eab7e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2495822
Commit-Queue: Ɓukasz Anforowicz <lukasza@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#820928}
diff --git a/tools/clang/rewrite_raw_ptr_fields/RewriteRawPtrFields.cpp b/tools/clang/rewrite_raw_ptr_fields/RewriteRawPtrFields.cpp
index dbef1f8..f18c929 100644
--- a/tools/clang/rewrite_raw_ptr_fields/RewriteRawPtrFields.cpp
+++ b/tools/clang/rewrite_raw_ptr_fields/RewriteRawPtrFields.cpp
@@ -1143,9 +1143,13 @@
       field_pointing_to_record_with_deleted_operator_new_matcher,
       &field_pointing_to_record_with_deleted_operator_new_writer);
 
-  // Matches fields in unions - see the testcases in tests/gen-unions-test.cc.
-  auto union_field_decl_matcher = fieldDecl(
-      allOf(field_decl_matcher, hasParent(decl(recordDecl(isUnion())))));
+  // Matches fields in unions (both directly rewritable fields as well as union
+  // fields that embed a struct that contains a rewritable field).  See also the
+  // testcases in tests/gen-unions-test.cc.
+  auto union_field_decl_matcher = recordDecl(allOf(
+      isUnion(), forEach(fieldDecl(anyOf(field_decl_matcher,
+                                         hasType(typeWithEmbeddedFieldDecl(
+                                             field_decl_matcher)))))));
   FilteredExprWriter union_field_decl_writer(&output_helper, "union");
   match_finder.addMatcher(union_field_decl_matcher, &union_field_decl_writer);
 
diff --git a/tools/clang/rewrite_raw_ptr_fields/tests/gen-unions-expected.txt b/tools/clang/rewrite_raw_ptr_fields/tests/gen-unions-expected.txt
index 063b1e1a..c9c54a5 100644
--- a/tools/clang/rewrite_raw_ptr_fields/tests/gen-unions-expected.txt
+++ b/tools/clang/rewrite_raw_ptr_fields/tests/gen-unions-expected.txt
@@ -2,6 +2,7 @@
 include-user-header:::/usr/local/google/home/lukasza/src/chromium4/src/tools/clang/rewrite_raw_ptr_fields/tests/gen-unions-actual.cc:::-1:::-1:::base/memory/checked_ptr.h
 r:::/usr/local/google/home/lukasza/src/chromium4/src/tools/clang/rewrite_raw_ptr_fields/tests/gen-unions-actual.cc:::1044:::11:::CheckedPtr<SomeClass> 
 r:::/usr/local/google/home/lukasza/src/chromium4/src/tools/clang/rewrite_raw_ptr_fields/tests/gen-unions-actual.cc:::1073:::11:::CheckedPtr<SomeClass> 
+r:::/usr/local/google/home/lukasza/src/chromium4/src/tools/clang/rewrite_raw_ptr_fields/tests/gen-unions-actual.cc:::1131:::11:::CheckedPtr<SomeClass> 
 r:::/usr/local/google/home/lukasza/src/chromium4/src/tools/clang/rewrite_raw_ptr_fields/tests/gen-unions-actual.cc:::810:::11:::CheckedPtr<SomeClass> 
 r:::/usr/local/google/home/lukasza/src/chromium4/src/tools/clang/rewrite_raw_ptr_fields/tests/gen-unions-actual.cc:::854:::11:::CheckedPtr<SomeClass> 
 r:::/usr/local/google/home/lukasza/src/chromium4/src/tools/clang/rewrite_raw_ptr_fields/tests/gen-unions-actual.cc:::899:::11:::CheckedPtr<SomeClass> 
@@ -9,6 +10,7 @@
 r:::/usr/local/google/home/lukasza/src/chromium4/src/tools/clang/rewrite_raw_ptr_fields/tests/gen-unions-actual.cc:::973:::11:::CheckedPtr<SomeClass> 
 ==== END EDITS ====
 ==== BEGIN FIELD FILTERS ====
+my_namespace::MyNestedStruct::ptr_field  # union
 my_namespace::MyUnion1::char_ptr  # const-char, union
 my_namespace::MyUnion1::some_class_ptr  # union
 my_namespace::MyUnion2::some_class_ptr  # union
diff --git a/tools/clang/rewrite_raw_ptr_fields/tests/gen-unions-test.cc b/tools/clang/rewrite_raw_ptr_fields/tests/gen-unions-test.cc
index 05c133a..65025bd 100644
--- a/tools/clang/rewrite_raw_ptr_fields/tests/gen-unions-test.cc
+++ b/tools/clang/rewrite_raw_ptr_fields/tests/gen-unions-test.cc
@@ -41,4 +41,13 @@
   SomeClass* some_class_ptr2;
 };
 
+struct MyNestedStruct {
+  SomeClass* ptr_field;
+};
+
+union MyUnion4 {
+  MyNestedStruct nested_struct;
+  uintptr_t uintptr;
+};
+
 }  // namespace my_namespace