mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
translate-c-2 member access
This commit is contained in:
parent
e65b9e8f7b
commit
cf7a5b7a4a
@ -27,6 +27,7 @@ pub const CToken = struct {
|
|||||||
Lt,
|
Lt,
|
||||||
Comma,
|
Comma,
|
||||||
Fn,
|
Fn,
|
||||||
|
Arrow,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const NumLitSuffix = enum {
|
pub const NumLitSuffix = enum {
|
||||||
@ -164,6 +165,8 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
|
|||||||
NumLitIntSuffixL,
|
NumLitIntSuffixL,
|
||||||
NumLitIntSuffixLL,
|
NumLitIntSuffixLL,
|
||||||
NumLitIntSuffixUL,
|
NumLitIntSuffixUL,
|
||||||
|
Minus,
|
||||||
|
Done,
|
||||||
} = .Start;
|
} = .Start;
|
||||||
|
|
||||||
var result = CToken{
|
var result = CToken{
|
||||||
@ -178,9 +181,6 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
|
|||||||
const c = chars[i.*];
|
const c = chars[i.*];
|
||||||
if (c == 0) {
|
if (c == 0) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
.Start => {
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
.Identifier,
|
.Identifier,
|
||||||
.Decimal,
|
.Decimal,
|
||||||
.Hex,
|
.Hex,
|
||||||
@ -193,6 +193,9 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
|
|||||||
result.bytes = chars[begin_index..i.*];
|
result.bytes = chars[begin_index..i.*];
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
.Start,
|
||||||
|
.Minus,
|
||||||
|
.Done,
|
||||||
.NumLitIntSuffixU,
|
.NumLitIntSuffixU,
|
||||||
.NumLitIntSuffixL,
|
.NumLitIntSuffixL,
|
||||||
.NumLitIntSuffixUL,
|
.NumLitIntSuffixUL,
|
||||||
@ -212,7 +215,6 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
|
|||||||
=> return error.TokenizingFailed,
|
=> return error.TokenizingFailed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i.* += 1;
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
.Start => {
|
.Start => {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
@ -220,12 +222,12 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
|
|||||||
'\'' => {
|
'\'' => {
|
||||||
state = .CharLit;
|
state = .CharLit;
|
||||||
result.id = .CharLit;
|
result.id = .CharLit;
|
||||||
begin_index = i.* - 1;
|
begin_index = i.*;
|
||||||
},
|
},
|
||||||
'\"' => {
|
'\"' => {
|
||||||
state = .String;
|
state = .String;
|
||||||
result.id = .StrLit;
|
result.id = .StrLit;
|
||||||
begin_index = i.* - 1;
|
begin_index = i.*;
|
||||||
},
|
},
|
||||||
'/' => {
|
'/' => {
|
||||||
state = .OpenComment;
|
state = .OpenComment;
|
||||||
@ -239,21 +241,21 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
|
|||||||
'a'...'z', 'A'...'Z', '_' => {
|
'a'...'z', 'A'...'Z', '_' => {
|
||||||
state = .Identifier;
|
state = .Identifier;
|
||||||
result.id = .Identifier;
|
result.id = .Identifier;
|
||||||
begin_index = i.* - 1;
|
begin_index = i.*;
|
||||||
},
|
},
|
||||||
'1'...'9' => {
|
'1'...'9' => {
|
||||||
state = .Decimal;
|
state = .Decimal;
|
||||||
result.id = .NumLitInt;
|
result.id = .NumLitInt;
|
||||||
begin_index = i.* - 1;
|
begin_index = i.*;
|
||||||
},
|
},
|
||||||
'0' => {
|
'0' => {
|
||||||
state = .GotZero;
|
state = .GotZero;
|
||||||
result.id = .NumLitInt;
|
result.id = .NumLitInt;
|
||||||
begin_index = i.* - 1;
|
begin_index = i.*;
|
||||||
},
|
},
|
||||||
'.' => {
|
'.' => {
|
||||||
result.id = .Dot;
|
result.id = .Dot;
|
||||||
return result;
|
state = .Done;
|
||||||
},
|
},
|
||||||
'<' => {
|
'<' => {
|
||||||
result.id = .Lt;
|
result.id = .Lt;
|
||||||
@ -261,40 +263,52 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
|
|||||||
},
|
},
|
||||||
'(' => {
|
'(' => {
|
||||||
result.id = .LParen;
|
result.id = .LParen;
|
||||||
return result;
|
state = .Done;
|
||||||
},
|
},
|
||||||
')' => {
|
')' => {
|
||||||
result.id = .RParen;
|
result.id = .RParen;
|
||||||
return result;
|
state = .Done;
|
||||||
},
|
},
|
||||||
'*' => {
|
'*' => {
|
||||||
result.id = .Asterisk;
|
result.id = .Asterisk;
|
||||||
return result;
|
state = .Done;
|
||||||
},
|
},
|
||||||
'-' => {
|
'-' => {
|
||||||
|
state = .Minus;
|
||||||
result.id = .Minus;
|
result.id = .Minus;
|
||||||
return result;
|
|
||||||
},
|
},
|
||||||
'!' => {
|
'!' => {
|
||||||
result.id = .Bang;
|
result.id = .Bang;
|
||||||
return result;
|
state = .Done;
|
||||||
},
|
},
|
||||||
'~' => {
|
'~' => {
|
||||||
result.id = .Tilde;
|
result.id = .Tilde;
|
||||||
return result;
|
state = .Done;
|
||||||
},
|
},
|
||||||
',' => {
|
',' => {
|
||||||
result.id = .Comma;
|
result.id = .Comma;
|
||||||
return result;
|
state = .Done;
|
||||||
},
|
},
|
||||||
else => return error.TokenizingFailed,
|
else => return error.TokenizingFailed,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
.Done => return result,
|
||||||
|
.Minus => {
|
||||||
|
switch (c) {
|
||||||
|
'>' => {
|
||||||
|
result.id = .Arrow;
|
||||||
|
state = .Done;
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
.GotLt => {
|
.GotLt => {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
'<' => {
|
'<' => {
|
||||||
result.id = .Shl;
|
result.id = .Shl;
|
||||||
return result;
|
state = .Done;
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
return result;
|
return result;
|
||||||
@ -310,19 +324,16 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
|
|||||||
'f',
|
'f',
|
||||||
'F',
|
'F',
|
||||||
=> {
|
=> {
|
||||||
i.* -= 1;
|
|
||||||
result.num_lit_suffix = .F;
|
result.num_lit_suffix = .F;
|
||||||
result.bytes = chars[begin_index..i.*];
|
result.bytes = chars[begin_index..i.*];
|
||||||
return result;
|
state = .Done;
|
||||||
},
|
},
|
||||||
'l', 'L' => {
|
'l', 'L' => {
|
||||||
i.* -= 1;
|
|
||||||
result.num_lit_suffix = .L;
|
result.num_lit_suffix = .L;
|
||||||
result.bytes = chars[begin_index..i.*];
|
result.bytes = chars[begin_index..i.*];
|
||||||
return result;
|
state = .Done;
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
i.* -= 1;
|
|
||||||
result.bytes = chars[begin_index..i.*];
|
result.bytes = chars[begin_index..i.*];
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
@ -352,16 +363,15 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
|
|||||||
'0'...'9' => {},
|
'0'...'9' => {},
|
||||||
'f', 'F' => {
|
'f', 'F' => {
|
||||||
result.num_lit_suffix = .F;
|
result.num_lit_suffix = .F;
|
||||||
result.bytes = chars[begin_index .. i.* - 1];
|
result.bytes = chars[begin_index..i.*];
|
||||||
return result;
|
state = .Done;
|
||||||
},
|
},
|
||||||
'l', 'L' => {
|
'l', 'L' => {
|
||||||
result.num_lit_suffix = .L;
|
result.num_lit_suffix = .L;
|
||||||
result.bytes = chars[begin_index .. i.* - 1];
|
result.bytes = chars[begin_index..i.*];
|
||||||
return result;
|
state = .Done;
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
i.* -= 1;
|
|
||||||
result.bytes = chars[begin_index..i.*];
|
result.bytes = chars[begin_index..i.*];
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
@ -374,19 +384,18 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
|
|||||||
'u', 'U' => {
|
'u', 'U' => {
|
||||||
state = .NumLitIntSuffixU;
|
state = .NumLitIntSuffixU;
|
||||||
result.num_lit_suffix = .U;
|
result.num_lit_suffix = .U;
|
||||||
result.bytes = chars[begin_index .. i.* - 1];
|
result.bytes = chars[begin_index..i.*];
|
||||||
},
|
},
|
||||||
'l', 'L' => {
|
'l', 'L' => {
|
||||||
state = .NumLitIntSuffixL;
|
state = .NumLitIntSuffixL;
|
||||||
result.num_lit_suffix = .L;
|
result.num_lit_suffix = .L;
|
||||||
result.bytes = chars[begin_index .. i.* - 1];
|
result.bytes = chars[begin_index..i.*];
|
||||||
},
|
},
|
||||||
'.' => {
|
'.' => {
|
||||||
result.id = .NumLitFloat;
|
result.id = .NumLitFloat;
|
||||||
state = .Float;
|
state = .Float;
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
i.* -= 1;
|
|
||||||
result.bytes = chars[begin_index..i.*];
|
result.bytes = chars[begin_index..i.*];
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
@ -407,12 +416,12 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
|
|||||||
'u', 'U' => {
|
'u', 'U' => {
|
||||||
state = .NumLitIntSuffixU;
|
state = .NumLitIntSuffixU;
|
||||||
result.num_lit_suffix = .U;
|
result.num_lit_suffix = .U;
|
||||||
result.bytes = chars[begin_index .. i.* - 1];
|
result.bytes = chars[begin_index..i.*];
|
||||||
},
|
},
|
||||||
'l', 'L' => {
|
'l', 'L' => {
|
||||||
state = .NumLitIntSuffixL;
|
state = .NumLitIntSuffixL;
|
||||||
result.num_lit_suffix = .L;
|
result.num_lit_suffix = .L;
|
||||||
result.bytes = chars[begin_index .. i.* - 1];
|
result.bytes = chars[begin_index..i.*];
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
i.* -= 1;
|
i.* -= 1;
|
||||||
@ -425,7 +434,6 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
|
|||||||
'0'...'7' => {},
|
'0'...'7' => {},
|
||||||
'8', '9' => return error.TokenizingFailed,
|
'8', '9' => return error.TokenizingFailed,
|
||||||
else => {
|
else => {
|
||||||
i.* -= 1;
|
|
||||||
result.bytes = chars[begin_index..i.*];
|
result.bytes = chars[begin_index..i.*];
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
@ -438,16 +446,15 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
|
|||||||
// marks the number literal as unsigned
|
// marks the number literal as unsigned
|
||||||
state = .NumLitIntSuffixU;
|
state = .NumLitIntSuffixU;
|
||||||
result.num_lit_suffix = .U;
|
result.num_lit_suffix = .U;
|
||||||
result.bytes = chars[begin_index .. i.* - 1];
|
result.bytes = chars[begin_index..i.*];
|
||||||
},
|
},
|
||||||
'l', 'L' => {
|
'l', 'L' => {
|
||||||
// marks the number literal as long
|
// marks the number literal as long
|
||||||
state = .NumLitIntSuffixL;
|
state = .NumLitIntSuffixL;
|
||||||
result.num_lit_suffix = .L;
|
result.num_lit_suffix = .L;
|
||||||
result.bytes = chars[begin_index .. i.* - 1];
|
result.bytes = chars[begin_index..i.*];
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
i.* -= 1;
|
|
||||||
result.bytes = chars[begin_index..i.*];
|
result.bytes = chars[begin_index..i.*];
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
@ -461,16 +468,15 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
|
|||||||
// marks the number literal as unsigned
|
// marks the number literal as unsigned
|
||||||
state = .NumLitIntSuffixU;
|
state = .NumLitIntSuffixU;
|
||||||
result.num_lit_suffix = .U;
|
result.num_lit_suffix = .U;
|
||||||
result.bytes = chars[begin_index .. i.* - 1];
|
result.bytes = chars[begin_index..i.*];
|
||||||
},
|
},
|
||||||
'l', 'L' => {
|
'l', 'L' => {
|
||||||
// marks the number literal as long
|
// marks the number literal as long
|
||||||
state = .NumLitIntSuffixL;
|
state = .NumLitIntSuffixL;
|
||||||
result.num_lit_suffix = .L;
|
result.num_lit_suffix = .L;
|
||||||
result.bytes = chars[begin_index .. i.* - 1];
|
result.bytes = chars[begin_index..i.*];
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
i.* -= 1;
|
|
||||||
result.bytes = chars[begin_index..i.*];
|
result.bytes = chars[begin_index..i.*];
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
@ -483,7 +489,6 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
|
|||||||
state = .NumLitIntSuffixUL;
|
state = .NumLitIntSuffixUL;
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
i.* -= 1;
|
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -496,10 +501,9 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
|
|||||||
},
|
},
|
||||||
'u', 'U' => {
|
'u', 'U' => {
|
||||||
result.num_lit_suffix = .LU;
|
result.num_lit_suffix = .LU;
|
||||||
return result;
|
state = .Done;
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
i.* -= 1;
|
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -508,10 +512,9 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
|
|||||||
switch (c) {
|
switch (c) {
|
||||||
'u', 'U' => {
|
'u', 'U' => {
|
||||||
result.num_lit_suffix = .LLU;
|
result.num_lit_suffix = .LLU;
|
||||||
return result;
|
state = .Done;
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
i.* -= 1;
|
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -523,7 +526,6 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
|
|||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
i.* -= 1;
|
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -532,17 +534,16 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
|
|||||||
switch (c) {
|
switch (c) {
|
||||||
'_', 'a'...'z', 'A'...'Z', '0'...'9' => {},
|
'_', 'a'...'z', 'A'...'Z', '0'...'9' => {},
|
||||||
else => {
|
else => {
|
||||||
i.* -= 1;
|
|
||||||
result.bytes = chars[begin_index..i.*];
|
result.bytes = chars[begin_index..i.*];
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.String => { // TODO char escapes
|
.String => {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
'\"' => {
|
'\"' => {
|
||||||
result.bytes = chars[begin_index..i.*];
|
result.bytes = chars[begin_index .. i.* + 1];
|
||||||
return result;
|
state = .Done;
|
||||||
},
|
},
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
@ -550,8 +551,8 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
|
|||||||
.CharLit => {
|
.CharLit => {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
'\'' => {
|
'\'' => {
|
||||||
result.bytes = chars[begin_index..i.*];
|
result.bytes = chars[begin_index .. i.* + 1];
|
||||||
return result;
|
state = .Done;
|
||||||
},
|
},
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
@ -566,7 +567,7 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
|
|||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
result.id = .Slash;
|
result.id = .Slash;
|
||||||
return result;
|
state = .Done;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -598,6 +599,7 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
i.* += 1;
|
||||||
}
|
}
|
||||||
unreachable;
|
unreachable;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1096,5 +1096,9 @@ pub extern fn ZigClangCharacterLiteral_getBeginLoc(*const ZigClangCharacterLiter
|
|||||||
pub extern fn ZigClangCharacterLiteral_getKind(*const ZigClangCharacterLiteral) ZigClangCharacterLiteral_CharacterKind;
|
pub extern fn ZigClangCharacterLiteral_getKind(*const ZigClangCharacterLiteral) ZigClangCharacterLiteral_CharacterKind;
|
||||||
pub extern fn ZigClangCharacterLiteral_getValue(*const ZigClangCharacterLiteral) c_uint;
|
pub extern fn ZigClangCharacterLiteral_getValue(*const ZigClangCharacterLiteral) c_uint;
|
||||||
|
|
||||||
pub extern fn ZigClangStmtExpr_getSubStmt( *const ZigClangStmtExpr) *const ZigClangCompoundStmt;
|
pub extern fn ZigClangStmtExpr_getSubStmt(*const ZigClangStmtExpr) *const ZigClangCompoundStmt;
|
||||||
|
|
||||||
|
pub extern fn ZigClangMemberExpr_getBase(*const ZigClangMemberExpr) *const ZigClangExpr;
|
||||||
|
pub extern fn ZigClangMemberExpr_isArrow(*const ZigClangMemberExpr) bool;
|
||||||
|
pub extern fn ZigClangMemberExpr_getMemberDecl(*const ZigClangMemberExpr) *const ZigClangValueDecl;
|
||||||
|
|
||||||
|
|||||||
@ -49,9 +49,6 @@ const Scope = struct {
|
|||||||
Root,
|
Root,
|
||||||
Condition,
|
Condition,
|
||||||
FnDef,
|
FnDef,
|
||||||
|
|
||||||
/// used when getting a member `a.b`
|
|
||||||
Ref,
|
|
||||||
Loop,
|
Loop,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -181,7 +178,6 @@ const Scope = struct {
|
|||||||
fn getAlias(scope: *Scope, name: []const u8) ?[]const u8 {
|
fn getAlias(scope: *Scope, name: []const u8) ?[]const u8 {
|
||||||
return switch (scope.id) {
|
return switch (scope.id) {
|
||||||
.Root => null,
|
.Root => null,
|
||||||
.Ref => null,
|
|
||||||
.FnDef => @fieldParentPtr(FnDef, "base", scope).getAlias(name),
|
.FnDef => @fieldParentPtr(FnDef, "base", scope).getAlias(name),
|
||||||
.Block => @fieldParentPtr(Block, "base", scope).getAlias(name),
|
.Block => @fieldParentPtr(Block, "base", scope).getAlias(name),
|
||||||
.Switch, .Loop, .Condition => scope.parent.?.getAlias(name),
|
.Switch, .Loop, .Condition => scope.parent.?.getAlias(name),
|
||||||
@ -190,7 +186,6 @@ const Scope = struct {
|
|||||||
|
|
||||||
fn contains(scope: *Scope, name: []const u8) bool {
|
fn contains(scope: *Scope, name: []const u8) bool {
|
||||||
return switch (scope.id) {
|
return switch (scope.id) {
|
||||||
.Ref => false,
|
|
||||||
.Root => @fieldParentPtr(Root, "base", scope).contains(name),
|
.Root => @fieldParentPtr(Root, "base", scope).contains(name),
|
||||||
.FnDef => @fieldParentPtr(FnDef, "base", scope).contains(name),
|
.FnDef => @fieldParentPtr(FnDef, "base", scope).contains(name),
|
||||||
.Block => @fieldParentPtr(Block, "base", scope).contains(name),
|
.Block => @fieldParentPtr(Block, "base", scope).contains(name),
|
||||||
@ -230,7 +225,6 @@ const Context = struct {
|
|||||||
decl_table: DeclTable,
|
decl_table: DeclTable,
|
||||||
alias_list: AliasList,
|
alias_list: AliasList,
|
||||||
global_scope: *Scope.Root,
|
global_scope: *Scope.Root,
|
||||||
ptr_params: std.BufSet,
|
|
||||||
clang_context: *ZigClangASTContext,
|
clang_context: *ZigClangASTContext,
|
||||||
mangle_count: u64 = 0,
|
mangle_count: u64 = 0,
|
||||||
|
|
||||||
@ -316,7 +310,6 @@ pub fn translate(
|
|||||||
.decl_table = DeclTable.init(arena),
|
.decl_table = DeclTable.init(arena),
|
||||||
.alias_list = AliasList.init(arena),
|
.alias_list = AliasList.init(arena),
|
||||||
.global_scope = try arena.create(Scope.Root),
|
.global_scope = try arena.create(Scope.Root),
|
||||||
.ptr_params = std.BufSet.init(arena),
|
|
||||||
.clang_context = ZigClangASTUnit_getASTContext(ast_unit).?,
|
.clang_context = ZigClangASTUnit_getASTContext(ast_unit).?,
|
||||||
};
|
};
|
||||||
context.global_scope.* = Scope.Root.init(&context);
|
context.global_scope.* = Scope.Root.init(&context);
|
||||||
@ -856,6 +849,7 @@ fn transStmt(
|
|||||||
.PredefinedExprClass => return transPredefinedExpr(rp, scope, @ptrCast(*const ZigClangPredefinedExpr, stmt), result_used),
|
.PredefinedExprClass => return transPredefinedExpr(rp, scope, @ptrCast(*const ZigClangPredefinedExpr, stmt), result_used),
|
||||||
.CharacterLiteralClass => return transCharLiteral(rp, scope, @ptrCast(*const ZigClangCharacterLiteral, stmt), result_used),
|
.CharacterLiteralClass => return transCharLiteral(rp, scope, @ptrCast(*const ZigClangCharacterLiteral, stmt), result_used),
|
||||||
.StmtExprClass => return transStmtExpr(rp, scope, @ptrCast(*const ZigClangStmtExpr, stmt), result_used),
|
.StmtExprClass => return transStmtExpr(rp, scope, @ptrCast(*const ZigClangStmtExpr, stmt), result_used),
|
||||||
|
.MemberExprClass => return transMemberExpr(rp, scope, @ptrCast(*const ZigClangMemberExpr, stmt), result_used),
|
||||||
else => {
|
else => {
|
||||||
return revertAndWarn(
|
return revertAndWarn(
|
||||||
rp,
|
rp,
|
||||||
@ -1147,7 +1141,6 @@ fn transDeclRefExpr(
|
|||||||
const value_decl = ZigClangDeclRefExpr_getDecl(expr);
|
const value_decl = ZigClangDeclRefExpr_getDecl(expr);
|
||||||
const name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, value_decl)));
|
const name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, value_decl)));
|
||||||
const checked_name = if (scope.getAlias(name)) |a| a else name;
|
const checked_name = if (scope.getAlias(name)) |a| a else name;
|
||||||
if (lrvalue == .l_value) try rp.c.ptr_params.put(checked_name);
|
|
||||||
return transCreateNodeIdentifier(rp.c, checked_name);
|
return transCreateNodeIdentifier(rp.c, checked_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1990,6 +1983,18 @@ fn transStmtExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangStmtExpr,
|
|||||||
return maybeSuppressResult(rp, scope, used, &grouped_expr.base);
|
return maybeSuppressResult(rp, scope, used, &grouped_expr.base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn transMemberExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangMemberExpr, result_used: ResultUsed) TransError!*ast.Node {
|
||||||
|
var container_node = try transExpr(rp, scope, ZigClangMemberExpr_getBase(stmt), .used, .r_value);
|
||||||
|
|
||||||
|
if (ZigClangMemberExpr_isArrow(stmt)) {
|
||||||
|
container_node = try transCreateNodePtrDeref(rp.c, container_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
const name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, ZigClangMemberExpr_getMemberDecl(stmt))));
|
||||||
|
const node = try transCreateNodeFieldAccess(rp.c, container_node, name);
|
||||||
|
return maybeSuppressResult(rp, scope, result_used, node);
|
||||||
|
}
|
||||||
|
|
||||||
fn transCPtrCast(
|
fn transCPtrCast(
|
||||||
rp: RestorePoint,
|
rp: RestorePoint,
|
||||||
loc: ZigClangSourceLocation,
|
loc: ZigClangSourceLocation,
|
||||||
@ -2213,8 +2218,8 @@ fn qualTypeToLog2IntRef(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigC
|
|||||||
import_fn_call.rparen_token = try appendToken(rp.c, .RParen, ")");
|
import_fn_call.rparen_token = try appendToken(rp.c, .RParen, ")");
|
||||||
|
|
||||||
const inner_field_access = try transCreateNodeFieldAccess(rp.c, &import_fn_call.base, "math");
|
const inner_field_access = try transCreateNodeFieldAccess(rp.c, &import_fn_call.base, "math");
|
||||||
const outer_field_access = try transCreateNodeFieldAccess(rp.c, &inner_field_access.base, "Log2Int");
|
const outer_field_access = try transCreateNodeFieldAccess(rp.c, inner_field_access, "Log2Int");
|
||||||
const log2int_fn_call = try transCreateNodeFnCall(rp.c, &outer_field_access.base);
|
const log2int_fn_call = try transCreateNodeFnCall(rp.c, outer_field_access);
|
||||||
try @ptrCast(*ast.Node.SuffixOp.Op.Call, &log2int_fn_call.op).params.push(zig_type_node);
|
try @ptrCast(*ast.Node.SuffixOp.Op.Call, &log2int_fn_call.op).params.push(zig_type_node);
|
||||||
log2int_fn_call.rtoken = try appendToken(rp.c, .RParen, ")");
|
log2int_fn_call.rtoken = try appendToken(rp.c, .RParen, ")");
|
||||||
|
|
||||||
@ -2446,7 +2451,7 @@ fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node) !*ast.Node.SuffixOp {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transCreateNodeFieldAccess(c: *Context, container: *ast.Node, field_name: []const u8) !*ast.Node.InfixOp {
|
fn transCreateNodeFieldAccess(c: *Context, container: *ast.Node, field_name: []const u8) !*ast.Node {
|
||||||
const field_access_node = try c.a().create(ast.Node.InfixOp);
|
const field_access_node = try c.a().create(ast.Node.InfixOp);
|
||||||
field_access_node.* = .{
|
field_access_node.* = .{
|
||||||
.op_token = try appendToken(c, .Period, "."),
|
.op_token = try appendToken(c, .Period, "."),
|
||||||
@ -2454,7 +2459,7 @@ fn transCreateNodeFieldAccess(c: *Context, container: *ast.Node, field_name: []c
|
|||||||
.op = .Period,
|
.op = .Period,
|
||||||
.rhs = try transCreateNodeIdentifier(c, field_name),
|
.rhs = try transCreateNodeIdentifier(c, field_name),
|
||||||
};
|
};
|
||||||
return field_access_node;
|
return &field_access_node.base;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transCreateNodePrefixOp(
|
fn transCreateNodePrefixOp(
|
||||||
@ -2924,9 +2929,9 @@ fn transCreateNodeShiftOp(
|
|||||||
rp: RestorePoint,
|
rp: RestorePoint,
|
||||||
scope: *Scope,
|
scope: *Scope,
|
||||||
stmt: *const ZigClangBinaryOperator,
|
stmt: *const ZigClangBinaryOperator,
|
||||||
comptime op: ast.Node.InfixOp.Op,
|
op: ast.Node.InfixOp.Op,
|
||||||
comptime op_tok_id: std.zig.Token.Id,
|
op_tok_id: std.zig.Token.Id,
|
||||||
comptime bytes: []const u8,
|
bytes: []const u8,
|
||||||
) !*ast.Node {
|
) !*ast.Node {
|
||||||
std.debug.assert(op == .BitShiftLeft or op == .BitShiftRight);
|
std.debug.assert(op == .BitShiftLeft or op == .BitShiftRight);
|
||||||
|
|
||||||
@ -2957,6 +2962,16 @@ fn transCreateNodeShiftOp(
|
|||||||
return &node.base;
|
return &node.base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn transCreateNodePtrDeref(c: *Context, lhs: *ast.Node) !*ast.Node {
|
||||||
|
const node = try c.a().create(ast.Node.SuffixOp);
|
||||||
|
node.* = .{
|
||||||
|
.lhs = .{ .node = lhs },
|
||||||
|
.op = .Deref,
|
||||||
|
.rtoken = try appendToken(c, .PeriodAsterisk, ".*"),
|
||||||
|
};
|
||||||
|
return &node.base;
|
||||||
|
}
|
||||||
|
|
||||||
const RestorePoint = struct {
|
const RestorePoint = struct {
|
||||||
c: *Context,
|
c: *Context,
|
||||||
token_index: ast.TokenIndex,
|
token_index: ast.TokenIndex,
|
||||||
@ -3862,16 +3877,21 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc
|
|||||||
.{},
|
.{},
|
||||||
);
|
);
|
||||||
|
|
||||||
const op_token = try appendToken(rp.c, .Period, ".");
|
node = try transCreateNodeFieldAccess(rp.c, node, name_tok.bytes);
|
||||||
const rhs = try transCreateNodeIdentifier(rp.c, name_tok.bytes);
|
},
|
||||||
const access_node = try rp.c.a().create(ast.Node.InfixOp);
|
.Arrow => {
|
||||||
access_node.* = .{
|
const name_tok = it.next().?;
|
||||||
.op_token = op_token,
|
if (name_tok.id != .Identifier)
|
||||||
.lhs = node,
|
return revertAndWarn(
|
||||||
.op = .Period,
|
rp,
|
||||||
.rhs = rhs,
|
error.ParseError,
|
||||||
};
|
source_loc,
|
||||||
node = &access_node.base;
|
"unable to translate C expr",
|
||||||
|
.{},
|
||||||
|
);
|
||||||
|
|
||||||
|
const deref = try transCreateNodePtrDeref(rp.c, node);
|
||||||
|
node = try transCreateNodeFieldAccess(rp.c, deref, name_tok.bytes);
|
||||||
},
|
},
|
||||||
.Asterisk => {
|
.Asterisk => {
|
||||||
if (it.peek().?.id == .RParen) {
|
if (it.peek().?.id == .RParen) {
|
||||||
@ -3887,14 +3907,14 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc
|
|||||||
// expr * expr
|
// expr * expr
|
||||||
const op_token = try appendToken(rp.c, .Asterisk, "*");
|
const op_token = try appendToken(rp.c, .Asterisk, "*");
|
||||||
const rhs = try parseCPrimaryExpr(rp, it, source_loc, scope);
|
const rhs = try parseCPrimaryExpr(rp, it, source_loc, scope);
|
||||||
const bitshift_node = try rp.c.a().create(ast.Node.InfixOp);
|
const mul_node = try rp.c.a().create(ast.Node.InfixOp);
|
||||||
bitshift_node.* = .{
|
mul_node.* = .{
|
||||||
.op_token = op_token,
|
.op_token = op_token,
|
||||||
.lhs = node,
|
.lhs = node,
|
||||||
.op = .BitShiftLeft,
|
.op = .BitShiftLeft,
|
||||||
.rhs = rhs,
|
.rhs = rhs,
|
||||||
};
|
};
|
||||||
node = &bitshift_node.base;
|
node = &mul_node.base;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.Shl => {
|
.Shl => {
|
||||||
@ -3938,13 +3958,7 @@ fn parseCPrefixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc
|
|||||||
},
|
},
|
||||||
.Asterisk => {
|
.Asterisk => {
|
||||||
const prefix_op_expr = try parseCPrefixOpExpr(rp, it, source_loc, scope);
|
const prefix_op_expr = try parseCPrefixOpExpr(rp, it, source_loc, scope);
|
||||||
const node = try rp.c.a().create(ast.Node.SuffixOp);
|
return try transCreateNodePtrDeref(rp.c, prefix_op_expr);
|
||||||
node.* = .{
|
|
||||||
.lhs = .{ .node = prefix_op_expr },
|
|
||||||
.op = .Deref,
|
|
||||||
.rtoken = try appendToken(rp.c, .PeriodAsterisk, ".*"),
|
|
||||||
};
|
|
||||||
return &node.base;
|
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
_ = it.prev();
|
_ = it.prev();
|
||||||
|
|||||||
@ -1494,6 +1494,35 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||||||
\\}
|
\\}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
cases.add_2("field access expression",
|
||||||
|
\\#define ARROW a->b
|
||||||
|
\\#define DOT a.b
|
||||||
|
\\extern struct Foo {
|
||||||
|
\\ int b;
|
||||||
|
\\}a;
|
||||||
|
\\float b = 2.0f;
|
||||||
|
\\int foo(void) {
|
||||||
|
\\ struct Foo *c;
|
||||||
|
\\ a.b;
|
||||||
|
\\ c->b;
|
||||||
|
\\}
|
||||||
|
, &[_][]const u8{
|
||||||
|
\\pub const struct_Foo = extern struct {
|
||||||
|
\\ b: c_int,
|
||||||
|
\\};
|
||||||
|
\\pub extern var a: struct_Foo;
|
||||||
|
\\pub export var b: f32 = 2;
|
||||||
|
\\pub export fn foo() c_int {
|
||||||
|
\\ var c: [*c]struct_Foo = undefined;
|
||||||
|
\\ _ = a.b;
|
||||||
|
\\ _ = c.*.b;
|
||||||
|
\\}
|
||||||
|
,
|
||||||
|
\\pub const DOT = a.b;
|
||||||
|
,
|
||||||
|
\\pub const ARROW = a.*.b;
|
||||||
|
});
|
||||||
|
|
||||||
/////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
|
/////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
|
||||||
|
|
||||||
cases.addAllowWarnings("simple data types",
|
cases.addAllowWarnings("simple data types",
|
||||||
@ -1702,22 +1731,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||||||
\\}
|
\\}
|
||||||
});
|
});
|
||||||
|
|
||||||
cases.addC("field access expression",
|
|
||||||
\\struct Foo {
|
|
||||||
\\ int field;
|
|
||||||
\\};
|
|
||||||
\\int read_field(struct Foo *foo) {
|
|
||||||
\\ return foo->field;
|
|
||||||
\\}
|
|
||||||
, &[_][]const u8{
|
|
||||||
\\pub const struct_Foo = extern struct {
|
|
||||||
\\ field: c_int,
|
|
||||||
\\};
|
|
||||||
\\pub export fn read_field(foo: [*c]struct_Foo) c_int {
|
|
||||||
\\ return foo.*.field;
|
|
||||||
\\}
|
|
||||||
});
|
|
||||||
|
|
||||||
cases.addC("array access",
|
cases.addC("array access",
|
||||||
\\int array[100];
|
\\int array[100];
|
||||||
\\int foo(int index) {
|
\\int foo(int index) {
|
||||||
@ -2627,4 +2640,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||||||
\\ };
|
\\ };
|
||||||
\\}
|
\\}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
cases.addC("field access expression",
|
||||||
|
\\struct Foo {
|
||||||
|
\\ int field;
|
||||||
|
\\};
|
||||||
|
\\int read_field(struct Foo *foo) {
|
||||||
|
\\ return foo->field;
|
||||||
|
\\}
|
||||||
|
, &[_][]const u8{
|
||||||
|
\\pub const struct_Foo = extern struct {
|
||||||
|
\\ field: c_int,
|
||||||
|
\\};
|
||||||
|
\\pub export fn read_field(foo: [*c]struct_Foo) c_int {
|
||||||
|
\\ return foo.*.field;
|
||||||
|
\\}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user