Skip to content

Commit dd667fb

Browse files
authored
Add new rules for brotli, socket and ip (#59)
This PR adds more translated symbols for brotli (enum values + functions), socket (enums + macros), and ip (enums). This is not straight forward because symbols like IPPROTO_TCP are defined as enum on Linux and macro on macOS. To handle this, I modified cpp_rule_preprocessor + mapper to match macros and VisitIntegerLiteral to emit the translated macro. Because on one platform the symbol is an enum and on the other it's a macro, the AST of the translated program is also different. To be able to generate the same code on both platforms, I use `IsCastRedundantInRust` to normalize `(libc::IPPROTO_TCP as i32)` (Linux) and `libc::IPPROTO_TCP` (macOS) to `libc::IPPROTO_TCP`. This uses the fact that `libc::IPPROTO_TCP` is already an i32 in Rust, so the cast is redundant.
1 parent 6a064cd commit dd667fb

22 files changed

Lines changed: 558 additions & 11 deletions

cpp2rust/converter/converter.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1626,6 +1626,11 @@ std::string Converter::getIntegerLiteral(clang::IntegerLiteral *expr,
16261626
}
16271627

16281628
bool Converter::VisitIntegerLiteral(clang::IntegerLiteral *expr) {
1629+
if (auto str = GetMappedAsString(expr); !str.empty()) {
1630+
StrCat(str);
1631+
computed_expr_type_ = ComputedExprType::FreshValue;
1632+
return false;
1633+
}
16291634
StrCat(getIntegerLiteral(expr, Mapper::Map(expr->getType()) != "i32"));
16301635
computed_expr_type_ = ComputedExprType::FreshValue;
16311636
return false;
@@ -1774,6 +1779,15 @@ void Converter::ConvertIntegralToBooleanCast(clang::ImplicitCastExpr *expr) {
17741779
}
17751780
}
17761781

1782+
bool Converter::IsCastRedundantInRust(clang::Expr *expr,
1783+
clang::QualType target_type) {
1784+
auto target = GetUnsafeTypeAsString(target_type);
1785+
if (const auto *rule = Mapper::GetExprRule(expr)) {
1786+
return rule->return_type.type == target;
1787+
}
1788+
return GetUnsafeTypeAsString(expr->getType()) == target;
1789+
}
1790+
17771791
bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
17781792
auto *sub_expr = expr->getSubExpr();
17791793
auto type = expr->getType();
@@ -1873,8 +1887,7 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
18731887
break;
18741888
}
18751889
// Skip cast if source and target map to the same Rust type.
1876-
if (GetUnsafeTypeAsString(sub_expr->getType()) ==
1877-
GetUnsafeTypeAsString(type)) {
1890+
if (IsCastRedundantInRust(sub_expr, type)) {
18781891
Convert(sub_expr);
18791892
break;
18801893
}
@@ -3129,7 +3142,7 @@ std::string Converter::GetUnsafeTypeAsString(clang::QualType qual_type) const {
31293142
std::string type_as_string;
31303143
Converter converter(type_as_string, ctx_);
31313144
converter.Convert(qual_type);
3132-
return type_as_string;
3145+
return std::string(Trim(type_as_string));
31333146
}
31343147

31353148
void Converter::ConvertVarInit(clang::QualType qual_type, clang::Expr *expr) {
@@ -3567,7 +3580,8 @@ void Converter::ConvertDeref(clang::Expr *expr) {
35673580

35683581
void Converter::ConvertArrow(clang::Expr *expr) { ConvertDeref(expr); }
35693582

3570-
void Converter::ConvertCast(clang::QualType qual_type) {
3583+
void Converter::ConvertCast(clang::QualType qual_type, int line) {
3584+
log() << "[ConvertCast] Called from line " << line << "\n";
35713585
StrCat(keyword::kAs, GetUnsafeTypeAsString(qual_type));
35723586
}
35733587

cpp2rust/converter/converter.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,8 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
480480

481481
virtual void ConvertArrow(clang::Expr *expr);
482482

483-
virtual void ConvertCast(clang::QualType qual_type);
483+
virtual void ConvertCast(clang::QualType qual_type,
484+
int line = __builtin_LINE());
484485

485486
virtual void ConvertLoopVariable(clang::VarDecl *decl,
486487
clang::Expr *range_init);
@@ -705,6 +706,8 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
705706

706707
TempMaterializationCtx CollectPrvalueToLRefArgs(clang::CallExpr *expr);
707708

709+
bool IsCastRedundantInRust(clang::Expr *expr, clang::QualType target_type);
710+
708711
private:
709712
void materializeTemplateSpecialization(clang::CXXRecordDecl *decl);
710713

cpp2rust/converter/converter_lib.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -803,7 +803,7 @@ bool SwitchHasFallthrough(clang::SwitchStmt *stmt) {
803803
return false;
804804
}
805805

806-
static std::string_view Trim(std::string_view s) {
806+
std::string_view Trim(std::string_view s) {
807807
auto is_space = [](unsigned char c) { return std::isspace(c); };
808808
auto b = std::find_if_not(s.begin(), s.end(), is_space);
809809
auto e = std::find_if_not(s.rbegin(), s.rend(), is_space).base();

cpp2rust/converter/converter_lib.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ std::vector<clang::Stmt *> GetSwitchCaseBody(clang::CompoundStmt *body,
170170

171171
bool SwitchHasFallthrough(clang::SwitchStmt *stmt);
172172

173+
std::string_view Trim(std::string_view s);
174+
173175
void Unwrap(std::string &s, std::string_view prefix, std::string_view suffix);
174176

175177
std::string ReplaceAll(std::string str, std::string_view from,

cpp2rust/converter/mapper.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <clang/AST/ExprCXX.h>
77
#include <clang/Basic/SourceManager.h>
8+
#include <clang/Lex/Lexer.h>
89
#include <llvm/Support/ThreadPool.h>
910

1011
#include <format>
@@ -804,6 +805,16 @@ std::string ToString(const clang::Expr *expr) {
804805

805806
expr = expr->IgnoreParenImpCasts();
806807

808+
if (llvm::isa<clang::IntegerLiteral>(expr) &&
809+
expr->getBeginLoc().isMacroID()) {
810+
auto &sm = ctx_->getSourceManager();
811+
auto name = clang::Lexer::getImmediateMacroName(expr->getBeginLoc(), sm,
812+
ctx_->getLangOpts());
813+
if (!name.empty()) {
814+
return name.str();
815+
}
816+
}
817+
807818
if (const auto *CE = llvm::dyn_cast<clang::CallExpr>(expr)) {
808819
if (const auto *decl = CE->getDirectCallee()) {
809820
return ToString(decl);

cpp2rust/cpp_rule_preprocessor.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,13 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
170170
add(Mapper::ToString(decl));
171171
return;
172172
}
173+
if (const auto *lit =
174+
R.Nodes.getNodeAs<clang::IntegerLiteral>("macro_int")) {
175+
if (lit->getBeginLoc().isMacroID()) {
176+
add(Mapper::ToString(lit));
177+
}
178+
return;
179+
}
173180
}
174181
}
175182

@@ -668,7 +675,8 @@ class ActionFactory : public clang::tooling::FrontendActionFactory {
668675
declRefExpr(to(decl(unless(parmVarDecl()))))))
669676
.bind("udeclref"),
670677
cxxDependentScopeMemberExpr().bind("dsme"),
671-
cxxUnresolvedConstructExpr().bind("uctor"))))),
678+
cxxUnresolvedConstructExpr().bind("uctor"),
679+
integerLiteral().bind("macro_int"))))),
672680
hasAncestor(functionDecl(isDefinition(),
673681
matchesName("(^|::)f[0-9]+$"),
674682
isExpansionInMainFile())

rules/brotli/brotli/decode.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,9 @@ typedef enum {
8787
BROTLI_ERROR_CODE(_ERROR_FORMAT_, PADDING_1, -14) SEPARATOR \
8888
BROTLI_ERROR_CODE(_ERROR_FORMAT_, PADDING_2, -15) SEPARATOR \
8989
\
90-
/* -16..-19 codes are reserved */ \
90+
/* -16..-18 codes are reserved */ \
9191
\
92+
BROTLI_ERROR_CODE(_ERROR_, DICTIONARY_NOT_SET, -19) SEPARATOR \
9293
BROTLI_ERROR_CODE(_ERROR_, INVALID_ARGUMENTS, -20) SEPARATOR \
9394
\
9495
/* Memory allocation problems */ \

0 commit comments

Comments
 (0)