Add the namespace hierarchy to BindingsAndMetadata
This cl also adds a --namespaces_json flag to Crubit for writing a .json file with the namespace contents. Bazel support for it will be provided in a followup cl.
PiperOrigin-RevId: 471791828
diff --git a/rs_bindings_from_cc/BUILD b/rs_bindings_from_cc/BUILD
index 5fb2839..8a3110f 100644
--- a/rs_bindings_from_cc/BUILD
+++ b/rs_bindings_from_cc/BUILD
@@ -67,6 +67,7 @@
":bazel_types",
":cc_ir",
":cmdline",
+ ":collect_namespaces",
":generate_bindings_and_metadata",
"//common:file_io",
"//common:rust_allocator_shims",
@@ -88,6 +89,7 @@
":cc_collect_instantiations",
":cc_ir",
":cmdline",
+ ":collect_namespaces",
":ir_from_cc",
":src_code_gen",
"//common:status_macros",
@@ -101,6 +103,7 @@
deps = [
":cc_ir",
":cmdline",
+ ":collect_namespaces",
":generate_bindings_and_metadata",
"//common:rust_allocator_shims",
"//common:test_utils",
diff --git a/rs_bindings_from_cc/cmdline.cc b/rs_bindings_from_cc/cmdline.cc
index 50a6545..707ccac 100644
--- a/rs_bindings_from_cc/cmdline.cc
+++ b/rs_bindings_from_cc/cmdline.cc
@@ -57,6 +57,9 @@
"[template instantiation mode only] output path for the JSON file "
"with mapping from a template instantiation to a generated Rust "
"struct name. This file is used by cc_template! macro expansion.");
+ABSL_FLAG(std::string, namespaces_out, "",
+ "(optional) output path for the JSON file containing the target's"
+ "namespace hierarchy.");
namespace crubit {
@@ -78,7 +81,8 @@
absl::StatusOr<Cmdline> Cmdline::Create() {
return CreateFromArgs(
absl::GetFlag(FLAGS_cc_out), absl::GetFlag(FLAGS_rs_out),
- absl::GetFlag(FLAGS_ir_out), absl::GetFlag(FLAGS_crubit_support_path),
+ absl::GetFlag(FLAGS_ir_out), absl::GetFlag(FLAGS_namespaces_out),
+ absl::GetFlag(FLAGS_crubit_support_path),
absl::GetFlag(FLAGS_rustfmt_exe_path),
absl::GetFlag(FLAGS_rustfmt_config_path), absl::GetFlag(FLAGS_do_nothing),
absl::GetFlag(FLAGS_public_headers),
@@ -89,9 +93,9 @@
absl::StatusOr<Cmdline> Cmdline::CreateFromArgs(
std::string cc_out, std::string rs_out, std::string ir_out,
- std::string crubit_support_path, std::string rustfmt_exe_path,
- std::string rustfmt_config_path, bool do_nothing,
- std::vector<std::string> public_headers,
+ std::string namespaces_out, std::string crubit_support_path,
+ std::string rustfmt_exe_path, std::string rustfmt_config_path,
+ bool do_nothing, std::vector<std::string> public_headers,
std::string targets_and_headers_str, std::vector<std::string> rust_sources,
std::string instantiations_out) {
Cmdline cmdline;
@@ -108,6 +112,8 @@
cmdline.ir_out_ = std::move(ir_out);
+ cmdline.namespaces_out_ = std::move(namespaces_out);
+
if (crubit_support_path.empty()) {
return absl::InvalidArgumentError("please specify --crubit_support_path");
}
diff --git a/rs_bindings_from_cc/cmdline.h b/rs_bindings_from_cc/cmdline.h
index b7fbd41..44091ca 100644
--- a/rs_bindings_from_cc/cmdline.h
+++ b/rs_bindings_from_cc/cmdline.h
@@ -26,17 +26,17 @@
// `rs_out`, and so forth.
static absl::StatusOr<Cmdline> CreateForTesting(
std::string cc_out, std::string rs_out, std::string ir_out,
- std::string crubit_support_path, std::string rustfmt_exe_path,
- std::string rustfmt_config_path, bool do_nothing,
- std::vector<std::string> public_headers,
+ std::string namespaces_out, std::string crubit_support_path,
+ std::string rustfmt_exe_path, std::string rustfmt_config_path,
+ bool do_nothing, std::vector<std::string> public_headers,
std::string targets_and_headers_str,
std::vector<std::string> rust_sources, std::string instantiations_out) {
return CreateFromArgs(
std::move(cc_out), std::move(rs_out), std::move(ir_out),
- std::move(crubit_support_path), std::move(rustfmt_exe_path),
- std::move(rustfmt_config_path), do_nothing, std::move(public_headers),
- std::move(targets_and_headers_str), std::move(rust_sources),
- std::move(instantiations_out));
+ std::move(namespaces_out), std::move(crubit_support_path),
+ std::move(rustfmt_exe_path), std::move(rustfmt_config_path), do_nothing,
+ std::move(public_headers), std::move(targets_and_headers_str),
+ std::move(rust_sources), std::move(instantiations_out));
}
Cmdline(const Cmdline&) = delete;
@@ -47,6 +47,7 @@
absl::string_view cc_out() const { return cc_out_; }
absl::string_view rs_out() const { return rs_out_; }
absl::string_view ir_out() const { return ir_out_; }
+ absl::string_view namespaces_out() const { return namespaces_out_; }
absl::string_view crubit_support_path() const { return crubit_support_path_; }
absl::string_view rustfmt_exe_path() const { return rustfmt_exe_path_; }
absl::string_view rustfmt_config_path() const { return rustfmt_config_path_; }
@@ -71,9 +72,9 @@
static absl::StatusOr<Cmdline> CreateFromArgs(
std::string cc_out, std::string rs_out, std::string ir_out,
- std::string crubit_support_path, std::string rustfmt_exe_path,
- std::string rustfmt_config_path, bool do_nothing,
- std::vector<std::string> public_headers,
+ std::string namespaces_out, std::string crubit_support_path,
+ std::string rustfmt_exe_path, std::string rustfmt_config_path,
+ bool do_nothing, std::vector<std::string> public_headers,
std::string targets_and_headers_str,
std::vector<std::string> rust_sources, std::string instantiations_out);
@@ -93,6 +94,8 @@
std::string instantiations_out_;
std::vector<std::string> rust_sources_;
+
+ std::string namespaces_out_;
};
} // namespace crubit
diff --git a/rs_bindings_from_cc/cmdline_test.cc b/rs_bindings_from_cc/cmdline_test.cc
index a4f753f..0753cd1 100644
--- a/rs_bindings_from_cc/cmdline_test.cc
+++ b/rs_bindings_from_cc/cmdline_test.cc
@@ -26,8 +26,8 @@
absl::StatusOr<Cmdline> TestCmdline(std::vector<std::string> public_headers,
const std::string& targets_and_headers) {
return Cmdline::CreateForTesting(
- "cc_out", "rs_out", "ir_out", "crubit_support_path", "rustfmt_exe_path",
- "rustfmt_config_path",
+ "cc_out", "rs_out", "ir_out", "namespaces_out", "crubit_support_path",
+ "rustfmt_exe_path", "rustfmt_config_path",
/* do_nothing= */ false, std::move(public_headers),
std::move(targets_and_headers), /* rust_sources= */ {},
@@ -37,16 +37,18 @@
} // namespace
TEST(CmdlineTest, BasicCorrectInput) {
- ASSERT_OK_AND_ASSIGN(Cmdline cmdline,
- Cmdline::CreateForTesting(
- "cc_out", "rs_out", "ir_out", "crubit_support_path",
- "rustfmt_exe_path", "rustfmt_config_path",
- /* do_nothing= */ false, {"h1"},
- R"([{"t": "t1", "h": ["h1", "h2"]}])", {"lib.rs"},
- "instantiations_out"));
+ ASSERT_OK_AND_ASSIGN(
+ Cmdline cmdline,
+ Cmdline::CreateForTesting("cc_out", "rs_out", "ir_out", "namespaces_out",
+ "crubit_support_path", "rustfmt_exe_path",
+ "rustfmt_config_path",
+ /* do_nothing= */ false, {"h1"},
+ R"([{"t": "t1", "h": ["h1", "h2"]}])",
+ {"lib.rs"}, "instantiations_out"));
EXPECT_EQ(cmdline.cc_out(), "cc_out");
EXPECT_EQ(cmdline.rs_out(), "rs_out");
EXPECT_EQ(cmdline.ir_out(), "ir_out");
+ EXPECT_EQ(cmdline.namespaces_out(), "namespaces_out");
EXPECT_EQ(cmdline.crubit_support_path(), "crubit_support_path");
EXPECT_EQ(cmdline.rustfmt_exe_path(), "rustfmt_exe_path");
EXPECT_EQ(cmdline.rustfmt_config_path(), "rustfmt_config_path");
@@ -194,7 +196,7 @@
{"t": "target1", "h": ["a.h", "b.h"]}
])";
ASSERT_THAT(
- (Cmdline::CreateForTesting("cc_out", "rs_out", "ir_out",
+ (Cmdline::CreateForTesting("cc_out", "rs_out", "ir_out", "namespaces_out",
"crubit_support_path", "rustfmt_exe_path",
"rustfmt_config_path",
/* do_nothing= */ false, {"a.h"},
@@ -213,7 +215,7 @@
])";
ASSERT_THAT(
Cmdline::CreateForTesting(
- "cc_out", "rs_out", "ir_out", "crubit_support_path",
+ "cc_out", "rs_out", "ir_out", "namespaces_out", "crubit_support_path",
"rustfmt_exe_path", "rustfmt_config_path",
/* do_nothing= */ false, {"a.h"}, std::string(kTargetsAndHeaders),
/* rust_sources= */ {}, "instantiations_out"),
@@ -228,14 +230,15 @@
constexpr absl::string_view kTargetsAndHeaders = R"([
{"t": "target1", "h": ["a.h", "b.h"]}
])";
- ASSERT_THAT(Cmdline::CreateForTesting(
- /* cc_out= */ "", "rs_out", "ir_out", "crubit_support_path",
- "rustfmt_exe_path", "rustfmt_config_path",
- /* do_nothing= */ false, {"a.h"},
- std::string(kTargetsAndHeaders), /* rust_sources= */ {},
- /* instantiations_out= */ ""),
- StatusIs(absl::StatusCode::kInvalidArgument,
- HasSubstr("please specify --cc_out")));
+ ASSERT_THAT(
+ Cmdline::CreateForTesting(
+ /* cc_out= */ "", "rs_out", "ir_out", "namespaces_out",
+ "crubit_support_path", "rustfmt_exe_path", "rustfmt_config_path",
+ /* do_nothing= */ false, {"a.h"}, std::string(kTargetsAndHeaders),
+ /* rust_sources= */ {},
+ /* instantiations_out= */ ""),
+ StatusIs(absl::StatusCode::kInvalidArgument,
+ HasSubstr("please specify --cc_out")));
}
TEST(CmdlineTest, RsOutEmpty) {
@@ -244,8 +247,8 @@
])";
ASSERT_THAT(
Cmdline::CreateForTesting(
- "cc_out", /* rs_out= */ "", "ir_out", "crubit_support_path",
- "rustfmt_exe_path", "rustfmt_config_path",
+ "cc_out", /* rs_out= */ "", "namespaces_out", "ir_out",
+ "crubit_support_path", "rustfmt_exe_path", "rustfmt_config_path",
/* do_nothing= */ false, {"a.h"}, std::string(kTargetsAndHeaders),
/* rust_sources= */ {},
/* instantiations_out= */ ""),
@@ -258,8 +261,8 @@
{"t": "target1", "h": ["a.h", "b.h"]}
])";
ASSERT_OK(Cmdline::CreateForTesting(
- "cc_out", "rs_out", /* ir_out= */ "", "crubit_support_path",
- "rustfmt_exe_path", "rustfmt_config_path",
+ "cc_out", "rs_out", /* ir_out= */ "", "namespaces_out",
+ "crubit_support_path", "rustfmt_exe_path", "rustfmt_config_path",
/* do_nothing= */ false, {"a.h"}, std::string(kTargetsAndHeaders),
/* rust_sources= */ {},
/* instantiations_out= */ ""));
@@ -271,7 +274,7 @@
])";
ASSERT_THAT(
Cmdline::CreateForTesting(
- "cc_out", "rs_out", "ir_out", "crubit_support_path",
+ "cc_out", "rs_out", "ir_out", "namespaces_out", "crubit_support_path",
/* rustfmt_exe_path= */ "", "rustfmt_config_path",
/* do_nothing= */ false, {"a.h"}, std::string(kTargetsAndHeaders),
/* rust_sources= */ {},
diff --git a/rs_bindings_from_cc/collect_namespaces.cc b/rs_bindings_from_cc/collect_namespaces.cc
index b921496..8b2bfd0 100644
--- a/rs_bindings_from_cc/collect_namespaces.cc
+++ b/rs_bindings_from_cc/collect_namespaces.cc
@@ -79,14 +79,14 @@
}
}
- // Converts a trie node into the JSON serializable NamespaceForCcImport.
- NamespaceForCcImport NodeToNamespaceForCcImport(const Node* node) const {
- std::vector<NamespaceForCcImport> namespaces;
+ // Converts a trie node into the JSON serializable NamespaceNode.
+ NamespaceNode NodeToNamespaceNode(const Node* node) const {
+ std::vector<NamespaceNode> namespaces;
namespaces.reserve(node->child_name_to_idx.size());
for (const auto& [_, idx] : node->child_name_to_idx) {
- namespaces.push_back(NodeToNamespaceForCcImport(&trie_nodes_[idx]));
+ namespaces.push_back(NodeToNamespaceNode(&trie_nodes_[idx]));
}
- return NamespaceForCcImport{std::string(node->name), std::move(namespaces)};
+ return NamespaceNode{std::string(node->name), std::move(namespaces)};
}
public:
@@ -118,21 +118,21 @@
}
}
- // Converts the trie into the JSON serializable AllNamespacesForCcImport.
- AllNamespacesForCcImport ToAllNamespacesForCcImport() {
- std::vector<NamespaceForCcImport> namespaces;
+ // Converts the trie into the JSON serializable NamespacesHierarchy.
+ NamespacesHierarchy ToNamespacesHierarchy() {
+ std::vector<NamespaceNode> namespaces;
namespaces.reserve(this->top_level_name_to_idx_.size());
for (auto& [_, idx] : this->top_level_name_to_idx_) {
- namespaces.push_back(NodeToNamespaceForCcImport(&trie_nodes_[idx]));
+ namespaces.push_back(NodeToNamespaceNode(&trie_nodes_[idx]));
}
- return AllNamespacesForCcImport{std::move(namespaces)};
+ return NamespacesHierarchy{std::move(namespaces)};
}
};
} // namespace
// Returns the current target's namespace hierarchy in JSON serializable format.
-AllNamespacesForCcImport CollectNamespaces(const IR& ir) {
+NamespacesHierarchy CollectNamespaces(const IR& ir) {
auto all_namespaces = ir.get_items_if<Namespace>();
absl::flat_hash_map<ItemId, const Namespace*> id_to_namespace;
for (auto ns : all_namespaces) {
@@ -152,10 +152,10 @@
trie.InsertTopLevel(ns);
}
- return trie.ToAllNamespacesForCcImport();
+ return trie.ToNamespacesHierarchy();
}
-llvm::json::Value NamespaceForCcImport::ToJson() const {
+llvm::json::Value NamespaceNode::ToJson() const {
std::vector<llvm::json::Value> json_children;
json_children.reserve(children.size());
for (const auto& child : children) {
@@ -172,7 +172,7 @@
};
}
-llvm::json::Value AllNamespacesForCcImport::ToJson() const {
+llvm::json::Value NamespacesHierarchy::ToJson() const {
std::vector<llvm::json::Value> json_namespaces;
json_namespaces.reserve(namespaces.size());
for (const auto& ns : namespaces) {
diff --git a/rs_bindings_from_cc/collect_namespaces.h b/rs_bindings_from_cc/collect_namespaces.h
index 6ef5cc1..d244ed5 100644
--- a/rs_bindings_from_cc/collect_namespaces.h
+++ b/rs_bindings_from_cc/collect_namespaces.h
@@ -17,34 +17,33 @@
// stores the names of the namespace children, as it is the only information
// that the cc_import! macro needs in order to be able to merge namespaces
// across targets.
-struct NamespaceForCcImport {
+struct NamespaceNode {
llvm::json::Value ToJson() const;
std::string name;
- std::vector<NamespaceForCcImport> children;
+ std::vector<NamespaceNode> children;
};
-inline std::ostream& operator<<(std::ostream& o,
- const NamespaceForCcImport& ns) {
+inline std::ostream& operator<<(std::ostream& o, const NamespaceNode& ns) {
return o << std::string(llvm::formatv("{0:2}", ns.ToJson()));
}
// Representation of all C++ namespaces within the current target.
-struct AllNamespacesForCcImport {
+struct NamespacesHierarchy {
llvm::json::Value ToJson() const;
- std::vector<NamespaceForCcImport> namespaces;
+ std::vector<NamespaceNode> namespaces;
};
inline std::ostream& operator<<(std::ostream& o,
- const AllNamespacesForCcImport& all) {
+ const NamespacesHierarchy& all) {
return o << std::string(llvm::formatv("{0:2}", all.ToJson()));
}
// Returns the current target's namespace hierarchy in JSON serializable format.
-AllNamespacesForCcImport CollectNamespaces(const IR& ir);
+NamespacesHierarchy CollectNamespaces(const IR& ir);
-inline std::string NamespacesAsJson(const AllNamespacesForCcImport& topLevel) {
+inline std::string NamespacesAsJson(const NamespacesHierarchy& topLevel) {
return llvm::formatv("{0:2}", topLevel.ToJson());
}
} // namespace crubit
diff --git a/rs_bindings_from_cc/generate_bindings_and_metadata.cc b/rs_bindings_from_cc/generate_bindings_and_metadata.cc
index 90d6036..d43144e 100644
--- a/rs_bindings_from_cc/generate_bindings_and_metadata.cc
+++ b/rs_bindings_from_cc/generate_bindings_and_metadata.cc
@@ -6,6 +6,7 @@
#include "common/status_macros.h"
#include "rs_bindings_from_cc/collect_instantiations.h"
+#include "rs_bindings_from_cc/collect_namespaces.h"
#include "rs_bindings_from_cc/ir_from_cc.h"
#include "rs_bindings_from_cc/src_code_gen.h"
@@ -36,10 +37,13 @@
cmdline.rustfmt_exe_path(),
cmdline.rustfmt_config_path()));
+ auto top_level_namespaces = crubit::CollectNamespaces(ir);
+
return BindingsAndMetadata{
.ir = ir,
.rs_api = bindings.rs_api,
.rs_api_impl = bindings.rs_api_impl,
+ .namespaces = top_level_namespaces,
};
}
diff --git a/rs_bindings_from_cc/generate_bindings_and_metadata.h b/rs_bindings_from_cc/generate_bindings_and_metadata.h
index 5140c0a..b641d9d 100644
--- a/rs_bindings_from_cc/generate_bindings_and_metadata.h
+++ b/rs_bindings_from_cc/generate_bindings_and_metadata.h
@@ -10,6 +10,7 @@
#include "absl/status/statusor.h"
#include "rs_bindings_from_cc/cmdline.h"
+#include "rs_bindings_from_cc/collect_namespaces.h"
#include "rs_bindings_from_cc/ir.h"
namespace crubit {
@@ -22,6 +23,8 @@
std::string rs_api;
// Generated C++ source code.
std::string rs_api_impl;
+ // A hierarchy tree for all C++ namespaces used in the target.
+ NamespacesHierarchy namespaces;
};
// Returns `BindingsAndMetadata` as requested by the user on the command line.
diff --git a/rs_bindings_from_cc/generate_bindings_and_metadata_test.cc b/rs_bindings_from_cc/generate_bindings_and_metadata_test.cc
index c89fb8c..193488a 100644
--- a/rs_bindings_from_cc/generate_bindings_and_metadata_test.cc
+++ b/rs_bindings_from_cc/generate_bindings_and_metadata_test.cc
@@ -8,6 +8,7 @@
#include "gtest/gtest.h"
#include "common/test_utils.h"
#include "rs_bindings_from_cc/cmdline.h"
+#include "rs_bindings_from_cc/collect_namespaces.h"
#include "rs_bindings_from_cc/ir.h"
namespace crubit {
@@ -26,7 +27,7 @@
ASSERT_OK_AND_ASSIGN(
Cmdline cmdline,
Cmdline::CreateForTesting(
- "cc_out", "rs_out", "ir_out", "crubit_support_path",
+ "cc_out", "rs_out", "ir_out", "namespaces_out", "crubit_support_path",
std::string(kDefaultRustfmtExePath), "nowhere/rustfmt.toml",
/* do_nothing= */ false,
/* public_headers= */ {"a.h"}, std::string(kTargetsAndHeaders),
@@ -54,7 +55,7 @@
ASSERT_OK_AND_ASSIGN(
Cmdline cmdline,
Cmdline::CreateForTesting(
- "cc_out", "rs_out", "ir_out", "crubit_support_path",
+ "cc_out", "rs_out", "ir_out", "namespaces_out", "crubit_support_path",
std::string(kDefaultRustfmtExePath), "nowhere/rustfmt.toml",
/* do_nothing= */ false,
/* public_headers= */ {"a.h"}, std::string(kTargetsAndHeaders),
@@ -79,7 +80,7 @@
ASSERT_OK_AND_ASSIGN(
Cmdline cmdline,
Cmdline::CreateForTesting(
- "cc_out", "rs_out", "ir_out", "crubit_support_path",
+ "cc_out", "rs_out", "ir_out", "namespaces_out", "crubit_support_path",
std::string(kDefaultRustfmtExePath), "nowhere/rustfmt.toml",
/* do_nothing= */ false,
/* public_headers= */ {"a.h"}, std::string(kTargetsAndHeaders),
@@ -96,5 +97,87 @@
ASSERT_THAT(InstantiationsAsJson(result.ir), StrEq("{}"));
}
+TEST(GenerateBindingsAndMetadataTest, NamespacesJsonGenerated) {
+ constexpr absl::string_view kTargetsAndHeaders = R"([
+ {"t": "target1", "h": ["a.h"]}
+ ])";
+ constexpr absl::string_view kHeaderContent = R"(
+ namespace top_level_1 {
+ namespace middle {
+ namespace inner_1 {}
+ }
+ namespace middle {
+ namespace inner_2 {}
+ }
+ }
+
+ namespace top_level_2 {
+ namespace inner_3 {}
+ }
+
+ namespace top_level_1 {}
+ )";
+ constexpr absl::string_view kExpected = R"({
+ "namespaces": [
+ {
+ "namespace": {
+ "children": [
+ {
+ "namespace": {
+ "children": [
+ {
+ "namespace": {
+ "children": [],
+ "name": "inner_1"
+ }
+ },
+ {
+ "namespace": {
+ "children": [],
+ "name": "inner_2"
+ }
+ }
+ ],
+ "name": "middle"
+ }
+ }
+ ],
+ "name": "top_level_1"
+ }
+ },
+ {
+ "namespace": {
+ "children": [
+ {
+ "namespace": {
+ "children": [],
+ "name": "inner_3"
+ }
+ }
+ ],
+ "name": "top_level_2"
+ }
+ }
+ ]
+})";
+
+ ASSERT_OK_AND_ASSIGN(
+ Cmdline cmdline,
+ Cmdline::CreateForTesting(
+ "cc_out", "rs_out", "ir_out", "namespaces_json",
+ "crubit_support_path", std::string(kDefaultRustfmtExePath),
+ "nowhere/rustfmt.toml",
+ /* do_nothing= */ false,
+ /* public_headers= */ {"a.h"}, std::string(kTargetsAndHeaders),
+ /* rust_sources= */ {}, /* instantiations_out= */ ""));
+ ASSERT_OK_AND_ASSIGN(BindingsAndMetadata result,
+ GenerateBindingsAndMetadata(
+ cmdline, DefaultClangArgs(),
+ /* virtual_headers_contents= */
+ {{HeaderName("a.h"), std::string(kHeaderContent)}}));
+
+ ASSERT_THAT(NamespacesAsJson(result.namespaces), StrEq(kExpected));
+}
+
} // namespace
} // namespace crubit
diff --git a/rs_bindings_from_cc/rs_bindings_from_cc.cc b/rs_bindings_from_cc/rs_bindings_from_cc.cc
index 1383fdc..fef6583 100644
--- a/rs_bindings_from_cc/rs_bindings_from_cc.cc
+++ b/rs_bindings_from_cc/rs_bindings_from_cc.cc
@@ -17,7 +17,9 @@
#include "common/file_io.h"
#include "common/status_macros.h"
#include "rs_bindings_from_cc/cmdline.h"
+#include "rs_bindings_from_cc/collect_namespaces.h"
#include "rs_bindings_from_cc/generate_bindings_and_metadata.h"
+#include "rs_bindings_from_cc/ir.h"
#include "llvm/Support/raw_ostream.h"
namespace crubit {
@@ -38,6 +40,9 @@
CRUBIT_RETURN_IF_ERROR(
SetFileContents(cmdline.instantiations_out(), "[]"));
}
+ if (!cmdline.namespaces_out().empty()) {
+ CRUBIT_RETURN_IF_ERROR(SetFileContents(cmdline.namespaces_out(), "[]"));
+ }
return absl::OkStatus();
}
@@ -64,6 +69,12 @@
crubit::InstantiationsAsJson(bindings_and_metadata.ir)));
}
+ if (!cmdline.namespaces_out().empty()) {
+ CRUBIT_RETURN_IF_ERROR(SetFileContents(
+ cmdline.namespaces_out(),
+ crubit::NamespacesAsJson(bindings_and_metadata.namespaces)));
+ }
+
return absl::OkStatus();
}