authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-02 12:35:19-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-02 12:35:19-05:00
log197509e1ec2d475fe646b3e1cde66a23df2520b3
tree06c4d32cd0bab4f9e5d0f424cabaf9d0966e0387
parent7bd80f207147167821634e16983edf9e9b115c9f
parentd908ca4823e51e8a9a413a3afac540e9e5295826
signaturelock-open Commit is signed but in an unrecognized format.

Merge LemonBoy's translate-c branch for linksection/align

closes #4034

5 files changed, 148 insertions(+), 7 deletions(-)

src-self-hosted/clang.zig+4
...@@ -764,6 +764,9 @@ pub extern fn ZigClangEnumDecl_getCanonicalDecl(self: ?*const struct_ZigClangEnu...@@ -764,6 +764,9 @@ pub extern fn ZigClangEnumDecl_getCanonicalDecl(self: ?*const struct_ZigClangEnu
764pub extern fn ZigClangTypedefNameDecl_getCanonicalDecl(self: ?*const struct_ZigClangTypedefNameDecl) ?*const struct_ZigClangTypedefNameDecl;764pub extern fn ZigClangTypedefNameDecl_getCanonicalDecl(self: ?*const struct_ZigClangTypedefNameDecl) ?*const struct_ZigClangTypedefNameDecl;
765pub extern fn ZigClangFunctionDecl_getCanonicalDecl(self: ?*const struct_ZigClangFunctionDecl) ?*const struct_ZigClangFunctionDecl;765pub extern fn ZigClangFunctionDecl_getCanonicalDecl(self: ?*const struct_ZigClangFunctionDecl) ?*const struct_ZigClangFunctionDecl;
766pub extern fn ZigClangVarDecl_getCanonicalDecl(self: ?*const struct_ZigClangVarDecl) ?*const struct_ZigClangVarDecl;766pub extern fn ZigClangVarDecl_getCanonicalDecl(self: ?*const struct_ZigClangVarDecl) ?*const struct_ZigClangVarDecl;
767pub extern fn ZigClangVarDecl_getSectionAttribute(self: *const ZigClangVarDecl, len: *usize) ?[*]const u8;
768pub extern fn ZigClangFunctionDecl_getAlignedAttribute(self: *const ZigClangFunctionDecl, *const ZigClangASTContext) c_uint;
769pub extern fn ZigClangVarDecl_getAlignedAttribute(self: *const ZigClangVarDecl, *const ZigClangASTContext) c_uint;
767pub extern fn ZigClangRecordDecl_getDefinition(self: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangRecordDecl;770pub extern fn ZigClangRecordDecl_getDefinition(self: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangRecordDecl;
768pub extern fn ZigClangEnumDecl_getDefinition(self: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangEnumDecl;771pub extern fn ZigClangEnumDecl_getDefinition(self: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangEnumDecl;
769pub extern fn ZigClangRecordDecl_getLocation(self: ?*const struct_ZigClangRecordDecl) struct_ZigClangSourceLocation;772pub extern fn ZigClangRecordDecl_getLocation(self: ?*const struct_ZigClangRecordDecl) struct_ZigClangSourceLocation;
...@@ -834,6 +837,7 @@ pub extern fn ZigClangFunctionDecl_getParamDecl(self: *const ZigClangFunctionDec...@@ -834,6 +837,7 @@ pub extern fn ZigClangFunctionDecl_getParamDecl(self: *const ZigClangFunctionDec
834pub extern fn ZigClangFunctionDecl_getBody(self: *const ZigClangFunctionDecl) *const struct_ZigClangStmt;837pub extern fn ZigClangFunctionDecl_getBody(self: *const ZigClangFunctionDecl) *const struct_ZigClangStmt;
835pub extern fn ZigClangFunctionDecl_doesDeclarationForceExternallyVisibleDefinition(self: *const ZigClangFunctionDecl) bool;838pub extern fn ZigClangFunctionDecl_doesDeclarationForceExternallyVisibleDefinition(self: *const ZigClangFunctionDecl) bool;
836pub extern fn ZigClangFunctionDecl_isInlineSpecified(self: *const ZigClangFunctionDecl) bool;839pub extern fn ZigClangFunctionDecl_isInlineSpecified(self: *const ZigClangFunctionDecl) bool;
840pub extern fn ZigClangFunctionDecl_getSectionAttribute(self: *const ZigClangFunctionDecl, len: *usize) ?[*]const u8;
837841
838pub extern fn ZigClangBuiltinType_getKind(self: *const struct_ZigClangBuiltinType) ZigClangBuiltinTypeKind;842pub extern fn ZigClangBuiltinType_getKind(self: *const struct_ZigClangBuiltinType) ZigClangBuiltinTypeKind;
839843
src-self-hosted/translate_c.zig+78-6
...@@ -581,6 +581,36 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {...@@ -581,6 +581,36 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
581 return failDecl(c, var_decl_loc, checked_name, "non-extern variable has no initializer", .{});581 return failDecl(c, var_decl_loc, checked_name, "non-extern variable has no initializer", .{});
582 }582 }
583583
584 const linksection_expr = blk: {
585 var str_len: usize = undefined;
586 if (ZigClangVarDecl_getSectionAttribute(var_decl, &str_len)) |str_ptr| {
587 _ = try appendToken(rp.c, .Keyword_linksection, "linksection");
588 _ = try appendToken(rp.c, .LParen, "(");
589 const expr = try transCreateNodeStringLiteral(
590 rp.c,
591 try std.fmt.allocPrint(rp.c.a(), "\"{}\"", .{str_ptr[0..str_len]}),
592 );
593 _ = try appendToken(rp.c, .RParen, ")");
594
595 break :blk expr;
596 }
597 break :blk null;
598 };
599
600 const align_expr = blk: {
601 const alignment = ZigClangVarDecl_getAlignedAttribute(var_decl, rp.c.clang_context);
602 if (alignment != 0) {
603 _ = try appendToken(rp.c, .Keyword_linksection, "align");
604 _ = try appendToken(rp.c, .LParen, "(");
605 // Clang reports the alignment in bits
606 const expr = try transCreateNodeInt(rp.c, alignment / 8);
607 _ = try appendToken(rp.c, .RParen, ")");
608
609 break :blk expr;
610 }
611 break :blk null;
612 };
613
584 const node = try c.a().create(ast.Node.VarDecl);614 const node = try c.a().create(ast.Node.VarDecl);
585 node.* = ast.Node.VarDecl{615 node.* = ast.Node.VarDecl{
586 .doc_comments = null,616 .doc_comments = null,
...@@ -593,8 +623,8 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {...@@ -593,8 +623,8 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
593 .extern_export_token = extern_tok,623 .extern_export_token = extern_tok,
594 .lib_name = null,624 .lib_name = null,
595 .type_node = type_node,625 .type_node = type_node,
596 .align_node = null,626 .align_node = align_expr,
597 .section_node = null,627 .section_node = linksection_expr,
598 .init_node = init_node,628 .init_node = init_node,
599 .semicolon_token = try appendToken(c, .Semicolon, ";"),629 .semicolon_token = try appendToken(c, .Semicolon, ";"),
600 };630 };
...@@ -3575,6 +3605,14 @@ fn transCreateNodeEnumLiteral(c: *Context, name: []const u8) !*ast.Node {...@@ -3575,6 +3605,14 @@ fn transCreateNodeEnumLiteral(c: *Context, name: []const u8) !*ast.Node {
3575 return &node.base;3605 return &node.base;
3576}3606}
35773607
3608fn transCreateNodeStringLiteral(c: *Context, str: []const u8) !*ast.Node {
3609 const node = try c.a().create(ast.Node.StringLiteral);
3610 node.* = .{
3611 .token = try appendToken(c, .StringLiteral, str),
3612 };
3613 return &node.base;
3614}
3615
3578fn transCreateNodeIf(c: *Context) !*ast.Node.If {3616fn transCreateNodeIf(c: *Context) !*ast.Node.If {
3579 const if_tok = try appendToken(c, .Keyword_if, "if");3617 const if_tok = try appendToken(c, .Keyword_if, "if");
3580 _ = try appendToken(c, .LParen, "(");3618 _ = try appendToken(c, .LParen, "(");
...@@ -4048,8 +4086,8 @@ fn finishTransFnProto(...@@ -4048,8 +4086,8 @@ fn finishTransFnProto(
4048 const noalias_tok = if (ZigClangQualType_isRestrictQualified(param_qt)) try appendToken(rp.c, .Keyword_noalias, "noalias") else null;4086 const noalias_tok = if (ZigClangQualType_isRestrictQualified(param_qt)) try appendToken(rp.c, .Keyword_noalias, "noalias") else null;
40494087
4050 const param_name_tok: ?ast.TokenIndex = blk: {4088 const param_name_tok: ?ast.TokenIndex = blk: {
4051 if (fn_decl != null) {4089 if (fn_decl) |decl| {
4052 const param = ZigClangFunctionDecl_getParamDecl(fn_decl.?, @intCast(c_uint, i));4090 const param = ZigClangFunctionDecl_getParamDecl(decl, @intCast(c_uint, i));
4053 const param_name: []const u8 = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, param)));4091 const param_name: []const u8 = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, param)));
4054 if (param_name.len < 1)4092 if (param_name.len < 1)
4055 break :blk null;4093 break :blk null;
...@@ -4100,6 +4138,40 @@ fn finishTransFnProto(...@@ -4100,6 +4138,40 @@ fn finishTransFnProto(
41004138
4101 const rparen_tok = try appendToken(rp.c, .RParen, ")");4139 const rparen_tok = try appendToken(rp.c, .RParen, ")");
41024140
4141 const linksection_expr = blk: {
4142 if (fn_decl) |decl| {
4143 var str_len: usize = undefined;
4144 if (ZigClangFunctionDecl_getSectionAttribute(decl, &str_len)) |str_ptr| {
4145 _ = try appendToken(rp.c, .Keyword_linksection, "linksection");
4146 _ = try appendToken(rp.c, .LParen, "(");
4147 const expr = try transCreateNodeStringLiteral(
4148 rp.c,
4149 try std.fmt.allocPrint(rp.c.a(), "\"{}\"", .{str_ptr[0..str_len]}),
4150 );
4151 _ = try appendToken(rp.c, .RParen, ")");
4152
4153 break :blk expr;
4154 }
4155 }
4156 break :blk null;
4157 };
4158
4159 const align_expr = blk: {
4160 if (fn_decl) |decl| {
4161 const alignment = ZigClangFunctionDecl_getAlignedAttribute(decl, rp.c.clang_context);
4162 if (alignment != 0) {
4163 _ = try appendToken(rp.c, .Keyword_linksection, "align");
4164 _ = try appendToken(rp.c, .LParen, "(");
4165 // Clang reports the alignment in bits
4166 const expr = try transCreateNodeInt(rp.c, alignment / 8);
4167 _ = try appendToken(rp.c, .RParen, ")");
4168
4169 break :blk expr;
4170 }
4171 }
4172 break :blk null;
4173 };
4174
4103 const return_type_node = blk: {4175 const return_type_node = blk: {
4104 if (ZigClangFunctionType_getNoReturnAttr(fn_ty)) {4176 if (ZigClangFunctionType_getNoReturnAttr(fn_ty)) {
4105 break :blk try transCreateNodeIdentifier(rp.c, "noreturn");4177 break :blk try transCreateNodeIdentifier(rp.c, "noreturn");
...@@ -4133,8 +4205,8 @@ fn finishTransFnProto(...@@ -4133,8 +4205,8 @@ fn finishTransFnProto(
4133 .cc_token = cc_tok,4205 .cc_token = cc_tok,
4134 .body_node = null,4206 .body_node = null,
4135 .lib_name = null,4207 .lib_name = null,
4136 .align_expr = null,4208 .align_expr = align_expr,
4137 .section_expr = null,4209 .section_expr = linksection_expr,
4138 };4210 };
4139 return fn_proto;4211 return fn_proto;
4140}4212}
src/zig_clang.cpp+40
...@@ -1582,6 +1582,36 @@ const ZigClangVarDecl *ZigClangVarDecl_getCanonicalDecl(const ZigClangVarDecl *s...@@ -1582,6 +1582,36 @@ const ZigClangVarDecl *ZigClangVarDecl_getCanonicalDecl(const ZigClangVarDecl *s
1582 return reinterpret_cast<const ZigClangVarDecl *>(decl);1582 return reinterpret_cast<const ZigClangVarDecl *>(decl);
1583}1583}
15841584
1585const char* ZigClangVarDecl_getSectionAttribute(const struct ZigClangVarDecl *self, size_t *len) {
1586 auto casted = reinterpret_cast<const clang::VarDecl *>(self);
1587 if (const clang::SectionAttr *SA = casted->getAttr<clang::SectionAttr>()) {
1588 llvm::StringRef str_ref = SA->getName();
1589 *len = str_ref.size();
1590 return (const char *)str_ref.bytes_begin();
1591 }
1592 return nullptr;
1593}
1594
1595unsigned ZigClangVarDecl_getAlignedAttribute(const struct ZigClangVarDecl *self, const ZigClangASTContext* ctx) {
1596 auto casted_self = reinterpret_cast<const clang::VarDecl *>(self);
1597 auto casted_ctx = const_cast<clang::ASTContext *>(reinterpret_cast<const clang::ASTContext *>(ctx));
1598 if (const clang::AlignedAttr *AA = casted_self->getAttr<clang::AlignedAttr>()) {
1599 return AA->getAlignment(*casted_ctx);
1600 }
1601 // Zero means no explicit alignment factor was specified
1602 return 0;
1603}
1604
1605unsigned ZigClangFunctionDecl_getAlignedAttribute(const struct ZigClangFunctionDecl *self, const ZigClangASTContext* ctx) {
1606 auto casted_self = reinterpret_cast<const clang::FunctionDecl *>(self);
1607 auto casted_ctx = const_cast<clang::ASTContext *>(reinterpret_cast<const clang::ASTContext *>(ctx));
1608 if (const clang::AlignedAttr *AA = casted_self->getAttr<clang::AlignedAttr>()) {
1609 return AA->getAlignment(*casted_ctx);
1610 }
1611 // Zero means no explicit alignment factor was specified
1612 return 0;
1613}
1614
1585const ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const ZigClangRecordDecl *zig_record_decl) {1615const ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const ZigClangRecordDecl *zig_record_decl) {
1586 const clang::RecordDecl *record_decl = reinterpret_cast<const clang::RecordDecl *>(zig_record_decl);1616 const clang::RecordDecl *record_decl = reinterpret_cast<const clang::RecordDecl *>(zig_record_decl);
1587 const clang::RecordDecl *definition = record_decl->getDefinition();1617 const clang::RecordDecl *definition = record_decl->getDefinition();
...@@ -1696,6 +1726,16 @@ bool ZigClangFunctionDecl_isInlineSpecified(const struct ZigClangFunctionDecl *s...@@ -1696,6 +1726,16 @@ bool ZigClangFunctionDecl_isInlineSpecified(const struct ZigClangFunctionDecl *s
1696 return casted->isInlineSpecified();1726 return casted->isInlineSpecified();
1697}1727}
16981728
1729const char* ZigClangFunctionDecl_getSectionAttribute(const struct ZigClangFunctionDecl *self, size_t *len) {
1730 auto casted = reinterpret_cast<const clang::FunctionDecl *>(self);
1731 if (const clang::SectionAttr *SA = casted->getAttr<clang::SectionAttr>()) {
1732 llvm::StringRef str_ref = SA->getName();
1733 *len = str_ref.size();
1734 return (const char *)str_ref.bytes_begin();
1735 }
1736 return nullptr;
1737}
1738
1699const ZigClangTypedefNameDecl *ZigClangTypedefType_getDecl(const ZigClangTypedefType *self) {1739const ZigClangTypedefNameDecl *ZigClangTypedefType_getDecl(const ZigClangTypedefType *self) {
1700 auto casted = reinterpret_cast<const clang::TypedefType *>(self);1740 auto casted = reinterpret_cast<const clang::TypedefType *>(self);
1701 const clang::TypedefNameDecl *name_decl = casted->getDecl();1741 const clang::TypedefNameDecl *name_decl = casted->getDecl();
src/zig_clang.h+4
...@@ -858,6 +858,9 @@ ZIG_EXTERN_C const struct ZigClangTagDecl *ZigClangEnumDecl_getCanonicalDecl(con...@@ -858,6 +858,9 @@ ZIG_EXTERN_C const struct ZigClangTagDecl *ZigClangEnumDecl_getCanonicalDecl(con
858ZIG_EXTERN_C const struct ZigClangTypedefNameDecl *ZigClangTypedefNameDecl_getCanonicalDecl(const struct ZigClangTypedefNameDecl *);858ZIG_EXTERN_C const struct ZigClangTypedefNameDecl *ZigClangTypedefNameDecl_getCanonicalDecl(const struct ZigClangTypedefNameDecl *);
859ZIG_EXTERN_C const struct ZigClangFunctionDecl *ZigClangFunctionDecl_getCanonicalDecl(const ZigClangFunctionDecl *self);859ZIG_EXTERN_C const struct ZigClangFunctionDecl *ZigClangFunctionDecl_getCanonicalDecl(const ZigClangFunctionDecl *self);
860ZIG_EXTERN_C const struct ZigClangVarDecl *ZigClangVarDecl_getCanonicalDecl(const ZigClangVarDecl *self);860ZIG_EXTERN_C const struct ZigClangVarDecl *ZigClangVarDecl_getCanonicalDecl(const ZigClangVarDecl *self);
861ZIG_EXTERN_C const char* ZigClangVarDecl_getSectionAttribute(const struct ZigClangVarDecl *self, size_t *len);
862ZIG_EXTERN_C unsigned ZigClangVarDecl_getAlignedAttribute(const struct ZigClangVarDecl *self, const ZigClangASTContext* ctx);
863ZIG_EXTERN_C unsigned ZigClangFunctionDecl_getAlignedAttribute(const struct ZigClangFunctionDecl *self, const ZigClangASTContext* ctx);
861864
862ZIG_EXTERN_C const struct ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const struct ZigClangRecordDecl *);865ZIG_EXTERN_C const struct ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const struct ZigClangRecordDecl *);
863ZIG_EXTERN_C const struct ZigClangEnumDecl *ZigClangEnumDecl_getDefinition(const struct ZigClangEnumDecl *);866ZIG_EXTERN_C const struct ZigClangEnumDecl *ZigClangEnumDecl_getDefinition(const struct ZigClangEnumDecl *);
...@@ -875,6 +878,7 @@ ZIG_EXTERN_C const struct ZigClangParmVarDecl *ZigClangFunctionDecl_getParamDecl...@@ -875,6 +878,7 @@ ZIG_EXTERN_C const struct ZigClangParmVarDecl *ZigClangFunctionDecl_getParamDecl
875ZIG_EXTERN_C const struct ZigClangStmt *ZigClangFunctionDecl_getBody(const struct ZigClangFunctionDecl *);878ZIG_EXTERN_C const struct ZigClangStmt *ZigClangFunctionDecl_getBody(const struct ZigClangFunctionDecl *);
876ZIG_EXTERN_C bool ZigClangFunctionDecl_doesDeclarationForceExternallyVisibleDefinition(const struct ZigClangFunctionDecl *);879ZIG_EXTERN_C bool ZigClangFunctionDecl_doesDeclarationForceExternallyVisibleDefinition(const struct ZigClangFunctionDecl *);
877ZIG_EXTERN_C bool ZigClangFunctionDecl_isInlineSpecified(const struct ZigClangFunctionDecl *);880ZIG_EXTERN_C bool ZigClangFunctionDecl_isInlineSpecified(const struct ZigClangFunctionDecl *);
881ZIG_EXTERN_C const char* ZigClangFunctionDecl_getSectionAttribute(const struct ZigClangFunctionDecl *, size_t *);
878882
879ZIG_EXTERN_C bool ZigClangRecordDecl_isUnion(const struct ZigClangRecordDecl *record_decl);883ZIG_EXTERN_C bool ZigClangRecordDecl_isUnion(const struct ZigClangRecordDecl *record_decl);
880ZIG_EXTERN_C bool ZigClangRecordDecl_isStruct(const struct ZigClangRecordDecl *record_decl);884ZIG_EXTERN_C bool ZigClangRecordDecl_isStruct(const struct ZigClangRecordDecl *record_decl);
test/translate_c.zig+22-1
...@@ -2,7 +2,6 @@ const tests = @import("tests.zig");...@@ -2,7 +2,6 @@ const tests = @import("tests.zig");
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub fn addCases(cases: *tests.TranslateCContext) void {4pub fn addCases(cases: *tests.TranslateCContext) void {
5 /////////////// Cases that pass for both stage1/stage2 ////////////////
6 cases.add("simple ptrCast for casts between opaque types",5 cases.add("simple ptrCast for casts between opaque types",
7 \\struct opaque;6 \\struct opaque;
8 \\struct opaque_2;7 \\struct opaque_2;
...@@ -18,6 +17,28 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -18,6 +17,28 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
18 \\}17 \\}
19 });18 });
2019
20 cases.add("align() attribute",
21 \\__attribute__ ((aligned(128)))
22 \\extern char my_array[16];
23 \\__attribute__ ((aligned(128)))
24 \\void my_fn(void) { }
25 , &[_][]const u8{
26 \\pub extern var my_array: [16]u8 align(128);
27 \\pub export fn my_fn() align(128) void {}
28 });
29
30 cases.add("linksection() attribute",
31 \\// Use the "segment,section" format to make this test pass when
32 \\// targeting the mach-o binary format
33 \\__attribute__ ((__section__("NEAR,.data")))
34 \\extern char my_array[16];
35 \\__attribute__ ((__section__("NEAR,.data")))
36 \\void my_fn(void) { }
37 , &[_][]const u8{
38 \\pub extern var my_array: [16]u8 linksection("NEAR,.data");
39 \\pub export fn my_fn() linksection("NEAR,.data") void {}
40 });
41
21 cases.add("simple function prototypes",42 cases.add("simple function prototypes",
22 \\void __attribute__((noreturn)) foo(void);43 \\void __attribute__((noreturn)) foo(void);
23 \\int bar(void);44 \\int bar(void);