mirror of
https://github.com/ziglang/zig.git
synced 2025-12-31 10:33:19 +00:00
Merge pull request #2602 from ziglang/copy-elision-3
result location mechanism (part of no-copy semantics)
This commit is contained in:
commit
01ff0d4d62
@ -6734,6 +6734,7 @@ add_custom_command(
|
||||
"-Doutput-dir=${CMAKE_BINARY_DIR}"
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
DEPENDS
|
||||
zig0
|
||||
"${CMAKE_SOURCE_DIR}/src-self-hosted/dep_tokenizer.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src-self-hosted/stage1.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src-self-hosted/translate_c.zig"
|
||||
|
||||
@ -74,7 +74,8 @@ pub fn build(b: *Builder) !void {
|
||||
const skip_non_native = b.option(bool, "skip-non-native", "Main test suite skips non-native builds") orelse false;
|
||||
const skip_self_hosted = b.option(bool, "skip-self-hosted", "Main test suite skips building self hosted compiler") orelse false;
|
||||
if (!skip_self_hosted) {
|
||||
test_step.dependOn(&exe.step);
|
||||
// TODO re-enable this after https://github.com/ziglang/zig/issues/2377
|
||||
//test_step.dependOn(&exe.step);
|
||||
}
|
||||
const verbose_link_exe = b.option(bool, "verbose-link", "Print link command for self hosted compiler") orelse false;
|
||||
exe.setVerboseLink(verbose_link_exe);
|
||||
|
||||
@ -5096,7 +5096,7 @@ fn gimmeTheBiggerInteger(a: u64, b: u64) u64 {
|
||||
<p>
|
||||
For example, if we were to introduce another function to the above snippet:
|
||||
</p>
|
||||
{#code_begin|test_err|values of type 'type' must be comptime known#}
|
||||
{#code_begin|test_err|cannot store runtime value in type 'type'#}
|
||||
fn max(comptime T: type, a: T, b: T) T {
|
||||
return if (a > b) a else b;
|
||||
}
|
||||
|
||||
@ -34,12 +34,17 @@ struct CodeGen;
|
||||
struct ConstExprValue;
|
||||
struct IrInstruction;
|
||||
struct IrInstructionCast;
|
||||
struct IrInstructionAllocaGen;
|
||||
struct IrBasicBlock;
|
||||
struct ScopeDecls;
|
||||
struct ZigWindowsSDK;
|
||||
struct Tld;
|
||||
struct TldExport;
|
||||
struct IrAnalyze;
|
||||
struct ResultLoc;
|
||||
struct ResultLocPeer;
|
||||
struct ResultLocPeerParent;
|
||||
struct ResultLocBitCast;
|
||||
|
||||
enum X64CABIClass {
|
||||
X64CABIClass_Unknown,
|
||||
@ -198,6 +203,9 @@ enum ConstPtrMut {
|
||||
// The pointer points to memory that is known only at runtime.
|
||||
// For example it may point to the initializer value of a variable.
|
||||
ConstPtrMutRuntimeVar,
|
||||
// The pointer points to memory for which it must be inferred whether the
|
||||
// value is comptime known or not.
|
||||
ConstPtrMutInfer,
|
||||
};
|
||||
|
||||
struct ConstPtrValue {
|
||||
@ -289,6 +297,7 @@ struct RuntimeHintSlice {
|
||||
struct ConstGlobalRefs {
|
||||
LLVMValueRef llvm_value;
|
||||
LLVMValueRef llvm_global;
|
||||
uint32_t align;
|
||||
};
|
||||
|
||||
struct ConstExprValue {
|
||||
@ -325,6 +334,10 @@ struct ConstExprValue {
|
||||
RuntimeHintPtr rh_ptr;
|
||||
RuntimeHintSlice rh_slice;
|
||||
} data;
|
||||
|
||||
// uncomment these to find bugs. can't leave them uncommented because of a gcc-9 warning
|
||||
//ConstExprValue(const ConstExprValue &other) = delete; // plz zero initialize with {}
|
||||
//ConstExprValue& operator= (const ConstExprValue &other) = delete; // use copy_const_val
|
||||
};
|
||||
|
||||
enum ReturnKnowledge {
|
||||
@ -426,7 +439,7 @@ enum NodeType {
|
||||
NodeTypeVariableDeclaration,
|
||||
NodeTypeTestDecl,
|
||||
NodeTypeBinOpExpr,
|
||||
NodeTypeUnwrapErrorExpr,
|
||||
NodeTypeCatchExpr,
|
||||
NodeTypeFloatLiteral,
|
||||
NodeTypeIntLiteral,
|
||||
NodeTypeStringLiteral,
|
||||
@ -1364,7 +1377,7 @@ struct ZigFn {
|
||||
AstNode *fn_no_inline_set_node;
|
||||
AstNode *fn_static_eval_set_node;
|
||||
|
||||
ZigList<IrInstruction *> alloca_list;
|
||||
ZigList<IrInstructionAllocaGen *> alloca_gen_list;
|
||||
ZigList<ZigVar *> variable_list;
|
||||
|
||||
Buf *section_name;
|
||||
@ -1999,6 +2012,11 @@ struct ScopeDecls {
|
||||
bool any_imports_failed;
|
||||
};
|
||||
|
||||
enum LVal {
|
||||
LValNone,
|
||||
LValPtr,
|
||||
};
|
||||
|
||||
// This scope comes from a block expression in user code.
|
||||
// NodeTypeBlock
|
||||
struct ScopeBlock {
|
||||
@ -2007,12 +2025,14 @@ struct ScopeBlock {
|
||||
Buf *name;
|
||||
IrBasicBlock *end_block;
|
||||
IrInstruction *is_comptime;
|
||||
ResultLocPeerParent *peer_parent;
|
||||
ZigList<IrInstruction *> *incoming_values;
|
||||
ZigList<IrBasicBlock *> *incoming_blocks;
|
||||
|
||||
AstNode *safety_set_node;
|
||||
AstNode *fast_math_set_node;
|
||||
|
||||
LVal lval;
|
||||
bool safety_off;
|
||||
bool fast_math_on;
|
||||
};
|
||||
@ -2056,12 +2076,14 @@ struct ScopeCImport {
|
||||
struct ScopeLoop {
|
||||
Scope base;
|
||||
|
||||
LVal lval;
|
||||
Buf *name;
|
||||
IrBasicBlock *break_block;
|
||||
IrBasicBlock *continue_block;
|
||||
IrInstruction *is_comptime;
|
||||
ZigList<IrInstruction *> *incoming_values;
|
||||
ZigList<IrBasicBlock *> *incoming_blocks;
|
||||
ResultLocPeerParent *peer_parent;
|
||||
};
|
||||
|
||||
// This scope blocks certain things from working such as comptime continue
|
||||
@ -2138,6 +2160,8 @@ struct IrBasicBlock {
|
||||
const char *name_hint;
|
||||
size_t debug_id;
|
||||
size_t ref_count;
|
||||
// index into the basic block list
|
||||
size_t index;
|
||||
LLVMBasicBlockRef llvm_block;
|
||||
LLVMBasicBlockRef llvm_exit_block;
|
||||
// The instruction that referenced this basic block and caused us to
|
||||
@ -2148,11 +2172,10 @@ struct IrBasicBlock {
|
||||
// if the branch is comptime. The instruction points to the reason
|
||||
// the basic block must be comptime.
|
||||
IrInstruction *must_be_comptime_source_instr;
|
||||
};
|
||||
|
||||
enum LVal {
|
||||
LValNone,
|
||||
LValPtr,
|
||||
IrInstruction *suspend_instruction_ref;
|
||||
bool already_appended;
|
||||
bool suspended;
|
||||
bool in_resume_stack;
|
||||
};
|
||||
|
||||
// These instructions are in transition to having "pass 1" instructions
|
||||
@ -2185,19 +2208,17 @@ enum IrInstructionId {
|
||||
IrInstructionIdUnionFieldPtr,
|
||||
IrInstructionIdElemPtr,
|
||||
IrInstructionIdVarPtr,
|
||||
IrInstructionIdCall,
|
||||
IrInstructionIdReturnPtr,
|
||||
IrInstructionIdCallSrc,
|
||||
IrInstructionIdCallGen,
|
||||
IrInstructionIdConst,
|
||||
IrInstructionIdReturn,
|
||||
IrInstructionIdCast,
|
||||
IrInstructionIdResizeSlice,
|
||||
IrInstructionIdContainerInitList,
|
||||
IrInstructionIdContainerInitFields,
|
||||
IrInstructionIdStructInit,
|
||||
IrInstructionIdUnionInit,
|
||||
IrInstructionIdUnreachable,
|
||||
IrInstructionIdTypeOf,
|
||||
IrInstructionIdToPtrType,
|
||||
IrInstructionIdPtrTypeChild,
|
||||
IrInstructionIdSetCold,
|
||||
IrInstructionIdSetRuntimeSafety,
|
||||
IrInstructionIdSetFloatMode,
|
||||
@ -2222,6 +2243,7 @@ enum IrInstructionId {
|
||||
IrInstructionIdCDefine,
|
||||
IrInstructionIdCUndef,
|
||||
IrInstructionIdRef,
|
||||
IrInstructionIdRefGen,
|
||||
IrInstructionIdCompileErr,
|
||||
IrInstructionIdCompileLog,
|
||||
IrInstructionIdErrName,
|
||||
@ -2240,7 +2262,8 @@ enum IrInstructionId {
|
||||
IrInstructionIdBoolNot,
|
||||
IrInstructionIdMemset,
|
||||
IrInstructionIdMemcpy,
|
||||
IrInstructionIdSlice,
|
||||
IrInstructionIdSliceSrc,
|
||||
IrInstructionIdSliceGen,
|
||||
IrInstructionIdMemberCount,
|
||||
IrInstructionIdMemberType,
|
||||
IrInstructionIdMemberName,
|
||||
@ -2250,9 +2273,10 @@ enum IrInstructionId {
|
||||
IrInstructionIdHandle,
|
||||
IrInstructionIdAlignOf,
|
||||
IrInstructionIdOverflowOp,
|
||||
IrInstructionIdTestErrSrc,
|
||||
IrInstructionIdTestErrGen,
|
||||
IrInstructionIdMulAdd,
|
||||
IrInstructionIdFloatOp,
|
||||
IrInstructionIdTestErr,
|
||||
IrInstructionIdUnwrapErrCode,
|
||||
IrInstructionIdUnwrapErrPayload,
|
||||
IrInstructionIdErrWrapCode,
|
||||
@ -2261,7 +2285,7 @@ enum IrInstructionId {
|
||||
IrInstructionIdTestComptime,
|
||||
IrInstructionIdPtrCastSrc,
|
||||
IrInstructionIdPtrCastGen,
|
||||
IrInstructionIdBitCast,
|
||||
IrInstructionIdBitCastSrc,
|
||||
IrInstructionIdBitCastGen,
|
||||
IrInstructionIdWidenOrShorten,
|
||||
IrInstructionIdIntToPtr,
|
||||
@ -2285,6 +2309,10 @@ enum IrInstructionId {
|
||||
IrInstructionIdSetEvalBranchQuota,
|
||||
IrInstructionIdPtrType,
|
||||
IrInstructionIdAlignCast,
|
||||
IrInstructionIdImplicitCast,
|
||||
IrInstructionIdResolveResult,
|
||||
IrInstructionIdResetResult,
|
||||
IrInstructionIdResultPtr,
|
||||
IrInstructionIdOpaqueType,
|
||||
IrInstructionIdSetAlignStack,
|
||||
IrInstructionIdArgType,
|
||||
@ -2323,10 +2351,13 @@ enum IrInstructionId {
|
||||
IrInstructionIdAssertNonNull,
|
||||
IrInstructionIdHasDecl,
|
||||
IrInstructionIdUndeclaredIdent,
|
||||
IrInstructionIdAllocaSrc,
|
||||
IrInstructionIdAllocaGen,
|
||||
IrInstructionIdEndExpr,
|
||||
IrInstructionIdPtrOfArrayToSlice,
|
||||
};
|
||||
|
||||
struct IrInstruction {
|
||||
IrInstructionId id;
|
||||
Scope *scope;
|
||||
AstNode *source_node;
|
||||
ConstExprValue value;
|
||||
@ -2340,6 +2371,7 @@ struct IrInstruction {
|
||||
// with this child field.
|
||||
IrInstruction *child;
|
||||
IrBasicBlock *owner_bb;
|
||||
IrInstructionId id;
|
||||
// true if this instruction was generated by zig and not from user code
|
||||
bool is_gen;
|
||||
};
|
||||
@ -2350,14 +2382,14 @@ struct IrInstructionDeclVarSrc {
|
||||
ZigVar *var;
|
||||
IrInstruction *var_type;
|
||||
IrInstruction *align_value;
|
||||
IrInstruction *init_value;
|
||||
IrInstruction *ptr;
|
||||
};
|
||||
|
||||
struct IrInstructionDeclVarGen {
|
||||
IrInstruction base;
|
||||
|
||||
ZigVar *var;
|
||||
IrInstruction *init_value;
|
||||
IrInstruction *var_ptr;
|
||||
};
|
||||
|
||||
struct IrInstructionCondBr {
|
||||
@ -2367,6 +2399,7 @@ struct IrInstructionCondBr {
|
||||
IrBasicBlock *then_block;
|
||||
IrBasicBlock *else_block;
|
||||
IrInstruction *is_comptime;
|
||||
ResultLoc *result_loc;
|
||||
};
|
||||
|
||||
struct IrInstructionBr {
|
||||
@ -2419,6 +2452,7 @@ struct IrInstructionPhi {
|
||||
size_t incoming_count;
|
||||
IrBasicBlock **incoming_blocks;
|
||||
IrInstruction **incoming_values;
|
||||
ResultLocPeerParent *peer_parent;
|
||||
};
|
||||
|
||||
enum IrUnOp {
|
||||
@ -2434,8 +2468,9 @@ struct IrInstructionUnOp {
|
||||
IrInstruction base;
|
||||
|
||||
IrUnOp op_id;
|
||||
IrInstruction *value;
|
||||
LVal lval;
|
||||
IrInstruction *value;
|
||||
ResultLoc *result_loc;
|
||||
};
|
||||
|
||||
enum IrBinOp {
|
||||
@ -2492,7 +2527,7 @@ struct IrInstructionLoadPtrGen {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *ptr;
|
||||
LLVMValueRef tmp_ptr;
|
||||
IrInstruction *result_loc;
|
||||
};
|
||||
|
||||
struct IrInstructionStorePtr {
|
||||
@ -2505,6 +2540,7 @@ struct IrInstructionStorePtr {
|
||||
struct IrInstructionFieldPtr {
|
||||
IrInstruction base;
|
||||
|
||||
bool initializing;
|
||||
IrInstruction *container_ptr;
|
||||
Buf *field_name_buffer;
|
||||
IrInstruction *field_name_expr;
|
||||
@ -2521,9 +2557,10 @@ struct IrInstructionStructFieldPtr {
|
||||
struct IrInstructionUnionFieldPtr {
|
||||
IrInstruction base;
|
||||
|
||||
bool safety_check_on;
|
||||
bool initializing;
|
||||
IrInstruction *union_ptr;
|
||||
TypeUnionField *field;
|
||||
bool is_const;
|
||||
};
|
||||
|
||||
struct IrInstructionElemPtr {
|
||||
@ -2531,8 +2568,8 @@ struct IrInstructionElemPtr {
|
||||
|
||||
IrInstruction *array_ptr;
|
||||
IrInstruction *elem_index;
|
||||
IrInstruction *init_array_type;
|
||||
PtrLen ptr_len;
|
||||
bool is_const;
|
||||
bool safety_check_on;
|
||||
};
|
||||
|
||||
@ -2543,14 +2580,21 @@ struct IrInstructionVarPtr {
|
||||
ScopeFnDef *crossed_fndef_scope;
|
||||
};
|
||||
|
||||
struct IrInstructionCall {
|
||||
// For functions that have a return type for which handle_is_ptr is true, a
|
||||
// result location pointer is the secret first parameter ("sret"). This
|
||||
// instruction returns that pointer.
|
||||
struct IrInstructionReturnPtr {
|
||||
IrInstruction base;
|
||||
};
|
||||
|
||||
struct IrInstructionCallSrc {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *fn_ref;
|
||||
ZigFn *fn_entry;
|
||||
size_t arg_count;
|
||||
IrInstruction **args;
|
||||
LLVMValueRef tmp_ptr;
|
||||
ResultLoc *result_loc;
|
||||
|
||||
IrInstruction *async_allocator;
|
||||
IrInstruction *new_stack;
|
||||
@ -2559,6 +2603,21 @@ struct IrInstructionCall {
|
||||
bool is_comptime;
|
||||
};
|
||||
|
||||
struct IrInstructionCallGen {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *fn_ref;
|
||||
ZigFn *fn_entry;
|
||||
size_t arg_count;
|
||||
IrInstruction **args;
|
||||
IrInstruction *result_loc;
|
||||
|
||||
IrInstruction *async_allocator;
|
||||
IrInstruction *new_stack;
|
||||
FnInline fn_inline;
|
||||
bool is_async;
|
||||
};
|
||||
|
||||
struct IrInstructionConst {
|
||||
IrInstruction base;
|
||||
};
|
||||
@ -2581,7 +2640,6 @@ enum CastOp {
|
||||
CastOpNumLitToConcrete,
|
||||
CastOpErrSet,
|
||||
CastOpBitCast,
|
||||
CastOpPtrOfArrayToSlice,
|
||||
};
|
||||
|
||||
// TODO get rid of this instruction, replace with instructions for each op code
|
||||
@ -2591,14 +2649,13 @@ struct IrInstructionCast {
|
||||
IrInstruction *value;
|
||||
ZigType *dest_type;
|
||||
CastOp cast_op;
|
||||
LLVMValueRef tmp_ptr;
|
||||
};
|
||||
|
||||
struct IrInstructionResizeSlice {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *operand;
|
||||
LLVMValueRef tmp_ptr;
|
||||
IrInstruction *result_loc;
|
||||
};
|
||||
|
||||
struct IrInstructionContainerInitList {
|
||||
@ -2607,15 +2664,15 @@ struct IrInstructionContainerInitList {
|
||||
IrInstruction *container_type;
|
||||
IrInstruction *elem_type;
|
||||
size_t item_count;
|
||||
IrInstruction **items;
|
||||
LLVMValueRef tmp_ptr;
|
||||
IrInstruction **elem_result_loc_list;
|
||||
IrInstruction *result_loc;
|
||||
};
|
||||
|
||||
struct IrInstructionContainerInitFieldsField {
|
||||
Buf *name;
|
||||
IrInstruction *value;
|
||||
AstNode *source_node;
|
||||
TypeStructField *type_struct_field;
|
||||
IrInstruction *result_loc;
|
||||
};
|
||||
|
||||
struct IrInstructionContainerInitFields {
|
||||
@ -2624,29 +2681,7 @@ struct IrInstructionContainerInitFields {
|
||||
IrInstruction *container_type;
|
||||
size_t field_count;
|
||||
IrInstructionContainerInitFieldsField *fields;
|
||||
};
|
||||
|
||||
struct IrInstructionStructInitField {
|
||||
IrInstruction *value;
|
||||
TypeStructField *type_struct_field;
|
||||
};
|
||||
|
||||
struct IrInstructionStructInit {
|
||||
IrInstruction base;
|
||||
|
||||
ZigType *struct_type;
|
||||
size_t field_count;
|
||||
IrInstructionStructInitField *fields;
|
||||
LLVMValueRef tmp_ptr;
|
||||
};
|
||||
|
||||
struct IrInstructionUnionInit {
|
||||
IrInstruction base;
|
||||
|
||||
ZigType *union_type;
|
||||
TypeUnionField *field;
|
||||
IrInstruction *init_value;
|
||||
LLVMValueRef tmp_ptr;
|
||||
IrInstruction *result_loc;
|
||||
};
|
||||
|
||||
struct IrInstructionUnreachable {
|
||||
@ -2659,18 +2694,6 @@ struct IrInstructionTypeOf {
|
||||
IrInstruction *value;
|
||||
};
|
||||
|
||||
struct IrInstructionToPtrType {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *ptr;
|
||||
};
|
||||
|
||||
struct IrInstructionPtrTypeChild {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *value;
|
||||
};
|
||||
|
||||
struct IrInstructionSetCold {
|
||||
IrInstruction base;
|
||||
|
||||
@ -2764,8 +2787,9 @@ struct IrInstructionTestNonNull {
|
||||
struct IrInstructionOptionalUnwrapPtr {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *base_ptr;
|
||||
bool safety_check_on;
|
||||
bool initializing;
|
||||
IrInstruction *base_ptr;
|
||||
};
|
||||
|
||||
struct IrInstructionCtz {
|
||||
@ -2805,11 +2829,17 @@ struct IrInstructionRef {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *value;
|
||||
LLVMValueRef tmp_ptr;
|
||||
bool is_const;
|
||||
bool is_volatile;
|
||||
};
|
||||
|
||||
struct IrInstructionRefGen {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *operand;
|
||||
IrInstruction *result_loc;
|
||||
};
|
||||
|
||||
struct IrInstructionCompileErr {
|
||||
IrInstruction base;
|
||||
|
||||
@ -2861,26 +2891,26 @@ struct IrInstructionEmbedFile {
|
||||
struct IrInstructionCmpxchgSrc {
|
||||
IrInstruction base;
|
||||
|
||||
bool is_weak;
|
||||
IrInstruction *type_value;
|
||||
IrInstruction *ptr;
|
||||
IrInstruction *cmp_value;
|
||||
IrInstruction *new_value;
|
||||
IrInstruction *success_order_value;
|
||||
IrInstruction *failure_order_value;
|
||||
|
||||
bool is_weak;
|
||||
ResultLoc *result_loc;
|
||||
};
|
||||
|
||||
struct IrInstructionCmpxchgGen {
|
||||
IrInstruction base;
|
||||
|
||||
bool is_weak;
|
||||
AtomicOrder success_order;
|
||||
AtomicOrder failure_order;
|
||||
IrInstruction *ptr;
|
||||
IrInstruction *cmp_value;
|
||||
IrInstruction *new_value;
|
||||
LLVMValueRef tmp_ptr;
|
||||
AtomicOrder success_order;
|
||||
AtomicOrder failure_order;
|
||||
bool is_weak;
|
||||
IrInstruction *result_loc;
|
||||
};
|
||||
|
||||
struct IrInstructionFence {
|
||||
@ -2924,6 +2954,7 @@ struct IrInstructionToBytes {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *target;
|
||||
ResultLoc *result_loc;
|
||||
};
|
||||
|
||||
struct IrInstructionFromBytes {
|
||||
@ -2931,6 +2962,7 @@ struct IrInstructionFromBytes {
|
||||
|
||||
IrInstruction *dest_child_type;
|
||||
IrInstruction *target;
|
||||
ResultLoc *result_loc;
|
||||
};
|
||||
|
||||
struct IrInstructionIntToFloat {
|
||||
@ -2989,14 +3021,24 @@ struct IrInstructionMemcpy {
|
||||
IrInstruction *count;
|
||||
};
|
||||
|
||||
struct IrInstructionSlice {
|
||||
struct IrInstructionSliceSrc {
|
||||
IrInstruction base;
|
||||
|
||||
bool safety_check_on;
|
||||
IrInstruction *ptr;
|
||||
IrInstruction *start;
|
||||
IrInstruction *end;
|
||||
ResultLoc *result_loc;
|
||||
};
|
||||
|
||||
struct IrInstructionSliceGen {
|
||||
IrInstruction base;
|
||||
|
||||
bool safety_check_on;
|
||||
LLVMValueRef tmp_ptr;
|
||||
IrInstruction *ptr;
|
||||
IrInstruction *start;
|
||||
IrInstruction *end;
|
||||
IrInstruction *result_loc;
|
||||
};
|
||||
|
||||
struct IrInstructionMemberCount {
|
||||
@ -3070,44 +3112,54 @@ struct IrInstructionAlignOf {
|
||||
};
|
||||
|
||||
// returns true if error, returns false if not error
|
||||
struct IrInstructionTestErr {
|
||||
struct IrInstructionTestErrSrc {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *value;
|
||||
bool resolve_err_set;
|
||||
IrInstruction *base_ptr;
|
||||
};
|
||||
|
||||
struct IrInstructionUnwrapErrCode {
|
||||
struct IrInstructionTestErrGen {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *err_union;
|
||||
};
|
||||
|
||||
// Takes an error union pointer, returns a pointer to the error code.
|
||||
struct IrInstructionUnwrapErrCode {
|
||||
IrInstruction base;
|
||||
|
||||
bool initializing;
|
||||
IrInstruction *err_union_ptr;
|
||||
};
|
||||
|
||||
struct IrInstructionUnwrapErrPayload {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *value;
|
||||
bool safety_check_on;
|
||||
bool initializing;
|
||||
IrInstruction *value;
|
||||
};
|
||||
|
||||
struct IrInstructionOptionalWrap {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *value;
|
||||
LLVMValueRef tmp_ptr;
|
||||
IrInstruction *operand;
|
||||
IrInstruction *result_loc;
|
||||
};
|
||||
|
||||
struct IrInstructionErrWrapPayload {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *value;
|
||||
LLVMValueRef tmp_ptr;
|
||||
IrInstruction *operand;
|
||||
IrInstruction *result_loc;
|
||||
};
|
||||
|
||||
struct IrInstructionErrWrapCode {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *value;
|
||||
LLVMValueRef tmp_ptr;
|
||||
IrInstruction *operand;
|
||||
IrInstruction *result_loc;
|
||||
};
|
||||
|
||||
struct IrInstructionFnProto {
|
||||
@ -3142,18 +3194,17 @@ struct IrInstructionPtrCastGen {
|
||||
bool safety_check_on;
|
||||
};
|
||||
|
||||
struct IrInstructionBitCast {
|
||||
struct IrInstructionBitCastSrc {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *dest_type;
|
||||
IrInstruction *value;
|
||||
IrInstruction *operand;
|
||||
ResultLocBitCast *result_loc_bit_cast;
|
||||
};
|
||||
|
||||
struct IrInstructionBitCastGen {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *operand;
|
||||
LLVMValueRef tmp_ptr;
|
||||
};
|
||||
|
||||
struct IrInstructionWidenOrShorten {
|
||||
@ -3229,8 +3280,8 @@ struct IrInstructionTypeName {
|
||||
struct IrInstructionDeclRef {
|
||||
IrInstruction base;
|
||||
|
||||
Tld *tld;
|
||||
LVal lval;
|
||||
Tld *tld;
|
||||
};
|
||||
|
||||
struct IrInstructionPanic {
|
||||
@ -3526,7 +3577,7 @@ struct IrInstructionVectorToArray {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *vector;
|
||||
LLVMValueRef tmp_ptr;
|
||||
IrInstruction *result_loc;
|
||||
};
|
||||
|
||||
struct IrInstructionAssertZero {
|
||||
@ -3554,6 +3605,139 @@ struct IrInstructionUndeclaredIdent {
|
||||
Buf *name;
|
||||
};
|
||||
|
||||
struct IrInstructionAllocaSrc {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *align;
|
||||
IrInstruction *is_comptime;
|
||||
const char *name_hint;
|
||||
};
|
||||
|
||||
struct IrInstructionAllocaGen {
|
||||
IrInstruction base;
|
||||
|
||||
uint32_t align;
|
||||
const char *name_hint;
|
||||
};
|
||||
|
||||
struct IrInstructionEndExpr {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *value;
|
||||
ResultLoc *result_loc;
|
||||
};
|
||||
|
||||
struct IrInstructionImplicitCast {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *dest_type;
|
||||
IrInstruction *target;
|
||||
ResultLoc *result_loc;
|
||||
};
|
||||
|
||||
// This one is for writing through the result pointer.
|
||||
struct IrInstructionResolveResult {
|
||||
IrInstruction base;
|
||||
|
||||
ResultLoc *result_loc;
|
||||
IrInstruction *ty;
|
||||
};
|
||||
|
||||
// This one is when you want to read the value of the result.
|
||||
// You have to give the value in case it is comptime.
|
||||
struct IrInstructionResultPtr {
|
||||
IrInstruction base;
|
||||
|
||||
ResultLoc *result_loc;
|
||||
IrInstruction *result;
|
||||
};
|
||||
|
||||
struct IrInstructionResetResult {
|
||||
IrInstruction base;
|
||||
|
||||
ResultLoc *result_loc;
|
||||
};
|
||||
|
||||
struct IrInstructionPtrOfArrayToSlice {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *operand;
|
||||
IrInstruction *result_loc;
|
||||
};
|
||||
|
||||
enum ResultLocId {
|
||||
ResultLocIdInvalid,
|
||||
ResultLocIdNone,
|
||||
ResultLocIdVar,
|
||||
ResultLocIdReturn,
|
||||
ResultLocIdPeer,
|
||||
ResultLocIdPeerParent,
|
||||
ResultLocIdInstruction,
|
||||
ResultLocIdBitCast,
|
||||
};
|
||||
|
||||
// Additions to this struct may need to be handled in
|
||||
// ir_reset_result
|
||||
struct ResultLoc {
|
||||
ResultLocId id;
|
||||
bool written;
|
||||
IrInstruction *resolved_loc; // result ptr
|
||||
IrInstruction *source_instruction;
|
||||
IrInstruction *gen_instruction; // value to store to the result loc
|
||||
ZigType *implicit_elem_type;
|
||||
};
|
||||
|
||||
struct ResultLocNone {
|
||||
ResultLoc base;
|
||||
};
|
||||
|
||||
struct ResultLocVar {
|
||||
ResultLoc base;
|
||||
|
||||
ZigVar *var;
|
||||
};
|
||||
|
||||
struct ResultLocReturn {
|
||||
ResultLoc base;
|
||||
};
|
||||
|
||||
struct IrSuspendPosition {
|
||||
size_t basic_block_index;
|
||||
size_t instruction_index;
|
||||
};
|
||||
|
||||
struct ResultLocPeerParent {
|
||||
ResultLoc base;
|
||||
|
||||
bool skipped;
|
||||
bool done_resuming;
|
||||
IrBasicBlock *end_bb;
|
||||
ResultLoc *parent;
|
||||
ZigList<ResultLocPeer *> peers;
|
||||
ZigType *resolved_type;
|
||||
IrInstruction *is_comptime;
|
||||
};
|
||||
|
||||
struct ResultLocPeer {
|
||||
ResultLoc base;
|
||||
|
||||
ResultLocPeerParent *parent;
|
||||
IrBasicBlock *next_bb;
|
||||
IrSuspendPosition suspend_pos;
|
||||
};
|
||||
|
||||
// The result location is the source instruction
|
||||
struct ResultLocInstruction {
|
||||
ResultLoc base;
|
||||
};
|
||||
|
||||
// The source_instruction is the destination type
|
||||
struct ResultLocBitCast {
|
||||
ResultLoc base;
|
||||
|
||||
ResultLoc *parent;
|
||||
};
|
||||
|
||||
static const size_t slice_ptr_index = 0;
|
||||
static const size_t slice_len_index = 1;
|
||||
|
||||
@ -3601,7 +3785,7 @@ struct FnWalkAttrs {
|
||||
|
||||
struct FnWalkCall {
|
||||
ZigList<LLVMValueRef> *gen_param_values;
|
||||
IrInstructionCall *inst;
|
||||
IrInstructionCallGen *inst;
|
||||
bool is_var_args;
|
||||
};
|
||||
|
||||
|
||||
@ -2995,7 +2995,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
|
||||
case NodeTypeBlock:
|
||||
case NodeTypeGroupedExpr:
|
||||
case NodeTypeBinOpExpr:
|
||||
case NodeTypeUnwrapErrorExpr:
|
||||
case NodeTypeCatchExpr:
|
||||
case NodeTypeFnCallExpr:
|
||||
case NodeTypeArrayAccessExpr:
|
||||
case NodeTypeSliceExpr:
|
||||
@ -4181,6 +4181,7 @@ static uint32_t hash_const_val_ptr(ConstExprValue *const_val) {
|
||||
case ConstPtrMutComptimeConst:
|
||||
hash_val += (uint32_t)4214318515;
|
||||
break;
|
||||
case ConstPtrMutInfer:
|
||||
case ConstPtrMutComptimeVar:
|
||||
hash_val += (uint32_t)1103195694;
|
||||
break;
|
||||
@ -4511,6 +4512,8 @@ bool fn_eval_cacheable(Scope *scope, ZigType *return_type) {
|
||||
ScopeVarDecl *var_scope = (ScopeVarDecl *)scope;
|
||||
if (type_is_invalid(var_scope->var->var_type))
|
||||
return false;
|
||||
if (var_scope->var->const_value->special == ConstValSpecialUndef)
|
||||
return false;
|
||||
if (can_mutate_comptime_var_state(var_scope->var->const_value))
|
||||
return false;
|
||||
} else if (scope->id == ScopeIdFnDef) {
|
||||
@ -4710,7 +4713,7 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) {
|
||||
void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
|
||||
auto entry = g->string_literals_table.maybe_get(str);
|
||||
if (entry != nullptr) {
|
||||
*const_val = *entry->value;
|
||||
memcpy(const_val, entry->value, sizeof(ConstExprValue));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4998,12 +5001,9 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
|
||||
field_val->type = wanted_type->data.structure.fields[i].type_entry;
|
||||
assert(field_val->type);
|
||||
init_const_undefined(g, field_val);
|
||||
ConstParent *parent = get_const_val_parent(g, field_val);
|
||||
if (parent != nullptr) {
|
||||
parent->id = ConstParentIdStruct;
|
||||
parent->data.p_struct.struct_val = const_val;
|
||||
parent->data.p_struct.field_index = i;
|
||||
}
|
||||
field_val->parent.id = ConstParentIdStruct;
|
||||
field_val->parent.data.p_struct.struct_val = const_val;
|
||||
field_val->parent.data.p_struct.field_index = i;
|
||||
}
|
||||
} else {
|
||||
const_val->special = ConstValSpecialUndef;
|
||||
@ -5843,11 +5843,6 @@ void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
// Deprecated. Reference the parent field directly.
|
||||
ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value) {
|
||||
return &value->parent;
|
||||
}
|
||||
|
||||
static const ZigTypeId all_type_ids[] = {
|
||||
ZigTypeIdMetaType,
|
||||
ZigTypeIdVoid,
|
||||
@ -7281,6 +7276,6 @@ void src_assert(bool ok, AstNode *source_node) {
|
||||
buf_ptr(source_node->owner->data.structure.root_struct->path),
|
||||
(unsigned)source_node->line + 1, (unsigned)source_node->column + 1);
|
||||
}
|
||||
const char *msg = "assertion failed";
|
||||
const char *msg = "assertion failed. This is a bug in the Zig compiler.";
|
||||
stage2_panic(msg, strlen(msg));
|
||||
}
|
||||
|
||||
@ -180,7 +180,6 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val);
|
||||
ConstExprValue *create_const_vals(size_t count);
|
||||
|
||||
ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
|
||||
ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value);
|
||||
void expand_undef_array(CodeGen *g, ConstExprValue *const_val);
|
||||
void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value);
|
||||
|
||||
|
||||
@ -165,8 +165,8 @@ static const char *node_type_str(NodeType node_type) {
|
||||
return "Parens";
|
||||
case NodeTypeBinOpExpr:
|
||||
return "BinOpExpr";
|
||||
case NodeTypeUnwrapErrorExpr:
|
||||
return "UnwrapErrorExpr";
|
||||
case NodeTypeCatchExpr:
|
||||
return "CatchExpr";
|
||||
case NodeTypeFnCallExpr:
|
||||
return "FnCallExpr";
|
||||
case NodeTypeArrayAccessExpr:
|
||||
@ -1108,7 +1108,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
|
||||
fprintf(ar->f, "]");
|
||||
break;
|
||||
}
|
||||
case NodeTypeUnwrapErrorExpr:
|
||||
case NodeTypeCatchExpr:
|
||||
{
|
||||
render_node_ungrouped(ar, node->data.unwrap_err_expr.op1);
|
||||
fprintf(ar->f, " catch ");
|
||||
|
||||
607
src/codegen.cpp
607
src/codegen.cpp
File diff suppressed because it is too large
Load Diff
4646
src/ir.cpp
4646
src/ir.cpp
File diff suppressed because it is too large
Load Diff
343
src/ir_print.cpp
343
src/ir_print.cpp
@ -57,13 +57,18 @@ static void ir_print_other_instruction(IrPrint *irp, IrInstruction *instruction)
|
||||
}
|
||||
|
||||
static void ir_print_other_block(IrPrint *irp, IrBasicBlock *bb) {
|
||||
fprintf(irp->f, "$%s_%" ZIG_PRI_usize "", bb->name_hint, bb->debug_id);
|
||||
if (bb == nullptr) {
|
||||
fprintf(irp->f, "(null block)");
|
||||
} else {
|
||||
fprintf(irp->f, "$%s_%" ZIG_PRI_usize "", bb->name_hint, bb->debug_id);
|
||||
}
|
||||
}
|
||||
|
||||
static void ir_print_return(IrPrint *irp, IrInstructionReturn *return_instruction) {
|
||||
assert(return_instruction->value);
|
||||
fprintf(irp->f, "return ");
|
||||
ir_print_other_instruction(irp, return_instruction->value);
|
||||
if (return_instruction->value != nullptr) {
|
||||
ir_print_other_instruction(irp, return_instruction->value);
|
||||
}
|
||||
}
|
||||
|
||||
static void ir_print_const(IrPrint *irp, IrInstructionConst *const_instruction) {
|
||||
@ -188,7 +193,7 @@ static void ir_print_decl_var_src(IrPrint *irp, IrInstructionDeclVarSrc *decl_va
|
||||
fprintf(irp->f, " ");
|
||||
}
|
||||
fprintf(irp->f, "= ");
|
||||
ir_print_other_instruction(irp, decl_var_instruction->init_value);
|
||||
ir_print_other_instruction(irp, decl_var_instruction->ptr);
|
||||
if (decl_var_instruction->var->is_comptime != nullptr) {
|
||||
fprintf(irp->f, " // comptime = ");
|
||||
ir_print_other_instruction(irp, decl_var_instruction->var->is_comptime);
|
||||
@ -201,7 +206,56 @@ static void ir_print_cast(IrPrint *irp, IrInstructionCast *cast_instruction) {
|
||||
fprintf(irp->f, " to %s", buf_ptr(&cast_instruction->dest_type->name));
|
||||
}
|
||||
|
||||
static void ir_print_call(IrPrint *irp, IrInstructionCall *call_instruction) {
|
||||
static void ir_print_result_loc_var(IrPrint *irp, ResultLocVar *result_loc_var) {
|
||||
fprintf(irp->f, "var(");
|
||||
ir_print_other_instruction(irp, result_loc_var->base.source_instruction);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_result_loc_instruction(IrPrint *irp, ResultLocInstruction *result_loc_inst) {
|
||||
fprintf(irp->f, "inst(");
|
||||
ir_print_other_instruction(irp, result_loc_inst->base.source_instruction);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_result_loc_peer(IrPrint *irp, ResultLocPeer *result_loc_peer) {
|
||||
fprintf(irp->f, "peer(next=");
|
||||
ir_print_other_block(irp, result_loc_peer->next_bb);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_result_loc_bit_cast(IrPrint *irp, ResultLocBitCast *result_loc_bit_cast) {
|
||||
fprintf(irp->f, "bitcast(ty=");
|
||||
ir_print_other_instruction(irp, result_loc_bit_cast->base.source_instruction);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_result_loc(IrPrint *irp, ResultLoc *result_loc) {
|
||||
switch (result_loc->id) {
|
||||
case ResultLocIdInvalid:
|
||||
zig_unreachable();
|
||||
case ResultLocIdNone:
|
||||
fprintf(irp->f, "none");
|
||||
return;
|
||||
case ResultLocIdReturn:
|
||||
fprintf(irp->f, "return");
|
||||
return;
|
||||
case ResultLocIdVar:
|
||||
return ir_print_result_loc_var(irp, (ResultLocVar *)result_loc);
|
||||
case ResultLocIdInstruction:
|
||||
return ir_print_result_loc_instruction(irp, (ResultLocInstruction *)result_loc);
|
||||
case ResultLocIdPeer:
|
||||
return ir_print_result_loc_peer(irp, (ResultLocPeer *)result_loc);
|
||||
case ResultLocIdBitCast:
|
||||
return ir_print_result_loc_bit_cast(irp, (ResultLocBitCast *)result_loc);
|
||||
case ResultLocIdPeerParent:
|
||||
fprintf(irp->f, "peer_parent");
|
||||
return;
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
static void ir_print_call_src(IrPrint *irp, IrInstructionCallSrc *call_instruction) {
|
||||
if (call_instruction->is_async) {
|
||||
fprintf(irp->f, "async");
|
||||
if (call_instruction->async_allocator != nullptr) {
|
||||
@ -224,7 +278,35 @@ static void ir_print_call(IrPrint *irp, IrInstructionCall *call_instruction) {
|
||||
fprintf(irp->f, ", ");
|
||||
ir_print_other_instruction(irp, arg);
|
||||
}
|
||||
fprintf(irp->f, ")");
|
||||
fprintf(irp->f, ")result=");
|
||||
ir_print_result_loc(irp, call_instruction->result_loc);
|
||||
}
|
||||
|
||||
static void ir_print_call_gen(IrPrint *irp, IrInstructionCallGen *call_instruction) {
|
||||
if (call_instruction->is_async) {
|
||||
fprintf(irp->f, "async");
|
||||
if (call_instruction->async_allocator != nullptr) {
|
||||
fprintf(irp->f, "<");
|
||||
ir_print_other_instruction(irp, call_instruction->async_allocator);
|
||||
fprintf(irp->f, ">");
|
||||
}
|
||||
fprintf(irp->f, " ");
|
||||
}
|
||||
if (call_instruction->fn_entry) {
|
||||
fprintf(irp->f, "%s", buf_ptr(&call_instruction->fn_entry->symbol_name));
|
||||
} else {
|
||||
assert(call_instruction->fn_ref);
|
||||
ir_print_other_instruction(irp, call_instruction->fn_ref);
|
||||
}
|
||||
fprintf(irp->f, "(");
|
||||
for (size_t i = 0; i < call_instruction->arg_count; i += 1) {
|
||||
IrInstruction *arg = call_instruction->args[i];
|
||||
if (i != 0)
|
||||
fprintf(irp->f, ", ");
|
||||
ir_print_other_instruction(irp, arg);
|
||||
}
|
||||
fprintf(irp->f, ")result=");
|
||||
ir_print_other_instruction(irp, call_instruction->result_loc);
|
||||
}
|
||||
|
||||
static void ir_print_cond_br(IrPrint *irp, IrInstructionCondBr *cond_br_instruction) {
|
||||
@ -270,10 +352,10 @@ static void ir_print_container_init_list(IrPrint *irp, IrInstructionContainerIni
|
||||
fprintf(irp->f, "...(%" ZIG_PRI_usize " items)...", instruction->item_count);
|
||||
} else {
|
||||
for (size_t i = 0; i < instruction->item_count; i += 1) {
|
||||
IrInstruction *item = instruction->items[i];
|
||||
IrInstruction *result_loc = instruction->elem_result_loc_list[i];
|
||||
if (i != 0)
|
||||
fprintf(irp->f, ", ");
|
||||
ir_print_other_instruction(irp, item);
|
||||
ir_print_other_instruction(irp, result_loc);
|
||||
}
|
||||
}
|
||||
fprintf(irp->f, "}");
|
||||
@ -286,32 +368,11 @@ static void ir_print_container_init_fields(IrPrint *irp, IrInstructionContainerI
|
||||
IrInstructionContainerInitFieldsField *field = &instruction->fields[i];
|
||||
const char *comma = (i == 0) ? "" : ", ";
|
||||
fprintf(irp->f, "%s.%s = ", comma, buf_ptr(field->name));
|
||||
ir_print_other_instruction(irp, field->value);
|
||||
ir_print_other_instruction(irp, field->result_loc);
|
||||
}
|
||||
fprintf(irp->f, "} // container init");
|
||||
}
|
||||
|
||||
static void ir_print_struct_init(IrPrint *irp, IrInstructionStructInit *instruction) {
|
||||
fprintf(irp->f, "%s {", buf_ptr(&instruction->struct_type->name));
|
||||
for (size_t i = 0; i < instruction->field_count; i += 1) {
|
||||
IrInstructionStructInitField *field = &instruction->fields[i];
|
||||
Buf *field_name = field->type_struct_field->name;
|
||||
const char *comma = (i == 0) ? "" : ", ";
|
||||
fprintf(irp->f, "%s.%s = ", comma, buf_ptr(field_name));
|
||||
ir_print_other_instruction(irp, field->value);
|
||||
}
|
||||
fprintf(irp->f, "} // struct init");
|
||||
}
|
||||
|
||||
static void ir_print_union_init(IrPrint *irp, IrInstructionUnionInit *instruction) {
|
||||
Buf *field_name = instruction->field->enum_field->name;
|
||||
|
||||
fprintf(irp->f, "%s {", buf_ptr(&instruction->union_type->name));
|
||||
fprintf(irp->f, ".%s = ", buf_ptr(field_name));
|
||||
ir_print_other_instruction(irp, instruction->init_value);
|
||||
fprintf(irp->f, "} // union init");
|
||||
}
|
||||
|
||||
static void ir_print_unreachable(IrPrint *irp, IrInstructionUnreachable *instruction) {
|
||||
fprintf(irp->f, "unreachable");
|
||||
}
|
||||
@ -331,14 +392,20 @@ static void ir_print_var_ptr(IrPrint *irp, IrInstructionVarPtr *instruction) {
|
||||
fprintf(irp->f, "&%s", buf_ptr(&instruction->var->name));
|
||||
}
|
||||
|
||||
static void ir_print_return_ptr(IrPrint *irp, IrInstructionReturnPtr *instruction) {
|
||||
fprintf(irp->f, "@ReturnPtr");
|
||||
}
|
||||
|
||||
static void ir_print_load_ptr(IrPrint *irp, IrInstructionLoadPtr *instruction) {
|
||||
ir_print_other_instruction(irp, instruction->ptr);
|
||||
fprintf(irp->f, ".*");
|
||||
}
|
||||
|
||||
static void ir_print_load_ptr_gen(IrPrint *irp, IrInstructionLoadPtrGen *instruction) {
|
||||
fprintf(irp->f, "loadptr(");
|
||||
ir_print_other_instruction(irp, instruction->ptr);
|
||||
fprintf(irp->f, ".*");
|
||||
fprintf(irp->f, ")result=");
|
||||
ir_print_other_instruction(irp, instruction->result_loc);
|
||||
}
|
||||
|
||||
static void ir_print_store_ptr(IrPrint *irp, IrInstructionStorePtr *instruction) {
|
||||
@ -354,18 +421,6 @@ static void ir_print_typeof(IrPrint *irp, IrInstructionTypeOf *instruction) {
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_to_ptr_type(IrPrint *irp, IrInstructionToPtrType *instruction) {
|
||||
fprintf(irp->f, "@toPtrType(");
|
||||
ir_print_other_instruction(irp, instruction->ptr);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_ptr_type_child(IrPrint *irp, IrInstructionPtrTypeChild *instruction) {
|
||||
fprintf(irp->f, "@ptrTypeChild(");
|
||||
ir_print_other_instruction(irp, instruction->value);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_field_ptr(IrPrint *irp, IrInstructionFieldPtr *instruction) {
|
||||
if (instruction->field_name_buffer) {
|
||||
fprintf(irp->f, "fieldptr ");
|
||||
@ -618,6 +673,13 @@ static void ir_print_ref(IrPrint *irp, IrInstructionRef *instruction) {
|
||||
ir_print_other_instruction(irp, instruction->value);
|
||||
}
|
||||
|
||||
static void ir_print_ref_gen(IrPrint *irp, IrInstructionRefGen *instruction) {
|
||||
fprintf(irp->f, "@ref(");
|
||||
ir_print_other_instruction(irp, instruction->operand);
|
||||
fprintf(irp->f, ")result=");
|
||||
ir_print_other_instruction(irp, instruction->result_loc);
|
||||
}
|
||||
|
||||
static void ir_print_compile_err(IrPrint *irp, IrInstructionCompileErr *instruction) {
|
||||
fprintf(irp->f, "@compileError(");
|
||||
ir_print_other_instruction(irp, instruction->msg);
|
||||
@ -682,7 +744,8 @@ static void ir_print_cmpxchg_src(IrPrint *irp, IrInstructionCmpxchgSrc *instruct
|
||||
ir_print_other_instruction(irp, instruction->success_order_value);
|
||||
fprintf(irp->f, ", ");
|
||||
ir_print_other_instruction(irp, instruction->failure_order_value);
|
||||
fprintf(irp->f, ")");
|
||||
fprintf(irp->f, ")result=");
|
||||
ir_print_result_loc(irp, instruction->result_loc);
|
||||
}
|
||||
|
||||
static void ir_print_cmpxchg_gen(IrPrint *irp, IrInstructionCmpxchgGen *instruction) {
|
||||
@ -692,7 +755,8 @@ static void ir_print_cmpxchg_gen(IrPrint *irp, IrInstructionCmpxchgGen *instruct
|
||||
ir_print_other_instruction(irp, instruction->cmp_value);
|
||||
fprintf(irp->f, ", ");
|
||||
ir_print_other_instruction(irp, instruction->new_value);
|
||||
fprintf(irp->f, ", TODO print atomic orders)");
|
||||
fprintf(irp->f, ", TODO print atomic orders)result=");
|
||||
ir_print_other_instruction(irp, instruction->result_loc);
|
||||
}
|
||||
|
||||
static void ir_print_fence(IrPrint *irp, IrInstructionFence *instruction) {
|
||||
@ -810,14 +874,26 @@ static void ir_print_memcpy(IrPrint *irp, IrInstructionMemcpy *instruction) {
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_slice(IrPrint *irp, IrInstructionSlice *instruction) {
|
||||
static void ir_print_slice_src(IrPrint *irp, IrInstructionSliceSrc *instruction) {
|
||||
ir_print_other_instruction(irp, instruction->ptr);
|
||||
fprintf(irp->f, "[");
|
||||
ir_print_other_instruction(irp, instruction->start);
|
||||
fprintf(irp->f, "..");
|
||||
if (instruction->end)
|
||||
ir_print_other_instruction(irp, instruction->end);
|
||||
fprintf(irp->f, "]");
|
||||
fprintf(irp->f, "]result=");
|
||||
ir_print_result_loc(irp, instruction->result_loc);
|
||||
}
|
||||
|
||||
static void ir_print_slice_gen(IrPrint *irp, IrInstructionSliceGen *instruction) {
|
||||
ir_print_other_instruction(irp, instruction->ptr);
|
||||
fprintf(irp->f, "[");
|
||||
ir_print_other_instruction(irp, instruction->start);
|
||||
fprintf(irp->f, "..");
|
||||
if (instruction->end)
|
||||
ir_print_other_instruction(irp, instruction->end);
|
||||
fprintf(irp->f, "]result=");
|
||||
ir_print_other_instruction(irp, instruction->result_loc);
|
||||
}
|
||||
|
||||
static void ir_print_member_count(IrPrint *irp, IrInstructionMemberCount *instruction) {
|
||||
@ -889,43 +965,49 @@ static void ir_print_overflow_op(IrPrint *irp, IrInstructionOverflowOp *instruct
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_test_err(IrPrint *irp, IrInstructionTestErr *instruction) {
|
||||
static void ir_print_test_err_src(IrPrint *irp, IrInstructionTestErrSrc *instruction) {
|
||||
fprintf(irp->f, "@testError(");
|
||||
ir_print_other_instruction(irp, instruction->value);
|
||||
ir_print_other_instruction(irp, instruction->base_ptr);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_test_err_gen(IrPrint *irp, IrInstructionTestErrGen *instruction) {
|
||||
fprintf(irp->f, "@testError(");
|
||||
ir_print_other_instruction(irp, instruction->err_union);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_unwrap_err_code(IrPrint *irp, IrInstructionUnwrapErrCode *instruction) {
|
||||
fprintf(irp->f, "UnwrapErrorCode(");
|
||||
ir_print_other_instruction(irp, instruction->err_union);
|
||||
ir_print_other_instruction(irp, instruction->err_union_ptr);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_unwrap_err_payload(IrPrint *irp, IrInstructionUnwrapErrPayload *instruction) {
|
||||
fprintf(irp->f, "ErrorUnionFieldPayload(");
|
||||
ir_print_other_instruction(irp, instruction->value);
|
||||
fprintf(irp->f, ")");
|
||||
if (!instruction->safety_check_on) {
|
||||
fprintf(irp->f, " // no safety");
|
||||
}
|
||||
fprintf(irp->f, ")safety=%d,init=%d",instruction->safety_check_on, instruction->initializing);
|
||||
}
|
||||
|
||||
static void ir_print_maybe_wrap(IrPrint *irp, IrInstructionOptionalWrap *instruction) {
|
||||
fprintf(irp->f, "@maybeWrap(");
|
||||
ir_print_other_instruction(irp, instruction->value);
|
||||
fprintf(irp->f, ")");
|
||||
static void ir_print_optional_wrap(IrPrint *irp, IrInstructionOptionalWrap *instruction) {
|
||||
fprintf(irp->f, "@optionalWrap(");
|
||||
ir_print_other_instruction(irp, instruction->operand);
|
||||
fprintf(irp->f, ")result=");
|
||||
ir_print_other_instruction(irp, instruction->result_loc);
|
||||
}
|
||||
|
||||
static void ir_print_err_wrap_code(IrPrint *irp, IrInstructionErrWrapCode *instruction) {
|
||||
fprintf(irp->f, "@errWrapCode(");
|
||||
ir_print_other_instruction(irp, instruction->value);
|
||||
fprintf(irp->f, ")");
|
||||
ir_print_other_instruction(irp, instruction->operand);
|
||||
fprintf(irp->f, ")result=");
|
||||
ir_print_other_instruction(irp, instruction->result_loc);
|
||||
}
|
||||
|
||||
static void ir_print_err_wrap_payload(IrPrint *irp, IrInstructionErrWrapPayload *instruction) {
|
||||
fprintf(irp->f, "@errWrapPayload(");
|
||||
ir_print_other_instruction(irp, instruction->value);
|
||||
fprintf(irp->f, ")");
|
||||
ir_print_other_instruction(irp, instruction->operand);
|
||||
fprintf(irp->f, ")result=");
|
||||
ir_print_other_instruction(irp, instruction->result_loc);
|
||||
}
|
||||
|
||||
static void ir_print_fn_proto(IrPrint *irp, IrInstructionFnProto *instruction) {
|
||||
@ -971,12 +1053,11 @@ static void ir_print_ptr_cast_gen(IrPrint *irp, IrInstructionPtrCastGen *instruc
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_bit_cast(IrPrint *irp, IrInstructionBitCast *instruction) {
|
||||
static void ir_print_bit_cast_src(IrPrint *irp, IrInstructionBitCastSrc *instruction) {
|
||||
fprintf(irp->f, "@bitCast(");
|
||||
ir_print_other_instruction(irp, instruction->dest_type);
|
||||
fprintf(irp->f, ",");
|
||||
ir_print_other_instruction(irp, instruction->value);
|
||||
fprintf(irp->f, ")");
|
||||
ir_print_other_instruction(irp, instruction->operand);
|
||||
fprintf(irp->f, ")result=");
|
||||
ir_print_result_loc(irp, &instruction->result_loc_bit_cast->base);
|
||||
}
|
||||
|
||||
static void ir_print_bit_cast_gen(IrPrint *irp, IrInstructionBitCastGen *instruction) {
|
||||
@ -1043,7 +1124,15 @@ static void ir_print_array_to_vector(IrPrint *irp, IrInstructionArrayToVector *i
|
||||
static void ir_print_vector_to_array(IrPrint *irp, IrInstructionVectorToArray *instruction) {
|
||||
fprintf(irp->f, "VectorToArray(");
|
||||
ir_print_other_instruction(irp, instruction->vector);
|
||||
fprintf(irp->f, ")");
|
||||
fprintf(irp->f, ")result=");
|
||||
ir_print_other_instruction(irp, instruction->result_loc);
|
||||
}
|
||||
|
||||
static void ir_print_ptr_of_array_to_slice(IrPrint *irp, IrInstructionPtrOfArrayToSlice *instruction) {
|
||||
fprintf(irp->f, "PtrOfArrayToSlice(");
|
||||
ir_print_other_instruction(irp, instruction->operand);
|
||||
fprintf(irp->f, ")result=");
|
||||
ir_print_other_instruction(irp, instruction->result_loc);
|
||||
}
|
||||
|
||||
static void ir_print_assert_zero(IrPrint *irp, IrInstructionAssertZero *instruction) {
|
||||
@ -1061,6 +1150,25 @@ static void ir_print_assert_non_null(IrPrint *irp, IrInstructionAssertNonNull *i
|
||||
static void ir_print_resize_slice(IrPrint *irp, IrInstructionResizeSlice *instruction) {
|
||||
fprintf(irp->f, "@resizeSlice(");
|
||||
ir_print_other_instruction(irp, instruction->operand);
|
||||
fprintf(irp->f, ")result=");
|
||||
ir_print_other_instruction(irp, instruction->result_loc);
|
||||
}
|
||||
|
||||
static void ir_print_alloca_src(IrPrint *irp, IrInstructionAllocaSrc *instruction) {
|
||||
fprintf(irp->f, "Alloca(align=");
|
||||
ir_print_other_instruction(irp, instruction->align);
|
||||
fprintf(irp->f, ",name=%s)", instruction->name_hint);
|
||||
}
|
||||
|
||||
static void ir_print_alloca_gen(IrPrint *irp, IrInstructionAllocaGen *instruction) {
|
||||
fprintf(irp->f, "Alloca(align=%" PRIu32 ",name=%s)", instruction->align, instruction->name_hint);
|
||||
}
|
||||
|
||||
static void ir_print_end_expr(IrPrint *irp, IrInstructionEndExpr *instruction) {
|
||||
fprintf(irp->f, "EndExpr(result=");
|
||||
ir_print_result_loc(irp, instruction->result_loc);
|
||||
fprintf(irp->f, ",value=");
|
||||
ir_print_other_instruction(irp, instruction->value);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
@ -1186,6 +1294,34 @@ static void ir_print_align_cast(IrPrint *irp, IrInstructionAlignCast *instructio
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_implicit_cast(IrPrint *irp, IrInstructionImplicitCast *instruction) {
|
||||
fprintf(irp->f, "@implicitCast(");
|
||||
ir_print_other_instruction(irp, instruction->dest_type);
|
||||
fprintf(irp->f, ",");
|
||||
ir_print_other_instruction(irp, instruction->target);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_resolve_result(IrPrint *irp, IrInstructionResolveResult *instruction) {
|
||||
fprintf(irp->f, "ResolveResult(");
|
||||
ir_print_result_loc(irp, instruction->result_loc);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_reset_result(IrPrint *irp, IrInstructionResetResult *instruction) {
|
||||
fprintf(irp->f, "ResetResult(");
|
||||
ir_print_result_loc(irp, instruction->result_loc);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_result_ptr(IrPrint *irp, IrInstructionResultPtr *instruction) {
|
||||
fprintf(irp->f, "ResultPtr(");
|
||||
ir_print_result_loc(irp, instruction->result_loc);
|
||||
fprintf(irp->f, ",");
|
||||
ir_print_other_instruction(irp, instruction->result);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_opaque_type(IrPrint *irp, IrInstructionOpaqueType *instruction) {
|
||||
fprintf(irp->f, "@OpaqueType()");
|
||||
}
|
||||
@ -1463,7 +1599,7 @@ static void ir_print_decl_var_gen(IrPrint *irp, IrInstructionDeclVarGen *decl_va
|
||||
fprintf(irp->f, "%s %s: %s align(%u) = ", var_or_const, name, buf_ptr(&var->var_type->name),
|
||||
var->align_bytes);
|
||||
|
||||
ir_print_other_instruction(irp, decl_var_instruction->init_value);
|
||||
ir_print_other_instruction(irp, decl_var_instruction->var_ptr);
|
||||
if (decl_var_instruction->var->is_comptime != nullptr) {
|
||||
fprintf(irp->f, " // comptime = ");
|
||||
ir_print_other_instruction(irp, decl_var_instruction->var->is_comptime);
|
||||
@ -1502,8 +1638,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
||||
case IrInstructionIdCast:
|
||||
ir_print_cast(irp, (IrInstructionCast *)instruction);
|
||||
break;
|
||||
case IrInstructionIdCall:
|
||||
ir_print_call(irp, (IrInstructionCall *)instruction);
|
||||
case IrInstructionIdCallSrc:
|
||||
ir_print_call_src(irp, (IrInstructionCallSrc *)instruction);
|
||||
break;
|
||||
case IrInstructionIdCallGen:
|
||||
ir_print_call_gen(irp, (IrInstructionCallGen *)instruction);
|
||||
break;
|
||||
case IrInstructionIdUnOp:
|
||||
ir_print_un_op(irp, (IrInstructionUnOp *)instruction);
|
||||
@ -1523,12 +1662,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
||||
case IrInstructionIdContainerInitFields:
|
||||
ir_print_container_init_fields(irp, (IrInstructionContainerInitFields *)instruction);
|
||||
break;
|
||||
case IrInstructionIdStructInit:
|
||||
ir_print_struct_init(irp, (IrInstructionStructInit *)instruction);
|
||||
break;
|
||||
case IrInstructionIdUnionInit:
|
||||
ir_print_union_init(irp, (IrInstructionUnionInit *)instruction);
|
||||
break;
|
||||
case IrInstructionIdUnreachable:
|
||||
ir_print_unreachable(irp, (IrInstructionUnreachable *)instruction);
|
||||
break;
|
||||
@ -1538,6 +1671,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
||||
case IrInstructionIdVarPtr:
|
||||
ir_print_var_ptr(irp, (IrInstructionVarPtr *)instruction);
|
||||
break;
|
||||
case IrInstructionIdReturnPtr:
|
||||
ir_print_return_ptr(irp, (IrInstructionReturnPtr *)instruction);
|
||||
break;
|
||||
case IrInstructionIdLoadPtr:
|
||||
ir_print_load_ptr(irp, (IrInstructionLoadPtr *)instruction);
|
||||
break;
|
||||
@ -1550,12 +1686,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
||||
case IrInstructionIdTypeOf:
|
||||
ir_print_typeof(irp, (IrInstructionTypeOf *)instruction);
|
||||
break;
|
||||
case IrInstructionIdToPtrType:
|
||||
ir_print_to_ptr_type(irp, (IrInstructionToPtrType *)instruction);
|
||||
break;
|
||||
case IrInstructionIdPtrTypeChild:
|
||||
ir_print_ptr_type_child(irp, (IrInstructionPtrTypeChild *)instruction);
|
||||
break;
|
||||
case IrInstructionIdFieldPtr:
|
||||
ir_print_field_ptr(irp, (IrInstructionFieldPtr *)instruction);
|
||||
break;
|
||||
@ -1634,6 +1764,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
||||
case IrInstructionIdRef:
|
||||
ir_print_ref(irp, (IrInstructionRef *)instruction);
|
||||
break;
|
||||
case IrInstructionIdRefGen:
|
||||
ir_print_ref_gen(irp, (IrInstructionRefGen *)instruction);
|
||||
break;
|
||||
case IrInstructionIdCompileErr:
|
||||
ir_print_compile_err(irp, (IrInstructionCompileErr *)instruction);
|
||||
break;
|
||||
@ -1709,8 +1842,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
||||
case IrInstructionIdMemcpy:
|
||||
ir_print_memcpy(irp, (IrInstructionMemcpy *)instruction);
|
||||
break;
|
||||
case IrInstructionIdSlice:
|
||||
ir_print_slice(irp, (IrInstructionSlice *)instruction);
|
||||
case IrInstructionIdSliceSrc:
|
||||
ir_print_slice_src(irp, (IrInstructionSliceSrc *)instruction);
|
||||
break;
|
||||
case IrInstructionIdSliceGen:
|
||||
ir_print_slice_gen(irp, (IrInstructionSliceGen *)instruction);
|
||||
break;
|
||||
case IrInstructionIdMemberCount:
|
||||
ir_print_member_count(irp, (IrInstructionMemberCount *)instruction);
|
||||
@ -1739,8 +1875,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
||||
case IrInstructionIdOverflowOp:
|
||||
ir_print_overflow_op(irp, (IrInstructionOverflowOp *)instruction);
|
||||
break;
|
||||
case IrInstructionIdTestErr:
|
||||
ir_print_test_err(irp, (IrInstructionTestErr *)instruction);
|
||||
case IrInstructionIdTestErrSrc:
|
||||
ir_print_test_err_src(irp, (IrInstructionTestErrSrc *)instruction);
|
||||
break;
|
||||
case IrInstructionIdTestErrGen:
|
||||
ir_print_test_err_gen(irp, (IrInstructionTestErrGen *)instruction);
|
||||
break;
|
||||
case IrInstructionIdUnwrapErrCode:
|
||||
ir_print_unwrap_err_code(irp, (IrInstructionUnwrapErrCode *)instruction);
|
||||
@ -1749,7 +1888,7 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
||||
ir_print_unwrap_err_payload(irp, (IrInstructionUnwrapErrPayload *)instruction);
|
||||
break;
|
||||
case IrInstructionIdOptionalWrap:
|
||||
ir_print_maybe_wrap(irp, (IrInstructionOptionalWrap *)instruction);
|
||||
ir_print_optional_wrap(irp, (IrInstructionOptionalWrap *)instruction);
|
||||
break;
|
||||
case IrInstructionIdErrWrapCode:
|
||||
ir_print_err_wrap_code(irp, (IrInstructionErrWrapCode *)instruction);
|
||||
@ -1769,8 +1908,8 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
||||
case IrInstructionIdPtrCastGen:
|
||||
ir_print_ptr_cast_gen(irp, (IrInstructionPtrCastGen *)instruction);
|
||||
break;
|
||||
case IrInstructionIdBitCast:
|
||||
ir_print_bit_cast(irp, (IrInstructionBitCast *)instruction);
|
||||
case IrInstructionIdBitCastSrc:
|
||||
ir_print_bit_cast_src(irp, (IrInstructionBitCastSrc *)instruction);
|
||||
break;
|
||||
case IrInstructionIdBitCastGen:
|
||||
ir_print_bit_cast_gen(irp, (IrInstructionBitCastGen *)instruction);
|
||||
@ -1835,6 +1974,18 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
||||
case IrInstructionIdAlignCast:
|
||||
ir_print_align_cast(irp, (IrInstructionAlignCast *)instruction);
|
||||
break;
|
||||
case IrInstructionIdImplicitCast:
|
||||
ir_print_implicit_cast(irp, (IrInstructionImplicitCast *)instruction);
|
||||
break;
|
||||
case IrInstructionIdResolveResult:
|
||||
ir_print_resolve_result(irp, (IrInstructionResolveResult *)instruction);
|
||||
break;
|
||||
case IrInstructionIdResetResult:
|
||||
ir_print_reset_result(irp, (IrInstructionResetResult *)instruction);
|
||||
break;
|
||||
case IrInstructionIdResultPtr:
|
||||
ir_print_result_ptr(irp, (IrInstructionResultPtr *)instruction);
|
||||
break;
|
||||
case IrInstructionIdOpaqueType:
|
||||
ir_print_opaque_type(irp, (IrInstructionOpaqueType *)instruction);
|
||||
break;
|
||||
@ -1943,6 +2094,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
||||
case IrInstructionIdVectorToArray:
|
||||
ir_print_vector_to_array(irp, (IrInstructionVectorToArray *)instruction);
|
||||
break;
|
||||
case IrInstructionIdPtrOfArrayToSlice:
|
||||
ir_print_ptr_of_array_to_slice(irp, (IrInstructionPtrOfArrayToSlice *)instruction);
|
||||
break;
|
||||
case IrInstructionIdAssertZero:
|
||||
ir_print_assert_zero(irp, (IrInstructionAssertZero *)instruction);
|
||||
break;
|
||||
@ -1958,6 +2112,15 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
||||
case IrInstructionIdUndeclaredIdent:
|
||||
ir_print_undeclared_ident(irp, (IrInstructionUndeclaredIdent *)instruction);
|
||||
break;
|
||||
case IrInstructionIdAllocaSrc:
|
||||
ir_print_alloca_src(irp, (IrInstructionAllocaSrc *)instruction);
|
||||
break;
|
||||
case IrInstructionIdAllocaGen:
|
||||
ir_print_alloca_gen(irp, (IrInstructionAllocaGen *)instruction);
|
||||
break;
|
||||
case IrInstructionIdEndExpr:
|
||||
ir_print_end_expr(irp, (IrInstructionEndExpr *)instruction);
|
||||
break;
|
||||
}
|
||||
fprintf(irp->f, "\n");
|
||||
}
|
||||
|
||||
@ -344,7 +344,7 @@ static AstNode *ast_parse_bin_op_expr(
|
||||
op->data.bin_op_expr.op1 = left;
|
||||
op->data.bin_op_expr.op2 = right;
|
||||
break;
|
||||
case NodeTypeUnwrapErrorExpr:
|
||||
case NodeTypeCatchExpr:
|
||||
op->data.unwrap_err_expr.op1 = left;
|
||||
op->data.unwrap_err_expr.op2 = right;
|
||||
break;
|
||||
@ -2404,7 +2404,7 @@ static AstNode *ast_parse_bitwise_op(ParseContext *pc) {
|
||||
Token *catch_token = eat_token_if(pc, TokenIdKeywordCatch);
|
||||
if (catch_token != nullptr) {
|
||||
Token *payload = ast_parse_payload(pc);
|
||||
AstNode *res = ast_create_node(pc, NodeTypeUnwrapErrorExpr, catch_token);
|
||||
AstNode *res = ast_create_node(pc, NodeTypeCatchExpr, catch_token);
|
||||
if (payload != nullptr)
|
||||
res->data.unwrap_err_expr.symbol = token_symbol(pc, payload);
|
||||
|
||||
@ -2897,7 +2897,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
|
||||
visit_field(&node->data.bin_op_expr.op1, visit, context);
|
||||
visit_field(&node->data.bin_op_expr.op2, visit, context);
|
||||
break;
|
||||
case NodeTypeUnwrapErrorExpr:
|
||||
case NodeTypeCatchExpr:
|
||||
visit_field(&node->data.unwrap_err_expr.op1, visit, context);
|
||||
visit_field(&node->data.unwrap_err_expr.symbol, visit, context);
|
||||
visit_field(&node->data.unwrap_err_expr.op2, visit, context);
|
||||
|
||||
@ -1290,10 +1290,9 @@ pub fn Watch(comptime V: type) type {
|
||||
error.FileDescriptorAlreadyPresentInSet => unreachable,
|
||||
error.OperationCausesCircularLoop => unreachable,
|
||||
error.FileDescriptorNotRegistered => unreachable,
|
||||
error.SystemResources => error.SystemResources,
|
||||
error.UserResourceLimitReached => error.UserResourceLimitReached,
|
||||
error.FileDescriptorIncompatibleWithEpoll => unreachable,
|
||||
error.Unexpected => unreachable,
|
||||
else => |e| e,
|
||||
};
|
||||
await (async channel.put(transformed_err) catch unreachable);
|
||||
};
|
||||
|
||||
@ -123,7 +123,6 @@ pub const Lock = struct {
|
||||
};
|
||||
|
||||
test "std.event.Lock" {
|
||||
// https://github.com/ziglang/zig/issues/1908
|
||||
if (builtin.single_threaded) return error.SkipZigTest;
|
||||
|
||||
const allocator = std.heap.direct_allocator;
|
||||
|
||||
@ -263,8 +263,8 @@ pub async fn connect(loop: *Loop, _address: *const std.net.Address) !File {
|
||||
}
|
||||
|
||||
test "listen on a port, send bytes, receive bytes" {
|
||||
// https://github.com/ziglang/zig/issues/1908
|
||||
if (builtin.single_threaded) return error.SkipZigTest;
|
||||
// https://github.com/ziglang/zig/issues/2377
|
||||
if (true) return error.SkipZigTest;
|
||||
|
||||
if (builtin.os != builtin.Os.linux) {
|
||||
// TODO build abstractions for other operating systems
|
||||
|
||||
@ -212,8 +212,8 @@ pub const RwLock = struct {
|
||||
};
|
||||
|
||||
test "std.event.RwLock" {
|
||||
// https://github.com/ziglang/zig/issues/1908
|
||||
if (builtin.single_threaded or builtin.os != builtin.Os.linux) return error.SkipZigTest;
|
||||
// https://github.com/ziglang/zig/issues/2377
|
||||
if (true) return error.SkipZigTest;
|
||||
|
||||
const allocator = std.heap.direct_allocator;
|
||||
|
||||
|
||||
@ -360,9 +360,9 @@ pub const ArenaAllocator = struct {
|
||||
var it = self.buffer_list.first;
|
||||
while (it) |node| {
|
||||
// this has to occur before the free because the free frees node
|
||||
it = node.next;
|
||||
|
||||
const next_it = node.next;
|
||||
self.child_allocator.free(node.data);
|
||||
it = next_it;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
20
std/io.zig
20
std/io.zig
@ -164,32 +164,32 @@ pub fn InStream(comptime ReadError: type) type {
|
||||
|
||||
/// Reads a native-endian integer
|
||||
pub fn readIntNative(self: *Self, comptime T: type) !T {
|
||||
var bytes: [(T.bit_count + 7 )/ 8]u8 = undefined;
|
||||
var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
|
||||
try self.readNoEof(bytes[0..]);
|
||||
return mem.readIntNative(T, &bytes);
|
||||
}
|
||||
|
||||
/// Reads a foreign-endian integer
|
||||
pub fn readIntForeign(self: *Self, comptime T: type) !T {
|
||||
var bytes: [(T.bit_count + 7 )/ 8]u8 = undefined;
|
||||
var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
|
||||
try self.readNoEof(bytes[0..]);
|
||||
return mem.readIntForeign(T, &bytes);
|
||||
}
|
||||
|
||||
pub fn readIntLittle(self: *Self, comptime T: type) !T {
|
||||
var bytes: [(T.bit_count + 7 )/ 8]u8 = undefined;
|
||||
var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
|
||||
try self.readNoEof(bytes[0..]);
|
||||
return mem.readIntLittle(T, &bytes);
|
||||
}
|
||||
|
||||
pub fn readIntBig(self: *Self, comptime T: type) !T {
|
||||
var bytes: [(T.bit_count + 7 )/ 8]u8 = undefined;
|
||||
var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
|
||||
try self.readNoEof(bytes[0..]);
|
||||
return mem.readIntBig(T, &bytes);
|
||||
}
|
||||
|
||||
pub fn readInt(self: *Self, comptime T: type, endian: builtin.Endian) !T {
|
||||
var bytes: [(T.bit_count + 7 )/ 8]u8 = undefined;
|
||||
var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
|
||||
try self.readNoEof(bytes[0..]);
|
||||
return mem.readInt(T, &bytes, endian);
|
||||
}
|
||||
@ -249,32 +249,32 @@ pub fn OutStream(comptime WriteError: type) type {
|
||||
|
||||
/// Write a native-endian integer.
|
||||
pub fn writeIntNative(self: *Self, comptime T: type, value: T) Error!void {
|
||||
var bytes: [(T.bit_count + 7 )/ 8]u8 = undefined;
|
||||
var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
|
||||
mem.writeIntNative(T, &bytes, value);
|
||||
return self.writeFn(self, bytes);
|
||||
}
|
||||
|
||||
/// Write a foreign-endian integer.
|
||||
pub fn writeIntForeign(self: *Self, comptime T: type, value: T) Error!void {
|
||||
var bytes: [(T.bit_count + 7 )/ 8]u8 = undefined;
|
||||
var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
|
||||
mem.writeIntForeign(T, &bytes, value);
|
||||
return self.writeFn(self, bytes);
|
||||
}
|
||||
|
||||
pub fn writeIntLittle(self: *Self, comptime T: type, value: T) Error!void {
|
||||
var bytes: [(T.bit_count + 7 )/ 8]u8 = undefined;
|
||||
var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
|
||||
mem.writeIntLittle(T, &bytes, value);
|
||||
return self.writeFn(self, bytes);
|
||||
}
|
||||
|
||||
pub fn writeIntBig(self: *Self, comptime T: type, value: T) Error!void {
|
||||
var bytes: [(T.bit_count + 7 )/ 8]u8 = undefined;
|
||||
var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
|
||||
mem.writeIntBig(T, &bytes, value);
|
||||
return self.writeFn(self, bytes);
|
||||
}
|
||||
|
||||
pub fn writeInt(self: *Self, comptime T: type, value: T, endian: builtin.Endian) Error!void {
|
||||
var bytes: [(T.bit_count + 7 )/ 8]u8 = undefined;
|
||||
var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
|
||||
mem.writeInt(T, &bytes, value, endian);
|
||||
return self.writeFn(self, bytes);
|
||||
}
|
||||
|
||||
@ -597,7 +597,10 @@ test "c out stream" {
|
||||
|
||||
const filename = c"tmp_io_test_file.txt";
|
||||
const out_file = std.c.fopen(filename, c"w") orelse return error.UnableToOpenTestFile;
|
||||
defer fs.deleteFileC(filename) catch {};
|
||||
defer {
|
||||
_ = std.c.fclose(out_file);
|
||||
fs.deleteFileC(filename) catch {};
|
||||
}
|
||||
|
||||
const out_stream = &io.COutStream.init(out_file).stream;
|
||||
try out_stream.print("hi: {}\n", i32(123));
|
||||
|
||||
@ -876,8 +876,9 @@ pub const TokenStream = struct {
|
||||
|
||||
pub fn next(self: *TokenStream) !?Token {
|
||||
if (self.token) |token| {
|
||||
const copy = token;
|
||||
self.token = null;
|
||||
return token;
|
||||
return copy;
|
||||
}
|
||||
|
||||
var t1: ?Token = undefined;
|
||||
|
||||
@ -348,6 +348,7 @@ pub const DeleteFileError = error{
|
||||
FileNotFound,
|
||||
AccessDenied,
|
||||
NameTooLong,
|
||||
FileBusy,
|
||||
Unexpected,
|
||||
};
|
||||
|
||||
@ -363,6 +364,7 @@ pub fn DeleteFileW(filename: [*]const u16) DeleteFileError!void {
|
||||
ERROR.ACCESS_DENIED => return error.AccessDenied,
|
||||
ERROR.FILENAME_EXCED_RANGE => return error.NameTooLong,
|
||||
ERROR.INVALID_PARAMETER => return error.NameTooLong,
|
||||
ERROR.SHARING_VIOLATION => return error.FileBusy,
|
||||
else => |err| return unexpectedError(err),
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,20 +114,20 @@ extern fn main(c_argc: i32, c_argv: [*][*]u8, c_envp: [*]?[*]u8) i32 {
|
||||
// and we want fewer call frames in stack traces.
|
||||
inline fn callMain() u8 {
|
||||
switch (@typeId(@typeOf(root.main).ReturnType)) {
|
||||
builtin.TypeId.NoReturn => {
|
||||
.NoReturn => {
|
||||
root.main();
|
||||
},
|
||||
builtin.TypeId.Void => {
|
||||
.Void => {
|
||||
root.main();
|
||||
return 0;
|
||||
},
|
||||
builtin.TypeId.Int => {
|
||||
.Int => {
|
||||
if (@typeOf(root.main).ReturnType.bit_count != 8) {
|
||||
@compileError("expected return type of main to be 'u8', 'noreturn', 'void', or '!void'");
|
||||
}
|
||||
return root.main();
|
||||
},
|
||||
builtin.TypeId.ErrorUnion => {
|
||||
.ErrorUnion => {
|
||||
root.main() catch |err| {
|
||||
std.debug.warn("error: {}\n", @errorName(err));
|
||||
if (builtin.os != builtin.Os.zen) {
|
||||
|
||||
@ -73,12 +73,15 @@ pub extern fn __getf2(a: f128, b: f128) c_int {
|
||||
|
||||
if (aAbs > infRep or bAbs > infRep) return GE_UNORDERED;
|
||||
if ((aAbs | bAbs) == 0) return GE_EQUAL;
|
||||
return if ((aInt & bInt) >= 0) if (aInt < bInt)
|
||||
GE_LESS
|
||||
else if (aInt == bInt)
|
||||
GE_EQUAL
|
||||
else
|
||||
GE_GREATER else if (aInt > bInt)
|
||||
// zig fmt issue here, see https://github.com/ziglang/zig/issues/2661
|
||||
return if ((aInt & bInt) >= 0)
|
||||
if (aInt < bInt)
|
||||
GE_LESS
|
||||
else if (aInt == bInt)
|
||||
GE_EQUAL
|
||||
else
|
||||
GE_GREATER
|
||||
else if (aInt > bInt)
|
||||
GE_LESS
|
||||
else if (aInt == bInt)
|
||||
GE_EQUAL
|
||||
|
||||
@ -9,16 +9,15 @@ const std = @import("std");
|
||||
pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn {
|
||||
@setCold(true);
|
||||
switch (builtin.os) {
|
||||
// TODO: fix panic in zen
|
||||
builtin.Os.freestanding, builtin.Os.zen => {
|
||||
.freestanding => {
|
||||
while (true) {}
|
||||
},
|
||||
builtin.Os.wasi => {
|
||||
.wasi => {
|
||||
std.debug.warn("{}", msg);
|
||||
_ = std.os.wasi.proc_raise(std.os.wasi.SIGABRT);
|
||||
unreachable;
|
||||
},
|
||||
builtin.Os.uefi => {
|
||||
.uefi => {
|
||||
// TODO look into using the debug info and logging helpful messages
|
||||
std.os.abort();
|
||||
},
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// TODO remove `use` keyword eventually
|
||||
// TODO remove `use` keyword eventually: https://github.com/ziglang/zig/issues/2591
|
||||
test "zig fmt: change use to usingnamespace" {
|
||||
try testTransform(
|
||||
\\use @import("std");
|
||||
@ -1105,7 +1105,7 @@ test "zig fmt: first line comment in struct initializer" {
|
||||
try testCanonical(
|
||||
\\pub async fn acquire(self: *Self) HeldLock {
|
||||
\\ return HeldLock{
|
||||
\\ // TODO guaranteed allocation elision
|
||||
\\ // guaranteed allocation elision
|
||||
\\ .held = await (async self.lock.acquire() catch unreachable),
|
||||
\\ .value = &self.private_data,
|
||||
\\ };
|
||||
|
||||
@ -939,10 +939,10 @@ fn renderExpression(
|
||||
}
|
||||
|
||||
switch (container_decl.init_arg_expr) {
|
||||
ast.Node.ContainerDecl.InitArg.None => {
|
||||
.None => {
|
||||
try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.Space); // union
|
||||
},
|
||||
ast.Node.ContainerDecl.InitArg.Enum => |enum_tag_type| {
|
||||
.Enum => |enum_tag_type| {
|
||||
try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.None); // union
|
||||
|
||||
const lparen = tree.nextToken(container_decl.kind_token);
|
||||
@ -962,7 +962,7 @@ fn renderExpression(
|
||||
try renderToken(tree, stream, tree.nextToken(enum_token), indent, start_col, Space.Space); // )
|
||||
}
|
||||
},
|
||||
ast.Node.ContainerDecl.InitArg.Type => |type_expr| {
|
||||
.Type => |type_expr| {
|
||||
try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.None); // union
|
||||
|
||||
const lparen = tree.nextToken(container_decl.kind_token);
|
||||
|
||||
@ -49,16 +49,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\const Foo = struct {
|
||||
\\ a: undefined,
|
||||
\\};
|
||||
\\const Bar = union {
|
||||
\\ a: undefined,
|
||||
\\};
|
||||
\\pub fn main() void {
|
||||
\\export fn entry1() void {
|
||||
\\ const foo: Foo = undefined;
|
||||
\\ const bar: Bar = undefined;
|
||||
\\}
|
||||
,
|
||||
"tmp.zig:2:8: error: expected type 'type', found '(undefined)'",
|
||||
"tmp.zig:5:8: error: expected type 'type', found '(undefined)'",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
@ -461,13 +456,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\const G = packed struct {
|
||||
\\ x: Enum,
|
||||
\\};
|
||||
\\export fn entry() void {
|
||||
\\export fn entry1() void {
|
||||
\\ var a: A = undefined;
|
||||
\\}
|
||||
\\export fn entry2() void {
|
||||
\\ var b: B = undefined;
|
||||
\\}
|
||||
\\export fn entry3() void {
|
||||
\\ var r: C = undefined;
|
||||
\\}
|
||||
\\export fn entry4() void {
|
||||
\\ var d: D = undefined;
|
||||
\\}
|
||||
\\export fn entry5() void {
|
||||
\\ var e: E = undefined;
|
||||
\\}
|
||||
\\export fn entry6() void {
|
||||
\\ var f: F = undefined;
|
||||
\\}
|
||||
\\export fn entry7() void {
|
||||
\\ var g: G = undefined;
|
||||
\\}
|
||||
\\const S = struct {
|
||||
@ -489,7 +496,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
"tmp.zig:14:5: error: non-packed, non-extern struct 'U' not allowed in packed struct; no guaranteed in-memory representation",
|
||||
"tmp.zig:17:5: error: type '?anyerror' not allowed in packed struct; no guaranteed in-memory representation",
|
||||
"tmp.zig:20:5: error: type 'Enum' not allowed in packed struct; no guaranteed in-memory representation",
|
||||
"tmp.zig:38:14: note: enum declaration does not specify an integer tag type",
|
||||
"tmp.zig:50:14: note: enum declaration does not specify an integer tag type",
|
||||
);
|
||||
|
||||
cases.addCase(x: {
|
||||
@ -721,7 +728,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\ var oops = @bitCast(u7, byte);
|
||||
\\}
|
||||
,
|
||||
"tmp.zig:2:16: error: destination type 'u7' has 7 bits but source type 'u8' has 8 bits",
|
||||
"tmp.zig:2:25: error: destination type 'u7' has 7 bits but source type 'u8' has 8 bits",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
@ -1381,7 +1388,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\ for (xx) |f| {}
|
||||
\\}
|
||||
,
|
||||
"tmp.zig:7:15: error: variable of type 'Foo' must be const or comptime",
|
||||
"tmp.zig:7:5: error: values of type 'Foo' must be comptime known, but index value is runtime known",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
@ -2250,6 +2257,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\}
|
||||
\\
|
||||
\\extern fn bar(x: *void) void { }
|
||||
\\export fn entry2() void {
|
||||
\\ bar(&{});
|
||||
\\}
|
||||
,
|
||||
"tmp.zig:1:30: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'ccc'",
|
||||
"tmp.zig:7:18: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'ccc'",
|
||||
@ -2576,7 +2586,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\
|
||||
\\fn b() void {}
|
||||
,
|
||||
"tmp.zig:3:5: error: unreachable code",
|
||||
"tmp.zig:3:6: error: unreachable code",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
@ -2596,7 +2606,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\}
|
||||
,
|
||||
"tmp.zig:3:5: error: use of undeclared identifier 'b'",
|
||||
"tmp.zig:4:5: error: use of undeclared identifier 'c'",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
@ -2662,7 +2671,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\ const a: noreturn = {};
|
||||
\\}
|
||||
,
|
||||
"tmp.zig:2:14: error: variable of type 'noreturn' not allowed",
|
||||
"tmp.zig:2:25: error: expected type 'noreturn', found 'void'",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
@ -2725,9 +2734,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\ var bad : bool = undefined;
|
||||
\\ bad[bad] = bad[bad];
|
||||
\\}
|
||||
\\export fn g() void {
|
||||
\\ var bad : bool = undefined;
|
||||
\\ _ = bad[bad];
|
||||
\\}
|
||||
,
|
||||
"tmp.zig:3:8: error: array access of non-array type 'bool'",
|
||||
"tmp.zig:3:19: error: array access of non-array type 'bool'",
|
||||
"tmp.zig:7:12: error: array access of non-array type 'bool'",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
@ -2737,9 +2750,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\ var bad = false;
|
||||
\\ array[bad] = array[bad];
|
||||
\\}
|
||||
\\export fn g() void {
|
||||
\\ var array = "aoeu";
|
||||
\\ var bad = false;
|
||||
\\ _ = array[bad];
|
||||
\\}
|
||||
,
|
||||
"tmp.zig:4:11: error: expected type 'usize', found 'bool'",
|
||||
"tmp.zig:4:24: error: expected type 'usize', found 'bool'",
|
||||
"tmp.zig:9:15: error: expected type 'usize', found 'bool'",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
@ -2757,12 +2775,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
"missing else clause",
|
||||
\\fn f(b: bool) void {
|
||||
\\ const x : i32 = if (b) h: { break :h 1; };
|
||||
\\}
|
||||
\\fn g(b: bool) void {
|
||||
\\ const y = if (b) h: { break :h i32(1); };
|
||||
\\}
|
||||
\\export fn entry() void { f(true); }
|
||||
\\export fn entry() void { f(true); g(true); }
|
||||
,
|
||||
"tmp.zig:2:42: error: integer value 1 cannot be implicitly casted to type 'void'",
|
||||
"tmp.zig:3:15: error: incompatible types: 'i32' and 'void'",
|
||||
"tmp.zig:5:15: error: incompatible types: 'i32' and 'void'",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
@ -2773,9 +2793,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\ a.foo = 1;
|
||||
\\ const y = a.bar;
|
||||
\\}
|
||||
\\export fn g() void {
|
||||
\\ var a : A = undefined;
|
||||
\\ const y = a.bar;
|
||||
\\}
|
||||
,
|
||||
"tmp.zig:4:6: error: no member named 'foo' in struct 'A'",
|
||||
"tmp.zig:5:16: error: no member named 'bar' in struct 'A'",
|
||||
"tmp.zig:9:16: error: no member named 'bar' in struct 'A'",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
@ -2920,7 +2944,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\ _ = foo;
|
||||
\\}
|
||||
,
|
||||
"tmp.zig:1:19: error: type '[3]u16' does not support struct initialization syntax",
|
||||
"tmp.zig:1:21: error: type '[3]u16' does not support struct initialization syntax",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
@ -3239,7 +3263,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\
|
||||
\\export fn entry() usize { return @sizeOf(@typeOf(Foo)); }
|
||||
,
|
||||
"tmp.zig:5:25: error: unable to evaluate constant expression",
|
||||
"tmp.zig:5:18: error: unable to evaluate constant expression",
|
||||
"tmp.zig:2:12: note: called from here",
|
||||
"tmp.zig:2:8: note: called from here",
|
||||
);
|
||||
@ -3856,7 +3880,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\ return 2;
|
||||
\\}
|
||||
,
|
||||
"tmp.zig:2:15: error: values of type 'comptime_int' must be comptime known",
|
||||
"tmp.zig:5:17: error: cannot store runtime value in type 'comptime_int'",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
@ -5108,7 +5132,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\ const array = [2]u8{1, 2, 3};
|
||||
\\}
|
||||
,
|
||||
"tmp.zig:2:24: error: expected [2]u8 literal, found [3]u8 literal",
|
||||
"tmp.zig:2:31: error: index 2 outside array of size 2",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
@ -5125,36 +5149,47 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
|
||||
cases.add(
|
||||
"non-const variables of things that require const variables",
|
||||
\\const Opaque = @OpaqueType();
|
||||
\\
|
||||
\\export fn entry(opaque: *Opaque) void {
|
||||
\\export fn entry1() void {
|
||||
\\ var m2 = &2;
|
||||
\\ const y: u32 = m2.*;
|
||||
\\
|
||||
\\}
|
||||
\\export fn entry2() void {
|
||||
\\ var a = undefined;
|
||||
\\}
|
||||
\\export fn entry3() void {
|
||||
\\ var b = 1;
|
||||
\\}
|
||||
\\export fn entry4() void {
|
||||
\\ var c = 1.0;
|
||||
\\}
|
||||
\\export fn entry5() void {
|
||||
\\ var d = null;
|
||||
\\}
|
||||
\\export fn entry6(opaque: *Opaque) void {
|
||||
\\ var e = opaque.*;
|
||||
\\}
|
||||
\\export fn entry7() void {
|
||||
\\ var f = i32;
|
||||
\\}
|
||||
\\export fn entry8() void {
|
||||
\\ var h = (Foo {}).bar;
|
||||
\\
|
||||
\\}
|
||||
\\export fn entry9() void {
|
||||
\\ var z: noreturn = return;
|
||||
\\}
|
||||
\\
|
||||
\\const Opaque = @OpaqueType();
|
||||
\\const Foo = struct {
|
||||
\\ fn bar(self: *const Foo) void {}
|
||||
\\};
|
||||
,
|
||||
"tmp.zig:4:4: error: variable of type '*comptime_int' must be const or comptime",
|
||||
"tmp.zig:7:4: error: variable of type '(undefined)' must be const or comptime",
|
||||
"tmp.zig:2:4: error: variable of type '*comptime_int' must be const or comptime",
|
||||
"tmp.zig:5:4: error: variable of type '(undefined)' must be const or comptime",
|
||||
"tmp.zig:8:4: error: variable of type 'comptime_int' must be const or comptime",
|
||||
"tmp.zig:9:4: error: variable of type 'comptime_float' must be const or comptime",
|
||||
"tmp.zig:10:4: error: variable of type '(null)' must be const or comptime",
|
||||
"tmp.zig:11:4: error: variable of type 'Opaque' not allowed",
|
||||
"tmp.zig:12:4: error: variable of type 'type' must be const or comptime",
|
||||
"tmp.zig:13:4: error: variable of type '(bound fn(*const Foo) void)' must be const or comptime",
|
||||
"tmp.zig:15:4: error: unreachable code",
|
||||
"tmp.zig:11:4: error: variable of type 'comptime_float' must be const or comptime",
|
||||
"tmp.zig:14:4: error: variable of type '(null)' must be const or comptime",
|
||||
"tmp.zig:17:4: error: variable of type 'Opaque' not allowed",
|
||||
"tmp.zig:20:4: error: variable of type 'type' must be const or comptime",
|
||||
"tmp.zig:23:4: error: variable of type '(bound fn(*const Foo) void)' must be const or comptime",
|
||||
"tmp.zig:26:4: error: unreachable code",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
@ -5300,7 +5335,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\ }
|
||||
\\}
|
||||
,
|
||||
"tmp.zig:37:16: error: cannot store runtime value in compile time variable",
|
||||
"tmp.zig:37:29: error: cannot store runtime value in compile time variable",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
@ -5924,7 +5959,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\ const foo = Foo { .Bar = x, .Baz = u8 };
|
||||
\\}
|
||||
,
|
||||
"tmp.zig:7:30: error: unable to evaluate constant expression",
|
||||
"tmp.zig:7:23: error: unable to evaluate constant expression",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
@ -5938,7 +5973,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\ const foo = Foo { .Bar = x };
|
||||
\\}
|
||||
,
|
||||
"tmp.zig:7:30: error: unable to evaluate constant expression",
|
||||
"tmp.zig:7:23: error: unable to evaluate constant expression",
|
||||
);
|
||||
|
||||
cases.addTest(
|
||||
|
||||
@ -172,6 +172,12 @@ fn plusOne(x: u32) u32 {
|
||||
return x + 1;
|
||||
}
|
||||
|
||||
test "runtime initialize array elem and then implicit cast to slice" {
|
||||
var two: i32 = 2;
|
||||
const x: []const i32 = [_]i32{two};
|
||||
expect(x[0] == 2);
|
||||
}
|
||||
|
||||
test "array literal as argument to function" {
|
||||
const S = struct {
|
||||
fn entry(two: i32) void {
|
||||
@ -227,7 +233,7 @@ test "double nested array to const slice cast in array literal" {
|
||||
|
||||
const cases2 = [_][]const i32{
|
||||
[_]i32{1},
|
||||
[_]i32{ two, 3 },
|
||||
&[_]i32{ two, 3 },
|
||||
};
|
||||
expect(cases2.len == 2);
|
||||
expect(cases2[0].len == 1);
|
||||
@ -238,7 +244,7 @@ test "double nested array to const slice cast in array literal" {
|
||||
|
||||
const cases3 = [_][]const []const i32{
|
||||
[_][]const i32{[_]i32{1}},
|
||||
[_][]const i32{[_]i32{ two, 3 }},
|
||||
&[_][]const i32{&[_]i32{ two, 3 }},
|
||||
[_][]const i32{
|
||||
[_]i32{4},
|
||||
[_]i32{ 5, 6, 7 },
|
||||
|
||||
@ -112,3 +112,16 @@ test "bitcast packed struct to integer and back" {
|
||||
S.doTheTest();
|
||||
comptime S.doTheTest();
|
||||
}
|
||||
|
||||
test "implicit cast to error union by returning" {
|
||||
const S = struct {
|
||||
fn entry() void {
|
||||
expect((func(-1) catch unreachable) == maxInt(u64));
|
||||
}
|
||||
pub fn func(sz: i64) anyerror!u64 {
|
||||
return @bitCast(u64, sz);
|
||||
}
|
||||
};
|
||||
S.entry();
|
||||
comptime S.entry();
|
||||
}
|
||||
|
||||
@ -482,3 +482,40 @@ test "@intCast to u0 and use the result" {
|
||||
S.doTheTest(0, 1, 0);
|
||||
comptime S.doTheTest(0, 1, 0);
|
||||
}
|
||||
|
||||
test "peer type resolution: unreachable, null, slice" {
|
||||
const S = struct {
|
||||
fn doTheTest(num: usize, word: []const u8) void {
|
||||
const result = switch (num) {
|
||||
0 => null,
|
||||
1 => word,
|
||||
else => unreachable,
|
||||
};
|
||||
expect(mem.eql(u8, result.?, "hi"));
|
||||
}
|
||||
};
|
||||
S.doTheTest(1, "hi");
|
||||
}
|
||||
|
||||
test "peer type resolution: unreachable, error set, unreachable" {
|
||||
const Error = error {
|
||||
FileDescriptorAlreadyPresentInSet,
|
||||
OperationCausesCircularLoop,
|
||||
FileDescriptorNotRegistered,
|
||||
SystemResources,
|
||||
UserResourceLimitReached,
|
||||
FileDescriptorIncompatibleWithEpoll,
|
||||
Unexpected,
|
||||
};
|
||||
var err = Error.SystemResources;
|
||||
const transformed_err = switch (err) {
|
||||
error.FileDescriptorAlreadyPresentInSet => unreachable,
|
||||
error.OperationCausesCircularLoop => unreachable,
|
||||
error.FileDescriptorNotRegistered => unreachable,
|
||||
error.SystemResources => error.SystemResources,
|
||||
error.UserResourceLimitReached => error.UserResourceLimitReached,
|
||||
error.FileDescriptorIncompatibleWithEpoll => unreachable,
|
||||
error.Unexpected => unreachable,
|
||||
};
|
||||
expect(transformed_err == error.SystemResources);
|
||||
}
|
||||
|
||||
@ -335,3 +335,43 @@ test "debug info for optional error set" {
|
||||
const SomeError = error{Hello};
|
||||
var a_local_variable: ?SomeError = null;
|
||||
}
|
||||
|
||||
test "nested catch" {
|
||||
const S = struct {
|
||||
fn entry() void {
|
||||
expectError(error.Bad, func());
|
||||
}
|
||||
fn fail() anyerror!Foo {
|
||||
return error.Wrong;
|
||||
}
|
||||
fn func() anyerror!Foo {
|
||||
const x = fail() catch
|
||||
fail() catch
|
||||
return error.Bad;
|
||||
unreachable;
|
||||
}
|
||||
const Foo = struct {
|
||||
field: i32,
|
||||
};
|
||||
};
|
||||
S.entry();
|
||||
comptime S.entry();
|
||||
}
|
||||
|
||||
test "implicit cast to optional to error union to return result loc" {
|
||||
const S = struct {
|
||||
fn entry() void {
|
||||
if (func(undefined)) |opt| {
|
||||
expect(opt != null);
|
||||
} else |_| @panic("expected non error");
|
||||
}
|
||||
fn func(f: *Foo) anyerror!?*Foo {
|
||||
return f;
|
||||
}
|
||||
const Foo = struct {
|
||||
field: i32,
|
||||
};
|
||||
};
|
||||
S.entry();
|
||||
//comptime S.entry(); TODO
|
||||
}
|
||||
|
||||
@ -190,6 +190,17 @@ fn testTryToTrickEvalWithRuntimeIf(b: bool) usize {
|
||||
}
|
||||
}
|
||||
|
||||
test "inlined loop has array literal with elided runtime scope on first iteration but not second iteration" {
|
||||
var runtime = [1]i32{3};
|
||||
comptime var i: usize = 0;
|
||||
inline while (i < 2) : (i += 1) {
|
||||
const result = if (i == 0) [1]i32{2} else runtime;
|
||||
}
|
||||
comptime {
|
||||
expect(i == 2);
|
||||
}
|
||||
}
|
||||
|
||||
fn max(comptime T: type, a: T, b: T) T {
|
||||
if (T == bool) {
|
||||
return a or b;
|
||||
@ -756,8 +767,7 @@ test "comptime bitwise operators" {
|
||||
test "*align(1) u16 is the same as *align(1:0:2) u16" {
|
||||
comptime {
|
||||
expect(*align(1:0:2) u16 == *align(1) u16);
|
||||
// TODO add parsing support for this syntax
|
||||
//expect(*align(:0:2) u16 == *u16);
|
||||
expect(*align(:0:2) u16 == *u16);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -205,3 +205,26 @@ test "extern struct with stdcallcc fn pointer" {
|
||||
s.ptr = S.foo;
|
||||
expect(s.ptr() == 1234);
|
||||
}
|
||||
|
||||
test "implicit cast fn call result to optional in field result" {
|
||||
const S = struct {
|
||||
fn entry() void {
|
||||
var x = Foo{
|
||||
.field = optionalPtr(),
|
||||
};
|
||||
expect(x.field.?.* == 999);
|
||||
}
|
||||
|
||||
const glob: i32 = 999;
|
||||
|
||||
fn optionalPtr() *const i32 {
|
||||
return &glob;
|
||||
}
|
||||
|
||||
const Foo = struct {
|
||||
field: ?*const i32,
|
||||
};
|
||||
};
|
||||
S.entry();
|
||||
comptime S.entry();
|
||||
}
|
||||
|
||||
@ -110,3 +110,19 @@ fn testContinueOuter() void {
|
||||
}
|
||||
expect(counter == array.len);
|
||||
}
|
||||
|
||||
test "2 break statements and an else" {
|
||||
const S = struct {
|
||||
fn entry(t: bool, f: bool) void {
|
||||
var buf: [10]u8 = undefined;
|
||||
var ok = false;
|
||||
ok = for (buf) |item| {
|
||||
if (f) break false;
|
||||
if (t) break true;
|
||||
} else false;
|
||||
expect(ok);
|
||||
}
|
||||
};
|
||||
S.entry(true, false);
|
||||
comptime S.entry(true, false);
|
||||
}
|
||||
|
||||
@ -52,3 +52,14 @@ test "unwrap mutable global var" {
|
||||
expect(e == error.SomeError);
|
||||
}
|
||||
}
|
||||
|
||||
test "labeled break inside comptime if inside runtime if" {
|
||||
var answer: i32 = 0;
|
||||
var c = true;
|
||||
if (c) {
|
||||
answer = if (true) blk: {
|
||||
break :blk i32(42);
|
||||
};
|
||||
}
|
||||
expect(answer == 42);
|
||||
}
|
||||
|
||||
@ -698,3 +698,11 @@ test "unicode escape in character literal" {
|
||||
var a: u24 = '\U01f4a9';
|
||||
expect(a == 128169);
|
||||
}
|
||||
|
||||
test "result location zero sized array inside struct field implicit cast to slice" {
|
||||
const E = struct {
|
||||
entries: []u32,
|
||||
};
|
||||
var foo = E{ .entries = [_]u32{} };
|
||||
expect(foo.entries.len == 0);
|
||||
}
|
||||
|
||||
@ -76,6 +76,27 @@ test "unwrap function call with optional pointer return value" {
|
||||
}
|
||||
};
|
||||
S.entry();
|
||||
// TODO https://github.com/ziglang/zig/issues/1901
|
||||
//comptime S.entry();
|
||||
comptime S.entry();
|
||||
}
|
||||
|
||||
test "nested orelse" {
|
||||
const S = struct {
|
||||
fn entry() void {
|
||||
expect(func() == null);
|
||||
}
|
||||
fn maybe() ?Foo {
|
||||
return null;
|
||||
}
|
||||
fn func() ?Foo {
|
||||
const x = maybe() orelse
|
||||
maybe() orelse
|
||||
return null;
|
||||
unreachable;
|
||||
}
|
||||
const Foo = struct {
|
||||
field: i32,
|
||||
};
|
||||
};
|
||||
S.entry();
|
||||
comptime S.entry();
|
||||
}
|
||||
|
||||
@ -578,3 +578,24 @@ test "default struct initialization fields" {
|
||||
};
|
||||
expectEqual(1239, x.a + x.b);
|
||||
}
|
||||
|
||||
test "extern fn returns struct by value" {
|
||||
const S = struct {
|
||||
fn entry() void {
|
||||
var x = makeBar(10);
|
||||
expectEqual(i32(10), x.handle);
|
||||
}
|
||||
|
||||
const ExternBar = extern struct {
|
||||
handle: i32,
|
||||
};
|
||||
|
||||
extern fn makeBar(t: i32) ExternBar {
|
||||
return ExternBar{
|
||||
.handle = t,
|
||||
};
|
||||
}
|
||||
};
|
||||
S.entry();
|
||||
comptime S.entry();
|
||||
}
|
||||
|
||||
@ -360,3 +360,19 @@ test "switch prongs with error set cases make a new error set type for capture v
|
||||
S.doTheTest();
|
||||
comptime S.doTheTest();
|
||||
}
|
||||
|
||||
test "return result loc and then switch with range implicit casted to error union" {
|
||||
const S = struct {
|
||||
fn doTheTest() void {
|
||||
expect((func(0xb) catch unreachable) == 0xb);
|
||||
}
|
||||
fn func(d: u8) anyerror!u8 {
|
||||
return switch (d) {
|
||||
0xa...0xf => d,
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
};
|
||||
S.doTheTest();
|
||||
comptime S.doTheTest();
|
||||
}
|
||||
|
||||
@ -402,3 +402,23 @@ test "comptime union field value equality" {
|
||||
expect(a0 != a1);
|
||||
expect(b0 != b1);
|
||||
}
|
||||
|
||||
test "return union init with void payload" {
|
||||
const S = struct {
|
||||
fn entry() void {
|
||||
expect(func().state == State.one);
|
||||
}
|
||||
const Outer = union(enum) {
|
||||
state: State,
|
||||
};
|
||||
const State = union(enum) {
|
||||
one: void,
|
||||
two: u32,
|
||||
};
|
||||
fn func() Outer {
|
||||
return Outer{ .state = State{ .one = {} }};
|
||||
}
|
||||
};
|
||||
S.entry();
|
||||
comptime S.entry();
|
||||
}
|
||||
|
||||
@ -61,3 +61,16 @@ test "vector bit operators" {
|
||||
S.doTheTest();
|
||||
comptime S.doTheTest();
|
||||
}
|
||||
|
||||
test "implicit cast vector to array" {
|
||||
const S = struct {
|
||||
fn doTheTest() void {
|
||||
var a: @Vector(4, i32) = [_]i32{ 1, 2, 3, 4 };
|
||||
var result_array: [4]i32 = a;
|
||||
result_array = a;
|
||||
expect(mem.eql(i32, result_array, [4]i32{ 1, 2, 3, 4 }));
|
||||
}
|
||||
};
|
||||
S.doTheTest();
|
||||
comptime S.doTheTest();
|
||||
}
|
||||
|
||||
@ -226,3 +226,48 @@ fn returnFalse() bool {
|
||||
fn returnTrue() bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
test "while bool 2 break statements and an else" {
|
||||
const S = struct {
|
||||
fn entry(t: bool, f: bool) void {
|
||||
var ok = false;
|
||||
ok = while (t) {
|
||||
if (f) break false;
|
||||
if (t) break true;
|
||||
} else false;
|
||||
expect(ok);
|
||||
}
|
||||
};
|
||||
S.entry(true, false);
|
||||
comptime S.entry(true, false);
|
||||
}
|
||||
|
||||
test "while optional 2 break statements and an else" {
|
||||
const S = struct {
|
||||
fn entry(opt_t: ?bool, f: bool) void {
|
||||
var ok = false;
|
||||
ok = while (opt_t) |t| {
|
||||
if (f) break false;
|
||||
if (t) break true;
|
||||
} else false;
|
||||
expect(ok);
|
||||
}
|
||||
};
|
||||
S.entry(true, false);
|
||||
comptime S.entry(true, false);
|
||||
}
|
||||
|
||||
test "while error 2 break statements and an else" {
|
||||
const S = struct {
|
||||
fn entry(opt_t: anyerror!bool, f: bool) void {
|
||||
var ok = false;
|
||||
ok = while (opt_t) |t| {
|
||||
if (f) break false;
|
||||
if (t) break true;
|
||||
} else |_| false;
|
||||
expect(ok);
|
||||
}
|
||||
};
|
||||
S.entry(true, false);
|
||||
comptime S.entry(true, false);
|
||||
}
|
||||
|
||||
@ -811,23 +811,21 @@ pub const CompileErrorContext = struct {
|
||||
pub fn addCase(self: *CompileErrorContext, case: *const TestCase) void {
|
||||
const b = self.b;
|
||||
|
||||
for (self.modes) |mode| {
|
||||
const annotated_case_name = fmt.allocPrint(self.b.allocator, "compile-error {} ({})", case.name, @tagName(mode)) catch unreachable;
|
||||
if (self.test_filter) |filter| {
|
||||
if (mem.indexOf(u8, annotated_case_name, filter) == null) continue;
|
||||
}
|
||||
const annotated_case_name = fmt.allocPrint(self.b.allocator, "compile-error {}", case.name) catch unreachable;
|
||||
if (self.test_filter) |filter| {
|
||||
if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
|
||||
}
|
||||
|
||||
const compile_and_cmp_errors = CompileCmpOutputStep.create(self, annotated_case_name, case, mode);
|
||||
self.step.dependOn(&compile_and_cmp_errors.step);
|
||||
const compile_and_cmp_errors = CompileCmpOutputStep.create(self, annotated_case_name, case, .Debug);
|
||||
self.step.dependOn(&compile_and_cmp_errors.step);
|
||||
|
||||
for (case.sources.toSliceConst()) |src_file| {
|
||||
const expanded_src_path = fs.path.join(
|
||||
b.allocator,
|
||||
[_][]const u8{ b.cache_root, src_file.filename },
|
||||
) catch unreachable;
|
||||
const write_src = b.addWriteFile(expanded_src_path, src_file.source);
|
||||
compile_and_cmp_errors.step.dependOn(&write_src.step);
|
||||
}
|
||||
for (case.sources.toSliceConst()) |src_file| {
|
||||
const expanded_src_path = fs.path.join(
|
||||
b.allocator,
|
||||
[_][]const u8{ b.cache_root, src_file.filename },
|
||||
) catch unreachable;
|
||||
const write_src = b.addWriteFile(expanded_src_path, src_file.source);
|
||||
compile_and_cmp_errors.step.dependOn(&write_src.step);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user