2222#include < utility>
2323#include < vector>
2424
25+ #include " absl/algorithm/container.h"
2526#include " absl/container/flat_hash_map.h"
2627#include " absl/status/status.h"
2728#include " absl/status/statusor.h"
4445namespace xls ::dslx {
4546namespace {
4647
48+ constexpr std::string_view kUniqueVarNamePrefix = " result" ;
49+
50+ std::string UniqueVarName (std::vector<std::string>& user_names) {
51+ std::string unique_name = std::string (kUniqueVarNamePrefix );
52+ if (!absl::c_contains (user_names, unique_name)) {
53+ return unique_name;
54+ }
55+ std::vector<std::string> existing_user_names = user_names;
56+ absl::c_sort (existing_user_names);
57+ // Appending a character avoids collision with previous names due to sorting.
58+ for (int64_t i = 0 ; i < existing_user_names.size (); ++i) {
59+ if (existing_user_names[i] == unique_name) {
60+ unique_name += " _" ;
61+ }
62+ }
63+ return unique_name;
64+ }
65+
4766absl::StatusOr<InterpValue> InterpretExpr (
4867 ImportData* import_data, TypeInfo* type_info, Expr* expr,
4968 const absl::flat_hash_map<std::string, InterpValue>& env) {
@@ -479,7 +498,8 @@ class StructCppTypeGenerator : public CppTypeGenerator {
479498 names.push_back (SanitizeCppName (struct_def->GetMemberName (i)));
480499 }
481500 return names;
482- }()) {}
501+ }()),
502+ tmp_var_name_ (UniqueVarName(cpp_member_names_)) {}
483503 ~StructCppTypeGenerator () override = default ;
484504
485505 static absl::StatusOr<std::unique_ptr<StructCppTypeGenerator>> Create (
@@ -566,14 +586,14 @@ class StructCppTypeGenerator : public CppTypeGenerator {
566586 " tuple of %d elements.\" );" ,
567587 struct_def_->size ()));
568588 pieces.push_back (" }" );
569- pieces.push_back (absl::StrFormat (" %s result ;" , cpp_type ()));
589+ pieces.push_back (absl::StrFormat (" %s %s ;" , cpp_type (), tmp_var_name_ ));
570590 for (int i = 0 ; i < struct_def_->members ().size (); i++) {
571591 std::string assignment = member_emitters_[i]->AssignFromValue (
572- /* lhs=*/ absl::StrFormat (" result .%s" , cpp_member_names_[i]),
592+ /* lhs=*/ absl::StrFormat (" %s .%s" , tmp_var_name_ , cpp_member_names_[i]),
573593 /* rhs=*/ absl::StrFormat (" value.element(%d)" , i), /* nesting=*/ 0 );
574594 pieces.push_back (assignment);
575595 }
576- pieces.push_back (" return result; " );
596+ pieces.push_back (absl::StrFormat ( " return %s; " , tmp_var_name_) );
577597 std::string body = absl::StrJoin (pieces, " \n " );
578598
579599 return CppSource{
@@ -588,16 +608,18 @@ class StructCppTypeGenerator : public CppTypeGenerator {
588608
589609 CppSource ToValueMethod () const {
590610 std::vector<std::string> pieces;
591- pieces.push_back (" std::vector<::xls::Value> members;" );
592611 pieces.push_back (
593- absl::StrFormat (" members.resize(%d);" , struct_def_->members ().size ()));
612+ absl::StrFormat (" std::vector<::xls::Value> %s;" , tmp_var_name_));
613+ pieces.push_back (absl::StrFormat (" %s.resize(%d);" , tmp_var_name_,
614+ struct_def_->members ().size ()));
594615 for (int i = 0 ; i < struct_def_->members ().size (); i++) {
595616 std::string assignment = member_emitters_[i]->AssignToValue (
596- /* lhs=*/ absl::StrFormat (" members [%d]" , i),
617+ /* lhs=*/ absl::StrFormat (" %s [%d]" , tmp_var_name_ , i),
597618 /* rhs=*/ cpp_member_names_[i], /* nesting=*/ 0 );
598619 pieces.push_back (assignment);
599620 }
600- pieces.push_back (" return ::xls::Value::Tuple(members);" );
621+ pieces.push_back (
622+ absl::StrFormat (" return ::xls::Value::Tuple(%s);" , tmp_var_name_));
601623 std::string body = absl::StrJoin (pieces, " \n " );
602624
603625 return CppSource{
@@ -627,18 +649,18 @@ class StructCppTypeGenerator : public CppTypeGenerator {
627649
628650 CppSource ToStringMethod () const {
629651 std::vector<std::string> pieces;
630- pieces.push_back (
631- absl::StrFormat ( " std::string result = \" %s { \\ n \" ; " , cpp_type ()));
652+ pieces.push_back (absl::StrFormat ( " std::string %s = \" %s { \\ n \" ; " ,
653+ tmp_var_name_ , cpp_type ()));
632654 for (int i = 0 ; i < struct_def_->members ().size (); i++) {
633- pieces.push_back (absl::StrFormat (
634- " result += __indent(indent + 1) + \" %s: \" ; " , cpp_member_names_[i]));
655+ pieces.push_back (absl::StrFormat (" %s += __indent(indent + 1) + \" %s: \" ; " ,
656+ tmp_var_name_ , cpp_member_names_[i]));
635657 std::string to_string = member_emitters_[i]->ToString (
636- " result " , " indent + 2" , cpp_member_names_[i], /* nesting=*/ 0 );
658+ tmp_var_name_ , " indent + 2" , cpp_member_names_[i], /* nesting=*/ 0 );
637659 pieces.push_back (to_string);
638- pieces.push_back (" result += \" ,\\ n\" ;" );
660+ pieces.push_back (tmp_var_name_ + " += \" ,\\ n\" ;" );
639661 }
640- pieces.push_back (" result += __indent(indent) + \" }\" ;" );
641- pieces.push_back (" return result; " );
662+ pieces.push_back (tmp_var_name_ + " += __indent(indent) + \" }\" ;" );
663+ pieces.push_back (absl::StrFormat ( " return %s; " , tmp_var_name_) );
642664 std::string body = absl::StrJoin (pieces, " \n " );
643665
644666 return CppSource{.header = " std::string ToString(int indent = 0) const;" ,
@@ -649,18 +671,18 @@ class StructCppTypeGenerator : public CppTypeGenerator {
649671
650672 CppSource ToDslxStringMethod () const {
651673 std::vector<std::string> pieces;
652- pieces.push_back (
653- absl::StrFormat ( " std::string result = \" %s { \\ n \" ; " , dslx_type ()));
674+ pieces.push_back (absl::StrFormat ( " std::string %s = \" %s { \\ n \" ; " ,
675+ tmp_var_name_ , dslx_type ()));
654676 for (int i = 0 ; i < struct_def_->members ().size (); i++) {
655- pieces.push_back (absl::StrFormat (
656- " result += __indent(indent + 1) + \" %s: \" ; " , cpp_member_names_[i]));
677+ pieces.push_back (absl::StrFormat (" %s += __indent(indent + 1) + \" %s: \" ; " ,
678+ tmp_var_name_ , cpp_member_names_[i]));
657679 std::string to_string = member_emitters_[i]->ToDslxString (
658- " result " , " indent + 2" , cpp_member_names_[i], /* nesting=*/ 0 );
680+ tmp_var_name_ , " indent + 2" , cpp_member_names_[i], /* nesting=*/ 0 );
659681 pieces.push_back (to_string);
660- pieces.push_back (" result += \" ,\\ n\" ;" );
682+ pieces.push_back (tmp_var_name_ + " += \" ,\\ n\" ;" );
661683 }
662- pieces.push_back (" result += __indent(indent) + \" }\" ;" );
663- pieces.push_back (" return result; " );
684+ pieces.push_back (tmp_var_name_ + " += __indent(indent) + \" }\" ;" );
685+ pieces.push_back (absl::StrFormat ( " return %s; " , tmp_var_name_) );
664686 std::string body = absl::StrJoin (pieces, " \n " );
665687
666688 return CppSource{
@@ -712,6 +734,9 @@ class StructCppTypeGenerator : public CppTypeGenerator {
712734 const StructDef* struct_def_;
713735 std::vector<std::unique_ptr<CppEmitter>> member_emitters_;
714736 std::vector<std::string> cpp_member_names_;
737+ // The name of temporary variables in generated code that do not collide with
738+ // user defined member names.
739+ std::string tmp_var_name_;
715740};
716741
717742} // namespace
0 commit comments