GCC/cpplib/ cpp create definition

This function reads and processes the macro.

/* Parse a macro and save its expansion. Returns nonzero on success. */

bool

_cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)

{

cpp_macro *macro;

unsigned int i;

bool ok;

if (pfile->hash_table->alloc_subobject)

macro = (cpp_macro *) pfile->hash_table->alloc_subobject

(sizeof (cpp_macro));

else

macro = (cpp_macro *) _cpp_aligned_alloc (pfile, sizeof (cpp_macro));

macro->line = pfile->directive_line;

macro->params = 0;

macro->paramc = 0;

macro->variadic = 0;

macro->used = !CPP_OPTION (pfile, warn_unused_macros);

macro->count = 0;

macro->fun_like = 0;

macro->extra_tokens = 0;

/* To suppress some diagnostics. */

macro->syshdr = pfile->buffer && pfile->buffer->sysp != 0;

if (CPP_OPTION (pfile, traditional))

ok = _cpp_create_trad_definition (pfile, macro);

else

{

ok = create_iso_definition (pfile, macro);

/* We set the type for SEEN_EOL in directives.c.

Longer term we should lex the whole line before coming here,

and just copy the expansion. */

/* Stop the lexer accepting __VA_ARGS__. */

pfile->state.va_args_ok = 0;

}

/* Clear the fast argument lookup indices. */

for (i = macro->paramc; i-- > 0; )

{

struct cpp_hashnode *node = macro->params[i];

node->flags &= ~ NODE_MACRO_ARG;

node->value = ((union _cpp_hashnode_value *) pfile->macro_buffer)[i];

}

if (!ok)

return ok;

if (node->type == NT_MACRO)

{

if (CPP_OPTION (pfile, warn_unused_macros))

_cpp_warn_if_unused_macro (pfile, node, NULL);

if (warn_of_redefinition (pfile, node, macro))

{

const int reason = (node->flags & NODE_BUILTIN)

? CPP_W_BUILTIN_MACRO_REDEFINED : CPP_W_NONE;

bool warned;

warned = cpp_pedwarning_with_line (pfile, reason,

pfile->directive_line, 0,

"\"%s\" redefined",

NODE_NAME (node));

if (warned && node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))

cpp_error_with_line (pfile, CPP_DL_NOTE,

node->value.macro->line, 0,

"this is the location of the previous definition");

}

}

if (node->type != NT_VOID)

_cpp_free_definition (node);

/* Enter definition in hash table. */

node->type = NT_MACRO;

node->value.macro = macro;

if (! ustrncmp (NODE_NAME (node), DSC ("__STDC_"))

&& ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_FORMAT_MACROS")

/* __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS are mentioned

in the C standard, as something that one must use in C++.

However DR#593 indicates that these aren't actually mentioned

in the C++ standard. We special-case them anyway. */

&& ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_LIMIT_MACROS")

&& ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_CONSTANT_MACROS"))

node->flags |= NODE_WARN;

/* If user defines one of the conditional macros, remove the

conditional flag */

node->flags &= ~NODE_CONDITIONAL;

return ok;

}

Related Mails

 * http://gcc.gnu.org/ml/gcc-patches/2006-12/msg01848.html