@@ -92,7 +92,7 @@ void Converter::EmitGlobalInits(Model model, std::string &out) {
9292
9393void Converter::EmitOpaqueRecords (std::string &out) {
9494 record_decls_.ForEachUndefined ([&](const std::string &name) {
95- out += " #[derive(Clone, Copy, Default, ByteRepr)]" ;
95+ out += " #[derive(Clone, Copy, Default, ByteRepr, VaArg, FnPtrArg )]" ;
9696 out += " pub struct " ;
9797 out += name;
9898 out += " ;\n " ;
@@ -151,61 +151,12 @@ std::string Converter::ConvertPointeeType(clang::QualType ptr_type) {
151151}
152152
153153bool Converter::VisitBuiltinType (clang::BuiltinType *type) {
154- switch (type->getKind ()) {
155- case clang::BuiltinType::Bool:
156- StrCat (" bool" );
157- break ;
158- case clang::BuiltinType::Float:
159- StrCat (" f32" );
160- break ;
161- case clang::BuiltinType::Double:
162- case clang::BuiltinType::LongDouble:
163- StrCat (" f64" );
164- break ;
165- case clang::BuiltinType::Char_S:
166- case clang::BuiltinType::Char_U:
167- StrCat (CharRustType ());
168- break ;
169- case clang::BuiltinType::SChar:
170- StrCat (" i8" );
171- break ;
172- case clang::BuiltinType::UChar:
173- StrCat (" u8" );
174- break ;
175- case clang::BuiltinType::UShort:
176- case clang::BuiltinType::UInt:
177- case clang::BuiltinType::ULong:
178- case clang::BuiltinType::ULongLong:
179- case clang::BuiltinType::Short:
180- case clang::BuiltinType::Int:
181- case clang::BuiltinType::Long:
182- case clang::BuiltinType::LongLong:
183- case clang::BuiltinType::WChar_S:
184- case clang::BuiltinType::WChar_U:
185- case clang::BuiltinType::Char8:
186- case clang::BuiltinType::Char16:
187- case clang::BuiltinType::Char32:
188- StrCat (std::format (" {}{}" , type->isSignedInteger () ? ' i' : ' u' ,
189- ctx_.getTypeSize (type)));
190- break ;
191- case clang::BuiltinType::Void:
192- StrCat (" ::libc::c_void" );
193- break ;
194- case clang::BuiltinType::UInt128:
195- StrCat (" u128" );
196- break ;
197- case clang::BuiltinType::Int128:
198- StrCat (" i128" );
199- break ;
200- case clang::BuiltinType::NullPtr:
201- Convert (ctx_.VoidPtrTy );
202- break ;
203- default :
204- llvm::errs () << " unsupported builtin type: "
205- << type->getName (ctx_.getPrintingPolicy ()) << ' \n ' ;
206- assert (0 && " unsupported builtin type\n " );
207- break ;
154+ auto mapped = Mapper::Map (clang::QualType (type, 0 ));
155+ if (mapped.empty ()) {
156+ llvm::report_fatal_error (llvm::Twine (" no type rule for builtin type: " ) +
157+ type->getName (ctx_.getPrintingPolicy ()));
208158 }
159+ StrCat (mapped);
209160 return false ;
210161}
211162
@@ -2507,11 +2458,6 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
25072458 case clang::CastKind::CK_BitCast: {
25082459 PushParen paren (*this );
25092460 Convert (sub_expr);
2510- if (type->isVoidPointerType ()) {
2511- StrCat (keyword::kAs ,
2512- type->getPointeeType ().isConstQualified () ? " *const" : " *mut" );
2513- StrCat (ConvertPointeeType (sub_expr->getType ()));
2514- }
25152461 ConvertCast (type);
25162462 SetFreshType (type);
25172463 break ;
@@ -3021,16 +2967,16 @@ bool Converter::VisitConditionalOperator(clang::ConditionalOperator *expr) {
30212967 return false ;
30222968}
30232969
3024- std::string Converter::ConvertDeclRefExpr (clang::DeclRefExpr *expr) {
2970+ std::string Converter::ConvertDeclRef (clang::Expr *expr,
2971+ clang::ValueDecl *decl) {
30252972 if (isAddrOf ()) {
30262973 clang::Expr *addrof_op = ToAddrOf (ctx_, expr);
30272974 if (auto str = GetMappedAsString (addrof_op); !str.empty ()) {
30282975 return str;
30292976 }
30302977 }
30312978
3032- auto *decl = expr->getDecl ();
3033- if (ShouldReplaceWithMappedBody (expr)) {
2979+ if (ShouldReplaceWithMappedBody (decl)) {
30342980 if (auto str = GetMappedAsString (expr); !str.empty ()) {
30352981 return str;
30362982 }
@@ -3053,7 +2999,8 @@ std::string Converter::ConvertDeclRefExpr(clang::DeclRefExpr *expr) {
30532999 return name;
30543000 }
30553001
3056- if (IsGlobalVar (expr)) {
3002+ if (auto *var = clang::dyn_cast<clang::VarDecl>(decl);
3003+ var && IsGlobalVar (var)) {
30573004 if (LazyStaticInit ()) {
30583005 return std::format (" (*std::cell::LazyCell::force_mut(&mut *&raw mut {}))" ,
30593006 GetNamedDeclAsString (decl));
@@ -3065,24 +3012,28 @@ std::string Converter::ConvertDeclRefExpr(clang::DeclRefExpr *expr) {
30653012}
30663013
30673014bool Converter::VisitDeclRefExpr (clang::DeclRefExpr *expr) {
3068- auto str = ConvertDeclRefExpr (expr);
3069- auto decl = expr->getDecl ();
3015+ ConvertDeclRefValue (expr, expr->getDecl ());
3016+ return false ;
3017+ }
3018+
3019+ void Converter::ConvertDeclRefValue (clang::Expr *expr, clang::ValueDecl *decl) {
3020+ auto str = ConvertDeclRef (expr, decl);
30703021
30713022 if (decl->getType ()->getAs <clang::ReferenceType>() && !isAddrOf () &&
30723023 !map_iter_decls_.contains (clang::dyn_cast<clang::VarDecl>(decl))) {
30733024 EmitDeref (std::move (str), decl->getType ().getNonReferenceType ());
30743025 SetValueFreshness (expr->getType ());
3075- return false ;
3026+ return ;
30763027 }
30773028
30783029 if (auto *fn_decl = clang::dyn_cast<clang::FunctionDecl>(decl)) {
30793030 if (isAddrOf ()) {
30803031 ConvertFunctionToFunctionPointer (fn_decl);
3081- return false ;
3032+ return ;
30823033 }
30833034 StrCat (str);
30843035 SetFreshType (expr->getType ());
3085- return false ;
3036+ return ;
30863037 }
30873038
30883039 if (auto var_decl = clang::dyn_cast<clang::VarDecl>(decl)) {
@@ -3093,7 +3044,7 @@ bool Converter::VisitDeclRefExpr(clang::DeclRefExpr *expr) {
30933044 PushParen paren (*this );
30943045 VisitLambdaExpr (lambda);
30953046 computed_expr_type_ = ComputedExprType::FreshValue;
3096- return false ;
3047+ return ;
30973048 }
30983049 }
30993050 }
@@ -3103,16 +3054,15 @@ bool Converter::VisitDeclRefExpr(clang::DeclRefExpr *expr) {
31033054 StrCat (token::kRef , decl->getType ().isConstQualified () ? " " : keyword_mut_,
31043055 str);
31053056 computed_expr_type_ = ComputedExprType::FreshPointer;
3106- return false ;
3057+ return ;
31073058 }
31083059
31093060 StrCat (str);
31103061 if (clang::isa<clang::EnumConstantDecl>(decl)) {
31113062 computed_expr_type_ = ComputedExprType::FreshValue;
3112- return false ;
3063+ return ;
31133064 }
31143065 SetValueFreshness (expr->getType ());
3115- return false ;
31163066}
31173067
31183068bool Converter::VisitParenExpr (clang::ParenExpr *expr) {
@@ -3196,6 +3146,10 @@ bool Converter::ConvertCXXOperatorCallExpr(clang::CXXOperatorCallExpr *expr) {
31963146
31973147bool Converter::VisitMemberExpr (clang::MemberExpr *expr) {
31983148 auto *member = expr->getMemberDecl ();
3149+ if (!member->isCXXInstanceMember ()) {
3150+ ConvertDeclRefValue (expr, member);
3151+ return false ;
3152+ }
31993153 if (auto *method = clang::dyn_cast<clang::CXXMethodDecl>(member);
32003154 method && IsMethodOnPtr (method) && !Mapper::Contains (expr)) {
32013155 SetUFCSReceiver (expr->getBase (), expr->isArrow (), method);
@@ -4034,10 +3988,6 @@ std::string Converter::GetArrayDefaultAsString(clang::QualType qual_type) {
40343988}
40353989
40363990std::string Converter::GetDefaultAsString (clang::QualType qual_type) {
4037- if (qual_type->isVoidType ()) {
4038- return " ()" ;
4039- }
4040-
40413991 if (IsVaListType (qual_type)) {
40423992 computed_expr_type_ = ComputedExprType::FreshValue;
40433993 return " VaList::default()" ;
@@ -4070,18 +4020,6 @@ std::string Converter::GetDefaultAsString(clang::QualType qual_type) {
40704020std::string Converter::GetDefaultAsStringFallback (clang::QualType qual_type) {
40714021 qual_type = qual_type.getUnqualifiedType ().getCanonicalType ();
40724022
4073- if (qual_type->isBooleanType ()) {
4074- return " false" ;
4075- }
4076-
4077- if (qual_type->isIntegerType () && !qual_type->isEnumeralType ()) {
4078- return getTypedLiteral (" 0" , ToString (qual_type));
4079- }
4080-
4081- if (qual_type->isFloatingType ()) {
4082- return getTypedLiteral (" 0.0" , ToString (qual_type));
4083- }
4084-
40854023 if (auto record = qual_type->getAsRecordDecl ()) {
40864024 if (ctx_.getSourceManager ().isInSystemHeader (record->getLocation ()) &&
40874025 qual_type.isPODType (ctx_)) {
@@ -4169,6 +4107,10 @@ Converter::GetStructAttributes(const clang::RecordDecl *decl) {
41694107 struct_attrs.emplace_back (" Clone" );
41704108 }
41714109
4110+ if (RecordImplementsClone (decl)) {
4111+ struct_attrs.emplace_back (" VaArg" );
4112+ }
4113+
41724114 if (RecordDerivesDefault (decl)) {
41734115 struct_attrs.emplace_back (" Default" );
41744116 }
@@ -4659,6 +4601,11 @@ void Converter::AddCloneTrait(const clang::RecordDecl *decl) {
46594601 : std::format (" as *mut {}" , record_name)));
46604602}
46614603
4604+ bool Converter::RecordImplementsClone (const clang::RecordDecl *decl) {
4605+ return HasDefaultedCopyConstructor (decl) ||
4606+ GetUserDefinedCopyConstructor (decl) != nullptr ;
4607+ }
4608+
46624609void Converter::AddDefaultTraitForUnion (const clang::RecordDecl *decl) {
46634610 StrCat (std::format (" impl Default for {}" , GetRecordName (decl)));
46644611 PushBrace impl_brace (*this );
@@ -5129,8 +5076,9 @@ bool Converter::isCallee() const {
51295076 return !curr_expr_kind_.empty () && curr_expr_kind_.back () == ExprKind::Callee;
51305077}
51315078
5132- bool Converter::ShouldReplaceWithMappedBody (clang::DeclRefExpr *expr) const {
5133- if (clang::isa<clang::FunctionDecl>(expr->getDecl ()) && isAddrOf ()) {
5079+ bool Converter::ShouldReplaceWithMappedBody (
5080+ const clang::ValueDecl *decl) const {
5081+ if (clang::isa<clang::FunctionDecl>(decl) && isAddrOf ()) {
51345082 return false ;
51355083 }
51365084 return true ;
0 commit comments