aboutsummaryrefslogtreecommitdiff
path: root/src/Module.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/Module.zig')
-rw-r--r--src/Module.zig352
1 files changed, 351 insertions, 1 deletions
diff --git a/src/Module.zig b/src/Module.zig
index 83406c36a4..283a4f75cc 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -13,7 +13,6 @@ const BigIntConst = std.math.big.int.Const;
const BigIntMutable = std.math.big.int.Mutable;
const Target = std.Target;
const Ast = std.zig.Ast;
-const LazySrcLoc = std.zig.LazySrcLoc;
/// Deprecated, use `Zcu`.
const Module = Zcu;
@@ -1905,6 +1904,357 @@ pub const SrcLoc = struct {
}
};
+/// Resolving a source location into a byte offset may require doing work
+/// that we would rather not do unless the error actually occurs.
+/// Therefore we need a data structure that contains the information necessary
+/// to lazily produce a `SrcLoc` as required.
+/// Most of the offsets in this data structure are relative to the containing Decl.
+/// This makes the source location resolve properly even when a Decl gets
+/// shifted up or down in the file, as long as the Decl's contents itself
+/// do not change.
+pub const LazySrcLoc = union(enum) {
+ /// When this tag is set, the code that constructed this `LazySrcLoc` is asserting
+ /// that all code paths which would need to resolve the source location are
+ /// unreachable. If you are debugging this tag incorrectly being this value,
+ /// look into using reverse-continue with a memory watchpoint to see where the
+ /// value is being set to this tag.
+ unneeded,
+ /// Means the source location points to an entire file; not any particular
+ /// location within the file. `file_scope` union field will be active.
+ entire_file,
+ /// The source location points to a byte offset within a source file,
+ /// offset from 0. The source file is determined contextually.
+ /// Inside a `SrcLoc`, the `file_scope` union field will be active.
+ byte_abs: u32,
+ /// The source location points to a token within a source file,
+ /// offset from 0. The source file is determined contextually.
+ /// Inside a `SrcLoc`, the `file_scope` union field will be active.
+ token_abs: u32,
+ /// The source location points to an AST node within a source file,
+ /// offset from 0. The source file is determined contextually.
+ /// Inside a `SrcLoc`, the `file_scope` union field will be active.
+ node_abs: u32,
+ /// The source location points to a byte offset within a source file,
+ /// offset from the byte offset of the Decl within the file.
+ /// The Decl is determined contextually.
+ byte_offset: u32,
+ /// This data is the offset into the token list from the Decl token.
+ /// The Decl is determined contextually.
+ token_offset: u32,
+ /// The source location points to an AST node, which is this value offset
+ /// from its containing Decl node AST index.
+ /// The Decl is determined contextually.
+ node_offset: TracedOffset,
+ /// The source location points to the main token of an AST node, found
+ /// by taking this AST node index offset from the containing Decl AST node.
+ /// The Decl is determined contextually.
+ node_offset_main_token: i32,
+ /// The source location points to the beginning of a struct initializer.
+ /// The Decl is determined contextually.
+ node_offset_initializer: i32,
+ /// The source location points to a variable declaration type expression,
+ /// found by taking this AST node index offset from the containing
+ /// Decl AST node, which points to a variable declaration AST node. Next, navigate
+ /// to the type expression.
+ /// The Decl is determined contextually.
+ node_offset_var_decl_ty: i32,
+ /// The source location points to the alignment expression of a var decl.
+ /// The Decl is determined contextually.
+ node_offset_var_decl_align: i32,
+ /// The source location points to the linksection expression of a var decl.
+ /// The Decl is determined contextually.
+ node_offset_var_decl_section: i32,
+ /// The source location points to the addrspace expression of a var decl.
+ /// The Decl is determined contextually.
+ node_offset_var_decl_addrspace: i32,
+ /// The source location points to the initializer of a var decl.
+ /// The Decl is determined contextually.
+ node_offset_var_decl_init: i32,
+ /// The source location points to the first parameter of a builtin
+ /// function call, found by taking this AST node index offset from the containing
+ /// Decl AST node, which points to a builtin call AST node. Next, navigate
+ /// to the first parameter.
+ /// The Decl is determined contextually.
+ node_offset_builtin_call_arg0: i32,
+ /// Same as `node_offset_builtin_call_arg0` except arg index 1.
+ node_offset_builtin_call_arg1: i32,
+ node_offset_builtin_call_arg2: i32,
+ node_offset_builtin_call_arg3: i32,
+ node_offset_builtin_call_arg4: i32,
+ node_offset_builtin_call_arg5: i32,
+ /// Like `node_offset_builtin_call_arg0` but recurses through arbitrarily many calls
+ /// to pointer cast builtins.
+ node_offset_ptrcast_operand: i32,
+ /// The source location points to the index expression of an array access
+ /// expression, found by taking this AST node index offset from the containing
+ /// Decl AST node, which points to an array access AST node. Next, navigate
+ /// to the index expression.
+ /// The Decl is determined contextually.
+ node_offset_array_access_index: i32,
+ /// The source location points to the LHS of a slice expression
+ /// expression, found by taking this AST node index offset from the containing
+ /// Decl AST node, which points to a slice AST node. Next, navigate
+ /// to the sentinel expression.
+ /// The Decl is determined contextually.
+ node_offset_slice_ptr: i32,
+ /// The source location points to start expression of a slice expression
+ /// expression, found by taking this AST node index offset from the containing
+ /// Decl AST node, which points to a slice AST node. Next, navigate
+ /// to the sentinel expression.
+ /// The Decl is determined contextually.
+ node_offset_slice_start: i32,
+ /// The source location points to the end expression of a slice
+ /// expression, found by taking this AST node index offset from the containing
+ /// Decl AST node, which points to a slice AST node. Next, navigate
+ /// to the sentinel expression.
+ /// The Decl is determined contextually.
+ node_offset_slice_end: i32,
+ /// The source location points to the sentinel expression of a slice
+ /// expression, found by taking this AST node index offset from the containing
+ /// Decl AST node, which points to a slice AST node. Next, navigate
+ /// to the sentinel expression.
+ /// The Decl is determined contextually.
+ node_offset_slice_sentinel: i32,
+ /// The source location points to the callee expression of a function
+ /// call expression, found by taking this AST node index offset from the containing
+ /// Decl AST node, which points to a function call AST node. Next, navigate
+ /// to the callee expression.
+ /// The Decl is determined contextually.
+ node_offset_call_func: i32,
+ /// The payload is offset from the containing Decl AST node.
+ /// The source location points to the field name of:
+ /// * a field access expression (`a.b`), or
+ /// * the callee of a method call (`a.b()`)
+ /// The Decl is determined contextually.
+ node_offset_field_name: i32,
+ /// The payload is offset from the containing Decl AST node.
+ /// The source location points to the field name of the operand ("b" node)
+ /// of a field initialization expression (`.a = b`)
+ /// The Decl is determined contextually.
+ node_offset_field_name_init: i32,
+ /// The source location points to the pointer of a pointer deref expression,
+ /// found by taking this AST node index offset from the containing
+ /// Decl AST node, which points to a pointer deref AST node. Next, navigate
+ /// to the pointer expression.
+ /// The Decl is determined contextually.
+ node_offset_deref_ptr: i32,
+ /// The source location points to the assembly source code of an inline assembly
+ /// expression, found by taking this AST node index offset from the containing
+ /// Decl AST node, which points to inline assembly AST node. Next, navigate
+ /// to the asm template source code.
+ /// The Decl is determined contextually.
+ node_offset_asm_source: i32,
+ /// The source location points to the return type of an inline assembly
+ /// expression, found by taking this AST node index offset from the containing
+ /// Decl AST node, which points to inline assembly AST node. Next, navigate
+ /// to the return type expression.
+ /// The Decl is determined contextually.
+ node_offset_asm_ret_ty: i32,
+ /// The source location points to the condition expression of an if
+ /// expression, found by taking this AST node index offset from the containing
+ /// Decl AST node, which points to an if expression AST node. Next, navigate
+ /// to the condition expression.
+ /// The Decl is determined contextually.
+ node_offset_if_cond: i32,
+ /// The source location points to a binary expression, such as `a + b`, found
+ /// by taking this AST node index offset from the containing Decl AST node.
+ /// The Decl is determined contextually.
+ node_offset_bin_op: i32,
+ /// The source location points to the LHS of a binary expression, found
+ /// by taking this AST node index offset from the containing Decl AST node,
+ /// which points to a binary expression AST node. Next, navigate to the LHS.
+ /// The Decl is determined contextually.
+ node_offset_bin_lhs: i32,
+ /// The source location points to the RHS of a binary expression, found
+ /// by taking this AST node index offset from the containing Decl AST node,
+ /// which points to a binary expression AST node. Next, navigate to the RHS.
+ /// The Decl is determined contextually.
+ node_offset_bin_rhs: i32,
+ /// The source location points to the operand of a switch expression, found
+ /// by taking this AST node index offset from the containing Decl AST node,
+ /// which points to a switch expression AST node. Next, navigate to the operand.
+ /// The Decl is determined contextually.
+ node_offset_switch_operand: i32,
+ /// The source location points to the else/`_` prong of a switch expression, found
+ /// by taking this AST node index offset from the containing Decl AST node,
+ /// which points to a switch expression AST node. Next, navigate to the else/`_` prong.
+ /// The Decl is determined contextually.
+ node_offset_switch_special_prong: i32,
+ /// The source location points to all the ranges of a switch expression, found
+ /// by taking this AST node index offset from the containing Decl AST node,
+ /// which points to a switch expression AST node. Next, navigate to any of the
+ /// range nodes. The error applies to all of them.
+ /// The Decl is determined contextually.
+ node_offset_switch_range: i32,
+ /// The source location points to the capture of a switch_prong.
+ /// The Decl is determined contextually.
+ node_offset_switch_prong_capture: i32,
+ /// The source location points to the tag capture of a switch_prong.
+ /// The Decl is determined contextually.
+ node_offset_switch_prong_tag_capture: i32,
+ /// The source location points to the align expr of a function type
+ /// expression, found by taking this AST node index offset from the containing
+ /// Decl AST node, which points to a function type AST node. Next, navigate to
+ /// the calling convention node.
+ /// The Decl is determined contextually.
+ node_offset_fn_type_align: i32,
+ /// The source location points to the addrspace expr of a function type
+ /// expression, found by taking this AST node index offset from the containing
+ /// Decl AST node, which points to a function type AST node. Next, navigate to
+ /// the calling convention node.
+ /// The Decl is determined contextually.
+ node_offset_fn_type_addrspace: i32,
+ /// The source location points to the linksection expr of a function type
+ /// expression, found by taking this AST node index offset from the containing
+ /// Decl AST node, which points to a function type AST node. Next, navigate to
+ /// the calling convention node.
+ /// The Decl is determined contextually.
+ node_offset_fn_type_section: i32,
+ /// The source location points to the calling convention of a function type
+ /// expression, found by taking this AST node index offset from the containing
+ /// Decl AST node, which points to a function type AST node. Next, navigate to
+ /// the calling convention node.
+ /// The Decl is determined contextually.
+ node_offset_fn_type_cc: i32,
+ /// The source location points to the return type of a function type
+ /// expression, found by taking this AST node index offset from the containing
+ /// Decl AST node, which points to a function type AST node. Next, navigate to
+ /// the return type node.
+ /// The Decl is determined contextually.
+ node_offset_fn_type_ret_ty: i32,
+ node_offset_param: i32,
+ token_offset_param: i32,
+ /// The source location points to the type expression of an `anyframe->T`
+ /// expression, found by taking this AST node index offset from the containing
+ /// Decl AST node, which points to a `anyframe->T` expression AST node. Next, navigate
+ /// to the type expression.
+ /// The Decl is determined contextually.
+ node_offset_anyframe_type: i32,
+ /// The source location points to the string literal of `extern "foo"`, found
+ /// by taking this AST node index offset from the containing
+ /// Decl AST node, which points to a function prototype or variable declaration
+ /// expression AST node. Next, navigate to the string literal of the `extern "foo"`.
+ /// The Decl is determined contextually.
+ node_offset_lib_name: i32,
+ /// The source location points to the len expression of an `[N:S]T`
+ /// expression, found by taking this AST node index offset from the containing
+ /// Decl AST node, which points to an `[N:S]T` expression AST node. Next, navigate
+ /// to the len expression.
+ /// The Decl is determined contextually.
+ node_offset_array_type_len: i32,
+ /// The source location points to the sentinel expression of an `[N:S]T`
+ /// expression, found by taking this AST node index offset from the containing
+ /// Decl AST node, which points to an `[N:S]T` expression AST node. Next, navigate
+ /// to the sentinel expression.
+ /// The Decl is determined contextually.
+ node_offset_array_type_sentinel: i32,
+ /// The source location points to the elem expression of an `[N:S]T`
+ /// expression, found by taking this AST node index offset from the containing
+ /// Decl AST node, which points to an `[N:S]T` expression AST node. Next, navigate
+ /// to the elem expression.
+ /// The Decl is determined contextually.
+ node_offset_array_type_elem: i32,
+ /// The source location points to the operand of an unary expression.
+ /// The Decl is determined contextually.
+ node_offset_un_op: i32,
+ /// The source location points to the elem type of a pointer.
+ /// The Decl is determined contextually.
+ node_offset_ptr_elem: i32,
+ /// The source location points to the sentinel of a pointer.
+ /// The Decl is determined contextually.
+ node_offset_ptr_sentinel: i32,
+ /// The source location points to the align expr of a pointer.
+ /// The Decl is determined contextually.
+ node_offset_ptr_align: i32,
+ /// The source location points to the addrspace expr of a pointer.
+ /// The Decl is determined contextually.
+ node_offset_ptr_addrspace: i32,
+ /// The source location points to the bit-offset of a pointer.
+ /// The Decl is determined contextually.
+ node_offset_ptr_bitoffset: i32,
+ /// The source location points to the host size of a pointer.
+ /// The Decl is determined contextually.
+ node_offset_ptr_hostsize: i32,
+ /// The source location points to the tag type of an union or an enum.
+ /// The Decl is determined contextually.
+ node_offset_container_tag: i32,
+ /// The source location points to the default value of a field.
+ /// The Decl is determined contextually.
+ node_offset_field_default: i32,
+ /// The source location points to the type of an array or struct initializer.
+ /// The Decl is determined contextually.
+ node_offset_init_ty: i32,
+ /// The source location points to the LHS of an assignment.
+ /// The Decl is determined contextually.
+ node_offset_store_ptr: i32,
+ /// The source location points to the RHS of an assignment.
+ /// The Decl is determined contextually.
+ node_offset_store_operand: i32,
+ /// The source location points to the operand of a `return` statement, or
+ /// the `return` itself if there is no explicit operand.
+ /// The Decl is determined contextually.
+ node_offset_return_operand: i32,
+ /// The source location points to a for loop input.
+ /// The Decl is determined contextually.
+ for_input: struct {
+ /// Points to the for loop AST node.
+ for_node_offset: i32,
+ /// Picks one of the inputs from the condition.
+ input_index: u32,
+ },
+ /// The source location points to one of the captures of a for loop, found
+ /// by taking this AST node index offset from the containing
+ /// Decl AST node, which points to one of the input nodes of a for loop.
+ /// Next, navigate to the corresponding capture.
+ /// The Decl is determined contextually.
+ for_capture_from_input: i32,
+ /// The source location points to the argument node of a function call.
+ call_arg: struct {
+ decl: Decl.Index,
+ /// Points to the function call AST node.
+ call_node_offset: i32,
+ /// The index of the argument the source location points to.
+ arg_index: u32,
+ },
+ fn_proto_param: struct {
+ decl: Decl.Index,
+ /// Points to the function prototype AST node.
+ fn_proto_node_offset: i32,
+ /// The index of the parameter the source location points to.
+ param_index: u32,
+ },
+ array_cat_lhs: ArrayCat,
+ array_cat_rhs: ArrayCat,
+
+ const ArrayCat = struct {
+ /// Points to the array concat AST node.
+ array_cat_offset: i32,
+ /// The index of the element the source location points to.
+ elem_index: u32,
+ };
+
+ pub const nodeOffset = if (TracedOffset.want_tracing) nodeOffsetDebug else nodeOffsetRelease;
+
+ noinline fn nodeOffsetDebug(node_offset: i32) LazySrcLoc {
+ var result: LazySrcLoc = .{ .node_offset = .{ .x = node_offset } };
+ result.node_offset.trace.addAddr(@returnAddress(), "init");
+ return result;
+ }
+
+ fn nodeOffsetRelease(node_offset: i32) LazySrcLoc {
+ return .{ .node_offset = .{ .x = node_offset } };
+ }
+
+ /// This wraps a simple integer in debug builds so that later on we can find out
+ /// where in semantic analysis the value got set.
+ pub const TracedOffset = struct {
+ x: i32,
+ trace: std.debug.Trace = std.debug.Trace.init,
+
+ const want_tracing = false;
+ };
+};
+
pub const SemaError = error{ OutOfMemory, AnalysisFail };
pub const CompileError = error{
OutOfMemory,