Repository: hylo-lang/hylo (swift)

Issue:
Fix member access translation in tests
Expression `if (b.value == 0) { c } else { d }` is currently translated to C++ as `value == 0 ? c : d`. Note that `b` is missing.

Fix translation for this case.

Pull request:
Fix #514

Patch:
diff --git a/Sources/CodeGen/CXX/CXXTranspiler.swift b/Sources/CodeGen/CXX/CXXTranspiler.swift
index 58df6ec3e..5ae960da9 100644
--- a/Sources/CodeGen/CXX/CXXTranspiler.swift
+++ b/Sources/CodeGen/CXX/CXXTranspiler.swift
@@ -513,17 +513,18 @@ public struct CXXTranspiler {
         return CXXIdentifier(nameOfDecl(callee))
       }
 
-    case .direct(let callee):
-      // For variables, and other declarations, just use the name of the declaration
-      return CXXIdentifier(nameOfDecl(callee))
+    case .direct(let callee), .member(let callee):
+      let r = CXXIdentifier(nameOfDecl(callee))
+      switch source.domain {
+      case .expr(let base):
+        return CXXInfixExpr(oper: .dotAccess, lhs: cxx(expr: base), rhs: r)
+      default:
+        return r
+      }
 
     case .member(let callee) where callee.kind == FunctionDecl.self:
       return cxx(nameOfMemberFunction: FunctionDecl.Typed(callee)!, withDomain: source.domain)
 
-    case .member(let callee):
-      // TODO: revisit this
-      return CXXIdentifier(nameOfDecl(callee))
-
     case .builtinFunction(let f):
       guard case .llvm(let n) = f.name else { fatalError("not implemented") }
       return CXXIdentifier("native_\(n)")


Test patch:
diff --git a/Tests/ValTests/TestCases/CXX/Decl/Methods.val b/Tests/ValTests/TestCases/CXX/Decl/Methods.val
index bded0702c..2e93fe6da 100644
--- a/Tests/ValTests/TestCases/CXX/Decl/Methods.val
+++ b/Tests/ValTests/TestCases/CXX/Decl/Methods.val
@@ -18,8 +18,7 @@ type MyInt {
 
   //! h Int sumWith(MyInt x, MyInt y, MyInt z) {
   fun sumWith(x: MyInt, y: MyInt, z: MyInt) -> Int {
-    // TODO
-    //! h return value + value + value + value
+    //! h return value + x . value + y . value + z . value
     return value + x.value + y.value + z.value
   }
 
diff --git a/Tests/ValTests/TestCases/CXX/Expr/PostfixOperators.val b/Tests/ValTests/TestCases/CXX/Expr/PostfixOperators.val
index 6613b53c4..32cd66ccf 100644
--- a/Tests/ValTests/TestCases/CXX/Expr/PostfixOperators.val
+++ b/Tests/ValTests/TestCases/CXX/Expr/PostfixOperators.val
@@ -1,10 +1,11 @@
 /*! cpp
 void test() {
   MyInt a;
-  a = a++;
-  a = a--;
+  a = a . u2bu2b();
+  a = a . u2du2d();
 }
 */
+// TODO: postfix ++ and --
 
 type MyInt: Sinkable {
   let value: Int
diff --git a/Tests/ValTests/TestCases/CXX/Expr/Precedence.val b/Tests/ValTests/TestCases/CXX/Expr/Precedence.val
index e5f97de25..6706108bc 100644
--- a/Tests/ValTests/TestCases/CXX/Expr/Precedence.val
+++ b/Tests/ValTests/TestCases/CXX/Expr/Precedence.val
@@ -111,7 +111,6 @@ fun cxxPrecedenceTest() {
   let _ = (a | b) & c ^ d
 
   // ternary operator
-  //! cpp a + (value == 0 ? c : d)
+  //! cpp a + (b . value == 0 ? c : d)
   let _ = a + if (b.value == 0) { c } else { d }
-  // TODO: above we need to translate `b.value`, not just `value`
 }
diff --git a/Tests/ValTests/TestCases/CXX/Expr/PrefixOperators.val b/Tests/ValTests/TestCases/CXX/Expr/PrefixOperators.val
index d5b7af43e..85a8c32a3 100644
--- a/Tests/ValTests/TestCases/CXX/Expr/PrefixOperators.val
+++ b/Tests/ValTests/TestCases/CXX/Expr/PrefixOperators.val
@@ -1,10 +1,11 @@
 /*! cpp
 void test() {
   Int a = 5;
-  a = +a;
-  a = -a;
+  a = a . u2b();
+  a = a . u2d();
 }
 */
+// TODO: fix prefix + and -
 
 fun test() {
   var a = 5
diff --git a/Tests/ValTests/TestCases/CXXCoreLibrary/GeneratedConstructors.val b/Tests/ValTests/TestCases/CXXCoreLibrary/GeneratedConstructors.val
index 23124aa53..44ac726a2 100644
--- a/Tests/ValTests/TestCases/CXXCoreLibrary/GeneratedConstructors.val
+++ b/Tests/ValTests/TestCases/CXXCoreLibrary/GeneratedConstructors.val
@@ -1,14 +1,14 @@
-//! h Int() { value = native_zeroinitializer_i64(); }
+//! h Int() { (*this) . value = native_zeroinitializer_i64(); }
 
-//! h Bool() { value = native_zeroinitializer_i1(); }
+//! h Bool() { (*this) . value = native_zeroinitializer_i1(); }
 
-//! h Double() { value = native_zeroinitializer_double(); }
+//! h Double() { (*this) . value = native_zeroinitializer_double(); }
 
-//! h Float() { value = native_zeroinitializer_float(); }
-//! h Float(Double other) { *this = Float(native_fptrunc_double_float(value)); }
+//! h Float() { (*this) . value = native_zeroinitializer_float(); }
+//! h Float(Double other) { *this = Float(native_fptrunc_double_float(other . value)); }
 
-//! h Int32() { value = native_zeroinitializer_i32(); }
-//! h Int32(Int other) { *this = Int32(native_trunc_i64_i32(value)); }
+//! h Int32() { (*this) . value = native_zeroinitializer_i32(); }
+//! h Int32(Int other) { *this = Int32(native_trunc_i64_i32(other . value)); }
 
-//! h Int8() { value = native_zeroinitializer_i8(); }
-//! h Int8(Int other) { *this = Int8(native_trunc_i64_i8(value)); }
+//! h Int8() { (*this) . value = native_zeroinitializer_i8(); }
+//! h Int8(Int other) { *this = Int8(native_trunc_i64_i8(other . value)); }