authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-02 11:33:26+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-02 12:32:51-05:00
log8e89bdfe991ebf643c6f35064a2e72de18feff9b
tree817be8192b4bea3127b6956490303ccbae1237e5
parent7bd80f207147167821634e16983edf9e9b115c9f
signature Commit is signed but in an unrecognized format.

Translate linksection attribute


5 files changed, 80 insertions(+), 5 deletions(-)

src-self-hosted/clang.zig+2
......@@ -764,6 +764,7 @@ pub extern fn ZigClangEnumDecl_getCanonicalDecl(self: ?*const struct_ZigClangEnu
764764pub extern fn ZigClangTypedefNameDecl_getCanonicalDecl(self: ?*const struct_ZigClangTypedefNameDecl) ?*const struct_ZigClangTypedefNameDecl;
765765pub extern fn ZigClangFunctionDecl_getCanonicalDecl(self: ?*const struct_ZigClangFunctionDecl) ?*const struct_ZigClangFunctionDecl;
766766pub extern fn ZigClangVarDecl_getCanonicalDecl(self: ?*const struct_ZigClangVarDecl) ?*const struct_ZigClangVarDecl;
767pub extern fn ZigClangVarDecl_getSectionAttribute(self: *const ZigClangVarDecl, len: *usize) ?[*]const u8;
767768pub extern fn ZigClangRecordDecl_getDefinition(self: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangRecordDecl;
768769pub extern fn ZigClangEnumDecl_getDefinition(self: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangEnumDecl;
769770pub extern fn ZigClangRecordDecl_getLocation(self: ?*const struct_ZigClangRecordDecl) struct_ZigClangSourceLocation;
......@@ -834,6 +835,7 @@ pub extern fn ZigClangFunctionDecl_getParamDecl(self: *const ZigClangFunctionDec
834835pub extern fn ZigClangFunctionDecl_getBody(self: *const ZigClangFunctionDecl) *const struct_ZigClangStmt;
835836pub extern fn ZigClangFunctionDecl_doesDeclarationForceExternallyVisibleDefinition(self: *const ZigClangFunctionDecl) bool;
836837pub extern fn ZigClangFunctionDecl_isInlineSpecified(self: *const ZigClangFunctionDecl) bool;
838pub extern fn ZigClangFunctionDecl_getSectionAttribute(self: *const ZigClangFunctionDecl, len: *usize) ?[*]const u8;
837839
838840pub extern fn ZigClangBuiltinType_getKind(self: *const struct_ZigClangBuiltinType) ZigClangBuiltinTypeKind;
839841
src-self-hosted/translate_c.zig+46-4
......@@ -581,6 +581,22 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
581581 return failDecl(c, var_decl_loc, checked_name, "non-extern variable has no initializer", .{});
582582 }
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
584600 const node = try c.a().create(ast.Node.VarDecl);
585601 node.* = ast.Node.VarDecl{
586602 .doc_comments = null,
......@@ -594,7 +610,7 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
594610 .lib_name = null,
595611 .type_node = type_node,
596612 .align_node = null,
597 .section_node = null,
613 .section_node = linksection_expr,
598614 .init_node = init_node,
599615 .semicolon_token = try appendToken(c, .Semicolon, ";"),
600616 };
......@@ -3575,6 +3591,14 @@ fn transCreateNodeEnumLiteral(c: *Context, name: []const u8) !*ast.Node {
35753591 return &node.base;
35763592}
35773593
3594fn transCreateNodeStringLiteral(c: *Context, str: []const u8) !*ast.Node {
3595 const node = try c.a().create(ast.Node.StringLiteral);
3596 node.* = .{
3597 .token = try appendToken(c, .StringLiteral, str),
3598 };
3599 return &node.base;
3600}
3601
35783602fn transCreateNodeIf(c: *Context) !*ast.Node.If {
35793603 const if_tok = try appendToken(c, .Keyword_if, "if");
35803604 _ = try appendToken(c, .LParen, "(");
......@@ -4048,8 +4072,8 @@ fn finishTransFnProto(
40484072 const noalias_tok = if (ZigClangQualType_isRestrictQualified(param_qt)) try appendToken(rp.c, .Keyword_noalias, "noalias") else null;
40494073
40504074 const param_name_tok: ?ast.TokenIndex = blk: {
4051 if (fn_decl != null) {
4052 const param = ZigClangFunctionDecl_getParamDecl(fn_decl.?, @intCast(c_uint, i));
4075 if (fn_decl) |decl| {
4076 const param = ZigClangFunctionDecl_getParamDecl(decl, @intCast(c_uint, i));
40534077 const param_name: []const u8 = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, param)));
40544078 if (param_name.len < 1)
40554079 break :blk null;
......@@ -4100,6 +4124,24 @@ fn finishTransFnProto(
41004124
41014125 const rparen_tok = try appendToken(rp.c, .RParen, ")");
41024126
4127 const linksection_expr = blk: {
4128 if (fn_decl) |decl| {
4129 var str_len: usize = undefined;
4130 if (ZigClangFunctionDecl_getSectionAttribute(decl, &str_len)) |str_ptr| {
4131 _ = try appendToken(rp.c, .Keyword_linksection, "linksection");
4132 _ = try appendToken(rp.c, .LParen, "(");
4133 const expr = try transCreateNodeStringLiteral(
4134 rp.c,
4135 try std.fmt.allocPrint(rp.c.a(), "\"{}\"", .{str_ptr[0..str_len]}),
4136 );
4137 _ = try appendToken(rp.c, .RParen, ")");
4138
4139 break :blk expr;
4140 }
4141 }
4142 break :blk null;
4143 };
4144
41034145 const return_type_node = blk: {
41044146 if (ZigClangFunctionType_getNoReturnAttr(fn_ty)) {
41054147 break :blk try transCreateNodeIdentifier(rp.c, "noreturn");
......@@ -4134,7 +4176,7 @@ fn finishTransFnProto(
41344176 .body_node = null,
41354177 .lib_name = null,
41364178 .align_expr = null,
4137 .section_expr = null,
4179 .section_expr = linksection_expr,
41384180 };
41394181 return fn_proto;
41404182}
src/zig_clang.cpp+20
......@@ -1582,6 +1582,16 @@ const ZigClangVarDecl *ZigClangVarDecl_getCanonicalDecl(const ZigClangVarDecl *s
15821582 return reinterpret_cast<const ZigClangVarDecl *>(decl);
15831583}
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
15851595const ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const ZigClangRecordDecl *zig_record_decl) {
15861596 const clang::RecordDecl *record_decl = reinterpret_cast<const clang::RecordDecl *>(zig_record_decl);
15871597 const clang::RecordDecl *definition = record_decl->getDefinition();
......@@ -1696,6 +1706,16 @@ bool ZigClangFunctionDecl_isInlineSpecified(const struct ZigClangFunctionDecl *s
16961706 return casted->isInlineSpecified();
16971707}
16981708
1709const char* ZigClangFunctionDecl_getSectionAttribute(const struct ZigClangFunctionDecl *self, size_t *len) {
1710 auto casted = reinterpret_cast<const clang::FunctionDecl *>(self);
1711 if (const clang::SectionAttr *SA = casted->getAttr<clang::SectionAttr>()) {
1712 llvm::StringRef str_ref = SA->getName();
1713 *len = str_ref.size();
1714 return (const char *)str_ref.bytes_begin();
1715 }
1716 return nullptr;
1717}
1718
16991719const ZigClangTypedefNameDecl *ZigClangTypedefType_getDecl(const ZigClangTypedefType *self) {
17001720 auto casted = reinterpret_cast<const clang::TypedefType *>(self);
17011721 const clang::TypedefNameDecl *name_decl = casted->getDecl();
src/zig_clang.h+2
......@@ -858,6 +858,7 @@ ZIG_EXTERN_C const struct ZigClangTagDecl *ZigClangEnumDecl_getCanonicalDecl(con
858858ZIG_EXTERN_C const struct ZigClangTypedefNameDecl *ZigClangTypedefNameDecl_getCanonicalDecl(const struct ZigClangTypedefNameDecl *);
859859ZIG_EXTERN_C const struct ZigClangFunctionDecl *ZigClangFunctionDecl_getCanonicalDecl(const ZigClangFunctionDecl *self);
860860ZIG_EXTERN_C const struct ZigClangVarDecl *ZigClangVarDecl_getCanonicalDecl(const ZigClangVarDecl *self);
861ZIG_EXTERN_C const char* ZigClangVarDecl_getSectionAttribute(const struct ZigClangVarDecl *self, size_t *len);
861862
862863ZIG_EXTERN_C const struct ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const struct ZigClangRecordDecl *);
863864ZIG_EXTERN_C const struct ZigClangEnumDecl *ZigClangEnumDecl_getDefinition(const struct ZigClangEnumDecl *);
......@@ -875,6 +876,7 @@ ZIG_EXTERN_C const struct ZigClangParmVarDecl *ZigClangFunctionDecl_getParamDecl
875876ZIG_EXTERN_C const struct ZigClangStmt *ZigClangFunctionDecl_getBody(const struct ZigClangFunctionDecl *);
876877ZIG_EXTERN_C bool ZigClangFunctionDecl_doesDeclarationForceExternallyVisibleDefinition(const struct ZigClangFunctionDecl *);
877878ZIG_EXTERN_C bool ZigClangFunctionDecl_isInlineSpecified(const struct ZigClangFunctionDecl *);
879ZIG_EXTERN_C const char* ZigClangFunctionDecl_getSectionAttribute(const struct ZigClangFunctionDecl *, size_t *);
878880
879881ZIG_EXTERN_C bool ZigClangRecordDecl_isUnion(const struct ZigClangRecordDecl *record_decl);
880882ZIG_EXTERN_C bool ZigClangRecordDecl_isStruct(const struct ZigClangRecordDecl *record_decl);
test/translate_c.zig+10-1
......@@ -2,7 +2,6 @@ const tests = @import("tests.zig");
22const builtin = @import("builtin");
33
44pub fn addCases(cases: *tests.TranslateCContext) void {
5 /////////////// Cases that pass for both stage1/stage2 ////////////////
65 cases.add("simple ptrCast for casts between opaque types",
76 \\struct opaque;
87 \\struct opaque_2;
......@@ -18,6 +17,16 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1817 \\}
1918 });
2019
20 cases.add("linksection() attribute",
21 \\__attribute__ ((__section__(".data")))
22 \\extern char my_array[16];
23 \\__attribute__ ((__section__(".data")))
24 \\void my_fn(void) { }
25 , &[_][]const u8{
26 \\pub extern var my_array: [16]u8 linksection(".data");
27 \\pub export fn my_fn() linksection(".data") void {}
28 });
29
2130 cases.add("simple function prototypes",
2231 \\void __attribute__((noreturn)) foo(void);
2332 \\int bar(void);