Alien-TinyCCx
view release on metacpan or search on metacpan
src/tccexsymtab.c view on Meta::CPAN
enum {
TS_TEST_GET_TOK,
TS_TEST_HAS_DEFINE,
TS_TEST_HAS_STRUCT,
TS_TEST_HAS_IDENTIFIER
};
LIBTCCAPI int tcc_extended_symtab_test(extended_symtab_p symtab, int to_test, const char * name)
{
TokenSym * ts;
/* Get the tokenSym by the given name */
ts = *token_string_hash_get_ref(symtab->tsh, name);
if (ts == NULL) return 0;
/* Perform the requested test */
switch(to_test) {
case TS_TEST_GET_TOK:
return ts->tok;
case TS_TEST_HAS_DEFINE:
return ts->sym_define != NULL;
case TS_TEST_HAS_IDENTIFIER:
return ts->sym_identifier != NULL;
case TS_TEST_HAS_STRUCT:
return ts->sym_struct != NULL;
}
return 0;
}
/*****************************************************************************/
/* Pre-compilation TokenSym Prep */
/*****************************************************************************/
LIBTCCAPI void tcc_prep_tokensym_list(extended_symtab * symtab)
{
int i;
for (i = 0; i < symtab->tok_start_offset; i++)
{
TokenSym * ext_ts = symtab->tokenSym_list[i];
int flagless_tok = ext_ts->tok & ~(SYM_STRUCT | SYM_FIELD | SYM_EXTENDED | SYM_FIRST_ANOM);
TokenSym * local_ts = table_ident[flagless_tok - TOK_IDENT];
/* Skip if we've already copied something for this TokenSym from another
* extended symbol table, since it'll never get looked up in this
* extended symbol table. */
if (local_ts->sym_struct || local_ts->sym_identifier || local_ts->sym_define) continue;
/* Copy */
copy_extended_tokensym(symtab, ext_ts, local_ts);
}
}
/*****************************************************************************/
/* copy extended symbol into local */
/*****************************************************************************/
/* Provide a mechanism for turning the local_stack off and back on outside of
* the current static file scope. */
ST_DATA Sym * local_stack_backup;
void local_stack_off() {
local_stack_backup = local_stack;
local_stack = NULL;
}
void local_stack_on() {
local_stack = local_stack_backup;
}
/* The define token stream is a series of bytes. They are collections of
* integer => data pairs, where the integer indicates the type (and thus size)
* of the data that follows. For example, if we encounter types TOK_PPNUM,
* TOK_STR, or TOK_LSTR, then the next few bytes are a CString struct (mostly
* filled with NULLs) followed by the associated character string. It gets
* complicated, but has only a handful of special cases to handle. The formats
* of the stream are codified in tok_str_add2, which is defined in tccpp.c.
*
* This function returns the length of a tokenstream, including the final
* null. If it is given a target tokenstream, it assumes that the
* contents of the original have already been copied to the target
* using memcpy, in which case it updates the token ids for arbitrary
* tokens (function names, variable names, etc). Using the macro for
* tokenstream_len defined in tccexsymtab.h, proper usage is:
*
* int len = tokenstream_len (stream_to_copy); // implicitly calls tokenstream_copy
* int * new = malloc(len * sizeof(int));
* memcpy(new, stream_to_copy, len * sizeof(int));
* tokenstream_copy(stream_to_copy, new, symtab);
*
* Note that the final symtab pointer is the symtab associated with the
* input stream, not the output stream.
*/
int tokenstream_copy (int * stream, int * to_stream, extended_symtab * symtab)
{
int len;
/* handle dumb user edge cases: either both to_stream and symtab
* are null, or they are both specified. */
if (to_stream == 0) symtab = 0;
if (symtab == 0) to_stream = 0;
len = 0;
while(stream[len] != 0)
{
/* One for the type */
len++;
switch(stream[len-1])
{
case TOK_CINT: case TOK_CUINT: case TOK_CCHAR:
case TOK_LCHAR: case TOK_CFLOAT: case TOK_LINENUM:
len++;
break;
case TOK_PPNUM: case TOK_PPSTR: case TOK_STR: case TOK_LSTR:
{
CString *cstr = (CString *)(stream + len);
len += 1 + (cstr->size + sizeof(int) - 1) / sizeof(int);
/* If copying, then one might naively expect that I
* should set up cstr to be usable for later
* preprocessor expansions. See tok_str_add2 in
* tccpp.c for details. However, the memcpy that was
* presumably performed prior to calling this
* function already did that! So I'm done. */
}
break;
( run in 3.126 seconds using v1.01-cache-2.11-cpan-dd78ea5b424 )