| author | |
| committer | |
| log | 8de14a98a68752cc834848343f2e7867ee8ca6c9 |
| tree | 7e6bc3259ec3926054830613d63025afa8e19117 |
| parent | 38d8aab4d283efe2f43c7e18411f6df7e1c2d04b |
Includes vector types, __builtin_shufflevector, and __builtin_convertvector7 files changed, 515 insertions(+), 8 deletions(-)
lib/std/meta.zig+32| ... | @@ -1297,3 +1297,35 @@ pub fn globalOption(comptime name: []const u8, comptime T: type) ?T { | ... | @@ -1297,3 +1297,35 @@ pub fn globalOption(comptime name: []const u8, comptime T: type) ?T { |
| 1297 | return null; | 1297 | return null; |
| 1298 | return @as(T, @field(root, name)); | 1298 | return @as(T, @field(root, name)); |
| 1299 | } | 1299 | } |
| 1300 | |||
| 1301 | /// This function is for translate-c and is not intended for general use. | ||
| 1302 | /// Convert from clang __builtin_shufflevector index to Zig @shuffle index | ||
| 1303 | /// clang requires __builtin_shufflevector index arguments to be integer constants. | ||
| 1304 | /// negative values for `this_index` indicate "don't care" so we arbitrarily choose 0 | ||
| 1305 | /// clang enforces that `this_index` is less than the total number of vector elements | ||
| 1306 | /// See https://ziglang.org/documentation/master/#shuffle | ||
| 1307 | /// See https://clang.llvm.org/docs/LanguageExtensions.html#langext-builtin-shufflevector | ||
| 1308 | pub fn shuffleVectorIndex(comptime this_index: c_int, comptime source_vector_len: usize) i32 { | ||
| 1309 | if (this_index <= 0) return 0; | ||
| 1310 | |||
| 1311 | const positive_index = @intCast(usize, this_index); | ||
| 1312 | if (positive_index < source_vector_len) return @intCast(i32, this_index); | ||
| 1313 | const b_index = positive_index - source_vector_len; | ||
| 1314 | return ~@intCast(i32, b_index); | ||
| 1315 | } | ||
| 1316 | |||
| 1317 | test "shuffleVectorIndex" { | ||
| 1318 | const vector_len: usize = 4; | ||
| 1319 | |||
| 1320 | testing.expect(shuffleVectorIndex(-1, vector_len) == 0); | ||
| 1321 | |||
| 1322 | testing.expect(shuffleVectorIndex(0, vector_len) == 0); | ||
| 1323 | testing.expect(shuffleVectorIndex(1, vector_len) == 1); | ||
| 1324 | testing.expect(shuffleVectorIndex(2, vector_len) == 2); | ||
| 1325 | testing.expect(shuffleVectorIndex(3, vector_len) == 3); | ||
| 1326 | |||
| 1327 | testing.expect(shuffleVectorIndex(4, vector_len) == -1); | ||
| 1328 | testing.expect(shuffleVectorIndex(5, vector_len) == -2); | ||
| 1329 | testing.expect(shuffleVectorIndex(6, vector_len) == -3); | ||
| 1330 | testing.expect(shuffleVectorIndex(7, vector_len) == -4); | ||
| 1331 | } | ||
| \ No newline at end of file | |||
src/clang.zig+27| ... | @@ -300,6 +300,14 @@ pub const ConstantExpr = opaque {}; | ... | @@ -300,6 +300,14 @@ pub const ConstantExpr = opaque {}; |
| 300 | 300 | ||
| 301 | pub const ContinueStmt = opaque {}; | 301 | pub const ContinueStmt = opaque {}; |
| 302 | 302 | ||
| 303 | pub const ConvertVectorExpr = opaque { | ||
| 304 | pub const getSrcExpr = ZigClangConvertVectorExpr_getSrcExpr; | ||
| 305 | extern fn ZigClangConvertVectorExpr_getSrcExpr(*const ConvertVectorExpr) *const Expr; | ||
| 306 | |||
| 307 | pub const getTypeSourceInfo_getType = ZigClangConvertVectorExpr_getTypeSourceInfo_getType; | ||
| 308 | extern fn ZigClangConvertVectorExpr_getTypeSourceInfo_getType(*const ConvertVectorExpr) QualType; | ||
| 309 | }; | ||
| 310 | |||
| 303 | pub const DecayedType = opaque { | 311 | pub const DecayedType = opaque { |
| 304 | pub const getDecayedType = ZigClangDecayedType_getDecayedType; | 312 | pub const getDecayedType = ZigClangDecayedType_getDecayedType; |
| 305 | extern fn ZigClangDecayedType_getDecayedType(*const DecayedType) QualType; | 313 | extern fn ZigClangDecayedType_getDecayedType(*const DecayedType) QualType; |
| ... | @@ -748,6 +756,14 @@ pub const ReturnStmt = opaque { | ... | @@ -748,6 +756,14 @@ pub const ReturnStmt = opaque { |
| 748 | extern fn ZigClangReturnStmt_getRetValue(*const ReturnStmt) ?*const Expr; | 756 | extern fn ZigClangReturnStmt_getRetValue(*const ReturnStmt) ?*const Expr; |
| 749 | }; | 757 | }; |
| 750 | 758 | ||
| 759 | pub const ShuffleVectorExpr = opaque { | ||
| 760 | pub const getNumSubExprs = ZigClangShuffleVectorExpr_getNumSubExprs; | ||
| 761 | extern fn ZigClangShuffleVectorExpr_getNumSubExprs(*const ShuffleVectorExpr) c_uint; | ||
| 762 | |||
| 763 | pub const getExpr = ZigClangShuffleVectorExpr_getExpr; | ||
| 764 | extern fn ZigClangShuffleVectorExpr_getExpr(*const ShuffleVectorExpr, c_uint) *const Expr; | ||
| 765 | }; | ||
| 766 | |||
| 751 | pub const SourceManager = opaque { | 767 | pub const SourceManager = opaque { |
| 752 | pub const getSpellingLoc = ZigClangSourceManager_getSpellingLoc; | 768 | pub const getSpellingLoc = ZigClangSourceManager_getSpellingLoc; |
| 753 | extern fn ZigClangSourceManager_getSpellingLoc(*const SourceManager, Loc: SourceLocation) SourceLocation; | 769 | extern fn ZigClangSourceManager_getSpellingLoc(*const SourceManager, Loc: SourceLocation) SourceLocation; |
| ... | @@ -837,6 +853,9 @@ pub const Type = opaque { | ... | @@ -837,6 +853,9 @@ pub const Type = opaque { |
| 837 | pub const isRecordType = ZigClangType_isRecordType; | 853 | pub const isRecordType = ZigClangType_isRecordType; |
| 838 | extern fn ZigClangType_isRecordType(*const Type) bool; | 854 | extern fn ZigClangType_isRecordType(*const Type) bool; |
| 839 | 855 | ||
| 856 | pub const isVectorType = ZigClangType_isVectorType; | ||
| 857 | extern fn ZigClangType_isVectorType(*const Type) bool; | ||
| 858 | |||
| 840 | pub const isIncompleteOrZeroLengthArrayType = ZigClangType_isIncompleteOrZeroLengthArrayType; | 859 | pub const isIncompleteOrZeroLengthArrayType = ZigClangType_isIncompleteOrZeroLengthArrayType; |
| 841 | extern fn ZigClangType_isIncompleteOrZeroLengthArrayType(*const Type, *const ASTContext) bool; | 860 | extern fn ZigClangType_isIncompleteOrZeroLengthArrayType(*const Type, *const ASTContext) bool; |
| 842 | 861 | ||
| ... | @@ -937,6 +956,14 @@ pub const VarDecl = opaque { | ... | @@ -937,6 +956,14 @@ pub const VarDecl = opaque { |
| 937 | extern fn ZigClangVarDecl_getTypeSourceInfo_getType(*const VarDecl) QualType; | 956 | extern fn ZigClangVarDecl_getTypeSourceInfo_getType(*const VarDecl) QualType; |
| 938 | }; | 957 | }; |
| 939 | 958 | ||
| 959 | pub const VectorType = opaque { | ||
| 960 | pub const getElementType = ZigClangVectorType_getElementType; | ||
| 961 | extern fn ZigClangVectorType_getElementType(*const VectorType) QualType; | ||
| 962 | |||
| 963 | pub const getNumElements = ZigClangVectorType_getNumElements; | ||
| 964 | extern fn ZigClangVectorType_getNumElements(*const VectorType) c_uint; | ||
| 965 | }; | ||
| 966 | |||
| 940 | pub const WhileStmt = opaque { | 967 | pub const WhileStmt = opaque { |
| 941 | pub const getCond = ZigClangWhileStmt_getCond; | 968 | pub const getCond = ZigClangWhileStmt_getCond; |
| 942 | extern fn ZigClangWhileStmt_getCond(*const WhileStmt) *const Expr; | 969 | extern fn ZigClangWhileStmt_getCond(*const WhileStmt) *const Expr; |
src/translate_c.zig+215| ... | @@ -1123,6 +1123,16 @@ fn transStmt( | ... | @@ -1123,6 +1123,16 @@ fn transStmt( |
| 1123 | const gen_sel = @ptrCast(*const clang.GenericSelectionExpr, stmt); | 1123 | const gen_sel = @ptrCast(*const clang.GenericSelectionExpr, stmt); |
| 1124 | return transExpr(c, scope, gen_sel.getResultExpr(), result_used); | 1124 | return transExpr(c, scope, gen_sel.getResultExpr(), result_used); |
| 1125 | }, | 1125 | }, |
| 1126 | .ConvertVectorExprClass => { | ||
| 1127 | const conv_vec = @ptrCast(*const clang.ConvertVectorExpr, stmt); | ||
| 1128 | const conv_vec_node = try transConvertVectorExpr(c, scope, stmt.getBeginLoc(), conv_vec); | ||
| 1129 | return maybeSuppressResult(c, scope, result_used, conv_vec_node); | ||
| 1130 | }, | ||
| 1131 | .ShuffleVectorExprClass => { | ||
| 1132 | const shuffle_vec_expr = @ptrCast(*const clang.ShuffleVectorExpr, stmt); | ||
| 1133 | const shuffle_vec_node = try transShuffleVectorExpr(c, scope, shuffle_vec_expr); | ||
| 1134 | return maybeSuppressResult(c, scope, result_used, shuffle_vec_node); | ||
| 1135 | }, | ||
| 1126 | // When adding new cases here, see comment for maybeBlockify() | 1136 | // When adding new cases here, see comment for maybeBlockify() |
| 1127 | else => { | 1137 | else => { |
| 1128 | return fail(c, error.UnsupportedTranslation, stmt.getBeginLoc(), "TODO implement translation of stmt class {s}", .{@tagName(sc)}); | 1138 | return fail(c, error.UnsupportedTranslation, stmt.getBeginLoc(), "TODO implement translation of stmt class {s}", .{@tagName(sc)}); |
| ... | @@ -1130,6 +1140,128 @@ fn transStmt( | ... | @@ -1130,6 +1140,128 @@ fn transStmt( |
| 1130 | } | 1140 | } |
| 1131 | } | 1141 | } |
| 1132 | 1142 | ||
| 1143 | /// See https://clang.llvm.org/docs/LanguageExtensions.html#langext-builtin-convertvector | ||
| 1144 | fn transConvertVectorExpr( | ||
| 1145 | c: *Context, | ||
| 1146 | scope: *Scope, | ||
| 1147 | source_loc: clang.SourceLocation, | ||
| 1148 | expr: *const clang.ConvertVectorExpr, | ||
| 1149 | ) TransError!Node { | ||
| 1150 | const base_stmt = @ptrCast(*const clang.Stmt, expr); | ||
| 1151 | |||
| 1152 | var block_scope = try Scope.Block.init(c, scope, true); | ||
| 1153 | defer block_scope.deinit(); | ||
| 1154 | |||
| 1155 | const src_expr = expr.getSrcExpr(); | ||
| 1156 | const src_type = qualTypeCanon(src_expr.getType()); | ||
| 1157 | const src_vector_ty = @ptrCast(*const clang.VectorType, src_type); | ||
| 1158 | const src_element_qt = src_vector_ty.getElementType(); | ||
| 1159 | const src_element_type_node = try transQualType(c, &block_scope.base, src_element_qt, base_stmt.getBeginLoc()); | ||
| 1160 | |||
| 1161 | const src_expr_node = try transExpr(c, &block_scope.base, src_expr, .used); | ||
| 1162 | |||
| 1163 | const dst_qt = expr.getTypeSourceInfo_getType(); | ||
| 1164 | const dst_type_node = try transQualType(c, &block_scope.base, dst_qt, base_stmt.getBeginLoc()); | ||
| 1165 | const dst_vector_ty = @ptrCast(*const clang.VectorType, qualTypeCanon(dst_qt)); | ||
| 1166 | const num_elements = dst_vector_ty.getNumElements(); | ||
| 1167 | const dst_element_qt = dst_vector_ty.getElementType(); | ||
| 1168 | |||
| 1169 | // workaround for https://github.com/ziglang/zig/issues/8322 | ||
| 1170 | // we store the casted results into temp variables and use those | ||
| 1171 | // to initialize the vector. Eventually we can just directly | ||
| 1172 | // construct the init_list from casted source members | ||
| 1173 | var i: usize = 0; | ||
| 1174 | while (i < num_elements) : (i += 1) { | ||
| 1175 | const mangled_name = try block_scope.makeMangledName(c, "tmp"); | ||
| 1176 | const value = try Tag.array_access.create(c.arena, .{ | ||
| 1177 | .lhs = src_expr_node, | ||
| 1178 | .rhs = try transCreateNodeNumber(c, i, .int), | ||
| 1179 | }); | ||
| 1180 | const tmp_decl_node = try Tag.var_simple.create(c.arena, .{ | ||
| 1181 | .name = mangled_name, | ||
| 1182 | .init = try transCCast(c, &block_scope.base, base_stmt.getBeginLoc(), dst_element_qt, src_element_qt, value), | ||
| 1183 | }); | ||
| 1184 | try block_scope.statements.append(tmp_decl_node); | ||
| 1185 | } | ||
| 1186 | |||
| 1187 | const init_list = try c.arena.alloc(Node, num_elements); | ||
| 1188 | for (init_list) |*init, init_index| { | ||
| 1189 | const tmp_decl = block_scope.statements.items[init_index]; | ||
| 1190 | const name = tmp_decl.castTag(.var_simple).?.data.name; | ||
| 1191 | init.* = try Tag.identifier.create(c.arena, name); | ||
| 1192 | } | ||
| 1193 | |||
| 1194 | const vec_init = try Tag.array_init.create(c.arena, .{ | ||
| 1195 | .cond = dst_type_node, | ||
| 1196 | .cases = init_list, | ||
| 1197 | }); | ||
| 1198 | |||
| 1199 | const break_node = try Tag.break_val.create(c.arena, .{ | ||
| 1200 | .label = block_scope.label, | ||
| 1201 | .val = vec_init, | ||
| 1202 | }); | ||
| 1203 | try block_scope.statements.append(break_node); | ||
| 1204 | return block_scope.complete(c); | ||
| 1205 | } | ||
| 1206 | |||
| 1207 | fn makeShuffleMask(c: *Context, scope: *Scope, expr: *const clang.ShuffleVectorExpr, vector_len: Node) TransError!Node { | ||
| 1208 | const num_subexprs = expr.getNumSubExprs(); | ||
| 1209 | assert(num_subexprs >= 3); // two source vectors + at least 1 index expression | ||
| 1210 | const mask_len = num_subexprs - 2; | ||
| 1211 | |||
| 1212 | const mask_type = try Tag.std_meta_vector.create(c.arena, .{ | ||
| 1213 | .lhs = try transCreateNodeNumber(c, mask_len, .int), | ||
| 1214 | .rhs = try Tag.type.create(c.arena, "i32"), | ||
| 1215 | }); | ||
| 1216 | |||
| 1217 | const init_list = try c.arena.alloc(Node, mask_len); | ||
| 1218 | |||
| 1219 | for (init_list) |*init, i| { | ||
| 1220 | const index_expr = try transExprCoercing(c, scope, expr.getExpr(@intCast(c_uint, i + 2)), .used); | ||
| 1221 | const converted_index = try Tag.std_meta_shuffle_vector_index.create(c.arena, .{ .lhs = index_expr, .rhs = vector_len }); | ||
| 1222 | init.* = converted_index; | ||
| 1223 | } | ||
| 1224 | |||
| 1225 | const mask_init = try Tag.array_init.create(c.arena, .{ | ||
| 1226 | .cond = mask_type, | ||
| 1227 | .cases = init_list, | ||
| 1228 | }); | ||
| 1229 | return Tag.@"comptime".create(c.arena, mask_init); | ||
| 1230 | } | ||
| 1231 | |||
| 1232 | /// @typeInfo(@TypeOf(vec_node)).Vector.<field> | ||
| 1233 | fn vectorTypeInfo(arena: *mem.Allocator, vec_node: Node, field: []const u8) TransError!Node { | ||
| 1234 | const typeof_call = try Tag.typeof.create(arena, vec_node); | ||
| 1235 | const typeinfo_call = try Tag.typeinfo.create(arena, typeof_call); | ||
| 1236 | const vector_type_info = try Tag.field_access.create(arena, .{ .lhs = typeinfo_call, .field_name = "Vector" }); | ||
| 1237 | return Tag.field_access.create(arena, .{ .lhs = vector_type_info, .field_name = field }); | ||
| 1238 | } | ||
| 1239 | |||
| 1240 | fn transShuffleVectorExpr( | ||
| 1241 | c: *Context, | ||
| 1242 | scope: *Scope, | ||
| 1243 | expr: *const clang.ShuffleVectorExpr, | ||
| 1244 | ) TransError!Node { | ||
| 1245 | const base_expr = @ptrCast(*const clang.Expr, expr); | ||
| 1246 | const num_subexprs = expr.getNumSubExprs(); | ||
| 1247 | if (num_subexprs < 3) return fail(c, error.UnsupportedTranslation, base_expr.getBeginLoc(), "ShuffleVector needs at least 1 index", .{}); | ||
| 1248 | |||
| 1249 | const a = try transExpr(c, scope, expr.getExpr(0), .used); | ||
| 1250 | const b = try transExpr(c, scope, expr.getExpr(1), .used); | ||
| 1251 | |||
| 1252 | // clang requires first two arguments to __builtin_shufflevector to be same type | ||
| 1253 | const vector_child_type = try vectorTypeInfo(c.arena, a, "child"); | ||
| 1254 | const vector_len = try vectorTypeInfo(c.arena, a, "len"); | ||
| 1255 | const shuffle_mask = try makeShuffleMask(c, scope, expr, vector_len); | ||
| 1256 | |||
| 1257 | return Tag.shuffle.create(c.arena, .{ | ||
| 1258 | .element_type = vector_child_type, | ||
| 1259 | .a = a, | ||
| 1260 | .b = b, | ||
| 1261 | .mask_vector = shuffle_mask, | ||
| 1262 | }); | ||
| 1263 | } | ||
| 1264 | |||
| 1133 | /// Translate a "simple" offsetof expression containing exactly one component, | 1265 | /// Translate a "simple" offsetof expression containing exactly one component, |
| 1134 | /// when that component is of kind .Field - e.g. offsetof(mytype, myfield) | 1266 | /// when that component is of kind .Field - e.g. offsetof(mytype, myfield) |
| 1135 | fn transSimpleOffsetOfExpr( | 1267 | fn transSimpleOffsetOfExpr( |
| ... | @@ -1935,6 +2067,10 @@ fn cIsEnum(qt: clang.QualType) bool { | ... | @@ -1935,6 +2067,10 @@ fn cIsEnum(qt: clang.QualType) bool { |
| 1935 | return qt.getCanonicalType().getTypeClass() == .Enum; | 2067 | return qt.getCanonicalType().getTypeClass() == .Enum; |
| 1936 | } | 2068 | } |
| 1937 | 2069 | ||
| 2070 | fn cIsVector(qt: clang.QualType) bool { | ||
| 2071 | return qt.getCanonicalType().getTypeClass() == .Vector; | ||
| 2072 | } | ||
| 2073 | |||
| 1938 | /// Get the underlying int type of an enum. The C compiler chooses a signed int | 2074 | /// Get the underlying int type of an enum. The C compiler chooses a signed int |
| 1939 | /// type that is large enough to hold all of the enum's values. It is not required | 2075 | /// type that is large enough to hold all of the enum's values. It is not required |
| 1940 | /// to be the smallest possible type that can hold all the values. | 2076 | /// to be the smallest possible type that can hold all the values. |
| ... | @@ -1991,6 +2127,11 @@ fn transCCast( | ... | @@ -1991,6 +2127,11 @@ fn transCCast( |
| 1991 | // @bitCast(dest_type, intermediate_value) | 2127 | // @bitCast(dest_type, intermediate_value) |
| 1992 | return Tag.bit_cast.create(c.arena, .{ .lhs = dst_node, .rhs = src_int_expr }); | 2128 | return Tag.bit_cast.create(c.arena, .{ .lhs = dst_node, .rhs = src_int_expr }); |
| 1993 | } | 2129 | } |
| 2130 | if (cIsVector(src_type) or cIsVector(dst_type)) { | ||
| 2131 | // C cast where at least 1 operand is a vector requires them to be same size | ||
| 2132 | // @bitCast(dest_type, val) | ||
| 2133 | return Tag.bit_cast.create(c.arena, .{ .lhs = dst_node, .rhs = expr }); | ||
| 2134 | } | ||
| 1994 | if (cIsInteger(dst_type) and qualTypeIsPtr(src_type)) { | 2135 | if (cIsInteger(dst_type) and qualTypeIsPtr(src_type)) { |
| 1995 | // @intCast(dest_type, @ptrToInt(val)) | 2136 | // @intCast(dest_type, @ptrToInt(val)) |
| 1996 | const ptr_to_int = try Tag.ptr_to_int.create(c.arena, expr); | 2137 | const ptr_to_int = try Tag.ptr_to_int.create(c.arena, expr); |
| ... | @@ -2209,6 +2350,63 @@ fn transInitListExprArray( | ... | @@ -2209,6 +2350,63 @@ fn transInitListExprArray( |
| 2209 | } | 2350 | } |
| 2210 | } | 2351 | } |
| 2211 | 2352 | ||
| 2353 | fn transInitListExprVector( | ||
| 2354 | c: *Context, | ||
| 2355 | scope: *Scope, | ||
| 2356 | loc: clang.SourceLocation, | ||
| 2357 | expr: *const clang.InitListExpr, | ||
| 2358 | ty: *const clang.Type, | ||
| 2359 | ) TransError!Node { | ||
| 2360 | |||
| 2361 | const qt = getExprQualType(c, @ptrCast(*const clang.Expr, expr)); | ||
| 2362 | const vector_type = try transQualType(c, scope, qt, loc); | ||
| 2363 | const init_count = expr.getNumInits(); | ||
| 2364 | |||
| 2365 | if (init_count == 0) { | ||
| 2366 | return Tag.container_init.create(c.arena, .{ | ||
| 2367 | .lhs = vector_type, | ||
| 2368 | .inits = try c.arena.alloc(ast.Payload.ContainerInit.Initializer, 0), | ||
| 2369 | }); | ||
| 2370 | } | ||
| 2371 | |||
| 2372 | var block_scope = try Scope.Block.init(c, scope, true); | ||
| 2373 | defer block_scope.deinit(); | ||
| 2374 | |||
| 2375 | // workaround for https://github.com/ziglang/zig/issues/8322 | ||
| 2376 | // we store the initializers in temp variables and use those | ||
| 2377 | // to initialize the vector. Eventually we can just directly | ||
| 2378 | // construct the init_list from casted source members | ||
| 2379 | var i: usize = 0; | ||
| 2380 | while (i < init_count) : (i += 1) { | ||
| 2381 | const mangled_name = try block_scope.makeMangledName(c, "tmp"); | ||
| 2382 | const init_expr = expr.getInit(@intCast(c_uint, i)); | ||
| 2383 | const tmp_decl_node = try Tag.var_simple.create(c.arena, .{ | ||
| 2384 | .name = mangled_name, | ||
| 2385 | .init = try transExpr(c, &block_scope.base, init_expr, .used), | ||
| 2386 | }); | ||
| 2387 | try block_scope.statements.append(tmp_decl_node); | ||
| 2388 | } | ||
| 2389 | |||
| 2390 | const init_list = try c.arena.alloc(Node, init_count); | ||
| 2391 | for (init_list) |*init, init_index| { | ||
| 2392 | const tmp_decl = block_scope.statements.items[init_index]; | ||
| 2393 | const name = tmp_decl.castTag(.var_simple).?.data.name; | ||
| 2394 | init.* = try Tag.identifier.create(c.arena, name); | ||
| 2395 | } | ||
| 2396 | |||
| 2397 | const array_init = try Tag.array_init.create(c.arena, .{ | ||
| 2398 | .cond = vector_type, | ||
| 2399 | .cases = init_list, | ||
| 2400 | }); | ||
| 2401 | const break_node = try Tag.break_val.create(c.arena, .{ | ||
| 2402 | .label = block_scope.label, | ||
| 2403 | .val = array_init, | ||
| 2404 | }); | ||
| 2405 | try block_scope.statements.append(break_node); | ||
| 2406 | |||
| 2407 | return block_scope.complete(c); | ||
| 2408 | } | ||
| 2409 | |||
| 2212 | fn transInitListExpr( | 2410 | fn transInitListExpr( |
| 2213 | c: *Context, | 2411 | c: *Context, |
| 2214 | scope: *Scope, | 2412 | scope: *Scope, |
| ... | @@ -2235,6 +2433,14 @@ fn transInitListExpr( | ... | @@ -2235,6 +2433,14 @@ fn transInitListExpr( |
| 2235 | expr, | 2433 | expr, |
| 2236 | qual_type, | 2434 | qual_type, |
| 2237 | )); | 2435 | )); |
| 2436 | } else if (qual_type.isVectorType()) { | ||
| 2437 | return maybeSuppressResult(c, scope, used, try transInitListExprVector( | ||
| 2438 | c, | ||
| 2439 | scope, | ||
| 2440 | source_loc, | ||
| 2441 | expr, | ||
| 2442 | qual_type, | ||
| 2443 | )); | ||
| 2238 | } else { | 2444 | } else { |
| 2239 | const type_name = c.str(qual_type.getTypeClassName()); | 2445 | const type_name = c.str(qual_type.getTypeClassName()); |
| 2240 | return fail(c, error.UnsupportedType, source_loc, "unsupported initlist type: '{s}'", .{type_name}); | 2446 | return fail(c, error.UnsupportedType, source_loc, "unsupported initlist type: '{s}'", .{type_name}); |
| ... | @@ -4085,6 +4291,15 @@ fn transType(c: *Context, scope: *Scope, ty: *const clang.Type, source_loc: clan | ... | @@ -4085,6 +4291,15 @@ fn transType(c: *Context, scope: *Scope, ty: *const clang.Type, source_loc: clan |
| 4085 | }; | 4291 | }; |
| 4086 | return Tag.typeof.create(c.arena, underlying_expr); | 4292 | return Tag.typeof.create(c.arena, underlying_expr); |
| 4087 | }, | 4293 | }, |
| 4294 | .Vector => { | ||
| 4295 | const vector_ty = @ptrCast(*const clang.VectorType, ty); | ||
| 4296 | const num_elements = vector_ty.getNumElements(); | ||
| 4297 | const element_qt = vector_ty.getElementType(); | ||
| 4298 | return Tag.std_meta_vector.create(c.arena, .{ | ||
| 4299 | .lhs = try transCreateNodeNumber(c, num_elements, .int), | ||
| 4300 | .rhs = try transQualType(c, scope, element_qt, source_loc), | ||
| 4301 | }); | ||
| 4302 | }, | ||
| 4088 | else => { | 4303 | else => { |
| 4089 | const type_name = c.str(ty.getTypeClassName()); | 4304 | const type_name = c.str(ty.getTypeClassName()); |
| 4090 | return fail(c, error.UnsupportedType, source_loc, "unsupported type: '{s}'", .{type_name}); | 4305 | return fail(c, error.UnsupportedType, source_loc, "unsupported type: '{s}'", .{type_name}); |
src/translate_c/ast.zig+95-8| ... | @@ -66,6 +66,7 @@ pub const Node = extern union { | ... | @@ -66,6 +66,7 @@ pub const Node = extern union { |
| 66 | @"enum", | 66 | @"enum", |
| 67 | @"struct", | 67 | @"struct", |
| 68 | @"union", | 68 | @"union", |
| 69 | @"comptime", | ||
| 69 | array_init, | 70 | array_init, |
| 70 | tuple, | 71 | tuple, |
| 71 | container_init, | 72 | container_init, |
| ... | @@ -154,6 +155,8 @@ pub const Node = extern union { | ... | @@ -154,6 +155,8 @@ pub const Node = extern union { |
| 154 | div_exact, | 155 | div_exact, |
| 155 | /// @byteOffsetOf(lhs, rhs) | 156 | /// @byteOffsetOf(lhs, rhs) |
| 156 | byte_offset_of, | 157 | byte_offset_of, |
| 158 | /// @shuffle(type, a, b, mask) | ||
| 159 | shuffle, | ||
| 157 | 160 | ||
| 158 | negate, | 161 | negate, |
| 159 | negate_wrap, | 162 | negate_wrap, |
| ... | @@ -172,6 +175,7 @@ pub const Node = extern union { | ... | @@ -172,6 +175,7 @@ pub const Node = extern union { |
| 172 | sizeof, | 175 | sizeof, |
| 173 | alignof, | 176 | alignof, |
| 174 | typeof, | 177 | typeof, |
| 178 | typeinfo, | ||
| 175 | type, | 179 | type, |
| 176 | 180 | ||
| 177 | optional_type, | 181 | optional_type, |
| ... | @@ -182,6 +186,10 @@ pub const Node = extern union { | ... | @@ -182,6 +186,10 @@ pub const Node = extern union { |
| 182 | 186 | ||
| 183 | /// @import("std").meta.sizeof(operand) | 187 | /// @import("std").meta.sizeof(operand) |
| 184 | std_meta_sizeof, | 188 | std_meta_sizeof, |
| 189 | /// @import("std").meta.shuffleVectorIndex(lhs, rhs) | ||
| 190 | std_meta_shuffle_vector_index, | ||
| 191 | /// @import("std").meta.Vector(lhs, rhs) | ||
| 192 | std_meta_vector, | ||
| 185 | /// @import("std").mem.zeroes(operand) | 193 | /// @import("std").mem.zeroes(operand) |
| 186 | std_mem_zeroes, | 194 | std_mem_zeroes, |
| 187 | /// @import("std").mem.zeroInit(lhs, rhs) | 195 | /// @import("std").mem.zeroInit(lhs, rhs) |
| ... | @@ -233,6 +241,7 @@ pub const Node = extern union { | ... | @@ -233,6 +241,7 @@ pub const Node = extern union { |
| 233 | 241 | ||
| 234 | .std_mem_zeroes, | 242 | .std_mem_zeroes, |
| 235 | .@"return", | 243 | .@"return", |
| 244 | .@"comptime", | ||
| 236 | .discard, | 245 | .discard, |
| 237 | .std_math_Log2Int, | 246 | .std_math_Log2Int, |
| 238 | .negate, | 247 | .negate, |
| ... | @@ -255,6 +264,7 @@ pub const Node = extern union { | ... | @@ -255,6 +264,7 @@ pub const Node = extern union { |
| 255 | .sizeof, | 264 | .sizeof, |
| 256 | .alignof, | 265 | .alignof, |
| 257 | .typeof, | 266 | .typeof, |
| 267 | .typeinfo, | ||
| 258 | => Payload.UnOp, | 268 | => Payload.UnOp, |
| 259 | 269 | ||
| 260 | .add, | 270 | .add, |
| ... | @@ -308,6 +318,8 @@ pub const Node = extern union { | ... | @@ -308,6 +318,8 @@ pub const Node = extern union { |
| 308 | .align_cast, | 318 | .align_cast, |
| 309 | .array_access, | 319 | .array_access, |
| 310 | .std_mem_zeroinit, | 320 | .std_mem_zeroinit, |
| 321 | .std_meta_shuffle_vector_index, | ||
| 322 | .std_meta_vector, | ||
| 311 | .ptr_cast, | 323 | .ptr_cast, |
| 312 | .div_exact, | 324 | .div_exact, |
| 313 | .byte_offset_of, | 325 | .byte_offset_of, |
| ... | @@ -346,6 +358,7 @@ pub const Node = extern union { | ... | @@ -346,6 +358,7 @@ pub const Node = extern union { |
| 346 | .pub_inline_fn => Payload.PubInlineFn, | 358 | .pub_inline_fn => Payload.PubInlineFn, |
| 347 | .field_access => Payload.FieldAccess, | 359 | .field_access => Payload.FieldAccess, |
| 348 | .string_slice => Payload.StringSlice, | 360 | .string_slice => Payload.StringSlice, |
| 361 | .shuffle => Payload.Shuffle, | ||
| 349 | }; | 362 | }; |
| 350 | } | 363 | } |
| 351 | 364 | ||
| ... | @@ -678,6 +691,16 @@ pub const Payload = struct { | ... | @@ -678,6 +691,16 @@ pub const Payload = struct { |
| 678 | end: usize, | 691 | end: usize, |
| 679 | }, | 692 | }, |
| 680 | }; | 693 | }; |
| 694 | |||
| 695 | pub const Shuffle = struct { | ||
| 696 | base: Payload, | ||
| 697 | data: struct { | ||
| 698 | element_type: Node, | ||
| 699 | a: Node, | ||
| 700 | b: Node, | ||
| 701 | mask_vector: Node, | ||
| 702 | }, | ||
| 703 | }; | ||
| 681 | }; | 704 | }; |
| 682 | 705 | ||
| 683 | /// Converts the nodes into a Zig ast. | 706 | /// Converts the nodes into a Zig ast. |
| ... | @@ -868,6 +891,16 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -868,6 +891,16 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 868 | const import_node = try renderStdImport(c, "mem", "zeroInit"); | 891 | const import_node = try renderStdImport(c, "mem", "zeroInit"); |
| 869 | return renderCall(c, import_node, &.{ payload.lhs, payload.rhs }); | 892 | return renderCall(c, import_node, &.{ payload.lhs, payload.rhs }); |
| 870 | }, | 893 | }, |
| 894 | .std_meta_shuffle_vector_index => { | ||
| 895 | const payload = node.castTag(.std_meta_shuffle_vector_index).?.data; | ||
| 896 | const import_node = try renderStdImport(c, "meta", "shuffleVectorIndex"); | ||
| 897 | return renderCall(c, import_node, &.{ payload.lhs, payload.rhs }); | ||
| 898 | }, | ||
| 899 | .std_meta_vector => { | ||
| 900 | const payload = node.castTag(.std_meta_vector).?.data; | ||
| 901 | const import_node = try renderStdImport(c, "meta", "Vector"); | ||
| 902 | return renderCall(c, import_node, &.{ payload.lhs, payload.rhs }); | ||
| 903 | }, | ||
| 871 | .call => { | 904 | .call => { |
| 872 | const payload = node.castTag(.call).?.data; | 905 | const payload = node.castTag(.call).?.data; |
| 873 | const lhs = try renderNode(c, payload.lhs); | 906 | const lhs = try renderNode(c, payload.lhs); |
| ... | @@ -964,6 +997,17 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -964,6 +997,17 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 964 | }, | 997 | }, |
| 965 | }); | 998 | }); |
| 966 | }, | 999 | }, |
| 1000 | .@"comptime" => { | ||
| 1001 | const payload = node.castTag(.@"comptime").?.data; | ||
| 1002 | return c.addNode(.{ | ||
| 1003 | .tag = .@"comptime", | ||
| 1004 | .main_token = try c.addToken(.keyword_comptime, "comptime"), | ||
| 1005 | .data = .{ | ||
| 1006 | .lhs = try renderNode(c, payload), | ||
| 1007 | .rhs = undefined, | ||
| 1008 | }, | ||
| 1009 | }); | ||
| 1010 | }, | ||
| 967 | .type => { | 1011 | .type => { |
| 968 | const payload = node.castTag(.type).?.data; | 1012 | const payload = node.castTag(.type).?.data; |
| 969 | return c.addNode(.{ | 1013 | return c.addNode(.{ |
| ... | @@ -1217,6 +1261,15 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1217,6 +1261,15 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1217 | const payload = node.castTag(.sizeof).?.data; | 1261 | const payload = node.castTag(.sizeof).?.data; |
| 1218 | return renderBuiltinCall(c, "@sizeOf", &.{payload}); | 1262 | return renderBuiltinCall(c, "@sizeOf", &.{payload}); |
| 1219 | }, | 1263 | }, |
| 1264 | .shuffle => { | ||
| 1265 | const payload = node.castTag(.shuffle).?.data; | ||
| 1266 | return renderBuiltinCall(c, "@shuffle", &.{ | ||
| 1267 | payload.element_type, | ||
| 1268 | payload.a, | ||
| 1269 | payload.b, | ||
| 1270 | payload.mask_vector, | ||
| 1271 | }); | ||
| 1272 | }, | ||
| 1220 | .alignof => { | 1273 | .alignof => { |
| 1221 | const payload = node.castTag(.alignof).?.data; | 1274 | const payload = node.castTag(.alignof).?.data; |
| 1222 | return renderBuiltinCall(c, "@alignOf", &.{payload}); | 1275 | return renderBuiltinCall(c, "@alignOf", &.{payload}); |
| ... | @@ -1225,6 +1278,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1225,6 +1278,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1225 | const payload = node.castTag(.typeof).?.data; | 1278 | const payload = node.castTag(.typeof).?.data; |
| 1226 | return renderBuiltinCall(c, "@TypeOf", &.{payload}); | 1279 | return renderBuiltinCall(c, "@TypeOf", &.{payload}); |
| 1227 | }, | 1280 | }, |
| 1281 | .typeinfo => { | ||
| 1282 | const payload = node.castTag(.typeinfo).?.data; | ||
| 1283 | return renderBuiltinCall(c, "@typeInfo", &.{payload}); | ||
| 1284 | }, | ||
| 1228 | .negate => return renderPrefixOp(c, node, .negation, .minus, "-"), | 1285 | .negate => return renderPrefixOp(c, node, .negation, .minus, "-"), |
| 1229 | .negate_wrap => return renderPrefixOp(c, node, .negation_wrap, .minus_percent, "-%"), | 1286 | .negate_wrap => return renderPrefixOp(c, node, .negation_wrap, .minus_percent, "-%"), |
| 1230 | .bit_not => return renderPrefixOp(c, node, .bit_not, .tilde, "~"), | 1287 | .bit_not => return renderPrefixOp(c, node, .bit_not, .tilde, "~"), |
| ... | @@ -2085,9 +2142,12 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { | ... | @@ -2085,9 +2142,12 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { |
| 2085 | .sizeof, | 2142 | .sizeof, |
| 2086 | .alignof, | 2143 | .alignof, |
| 2087 | .typeof, | 2144 | .typeof, |
| 2145 | .typeinfo, | ||
| 2088 | .std_meta_sizeof, | 2146 | .std_meta_sizeof, |
| 2089 | .std_meta_cast, | 2147 | .std_meta_cast, |
| 2090 | .std_meta_promoteIntLiteral, | 2148 | .std_meta_promoteIntLiteral, |
| 2149 | .std_meta_vector, | ||
| 2150 | .std_meta_shuffle_vector_index, | ||
| 2091 | .std_mem_zeroinit, | 2151 | .std_mem_zeroinit, |
| 2092 | .integer_literal, | 2152 | .integer_literal, |
| 2093 | .float_literal, | 2153 | .float_literal, |
| ... | @@ -2118,6 +2178,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { | ... | @@ -2118,6 +2178,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { |
| 2118 | .bool_to_int, | 2178 | .bool_to_int, |
| 2119 | .div_exact, | 2179 | .div_exact, |
| 2120 | .byte_offset_of, | 2180 | .byte_offset_of, |
| 2181 | .shuffle, | ||
| 2121 | => { | 2182 | => { |
| 2122 | // no grouping needed | 2183 | // no grouping needed |
| 2123 | return renderNode(c, node); | 2184 | return renderNode(c, node); |
| ... | @@ -2185,6 +2246,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { | ... | @@ -2185,6 +2246,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { |
| 2185 | .discard, | 2246 | .discard, |
| 2186 | .@"continue", | 2247 | .@"continue", |
| 2187 | .@"return", | 2248 | .@"return", |
| 2249 | .@"comptime", | ||
| 2188 | .usingnamespace_builtins, | 2250 | .usingnamespace_builtins, |
| 2189 | .while_true, | 2251 | .while_true, |
| 2190 | .if_not_break, | 2252 | .if_not_break, |
| ... | @@ -2327,6 +2389,8 @@ fn renderBuiltinCall(c: *Context, builtin: []const u8, args: []const Node) !Node | ... | @@ -2327,6 +2389,8 @@ fn renderBuiltinCall(c: *Context, builtin: []const u8, args: []const Node) !Node |
| 2327 | _ = try c.addToken(.l_paren, "("); | 2389 | _ = try c.addToken(.l_paren, "("); |
| 2328 | var arg_1: NodeIndex = 0; | 2390 | var arg_1: NodeIndex = 0; |
| 2329 | var arg_2: NodeIndex = 0; | 2391 | var arg_2: NodeIndex = 0; |
| 2392 | var arg_3: NodeIndex = 0; | ||
| 2393 | var arg_4: NodeIndex = 0; | ||
| 2330 | switch (args.len) { | 2394 | switch (args.len) { |
| 2331 | 0 => {}, | 2395 | 0 => {}, |
| 2332 | 1 => { | 2396 | 1 => { |
| ... | @@ -2337,18 +2401,41 @@ fn renderBuiltinCall(c: *Context, builtin: []const u8, args: []const Node) !Node | ... | @@ -2337,18 +2401,41 @@ fn renderBuiltinCall(c: *Context, builtin: []const u8, args: []const Node) !Node |
| 2337 | _ = try c.addToken(.comma, ","); | 2401 | _ = try c.addToken(.comma, ","); |
| 2338 | arg_2 = try renderNode(c, args[1]); | 2402 | arg_2 = try renderNode(c, args[1]); |
| 2339 | }, | 2403 | }, |
| 2404 | 4 => { | ||
| 2405 | arg_1 = try renderNode(c, args[0]); | ||
| 2406 | _ = try c.addToken(.comma, ","); | ||
| 2407 | arg_2 = try renderNode(c, args[1]); | ||
| 2408 | _ = try c.addToken(.comma, ","); | ||
| 2409 | arg_3 = try renderNode(c, args[2]); | ||
| 2410 | _ = try c.addToken(.comma, ","); | ||
| 2411 | arg_4 = try renderNode(c, args[3]); | ||
| 2412 | }, | ||
| 2340 | else => unreachable, // expand this function as needed. | 2413 | else => unreachable, // expand this function as needed. |
| 2341 | } | 2414 | } |
| 2342 | 2415 | ||
| 2343 | _ = try c.addToken(.r_paren, ")"); | 2416 | _ = try c.addToken(.r_paren, ")"); |
| 2344 | return c.addNode(.{ | 2417 | if (args.len <= 2) { |
| 2345 | .tag = .builtin_call_two, | 2418 | return c.addNode(.{ |
| 2346 | .main_token = builtin_tok, | 2419 | .tag = .builtin_call_two, |
| 2347 | .data = .{ | 2420 | .main_token = builtin_tok, |
| 2348 | .lhs = arg_1, | 2421 | .data = .{ |
| 2349 | .rhs = arg_2, | 2422 | .lhs = arg_1, |
| 2350 | }, | 2423 | .rhs = arg_2, |
| 2351 | }); | 2424 | }, |
| 2425 | }); | ||
| 2426 | } else { | ||
| 2427 | std.debug.assert(args.len == 4); | ||
| 2428 | |||
| 2429 | const params = try c.listToSpan(&.{ arg_1, arg_2, arg_3, arg_4 }); | ||
| 2430 | return c.addNode(.{ | ||
| 2431 | .tag = .builtin_call, | ||
| 2432 | .main_token = builtin_tok, | ||
| 2433 | .data = .{ | ||
| 2434 | .lhs = params.start, | ||
| 2435 | .rhs = params.end, | ||
| 2436 | }, | ||
| 2437 | }); | ||
| 2438 | } | ||
| 2352 | } | 2439 | } |
| 2353 | 2440 | ||
| 2354 | fn renderVar(c: *Context, node: Node) !NodeIndex { | 2441 | fn renderVar(c: *Context, node: Node) !NodeIndex { |
src/zig_clang.cpp+34| ... | @@ -2046,6 +2046,11 @@ bool ZigClangType_isRecordType(const ZigClangType *self) { | ... | @@ -2046,6 +2046,11 @@ bool ZigClangType_isRecordType(const ZigClangType *self) { |
| 2046 | return casted->isRecordType(); | 2046 | return casted->isRecordType(); |
| 2047 | } | 2047 | } |
| 2048 | 2048 | ||
| 2049 | bool ZigClangType_isVectorType(const ZigClangType *self) { | ||
| 2050 | auto casted = reinterpret_cast<const clang::Type *>(self); | ||
| 2051 | return casted->isVectorType(); | ||
| 2052 | } | ||
| 2053 | |||
| 2049 | bool ZigClangType_isIncompleteOrZeroLengthArrayType(const ZigClangQualType *self, | 2054 | bool ZigClangType_isIncompleteOrZeroLengthArrayType(const ZigClangQualType *self, |
| 2050 | const struct ZigClangASTContext *ctx) | 2055 | const struct ZigClangASTContext *ctx) |
| 2051 | { | 2056 | { |
| ... | @@ -2738,6 +2743,16 @@ struct ZigClangQualType ZigClangBinaryOperator_getType(const struct ZigClangBina | ... | @@ -2738,6 +2743,16 @@ struct ZigClangQualType ZigClangBinaryOperator_getType(const struct ZigClangBina |
| 2738 | return bitcast(casted->getType()); | 2743 | return bitcast(casted->getType()); |
| 2739 | } | 2744 | } |
| 2740 | 2745 | ||
| 2746 | const struct ZigClangExpr *ZigClangConvertVectorExpr_getSrcExpr(const struct ZigClangConvertVectorExpr *self) { | ||
| 2747 | auto casted = reinterpret_cast<const clang::ConvertVectorExpr *>(self); | ||
| 2748 | return reinterpret_cast<const struct ZigClangExpr *>(casted->getSrcExpr()); | ||
| 2749 | } | ||
| 2750 | |||
| 2751 | struct ZigClangQualType ZigClangConvertVectorExpr_getTypeSourceInfo_getType(const struct ZigClangConvertVectorExpr *self) { | ||
| 2752 | auto casted = reinterpret_cast<const clang::ConvertVectorExpr *>(self); | ||
| 2753 | return bitcast(casted->getTypeSourceInfo()->getType()); | ||
| 2754 | } | ||
| 2755 | |||
| 2741 | struct ZigClangQualType ZigClangDecayedType_getDecayedType(const struct ZigClangDecayedType *self) { | 2756 | struct ZigClangQualType ZigClangDecayedType_getDecayedType(const struct ZigClangDecayedType *self) { |
| 2742 | auto casted = reinterpret_cast<const clang::DecayedType *>(self); | 2757 | auto casted = reinterpret_cast<const clang::DecayedType *>(self); |
| 2743 | return bitcast(casted->getDecayedType()); | 2758 | return bitcast(casted->getDecayedType()); |
| ... | @@ -2843,6 +2858,16 @@ struct ZigClangQualType ZigClangValueDecl_getType(const struct ZigClangValueDecl | ... | @@ -2843,6 +2858,16 @@ struct ZigClangQualType ZigClangValueDecl_getType(const struct ZigClangValueDecl |
| 2843 | return bitcast(casted->getType()); | 2858 | return bitcast(casted->getType()); |
| 2844 | } | 2859 | } |
| 2845 | 2860 | ||
| 2861 | struct ZigClangQualType ZigClangVectorType_getElementType(const struct ZigClangVectorType *self) { | ||
| 2862 | auto casted = reinterpret_cast<const clang::VectorType *>(self); | ||
| 2863 | return bitcast(casted->getElementType()); | ||
| 2864 | } | ||
| 2865 | |||
| 2866 | unsigned ZigClangVectorType_getNumElements(const struct ZigClangVectorType *self) { | ||
| 2867 | auto casted = reinterpret_cast<const clang::VectorType *>(self); | ||
| 2868 | return casted->getNumElements(); | ||
| 2869 | } | ||
| 2870 | |||
| 2846 | const struct ZigClangExpr *ZigClangWhileStmt_getCond(const struct ZigClangWhileStmt *self) { | 2871 | const struct ZigClangExpr *ZigClangWhileStmt_getCond(const struct ZigClangWhileStmt *self) { |
| 2847 | auto casted = reinterpret_cast<const clang::WhileStmt *>(self); | 2872 | auto casted = reinterpret_cast<const clang::WhileStmt *>(self); |
| 2848 | return reinterpret_cast<const struct ZigClangExpr *>(casted->getCond()); | 2873 | return reinterpret_cast<const struct ZigClangExpr *>(casted->getCond()); |
| ... | @@ -2922,6 +2947,15 @@ struct ZigClangSourceLocation ZigClangUnaryExprOrTypeTraitExpr_getBeginLoc( | ... | @@ -2922,6 +2947,15 @@ struct ZigClangSourceLocation ZigClangUnaryExprOrTypeTraitExpr_getBeginLoc( |
| 2922 | return bitcast(casted->getBeginLoc()); | 2947 | return bitcast(casted->getBeginLoc()); |
| 2923 | } | 2948 | } |
| 2924 | 2949 | ||
| 2950 | unsigned ZigClangShuffleVectorExpr_getNumSubExprs(const ZigClangShuffleVectorExpr *self) { | ||
| 2951 | auto casted = reinterpret_cast<const clang::ShuffleVectorExpr *>(self); | ||
| 2952 | return casted->getNumSubExprs(); | ||
| 2953 | } | ||
| 2954 | |||
| 2955 | const struct ZigClangExpr *ZigClangShuffleVectorExpr_getExpr(const struct ZigClangShuffleVectorExpr *self, unsigned idx) { | ||
| 2956 | auto casted = reinterpret_cast<const clang::ShuffleVectorExpr *>(self); | ||
| 2957 | return reinterpret_cast<const struct ZigClangExpr *>(casted->getExpr(idx)); | ||
| 2958 | } | ||
| 2925 | 2959 | ||
| 2926 | enum ZigClangUnaryExprOrTypeTrait_Kind ZigClangUnaryExprOrTypeTraitExpr_getKind( | 2960 | enum ZigClangUnaryExprOrTypeTrait_Kind ZigClangUnaryExprOrTypeTraitExpr_getKind( |
| 2927 | const struct ZigClangUnaryExprOrTypeTraitExpr *self) | 2961 | const struct ZigClangUnaryExprOrTypeTraitExpr *self) |
src/zig_clang.h+10| ... | @@ -1064,6 +1064,7 @@ ZIG_EXTERN_C bool ZigClangType_isBooleanType(const struct ZigClangType *self); | ... | @@ -1064,6 +1064,7 @@ ZIG_EXTERN_C bool ZigClangType_isBooleanType(const struct ZigClangType *self); |
| 1064 | ZIG_EXTERN_C bool ZigClangType_isVoidType(const struct ZigClangType *self); | 1064 | ZIG_EXTERN_C bool ZigClangType_isVoidType(const struct ZigClangType *self); |
| 1065 | ZIG_EXTERN_C bool ZigClangType_isArrayType(const struct ZigClangType *self); | 1065 | ZIG_EXTERN_C bool ZigClangType_isArrayType(const struct ZigClangType *self); |
| 1066 | ZIG_EXTERN_C bool ZigClangType_isRecordType(const struct ZigClangType *self); | 1066 | ZIG_EXTERN_C bool ZigClangType_isRecordType(const struct ZigClangType *self); |
| 1067 | ZIG_EXTERN_C bool ZigClangType_isVectorType(const struct ZigClangType *self); | ||
| 1067 | ZIG_EXTERN_C bool ZigClangType_isIncompleteOrZeroLengthArrayType(const ZigClangQualType *self, const struct ZigClangASTContext *ctx); | 1068 | ZIG_EXTERN_C bool ZigClangType_isIncompleteOrZeroLengthArrayType(const ZigClangQualType *self, const struct ZigClangASTContext *ctx); |
| 1068 | ZIG_EXTERN_C bool ZigClangType_isConstantArrayType(const ZigClangType *self); | 1069 | ZIG_EXTERN_C bool ZigClangType_isConstantArrayType(const ZigClangType *self); |
| 1069 | ZIG_EXTERN_C const char *ZigClangType_getTypeClassName(const struct ZigClangType *self); | 1070 | ZIG_EXTERN_C const char *ZigClangType_getTypeClassName(const struct ZigClangType *self); |
| ... | @@ -1199,6 +1200,9 @@ ZIG_EXTERN_C const struct ZigClangExpr *ZigClangBinaryOperator_getLHS(const stru | ... | @@ -1199,6 +1200,9 @@ ZIG_EXTERN_C const struct ZigClangExpr *ZigClangBinaryOperator_getLHS(const stru |
| 1199 | ZIG_EXTERN_C const struct ZigClangExpr *ZigClangBinaryOperator_getRHS(const struct ZigClangBinaryOperator *); | 1200 | ZIG_EXTERN_C const struct ZigClangExpr *ZigClangBinaryOperator_getRHS(const struct ZigClangBinaryOperator *); |
| 1200 | ZIG_EXTERN_C struct ZigClangQualType ZigClangBinaryOperator_getType(const struct ZigClangBinaryOperator *); | 1201 | ZIG_EXTERN_C struct ZigClangQualType ZigClangBinaryOperator_getType(const struct ZigClangBinaryOperator *); |
| 1201 | 1202 | ||
| 1203 | ZIG_EXTERN_C const struct ZigClangExpr *ZigClangConvertVectorExpr_getSrcExpr(const struct ZigClangConvertVectorExpr *); | ||
| 1204 | ZIG_EXTERN_C struct ZigClangQualType ZigClangConvertVectorExpr_getTypeSourceInfo_getType(const struct ZigClangConvertVectorExpr *); | ||
| 1205 | |||
| 1202 | ZIG_EXTERN_C struct ZigClangQualType ZigClangDecayedType_getDecayedType(const struct ZigClangDecayedType *); | 1206 | ZIG_EXTERN_C struct ZigClangQualType ZigClangDecayedType_getDecayedType(const struct ZigClangDecayedType *); |
| 1203 | 1207 | ||
| 1204 | ZIG_EXTERN_C const struct ZigClangCompoundStmt *ZigClangStmtExpr_getSubStmt(const struct ZigClangStmtExpr *); | 1208 | ZIG_EXTERN_C const struct ZigClangCompoundStmt *ZigClangStmtExpr_getSubStmt(const struct ZigClangStmtExpr *); |
| ... | @@ -1228,6 +1232,9 @@ ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangUnaryOperator_getBeginLoc(con | ... | @@ -1228,6 +1232,9 @@ ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangUnaryOperator_getBeginLoc(con |
| 1228 | 1232 | ||
| 1229 | ZIG_EXTERN_C struct ZigClangQualType ZigClangValueDecl_getType(const struct ZigClangValueDecl *); | 1233 | ZIG_EXTERN_C struct ZigClangQualType ZigClangValueDecl_getType(const struct ZigClangValueDecl *); |
| 1230 | 1234 | ||
| 1235 | ZIG_EXTERN_C struct ZigClangQualType ZigClangVectorType_getElementType(const struct ZigClangVectorType *); | ||
| 1236 | ZIG_EXTERN_C unsigned ZigClangVectorType_getNumElements(const struct ZigClangVectorType *); | ||
| 1237 | |||
| 1231 | ZIG_EXTERN_C const struct ZigClangExpr *ZigClangWhileStmt_getCond(const struct ZigClangWhileStmt *); | 1238 | ZIG_EXTERN_C const struct ZigClangExpr *ZigClangWhileStmt_getCond(const struct ZigClangWhileStmt *); |
| 1232 | ZIG_EXTERN_C const struct ZigClangStmt *ZigClangWhileStmt_getBody(const struct ZigClangWhileStmt *); | 1239 | ZIG_EXTERN_C const struct ZigClangStmt *ZigClangWhileStmt_getBody(const struct ZigClangWhileStmt *); |
| 1233 | 1240 | ||
| ... | @@ -1252,6 +1259,9 @@ ZIG_EXTERN_C struct ZigClangQualType ZigClangUnaryExprOrTypeTraitExpr_getTypeOfA | ... | @@ -1252,6 +1259,9 @@ ZIG_EXTERN_C struct ZigClangQualType ZigClangUnaryExprOrTypeTraitExpr_getTypeOfA |
| 1252 | ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangUnaryExprOrTypeTraitExpr_getBeginLoc(const struct ZigClangUnaryExprOrTypeTraitExpr *); | 1259 | ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangUnaryExprOrTypeTraitExpr_getBeginLoc(const struct ZigClangUnaryExprOrTypeTraitExpr *); |
| 1253 | ZIG_EXTERN_C enum ZigClangUnaryExprOrTypeTrait_Kind ZigClangUnaryExprOrTypeTraitExpr_getKind(const struct ZigClangUnaryExprOrTypeTraitExpr *); | 1260 | ZIG_EXTERN_C enum ZigClangUnaryExprOrTypeTrait_Kind ZigClangUnaryExprOrTypeTraitExpr_getKind(const struct ZigClangUnaryExprOrTypeTraitExpr *); |
| 1254 | 1261 | ||
| 1262 | ZIG_EXTERN_C unsigned ZigClangShuffleVectorExpr_getNumSubExprs(const struct ZigClangShuffleVectorExpr *); | ||
| 1263 | ZIG_EXTERN_C const struct ZigClangExpr *ZigClangShuffleVectorExpr_getExpr(const struct ZigClangShuffleVectorExpr *, unsigned); | ||
| 1264 | |||
| 1255 | ZIG_EXTERN_C const struct ZigClangStmt *ZigClangDoStmt_getBody(const struct ZigClangDoStmt *); | 1265 | ZIG_EXTERN_C const struct ZigClangStmt *ZigClangDoStmt_getBody(const struct ZigClangDoStmt *); |
| 1256 | ZIG_EXTERN_C const struct ZigClangExpr *ZigClangDoStmt_getCond(const struct ZigClangDoStmt *); | 1266 | ZIG_EXTERN_C const struct ZigClangExpr *ZigClangDoStmt_getCond(const struct ZigClangDoStmt *); |
| 1257 | 1267 |
test/run_translated_c.zig+102| ... | @@ -1308,4 +1308,106 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { | ... | @@ -1308,4 +1308,106 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { |
| 1308 | \\ ufoo = (uval += 100000000); // compile error if @truncate() not inserted | 1308 | \\ ufoo = (uval += 100000000); // compile error if @truncate() not inserted |
| 1309 | \\} | 1309 | \\} |
| 1310 | , ""); | 1310 | , ""); |
| 1311 | |||
| 1312 | cases.add("basic vector expressions", | ||
| 1313 | \\#include <stdlib.h> | ||
| 1314 | \\#include <stdint.h> | ||
| 1315 | \\typedef int16_t __v8hi __attribute__((__vector_size__(16))); | ||
| 1316 | \\int main(int argc, char**argv) { | ||
| 1317 | \\ __v8hi uninitialized; | ||
| 1318 | \\ __v8hi empty_init = {}; | ||
| 1319 | \\ __v8hi partial_init = {0, 1, 2, 3}; | ||
| 1320 | \\ | ||
| 1321 | \\ __v8hi a = {0, 1, 2, 3, 4, 5, 6, 7}; | ||
| 1322 | \\ __v8hi b = (__v8hi) {100, 200, 300, 400, 500, 600, 700, 800}; | ||
| 1323 | \\ | ||
| 1324 | \\ __v8hi sum = a + b; | ||
| 1325 | \\ for (int i = 0; i < 8; i++) { | ||
| 1326 | \\ if (sum[i] != a[i] + b[i]) abort(); | ||
| 1327 | \\ } | ||
| 1328 | \\ return 0; | ||
| 1329 | \\} | ||
| 1330 | , ""); | ||
| 1331 | |||
| 1332 | cases.add("__builtin_shufflevector", | ||
| 1333 | \\#include <stdlib.h> | ||
| 1334 | \\#include <stdint.h> | ||
| 1335 | \\typedef int16_t __v4hi __attribute__((__vector_size__(8))); | ||
| 1336 | \\typedef int16_t __v8hi __attribute__((__vector_size__(16))); | ||
| 1337 | \\int main(int argc, char**argv) { | ||
| 1338 | \\ __v8hi v8_a = {0, 1, 2, 3, 4, 5, 6, 7}; | ||
| 1339 | \\ __v8hi v8_b = {100, 200, 300, 400, 500, 600, 700, 800}; | ||
| 1340 | \\ __v8hi shuffled = __builtin_shufflevector(v8_a, v8_b, 0, 1, 2, 3, 8, 9, 10, 11); | ||
| 1341 | \\ for (int i = 0; i < 8; i++) { | ||
| 1342 | \\ if (i < 4) { | ||
| 1343 | \\ if (shuffled[i] != v8_a[i]) abort(); | ||
| 1344 | \\ } else { | ||
| 1345 | \\ if (shuffled[i] != v8_b[i - 4]) abort(); | ||
| 1346 | \\ } | ||
| 1347 | \\ } | ||
| 1348 | \\ shuffled = __builtin_shufflevector( | ||
| 1349 | \\ (__v8hi) {-1, -1, -1, -1, -1, -1, -1, -1}, | ||
| 1350 | \\ (__v8hi) {42, 42, 42, 42, 42, 42, 42, 42}, | ||
| 1351 | \\ 0, 1, 2, 3, 8, 9, 10, 11 | ||
| 1352 | \\ ); | ||
| 1353 | \\ for (int i = 0; i < 8; i++) { | ||
| 1354 | \\ if (i < 4) { | ||
| 1355 | \\ if (shuffled[i] != -1) abort(); | ||
| 1356 | \\ } else { | ||
| 1357 | \\ if (shuffled[i] != 42) abort(); | ||
| 1358 | \\ } | ||
| 1359 | \\ } | ||
| 1360 | \\ __v4hi shuffled_to_fewer_elements = __builtin_shufflevector(v8_a, v8_b, 0, 1, 8, 9); | ||
| 1361 | \\ for (int i = 0; i < 4; i++) { | ||
| 1362 | \\ if (i < 2) { | ||
| 1363 | \\ if (shuffled_to_fewer_elements[i] != v8_a[i]) abort(); | ||
| 1364 | \\ } else { | ||
| 1365 | \\ if (shuffled_to_fewer_elements[i] != v8_b[i - 2]) abort(); | ||
| 1366 | \\ } | ||
| 1367 | \\ } | ||
| 1368 | \\ __v4hi v4_a = {0, 1, 2, 3}; | ||
| 1369 | \\ __v4hi v4_b = {100, 200, 300, 400}; | ||
| 1370 | \\ __v8hi shuffled_to_more_elements = __builtin_shufflevector(v4_a, v4_b, 0, 1, 2, 3, 4, 5, 6, 7); | ||
| 1371 | \\ for (int i = 0; i < 4; i++) { | ||
| 1372 | \\ if (shuffled_to_more_elements[i] != v4_a[i]) abort(); | ||
| 1373 | \\ if (shuffled_to_more_elements[i + 4] != v4_b[i]) abort(); | ||
| 1374 | \\ } | ||
| 1375 | \\ return 0; | ||
| 1376 | \\} | ||
| 1377 | , ""); | ||
| 1378 | |||
| 1379 | cases.add("__builtin_convertvector", | ||
| 1380 | \\#include <stdlib.h> | ||
| 1381 | \\#include <stdint.h> | ||
| 1382 | \\typedef int16_t __v8hi __attribute__((__vector_size__(16))); | ||
| 1383 | \\typedef uint16_t __v8hu __attribute__((__vector_size__(16))); | ||
| 1384 | \\int main(int argc, char**argv) { | ||
| 1385 | \\ __v8hi signed_vector = { 1, 2, 3, 4, -1, -2, -3,-4}; | ||
| 1386 | \\ __v8hu unsigned_vector = __builtin_convertvector(signed_vector, __v8hu); | ||
| 1387 | \\ | ||
| 1388 | \\ for (int i = 0; i < 8; i++) { | ||
| 1389 | \\ if (unsigned_vector[i] != (uint16_t)signed_vector[i]) abort(); | ||
| 1390 | \\ } | ||
| 1391 | \\ return 0; | ||
| 1392 | \\} | ||
| 1393 | , ""); | ||
| 1394 | |||
| 1395 | cases.add("vector casting", | ||
| 1396 | \\#include <stdlib.h> | ||
| 1397 | \\#include <stdint.h> | ||
| 1398 | \\typedef int8_t __v8qi __attribute__((__vector_size__(8))); | ||
| 1399 | \\typedef uint8_t __v8qu __attribute__((__vector_size__(8))); | ||
| 1400 | \\int main(int argc, char**argv) { | ||
| 1401 | \\ __v8qi signed_vector = { 1, 2, 3, 4, -1, -2, -3,-4}; | ||
| 1402 | \\ | ||
| 1403 | \\ uint64_t big_int = (uint64_t) signed_vector; | ||
| 1404 | \\ if (big_int != 0x01020304FFFEFDFCULL && big_int != 0xFCFDFEFF04030201ULL) abort(); | ||
| 1405 | \\ __v8qu unsigned_vector = (__v8qu) big_int; | ||
| 1406 | \\ for (int i = 0; i < 8; i++) { | ||
| 1407 | \\ if (unsigned_vector[i] != (uint8_t)signed_vector[i] && unsigned_vector[i] != (uint8_t)signed_vector[7 - i]) abort(); | ||
| 1408 | \\ } | ||
| 1409 | \\ return 0; | ||
| 1410 | \\} | ||
| 1411 | , ""); | ||
| 1412 | |||
| 1311 | } | 1413 | } |