importer_test.cc: Add test case for importing forward declarations.

To serve as regression tests for the upcoming CL that touches logic on importing incomplete records.

PiperOrigin-RevId: 580466860
Change-Id: I1d283535228b43cd89fc0edee2d353d1eb4064fc
diff --git a/rs_bindings_from_cc/importer_test.cc b/rs_bindings_from_cc/importer_test.cc
index ddb3601..6c29474 100644
--- a/rs_bindings_from_cc/importer_test.cc
+++ b/rs_bindings_from_cc/importer_test.cc
@@ -54,6 +54,9 @@
       return item;
     } else if (auto* ns = std::get_if<Namespace>(&item); ns && ns->id == id) {
       return item;
+    } else if (auto* incomplete = std::get_if<IncompleteRecord>(&item);
+               incomplete && incomplete->id == id) {
+      return item;
     }
   }
   return std::nullopt;
@@ -793,6 +796,7 @@
 
 TEST(ImporterTest, TopLevelItemIds) {
   absl::string_view file = R"cc(
+    struct ForwardDeclaration;
     struct TopLevelStruct {};
     // Top level comment
 
@@ -815,10 +819,11 @@
     items.push_back(*item);
   }
 
-  EXPECT_THAT(ir.top_level_item_ids, SizeIs(5));
+  EXPECT_THAT(ir.top_level_item_ids, SizeIs(6));
   EXPECT_THAT(
       items,
       ElementsAre(
+          VariantWith<IncompleteRecord>(RsNameIs("ForwardDeclaration")),
           VariantWith<Record>(RsNameIs("TopLevelStruct")),
           VariantWith<Comment>(TextIs("Top level comment")),
           VariantWith<Func>(IdentifierIs("top_level_func")),
@@ -826,6 +831,31 @@
           VariantWith<Comment>(TextIs("namespace top_level_namespace"))));
 }
 
+TEST(ImporterTest, ForwardDeclarationAndDefinition) {
+  absl::string_view file = R"cc(
+    struct ForwardDeclaredStruct;
+    struct ForwardDeclaredStruct {};
+    struct Struct {};
+    struct Struct;
+    struct ForwardDeclaredStructWithNoDefinition;
+  )cc";
+  ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc({file}));
+
+  std::vector<IR::Item> items;
+  for (const auto& id : ir.top_level_item_ids) {
+    auto item = FindItemById(ir, id);
+    std::cout << ItemToString(item) << std::endl;
+    items.push_back(*item);
+  }
+
+  EXPECT_THAT(ir.top_level_item_ids, SizeIs(3));
+  EXPECT_THAT(
+      items, ElementsAre(VariantWith<Record>(RsNameIs("ForwardDeclaredStruct")),
+                         VariantWith<Record>(RsNameIs("Struct")),
+                         VariantWith<IncompleteRecord>(RsNameIs(
+                             "ForwardDeclaredStructWithNoDefinition"))));
+}
+
 TEST(ImporterTest, RecordItemIds) {
   absl::string_view file = R"cc(
     struct TopLevelStruct {
diff --git a/rs_bindings_from_cc/test/golden/BUILD b/rs_bindings_from_cc/test/golden/BUILD
index 12a884b..41ff4c5 100644
--- a/rs_bindings_from_cc/test/golden/BUILD
+++ b/rs_bindings_from_cc/test/golden/BUILD
@@ -38,6 +38,9 @@
         "unsupported",
     ],
     "types": ["//support/rs_std:rs_char"],
+    "definition_of_forward_declaration": [
+        "forward_declaration",
+    ],
 }
 
 TAGS = {}
