Commit c760532be0

Evan Haas <evan@lagerdata.com>
2021-03-07 22:34:27
translate-c: Add compound literal support
1 parent b988815
src/clang.zig
@@ -271,6 +271,11 @@ pub const CompoundAssignOperator = opaque {
     extern fn ZigClangCompoundAssignOperator_getRHS(*const CompoundAssignOperator) *const Expr;
 };
 
+pub const CompoundLiteralExpr = opaque {
+    pub const getInitializer = ZigClangCompoundLiteralExpr_getInitializer;
+    extern fn ZigClangCompoundLiteralExpr_getInitializer(*const CompoundLiteralExpr) *const Expr;
+};
+
 pub const CompoundStmt = opaque {
     pub const body_begin = ZigClangCompoundStmt_body_begin;
     extern fn ZigClangCompoundStmt_body_begin(*const CompoundStmt) ConstBodyIterator;
src/translate_c.zig
@@ -1054,6 +1054,10 @@ fn transStmt(
             return maybeSuppressResult(c, scope, result_used, expr);
         },
         .OffsetOfExprClass => return transOffsetOfExpr(c, scope, @ptrCast(*const clang.OffsetOfExpr, stmt), result_used),
+        .CompoundLiteralExprClass => {
+            const compound_literal = @ptrCast(*const clang.CompoundLiteralExpr, stmt);
+            return transExpr(c, scope, compound_literal.getInitializer(), result_used);
+        },
         else => {
             return fail(c, error.UnsupportedTranslation, stmt.getBeginLoc(), "TODO implement translation of stmt class {s}", .{@tagName(sc)});
         },
@@ -2560,8 +2564,8 @@ fn transConstantExpr(c: *Context, scope: *Scope, expr: *const clang.Expr, used:
             });
             return maybeSuppressResult(c, scope, used, as_node);
         },
-        else => {
-            return fail(c, error.UnsupportedTranslation, expr.getBeginLoc(), "unsupported constant expression kind", .{});
+        else => |kind| {
+            return fail(c, error.UnsupportedTranslation, expr.getBeginLoc(), "unsupported constant expression kind '{s}'", .{kind});
         },
     }
 }
src/zig_clang.cpp
@@ -2808,6 +2808,11 @@ const struct ZigClangExpr *ZigClangCompoundAssignOperator_getRHS(const struct Zi
     return reinterpret_cast<const struct ZigClangExpr *>(casted->getRHS());
 }
 
+const struct ZigClangExpr *ZigClangCompoundLiteralExpr_getInitializer(const ZigClangCompoundLiteralExpr *self) {
+    auto casted = reinterpret_cast<const clang::CompoundLiteralExpr *>(self);
+    return reinterpret_cast<const ZigClangExpr *>(casted->getInitializer());
+}
+
 enum ZigClangUO ZigClangUnaryOperator_getOpcode(const struct ZigClangUnaryOperator *self) {
     auto casted = reinterpret_cast<const clang::UnaryOperator *>(self);
     return (ZigClangUO)casted->getOpcode();
src/zig_clang.h
@@ -1217,6 +1217,8 @@ ZIG_EXTERN_C enum ZigClangBO ZigClangCompoundAssignOperator_getOpcode(const stru
 ZIG_EXTERN_C const struct ZigClangExpr *ZigClangCompoundAssignOperator_getLHS(const struct ZigClangCompoundAssignOperator *);
 ZIG_EXTERN_C const struct ZigClangExpr *ZigClangCompoundAssignOperator_getRHS(const struct ZigClangCompoundAssignOperator *);
 
+ZIG_EXTERN_C const struct ZigClangExpr *ZigClangCompoundLiteralExpr_getInitializer(const struct ZigClangCompoundLiteralExpr *);
+
 ZIG_EXTERN_C enum ZigClangUO ZigClangUnaryOperator_getOpcode(const struct ZigClangUnaryOperator *);
 ZIG_EXTERN_C struct ZigClangQualType ZigClangUnaryOperator_getType(const struct ZigClangUnaryOperator *);
 ZIG_EXTERN_C const struct ZigClangExpr *ZigClangUnaryOperator_getSubExpr(const struct ZigClangUnaryOperator *);
test/run_translated_c.zig
@@ -1171,4 +1171,20 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
         \\    return 0;
         \\}
     , "");
+
+    cases.add("Compound literals",
+        \\#include <stdlib.h>
+        \\struct Foo {
+        \\    int a;
+        \\    char b[2];
+        \\    float c;
+        \\};
+        \\int main() {
+        \\    struct Foo foo;
+        \\    int x = 1, y = 2;
+        \\    foo = (struct Foo) {x + y, {'a', 'b'}, 42.0f};
+        \\    if (foo.a != x + y || foo.b[0] != 'a' || foo.b[1] != 'b' || foo.c != 42.0f) abort();
+        \\    return 0;
+        \\}
+    , "");
 }