diff --git a/include/runtime.h b/include/runtime.h index 94745fb..00f661c 100644 --- a/include/runtime.h +++ b/include/runtime.h @@ -5,7 +5,9 @@ #include "parser.h" -extern int show_warning; +#include + +extern bool show_warning; extern int warning_cnt; extern char *user_input; extern CharPtrList *user_input_list; @@ -37,6 +39,8 @@ extern FileName *filenames; extern char *input_file; extern char *output_file; extern Location *consumed_loc; +extern int hierarchy_level; +extern bool print_include_files; extern IncludePath *include_paths; extern FILE *fp; extern Macro *macros; diff --git a/src/lexer/preprocess_include.c b/src/lexer/preprocess_include.c index 2cd63b0..e459656 100644 --- a/src/lexer/preprocess_include.c +++ b/src/lexer/preprocess_include.c @@ -22,7 +22,14 @@ static void handle_include_directive(char *name, char *p, int is_system_header) free(raw_name); char *input_file_prev = input_file; + int prev_level = hierarchy_level; + hierarchy_level++; input_file = resolved_path; + if (print_include_files) { + for (int i = 0; i < hierarchy_level; i++) + fprintf(stderr, "."); + fprintf(stderr, " %s\n", resolved_path); + } FileName *filename = malloc(sizeof(FileName)); filename->name = resolved_path; filename->next = filenames; @@ -43,6 +50,7 @@ static void handle_include_directive(char *name, char *p, int is_system_header) user_input = user_input_prev; input_file = input_file_prev; + hierarchy_level = prev_level; } static void handle_include_next_directive(char *name, char *p) { diff --git a/src/main.c b/src/main.c index 711b9ac..8ab1e76 100644 --- a/src/main.c +++ b/src/main.c @@ -227,6 +227,8 @@ int main(int argc, char **argv) { } else if (!strncmp(argv[i], "-S", 2)) { } else if (!strncmp(argv[i], "-w", 2)) { show_warning = false; + } else if (!strncmp(argv[i], "-H", 2)) { + print_include_files = true; } else if (!strncmp(argv[i], "-o", 2) && i + 1 < argc) { if (output_file_specified) { error("multiple output files specified."); @@ -255,6 +257,7 @@ int main(int argc, char **argv) { filename->name = input_file; filename->next = filenames; filenames = filename; + hierarchy_level = 0; if (strncmp(input_file + length - 2, ".c", 2)) { error("source file must have a .c extension."); } diff --git a/src/parser/decl.c b/src/parser/decl.c index b715eae..8de7e26 100644 --- a/src/parser/decl.c +++ b/src/parser/decl.c @@ -748,6 +748,10 @@ Node *typedef_stmt() { Token *tok; type = parse_declarator(type, &tok, "typedef"); skip_gnu_asm_specifier("asm specifier"); + if (!type) { + Location *loc = token ? token->loc : consumed_loc; + error_at(loc, "expected a type [in typedef]"); + } if (!tok) { Location *loc = token ? token->loc : consumed_loc; error_at(loc, "expected an identifier [in typedef statement]"); diff --git a/src/parser/parse.c b/src/parser/parse.c index f40451d..0a54cc4 100644 --- a/src/parser/parse.c +++ b/src/parser/parse.c @@ -78,8 +78,14 @@ int parse_sign() { // 数値の期待値取得(符号付き) int expect_signed_number() { - int sign = parse_sign(); - return expect_number("expect signed number") * sign; + Token *tok = token; + Node *expr_node = assign(); + int ok = true; + int value = eval_const_expr(expr_node, &ok); + if (!ok) { + error_at(tok->loc, "expected a compile time constant [in expect signed number statement]"); + } + return value; } void error_duplicate_name(Token *tok, const char *type) { diff --git a/src/types/type.c b/src/types/type.c index e183d94..17cbe1e 100644 --- a/src/types/type.c +++ b/src/types/type.c @@ -132,23 +132,13 @@ Type *parse_base_type_internal(const int should_consume, const int should_record type->ty = TY_INT; type->object = enum_declaration(should_record); } else if (token->kind == TK_IDENT) { - // サポートしていないが、システムヘッダで現れる組込み型に対する最低限の対応 - // 例: glibc の stdarg.h などで使用される '__builtin_va_list' - if (token->len == (int)strlen("__builtin_va_list") && strncmp(token->str, "__builtin_va_list", token->len) == 0) { + int bits = 0; + int is_unsigned = 0; + if (token_matches(token, "__builtin_va_list")) { // 内部表現としては void* 相当で十分(実際のレイアウトは不要) Type *void_ty = new_type(TY_VOID); type = new_type_ptr(void_ty); token = token->next; - } else if (token->len == (int)strlen("wchar_t") && strncmp(token->str, "wchar_t", token->len) == 0) { - // C では本来 typedef だが、ヘッダ互換性のためビルトイン扱い(LP64 では int 相当) - type->ty = TY_INT; - type->is_unsigned = false; - token = token->next; - } else if (token->len == (int)strlen("size_t") && strncmp(token->str, "size_t", token->len) == 0) { - // size_t をビルトイン型として扱う(LP64 では unsigned long) - type->ty = TY_LONG; - type->is_unsigned = true; - token = token->next; } else { TypeTag *type_tag = find_type_tag(token); if (type_tag) { @@ -718,9 +708,9 @@ int is_type(Token *tok) { if (tok->kind == TK_IDENT) { // Recognize common typedef-like builtins even before their typedefs are seen // to match parse_base_type() behavior (e.g., size_t, wchar_t, __builtin_va_list). - if ((tok->len == (int)strlen("size_t") && strncmp(tok->str, "size_t", tok->len) == 0) || - (tok->len == (int)strlen("wchar_t") && strncmp(tok->str, "wchar_t", tok->len) == 0) || - (tok->len == (int)strlen("__builtin_va_list") && strncmp(tok->str, "__builtin_va_list", tok->len) == 0)) { + int bits = 0; + int is_unsigned = 0; + if (tok->len == (int)strlen("__builtin_va_list") && strncmp(tok->str, "__builtin_va_list", tok->len) == 0) { return true; } diff --git a/src/utils/globals.c b/src/utils/globals.c index 559aed7..9c87a69 100644 --- a/src/utils/globals.c +++ b/src/utils/globals.c @@ -2,9 +2,10 @@ #include "parser.h" #include "source.h" +#include #include -int show_warning = 1; +bool show_warning = true; int warning_cnt = 0; char *user_input = 0; CharPtrList *user_input_list = 0; @@ -18,28 +19,30 @@ int loop_id = -1; int variable_cnt = 0; int block_cnt = 0; int block_id = 0; -Node *current_switch = 0; -Function *functions = 0; -Function *current_fn = 0; -LVar *locals = 0; -LVar *globals = 0; -LVar *statics = 0; -Object *structs = 0; -Object *unions = 0; -Object *enums = 0; -Object *current_enum_scope = 0; -TypeTag *type_tags = 0; -String *strings = 0; -Array *arrays = 0; -StructLiteral *struct_literals = 0; -FileName *filenames = 0; -char *input_file = 0; -char *output_file = 0; -Location *consumed_loc = 0; +Node *current_switch = NULL; +Function *functions = NULL; +Function *current_fn = NULL; +LVar *locals = NULL; +LVar *globals = NULL; +LVar *statics = NULL; +Object *structs = NULL; +Object *unions = NULL; +Object *enums = NULL; +Object *current_enum_scope = NULL; +TypeTag *type_tags = NULL; +String *strings = NULL; +Array *arrays = NULL; +StructLiteral *struct_literals = NULL; +FileName *filenames = NULL; +char *input_file = NULL; +char *output_file = NULL; +Location *consumed_loc = NULL; +int hierarchy_level = -1; +bool print_include_files = false; -IncludePath *include_paths = 0; -FILE *fp = 0; -Macro *macros = 0; +IncludePath *include_paths = NULL; +FILE *fp = NULL; +Macro *macros = NULL; void init_global_variables() { // グローバル変数の初期化