|
|
|
@ -1820,6 +1820,8 @@ static void new_std_macro (c2m_ctx_t c2m_ctx, const char *id_str) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void init_macros (c2m_ctx_t c2m_ctx) {
|
|
|
|
|
VARR (token_t) * params;
|
|
|
|
|
|
|
|
|
|
VARR_CREATE (macro_t, macros, 2048);
|
|
|
|
|
HTAB_CREATE (macro_t, macro_tab, 2048, macro_hash, macro_eq);
|
|
|
|
|
/* Standard macros : */
|
|
|
|
@ -1827,6 +1829,10 @@ static void init_macros (c2m_ctx_t c2m_ctx) {
|
|
|
|
|
new_std_macro (c2m_ctx, "__TIME__");
|
|
|
|
|
new_std_macro (c2m_ctx, "__FILE__");
|
|
|
|
|
new_std_macro (c2m_ctx, "__LINE__");
|
|
|
|
|
VARR_CREATE (token_t, params, 1);
|
|
|
|
|
VARR_PUSH (token_t, params, new_id_token (c2m_ctx, no_pos, "$"));
|
|
|
|
|
if (!options->pedantic_p)
|
|
|
|
|
new_macro (c2m_ctx, new_id_token (c2m_ctx, no_pos, "__has_include"), params, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static macro_t new_macro (c2m_ctx_t c2m_ctx, token_t id, VARR (token_t) * params,
|
|
|
|
@ -1938,12 +1944,12 @@ static void pre_finish (c2m_ctx_t c2m_ctx) {
|
|
|
|
|
free (c2m_ctx->pre_ctx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void add_include_stream (c2m_ctx_t c2m_ctx, const char *fname) {
|
|
|
|
|
static void add_include_stream (c2m_ctx_t c2m_ctx, const char *fname, pos_t err_pos) {
|
|
|
|
|
FILE *f;
|
|
|
|
|
|
|
|
|
|
assert (fname != NULL);
|
|
|
|
|
if ((f = fopen (fname, "r")) == NULL) {
|
|
|
|
|
if (options->message_file != NULL) fprintf (stderr, "error in opening file %s\n", fname);
|
|
|
|
|
if (options->message_file != NULL) error (c2m_ctx, err_pos, "error in opening file %s", fname);
|
|
|
|
|
longjmp (c2m_ctx->env, 1); // ???
|
|
|
|
|
}
|
|
|
|
|
add_stream (c2m_ctx, f, fname, NULL);
|
|
|
|
@ -2071,8 +2077,10 @@ static void define (c2m_ctx_t c2m_ctx) {
|
|
|
|
|
}
|
|
|
|
|
} else if (m->replacement == NULL) {
|
|
|
|
|
error (c2m_ctx, id->pos, "standard macro %s redefinition", name);
|
|
|
|
|
} else if (!params_eq_p (m->params, params) || !replacement_eq_p (m->replacement, repl)) {
|
|
|
|
|
error (c2m_ctx, id->pos, "different macro redefinition of %s", name);
|
|
|
|
|
} else {
|
|
|
|
|
if (!params_eq_p (m->params, params) || !replacement_eq_p (m->replacement, repl))
|
|
|
|
|
error (c2m_ctx, id->pos, "different macro redefinition of %s", name);
|
|
|
|
|
VARR_DESTROY (token_t, repl);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -2646,9 +2654,24 @@ static void processing (c2m_ctx_t c2m_ctx, int ignore_directive_p);
|
|
|
|
|
|
|
|
|
|
static struct val eval_expr (c2m_ctx_t c2m_ctx, VARR (token_t) * buffer, token_t if_token);
|
|
|
|
|
|
|
|
|
|
static const char *get_header_name (c2m_ctx_t c2m_ctx, VARR (token_t) * buffer, pos_t err_pos) {
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
transform_to_header (c2m_ctx, buffer);
|
|
|
|
|
i = 0;
|
|
|
|
|
if (VARR_LENGTH (token_t, buffer) != 0 && VARR_GET (token_t, buffer, 0)->code == ' ') i++;
|
|
|
|
|
if (i != VARR_LENGTH (token_t, buffer) - 1
|
|
|
|
|
|| (VARR_GET (token_t, buffer, i)->code != T_STR
|
|
|
|
|
&& VARR_GET (token_t, buffer, i)->code != T_HEADER)) {
|
|
|
|
|
error (c2m_ctx, err_pos, "wrong #include");
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
return get_include_fname (c2m_ctx, VARR_GET (token_t, buffer, i));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void process_directive (c2m_ctx_t c2m_ctx) {
|
|
|
|
|
token_t t, t1;
|
|
|
|
|
int i, true_p;
|
|
|
|
|
int true_p;
|
|
|
|
|
VARR (token_t) * temp_buffer;
|
|
|
|
|
pos_t pos;
|
|
|
|
|
struct macro macro;
|
|
|
|
@ -2760,24 +2783,16 @@ static void process_directive (c2m_ctx_t c2m_ctx) {
|
|
|
|
|
processing (c2m_ctx, TRUE);
|
|
|
|
|
no_out_p = FALSE;
|
|
|
|
|
move_tokens (temp_buffer, output_buffer);
|
|
|
|
|
transform_to_header (c2m_ctx, temp_buffer);
|
|
|
|
|
i = 0;
|
|
|
|
|
if (VARR_LENGTH (token_t, temp_buffer) != 0
|
|
|
|
|
&& VARR_GET (token_t, temp_buffer, 0)->code == ' ')
|
|
|
|
|
i++;
|
|
|
|
|
if (i != VARR_LENGTH (token_t, temp_buffer) - 1
|
|
|
|
|
|| (VARR_GET (token_t, temp_buffer, i)->code != T_STR
|
|
|
|
|
&& VARR_GET (token_t, temp_buffer, i)->code != T_HEADER)) {
|
|
|
|
|
if ((name = get_header_name (c2m_ctx, temp_buffer, t->pos)) == NULL) {
|
|
|
|
|
error (c2m_ctx, t->pos, "wrong #include");
|
|
|
|
|
goto ret;
|
|
|
|
|
}
|
|
|
|
|
name = get_include_fname (c2m_ctx, VARR_GET (token_t, temp_buffer, i));
|
|
|
|
|
}
|
|
|
|
|
if (VARR_LENGTH (stream_t, streams) >= max_nested_includes + 1) {
|
|
|
|
|
error (c2m_ctx, t->pos, "more %d include levels", VARR_LENGTH (stream_t, streams) - 1);
|
|
|
|
|
goto ret;
|
|
|
|
|
}
|
|
|
|
|
add_include_stream (c2m_ctx, name);
|
|
|
|
|
add_include_stream (c2m_ctx, name, t->pos);
|
|
|
|
|
} else if (strcmp (t->repr, "line") == 0) {
|
|
|
|
|
skip_nl (c2m_ctx, NULL, temp_buffer);
|
|
|
|
|
unget_next_pptoken (c2m_ctx, new_token (c2m_ctx, t->pos, "", T_EOP, N_IGNORE));
|
|
|
|
@ -3043,7 +3058,12 @@ static struct val eval_expr (c2m_ctx_t c2m_ctx, VARR (token_t) * expr_buffer, to
|
|
|
|
|
VARR_PUSH (token_t, temp_buffer, t);
|
|
|
|
|
}
|
|
|
|
|
no_out_p = TRUE;
|
|
|
|
|
tree = parse_pre_expr (c2m_ctx, temp_buffer);
|
|
|
|
|
if (VARR_LENGTH (token_t, temp_buffer) != 0) {
|
|
|
|
|
tree = parse_pre_expr (c2m_ctx, temp_buffer);
|
|
|
|
|
} else {
|
|
|
|
|
error (c2m_ctx, if_token->pos, "empty preprocessor expression");
|
|
|
|
|
tree = NULL;
|
|
|
|
|
}
|
|
|
|
|
no_out_p = FALSE;
|
|
|
|
|
VARR_DESTROY (token_t, temp_buffer);
|
|
|
|
|
if (tree == NULL) {
|
|
|
|
@ -3194,6 +3214,30 @@ static struct val eval (c2m_ctx_t c2m_ctx, node_t tree) {
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static macro_call_t try_param_macro_call (c2m_ctx_t c2m_ctx, macro_t m, token_t macro_id) {
|
|
|
|
|
macro_call_t mc;
|
|
|
|
|
token_t t1 = get_next_pptoken (c2m_ctx), t2 = NULL;
|
|
|
|
|
|
|
|
|
|
if (t1->code == T_EOR) {
|
|
|
|
|
pop_macro_call (c2m_ctx);
|
|
|
|
|
t1 = get_next_pptoken (c2m_ctx);
|
|
|
|
|
}
|
|
|
|
|
if (t1->code == ' ' || t1->code == '\n') {
|
|
|
|
|
t2 = t1;
|
|
|
|
|
t1 = get_next_pptoken (c2m_ctx);
|
|
|
|
|
}
|
|
|
|
|
if (t1->code != '(') { /* no args: it is not a macro call */
|
|
|
|
|
unget_next_pptoken (c2m_ctx, t1);
|
|
|
|
|
if (t2 != NULL) unget_next_pptoken (c2m_ctx, t2);
|
|
|
|
|
out_token (c2m_ctx, macro_id);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
mc = new_macro_call (m, macro_id->pos);
|
|
|
|
|
find_args (c2m_ctx, mc);
|
|
|
|
|
VARR_PUSH (macro_call_t, macro_call_stack, mc);
|
|
|
|
|
return mc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void processing (c2m_ctx_t c2m_ctx, int ignore_directive_p) {
|
|
|
|
|
token_t t, t1, t2;
|
|
|
|
|
struct macro macro_struct;
|
|
|
|
@ -3282,6 +3326,31 @@ static void processing (c2m_ctx_t c2m_ctx, int ignore_directive_p) {
|
|
|
|
|
t = new_node_token (c2m_ctx, t->pos, time_str_repr, T_STR,
|
|
|
|
|
new_str_node (c2m_ctx, N_STR, uniq_cstr (c2m_ctx, time_str), t->pos));
|
|
|
|
|
out_token (c2m_ctx, t);
|
|
|
|
|
} else if (strcmp (t->repr, "__has_include") == 0) {
|
|
|
|
|
int res;
|
|
|
|
|
VARR (token_t) * arg;
|
|
|
|
|
const char *name;
|
|
|
|
|
FILE *f;
|
|
|
|
|
|
|
|
|
|
if ((mc = try_param_macro_call (c2m_ctx, m, t)) != NULL) {
|
|
|
|
|
unget_next_pptoken (c2m_ctx, new_token (c2m_ctx, t->pos, "", T_EOR, N_IGNORE));
|
|
|
|
|
if (VARR_LENGTH (token_arr_t, mc->args) != 1) {
|
|
|
|
|
res = 0;
|
|
|
|
|
} else {
|
|
|
|
|
arg = VARR_LAST (token_arr_t, mc->args);
|
|
|
|
|
if ((name = get_header_name (c2m_ctx, arg, t->pos)) != NULL) {
|
|
|
|
|
res = ((f = fopen (name, "r")) != NULL && !fclose (f)) ? 1 : 0;
|
|
|
|
|
} else {
|
|
|
|
|
error (c2m_ctx, t->pos, "wrong arg of predefined __has_include");
|
|
|
|
|
res = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
m->ignore_p = TRUE;
|
|
|
|
|
unget_next_pptoken (c2m_ctx,
|
|
|
|
|
new_node_token (c2m_ctx, t->pos,
|
|
|
|
|
uniq_cstr (c2m_ctx, res ? "1" : "0").s, T_NUMBER,
|
|
|
|
|
new_i_node (c2m_ctx, res, t->pos)));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
assert (FALSE);
|
|
|
|
|
}
|
|
|
|
@ -3302,26 +3371,7 @@ static void processing (c2m_ctx_t c2m_ctx, int ignore_directive_p) {
|
|
|
|
|
copy_and_push_back (c2m_ctx, do_concat (c2m_ctx, mc->repl_buffer), mc->pos);
|
|
|
|
|
m->ignore_p = TRUE;
|
|
|
|
|
VARR_PUSH (macro_call_t, macro_call_stack, mc);
|
|
|
|
|
} else { /* macro with parameters */
|
|
|
|
|
t2 = NULL;
|
|
|
|
|
t1 = get_next_pptoken (c2m_ctx);
|
|
|
|
|
if (t1->code == T_EOR) {
|
|
|
|
|
pop_macro_call (c2m_ctx);
|
|
|
|
|
t1 = get_next_pptoken (c2m_ctx);
|
|
|
|
|
}
|
|
|
|
|
if (t1->code == ' ' || t1->code == '\n') {
|
|
|
|
|
t2 = t1;
|
|
|
|
|
t1 = get_next_pptoken (c2m_ctx);
|
|
|
|
|
}
|
|
|
|
|
if (t1->code != '(') { /* no args: it is not a macro call */
|
|
|
|
|
unget_next_pptoken (c2m_ctx, t1);
|
|
|
|
|
if (t2 != NULL) unget_next_pptoken (c2m_ctx, t2);
|
|
|
|
|
out_token (c2m_ctx, t);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
mc = new_macro_call (m, t->pos);
|
|
|
|
|
find_args (c2m_ctx, mc);
|
|
|
|
|
VARR_PUSH (macro_call_t, macro_call_stack, mc);
|
|
|
|
|
} else if ((mc = try_param_macro_call (c2m_ctx, m, t)) != NULL) { /* macro with parameters */
|
|
|
|
|
process_replacement (c2m_ctx, mc);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -9293,6 +9343,8 @@ static void emit_insn_opt (MIR_context_t ctx, MIR_insn_t insn) {
|
|
|
|
|
MIR_insn_op_mode (ctx, tail, 0, &out_p);
|
|
|
|
|
if (out_p) {
|
|
|
|
|
tail->ops[0] = insn->ops[0];
|
|
|
|
|
MIR_append_insn (ctx, curr_func, insn);
|
|
|
|
|
MIR_remove_insn (ctx, curr_func, insn);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -12015,6 +12067,7 @@ static void print_node (MIR_context_t ctx, FILE *f, node_t n, int indent, int at
|
|
|
|
|
static void init_include_dirs (MIR_context_t ctx) {
|
|
|
|
|
c2m_ctx_t c2m_ctx = *c2m_ctx_loc (ctx);
|
|
|
|
|
const char *str;
|
|
|
|
|
int added_p = FALSE;
|
|
|
|
|
|
|
|
|
|
VARR_CREATE (char_ptr_t, headers, 0);
|
|
|
|
|
VARR_CREATE (char_ptr_t, system_headers, 0);
|
|
|
|
@ -12038,14 +12091,22 @@ static void init_include_dirs (MIR_context_t ctx) {
|
|
|
|
|
}
|
|
|
|
|
#if defined(__APPLE__) || defined(__unix__)
|
|
|
|
|
VARR_PUSH (char_ptr_t, system_headers, "/usr/local/include");
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef ADDITIONAL_INCLUDE_PATH
|
|
|
|
|
if (ADDITIONAL_INCLUDE_PATH[0] != 0) {
|
|
|
|
|
added_p = TRUE;
|
|
|
|
|
VARR_PUSH (char_ptr_t, system_headers, ADDITIONAL_INCLUDE_PATH);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#if defined(__APPLE__)
|
|
|
|
|
VARR_PUSH (char_ptr_t, system_headers,
|
|
|
|
|
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/"
|
|
|
|
|
"MacOSX.sdk/usr/include");
|
|
|
|
|
if (!added_p)
|
|
|
|
|
VARR_PUSH (char_ptr_t, system_headers,
|
|
|
|
|
"/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include");
|
|
|
|
|
#endif
|
|
|
|
|
#if defined(__linux__) && defined(__x86_64__)
|
|
|
|
|
VARR_PUSH (char_ptr_t, system_headers, "/usr/include/x86_64-linux-gnu");
|
|
|
|
|
#endif
|
|
|
|
|
#if defined(__APPLE__) || defined(__unix__)
|
|
|
|
|
VARR_PUSH (char_ptr_t, system_headers, "/usr/include");
|
|
|
|
|
#endif
|
|
|
|
|
VARR_PUSH (char_ptr_t, system_headers, NULL);
|
|
|
|
|