Skip to content

Commit 36da8d0

Browse files
ehaasVexu
authored andcommitted
translate-c: translate global (file scope) assembly
1 parent 607abb5 commit 36da8d0

File tree

6 files changed

+62
-0
lines changed

6 files changed

+62
-0
lines changed

src/clang.zig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,11 @@ pub const TypedefNameDecl = opaque {
905905
extern fn ZigClangTypedefNameDecl_getLocation(*const TypedefNameDecl) SourceLocation;
906906
};
907907

908+
pub const FileScopeAsmDecl = opaque {
909+
pub const getAsmString = ZigClangFileScopeAsmDecl_getAsmString;
910+
extern fn ZigClangFileScopeAsmDecl_getAsmString(*const FileScopeAsmDecl) *const StringLiteral;
911+
};
912+
908913
pub const TypedefType = opaque {
909914
pub const getDecl = ZigClangTypedefType_getDecl;
910915
extern fn ZigClangTypedefType_getDecl(*const TypedefType) *const TypedefNameDecl;

src/translate_c.zig

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,13 +480,31 @@ fn declVisitor(c: *Context, decl: *const clang.Decl) Error!void {
480480
.Empty => {
481481
// Do nothing
482482
},
483+
.FileScopeAsm => {
484+
try transFileScopeAsm(c, &c.global_scope.base, @ptrCast(*const clang.FileScopeAsmDecl, decl));
485+
},
483486
else => {
484487
const decl_name = try c.str(decl.getDeclKindName());
485488
try warn(c, &c.global_scope.base, decl.getLocation(), "ignoring {s} declaration", .{decl_name});
486489
},
487490
}
488491
}
489492

493+
fn transFileScopeAsm(c: *Context, scope: *Scope, file_scope_asm: *const clang.FileScopeAsmDecl) Error!void {
494+
const asm_string = file_scope_asm.getAsmString();
495+
var len: usize = undefined;
496+
const bytes_ptr = asm_string.getString_bytes_begin_size(&len);
497+
498+
const str = try std.fmt.allocPrint(c.arena, "\"{}\"", .{std.zig.fmtEscapes(bytes_ptr[0..len])});
499+
const str_node = try Tag.string_literal.create(c.arena, str);
500+
501+
const asm_node = try Tag.asm_simple.create(c.arena, str_node);
502+
const block = try Tag.block_single.create(c.arena, asm_node);
503+
const comptime_node = try Tag.@"comptime".create(c.arena, block);
504+
505+
try scope.appendNode(comptime_node);
506+
}
507+
490508
fn visitFnDecl(c: *Context, fn_decl: *const clang.FunctionDecl) Error!void {
491509
const fn_name = try c.str(@ptrCast(*const clang.NamedDecl, fn_decl).getName_bytes_begin());
492510
if (c.global_scope.sym_table.contains(fn_name))

src/translate_c/ast.zig

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ pub const Node = extern union {
161161
/// @shuffle(type, a, b, mask)
162162
shuffle,
163163

164+
asm_simple,
165+
164166
negate,
165167
negate_wrap,
166168
bit_not,
@@ -245,6 +247,7 @@ pub const Node = extern union {
245247
.std_mem_zeroes,
246248
.@"return",
247249
.@"comptime",
250+
.asm_simple,
248251
.discard,
249252
.std_math_Log2Int,
250253
.negate,
@@ -1017,6 +1020,19 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
10171020
},
10181021
});
10191022
},
1023+
.asm_simple => {
1024+
const payload = node.castTag(.asm_simple).?.data;
1025+
const asm_token = try c.addToken(.keyword_asm, "asm");
1026+
_ = try c.addToken(.l_paren, "(");
1027+
return c.addNode(.{
1028+
.tag = .asm_simple,
1029+
.main_token = asm_token,
1030+
.data = .{
1031+
.lhs = try renderNode(c, payload),
1032+
.rhs = try c.addToken(.r_paren, ")"),
1033+
},
1034+
});
1035+
},
10201036
.type => {
10211037
const payload = node.castTag(.type).?.data;
10221038
return c.addNode(.{
@@ -2257,6 +2273,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
22572273
.@"continue",
22582274
.@"return",
22592275
.@"comptime",
2276+
.asm_simple,
22602277
.usingnamespace_builtins,
22612278
.while_true,
22622279
.if_not_break,

src/zig_clang.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1820,6 +1820,11 @@ const ZigClangEnumDecl *ZigClangEnumDecl_getDefinition(const ZigClangEnumDecl *z
18201820
return reinterpret_cast<const ZigClangEnumDecl *>(definition);
18211821
}
18221822

1823+
const ZigClangStringLiteral *ZigClangFileScopeAsmDecl_getAsmString(const ZigClangFileScopeAsmDecl *self) {
1824+
const clang::StringLiteral *result = reinterpret_cast<const clang::FileScopeAsmDecl*>(self)->getAsmString();
1825+
return reinterpret_cast<const ZigClangStringLiteral *>(result);
1826+
}
1827+
18231828
bool ZigClangRecordDecl_isUnion(const ZigClangRecordDecl *record_decl) {
18241829
return reinterpret_cast<const clang::RecordDecl*>(record_decl)->isUnion();
18251830
}

src/zig_clang.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ struct ZigClangEnumType;
124124
struct ZigClangExpr;
125125
struct ZigClangFieldDecl;
126126
struct ZigClangFileID;
127+
struct ZigClangFileScopeAsmDecl;
127128
struct ZigClangFloatingLiteral;
128129
struct ZigClangForStmt;
129130
struct ZigClangFullSourceLoc;
@@ -1000,6 +1001,8 @@ ZIG_EXTERN_C unsigned ZigClangVarDecl_getAlignedAttribute(const struct ZigClangV
10001001
ZIG_EXTERN_C unsigned ZigClangFunctionDecl_getAlignedAttribute(const struct ZigClangFunctionDecl *self, const ZigClangASTContext* ctx);
10011002
ZIG_EXTERN_C unsigned ZigClangFieldDecl_getAlignedAttribute(const struct ZigClangFieldDecl *self, const ZigClangASTContext* ctx);
10021003

1004+
ZIG_EXTERN_C const struct ZigClangStringLiteral *ZigClangFileScopeAsmDecl_getAsmString(const struct ZigClangFileScopeAsmDecl *self);
1005+
10031006
ZIG_EXTERN_C struct ZigClangQualType ZigClangParmVarDecl_getOriginalType(const struct ZigClangParmVarDecl *self);
10041007

10051008
ZIG_EXTERN_C bool ZigClangRecordDecl_getPackedAttribute(const struct ZigClangRecordDecl *);

test/translate_c.zig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3499,4 +3499,18 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
34993499
\\ '\u{1f4af}',
35003500
\\};
35013501
});
3502+
3503+
cases.add("global assembly",
3504+
\\__asm__(".globl func\n\t"
3505+
\\ ".type func, @function\n\t"
3506+
\\ "func:\n\t"
3507+
\\ ".cfi_startproc\n\t"
3508+
\\ "movl $42, %eax\n\t"
3509+
\\ "ret\n\t"
3510+
\\ ".cfi_endproc");
3511+
, &[_][]const u8{
3512+
\\comptime {
3513+
\\ asm (".globl func\n\t.type func, @function\n\tfunc:\n\t.cfi_startproc\n\tmovl $42, %eax\n\tret\n\t.cfi_endproc");
3514+
\\}
3515+
});
35023516
}

0 commit comments

Comments
 (0)