Alien-TinyCCx
view release on metacpan or search on metacpan
src/tccgen.c view on Meta::CPAN
/* put a common area */
put_extern_sym(sym, NULL, align, size);
/* XXX: find a nicer way */
esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
esym->st_shndx = SHN_COMMON;
}
} else {
/* push global reference */
sym = get_sym_ref(type, sec, addr, size);
vpushsym(type, sym);
}
/* patch symbol weakness */
if (type->t & VT_WEAK)
weaken_symbol(sym);
apply_visibility(sym, type);
#ifdef CONFIG_TCC_BCHECK
/* handles bounds now because the symbol must be defined
before for the relocation */
if (tcc_state->do_bounds_check) {
addr_t *bounds_ptr;
greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
/* then add global bound info */
bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(addr_t));
bounds_ptr[0] = 0; /* relocated */
bounds_ptr[1] = size;
}
#endif
}
if (has_init || (type->t & VT_VLA)) {
decl_initializer(type, sec, addr, 1, 0);
/* patch flexible array member size back to -1, */
/* for possible subsequent similar declarations */
if (flexible_array)
flexible_array->type.ref->c = -1;
}
no_alloc: ;
/* restore parse state if needed */
if (init_str) {
end_macro();
restore_parse_state(&saved_parse_state);
}
}
static void put_func_debug(Sym *sym)
{
char buf[512];
/* stabs info */
/* XXX: we put here a dummy type */
snprintf(buf, sizeof(buf), "%s:%c1",
funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
cur_text_section, sym->c);
/* //gr gdb wants a line at the function */
put_stabn(N_SLINE, 0, file->line_num, 0);
last_ind = 0;
last_line_num = 0;
}
/* parse an old style function declaration list */
/* XXX: check multiple parameter */
static void func_decl_list(Sym *func_sym)
{
AttributeDef ad;
int v;
Sym *s;
CType btype, type;
/* parse each declaration */
while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
if (!parse_btype(&btype, &ad))
expect("declaration list");
if (((btype.t & VT_BTYPE) == VT_ENUM ||
(btype.t & VT_BTYPE) == VT_STRUCT) &&
tok == ';') {
/* we accept no variable after */
} else {
for(;;) {
type = btype;
type_decl(&type, &ad, &v, TYPE_DIRECT);
/* find parameter in function parameter list */
s = func_sym->next;
while (s != NULL) {
if ((s->v & ~SYM_FIELD) == v)
goto found;
s = s->next;
}
tcc_error("declaration for parameter '%s' but no such parameter",
get_tok_str(v, NULL));
found:
/* check that no storage specifier except 'register' was given */
if (type.t & VT_STORAGE)
tcc_error("storage class specified for '%s'", get_tok_str(v, NULL));
convert_parameter_type(&type);
/* we can add the type (NOTE: it could be local to the function) */
s->type = type;
/* accept other parameters */
if (tok == ',')
next();
else
break;
}
}
skip(';');
}
}
/* parse a function defined by symbol 'sym' and generate its code in
'cur_text_section' */
static void gen_function(Sym *sym)
{
int saved_nocode_wanted = nocode_wanted;
nocode_wanted = 0;
ind = cur_text_section->data_offset;
/* NOTE: we patch the symbol size later */
put_extern_sym(sym, cur_text_section, ind, 0);
funcname = get_tok_str(sym->v, NULL);
func_ind = ind;
src/tccgen.c view on Meta::CPAN
tok_str_free(fn->func_str);
}
dynarray_reset(&s->inline_fns, &s->nb_inline_fns);
}
/* 'l' is VT_LOCAL or VT_CONST to define default storage type */
static int decl0(int l, int is_for_loop_init)
{
int v, has_init, r;
CType type, btype;
Sym *sym;
AttributeDef ad;
while (1) {
if (!parse_btype(&btype, &ad)) {
if (is_for_loop_init)
return 0;
/* skip redundant ';' */
/* XXX: find more elegant solution */
if (tok == ';') {
next();
continue;
}
if (l == VT_CONST &&
(tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
/* global asm block */
asm_global_instr();
continue;
}
/* special test for old K&R protos without explicit int
type. Only accepted when defining global data */
if (l == VT_LOCAL || tok < TOK_UIDENT)
break;
btype.t = VT_INT;
}
if (((btype.t & VT_BTYPE) == VT_ENUM ||
(btype.t & VT_BTYPE) == VT_STRUCT) &&
tok == ';') {
if ((btype.t & VT_BTYPE) == VT_STRUCT) {
int v = btype.ref->v;
if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM)
tcc_warning("unnamed struct/union that defines no instances");
}
next();
continue;
}
while (1) { /* iterate thru each declaration */
type = btype;
type_decl(&type, &ad, &v, TYPE_DIRECT);
#if 0
{
char buf[500];
type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
printf("type = '%s'\n", buf);
}
#endif
if ((type.t & VT_BTYPE) == VT_FUNC) {
if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
tcc_error("function without file scope cannot be static");
}
/* if old style function prototype, we accept a
declaration list */
sym = type.ref;
if (sym->c == FUNC_OLD)
func_decl_list(sym);
}
if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
ad.asm_label = asm_label_instr();
/* parse one last attribute list, after asm label */
parse_attribute(&ad);
if (tok == '{')
expect(";");
}
if (ad.a.weak)
type.t |= VT_WEAK;
#ifdef TCC_TARGET_PE
if (ad.a.func_import)
type.t |= VT_IMPORT;
if (ad.a.func_export)
type.t |= VT_EXPORT;
#endif
type.t |= ad.a.visibility << VT_VIS_SHIFT;
if (tok == '{') {
if (l == VT_LOCAL)
tcc_error("cannot use local functions");
if ((type.t & VT_BTYPE) != VT_FUNC)
expect("function definition");
/* reject abstract declarators in function definition */
sym = type.ref;
while ((sym = sym->next) != NULL)
if (!(sym->v & ~SYM_FIELD))
expect("identifier");
/* XXX: cannot do better now: convert extern line to static inline */
if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
sym = sym_find(v);
if (sym) {
Sym *ref;
if ((sym->type.t & VT_BTYPE) != VT_FUNC)
goto func_error1;
ref = sym->type.ref;
if (0 == ref->a.func_proto)
tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
/* use func_call from prototype if not defined */
if (ref->a.func_call != FUNC_CDECL
&& type.ref->a.func_call == FUNC_CDECL)
type.ref->a.func_call = ref->a.func_call;
/* use export from prototype */
if (ref->a.func_export)
type.ref->a.func_export = 1;
/* use static from prototype */
( run in 0.350 second using v1.01-cache-2.11-cpan-f5b5a18a01a )