blob: d81526f9c9738696ee4e8e65d3feff956f0df39a [file] [log] [blame]
Marcel Hlopkoe8f1c4e2021-07-28 18:12:49 +00001// Part of the Crubit project, under the Apache License v2.0 with LLVM
2// Exceptions. See /LICENSE for license information.
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
Googler870b38e2021-12-01 15:54:08 +00005#include <optional>
Marcel Hlopkoe8f1c4e2021-07-28 18:12:49 +00006#include <string>
Marcel Hlopko20f4ce42021-11-02 08:20:00 +00007#include <type_traits>
8#include <variant>
Marcel Hlopkoe8f1c4e2021-07-28 18:12:49 +00009#include <vector>
10
Marcel Hlopko7aa38a72021-11-11 07:39:51 +000011#include "rs_bindings_from_cc/bazel_types.h"
Marcel Hlopko7d739792021-08-12 07:52:47 +000012#include "rs_bindings_from_cc/ir.h"
Googler741ed9c2021-10-01 08:00:49 +000013#include "rs_bindings_from_cc/ir_from_cc.h"
Marcel Hlopko7d739792021-08-12 07:52:47 +000014#include "testing/base/public/gmock.h"
Marcel Hlopkoe8f1c4e2021-07-28 18:12:49 +000015#include "testing/base/public/gunit.h"
Marcel Hlopko20f4ce42021-11-02 08:20:00 +000016#include "third_party/absl/status/status.h"
17#include "third_party/absl/status/statusor.h"
Marcel Hlopkoe8f1c4e2021-07-28 18:12:49 +000018#include "third_party/absl/strings/string_view.h"
Marcel Hlopkof1123c82021-08-19 11:38:52 +000019#include "third_party/absl/types/span.h"
Marcel Hlopko20f4ce42021-11-02 08:20:00 +000020#include "util/task/status_macros.h"
Marcel Hlopkoe8f1c4e2021-07-28 18:12:49 +000021
22namespace rs_bindings_from_cc {
23namespace {
24
Googler5bb23512021-09-17 12:13:27 +000025using ::testing::AllOf;
Devin Jeanpierrebe2f33b2021-10-21 12:54:19 +000026using ::testing::AnyOf;
Michael Forster523dbd42021-10-12 11:05:44 +000027using ::testing::Each;
Googler5bb23512021-09-17 12:13:27 +000028using ::testing::ElementsAre;
Marcel Hlopko7d739792021-08-12 07:52:47 +000029using ::testing::IsEmpty;
Googler5bb23512021-09-17 12:13:27 +000030using ::testing::Not;
Michael Forster523dbd42021-10-12 11:05:44 +000031using ::testing::Pointee;
Googler5bb23512021-09-17 12:13:27 +000032using ::testing::Property;
Marcel Hlopko7d739792021-08-12 07:52:47 +000033using ::testing::SizeIs;
Michael Forster7ef80732021-10-01 18:12:19 +000034using ::testing::VariantWith;
Michael Forster3f323be2021-10-11 07:13:28 +000035using ::testing::status::StatusIs;
Marcel Hlopkoe8f1c4e2021-07-28 18:12:49 +000036
Devin Jeanpierref2ec8712021-10-13 20:47:16 +000037template <typename T>
38UnqualifiedIdentifier GetName(const T& x) {
39 return x.identifier;
40}
41UnqualifiedIdentifier GetName(const Func& x) { return x.name; }
42
Googler870b38e2021-12-01 15:54:08 +000043std::optional<DeclId> DeclIdForRecord(const IR& ir, absl::string_view ident) {
44 for (const Record* record : ir.get_items_if<Record>()) {
45 if (record->identifier.Ident() == ident) {
46 return record->decl_id;
47 }
48 }
49 return std::nullopt;
50}
51
Googler5bb23512021-09-17 12:13:27 +000052// Matches an IR node that has the given identifier.
53MATCHER_P(IdentifierIs, identifier, "") {
Devin Jeanpierref2ec8712021-10-13 20:47:16 +000054 UnqualifiedIdentifier name = GetName(arg);
55 const Identifier* actual = std::get_if<Identifier>(&name);
56 if (actual == nullptr) {
57 *result_listener << "actual name not an identifier.";
58 return false;
59 }
60 if (actual->Ident() == identifier) return true;
Googler5bb23512021-09-17 12:13:27 +000061
Devin Jeanpierref2ec8712021-10-13 20:47:16 +000062 *result_listener << "actual identifier: '" << actual->Ident() << "'";
Googler5bb23512021-09-17 12:13:27 +000063 return false;
64}
65
Michael Forster028800b2021-10-05 12:39:59 +000066// Matches an IR node that has the given doc comment.
67MATCHER_P(DocCommentIs, doc_comment, "") {
68 if (arg.doc_comment && *arg.doc_comment == doc_comment) return true;
69
70 *result_listener << "actual doc comment: '"
71 << (arg.doc_comment ? *arg.doc_comment : "<none>") << "'";
72 return false;
73}
74
Googler5bb23512021-09-17 12:13:27 +000075// Matches a Func that has the given mangled name.
76MATCHER_P(MangledNameIs, mangled_name, "") {
77 if (arg.mangled_name == mangled_name) return true;
78
79 *result_listener << "actual mangled name: '" << arg.mangled_name << "'";
80 return false;
81}
82
83// Matches a Func that has a return type matching `matcher`.
84template <typename Matcher>
85auto ReturnType(const Matcher& matcher) {
Devin Jeanpierre64ca9f62021-09-30 07:10:02 +000086 return testing::Field("return_type", &Func::return_type, matcher);
Googler5bb23512021-09-17 12:13:27 +000087}
88
89// Matches a Func that has parameters matching `matchers`.
90template <typename... Args>
91auto ParamsAre(const Args&... matchers) {
Devin Jeanpierre64ca9f62021-09-30 07:10:02 +000092 return testing::Field("params", &Func::params, ElementsAre(matchers...));
Googler5bb23512021-09-17 12:13:27 +000093}
94
95// Matches a Func that is inline.
96MATCHER(IsInline, "") { return arg.is_inline; }
97
Googlerf09ef0e2021-09-17 12:13:45 +000098// Matches a FuncParam with a type that matches all given matchers.
99template <typename... Args>
100auto ParamType(const Args&... matchers) {
Devin Jeanpierre64ca9f62021-09-30 07:10:02 +0000101 return testing::Field("type", &FuncParam::type, AllOf(matchers...));
Googlerf09ef0e2021-09-17 12:13:45 +0000102}
103
Googler870b38e2021-12-01 15:54:08 +0000104// Matches an RsType or CcType that has the given name.
Devin Jeanpierre09c6f452021-09-29 07:34:24 +0000105MATCHER_P(NameIs, name, "") {
106 if (arg.name == name) return true;
Googlerf09ef0e2021-09-17 12:13:45 +0000107
Devin Jeanpierre09c6f452021-09-29 07:34:24 +0000108 *result_listener << "actual name: '" << arg.name << "'";
Googlerf09ef0e2021-09-17 12:13:45 +0000109 return false;
110}
111
Googler870b38e2021-12-01 15:54:08 +0000112// Matches an RsType or CcType that has the given decl_id.
113MATCHER_P(DeclIdIs, decl_id, "") {
114 if (arg.decl_id.has_value() && *arg.decl_id == decl_id) return true;
115
116 *result_listener << "actual decl_id: ";
117 if (arg.decl_id.has_value()) {
118 *result_listener << *arg.decl_id;
119 } else {
120 *result_listener << "std::nullopt";
121 }
122 return false;
123}
124
125// Matches an RsType or CcType that is const .
126MATCHER(IsConst, "") { return arg.is_const; }
127
Devin Jeanpierre09c6f452021-09-29 07:34:24 +0000128// Matches a MappedType with a CcType that matches all given matchers.
Googlerf09ef0e2021-09-17 12:13:45 +0000129template <typename... Args>
Devin Jeanpierre09c6f452021-09-29 07:34:24 +0000130auto CcTypeIs(const Args&... matchers) {
Devin Jeanpierre64ca9f62021-09-30 07:10:02 +0000131 return testing::Field("cc_type", &MappedType::cc_type, AllOf(matchers...));
Googlerf09ef0e2021-09-17 12:13:45 +0000132}
133
Devin Jeanpierre09c6f452021-09-29 07:34:24 +0000134// Matches a MappedType with a RsType that matches all given matchers.
135template <typename... Args>
136auto RsTypeIs(const Args&... matchers) {
Devin Jeanpierre64ca9f62021-09-30 07:10:02 +0000137 return testing::Field("rs_type", &MappedType::rs_type, AllOf(matchers...));
Devin Jeanpierre09c6f452021-09-29 07:34:24 +0000138}
139
Devin Jeanpierrecb0277b2021-09-29 07:44:29 +0000140// Matches an RsType that has type parameters matching `matchers`.
Devin Jeanpierre09c6f452021-09-29 07:34:24 +0000141template <typename... Args>
142auto RsTypeParamsAre(const Args&... matchers) {
Devin Jeanpierre64ca9f62021-09-30 07:10:02 +0000143 return testing::Field("type_params", &RsType::type_params,
144 ElementsAre(matchers...));
Devin Jeanpierre09c6f452021-09-29 07:34:24 +0000145}
146
Devin Jeanpierrecb0277b2021-09-29 07:44:29 +0000147// Matches a CcType that has type parameters matching `matchers`.
Devin Jeanpierre09c6f452021-09-29 07:34:24 +0000148template <typename... Args>
149auto CcTypeParamsAre(const Args&... matchers) {
Devin Jeanpierre64ca9f62021-09-30 07:10:02 +0000150 return testing::Field("type_params", &CcType::type_params,
151 ElementsAre(matchers...));
Devin Jeanpierre09c6f452021-09-29 07:34:24 +0000152}
153
154auto IsCcInt() { return AllOf(NameIs("int"), CcTypeParamsAre()); }
155
156auto IsRsInt() { return AllOf(NameIs("i32"), RsTypeParamsAre()); }
157
158// Matches a CcType that is a pointer to a type matching `matcher`.
159template <typename Matcher>
160auto CcPointsTo(const Matcher& matcher) {
161 return AllOf(NameIs("*"), CcTypeParamsAre(matcher));
162}
163
Googler870b38e2021-12-01 15:54:08 +0000164// Matches an RsType that is a mutable pointer to a type matching `matcher`.
Devin Jeanpierre09c6f452021-09-29 07:34:24 +0000165template <typename Matcher>
166auto RsPointsTo(const Matcher& matcher) {
167 return AllOf(NameIs("*mut"), RsTypeParamsAre(matcher));
168}
169
Googler870b38e2021-12-01 15:54:08 +0000170// Matches an RsType that is a const pointer to a type matching `matcher`.
171template <typename Matcher>
172auto RsConstPointsTo(const Matcher& matcher) {
173 return AllOf(NameIs("*const"), RsTypeParamsAre(matcher));
174}
175
Devin Jeanpierre09c6f452021-09-29 07:34:24 +0000176// Matches a MappedType that is void.
Googler5bb23512021-09-17 12:13:27 +0000177MATCHER(IsVoid, "") { return arg.IsVoid(); }
178
Devin Jeanpierre09c6f452021-09-29 07:34:24 +0000179// Matches a MappedType that is an integer.
180auto IsInt() { return AllOf(CcTypeIs(IsCcInt()), RsTypeIs(IsRsInt())); }
181
182// Matches a MappedType that is a pointer to integer.
183auto IsIntPtr() {
184 return AllOf(CcTypeIs(CcPointsTo(IsCcInt())),
185 RsTypeIs(RsPointsTo(IsRsInt())));
Googlerf09ef0e2021-09-17 12:13:45 +0000186}
187
Devin Jeanpierre09c6f452021-09-29 07:34:24 +0000188// Matches a MappedType for cc and rs types with no type parameters.
189auto IsSimpleType(absl::string_view rs_name, absl::string_view cc_name) {
190 return AllOf(CcTypeIs(NameIs(cc_name), CcTypeParamsAre()),
191 RsTypeIs(NameIs(rs_name), RsTypeParamsAre()));
Googlerf09ef0e2021-09-17 12:13:45 +0000192}
193
Googler5bb23512021-09-17 12:13:27 +0000194// Matches a Record that has fields matching `matchers`.
195template <typename... Args>
196auto FieldsAre(const Args&... matchers) {
Devin Jeanpierre64ca9f62021-09-30 07:10:02 +0000197 return testing::Field("fields", &Record::fields, ElementsAre(matchers...));
Googler5bb23512021-09-17 12:13:27 +0000198}
199
Googler6986c072021-09-17 13:54:56 +0000200// Matches a Record that has the given size.
201MATCHER_P(RecordSizeIs, size, "") {
202 if (arg.size == size) return true;
203
204 *result_listener << "actual size: " << arg.size;
205 return false;
206}
207
208// Matches a Record that has the given alignment.
209MATCHER_P(AlignmentIs, alignment, "") {
210 if (arg.alignment == alignment) return true;
211
212 *result_listener << "actual alignment: " << arg.alignment;
213 return false;
214}
215
Devin Jeanpierre07931272021-10-05 11:40:13 +0000216// Matches a Record with a copy_constructor that matches all given matchers.
217template <typename... Args>
218auto CopyConstructor(const Args&... matchers) {
219 return testing::Field("copy_constructor", &Record::copy_constructor,
220 AllOf(matchers...));
221}
222
223// Matches a Record with a move_constructor that matches all given matchers.
224template <typename... Args>
225auto MoveConstructor(const Args&... matchers) {
226 return testing::Field("move_constructor", &Record::move_constructor,
227 AllOf(matchers...));
228}
229
Devin Jeanpierree78b2fb2021-10-05 11:40:33 +0000230// Matches a Record with a destructor that matches all given matchers.
231template <typename... Args>
232auto Destructor(const Args&... matchers) {
233 return testing::Field("destructor", &Record::destructor, AllOf(matchers...));
234}
235
Devin Jeanpierrea4896de2021-10-05 13:57:23 +0000236// Matches a Record which is trivial for calls.
237MATCHER(IsTrivialAbi, "") { return arg.is_trivial_abi; }
238
Devin Jeanpierre07931272021-10-05 11:40:13 +0000239// Matches a SpecialMemberFunc that has the given definition.
240MATCHER_P(DefinitionIs, definition, "") { return arg.definition == definition; }
241
Googler5bb23512021-09-17 12:13:27 +0000242// Matches a Field that has the given access specifier.
243MATCHER_P(AccessIs, access, "") { return arg.access == access; }
244
Googler6986c072021-09-17 13:54:56 +0000245// Matches a Field that has the given offset.
246MATCHER_P(OffsetIs, offset, "") {
247 if (arg.offset == offset) return true;
248
249 *result_listener << "actual offset: " << arg.offset;
250 return false;
251}
252
Googlerf09ef0e2021-09-17 12:13:45 +0000253// Matches a Field with a type that matches all given matchers.
254template <typename... Args>
255auto FieldType(const Args&... matchers) {
Devin Jeanpierre64ca9f62021-09-30 07:10:02 +0000256 return testing::Field("type", &Field::type, AllOf(matchers...));
Googlerf09ef0e2021-09-17 12:13:45 +0000257}
258
Googler52c709b2021-09-16 07:58:29 +0000259TEST(AstVisitorTest, Noop) {
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000260 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc("// nothing interesting there."));
Michael Forster3f323be2021-10-11 07:13:28 +0000261
Michael Forster7ef80732021-10-01 18:12:19 +0000262 EXPECT_THAT(ir.items, IsEmpty());
Marcel Hlopko7d739792021-08-12 07:52:47 +0000263}
264
Michael Forster3f323be2021-10-11 07:13:28 +0000265TEST(AstVisitorTest, ErrorOnInvalidInput) {
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000266 ASSERT_THAT(IrFromCc("int foo(); But this is not C++"),
Michael Forster3f323be2021-10-11 07:13:28 +0000267 StatusIs(absl::StatusCode::kInvalidArgument));
Marcel Hlopko19f2ebf2021-08-18 09:35:05 +0000268}
269
Googler76b2cad2021-09-16 08:05:11 +0000270TEST(AstVisitorTest, FuncWithVoidReturnType) {
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000271 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc("void Foo();"));
Michael Forster7ef80732021-10-01 18:12:19 +0000272 EXPECT_THAT(ir.items, ElementsAre(VariantWith<Func>(
273 AllOf(IdentifierIs("Foo"), MangledNameIs("_Z3Foov"),
274 ReturnType(IsVoid()), ParamsAre()))));
Marcel Hlopko7d739792021-08-12 07:52:47 +0000275}
276
Googler76b2cad2021-09-16 08:05:11 +0000277TEST(AstVisitorTest, TwoFuncs) {
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000278 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc("void Foo(); void Bar();"));
Michael Forster7ef80732021-10-01 18:12:19 +0000279 EXPECT_THAT(
280 ir.items,
281 ElementsAre(
282 VariantWith<Func>(AllOf(IdentifierIs("Foo"), MangledNameIs("_Z3Foov"),
283 ReturnType(IsVoid()), ParamsAre())),
284 VariantWith<Func>(AllOf(IdentifierIs("Bar"), MangledNameIs("_Z3Barv"),
285 ReturnType(IsVoid()), ParamsAre()))));
Marcel Hlopko7d739792021-08-12 07:52:47 +0000286}
287
Googler76b2cad2021-09-16 08:05:11 +0000288TEST(AstVisitorTest, TwoFuncsFromTwoHeaders) {
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000289 ASSERT_OK_AND_ASSIGN(
290 IR ir, IrFromCc("", Label{"//two_funcs:one_target"},
291 {HeaderName("test/testing_header_0.h"),
292 HeaderName("test/testing_header_1.h")},
293 {{HeaderName("test/testing_header_0.h"), "void Foo();"},
294 {HeaderName("test/testing_header_1.h"), "void Bar();"}},
295 {
296 {HeaderName("test/testing_header_0.h"),
297 Label{"//two_funcs:one_target"}},
298 {HeaderName("test/testing_header_1.h"),
299 Label{"//two_funcs:one_target"}},
300 }));
Michael Forster7ef80732021-10-01 18:12:19 +0000301 EXPECT_THAT(ir.items, ElementsAre(VariantWith<Func>(IdentifierIs("Foo")),
302 VariantWith<Func>(IdentifierIs("Bar"))));
Marcel Hlopkof1123c82021-08-19 11:38:52 +0000303}
304
Googler76b2cad2021-09-16 08:05:11 +0000305TEST(AstVisitorTest, NonInlineFunc) {
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000306 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc("void Foo() {}"));
Michael Forster7ef80732021-10-01 18:12:19 +0000307 EXPECT_THAT(ir.items, ElementsAre(VariantWith<Func>(
308 AllOf(IdentifierIs("Foo"), Not(IsInline())))));
Marcel Hlopko3164eee2021-08-24 20:09:22 +0000309}
310
Googler76b2cad2021-09-16 08:05:11 +0000311TEST(AstVisitorTest, InlineFunc) {
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000312 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc("inline void Foo() {}"));
Michael Forster7ef80732021-10-01 18:12:19 +0000313 EXPECT_THAT(
314 ir.items,
315 ElementsAre(VariantWith<Func>(AllOf(IdentifierIs("Foo"), IsInline()))));
Marcel Hlopko3164eee2021-08-24 20:09:22 +0000316}
317
Googler76b2cad2021-09-16 08:05:11 +0000318TEST(AstVisitorTest, FuncJustOnce) {
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000319 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc("void Foo(); void Foo();"));
Michael Forster7ef80732021-10-01 18:12:19 +0000320 EXPECT_THAT(ir.items,
321 ElementsAre(VariantWith<Func>(AllOf(IdentifierIs("Foo")))));
Marcel Hlopko7d739792021-08-12 07:52:47 +0000322}
323
Devin Jeanpierre5c87a722021-09-16 10:35:58 +0000324TEST(AstVisitorTest, TestImportPointerFunc) {
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000325 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc("int* Foo(int* a);"));
Devin Jeanpierre5c87a722021-09-16 10:35:58 +0000326
Michael Forster7ef80732021-10-01 18:12:19 +0000327 EXPECT_THAT(ir.items,
328 ElementsAre(VariantWith<Func>(AllOf(
329 ReturnType(IsIntPtr()), ParamsAre(ParamType(IsIntPtr()))))));
Devin Jeanpierre5c87a722021-09-16 10:35:58 +0000330}
331
Googler870b38e2021-12-01 15:54:08 +0000332TEST(AstVisitorTest, TestImportConstStructPointerFunc) {
333 ASSERT_OK_AND_ASSIGN(IR ir,
334 IrFromCc("struct S{}; const S* Foo(const S* s);"));
335
336 std::optional<DeclId> decl_id = DeclIdForRecord(ir, "S");
337 ASSERT_TRUE(decl_id.has_value());
338
339 auto is_ptr_to_const_s =
340 AllOf(CcTypeIs(CcPointsTo(AllOf(DeclIdIs(*decl_id), IsConst()))),
341 RsTypeIs(RsConstPointsTo(DeclIdIs(*decl_id))));
342
343 EXPECT_THAT(ir.items, Contains(VariantWith<Func>(AllOf(
344 IdentifierIs("Foo"), ReturnType(is_ptr_to_const_s),
345 ParamsAre(ParamType(is_ptr_to_const_s))))));
346}
347
Googler76b2cad2021-09-16 08:05:11 +0000348TEST(AstVisitorTest, Struct) {
Michael Forster3f323be2021-10-11 07:13:28 +0000349 ASSERT_OK_AND_ASSIGN(
350 IR ir,
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000351 IrFromCc("struct SomeStruct { int first_field; int second_field; };"));
Marcel Hlopkob4b28742021-09-15 12:45:20 +0000352
Googler1661eee2021-12-01 12:36:19 +0000353 std::vector<const Record*> records = ir.get_items_if<Record>();
Devin Jeanpierredf4dc8b2021-10-21 12:53:19 +0000354 EXPECT_THAT(records,
355 ElementsAre(Pointee(AllOf(
Googler6986c072021-09-17 13:54:56 +0000356 IdentifierIs("SomeStruct"), RecordSizeIs(8), AlignmentIs(4),
357 FieldsAre(AllOf(IdentifierIs("first_field"),
358 FieldType(IsInt()), OffsetIs(0)),
359 AllOf(IdentifierIs("second_field"),
Michael Forster7ef80732021-10-01 18:12:19 +0000360 FieldType(IsInt()), OffsetIs(32)))))));
Marcel Hlopkob4b28742021-09-15 12:45:20 +0000361}
362
Devin Jeanpierre07931272021-10-05 11:40:13 +0000363TEST(AstVisitorTest, TrivialCopyConstructor) {
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000364 absl::string_view file = R"cc(
365 struct Implicit {};
366 struct Defaulted {
367 Defaulted(const Defaulted&) = default;
368 };
369 )cc";
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000370 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc(file));
Devin Jeanpierre07931272021-10-05 11:40:13 +0000371
Googler1661eee2021-12-01 12:36:19 +0000372 std::vector<const Record*> records = ir.get_items_if<Record>();
Michael Forster523dbd42021-10-12 11:05:44 +0000373 EXPECT_THAT(records, SizeIs(2));
374 EXPECT_THAT(records, Each(Pointee(CopyConstructor(DefinitionIs(
375 SpecialMemberFunc::Definition::kTrivial)))));
Devin Jeanpierre07931272021-10-05 11:40:13 +0000376}
377
Devin Jeanpierrebe2f33b2021-10-21 12:54:19 +0000378TEST(AstVisitorTest, NontrivialSelfCopyConstructor) {
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000379 absl::string_view file = R"cc(
Devin Jeanpierrebe2f33b2021-10-21 12:54:19 +0000380 struct NontrivialSelf {
381 NontrivialSelf(const NontrivialSelf&);
382 };
383 struct NontrivialSub : public NontrivialSelf {};
Devin Jeanpierreb41041d2021-10-27 18:48:22 +0000384
385 // Despite having a defaulted copy constructor, this is not trivially
386 // copyable, because the *first* declaration is not defaulted.
387 struct NontrivialSelfDefaulted {
388 NontrivialSelfDefaulted(const NontrivialSelfDefaulted&);
389 };
390 inline NontrivialSelfDefaulted::NontrivialSelfDefaulted(
391 const NontrivialSelfDefaulted&) = default;
Devin Jeanpierrebe2f33b2021-10-21 12:54:19 +0000392 )cc";
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000393 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc(file));
Devin Jeanpierrebe2f33b2021-10-21 12:54:19 +0000394
Googler1661eee2021-12-01 12:36:19 +0000395 std::vector<const Record*> records = ir.get_items_if<Record>();
Devin Jeanpierreb41041d2021-10-27 18:48:22 +0000396 EXPECT_THAT(records, SizeIs(3));
Devin Jeanpierrebe2f33b2021-10-21 12:54:19 +0000397 EXPECT_THAT(records, Each(Pointee(CopyConstructor(DefinitionIs(
398 SpecialMemberFunc::Definition::kNontrivialSelf)))));
399}
400
401TEST(AstVisitorTest, NontrivialMembersCopyConstructor) {
402 absl::string_view file = R"cc(
403 struct NontrivialSelf {
404 NontrivialSelf(const NontrivialSelf&);
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000405 };
406 struct MemberImplicit {
Devin Jeanpierrebe2f33b2021-10-21 12:54:19 +0000407 NontrivialSelf x;
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000408 };
409 struct MemberDefaulted {
410 MemberDefaulted(const MemberDefaulted&) = default;
Devin Jeanpierrebe2f33b2021-10-21 12:54:19 +0000411 NontrivialSelf x;
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000412 };
Devin Jeanpierrebe2f33b2021-10-21 12:54:19 +0000413 struct Subclass : public MemberImplicit {};
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000414 )cc";
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000415 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc(file));
Googler1661eee2021-12-01 12:36:19 +0000416 std::vector<const Record*> records = ir.get_items_if<Record>();
Devin Jeanpierrebe2f33b2021-10-21 12:54:19 +0000417 EXPECT_THAT(records, SizeIs(4));
418 EXPECT_THAT(records,
419 Each(Pointee(AnyOf(
420 IdentifierIs(
421 "NontrivialSelf"), // needed to create nontrivial members
422 CopyConstructor(DefinitionIs(
423 SpecialMemberFunc::Definition::kNontrivialMembers))))));
Devin Jeanpierre07931272021-10-05 11:40:13 +0000424}
425
426TEST(AstVisitorTest, DeletedCopyConstructor) {
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000427 absl::string_view file = R"cc(
428 struct Deleted {
429 Deleted(const Deleted&) = delete;
430 };
431 struct DeletedByMember {
432 Deleted x;
433 };
434 struct DeletedByCtorDef {
435 DeletedByCtorDef(DeletedByCtorDef&&) {}
436 };
437 )cc";
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000438 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc(file));
Googler1661eee2021-12-01 12:36:19 +0000439 std::vector<const Record*> records = ir.get_items_if<Record>();
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000440 EXPECT_THAT(records, SizeIs(3));
Michael Forster523dbd42021-10-12 11:05:44 +0000441 EXPECT_THAT(records, Each(Pointee(CopyConstructor(DefinitionIs(
442 SpecialMemberFunc::Definition::kDeleted)))));
Devin Jeanpierre07931272021-10-05 11:40:13 +0000443}
444
445TEST(AstVisitorTest, PublicCopyConstructor) {
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000446 absl::string_view file = R"cc(
447 class Implicit {};
448 struct Defaulted {
449 Defaulted(const Defaulted&) = default;
450 };
451 class Section {
452 public:
453 Section(const Section&) = default;
454 };
455 )cc";
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000456 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc(file));
Devin Jeanpierre07931272021-10-05 11:40:13 +0000457
Googler1661eee2021-12-01 12:36:19 +0000458 std::vector<const Record*> records = ir.get_items_if<Record>();
Michael Forster523dbd42021-10-12 11:05:44 +0000459 EXPECT_THAT(records, SizeIs(3));
460 EXPECT_THAT(records, Each(Pointee(CopyConstructor(AccessIs(kPublic)))));
Devin Jeanpierre07931272021-10-05 11:40:13 +0000461}
462
463TEST(AstVisitorTest, PrivateCopyConstructor) {
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000464 absl::string_view file = R"cc(
465 class Defaulted {
466 Defaulted(const Defaulted&) = default;
467 };
468 struct Section {
469 private:
470 Section(const Section&) = default;
471 };
472 )cc";
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000473 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc(file));
Devin Jeanpierre07931272021-10-05 11:40:13 +0000474
Googler1661eee2021-12-01 12:36:19 +0000475 std::vector<const Record*> records = ir.get_items_if<Record>();
Michael Forster523dbd42021-10-12 11:05:44 +0000476 EXPECT_THAT(records, SizeIs(2));
477 EXPECT_THAT(records, Each(Pointee(CopyConstructor(AccessIs(kPrivate)))));
Devin Jeanpierre07931272021-10-05 11:40:13 +0000478}
479
480TEST(AstVisitorTest, TrivialMoveConstructor) {
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000481 absl::string_view file = R"cc(
482 struct Implicit {};
483 struct Defaulted {
484 Defaulted(Defaulted&&) = default;
485 };
486 )cc";
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000487 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc(file));
Devin Jeanpierre07931272021-10-05 11:40:13 +0000488
Googler1661eee2021-12-01 12:36:19 +0000489 std::vector<const Record*> records = ir.get_items_if<Record>();
Michael Forster523dbd42021-10-12 11:05:44 +0000490 EXPECT_THAT(records, SizeIs(2));
491 EXPECT_THAT(records, Each(Pointee(MoveConstructor(DefinitionIs(
492 SpecialMemberFunc::Definition::kTrivial)))));
Devin Jeanpierre07931272021-10-05 11:40:13 +0000493}
494
Devin Jeanpierrebe2f33b2021-10-21 12:54:19 +0000495TEST(AstVisitorTest, NontrivialSelfMoveConstructor) {
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000496 absl::string_view file = R"cc(
Devin Jeanpierrebe2f33b2021-10-21 12:54:19 +0000497 struct NontrivialSelf {
498 NontrivialSelf(NontrivialSelf&&);
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000499 };
Devin Jeanpierrebe2f33b2021-10-21 12:54:19 +0000500 struct NontrivialSub : public NontrivialSelf {};
Devin Jeanpierreb41041d2021-10-27 18:48:22 +0000501
502 // Despite having a defaulted move constructor, this is not trivially
503 // movable, because the *first* declaration is not defaulted.
504 struct NontrivialSelfDefaulted {
505 NontrivialSelfDefaulted(NontrivialSelfDefaulted&&);
506 };
507 inline NontrivialSelfDefaulted::NontrivialSelfDefaulted(
508 NontrivialSelfDefaulted&&) = default;
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000509 )cc";
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000510 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc(file));
Googler1661eee2021-12-01 12:36:19 +0000511 std::vector<const Record*> records = ir.get_items_if<Record>();
Devin Jeanpierreb41041d2021-10-27 18:48:22 +0000512 EXPECT_THAT(records, SizeIs(3));
Michael Forster523dbd42021-10-12 11:05:44 +0000513 EXPECT_THAT(records, Each(Pointee(MoveConstructor(DefinitionIs(
Devin Jeanpierrebe2f33b2021-10-21 12:54:19 +0000514 SpecialMemberFunc::Definition::kNontrivialSelf)))));
515}
516
517TEST(AstVisitorTest, NontrivialMembersMoveConstructor) {
518 absl::string_view file = R"cc(
519 struct NontrivialSelf {
520 NontrivialSelf(NontrivialSelf&&);
521 };
522 struct MemberImplicit {
523 NontrivialSelf x;
524 };
525 struct MemberDefaulted {
526 MemberDefaulted(MemberDefaulted&&) = default;
527 NontrivialSelf x;
528 };
529 struct Subclass : public MemberImplicit {};
530 )cc";
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000531 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc(file));
Googler1661eee2021-12-01 12:36:19 +0000532 std::vector<const Record*> records = ir.get_items_if<Record>();
Devin Jeanpierrebe2f33b2021-10-21 12:54:19 +0000533 EXPECT_THAT(records, SizeIs(4));
534 EXPECT_THAT(records,
535 Each(Pointee(AnyOf(
536 IdentifierIs(
537 "NontrivialSelf"), // needed to create nontrivial members
538 MoveConstructor(DefinitionIs(
539 SpecialMemberFunc::Definition::kNontrivialMembers))))));
Devin Jeanpierre07931272021-10-05 11:40:13 +0000540}
541
542TEST(AstVisitorTest, DeletedMoveConstructor) {
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000543 absl::string_view file = R"cc(
544 struct Deleted {
545 Deleted(Deleted&&) = delete;
546 };
547 struct DeletedByMember {
548 Deleted x;
549 };
550 struct SuppressedByCtorDef {
551 SuppressedByCtorDef(const SuppressedByCtorDef&) {}
552 };
553 )cc";
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000554 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc(file));
Googler1661eee2021-12-01 12:36:19 +0000555 std::vector<const Record*> records = ir.get_items_if<Record>();
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000556 EXPECT_THAT(records, SizeIs(3));
Michael Forster523dbd42021-10-12 11:05:44 +0000557 EXPECT_THAT(records, Each(Pointee(MoveConstructor(DefinitionIs(
558 SpecialMemberFunc::Definition::kDeleted)))));
Devin Jeanpierre07931272021-10-05 11:40:13 +0000559}
560
561TEST(AstVisitorTest, PublicMoveConstructor) {
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000562 absl::string_view file = R"cc(
563 class Implicit {};
564 struct Defaulted {
565 Defaulted(Defaulted&&) = default;
566 };
567 class Section {
568 public:
569 Section(Section&&) = default;
570 };
571 )cc";
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000572 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc(file));
Devin Jeanpierre07931272021-10-05 11:40:13 +0000573
Googler1661eee2021-12-01 12:36:19 +0000574 std::vector<const Record*> records = ir.get_items_if<Record>();
Michael Forster523dbd42021-10-12 11:05:44 +0000575 EXPECT_THAT(records, SizeIs(3));
576 EXPECT_THAT(records, Each(Pointee(MoveConstructor(AccessIs(kPublic)))));
Devin Jeanpierre07931272021-10-05 11:40:13 +0000577}
578
579TEST(AstVisitorTest, PrivateMoveConstructor) {
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000580 absl::string_view file = R"cc(
581 class Defaulted {
582 Defaulted(Defaulted&&) = default;
583 };
584 struct Section {
585 private:
586 Section(Section&&) = default;
587 };
588 )cc";
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000589 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc(file));
Devin Jeanpierre07931272021-10-05 11:40:13 +0000590
Googler1661eee2021-12-01 12:36:19 +0000591 std::vector<const Record*> records = ir.get_items_if<Record>();
Michael Forster523dbd42021-10-12 11:05:44 +0000592 EXPECT_THAT(records, SizeIs(2));
593 EXPECT_THAT(records, Each(Pointee(MoveConstructor(AccessIs(kPrivate)))));
Devin Jeanpierre07931272021-10-05 11:40:13 +0000594}
595
Devin Jeanpierree78b2fb2021-10-05 11:40:33 +0000596TEST(AstVisitorTest, TrivialDestructor) {
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000597 absl::string_view file = R"cc(
598 struct Implicit {};
599 struct Defaulted {
600 ~Defaulted() = default;
601 };
602 )cc";
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000603 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc(file));
Devin Jeanpierree78b2fb2021-10-05 11:40:33 +0000604
Googler1661eee2021-12-01 12:36:19 +0000605 std::vector<const Record*> records = ir.get_items_if<Record>();
Devin Jeanpierref2ec8712021-10-13 20:47:16 +0000606 EXPECT_THAT(records, SizeIs(2));
607 EXPECT_THAT(records, Each(Pointee(Destructor(DefinitionIs(
608 SpecialMemberFunc::Definition::kTrivial)))));
Devin Jeanpierree78b2fb2021-10-05 11:40:33 +0000609}
610
Devin Jeanpierrebe2f33b2021-10-21 12:54:19 +0000611TEST(AstVisitorTest, NontrivialSelfDestructor) {
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000612 absl::string_view file = R"cc(
Devin Jeanpierrebe2f33b2021-10-21 12:54:19 +0000613 struct NontrivialSelf {
614 ~NontrivialSelf();
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000615 };
Devin Jeanpierrebe2f33b2021-10-21 12:54:19 +0000616 struct NontrivialSub : public NontrivialSelf {};
Devin Jeanpierreb41041d2021-10-27 18:48:22 +0000617
618 // Despite having a defaulted destructor, this is not trivially
619 // destructible, because the *first* declaration is not defaulted.
620 struct NontrivialSelfDefaulted {
621 ~NontrivialSelfDefaulted();
622 };
623 inline NontrivialSelfDefaulted::~NontrivialSelfDefaulted() = default;
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000624 )cc";
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000625 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc(file));
Googler1661eee2021-12-01 12:36:19 +0000626 std::vector<const Record*> records = ir.get_items_if<Record>();
Devin Jeanpierreb41041d2021-10-27 18:48:22 +0000627 EXPECT_THAT(records, SizeIs(3));
Devin Jeanpierref2ec8712021-10-13 20:47:16 +0000628 EXPECT_THAT(records, Each(Pointee(Destructor(DefinitionIs(
Devin Jeanpierrebe2f33b2021-10-21 12:54:19 +0000629 SpecialMemberFunc::Definition::kNontrivialSelf)))));
630}
631
632TEST(AstVisitorTest, NontrivialMembersDestructor) {
633 absl::string_view file = R"cc(
634 struct NontrivialSelf {
635 ~NontrivialSelf();
636 };
637 struct MemberImplicit {
638 NontrivialSelf x;
639 };
640 struct MemberDefaulted {
641 MemberDefaulted(MemberDefaulted&&) = default;
642 NontrivialSelf x;
643 };
644 struct Subclass : public MemberImplicit {};
645 )cc";
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000646 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc(file));
Googler1661eee2021-12-01 12:36:19 +0000647 std::vector<const Record*> records = ir.get_items_if<Record>();
Devin Jeanpierrebe2f33b2021-10-21 12:54:19 +0000648 EXPECT_THAT(records, SizeIs(4));
649 EXPECT_THAT(records,
650 Each(Pointee(AnyOf(
651 IdentifierIs(
652 "NontrivialSelf"), // needed to create nontrivial members
653 Destructor(DefinitionIs(
654 SpecialMemberFunc::Definition::kNontrivialMembers))))));
Devin Jeanpierree78b2fb2021-10-05 11:40:33 +0000655}
656
657TEST(AstVisitorTest, DeletedDestructor) {
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000658 absl::string_view file = R"cc(
659 struct Deleted {
660 ~Deleted() = delete;
661 };
662 struct DeletedByMember {
663 Deleted x;
664 };
665 )cc";
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000666 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc(file));
Devin Jeanpierree78b2fb2021-10-05 11:40:33 +0000667
Googler1661eee2021-12-01 12:36:19 +0000668 std::vector<const Record*> records = ir.get_items_if<Record>();
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000669 EXPECT_THAT(records, SizeIs(2));
Devin Jeanpierref2ec8712021-10-13 20:47:16 +0000670 EXPECT_THAT(records, Each(Pointee(Destructor(DefinitionIs(
671 SpecialMemberFunc::Definition::kDeleted)))));
Devin Jeanpierree78b2fb2021-10-05 11:40:33 +0000672}
673
674TEST(AstVisitorTest, PublicDestructor) {
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000675 absl::string_view file = R"cc(
676 class Implicit {};
677 struct Defaulted {
678 ~Defaulted() = default;
679 };
680 class Section {
681 public:
682 ~Section() = default;
683 };
684 )cc";
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000685 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc(file));
Devin Jeanpierree78b2fb2021-10-05 11:40:33 +0000686
Googler1661eee2021-12-01 12:36:19 +0000687 std::vector<const Record*> records = ir.get_items_if<Record>();
Devin Jeanpierref2ec8712021-10-13 20:47:16 +0000688 EXPECT_THAT(records, SizeIs(3));
689 EXPECT_THAT(records, Each(Pointee(Destructor(AccessIs(kPublic)))));
Devin Jeanpierree78b2fb2021-10-05 11:40:33 +0000690}
691
692TEST(AstVisitorTest, PrivateDestructor) {
Devin Jeanpierrebf0d5602021-10-13 20:47:39 +0000693 absl::string_view file = R"cc(
694 class Defaulted {
695 ~Defaulted() = default;
696 };
697 struct Section {
698 private:
699 ~Section() = default;
700 };
701 )cc";
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000702 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc(file));
Devin Jeanpierree78b2fb2021-10-05 11:40:33 +0000703
Googler1661eee2021-12-01 12:36:19 +0000704 std::vector<const Record*> records = ir.get_items_if<Record>();
Devin Jeanpierref2ec8712021-10-13 20:47:16 +0000705 EXPECT_THAT(records, SizeIs(2));
706 EXPECT_THAT(records, Each(Pointee(Destructor(AccessIs(kPrivate)))));
Devin Jeanpierree78b2fb2021-10-05 11:40:33 +0000707}
708
Devin Jeanpierrea4896de2021-10-05 13:57:23 +0000709TEST(AstVisitorTest, TrivialAbi) {
710 absl::string_view file = R"cc(
711 struct Empty {};
712 struct Defaulted {
713 Defaulted(const Defaulted&) = default;
714 };
715 struct [[clang::trivial_abi]] Nontrivial {
716 Nontrivial(const Nontrivial&) {}
717 };
718 )cc";
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000719 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc(file));
Devin Jeanpierrea4896de2021-10-05 13:57:23 +0000720
Googler1661eee2021-12-01 12:36:19 +0000721 std::vector<const Record*> records = ir.get_items_if<Record>();
Michael Forster523dbd42021-10-12 11:05:44 +0000722 EXPECT_THAT(records, SizeIs(3));
723 EXPECT_THAT(records, Each(Pointee(IsTrivialAbi())));
Devin Jeanpierrea4896de2021-10-05 13:57:23 +0000724}
725
726TEST(AstVisitorTest, NotTrivialAbi) {
727 absl::string_view file = R"cc(
728 struct Nontrivial {
729 Nontrivial(const Nontrivial&) {}
730 };
731 )cc";
Marcel Hlopko7aa38a72021-11-11 07:39:51 +0000732 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc(file));
Devin Jeanpierrea4896de2021-10-05 13:57:23 +0000733
Googler1661eee2021-12-01 12:36:19 +0000734 std::vector<const Record*> records = ir.get_items_if<Record>();
Michael Forster523dbd42021-10-12 11:05:44 +0000735 EXPECT_THAT(records, SizeIs(1));
736 EXPECT_THAT(records, Each(Pointee(Not(IsTrivialAbi()))));
Devin Jeanpierrea4896de2021-10-05 13:57:23 +0000737}
738
Googler2e85f342021-09-17 07:04:07 +0000739TEST(AstVisitorTest, MemberVariableAccessSpecifiers) {
Michael Forster3f323be2021-10-11 07:13:28 +0000740 ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc({R"(
Googler2e85f342021-09-17 07:04:07 +0000741 struct SomeStruct {
742 int default_access_int;
743 public:
744 int public_int;
745 protected:
746 int protected_int;
747 private:
748 int private_int;
749 };
750
751 class SomeClass {
752 int default_access_int;
753 };
Michael Forster3f323be2021-10-11 07:13:28 +0000754 )"}));
Googler2e85f342021-09-17 07:04:07 +0000755
Googler1661eee2021-12-01 12:36:19 +0000756 std::vector<const Record*> records = ir.get_items_if<Record>();
Googler5bb23512021-09-17 12:13:27 +0000757 EXPECT_THAT(
Devin Jeanpierredf4dc8b2021-10-21 12:53:19 +0000758 records,
Googler5bb23512021-09-17 12:13:27 +0000759 ElementsAre(
Devin Jeanpierredf4dc8b2021-10-21 12:53:19 +0000760 Pointee(AllOf(
Googler5bb23512021-09-17 12:13:27 +0000761 IdentifierIs("SomeStruct"),
762 FieldsAre(
763 AllOf(IdentifierIs("default_access_int"), AccessIs(kPublic)),
764 AllOf(IdentifierIs("public_int"), AccessIs(kPublic)),
765 AllOf(IdentifierIs("protected_int"), AccessIs(kProtected)),
Michael Forster7ef80732021-10-01 18:12:19 +0000766 AllOf(IdentifierIs("private_int"), AccessIs(kPrivate))))),
Devin Jeanpierredf4dc8b2021-10-21 12:53:19 +0000767 Pointee(AllOf(IdentifierIs("SomeClass"),
768 FieldsAre(AllOf(IdentifierIs("default_access_int"),
769 AccessIs(kPrivate)))))));
Googler2e85f342021-09-17 07:04:07 +0000770}
771
Marcel Hlopkoe8f1c4e2021-07-28 18:12:49 +0000772} // namespace
773} // namespace rs_bindings_from_cc