mirror of
https://github.com/ziglang/zig.git
synced 2026-01-26 09:15:24 +00:00
stage1: rework tokenizer to match stage2
* Extracts AstGen logic from ir.cpp into astgen.cpp. Reduces the
largest file of stage1 from 33,551 lines to 25,510.
* tokenizer: rework it completely to match the stage2 tokenizer logic.
They can now be maintained together; when one is changed, the other
can be changed in the same way.
- Each token now takes up 13 bytes instead of 64 bytes. The tokenizer
does not parse char literals, string literals, integer literals,
etc into meaningful data. Instead, that happens during parsing or
astgen.
- no longer store line offsets. Error messages scan source
files to find the line/column as needed (same as stage2).
- main loop: instead of checking the loop, handle a null byte
explicitly in the switch statements. This is a nice improvement
that we may want to backport to stage2.
- delete some dead tokens, artifacts of past syntax that no longer
exists.
* Parser: fix a TODO by parsing builtin functions as tokens rather than
`@` as a separate token. This is how stage2 does it.
* Remove some debugging infrastructure. These will need to be redone,
if at all, as the code migrates to match stage2.
- remove the ast_render code.
- remove the IR debugging stuff
- remove teh token printing code
This commit is contained in:
parent
673ae5b457
commit
2a990d6966
@ -292,7 +292,7 @@ set(ZIG0_SOURCES
|
||||
|
||||
set(STAGE1_SOURCES
|
||||
"${CMAKE_SOURCE_DIR}/src/stage1/analyze.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/stage1/ast_render.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/stage1/astgen.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/stage1/bigfloat.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/stage1/bigint.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/stage1/buffer.cpp"
|
||||
@ -307,11 +307,11 @@ set(STAGE1_SOURCES
|
||||
"${CMAKE_SOURCE_DIR}/src/stage1/os.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/stage1/parser.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/stage1/range_set.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/stage1/softfloat_ext.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/stage1/stage1.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/stage1/target.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/stage1/tokenizer.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/stage1/util.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/stage1/softfloat_ext.cpp"
|
||||
)
|
||||
set(OPTIMIZED_C_SOURCES
|
||||
"${CMAKE_SOURCE_DIR}/src/stage1/parse_f128.c"
|
||||
|
||||
@ -107,6 +107,7 @@ pub fn parseAppend(buf: *std.ArrayList(u8), bytes: []const u8) error{OutOfMemory
|
||||
const hex_str = slice[index + 2 .. index_end];
|
||||
if (std.fmt.parseUnsigned(u32, hex_str, 16)) |uint| {
|
||||
if (uint <= 0x10ffff) {
|
||||
// TODO this incorrectly depends on endianness
|
||||
try buf.appendSlice(std.mem.toBytes(uint)[0..]);
|
||||
state = State.Start;
|
||||
index = index_end; // loop-header increments
|
||||
|
||||
@ -252,6 +252,8 @@ const Error = extern enum {
|
||||
ZigIsTheCCompiler,
|
||||
FileBusy,
|
||||
Locked,
|
||||
InvalidCharacter,
|
||||
UnicodePointTooLarge,
|
||||
};
|
||||
|
||||
// ABI warning
|
||||
|
||||
@ -670,7 +670,7 @@ enum NodeType {
|
||||
NodeTypeIntLiteral,
|
||||
NodeTypeStringLiteral,
|
||||
NodeTypeCharLiteral,
|
||||
NodeTypeSymbol,
|
||||
NodeTypeIdentifier,
|
||||
NodeTypePrefixOpExpr,
|
||||
NodeTypePointerType,
|
||||
NodeTypeFnCallExpr,
|
||||
@ -710,6 +710,7 @@ enum NodeType {
|
||||
NodeTypeAwaitExpr,
|
||||
NodeTypeSuspend,
|
||||
NodeTypeAnyFrameType,
|
||||
// main_token points to the identifier.
|
||||
NodeTypeEnumLiteral,
|
||||
NodeTypeAnyTypeField,
|
||||
};
|
||||
@ -733,7 +734,8 @@ struct AstNodeFnProto {
|
||||
AstNode *section_expr;
|
||||
// populated if the "callconv(S)" is present
|
||||
AstNode *callconv_expr;
|
||||
Buf doc_comments;
|
||||
|
||||
TokenIndex doc_comments;
|
||||
|
||||
// This is set based only on the existence of a noinline or inline keyword.
|
||||
// This is then resolved to an is_noinline bool and (potentially .Inline)
|
||||
@ -755,8 +757,8 @@ struct AstNodeFnDef {
|
||||
struct AstNodeParamDecl {
|
||||
Buf *name;
|
||||
AstNode *type;
|
||||
Token *anytype_token;
|
||||
Buf doc_comments;
|
||||
TokenIndex doc_comments;
|
||||
TokenIndex anytype_token;
|
||||
bool is_noalias;
|
||||
bool is_comptime;
|
||||
bool is_var_args;
|
||||
@ -799,9 +801,9 @@ struct AstNodeVariableDeclaration {
|
||||
AstNode *align_expr;
|
||||
// populated if the "section(S)" is present
|
||||
AstNode *section_expr;
|
||||
Token *threadlocal_tok;
|
||||
Buf doc_comments;
|
||||
TokenIndex doc_comments;
|
||||
|
||||
TokenIndex threadlocal_tok;
|
||||
VisibMod visib_mod;
|
||||
bool is_const;
|
||||
bool is_comptime;
|
||||
@ -935,13 +937,14 @@ struct AstNodePrefixOpExpr {
|
||||
};
|
||||
|
||||
struct AstNodePointerType {
|
||||
Token *star_token;
|
||||
TokenIndex star_token;
|
||||
TokenIndex allow_zero_token;
|
||||
TokenIndex bit_offset_start;
|
||||
TokenIndex host_int_bytes;
|
||||
|
||||
AstNode *sentinel;
|
||||
AstNode *align_expr;
|
||||
BigInt *bit_offset_start;
|
||||
BigInt *host_int_bytes;
|
||||
AstNode *op_expr;
|
||||
Token *allow_zero_token;
|
||||
bool is_const;
|
||||
bool is_volatile;
|
||||
};
|
||||
@ -956,7 +959,7 @@ struct AstNodeArrayType {
|
||||
AstNode *sentinel;
|
||||
AstNode *child_type;
|
||||
AstNode *align_expr;
|
||||
Token *allow_zero_token;
|
||||
TokenIndex allow_zero_token;
|
||||
bool is_const;
|
||||
bool is_volatile;
|
||||
};
|
||||
@ -974,11 +977,11 @@ struct AstNodeIfBoolExpr {
|
||||
|
||||
struct AstNodeTryExpr {
|
||||
Buf *var_symbol;
|
||||
bool var_is_ptr;
|
||||
AstNode *target_node;
|
||||
AstNode *then_node;
|
||||
AstNode *else_node;
|
||||
Buf *err_symbol;
|
||||
bool var_is_ptr;
|
||||
};
|
||||
|
||||
struct AstNodeTestExpr {
|
||||
@ -993,12 +996,12 @@ struct AstNodeWhileExpr {
|
||||
Buf *name;
|
||||
AstNode *condition;
|
||||
Buf *var_symbol;
|
||||
bool var_is_ptr;
|
||||
AstNode *continue_expr;
|
||||
AstNode *body;
|
||||
AstNode *else_node;
|
||||
Buf *err_symbol;
|
||||
bool is_inline;
|
||||
bool var_is_ptr;
|
||||
};
|
||||
|
||||
struct AstNodeForExpr {
|
||||
@ -1070,7 +1073,7 @@ struct AsmToken {
|
||||
};
|
||||
|
||||
struct AstNodeAsmExpr {
|
||||
Token *volatile_token;
|
||||
TokenIndex volatile_token;
|
||||
AstNode *asm_template;
|
||||
ZigList<AsmOutput*> output_list;
|
||||
ZigList<AsmInput*> input_list;
|
||||
@ -1094,7 +1097,7 @@ struct AstNodeContainerDecl {
|
||||
AstNode *init_arg_expr; // enum(T), struct(endianness), or union(T), or union(enum(T))
|
||||
ZigList<AstNode *> fields;
|
||||
ZigList<AstNode *> decls;
|
||||
Buf doc_comments;
|
||||
TokenIndex doc_comments;
|
||||
|
||||
ContainerKind kind;
|
||||
ContainerLayout layout;
|
||||
@ -1103,7 +1106,7 @@ struct AstNodeContainerDecl {
|
||||
};
|
||||
|
||||
struct AstNodeErrorSetField {
|
||||
Buf doc_comments;
|
||||
TokenIndex doc_comments;
|
||||
AstNode *field_name;
|
||||
};
|
||||
|
||||
@ -1118,28 +1121,8 @@ struct AstNodeStructField {
|
||||
AstNode *value;
|
||||
// populated if the "align(A)" is present
|
||||
AstNode *align_expr;
|
||||
Buf doc_comments;
|
||||
Token *comptime_token;
|
||||
};
|
||||
|
||||
struct AstNodeStringLiteral {
|
||||
Buf *buf;
|
||||
};
|
||||
|
||||
struct AstNodeCharLiteral {
|
||||
uint32_t value;
|
||||
};
|
||||
|
||||
struct AstNodeFloatLiteral {
|
||||
BigFloat *bigfloat;
|
||||
|
||||
// overflow is true if when parsing the number, we discovered it would not
|
||||
// fit without losing data in a double
|
||||
bool overflow;
|
||||
};
|
||||
|
||||
struct AstNodeIntLiteral {
|
||||
BigInt *bigint;
|
||||
TokenIndex doc_comments;
|
||||
TokenIndex comptime_token;
|
||||
};
|
||||
|
||||
struct AstNodeStructValueField {
|
||||
@ -1158,19 +1141,6 @@ struct AstNodeContainerInitExpr {
|
||||
ContainerInitKind kind;
|
||||
};
|
||||
|
||||
struct AstNodeNullLiteral {
|
||||
};
|
||||
|
||||
struct AstNodeUndefinedLiteral {
|
||||
};
|
||||
|
||||
struct AstNodeThisLiteral {
|
||||
};
|
||||
|
||||
struct AstNodeSymbolExpr {
|
||||
Buf *symbol;
|
||||
};
|
||||
|
||||
struct AstNodeBoolLiteral {
|
||||
bool value;
|
||||
};
|
||||
@ -1188,13 +1158,6 @@ struct AstNodeContinueExpr {
|
||||
Buf *name;
|
||||
};
|
||||
|
||||
struct AstNodeUnreachableExpr {
|
||||
};
|
||||
|
||||
|
||||
struct AstNodeErrorType {
|
||||
};
|
||||
|
||||
struct AstNodeAwaitExpr {
|
||||
AstNode *expr;
|
||||
};
|
||||
@ -1207,16 +1170,10 @@ struct AstNodeAnyFrameType {
|
||||
AstNode *payload_type; // can be NULL
|
||||
};
|
||||
|
||||
struct AstNodeEnumLiteral {
|
||||
Token *period;
|
||||
Token *identifier;
|
||||
};
|
||||
|
||||
struct AstNode {
|
||||
enum NodeType type;
|
||||
TokenIndex main_token;
|
||||
bool already_traced_this_node;
|
||||
size_t line;
|
||||
size_t column;
|
||||
ZigType *owner;
|
||||
union {
|
||||
AstNodeFnDef fn_def;
|
||||
@ -1252,30 +1209,19 @@ struct AstNode {
|
||||
AstNodePtrDerefExpr ptr_deref_expr;
|
||||
AstNodeContainerDecl container_decl;
|
||||
AstNodeStructField struct_field;
|
||||
AstNodeStringLiteral string_literal;
|
||||
AstNodeCharLiteral char_literal;
|
||||
AstNodeFloatLiteral float_literal;
|
||||
AstNodeIntLiteral int_literal;
|
||||
AstNodeContainerInitExpr container_init_expr;
|
||||
AstNodeStructValueField struct_val_field;
|
||||
AstNodeNullLiteral null_literal;
|
||||
AstNodeUndefinedLiteral undefined_literal;
|
||||
AstNodeThisLiteral this_literal;
|
||||
AstNodeSymbolExpr symbol_expr;
|
||||
AstNodeBoolLiteral bool_literal;
|
||||
AstNodeBreakExpr break_expr;
|
||||
AstNodeContinueExpr continue_expr;
|
||||
AstNodeUnreachableExpr unreachable_expr;
|
||||
AstNodeArrayType array_type;
|
||||
AstNodeInferredArrayType inferred_array_type;
|
||||
AstNodeErrorType error_type;
|
||||
AstNodeErrorSetDecl err_set_decl;
|
||||
AstNodeErrorSetField err_set_field;
|
||||
AstNodeResumeExpr resume_expr;
|
||||
AstNodeAwaitExpr await_expr;
|
||||
AstNodeSuspend suspend;
|
||||
AstNodeAnyFrameType anyframe_type;
|
||||
AstNodeEnumLiteral enum_literal;
|
||||
} data;
|
||||
|
||||
// This is a function for use in the debugger to print
|
||||
@ -1409,9 +1355,11 @@ struct ZigPackage {
|
||||
struct RootStruct {
|
||||
ZigPackage *package;
|
||||
Buf *path; // relative to root_package->root_src_dir
|
||||
ZigList<size_t> *line_offsets;
|
||||
Buf *source_code;
|
||||
ZigLLVMDIFile *di_file;
|
||||
size_t token_count;
|
||||
TokenId *token_ids;
|
||||
TokenLoc *token_locs;
|
||||
};
|
||||
|
||||
enum StructSpecial {
|
||||
|
||||
@ -6,9 +6,9 @@
|
||||
*/
|
||||
|
||||
#include "analyze.hpp"
|
||||
#include "ast_render.hpp"
|
||||
#include "codegen.hpp"
|
||||
#include "error.hpp"
|
||||
#include "astgen.hpp"
|
||||
#include "ir.hpp"
|
||||
#include "ir_print.hpp"
|
||||
#include "os.hpp"
|
||||
@ -41,41 +41,44 @@ static bool is_top_level_struct(ZigType *import) {
|
||||
return import->id == ZigTypeIdStruct && import->data.structure.root_struct != nullptr;
|
||||
}
|
||||
|
||||
static ErrorMsg *add_error_note_token(CodeGen *g, ErrorMsg *parent_msg, ZigType *owner, Token *token, Buf *msg) {
|
||||
static ErrorMsg *add_error_note_token(CodeGen *g, ErrorMsg *parent_msg, ZigType *owner,
|
||||
TokenIndex token, Buf *msg)
|
||||
{
|
||||
assert(is_top_level_struct(owner));
|
||||
RootStruct *root_struct = owner->data.structure.root_struct;
|
||||
|
||||
ErrorMsg *err = err_msg_create_with_line(root_struct->path, token->start_line, token->start_column,
|
||||
root_struct->source_code, root_struct->line_offsets, msg);
|
||||
uint32_t byte_offset = root_struct->token_locs[token].offset;
|
||||
ErrorMsg *err = err_msg_create_with_offset(root_struct->path, byte_offset,
|
||||
buf_ptr(root_struct->source_code), msg);
|
||||
|
||||
err_msg_add_note(parent_msg, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
ErrorMsg *add_token_error(CodeGen *g, ZigType *owner, Token *token, Buf *msg) {
|
||||
ErrorMsg *add_token_error_offset(CodeGen *g, ZigType *owner, TokenIndex token, Buf *msg,
|
||||
uint32_t bad_index)
|
||||
{
|
||||
assert(is_top_level_struct(owner));
|
||||
RootStruct *root_struct = owner->data.structure.root_struct;
|
||||
ErrorMsg *err = err_msg_create_with_line(root_struct->path, token->start_line, token->start_column,
|
||||
root_struct->source_code, root_struct->line_offsets, msg);
|
||||
uint32_t byte_offset = root_struct->token_locs[token].offset + bad_index;
|
||||
ErrorMsg *err = err_msg_create_with_offset(root_struct->path, byte_offset,
|
||||
buf_ptr(root_struct->source_code), msg);
|
||||
|
||||
g->errors.append(err);
|
||||
g->trace_err = err;
|
||||
return err;
|
||||
}
|
||||
|
||||
ErrorMsg *add_token_error(CodeGen *g, ZigType *owner, TokenIndex token, Buf *msg) {
|
||||
return add_token_error_offset(g, owner, token, msg, 0);
|
||||
}
|
||||
|
||||
ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) {
|
||||
Token fake_token;
|
||||
fake_token.start_line = node->line;
|
||||
fake_token.start_column = node->column;
|
||||
node->already_traced_this_node = true;
|
||||
return add_token_error(g, node->owner, &fake_token, msg);
|
||||
return add_token_error(g, node->owner, node->main_token, msg);
|
||||
}
|
||||
|
||||
ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, const AstNode *node, Buf *msg) {
|
||||
Token fake_token;
|
||||
fake_token.start_line = node->line;
|
||||
fake_token.start_column = node->column;
|
||||
return add_error_note_token(g, parent_msg, node->owner, &fake_token, msg);
|
||||
return add_error_note_token(g, parent_msg, node->owner, node->main_token, msg);
|
||||
}
|
||||
|
||||
ZigType *new_type_table_entry(ZigTypeId id) {
|
||||
@ -913,13 +916,27 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) {
|
||||
return entry;
|
||||
}
|
||||
|
||||
ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *full_name, Buf *bare_name) {
|
||||
static uint32_t node_line_onebased(AstNode *node) {
|
||||
RootStruct *root_struct = node->owner->data.structure.root_struct;
|
||||
assert(node->main_token < root_struct->token_count);
|
||||
return root_struct->token_locs[node->main_token].line + 1;
|
||||
}
|
||||
|
||||
static uint32_t node_column_onebased(AstNode *node) {
|
||||
RootStruct *root_struct = node->owner->data.structure.root_struct;
|
||||
assert(node->main_token < root_struct->token_count);
|
||||
return root_struct->token_locs[node->main_token].column + 1;
|
||||
}
|
||||
|
||||
ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *full_name,
|
||||
Buf *bare_name)
|
||||
{
|
||||
ZigType *entry = new_type_table_entry(ZigTypeIdOpaque);
|
||||
|
||||
buf_init_from_str(&entry->name, full_name);
|
||||
|
||||
ZigType *import = scope ? get_scope_import(scope) : nullptr;
|
||||
unsigned line = source_node ? (unsigned)(source_node->line + 1) : 0;
|
||||
unsigned line = source_node ? node_line_onebased(source_node) : 0;
|
||||
|
||||
// Note: duplicated in get_partial_container_type
|
||||
entry->llvm_type = LLVMInt8Type();
|
||||
@ -1142,7 +1159,7 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind
|
||||
break;
|
||||
case ContainerKindOpaque: {
|
||||
ZigType *import = scope ? get_scope_import(scope) : nullptr;
|
||||
unsigned line = decl_node ? (unsigned)(decl_node->line + 1) : 0;
|
||||
unsigned line = decl_node ? node_line_onebased(decl_node) : 0;
|
||||
// Note: duplicated in get_opaque_type
|
||||
entry->llvm_type = LLVMInt8Type();
|
||||
entry->llvm_di_type = ZigLLVMCreateDebugForwardDeclType(g->dbuilder,
|
||||
@ -1584,8 +1601,9 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, ZigV
|
||||
ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) {
|
||||
Error err;
|
||||
// Hot path for simple identifiers, to avoid unnecessary memory allocations.
|
||||
if (node->type == NodeTypeSymbol) {
|
||||
Buf *variable_name = node->data.symbol_expr.symbol;
|
||||
if (node->type == NodeTypeIdentifier) {
|
||||
RootStruct *root_struct = node->owner->data.structure.root_struct;
|
||||
Buf *variable_name = token_identifier_buf(root_struct, node->main_token);
|
||||
if (buf_eql_str(variable_name, "_"))
|
||||
goto abort_hot_path;
|
||||
ZigType *primitive_type;
|
||||
@ -2034,7 +2052,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
|
||||
buf_sprintf("var args only allowed in functions with C calling convention"));
|
||||
return g->builtin_types.entry_invalid;
|
||||
}
|
||||
} else if (param_node->data.param_decl.anytype_token != nullptr) {
|
||||
} else if (param_node->data.param_decl.anytype_token != 0) {
|
||||
if (!calling_convention_allows_zig_types(fn_type_id.cc)) {
|
||||
add_node_error(g, param_node,
|
||||
buf_sprintf("parameter of type 'anytype' not allowed in function with calling convention '%s'",
|
||||
@ -3021,7 +3039,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
|
||||
field_node = decl_node->data.container_decl.fields.at(i);
|
||||
type_struct_field->name = field_node->data.struct_field.name;
|
||||
type_struct_field->decl_node = field_node;
|
||||
if (field_node->data.struct_field.comptime_token != nullptr) {
|
||||
if (field_node->data.struct_field.comptime_token != 0) {
|
||||
if (field_node->data.struct_field.value == nullptr) {
|
||||
add_token_error(g, field_node->owner,
|
||||
field_node->data.struct_field.comptime_token,
|
||||
@ -4042,7 +4060,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
|
||||
case NodeTypeBoolLiteral:
|
||||
case NodeTypeNullLiteral:
|
||||
case NodeTypeUndefinedLiteral:
|
||||
case NodeTypeSymbol:
|
||||
case NodeTypeIdentifier:
|
||||
case NodeTypePrefixOpExpr:
|
||||
case NodeTypePointerType:
|
||||
case NodeTypeIfBoolExpr:
|
||||
@ -4238,7 +4256,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) {
|
||||
bool is_const = var_decl->is_const;
|
||||
bool is_extern = var_decl->is_extern;
|
||||
bool is_export = var_decl->is_export;
|
||||
bool is_thread_local = var_decl->threadlocal_tok != nullptr;
|
||||
bool is_thread_local = var_decl->threadlocal_tok != 0;
|
||||
|
||||
ZigType *explicit_type = nullptr;
|
||||
if (var_decl->type) {
|
||||
@ -5225,8 +5243,6 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {
|
||||
}
|
||||
|
||||
if (g->verbose_ir) {
|
||||
fprintf(stderr, "\n");
|
||||
ast_render(stderr, fn_table_entry->body_node, 4);
|
||||
fprintf(stderr, "\nfn %s() { // (IR)\n", buf_ptr(&fn_table_entry->symbol_name));
|
||||
ir_print_src(g, stderr, fn_table_entry->ir_executable, 4);
|
||||
fprintf(stderr, "}\n");
|
||||
@ -5238,33 +5254,17 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {
|
||||
ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Buf *source_code,
|
||||
SourceKind source_kind)
|
||||
{
|
||||
if (g->verbose_tokenize) {
|
||||
fprintf(stderr, "\nOriginal Source (%s):\n", buf_ptr(resolved_path));
|
||||
fprintf(stderr, "----------------\n");
|
||||
fprintf(stderr, "%s\n", buf_ptr(source_code));
|
||||
|
||||
fprintf(stderr, "\nTokens:\n");
|
||||
fprintf(stderr, "---------\n");
|
||||
}
|
||||
|
||||
Tokenization tokenization = {0};
|
||||
tokenize(source_code, &tokenization);
|
||||
tokenize(buf_ptr(source_code), &tokenization);
|
||||
|
||||
if (tokenization.err) {
|
||||
ErrorMsg *err = err_msg_create_with_line(resolved_path, tokenization.err_line, tokenization.err_column,
|
||||
source_code, tokenization.line_offsets, tokenization.err);
|
||||
ErrorMsg *err = err_msg_create_with_offset(resolved_path, tokenization.err_byte_offset,
|
||||
buf_ptr(source_code), tokenization.err);
|
||||
|
||||
print_err_msg(err, g->err_color);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (g->verbose_tokenize) {
|
||||
print_tokens(source_code, tokenization.tokens);
|
||||
|
||||
fprintf(stderr, "\nAST:\n");
|
||||
fprintf(stderr, "------\n");
|
||||
}
|
||||
|
||||
Buf *src_dirname = buf_alloc();
|
||||
Buf *src_basename = buf_alloc();
|
||||
os_path_split(resolved_path, src_dirname, src_basename);
|
||||
@ -5297,9 +5297,20 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu
|
||||
RootStruct *root_struct = heap::c_allocator.create<RootStruct>();
|
||||
root_struct->package = package;
|
||||
root_struct->source_code = source_code;
|
||||
root_struct->line_offsets = tokenization.line_offsets;
|
||||
root_struct->path = resolved_path;
|
||||
root_struct->di_file = ZigLLVMCreateFile(g->dbuilder, buf_ptr(src_basename), buf_ptr(src_dirname));
|
||||
|
||||
assert(tokenization.ids.length == tokenization.locs.length);
|
||||
size_t token_count = tokenization.ids.length;
|
||||
root_struct->token_count = token_count;
|
||||
root_struct->token_ids = g->pass1_arena->allocate<TokenId>(token_count);
|
||||
memcpy(root_struct->token_ids, tokenization.ids.items, token_count * sizeof(TokenId));
|
||||
root_struct->token_locs = g->pass1_arena->allocate<TokenLoc>(token_count);
|
||||
memcpy(root_struct->token_locs, tokenization.locs.items, token_count * sizeof(TokenLoc));
|
||||
|
||||
tokenization.ids.deinit();
|
||||
tokenization.locs.deinit();
|
||||
|
||||
ZigType *import_entry = get_root_container_type(g, buf_ptr(namespace_name), bare_name, root_struct);
|
||||
if (source_kind == SourceKindRoot) {
|
||||
assert(g->root_import == nullptr);
|
||||
@ -5307,14 +5318,11 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu
|
||||
}
|
||||
g->import_table.put(resolved_path, import_entry);
|
||||
|
||||
AstNode *root_node = ast_parse(source_code, tokenization.tokens, import_entry, g->err_color);
|
||||
AstNode *root_node = ast_parse(source_code, import_entry, g->err_color);
|
||||
assert(root_node != nullptr);
|
||||
assert(root_node->type == NodeTypeContainerDecl);
|
||||
import_entry->data.structure.decl_node = root_node;
|
||||
import_entry->data.structure.decls_scope->base.source_node = root_node;
|
||||
if (g->verbose_ast) {
|
||||
ast_print(stderr, root_node, 0);
|
||||
}
|
||||
|
||||
for (size_t decl_i = 0; decl_i < root_node->data.container_decl.decls.length; decl_i += 1) {
|
||||
AstNode *top_level_decl = root_node->data.container_decl.decls.at(decl_i);
|
||||
@ -6254,9 +6262,12 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *ty) {
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
void init_const_str_lit(CodeGen *g, ZigValue *const_val, Buf *str) {
|
||||
void init_const_str_lit(CodeGen *g, ZigValue *const_val, Buf *str, bool move_str) {
|
||||
auto entry = g->string_literals_table.maybe_get(str);
|
||||
if (entry != nullptr) {
|
||||
if (move_str) {
|
||||
buf_destroy(str);
|
||||
}
|
||||
memcpy(const_val, entry->value, sizeof(ZigValue));
|
||||
return;
|
||||
}
|
||||
@ -6280,7 +6291,7 @@ void init_const_str_lit(CodeGen *g, ZigValue *const_val, Buf *str) {
|
||||
|
||||
ZigValue *create_const_str_lit(CodeGen *g, Buf *str) {
|
||||
ZigValue *const_val = g->pass1_arena->create<ZigValue>();
|
||||
init_const_str_lit(g, const_val, str);
|
||||
init_const_str_lit(g, const_val, str, false);
|
||||
return const_val;
|
||||
}
|
||||
|
||||
@ -8626,7 +8637,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
|
||||
ZigType *import = get_scope_import(scope);
|
||||
di_file = import->data.structure.root_struct->di_file;
|
||||
di_scope = ZigLLVMFileToScope(di_file);
|
||||
line = decl_node->line + 1;
|
||||
line = node_line_onebased(decl_node);
|
||||
} else {
|
||||
di_file = nullptr;
|
||||
di_scope = ZigLLVMCompileUnitToScope(g->compile_unit);
|
||||
@ -8830,7 +8841,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
|
||||
unsigned line;
|
||||
if (decl_node != nullptr) {
|
||||
AstNode *field_node = field->decl_node;
|
||||
line = field_node->line + 1;
|
||||
line = node_line_onebased(field_node);
|
||||
} else {
|
||||
line = 0;
|
||||
}
|
||||
@ -8881,7 +8892,7 @@ static ZigLLVMDIType *make_empty_namespace_llvm_di_type(CodeGen *g, ZigType *imp
|
||||
return ZigLLVMCreateDebugStructType(g->dbuilder,
|
||||
ZigLLVMFileToScope(import->data.structure.root_struct->di_file),
|
||||
name,
|
||||
import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
|
||||
import->data.structure.root_struct->di_file, node_line_onebased(decl_node),
|
||||
debug_size_in_bits,
|
||||
debug_align_in_bits,
|
||||
ZigLLVM_DIFlags_Zero,
|
||||
@ -8926,7 +8937,7 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type, ResolveStatu
|
||||
uint64_t tag_debug_align_in_bits = 8*tag_int_type->abi_align;
|
||||
ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,
|
||||
ZigLLVMFileToScope(import->data.structure.root_struct->di_file), buf_ptr(&enum_type->name),
|
||||
import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
|
||||
import->data.structure.root_struct->di_file, node_line_onebased(decl_node),
|
||||
tag_debug_size_in_bits,
|
||||
tag_debug_align_in_bits,
|
||||
di_enumerators, field_count,
|
||||
@ -8966,12 +8977,12 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
|
||||
|
||||
if (union_type->data.unionation.resolve_status < ResolveStatusLLVMFwdDecl) {
|
||||
union_type->llvm_type = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&union_type->name));
|
||||
size_t line = decl_node ? decl_node->line : 0;
|
||||
unsigned line = decl_node ? node_line_onebased(decl_node) : 0;
|
||||
unsigned dwarf_kind = ZigLLVMTag_DW_structure_type();
|
||||
union_type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
|
||||
dwarf_kind, buf_ptr(&union_type->name),
|
||||
ZigLLVMFileToScope(import->data.structure.root_struct->di_file),
|
||||
import->data.structure.root_struct->di_file, (unsigned)(line + 1));
|
||||
import->data.structure.root_struct->di_file, line);
|
||||
|
||||
union_type->data.unionation.resolve_status = ResolveStatusLLVMFwdDecl;
|
||||
if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) return;
|
||||
@ -8992,7 +9003,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
|
||||
AstNode *field_node = union_field->decl_node;
|
||||
union_inner_di_types[union_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
|
||||
ZigLLVMTypeToScope(union_type->llvm_di_type), buf_ptr(union_field->enum_field->name),
|
||||
import->data.structure.root_struct->di_file, (unsigned)(field_node->line + 1),
|
||||
import->data.structure.root_struct->di_file, node_line_onebased(field_node),
|
||||
store_size_in_bits,
|
||||
abi_align_in_bits,
|
||||
0,
|
||||
@ -9022,7 +9033,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
|
||||
// create debug type for union
|
||||
ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder,
|
||||
ZigLLVMFileToScope(import->data.structure.root_struct->di_file), buf_ptr(&union_type->name),
|
||||
import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
|
||||
import->data.structure.root_struct->di_file, node_line_onebased(decl_node),
|
||||
union_type->data.unionation.union_abi_size * 8,
|
||||
most_aligned_union_member->align * 8,
|
||||
ZigLLVM_DIFlags_Zero, union_inner_di_types,
|
||||
@ -9057,7 +9068,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
|
||||
// create debug type for union
|
||||
ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder,
|
||||
ZigLLVMTypeToScope(union_type->llvm_di_type), "AnonUnion",
|
||||
import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
|
||||
import->data.structure.root_struct->di_file, node_line_onebased(decl_node),
|
||||
most_aligned_union_member->type_entry->size_in_bits, 8*most_aligned_union_member->align,
|
||||
ZigLLVM_DIFlags_Zero, union_inner_di_types, gen_field_count, 0, "");
|
||||
|
||||
@ -9068,7 +9079,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
|
||||
|
||||
ZigLLVMDIType *union_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder,
|
||||
ZigLLVMTypeToScope(union_type->llvm_di_type), "payload",
|
||||
import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
|
||||
import->data.structure.root_struct->di_file, node_line_onebased(decl_node),
|
||||
most_aligned_union_member->type_entry->size_in_bits,
|
||||
8*most_aligned_union_member->align,
|
||||
union_offset_in_bits,
|
||||
@ -9079,7 +9090,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
|
||||
|
||||
ZigLLVMDIType *tag_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder,
|
||||
ZigLLVMTypeToScope(union_type->llvm_di_type), "tag",
|
||||
import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
|
||||
import->data.structure.root_struct->di_file, node_line_onebased(decl_node),
|
||||
tag_debug_size_in_bits,
|
||||
tag_debug_align_in_bits,
|
||||
tag_offset_in_bits,
|
||||
@ -9094,7 +9105,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
|
||||
ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
|
||||
ZigLLVMFileToScope(import->data.structure.root_struct->di_file),
|
||||
buf_ptr(&union_type->name),
|
||||
import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
|
||||
import->data.structure.root_struct->di_file, node_line_onebased(decl_node),
|
||||
debug_size_in_bits,
|
||||
debug_align_in_bits,
|
||||
ZigLLVM_DIFlags_Zero, nullptr, di_root_members, 2, 0, nullptr, "");
|
||||
@ -9774,9 +9785,9 @@ void src_assert_impl(bool ok, AstNode *source_node, char const *file, unsigned i
|
||||
if (source_node == nullptr) {
|
||||
fprintf(stderr, "when analyzing (unknown source location) ");
|
||||
} else {
|
||||
fprintf(stderr, "when analyzing %s:%u:%u ",
|
||||
buf_ptr(source_node->owner->data.structure.root_struct->path),
|
||||
(unsigned)source_node->line + 1, (unsigned)source_node->column + 1);
|
||||
RootStruct *root_struct = source_node->owner->data.structure.root_struct;
|
||||
fprintf(stderr, "when analyzing %s:%u:%u ", buf_ptr(root_struct->path),
|
||||
node_line_onebased(source_node), node_column_onebased(source_node));
|
||||
}
|
||||
fprintf(stderr, "in compiler source at %s:%u: ", file, line);
|
||||
const char *msg = "assertion failed. This is a bug in the Zig compiler.";
|
||||
@ -9842,6 +9853,14 @@ Error analyze_import(CodeGen *g, ZigType *source_import, Buf *import_target_str,
|
||||
return ErrorNone;
|
||||
}
|
||||
|
||||
void AstNode::src() {
|
||||
RootStruct *root_struct = this->owner->data.structure.root_struct;
|
||||
uint32_t line = root_struct->token_locs[this->main_token].line + 1;
|
||||
uint32_t column = root_struct->token_locs[this->main_token].column + 1;
|
||||
fprintf(stderr, "%s:%" PRIu32 ":%" PRIu32 "\n",
|
||||
buf_ptr(root_struct->path),
|
||||
line, column);
|
||||
}
|
||||
|
||||
void IrExecutableSrc::src() {
|
||||
if (this->source_node != nullptr) {
|
||||
|
||||
@ -12,7 +12,9 @@
|
||||
|
||||
void semantic_analyze(CodeGen *g);
|
||||
ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg);
|
||||
ErrorMsg *add_token_error(CodeGen *g, ZigType *owner, Token *token, Buf *msg);
|
||||
ErrorMsg *add_token_error(CodeGen *g, ZigType *owner, TokenIndex token, Buf *msg);
|
||||
ErrorMsg *add_token_error_offset(CodeGen *g, ZigType *owner, TokenIndex token, Buf *msg,
|
||||
uint32_t bad_index);
|
||||
ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, const AstNode *node, Buf *msg);
|
||||
ZigType *new_type_table_entry(ZigTypeId id);
|
||||
ZigType *get_fn_frame_type(CodeGen *g, ZigFn *fn);
|
||||
@ -140,7 +142,7 @@ Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstSrc
|
||||
Scope *create_typeof_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||
ScopeExpr *create_expr_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||
|
||||
void init_const_str_lit(CodeGen *g, ZigValue *const_val, Buf *str);
|
||||
void init_const_str_lit(CodeGen *g, ZigValue *const_val, Buf *str, bool move_str);
|
||||
ZigValue *create_const_str_lit(CodeGen *g, Buf *str);
|
||||
|
||||
void init_const_bigint(ZigValue *const_val, ZigType *type, const BigInt *bigint);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Andrew Kelley
|
||||
*
|
||||
* This file is part of zig, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#ifndef ZIG_AST_RENDER_HPP
|
||||
#define ZIG_AST_RENDER_HPP
|
||||
|
||||
#include "all_types.hpp"
|
||||
#include "parser.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void ast_print(FILE *f, AstNode *node, int indent);
|
||||
|
||||
void ast_render(FILE *f, AstNode *node, int indent_size);
|
||||
|
||||
#endif
|
||||
8120
src/stage1/astgen.cpp
Normal file
8120
src/stage1/astgen.cpp
Normal file
File diff suppressed because it is too large
Load Diff
43
src/stage1/astgen.hpp
Normal file
43
src/stage1/astgen.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Andrew Kelley
|
||||
*
|
||||
* This file is part of zig, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#ifndef ZIG_ASTGEN_HPP
|
||||
#define ZIG_ASTGEN_HPP
|
||||
|
||||
#include "all_types.hpp"
|
||||
|
||||
bool ir_gen(CodeGen *g, AstNode *node, Scope *scope, IrExecutableSrc *ir_executable);
|
||||
bool ir_gen_fn(CodeGen *g, ZigFn *fn_entry);
|
||||
|
||||
bool ir_inst_src_has_side_effects(IrInstSrc *inst);
|
||||
|
||||
ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope,
|
||||
Buf *name, bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstSrc *is_comptime,
|
||||
bool skip_name_check);
|
||||
|
||||
ResultLoc *no_result_loc(void);
|
||||
|
||||
void invalidate_exec(IrExecutableSrc *exec, ErrorMsg *msg);
|
||||
|
||||
AstNode *ast_field_to_symbol_node(AstNode *err_set_field_node);
|
||||
void ir_add_call_stack_errors_gen(CodeGen *codegen, IrExecutableGen *exec, ErrorMsg *err_msg,
|
||||
int limit);
|
||||
|
||||
void destroy_instruction_src(IrInstSrc *inst);
|
||||
|
||||
struct IrBuilderSrc {
|
||||
CodeGen *codegen;
|
||||
IrExecutableSrc *exec;
|
||||
IrBasicBlockSrc *current_basic_block;
|
||||
AstNode *main_block_node;
|
||||
};
|
||||
|
||||
bool ir_should_inline(IrExecutableSrc *exec, Scope *scope);
|
||||
Buf *get_anon_type_name(CodeGen *codegen, IrExecutableSrc *exec, const char *kind_name,
|
||||
Scope *scope, AstNode *source_node, Buf *out_bare_name);
|
||||
|
||||
#endif
|
||||
@ -69,7 +69,7 @@ void bigfloat_init_bigint(BigFloat *dest, const BigInt *op) {
|
||||
}
|
||||
}
|
||||
|
||||
Error bigfloat_init_buf(BigFloat *dest, const uint8_t *buf_ptr, size_t buf_len) {
|
||||
Error bigfloat_init_buf(BigFloat *dest, const uint8_t *buf_ptr) {
|
||||
char *str_begin = (char *)buf_ptr;
|
||||
char *str_end;
|
||||
|
||||
@ -79,7 +79,6 @@ Error bigfloat_init_buf(BigFloat *dest, const uint8_t *buf_ptr, size_t buf_len)
|
||||
return ErrorOverflow;
|
||||
}
|
||||
|
||||
assert(str_end <= ((char*)buf_ptr) + buf_len);
|
||||
return ErrorNone;
|
||||
}
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@ void bigfloat_init_64(BigFloat *dest, double x);
|
||||
void bigfloat_init_128(BigFloat *dest, float128_t x);
|
||||
void bigfloat_init_bigfloat(BigFloat *dest, const BigFloat *x);
|
||||
void bigfloat_init_bigint(BigFloat *dest, const BigInt *op);
|
||||
Error bigfloat_init_buf(BigFloat *dest, const uint8_t *buf_ptr, size_t buf_len);
|
||||
Error bigfloat_init_buf(BigFloat *dest, const uint8_t *buf_ptr);
|
||||
|
||||
float16_t bigfloat_to_f16(const BigFloat *bigfloat);
|
||||
float bigfloat_to_f32(const BigFloat *bigfloat);
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
*/
|
||||
|
||||
#include "analyze.hpp"
|
||||
#include "ast_render.hpp"
|
||||
#include "codegen.hpp"
|
||||
#include "errmsg.hpp"
|
||||
#include "error.hpp"
|
||||
@ -642,6 +641,18 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn) {
|
||||
return fn->llvm_value;
|
||||
}
|
||||
|
||||
static uint32_t node_line_onebased(AstNode *node) {
|
||||
RootStruct *root_struct = node->owner->data.structure.root_struct;
|
||||
assert(node->main_token < root_struct->token_count);
|
||||
return root_struct->token_locs[node->main_token].line + 1;
|
||||
}
|
||||
|
||||
static uint32_t node_column_onebased(AstNode *node) {
|
||||
RootStruct *root_struct = node->owner->data.structure.root_struct;
|
||||
assert(node->main_token < root_struct->token_count);
|
||||
return root_struct->token_locs[node->main_token].column + 1;
|
||||
}
|
||||
|
||||
static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
|
||||
if (scope->di_scope)
|
||||
return scope->di_scope;
|
||||
@ -657,8 +668,7 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
|
||||
ZigFn *fn_table_entry = fn_scope->fn_entry;
|
||||
if (!fn_table_entry->proto_node)
|
||||
return get_di_scope(g, scope->parent);
|
||||
unsigned line_number = (unsigned)(fn_table_entry->proto_node->line == 0) ?
|
||||
0 : (fn_table_entry->proto_node->line + 1);
|
||||
unsigned line_number = node_line_onebased(fn_table_entry->proto_node);
|
||||
unsigned scope_line = line_number;
|
||||
bool is_definition = fn_table_entry->body_node != nullptr;
|
||||
bool is_optimized = g->build_mode != BuildModeDebug;
|
||||
@ -696,8 +706,8 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
|
||||
ZigLLVMDILexicalBlock *di_block = ZigLLVMCreateLexicalBlock(g->dbuilder,
|
||||
get_di_scope(g, scope->parent),
|
||||
import->data.structure.root_struct->di_file,
|
||||
(unsigned)scope->source_node->line + 1,
|
||||
(unsigned)scope->source_node->column + 1);
|
||||
node_line_onebased(scope->source_node),
|
||||
node_column_onebased(scope->source_node));
|
||||
scope->di_scope = ZigLLVMLexicalBlockToScope(di_block);
|
||||
return scope->di_scope;
|
||||
}
|
||||
@ -1798,8 +1808,8 @@ static void gen_var_debug_decl(CodeGen *g, ZigVar *var) {
|
||||
if (g->strip_debug_symbols) return;
|
||||
assert(var->di_loc_var != nullptr);
|
||||
AstNode *source_node = var->decl_node;
|
||||
ZigLLVMDILocation *debug_loc = ZigLLVMGetDebugLoc((unsigned)source_node->line + 1,
|
||||
(unsigned)source_node->column + 1, get_di_scope(g, var->parent_scope));
|
||||
ZigLLVMDILocation *debug_loc = ZigLLVMGetDebugLoc(node_line_onebased(source_node),
|
||||
node_column_onebased(source_node), get_di_scope(g, var->parent_scope));
|
||||
ZigLLVMInsertDeclareAtEnd(g->dbuilder, var->value_ref, var->di_loc_var, debug_loc,
|
||||
LLVMGetInsertBlock(g->builder));
|
||||
}
|
||||
@ -2198,7 +2208,7 @@ var_ok:
|
||||
// arg index + 1 because the 0 index is return value
|
||||
var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
|
||||
var->name, fn_walk->data.vars.import->data.structure.root_struct->di_file,
|
||||
(unsigned)(var->decl_node->line + 1),
|
||||
node_line_onebased(var->decl_node),
|
||||
get_llvm_di_type(g, dest_ty), !g->strip_debug_symbols, 0, di_arg_index + 1);
|
||||
}
|
||||
return true;
|
||||
@ -4126,7 +4136,7 @@ static void render_async_spills(CodeGen *g) {
|
||||
if (var->decl_node) {
|
||||
var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
|
||||
var->name, import->data.structure.root_struct->di_file,
|
||||
(unsigned)(var->decl_node->line + 1),
|
||||
node_line_onebased(var->decl_node),
|
||||
get_llvm_di_type(g, var->var_type), !g->strip_debug_symbols, 0);
|
||||
gen_var_debug_decl(g, var);
|
||||
}
|
||||
@ -6797,8 +6807,8 @@ static void set_debug_location(CodeGen *g, IrInstGen *instruction) {
|
||||
assert(source_node);
|
||||
assert(scope);
|
||||
|
||||
ZigLLVMSetCurrentDebugLocation(g->builder, (int)source_node->line + 1,
|
||||
(int)source_node->column + 1, get_di_scope(g, scope));
|
||||
ZigLLVMSetCurrentDebugLocation(g->builder, node_line_onebased(source_node),
|
||||
node_column_onebased(source_node), get_di_scope(g, scope));
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutableGen *executable, IrInstGen *instruction) {
|
||||
@ -8021,7 +8031,7 @@ static void gen_global_var(CodeGen *g, ZigVar *var, LLVMValueRef init_val,
|
||||
bool is_local_to_unit = true;
|
||||
ZigLLVMCreateGlobalVariable(g->dbuilder, get_di_scope(g, var->parent_scope), var->name,
|
||||
var->name, import->data.structure.root_struct->di_file,
|
||||
(unsigned)(var->decl_node->line + 1),
|
||||
node_line_onebased(var->decl_node),
|
||||
get_llvm_di_type(g, type_entry), is_local_to_unit);
|
||||
|
||||
// TODO ^^ make an actual global variable
|
||||
@ -8296,7 +8306,8 @@ static void do_code_gen(CodeGen *g) {
|
||||
|
||||
if (var->src_arg_index == SIZE_MAX) {
|
||||
var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
|
||||
var->name, import->data.structure.root_struct->di_file, (unsigned)(var->decl_node->line + 1),
|
||||
var->name, import->data.structure.root_struct->di_file,
|
||||
node_line_onebased(var->decl_node),
|
||||
get_llvm_di_type(g, var->var_type), !g->strip_debug_symbols, 0);
|
||||
|
||||
} else if (is_c_abi) {
|
||||
@ -8321,7 +8332,7 @@ static void do_code_gen(CodeGen *g) {
|
||||
if (var->decl_node) {
|
||||
var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
|
||||
var->name, import->data.structure.root_struct->di_file,
|
||||
(unsigned)(var->decl_node->line + 1),
|
||||
node_line_onebased(var->decl_node),
|
||||
get_llvm_di_type(g, gen_type), !g->strip_debug_symbols, 0, (unsigned)(gen_info->gen_index+1));
|
||||
}
|
||||
|
||||
@ -8365,8 +8376,9 @@ static void do_code_gen(CodeGen *g) {
|
||||
|
||||
if (!g->strip_debug_symbols) {
|
||||
AstNode *source_node = fn_table_entry->proto_node;
|
||||
ZigLLVMSetCurrentDebugLocation(g->builder, (int)source_node->line + 1,
|
||||
(int)source_node->column + 1, get_di_scope(g, fn_table_entry->child_scope));
|
||||
ZigLLVMSetCurrentDebugLocation(g->builder,
|
||||
node_line_onebased(source_node), node_column_onebased(source_node),
|
||||
get_di_scope(g, fn_table_entry->child_scope));
|
||||
}
|
||||
IrExecutableGen *executable = &fn_table_entry->analyzed_executable;
|
||||
LLVMBasicBlockRef bad_resume_block = LLVMAppendBasicBlock(g->cur_fn_val, "BadResume");
|
||||
|
||||
@ -1084,19 +1084,43 @@ static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) {
|
||||
jw_end_object(jw);
|
||||
}
|
||||
|
||||
static Buf *collect_doc_comments(RootStruct *root_struct, TokenIndex first_token) {
|
||||
if (first_token == 0)
|
||||
return nullptr;
|
||||
|
||||
TokenId *token_ids = root_struct->token_ids;
|
||||
TokenLoc *token_locs = root_struct->token_locs;
|
||||
Buf *str = buf_alloc();
|
||||
const char *source = buf_ptr(root_struct->source_code);
|
||||
TokenIndex doc_token = first_token;
|
||||
for (;token_ids[doc_token] == TokenIdDocComment; doc_token += 1) {
|
||||
// chops off '///' but leaves '\n'
|
||||
uint32_t start_pos = token_locs[doc_token].offset;
|
||||
uint32_t token_len = 0;
|
||||
while (source[start_pos + token_len] != '\n' &&
|
||||
source[start_pos + token_len] != 0)
|
||||
{
|
||||
token_len += 1;
|
||||
}
|
||||
buf_append_mem(str, source + start_pos + 3, token_len - 3);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
static void anal_dump_node(AnalDumpCtx *ctx, const AstNode *node) {
|
||||
JsonWriter *jw = &ctx->jw;
|
||||
|
||||
jw_begin_object(jw);
|
||||
|
||||
jw_object_field(jw, "file");
|
||||
anal_dump_file_ref(ctx, node->owner->data.structure.root_struct->path);
|
||||
RootStruct *root_struct = node->owner->data.structure.root_struct;
|
||||
anal_dump_file_ref(ctx, root_struct->path);
|
||||
|
||||
jw_object_field(jw, "line");
|
||||
jw_int(jw, node->line);
|
||||
jw_int(jw, root_struct->token_locs[node->main_token].line);
|
||||
|
||||
jw_object_field(jw, "col");
|
||||
jw_int(jw, node->column);
|
||||
jw_int(jw, root_struct->token_locs[node->main_token].column);
|
||||
|
||||
const Buf *doc_comments_buf = nullptr;
|
||||
const Buf *name_buf = nullptr;
|
||||
@ -1107,30 +1131,30 @@ static void anal_dump_node(AnalDumpCtx *ctx, const AstNode *node) {
|
||||
|
||||
switch (node->type) {
|
||||
case NodeTypeParamDecl:
|
||||
doc_comments_buf = &node->data.param_decl.doc_comments;
|
||||
doc_comments_buf = collect_doc_comments(root_struct, node->data.param_decl.doc_comments);
|
||||
name_buf = node->data.param_decl.name;
|
||||
is_var_args = node->data.param_decl.is_var_args;
|
||||
is_noalias = node->data.param_decl.is_noalias;
|
||||
is_comptime = node->data.param_decl.is_comptime;
|
||||
break;
|
||||
case NodeTypeFnProto:
|
||||
doc_comments_buf = &node->data.fn_proto.doc_comments;
|
||||
doc_comments_buf = collect_doc_comments(root_struct, node->data.fn_proto.doc_comments);
|
||||
field_nodes = &node->data.fn_proto.params;
|
||||
is_var_args = node->data.fn_proto.is_var_args;
|
||||
break;
|
||||
case NodeTypeVariableDeclaration:
|
||||
doc_comments_buf = &node->data.variable_declaration.doc_comments;
|
||||
doc_comments_buf = collect_doc_comments(root_struct, node->data.variable_declaration.doc_comments);
|
||||
break;
|
||||
case NodeTypeErrorSetField:
|
||||
doc_comments_buf = &node->data.err_set_field.doc_comments;
|
||||
doc_comments_buf = collect_doc_comments(root_struct, node->data.err_set_field.doc_comments);
|
||||
break;
|
||||
case NodeTypeStructField:
|
||||
doc_comments_buf = &node->data.struct_field.doc_comments;
|
||||
doc_comments_buf = collect_doc_comments(root_struct, node->data.struct_field.doc_comments);
|
||||
name_buf = node->data.struct_field.name;
|
||||
break;
|
||||
case NodeTypeContainerDecl:
|
||||
field_nodes = &node->data.container_decl.fields;
|
||||
doc_comments_buf = &node->data.container_decl.doc_comments;
|
||||
doc_comments_buf = collect_doc_comments(root_struct, node->data.container_decl.doc_comments);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@ -96,14 +96,14 @@ void err_msg_add_note(ErrorMsg *parent, ErrorMsg *note) {
|
||||
parent->notes.append(note);
|
||||
}
|
||||
|
||||
ErrorMsg *err_msg_create_with_offset(Buf *path, size_t line, size_t column, size_t offset,
|
||||
const char *source, Buf *msg)
|
||||
ErrorMsg *err_msg_create_with_offset(Buf *path, uint32_t byte_offset, const char *source,
|
||||
Buf *msg)
|
||||
{
|
||||
ErrorMsg *err_msg = heap::c_allocator.create<ErrorMsg>();
|
||||
err_msg->path = path;
|
||||
err_msg->line_start = line;
|
||||
err_msg->column_start = column;
|
||||
err_msg->msg = msg;
|
||||
err_msg->line_start = 0;
|
||||
err_msg->column_start = 0;
|
||||
|
||||
if (source == nullptr) {
|
||||
// Must initialize the buffer anyway
|
||||
@ -111,46 +111,25 @@ ErrorMsg *err_msg_create_with_offset(Buf *path, size_t line, size_t column, size
|
||||
return err_msg;
|
||||
}
|
||||
|
||||
size_t line_start_offset = offset;
|
||||
for (;;) {
|
||||
if (line_start_offset == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
line_start_offset -= 1;
|
||||
|
||||
if (source[line_start_offset] == '\n') {
|
||||
line_start_offset += 1;
|
||||
break;
|
||||
size_t line_start = 0;
|
||||
size_t i = 0;
|
||||
for (;i < byte_offset; i += 1) {
|
||||
switch (source[i]) {
|
||||
case '\n':
|
||||
err_msg->line_start += 1;
|
||||
err_msg->column_start = 0;
|
||||
line_start = i + 1;
|
||||
continue;
|
||||
default:
|
||||
err_msg->column_start += 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
size_t line_end_offset = offset;
|
||||
while (source[line_end_offset] && source[line_end_offset] != '\n') {
|
||||
line_end_offset += 1;
|
||||
while (source[i] != '\n' && source[i] != 0) {
|
||||
i += 1;
|
||||
}
|
||||
|
||||
buf_init_from_mem(&err_msg->line_buf, source + line_start_offset, line_end_offset - line_start_offset);
|
||||
|
||||
return err_msg;
|
||||
}
|
||||
|
||||
ErrorMsg *err_msg_create_with_line(Buf *path, size_t line, size_t column,
|
||||
Buf *source, ZigList<size_t> *line_offsets, Buf *msg)
|
||||
{
|
||||
ErrorMsg *err_msg = heap::c_allocator.create<ErrorMsg>();
|
||||
err_msg->path = path;
|
||||
err_msg->line_start = line;
|
||||
err_msg->column_start = column;
|
||||
err_msg->msg = msg;
|
||||
|
||||
size_t line_start_offset = line_offsets->at(line);
|
||||
size_t end_line = line + 1;
|
||||
size_t line_end_offset = (end_line >= line_offsets->length) ? buf_len(source) : line_offsets->at(line + 1);
|
||||
size_t len = (line_end_offset + 1 > line_start_offset) ? (line_end_offset - line_start_offset - 1) : 0;
|
||||
if (len == SIZE_MAX) len = 0;
|
||||
|
||||
buf_init_from_mem(&err_msg->line_buf, buf_ptr(source) + line_start_offset, len);
|
||||
buf_init_from_mem(&err_msg->line_buf, source + line_start, i - line_start);
|
||||
|
||||
return err_msg;
|
||||
}
|
||||
|
||||
@ -25,10 +25,6 @@ struct ErrorMsg {
|
||||
void print_err_msg(ErrorMsg *msg, ErrColor color);
|
||||
|
||||
void err_msg_add_note(ErrorMsg *parent, ErrorMsg *note);
|
||||
ErrorMsg *err_msg_create_with_offset(Buf *path, size_t line, size_t column, size_t offset,
|
||||
const char *source, Buf *msg);
|
||||
|
||||
ErrorMsg *err_msg_create_with_line(Buf *path, size_t line, size_t column,
|
||||
Buf *source, ZigList<size_t> *line_offsets, Buf *msg);
|
||||
ErrorMsg *err_msg_create_with_offset(Buf *path, uint32_t byte_offset, const char *source, Buf *msg);
|
||||
|
||||
#endif
|
||||
|
||||
@ -88,6 +88,8 @@ const char *err_str(Error err) {
|
||||
case ErrorZigIsTheCCompiler: return "Zig was not provided with libc installation information, and so it does not know where the libc paths are on the system. Zig attempted to use the system C compiler to find out where the libc paths are, but discovered that Zig is being used as the system C compiler.";
|
||||
case ErrorFileBusy: return "file is busy";
|
||||
case ErrorLocked: return "file is locked by another process";
|
||||
case ErrorInvalidCharacter: return "invalid character";
|
||||
case ErrorUnicodePointTooLarge: return "unicode codepoint too large";
|
||||
}
|
||||
return "(invalid error)";
|
||||
}
|
||||
|
||||
8215
src/stage1/ir.cpp
8215
src/stage1/ir.cpp
File diff suppressed because it is too large
Load Diff
@ -10,9 +10,6 @@
|
||||
|
||||
#include "all_types.hpp"
|
||||
|
||||
bool ir_gen(CodeGen *g, AstNode *node, Scope *scope, IrExecutableSrc *ir_executable);
|
||||
bool ir_gen_fn(CodeGen *g, ZigFn *fn_entry);
|
||||
|
||||
IrInstGen *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node, ZigFn *fn,
|
||||
ZigType *var_type, const char *name_hint);
|
||||
|
||||
@ -33,8 +30,4 @@ struct IrAnalyze;
|
||||
ZigValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ZigValue *const_val,
|
||||
AstNode *source_node);
|
||||
|
||||
// for debugging purposes
|
||||
void dbg_ir_break(const char *src_file, uint32_t line);
|
||||
void dbg_ir_clear(void);
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -12,14 +12,21 @@
|
||||
#include "tokenizer.hpp"
|
||||
#include "errmsg.hpp"
|
||||
|
||||
ATTRIBUTE_PRINTF(2, 3)
|
||||
void ast_token_error(Token *token, const char *format, ...);
|
||||
|
||||
|
||||
AstNode * ast_parse(Buf *buf, ZigList<Token> *tokens, ZigType *owner, ErrColor err_color);
|
||||
AstNode * ast_parse(Buf *buf, ZigType *owner, ErrColor err_color);
|
||||
|
||||
void ast_print(AstNode *node, int indent);
|
||||
|
||||
void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *context), void *context);
|
||||
|
||||
Buf *node_identifier_buf(AstNode *node);
|
||||
Buf *node_string_literal_buf(AstNode *node);
|
||||
|
||||
Buf *token_identifier_buf(RootStruct *root_struct, TokenIndex token);
|
||||
Buf *token_string_literal_buf(RootStruct *root_struct, TokenIndex token);
|
||||
|
||||
void token_number_literal_bigint(RootStruct *root_struct, BigInt *result, TokenIndex token);
|
||||
|
||||
Error source_string_literal_buf(const char *source, Buf *out, size_t *bad_index);
|
||||
Error source_char_literal(const char *source, uint32_t *out, size_t *bad_index);
|
||||
|
||||
#endif
|
||||
|
||||
@ -112,6 +112,8 @@ enum Error {
|
||||
ErrorZigIsTheCCompiler,
|
||||
ErrorFileBusy,
|
||||
ErrorLocked,
|
||||
ErrorInvalidCharacter,
|
||||
ErrorUnicodePointTooLarge,
|
||||
};
|
||||
|
||||
// ABI warning
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -12,10 +12,9 @@
|
||||
#include "bigint.hpp"
|
||||
#include "bigfloat.hpp"
|
||||
|
||||
enum TokenId {
|
||||
enum TokenId : uint8_t {
|
||||
TokenIdAmpersand,
|
||||
TokenIdArrow,
|
||||
TokenIdAtSign,
|
||||
TokenIdBang,
|
||||
TokenIdBarBar,
|
||||
TokenIdBinOr,
|
||||
@ -27,6 +26,7 @@ enum TokenId {
|
||||
TokenIdBitShiftRight,
|
||||
TokenIdBitShiftRightEq,
|
||||
TokenIdBitXorEq,
|
||||
TokenIdBuiltin,
|
||||
TokenIdCharLiteral,
|
||||
TokenIdCmpEq,
|
||||
TokenIdCmpGreaterOrEq,
|
||||
@ -109,9 +109,7 @@ enum TokenId {
|
||||
TokenIdMinusPercent,
|
||||
TokenIdMinusPercentEq,
|
||||
TokenIdModEq,
|
||||
TokenIdNumberSign,
|
||||
TokenIdPercent,
|
||||
TokenIdPercentDot,
|
||||
TokenIdPlus,
|
||||
TokenIdPlusEq,
|
||||
TokenIdPlusPercent,
|
||||
@ -125,75 +123,35 @@ enum TokenId {
|
||||
TokenIdStar,
|
||||
TokenIdStarStar,
|
||||
TokenIdStringLiteral,
|
||||
TokenIdMultilineStringLiteral,
|
||||
TokenIdSymbol,
|
||||
TokenIdMultilineStringLiteralLine,
|
||||
TokenIdIdentifier,
|
||||
TokenIdTilde,
|
||||
TokenIdTimesEq,
|
||||
TokenIdTimesPercent,
|
||||
TokenIdTimesPercentEq,
|
||||
|
||||
TokenIdCount,
|
||||
};
|
||||
|
||||
struct TokenFloatLit {
|
||||
BigFloat bigfloat;
|
||||
// overflow is true if when parsing the number, we discovered it would not fit
|
||||
// without losing data
|
||||
bool overflow;
|
||||
typedef uint32_t TokenIndex;
|
||||
|
||||
struct TokenLoc {
|
||||
uint32_t offset;
|
||||
uint32_t line;
|
||||
uint32_t column;
|
||||
};
|
||||
|
||||
struct TokenIntLit {
|
||||
BigInt bigint;
|
||||
};
|
||||
|
||||
struct TokenStrLit {
|
||||
Buf str;
|
||||
};
|
||||
|
||||
struct TokenCharLit {
|
||||
uint32_t c;
|
||||
};
|
||||
|
||||
struct Token {
|
||||
TokenId id;
|
||||
size_t start_pos;
|
||||
size_t end_pos;
|
||||
size_t start_line;
|
||||
size_t start_column;
|
||||
|
||||
union {
|
||||
// TokenIdIntLiteral
|
||||
TokenIntLit int_lit;
|
||||
|
||||
// TokenIdFloatLiteral
|
||||
TokenFloatLit float_lit;
|
||||
|
||||
// TokenIdStringLiteral, TokenIdMultilineStringLiteral or TokenIdSymbol
|
||||
TokenStrLit str_lit;
|
||||
|
||||
// TokenIdCharLiteral
|
||||
TokenCharLit char_lit;
|
||||
} data;
|
||||
};
|
||||
// work around conflicting name Token which is also found in libclang
|
||||
typedef Token ZigToken;
|
||||
|
||||
struct Tokenization {
|
||||
ZigList<Token> *tokens;
|
||||
ZigList<size_t> *line_offsets;
|
||||
ZigList<TokenId> ids;
|
||||
ZigList<TokenLoc> locs;
|
||||
|
||||
// if an error occurred
|
||||
Buf *err;
|
||||
size_t err_line;
|
||||
size_t err_column;
|
||||
uint32_t err_byte_offset;
|
||||
};
|
||||
|
||||
void tokenize(Buf *buf, Tokenization *out_tokenization);
|
||||
|
||||
void print_tokens(Buf *buf, ZigList<Token> *tokens);
|
||||
void tokenize(const char *source, Tokenization *out_tokenization);
|
||||
|
||||
const char * token_name(TokenId id);
|
||||
|
||||
bool valid_symbol_starter(uint8_t c);
|
||||
bool is_zig_keyword(Buf *buf);
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
const std = @import("std");
|
||||
const expect = std.testing.expect;
|
||||
const expectEqualSlices = std.testing.expectEqualSlices;
|
||||
const expectEqualStrings = std.testing.expectEqualStrings;
|
||||
const mem = std.mem;
|
||||
const builtin = @import("builtin");
|
||||
|
||||
@ -147,13 +148,13 @@ test "array mult operator" {
|
||||
}
|
||||
|
||||
test "string escapes" {
|
||||
try expect(mem.eql(u8, "\"", "\x22"));
|
||||
try expect(mem.eql(u8, "\'", "\x27"));
|
||||
try expect(mem.eql(u8, "\n", "\x0a"));
|
||||
try expect(mem.eql(u8, "\r", "\x0d"));
|
||||
try expect(mem.eql(u8, "\t", "\x09"));
|
||||
try expect(mem.eql(u8, "\\", "\x5c"));
|
||||
try expect(mem.eql(u8, "\u{1234}\u{069}\u{1}", "\xe1\x88\xb4\x69\x01"));
|
||||
try expectEqualStrings("\"", "\x22");
|
||||
try expectEqualStrings("\'", "\x27");
|
||||
try expectEqualStrings("\n", "\x0a");
|
||||
try expectEqualStrings("\r", "\x0d");
|
||||
try expectEqualStrings("\t", "\x09");
|
||||
try expectEqualStrings("\\", "\x5c");
|
||||
try expectEqualStrings("\u{1234}\u{069}\u{1}", "\xe1\x88\xb4\x69\x01");
|
||||
}
|
||||
|
||||
test "multiline string" {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user