@@ -723,9 +723,8 @@ bool Converter::TypeDerivesDefault(clang::QualType qual_type) {
723723 return false ;
724724 }
725725
726- // Types that need a custom array initializer (e.g., std::array, which is
727- // translated to Vec)
728- if (!GetArrayDefaultAsString (qual_type).empty ()) {
726+ auto *cxx_record = qual_type->getAsCXXRecordDecl ();
727+ if (IsStdDecl (cxx_record, " array" ) || IsStdDecl (cxx_record, " basic_string" )) {
729728 return false ;
730729 }
731730
@@ -1373,6 +1372,9 @@ bool Converter::VisitDeclStmt(clang::DeclStmt *stmt) {
13731372 hoisted_records_ += std::move (buf).str ();
13741373 continue ;
13751374 }
1375+ if (var && IsAliasOfInit (ctx_, var)) {
1376+ continue ;
1377+ }
13761378 if (var && var->isImplicit ()) {
13771379 VisitVarDecl (var);
13781380 } else {
@@ -1488,112 +1490,25 @@ bool Converter::VisitForStmt(clang::ForStmt *stmt) {
14881490 return false ;
14891491}
14901492
1491- void Converter::ConvertLoopVariable (clang::VarDecl *decl,
1492- clang::Expr *range_init) {
1493- auto loop_var_type = decl->getType ();
1494- auto loop_var_name = GetNamedDeclAsString (decl);
1495-
1496- if (loop_var_type->isReferenceType ()) {
1497- auto pointee_type = loop_var_type->getPointeeType ();
1498- Convert (range_init);
1499- if (pointee_type.isConstQualified ()) {
1500- StrCat (std::format (" .as_ptr().add({})" , loop_var_name));
1501- } else {
1502- StrCat (std::format (" .as_mut_ptr().add({})" , loop_var_name));
1503- }
1504- } else {
1505- {
1506- PushExplicitAutoref autoref (*this , /* is_mut=*/ false );
1507- Convert (range_init);
1508- }
1509- StrCat (std::format (" [{}]" , loop_var_name));
1510- StrCat (" .clone()" );
1511- }
1512- }
1513-
1514- void Converter::ConvertForRangeBody (clang::CXXForRangeStmt *stmt) {
1515- PushBreakTarget push (break_target_, BreakTarget::Loop);
1516- curr_for_inc_.emplace_back (nullptr );
1517- ConvertBodyStmts (stmt->getBody ());
1518- curr_for_inc_.pop_back ();
1519- }
1520-
15211493bool Converter::VisitCXXForRangeStmt (clang::CXXForRangeStmt *stmt) {
1522- auto range_init_type = stmt->getRangeInit ()->getType ();
1523-
1524- if (!Mapper::Contains (ctx_, range_init_type.getUnqualifiedType ())) {
1525- // FIXME: improve error handling
1526- log () << " for range stmts only for types in std namespace\n " ;
1527- }
1528-
1529- log () << " GetClassName: " << GetClassName (range_init_type) << ' \n ' ;
1530-
1531- if (GetClassName (range_init_type) == " std::map" ) {
1532- return VisitCXXForRangeStmtMap (stmt);
1533- }
1534- if (GetClassName (range_init_type) == " std::basic_string" ) {
1535- return VisitCXXForRangeStmtString (stmt);
1536- }
1537- return VisitCXXForRangeStmtVector (stmt);
1538- }
1539-
1540- bool Converter::VisitCXXForRangeStmtMap (clang::CXXForRangeStmt *stmt) {
1541- auto begin =
1542- llvm::cast<clang::VarDecl>(stmt->getBeginStmt ()->getSingleDecl ());
1543-
1494+ PushBreakTarget push (break_target_, BreakTarget::Loop);
1495+ Convert (stmt->getInit ());
1496+ Convert (stmt->getRangeStmt ());
1497+ auto *begin =
1498+ clang::cast<clang::VarDecl>(stmt->getBeginStmt ()->getSingleDecl ());
1499+ auto *end = clang::cast<clang::VarDecl>(stmt->getEndStmt ()->getSingleDecl ());
1500+ begin->setDeclName (stmt->getLoopVariable ()->getDeclName ());
15441501 StrCat (" 'loop_:" );
1545- auto map_type = Mapper::Map (*this , stmt->getRangeInit ()->getType ());
15461502 StrCat (keyword::kFor , GetNamedDeclAsString (begin), keyword::kIn ,
1547- " UnsafeMap::range(&" );
1548- Convert (stmt->getRangeInit ());
1549- StrCat (std::format (" as *const {})" , map_type));
1503+ " IterRange::new(" , ConvertFreshRValue (begin->getInit ()), token::kComma ,
1504+ ConvertFreshRValue (end->getInit ()), ' )' );
15501505 {
15511506 PushBrace brace (*this );
1507+ curr_for_inc_.emplace_back (nullptr );
15521508 Convert (stmt->getLoopVarStmt ());
1553- ConvertForRangeBody (stmt);
1554- }
1555-
1556- return false ;
1557- }
1558-
1559- bool Converter::VisitCXXForRangeStmtString (clang::CXXForRangeStmt *stmt) {
1560- return VisitCXXForRangeStmtIndexBased (stmt, " len()-1" );
1561- }
1562-
1563- bool Converter::VisitCXXForRangeStmtVector (clang::CXXForRangeStmt *stmt) {
1564- return VisitCXXForRangeStmtIndexBased (stmt, " len()" );
1565- }
1566-
1567- bool Converter::VisitCXXForRangeStmtIndexBased (clang::CXXForRangeStmt *stmt,
1568- const char *len_suffix) {
1569- auto *loop_var = stmt->getLoopVariable ();
1570- auto loop_var_name = GetNamedDeclAsString (loop_var);
1571-
1572- StrCat (" 'loop_:" );
1573- StrCat (keyword::kFor , loop_var_name, keyword::kIn , " 0.." );
1574- {
1575- PushParen range (*this );
1576- Convert (stmt->getRangeInit ());
1577- StrCat (token::kDot , len_suffix);
1578- }
1579- {
1580- PushBrace body (*this );
1581- StrCat (keyword::kLet );
1582-
1583- auto loop_var_type = loop_var->getType ();
1584- if (!loop_var_type.isConstQualified ()) {
1585- StrCat (keyword_mut_);
1586- }
1587-
1588- StrCat (loop_var_name);
1589- StrCat (token::kAssign );
1590-
1591- ConvertLoopVariable (loop_var, stmt->getRangeInit ());
1592-
1593- StrCat (token::kSemiColon );
1594- ConvertForRangeBody (stmt);
1509+ ConvertBodyStmts (stmt->getBody ());
1510+ curr_for_inc_.pop_back ();
15951511 }
1596-
15971512 return false ;
15981513}
15991514
@@ -3269,6 +3184,11 @@ bool Converter::VisitDeclRefExpr(clang::DeclRefExpr *expr) {
32693184 Convert (init);
32703185 return false ;
32713186 }
3187+ if (auto var = clang::dyn_cast<clang::VarDecl>(expr->getDecl ());
3188+ var && IsAliasOfInit (ctx_, var)) {
3189+ Convert (var->getInit ());
3190+ return false ;
3191+ }
32723192 ConvertDeclRefValue (expr, expr->getDecl ());
32733193 return false ;
32743194}
@@ -3613,22 +3533,20 @@ bool Converter::VisitInitListExpr(clang::InitListExpr *expr) {
36133533 }
36143534 } else if (qual_type->isRecordType ()) {
36153535 const auto *record = qual_type->getAsRecordDecl ();
3616- if (record->getQualifiedNameAsString () == " std::array" ) {
3617- if (auto init = clang::dyn_cast<clang::InitListExpr>(expr->getInit (0 ))) {
3618- StrCat (" vec!" );
3619- VisitInitListExpr (init);
3620- } else {
3621- StrCat (GetArrayDefaultAsString (qual_type));
3622- }
3536+ if (syntactic->getNumInits () == 0 ) {
3537+ StrCat (GetDefaultAsString (qual_type));
36233538 SetFreshType (qual_type);
36243539 return false ;
36253540 }
36263541
3627- if (syntactic->getNumInits () == 0 ) {
3628- StrCat (GetDefaultAsString (qual_type));
3542+ if (auto str =
3543+ GetMappedAsString (expr, expr->getInits (), expr->getNumInits ());
3544+ !str.empty ()) {
3545+ StrCat (str);
36293546 SetFreshType (qual_type);
36303547 return false ;
36313548 }
3549+ assert (IsUserDefinedDecl (record) && " aggregate list without a rule" );
36323550
36333551 StrCat (GetUnsafeTypeAsString (qual_type));
36343552 PushBrace brace (*this );
@@ -4258,11 +4176,11 @@ bool Converter::VisitClassTemplateDecl(clang::ClassTemplateDecl *decl) {
42584176
42594177bool Converter::VisitCXXStdInitializerListExpr (
42604178 clang::CXXStdInitializerListExpr *expr) {
4261- if ( expr->getSubExpr ()-> getType ()-> isArrayType ()) {
4262- // Arrays become Vec's
4263- StrCat ( " vec! " );
4264- }
4265- Convert (expr->getSubExpr ());
4179+ auto *backing = expr->getSubExpr ();
4180+ auto str = GetMappedAsString (expr, &backing, 1 );
4181+ ENSURE (!str. empty () );
4182+ StrCat (str);
4183+ SetFreshType (expr->getType ());
42664184 return false ;
42674185}
42684186
@@ -4283,33 +4201,6 @@ std::string Converter::GetArrayDefaultAsString(clang::QualType qual_type) {
42834201 if (clang::isa<clang::IncompleteArrayType>(qual_type)) {
42844202 return " []" ;
42854203 }
4286- if (IsStdDecl (qual_type->getAsCXXRecordDecl (), " array" )) {
4287- assert (GetTemplateArgs (qual_type).has_value ());
4288- auto template_args = *GetTemplateArgs (qual_type);
4289- assert (template_args.size () == 2 );
4290- auto array_size = template_args[1 ];
4291- unsigned size = 0 ;
4292- switch (array_size.getKind ()) {
4293- case clang::TemplateArgument::Expression: {
4294- auto array_size_expr = array_size.getAsExpr ();
4295- assert (array_size_expr && !array_size_expr->isValueDependent ());
4296- clang::Expr::EvalResult result;
4297- ENSURE (array_size_expr->EvaluateAsInt (result, ctx_));
4298- size = result.Val .getInt ().getZExtValue ();
4299- break ;
4300- }
4301- case clang::TemplateArgument::Integral: {
4302- size = array_size.getAsIntegral ().getZExtValue ();
4303- break ;
4304- }
4305- default :
4306- assert (0 && " Unsupported array size kind" );
4307- break ;
4308- }
4309- return std::format (
4310- " std::array::from_fn::<_, {}, _>(|_| Default::default()).to_vec()" ,
4311- size);
4312- }
43134204 return {};
43144205}
43154206
0 commit comments