diff --git a/rs_bindings_from_cc/test/golden/definition_of_forward_declaration.h b/rs_bindings_from_cc/test/golden/definition_of_forward_declaration.h
new file mode 100644
index 0000000..1edab07
--- /dev/null
+++ b/rs_bindings_from_cc/test/golden/definition_of_forward_declaration.h
@@ -0,0 +1,12 @@
+// Part of the Crubit project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#ifndef THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_DEFINITION_OF_FORWARD_DECLARATION_H_
+#define THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_DEFINITION_OF_FORWARD_DECLARATION_H_
+
+#include "rs_bindings_from_cc/test/golden/forward_declaration.h"
+
+struct ForwardDeclaredStruct {};
+
+#endif  // THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_DEFINITION_OF_FORWARD_DECLARATION_H_
diff --git a/rs_bindings_from_cc/test/golden/definition_of_forward_declaration_rs_api.rs b/rs_bindings_from_cc/test/golden/definition_of_forward_declaration_rs_api.rs
new file mode 100644
index 0000000..e1e48d5
--- /dev/null
+++ b/rs_bindings_from_cc/test/golden/definition_of_forward_declaration_rs_api.rs
@@ -0,0 +1,25 @@
+// Part of the Crubit project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+// Automatically @generated Rust bindings for the following C++ target:
+// //rs_bindings_from_cc/test/golden:definition_of_forward_declaration_cc
+// Features: experimental, supported
+
+#![rustfmt::skip]
+#![feature(custom_inner_attributes)]
+#![allow(stable_features)]
+#![no_std]
+#![allow(improper_ctypes)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+#![allow(non_upper_case_globals)]
+#![deny(warnings)]
+
+// Part of the Crubit project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+// THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_DEFINITION_OF_FORWARD_DECLARATION_H_
+
+const _: () = assert!(::core::mem::size_of::<Option<&i32>>() == ::core::mem::size_of::<&i32>());
diff --git a/rs_bindings_from_cc/test/golden/definition_of_forward_declaration_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/definition_of_forward_declaration_rs_api_impl.cc
new file mode 100644
index 0000000..e7c60d8
--- /dev/null
+++ b/rs_bindings_from_cc/test/golden/definition_of_forward_declaration_rs_api_impl.cc
@@ -0,0 +1,22 @@
+// Part of the Crubit project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+// Automatically @generated Rust bindings for the following C++ target:
+// //rs_bindings_from_cc/test/golden:definition_of_forward_declaration_cc
+// Features: experimental, supported
+
+#include "support/internal/cxx20_backports.h"
+#include "support/internal/offsetof.h"
+#include "support/internal/sizeof.h"
+
+#include <cstddef>
+#include <memory>
+
+// Public headers of the C++ library being wrapped.
+#include "rs_bindings_from_cc/test/golden/definition_of_forward_declaration.h"
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wthread-safety-analysis"
+
+#pragma clang diagnostic pop
diff --git a/rs_bindings_from_cc/test/golden/forward_declaration.h b/rs_bindings_from_cc/test/golden/forward_declaration.h
new file mode 100644
index 0000000..1925976
--- /dev/null
+++ b/rs_bindings_from_cc/test/golden/forward_declaration.h
@@ -0,0 +1,10 @@
+// Part of the Crubit project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#ifndef THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_FORWARD_DECLARATION_H_
+#define THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_FORWARD_DECLARATION_H_
+
+struct ForwardDeclaredStruct;
+
+#endif  // THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_FORWARD_DECLARATION_H_
diff --git a/rs_bindings_from_cc/test/golden/forward_declaration_rs_api.rs b/rs_bindings_from_cc/test/golden/forward_declaration_rs_api.rs
new file mode 100644
index 0000000..da3b7ff
--- /dev/null
+++ b/rs_bindings_from_cc/test/golden/forward_declaration_rs_api.rs
@@ -0,0 +1,27 @@
+// Part of the Crubit project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+// Automatically @generated Rust bindings for the following C++ target:
+// //rs_bindings_from_cc/test/golden:forward_declaration_cc
+// Features: experimental, supported
+
+#![rustfmt::skip]
+#![feature(custom_inner_attributes)]
+#![allow(stable_features)]
+#![no_std]
+#![allow(improper_ctypes)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+#![allow(non_upper_case_globals)]
+#![deny(warnings)]
+
+// Part of the Crubit project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+forward_declare::forward_declare!(pub ForwardDeclaredStruct = forward_declare::symbol!("ForwardDeclaredStruct"));
+
+// THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_FORWARD_DECLARATION_H_
+
+const _: () = assert!(::core::mem::size_of::<Option<&i32>>() == ::core::mem::size_of::<&i32>());
diff --git a/rs_bindings_from_cc/test/golden/forward_declaration_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/forward_declaration_rs_api_impl.cc
new file mode 100644
index 0000000..a6f67d6
--- /dev/null
+++ b/rs_bindings_from_cc/test/golden/forward_declaration_rs_api_impl.cc
@@ -0,0 +1,20 @@
+// Part of the Crubit project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+// Automatically @generated Rust bindings for the following C++ target:
+// //rs_bindings_from_cc/test/golden:forward_declaration_cc
+// Features: experimental, supported
+
+#include "support/internal/cxx20_backports.h"
+#include "support/internal/offsetof.h"
+
+#include <memory>
+
+// Public headers of the C++ library being wrapped.
+#include "rs_bindings_from_cc/test/golden/forward_declaration.h"
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wthread-safety-analysis"
+
+#pragma clang diagnostic pop