Replace LOG(FATAL) and DCHECK with LLVM equivalents.
At a high-level the changes in this CL look like this:
*) LOG(FATAL) => llvm::report_fatal_error + llvm::formatv
*) DCHECK => assert
*) CHECK => assert (this wouldn't preserve behavior in NDEBUG builds so
this transformation is not applied in all the cases).
PiperOrigin-RevId: 435361199
diff --git a/rs_bindings_from_cc/ast_consumer.cc b/rs_bindings_from_cc/ast_consumer.cc
index aa92100..15ceac5 100644
--- a/rs_bindings_from_cc/ast_consumer.cc
+++ b/rs_bindings_from_cc/ast_consumer.cc
@@ -4,8 +4,8 @@
#include "rs_bindings_from_cc/ast_consumer.h"
-#include "base/logging.h"
#include "rs_bindings_from_cc/importer.h"
+#include "rs_bindings_from_cc/util/check.h"
#include "third_party/llvm/llvm-project/clang/include/clang/AST/ASTContext.h"
#include "third_party/llvm/llvm-project/clang/include/clang/Frontend/CompilerInstance.h"
@@ -19,7 +19,7 @@
// There is nothing more for us to do here.
return;
}
- CHECK(instance_.hasSema());
+ CRUBIT_CHECK(instance_.hasSema());
Importer importer(invocation_, ast_context, instance_.getSema());
importer.Import(ast_context.getTranslationUnitDecl());
}
diff --git a/rs_bindings_from_cc/ast_convert.cc b/rs_bindings_from_cc/ast_convert.cc
index e05946d..b247651 100644
--- a/rs_bindings_from_cc/ast_convert.cc
+++ b/rs_bindings_from_cc/ast_convert.cc
@@ -4,10 +4,9 @@
#include "rs_bindings_from_cc/ast_convert.h"
-#include <assert.h>
-
#include "third_party/absl/functional/function_ref.h"
#include "rs_bindings_from_cc/ir.h"
+#include "rs_bindings_from_cc/util/check.h"
#include "third_party/llvm/llvm-project/clang/include/clang/AST/Decl.h"
#include "third_party/llvm/llvm-project/clang/include/clang/AST/DeclCXX.h"
#include "third_party/llvm/llvm-project/clang/include/clang/Basic/Specifiers.h"
@@ -109,8 +108,9 @@
case clang::AS_private:
return kPrivate;
case clang::AS_none:
- // We should never be encoding a "none" access specifier in IR.
- assert(false);
+ CRUBIT_CHECK(
+ false &&
+ "We should never be encoding a 'none' access specifier in IR.");
// We have to return something. Conservatively return private so we don't
// inadvertently make a private member variable accessible in Rust.
return kPrivate;
diff --git a/rs_bindings_from_cc/importer.cc b/rs_bindings_from_cc/importer.cc
index 6b640c0..d2dfcc3 100644
--- a/rs_bindings_from_cc/importer.cc
+++ b/rs_bindings_from_cc/importer.cc
@@ -15,7 +15,6 @@
#include <utility>
#include <vector>
-#include "base/logging.h"
#include "third_party/absl/container/flat_hash_map.h"
#include "third_party/absl/container/flat_hash_set.h"
#include "third_party/absl/status/status.h"
@@ -28,6 +27,7 @@
#include "rs_bindings_from_cc/ast_convert.h"
#include "rs_bindings_from_cc/bazel_types.h"
#include "rs_bindings_from_cc/ir.h"
+#include "rs_bindings_from_cc/util/check.h"
#include "third_party/llvm/llvm-project/clang/include/clang/AST/ASTContext.h"
#include "third_party/llvm/llvm-project/clang/include/clang/AST/Attrs.inc"
#include "third_party/llvm/llvm-project/clang/include/clang/AST/CXXInheritance.h"
@@ -48,6 +48,7 @@
#include "third_party/llvm/llvm-project/llvm/include/llvm/ADT/SmallPtrSet.h"
#include "third_party/llvm/llvm-project/llvm/include/llvm/Support/Casting.h"
#include "third_party/llvm/llvm-project/llvm/include/llvm/Support/ErrorHandling.h"
+#include "third_party/llvm/llvm-project/llvm/include/llvm/Support/FormatVariadic.h"
#include "third_party/llvm/llvm-project/llvm/include/llvm/Support/Regex.h"
#include "util/task/status_macros.h"
@@ -167,8 +168,8 @@
base_path_element.Base->getType()->getAsCXXRecordDecl()))
.getQuantity()};
}
- DCHECK(!offset.hasValue() || *offset >= 0)
- << "Concrete base classes should have non-negative offsets.";
+ CRUBIT_CHECK((!offset.hasValue() || *offset >= 0) &&
+ "Concrete base classes should have non-negative offsets.");
bases.push_back(
BaseClass{.base_record_id = GenerateDeclId(base_record_decl),
.offset = offset});
@@ -496,9 +497,7 @@
std::set<std::string> errors;
auto add_error = [&errors, function_decl](std::string msg) {
auto result = errors.insert(std::move(msg));
- CHECK(result.second) << "Duplicated error message for "
- << function_decl->getNameAsString() << ": "
- << *result.first;
+ CRUBIT_CHECK(result.second && "Duplicated error message");
};
if (auto* method_decl =
clang::dyn_cast<clang::CXXMethodDecl>(function_decl)) {
@@ -527,7 +526,8 @@
}
if (lifetimes) {
- CHECK_EQ(lifetimes->param_lifetimes.size(), function_decl->getNumParams());
+ CRUBIT_CHECK(lifetimes->param_lifetimes.size() ==
+ function_decl->getNumParams());
}
for (unsigned i = 0; i < function_decl->getNumParams(); ++i) {
const clang::ParmVarDecl* param = function_decl->getParamDecl(i);
@@ -560,7 +560,7 @@
}
std::optional<Identifier> param_name = GetTranslatedIdentifier(param);
- CHECK(param_name.has_value()); // No known cases where the above can fail.
+ CRUBIT_CHECK(param_name.has_value()); // No known failure cases.
params.push_back({*param_type, *std::move(param_name)});
}
@@ -596,7 +596,7 @@
for (devtools_rust::Lifetime lifetime : all_lifetimes) {
std::optional<llvm::StringRef> name =
lifetime_symbol_table.LookupLifetime(lifetime);
- CHECK(name.has_value());
+ CRUBIT_CHECK(name.has_value());
lifetime_params.push_back(
{.name = name->str(), .id = LifetimeId(lifetime.Id())});
}
@@ -655,7 +655,11 @@
std::optional<UnqualifiedIdentifier> translated_name =
GetTranslatedName(function_decl);
- CHECK(return_type.ok()); // Silence ClangTidy, checked above.
+
+ // Silence ClangTidy, checked above: calling `add_error` if
+ // `!return_type.ok()` and returning early if `!errors.empty()`.
+ CRUBIT_CHECK(return_type.ok());
+
if (translated_name.has_value()) {
return LookupResult(Func{
.name = *translated_name,
@@ -870,10 +874,7 @@
std::optional<Identifier> identifier =
GetTranslatedIdentifier(typedef_name_decl);
- if (!identifier.has_value()) {
- // This should never happen.
- LOG(FATAL) << "Couldn't get identifier for TypedefNameDecl";
- }
+ CRUBIT_CHECK(identifier.has_value()); // This should never happen.
std::optional<devtools_rust::TypeLifetimes> no_lifetimes;
absl::StatusOr<MappedType> underlying_type =
ConvertQualType(typedef_name_decl->getUnderlyingType(), no_lifetimes);
@@ -959,7 +960,7 @@
clang::QualType pointee_type = type->getPointeeType();
std::optional<LifetimeId> lifetime;
if (lifetimes.has_value()) {
- CHECK(!lifetimes->empty());
+ CRUBIT_CHECK(!lifetimes->empty());
lifetime = LifetimeId(lifetimes->back().Id());
lifetimes->pop_back();
}
@@ -992,7 +993,7 @@
std::move(mapped_return_type),
std::move(mapped_param_types));
} else {
- DCHECK(type->isLValueReferenceType());
+ CRUBIT_CHECK(type->isLValueReferenceType());
return MappedType::FuncRef(cc_call_conv, rs_abi, lifetime,
std::move(mapped_return_type),
std::move(mapped_param_types));
@@ -1005,7 +1006,7 @@
return MappedType::PointerTo(std::move(mapped_pointee_type), lifetime,
nullable);
} else {
- DCHECK(type->isLValueReferenceType());
+ CRUBIT_CHECK(type->isLValueReferenceType());
return MappedType::LValueReferenceTo(std::move(mapped_pointee_type),
lifetime);
}
@@ -1170,10 +1171,12 @@
case clang::DeclarationName::CXXOperatorName:
switch (named_decl->getDeclName().getCXXOverloadedOperator()) {
case clang::OO_None:
- LOG(FATAL) << "No OO_None expected under CXXOperatorName branch";
+ CRUBIT_CHECK(false &&
+ "No OO_None expected under CXXOperatorName branch");
return std::nullopt;
case clang::NUM_OVERLOADED_OPERATORS:
- LOG(FATAL) << "No NUM_OVERLOADED_OPERATORS expected at runtime";
+ CRUBIT_CHECK(false &&
+ "No NUM_OVERLOADED_OPERATORS expected at runtime");
return std::nullopt;
// clang-format off
#define OVERLOADED_OPERATOR(name, spelling, ...) \
@@ -1184,7 +1187,8 @@
#undef OVERLOADED_OPERATOR
// clang-format on
}
- LOG(FATAL) << "The `switch` above should handle all cases and `return`";
+ CRUBIT_CHECK(false && "The `switch` above should handle all cases");
+ return std::nullopt;
default:
// To be implemented later: CXXConversionFunctionName.
// There are also e.g. literal operators, deduction guides, etc., but
diff --git a/rs_bindings_from_cc/importer.h b/rs_bindings_from_cc/importer.h
index 59c037d..4642c17 100644
--- a/rs_bindings_from_cc/importer.h
+++ b/rs_bindings_from_cc/importer.h
@@ -13,7 +13,6 @@
#include <variant>
#include <vector>
-#include "base/logging.h"
#include "third_party/absl/container/flat_hash_map.h"
#include "third_party/absl/container/flat_hash_set.h"
#include "third_party/absl/status/statusor.h"
@@ -21,6 +20,7 @@
#include "lifetime_annotations/lifetime_annotations.h"
#include "rs_bindings_from_cc/bazel_types.h"
#include "rs_bindings_from_cc/ir.h"
+#include "rs_bindings_from_cc/util/check.h"
#include "third_party/llvm/llvm-project/clang/include/clang/AST/ASTContext.h"
#include "third_party/llvm/llvm-project/clang/include/clang/AST/Decl.h"
#include "third_party/llvm/llvm-project/clang/include/clang/AST/Mangle.h"
@@ -48,8 +48,10 @@
lifetime_context_(
std::make_shared<devtools_rust::LifetimeAnnotationContext>()),
header_targets_(header_targets) {
- CHECK(!entry_headers_.empty());
- CHECK(!header_targets_.empty());
+ // Caller should verify that the inputs are non-empty.
+ CRUBIT_CHECK(!entry_headers_.empty());
+ CRUBIT_CHECK(!header_targets_.empty());
+
ir_.used_headers.insert(ir_.used_headers.end(), entry_headers_.begin(),
entry_headers.end());
ir_.current_target = target_;
@@ -85,7 +87,7 @@
: invocation_(invocation),
ctx_(ctx),
sema_(sema),
- mangler_(ABSL_DIE_IF_NULL(ctx_.createMangleContext())) {}
+ mangler_(CRUBIT_DIE_IF_NULL(ctx_.createMangleContext())) {}
// Import all visible declarations from a translation unit.
void Import(clang::TranslationUnitDecl* decl);
diff --git a/rs_bindings_from_cc/ir.cc b/rs_bindings_from_cc/ir.cc
index 10099d4..6261631 100644
--- a/rs_bindings_from_cc/ir.cc
+++ b/rs_bindings_from_cc/ir.cc
@@ -13,9 +13,9 @@
#include <variant>
#include <vector>
-#include "base/integral_types.h"
#include "third_party/absl/strings/string_view.h"
#include "rs_bindings_from_cc/bazel_types.h"
+#include "rs_bindings_from_cc/util/check.h"
#include "rs_bindings_from_cc/util/strong_int.h"
#include "third_party/llvm/llvm-project/llvm/include/llvm/Support/JSON.h"
@@ -117,12 +117,13 @@
MappedType result = FuncRef(cc_call_conv, rs_abi, lifetime,
std::move(return_type), std::move(param_types));
- DCHECK_EQ(result.cc_type.name, internal::kCcLValueRef);
+ CRUBIT_CHECK(result.cc_type.name == internal::kCcLValueRef);
result.cc_type.name = std::string(internal::kCcPtr);
RsType rs_func_ptr_type = std::move(result.rs_type);
- DCHECK_EQ(rs_func_ptr_type.name.substr(0, internal::kRustFuncPtr.length()),
- internal::kRustFuncPtr);
+ CRUBIT_CHECK(
+ rs_func_ptr_type.name.substr(0, internal::kRustFuncPtr.length()) ==
+ internal::kRustFuncPtr);
result.rs_type =
RsType{.name = "Option", .type_args = {std::move(rs_func_ptr_type)}};
diff --git a/rs_bindings_from_cc/ir.h b/rs_bindings_from_cc/ir.h
index 1dadd71..f43fab7 100644
--- a/rs_bindings_from_cc/ir.h
+++ b/rs_bindings_from_cc/ir.h
@@ -21,10 +21,9 @@
#include <variant>
#include <vector>
-#include "base/integral_types.h"
-#include "base/logging.h"
#include "third_party/absl/strings/string_view.h"
#include "rs_bindings_from_cc/bazel_types.h"
+#include "rs_bindings_from_cc/util/check.h"
#include "rs_bindings_from_cc/util/strong_int.h"
#include "third_party/llvm/llvm-project/llvm/include/llvm/ADT/APSInt.h"
#include "third_party/llvm/llvm-project/llvm/include/llvm/ADT/Optional.h"
@@ -247,7 +246,7 @@
public:
explicit Identifier(std::string identifier)
: identifier_(std::move(identifier)) {
- CHECK(!identifier_.empty()) << "Identifier name cannot be empty.";
+ CRUBIT_CHECK(!identifier_.empty());
}
absl::string_view Ident() const { return identifier_; }
@@ -268,8 +267,7 @@
class IntegerConstant {
public:
explicit IntegerConstant(const llvm::APSInt& value) {
- CHECK(value.getSignificantBits() <= 64)
- << "enumerator value unexpectedly had more than 64 bits";
+ CRUBIT_CHECK(value.getSignificantBits() <= 64);
is_negative_ = value < 0;
wrapped_value_ = static_cast<uint64_t>(value.getExtValue());
}
@@ -289,7 +287,7 @@
class Operator {
public:
explicit Operator(std::string name) : name_(std::move(name)) {
- CHECK(!name_.empty()) << "Operator name cannot be empty.";
+ CRUBIT_CHECK(!name_.empty());
}
absl::string_view Name() const { return name_; }
diff --git a/rs_bindings_from_cc/ir_from_cc.cc b/rs_bindings_from_cc/ir_from_cc.cc
index cc62eea..db8556c 100644
--- a/rs_bindings_from_cc/ir_from_cc.cc
+++ b/rs_bindings_from_cc/ir_from_cc.cc
@@ -19,6 +19,7 @@
#include "rs_bindings_from_cc/frontend_action.h"
#include "rs_bindings_from_cc/importer.h"
#include "rs_bindings_from_cc/ir.h"
+#include "rs_bindings_from_cc/util/check.h"
#include "third_party/llvm/llvm-project/clang/include/clang/Basic/FileManager.h"
#include "third_party/llvm/llvm-project/clang/include/clang/Basic/FileSystemOptions.h"
#include "third_party/llvm/llvm-project/clang/include/clang/Frontend/FrontendAction.h"
@@ -38,6 +39,10 @@
virtual_headers_contents,
absl::flat_hash_map<const HeaderName, const BlazeLabel> headers_to_targets,
absl::Span<const absl::string_view> args) {
+ // Caller should verify that the inputs are not empty.
+ CRUBIT_CHECK(!extra_source_code.empty() || !public_headers.empty());
+ CRUBIT_CHECK(!extra_source_code.empty() || !headers_to_targets.empty());
+
std::vector<HeaderName> entrypoint_headers(public_headers.begin(),
public_headers.end());
clang::tooling::FileContentMappings file_contents;
diff --git a/rs_bindings_from_cc/json_from_cc.cc b/rs_bindings_from_cc/json_from_cc.cc
index b1df4a4..ccd4391 100644
--- a/rs_bindings_from_cc/json_from_cc.cc
+++ b/rs_bindings_from_cc/json_from_cc.cc
@@ -4,7 +4,6 @@
#include <string>
-#include "base/logging.h"
#include "third_party/absl/status/statusor.h"
#include "rs_bindings_from_cc/bazel_types.h"
#include "rs_bindings_from_cc/ffi_types.h"
@@ -38,7 +37,10 @@
// this from tests, which are ok to just fail. Clang has already printed error
// messages. If we start using this for production, then we should bridge the
// error code into Rust.
- CHECK(ir.ok()) << "- IrFromCc reported an error: " << ir.status().message();
+ if (!ir.ok()) {
+ llvm::report_fatal_error(llvm::formatv("IrFromCc reported an error: {0}",
+ ir.status().message()));
+ }
std::string json = llvm::formatv("{0}", ir->ToJson());
return AllocFfiU8SliceBox(MakeFfiU8Slice(json));
}
diff --git a/rs_bindings_from_cc/rs_bindings_from_cc.cc b/rs_bindings_from_cc/rs_bindings_from_cc.cc
index 1060f6c..4a2a0e2 100644
--- a/rs_bindings_from_cc/rs_bindings_from_cc.cc
+++ b/rs_bindings_from_cc/rs_bindings_from_cc.cc
@@ -11,7 +11,6 @@
#include <vector>
#include "base/init_google.h"
-#include "base/logging.h"
#include "third_party/absl/container/flat_hash_map.h"
#include "third_party/absl/status/status.h"
#include "third_party/absl/status/statusor.h"
diff --git a/rs_bindings_from_cc/util/check.h b/rs_bindings_from_cc/util/check.h
new file mode 100644
index 0000000..581738b
--- /dev/null
+++ b/rs_bindings_from_cc/util/check.h
@@ -0,0 +1,36 @@
+// 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 CRUBIT_RS_BINDINGS_FROM_CC_UTIL_CHECK_H_
+#define CRUBIT_RS_BINDINGS_FROM_CC_UTIL_CHECK_H_
+
+#include "third_party/absl/base/attributes.h"
+#include "third_party/absl/base/optimization.h"
+#include "third_party/llvm/llvm-project/llvm/include/llvm/Support/ErrorHandling.h"
+#include "third_party/llvm/llvm-project/llvm/include/llvm/Support/FormatVariadic.h"
+
+#define CRUBIT_CHECK(condition) \
+ do { \
+ if (ABSL_PREDICT_FALSE(!(condition))) { \
+ ::llvm::report_fatal_error( \
+ ::llvm::formatv("CRUBIT_CHECK failure: {0}:{1}: {2}", __FILE__, \
+ __LINE__, #condition)); \
+ } \
+ } while (false)
+
+namespace rs_bindings_from_cc {
+template <typename T>
+ABSL_MUST_USE_RESULT T DieIfNull(const char* file, int line,
+ const char* exprtext, T&& t) {
+ if (ABSL_PREDICT_FALSE(t == nullptr)) {
+ ::llvm::report_fatal_error(llvm::formatv(
+ "CRUBIT_DIE_IF_NULL failure: {0}:{1}: {2}", file, line, exprtext));
+ }
+ return std::forward<T>(t);
+}
+} // namespace rs_bindings_from_cc
+#define CRUBIT_DIE_IF_NULL(value) \
+ ::rs_bindings_from_cc::DieIfNull(__FILE__, __LINE__, #value, (value))
+
+#endif // CRUBIT_RS_BINDINGS_FROM_CC_UTIL_CHECK_H_