Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion include/runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@

#include "parser.h"

extern int show_warning;
#include <stdbool.h>

extern bool show_warning;
extern int warning_cnt;
extern char *user_input;
extern CharPtrList *user_input_list;
Expand Down Expand Up @@ -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;
Expand Down
8 changes: 8 additions & 0 deletions src/lexer/preprocess_include.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand Down
3 changes: 3 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.");
Expand Down Expand Up @@ -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.");
}
Expand Down
4 changes: 4 additions & 0 deletions src/parser/decl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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]");
Expand Down
10 changes: 8 additions & 2 deletions src/parser/parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
22 changes: 6 additions & 16 deletions src/types/type.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
}

Expand Down
47 changes: 25 additions & 22 deletions src/utils/globals.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
#include "parser.h"
#include "source.h"

#include <stdbool.h>
#include <stdio.h>

int show_warning = 1;
bool show_warning = true;
int warning_cnt = 0;
char *user_input = 0;
CharPtrList *user_input_list = 0;
Expand All @@ -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() {
// グローバル変数の初期化
Expand Down