Alien-TinyCCx
view release on metacpan or search on metacpan
src/tests/exsymtab/10-symtab-compare-func-decl-and-def.c view on Meta::CPAN
/*
* Compares the symtab layout for a function declaration and (in a separately
* compiled context) a function definition. There should be only one difference
* between them.
*/
#include "libtcc.h"
#include "tcc.h"
#include "test_setup.h"
#include <stdlib.h>
char definition_code[] = "double foo(int bar, double *baz) { return 0; }\n";
char declaration_code[] = "double foo(int bar, double *baz);\n";
int main(int argc, char **argv)
{
TCCState *s_decl = tcc_new();
SIMPLE_SETUP(s_decl);
/* Indicate that we want the symtab */
tcc_save_extended_symtab(s_decl);
/* Compile */
if (tcc_compile_string(s_decl, declaration_code) == -1) return 1;
/* Get symtab */
extended_symtab_p decl_symtab = tcc_get_extended_symbol_table(s_decl);
/* All done with that compiler, clean up */
tcc_free(s_decl);
pass("Built declaration compiler state's symbol table");
TCCState *s_def = tcc_new();
if (!s_def) {
fprintf(stderr, "Could not create tcc state\n");
exit(1);
}
/* if tcclib.h and libtcc1.a are not installed, where can we find them */
if (argc == 2 && !memcmp(argv[1], "lib_path=",9))
tcc_set_lib_path(s_def, argv[1]+9);
/* MUST BE CALLED before any compilation */
tcc_set_output_type(s_def, TCC_OUTPUT_MEMORY);
/* indicate that we want the symtab */
tcc_save_extended_symtab(s_def);
/* Compile */
if (tcc_compile_string(s_def, definition_code) == -1) return 1;
/* Get the symtab */
extended_symtab_p def_symtab = tcc_get_extended_symbol_table(s_def);
/* All done with that compiler, clean up */
tcc_free(s_def);
pass("Built definition compiler state's symbol table");
/* get the symbol table layouts of the two */
TokenSym * ts = tcc_get_extended_tokensym(decl_symtab, "foo");
if (ts == NULL) {
printf("could not find foo tokensym in declaration symtab\n");
return(1);
}
if (ts->sym_identifier == NULL) {
printf("foo TokenSym in declaration has no sym_identifier\n");
return(1);
}
Sym * foo_decl = ts->sym_identifier;
ts = tcc_get_extended_tokensym(def_symtab, "foo");
if (ts == NULL) {
printf("could not find foo tokensym in definition symtab\n");
return(1);
}
if (ts->sym_identifier == NULL) {
printf("foo TokenSym in definition has no sym_identifier\n");
return(1);
}
Sym * foo_def = ts->sym_identifier;
/* ---- Compare them ---- */
is_i(foo_decl->r, foo_def->r, "foo->r agree");
is_i(foo_decl->c, foo_def->c, "foo->c agree");
is_i(foo_decl->type.t, foo_def->type.t, "foo->type.t agree");
Sym * def_ret = foo_def->type.ref;
Sym * dec_ret = foo_decl->type.ref;
/* This is the only difference. The value 0x10000 indicates "This is just a
* prototype," which means a later definition is allowed. I do not want a
* later redefinition for functions that have been defined in an earlier
* context, so these are allowed (and encouraged) to differ.
*/
is_i(dec_ret->r, 0x11000, "declaration ret->r is 0x11000");
is_i(def_ret->r, 0x1000, "definition ret->r is 0x01000");
is_i(dec_ret->c, def_ret->c, "ret->r agree");
is_i(dec_ret->type.t, def_ret->type.t, "ret->type.t agree");
Sym * def_arg1 = def_ret->next;
( run in 0.493 second using v1.01-cache-2.11-cpan-5b529ec07f3 )