===================================================================
*************** dump_generic_node (pretty_printer *buffe
{
unsigned int quals = TYPE_QUALS (node);
! dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
pp_space (buffer);
pp_string (buffer, str);
{
unsigned int quals = TYPE_QUALS (node);
! dump_generic_node (buffer, TREE_TYPE (node), spc,
! flags & !TDF_VISDEF, false);
pp_space (buffer);
pp_string (buffer, str);
*************** dump_generic_node (pretty_printer *buffe
for (tmp = TREE_TYPE (node); TREE_CODE (tmp) == ARRAY_TYPE;
tmp = TREE_TYPE (tmp))
;
! dump_generic_node (buffer, tmp, spc, flags, false);
/* Print the dimensions. */
for (tmp = node; TREE_CODE (tmp) == ARRAY_TYPE; tmp = TREE_TYPE (tmp))
for (tmp = TREE_TYPE (node); TREE_CODE (tmp) == ARRAY_TYPE;
tmp = TREE_TYPE (tmp))
;
! dump_generic_node (buffer, tmp, spc, flags & !TDF_VISDEF, false);
/* Print the dimensions. */
for (tmp = node; TREE_CODE (tmp) == ARRAY_TYPE; tmp = TREE_TYPE (tmp))
*************** dump_generic_node (pretty_printer *buffe
if (quals & TYPE_QUAL_VOLATILE)
pp_string (buffer, "volatile ");
! /* Print the name of the structure. */
! if (TREE_CODE (node) == RECORD_TYPE)
! pp_string (buffer, "struct ");
! else if (TREE_CODE (node) == UNION_TYPE)
! pp_string (buffer, "union ");
!
! if (TYPE_NAME (node))
! dump_generic_node (buffer, TYPE_NAME (node), spc, flags, false);
! else if (!(flags & TDF_SLIM))
! /* FIXME: If we eliminate the 'else' above and attempt
! to show the fields for named types, we may get stuck
! following a cycle of pointers to structs. The alleged
! self-reference check in print_struct_decl will not detect
! cycles involving more than one pointer or struct type. */
print_struct_decl (buffer, node, spc, flags);
break;
}
if (quals & TYPE_QUAL_VOLATILE)
pp_string (buffer, "volatile ");
! if (flags & TDF_VISDEF)
print_struct_decl (buffer, node, spc, flags);
+ else
+ {
+ /* Print the name of the structure. */
+ if (TREE_CODE (node) == RECORD_TYPE)
+ pp_string (buffer, "struct ");
+ else if (TREE_CODE (node) == UNION_TYPE)
+ pp_string (buffer, "union ");
+ if (TYPE_NAME (node))
+ dump_generic_node (buffer, TYPE_NAME (node), spc, flags, false);
+ else if (!(flags & TDF_SLIM))
+ /* FIXME: If we eliminate the 'else' above and attempt
+ to show the fields for named types, we may get stuck
+ following a cycle of pointers to structs. The alleged
+ self-reference check in print_struct_decl will not detect
+ cycles involving more than one pointer or struct type. */
+ print_struct_decl (buffer, node, spc, flags);
+ }
break;
}
*************** dump_generic_node (pretty_printer *buffe
return spc;
}
! /* Print the declaration of a variable. */
void
print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
{
! INDENT (spc);
! if (TREE_CODE (t) == TYPE_DECL)
! pp_string (buffer, "typedef ");
if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL) && DECL_REGISTER (t))
pp_string (buffer, "register ");
if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
pp_string (buffer, "extern ");
! else if (TREE_STATIC (t))
pp_string (buffer, "static ");
/* Print the type and name. */
return spc;
}
! /* Print a declaration. */
void
print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
{
! /* When printing visible definitions, do not print artificial types,
! unless the artifical typedef
! is actually the implicit C++ typedef for a struct,
! in which case do print the struct. */
! if ((flags & TDF_VISDEF)
! && DECL_ARTIFICIAL (t)
! && !(TREE_CODE (t) == TYPE_DECL && DECL_LANG_FLAG_2 (t)))
! /* FIXME pph: DECL_IMPLICIT_TYPEDEF_P (t) from cp/cp-tree.h */
! return;
! INDENT (spc);
if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL) && DECL_REGISTER (t))
pp_string (buffer, "register ");
if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
pp_string (buffer, "extern ");
! else if (TREE_STATIC (t) && !TREE_PUBLIC (t))
pp_string (buffer, "static ");
/* Print the type and name. */
*************** print_declaration (pretty_printer *buffe
dump_decl_name (buffer, t, flags);
dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
}
+ else if (TREE_CODE (t) == TYPE_DECL)
+ {
+ if ((flags & TDF_VISDEF) && DECL_ARTIFICIAL (t))
+ {
+ const char* id = IDENTIFIER_POINTER (DECL_NAME (t));
+ if (id[0] != '.')
+ {
+ /* Print type's value. */
+ dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
+ }
+ }
+ else
+ {
+ /* Print type declaration. */
+ dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
+ /* Print variable's name. */
+ pp_space (buffer);
+ dump_generic_node (buffer, t, spc, flags, false);
+ }
+ }
else
{
/* Print type declaration. */
*************** print_declaration (pretty_printer *buffe
static void
print_struct_decl (pretty_printer *buffer, const_tree node, int spc, int flags)
{
/* Print the name of the structure. */
! if (TYPE_NAME (node))
{
- INDENT (spc);
if (TREE_CODE (node) == RECORD_TYPE)
pp_string (buffer, "struct ");
else if ((TREE_CODE (node) == UNION_TYPE
|| TREE_CODE (node) == QUAL_UNION_TYPE))
pp_string (buffer, "union ");
! dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
}
/* Print the contents of the structure. */
static void
print_struct_decl (pretty_printer *buffer, const_tree node, int spc, int flags)
{
+ tree name = TYPE_NAME (node);
/* Print the name of the structure. */
! if (name)
{
if (TREE_CODE (node) == RECORD_TYPE)
pp_string (buffer, "struct ");
else if ((TREE_CODE (node) == UNION_TYPE
|| TREE_CODE (node) == QUAL_UNION_TYPE))
pp_string (buffer, "union ");
! if ((flags & TDF_VISDEF) && DECL_ARTIFICIAL (name))
! {
! const char* id = IDENTIFIER_POINTER (DECL_NAME (name));
! if (id[0] != '.')
! dump_generic_node (buffer, name, spc, 0, false);
! }
! else
! dump_generic_node (buffer, name, spc, 0, false);
}
/* Print the contents of the structure. */
*************** print_struct_decl (pretty_printer *buffe
tmp = TYPE_FIELDS (node);
while (tmp)
{
! /* Avoid to print recursively the structure. */
! /* FIXME : Not implemented correctly...,
! what about the case when we have a cycle in the contain graph? ...
! Maybe this could be solved by looking at the scope in which the
! structure was declared. */
! if (TREE_TYPE (tmp) != node
! && (TREE_CODE (TREE_TYPE (tmp)) != POINTER_TYPE
! || TREE_TYPE (TREE_TYPE (tmp)) != node))
{
print_declaration (buffer, tmp, spc+2, flags);
pp_newline (buffer);
}
tmp = DECL_CHAIN (tmp);
}
}
tmp = TYPE_FIELDS (node);
while (tmp)
{
! if (flags & TDF_VISDEF)
{
print_declaration (buffer, tmp, spc+2, flags);
pp_newline (buffer);
}
+ else
+ {
+ /* Avoid to print recursively the structure. */
+ /* FIXME : Not implemented correctly...,
+ what about the case when we have a cycle in the contain graph?
+ ...
+ Maybe this could be solved by looking at the scope in which the
+ structure was declared. */
+ if (TREE_TYPE (tmp) != node
+ && (TREE_CODE (TREE_TYPE (tmp)) != POINTER_TYPE
+ || TREE_TYPE (TREE_TYPE (tmp)) != node))
+ {
+ print_declaration (buffer, tmp, spc+2, flags);
+ pp_newline (buffer);
+ }
+ }
tmp = DECL_CHAIN (tmp);
}
}
===================================================================
*************** fpph-decls=
C++ Joined RejectNegative UInteger Var(flag_pph_decls)
-fpph-decls=N Enable declaration identifier output at level N from PPH support
+ fpph-fmt=
+ C++ Joined RejectNegative UInteger Var(flag_pph_fmt)
+ -fpph-fmt=N Output format is (0) normal (1) pretty summary (2) dump
+
fpph-logfile=
C++ Joined RejectNegative Var(flag_pph_logfile)
-fpph-logfile=<file-name> Emit PPH debug information to <file-name>
===================================================================
*************** enum tree_dump_index
#define TDF_ALIAS (1 << 21) /* display alias information */
#define TDF_ENUMERATE_LOCALS (1 << 22) /* Enumerate locals by uid. */
#define TDF_CSELIB (1 << 23) /* Dump cselib details. */
+ #define TDF_VISDEF (1 << 24) /* Dump visible definitions. */
/* In tree-dump.c */
===================================================================
***************
! #include <stdlib.h>
! #include <stdio.h>
! #include <math.h>
! #include <string.h>
static unsigned long long MAX_ITEMS = 10000;
! #include <stdlib.h> // {dg-error fails macro validation "" { xfail *-*-* } }
! #include <stdio.h> // {dg-error fails macro validation "" { xfail *-*-* } }
! #include <math.h> // {dg-error fails macro validation "" { xfail *-*-* } }
! #include <string.h> // {dg-error fails macro validation "" { xfail *-*-* } }
! // { dg-excess-errors "In file included from" { xfail *-*-* } }
! // { dg-excess-errors "assembly comparison" { xfail *-*-* } }
static unsigned long long MAX_ITEMS = 10000;
===================================================================
***************
#include "c2dupguard1.h"
! #include "c2dupguard2.h"
! // { dg-error "duplicate PPH guard header" "" { xfail *-*-* } }
int foo() { return x; }
#include "c2dupguard1.h"
! #include "c2dupguard2.h" // { dg-error "fails macro validation" "" { xfail *-*-* } }
int foo() { return x; }
===================================================================
***************
#include "c1chained1.h"
! #include "c1chained2.h"
! // { dg-error "Preprocessor state inconsistent for PPH" "" { xfail *-*-* } }
int x = TWO;
#include "c1chained1.h"
! #include "c1chained2.h" // { dg-error "fails macro validation" }
int x = TWO;
===================================================================
***************
! #include <stdlib.h>
int f(const char* s)
{
return atoi(s);
! #include <stdlib.h> // { dg-error "fails macro validation" "" { xfail *-*-* } }
! // { dg-excess-errors "In file included from" { xfail *-*-* } }
! // { dg-excess-errors "regular compilation failed" { xfail *-*-* } }
!
int f(const char* s)
{
return atoi(s);
===================================================================
*************** pth_write_header (pth_image *image, FILE
gcc_assert (nbytes == pth_header_len ());
}
+
+ /* Pretty print the previous macro definitions in the table of IDENTIFIERS to
+ the STREAM. */
+
+ static void
+ pph_print_macro_defs_before (FILE *stream, cpp_idents_used *identifiers)
+ {
+ unsigned int idx;
+
+ for (idx = 0; idx < identifiers->num_entries; ++idx)
+ {
+ cpp_ident_use *entry = identifiers->entries + idx;
+ const char *ident = entry->ident_str;
+ const char *before = entry->before_str;
+
+ if (before)
+ fprintf (stream, "#define %s%s\n", ident, before);
+ else
+ fprintf (stream, "#undef %s\n", ident);
+ }
+ }
+
+
+ /* Pretty print the subsequent macro definitions in the table of IDENTIFIERS to
+ the STREAM. */
+
+ static void
+ pph_print_macro_defs_after (FILE *stream, cpp_idents_used *identifiers)
+ {
+ unsigned int idx;
+
+ for (idx = 0; idx < identifiers->num_entries; ++idx)
+ {
+ cpp_ident_use *entry = identifiers->entries + idx;
+ const char *ident = entry->ident_str;
+ const char *before = entry->before_str;
+ const char *after = entry->after_str;
+
+ if (before != after)
+ {
+ if (after && (!before || strcmp (after, before) != 0))
+ fprintf (stream, "#define %s%s\n", ident, after);
+ else if (before)
+ fprintf (stream, "#undef %s\n", ident);
+ }
+ }
+ }
+
+
/* Dump a table of IDENTIFIERS to the STREAM. */
static void
*************** pth_file_change (cpp_reader *reader, con
/* Write PPH output file. */
static void
! write_pph_output (void)
{
FILE *stream;
if (flag_pph_debug >= 1)
fprintf (pph_logfile, "PPH: Writing %s\n", pph_out_file);
/* Write PPH output file. */
+ typedef void (*write_pph_format)(FILE *stream, tree decl, int flags);
+
+ static void
+ write_pph_namespace (FILE *stream, tree decl, write_pph_format fmt, int flags);
+
+
+ /* Write symbol to PPH output file like C. */
+
+ static void
+ write_pph_print (FILE *stream, tree decl, int flags)
+ {
+ print_generic_decl (stream, decl, flags | TDF_VISDEF);
+ fprintf (stream, "\n");
+ }
+
+
+ /* Write symbol to PPH output file as a dump. */
+
+ static void
+ write_pph_dump (FILE *stream, tree decl, int flags)
+ {
+ dump_node (decl, flags, stream);
+ }
+
+
+ /* Write symbol to PPH output file. */
+
+ static void
+ write_pph_symbol (FILE *stream, tree decl, write_pph_format fmt, int flags)
+ {
+ if (TREE_CODE (decl) == NAMESPACE_DECL)
+ write_pph_namespace (stream, decl, fmt, flags);
+ else if (!DECL_IS_BUILTIN (decl))
+ fmt (stream, decl, flags);
+ }
+
+
+ /* Write namespace to PPH output file. */
+
+ typedef void (*declvisitor)(FILE *, tree, write_pph_format, int);
+
+ static void
+ write_pph_namespace_1 (declvisitor vtor, FILE *stream, tree decl,
+ write_pph_format fmt, int flags)
+ {
+ tree prior = TREE_CHAIN (decl);
+ if (prior)
+ write_pph_namespace_1 (vtor, stream, prior, fmt, flags);
+ vtor (stream, decl, fmt, flags);
+ }
+
+ static void
+ write_pph_namespace (FILE *stream, tree decl, write_pph_format fmt, int flags)
+ {
+ struct cp_binding_level *level = NAMESPACE_LEVEL (decl);
+ decl = level->namespaces;
+ if (decl)
+ write_pph_namespace_1 (write_pph_namespace, stream, decl, fmt, flags);
+ decl = level->names;
+ if (decl)
+ write_pph_namespace_1 (write_pph_symbol, stream, decl, fmt, flags);
+ }
+
+
+ /* Write PPH output symbols and IDENTS_USED to STREAM as an object. */
+
+ static void
+ write_pph_file_object (FILE *stream, cpp_idents_used *idents_used)
+ {
+ int flags = 0;
+ pth_save_identifiers (idents_used, stream);
+ fprintf (stream, "\n====\n");
+ /* FIX pph: Wrong format for writing decls. */
+ write_pph_namespace (stream, global_namespace, write_pph_print, flags);
+ }
+
+
+ /* Write PPH output symbols and IDENTS_USED to STREAM as a pretty summary. */
+
+ static void
+ write_pph_file_summary (FILE *stream, cpp_idents_used *idents_used)
+ {
+ int flags = 0;
+ pph_print_macro_defs_before (stream, idents_used);
+ write_pph_namespace (stream, global_namespace, write_pph_print, flags);
+ pph_print_macro_defs_after (stream, idents_used);
+ }
+
+
+ /* Write PPH output symbols and IDENTS_USED to STREAM as a textual dump. */
+
+ static void
+ write_pph_file_dump (FILE *stream, cpp_idents_used *idents_used)
+ {
+ int flags = TDF_UID | TDF_LINENO;
+ pth_dump_identifiers (stream, idents_used);
+ write_pph_namespace (stream, global_namespace, write_pph_dump, flags);
+ }
+
+
+ /* Write PPH output file. */
+
static void
! write_pph_file (void)
{
FILE *stream;
+ cpp_idents_used idents_used;
if (flag_pph_debug >= 1)
fprintf (pph_logfile, "PPH: Writing %s\n", pph_out_file);
*************** write_pph_output (void)
if (!stream)
fatal_error ("Cannot open PPH file for writing: %s: %m", pph_out_file);
! fprintf (stream, "%s\n", pph_out_file);
fclose (stream);
}
/* Read PPH file. */
static void
! read_pph_file (const char* filename)
{
FILE *stream;
- char *line;
- char *eol;
- char linebuf[2*MAXPATHLEN];
if (flag_pph_debug >= 1)
fprintf (pph_logfile, "PPH: Reading %s\n", filename);
if (!stream)
fatal_error ("Cannot open PPH file for writing: %s: %m", pph_out_file);
! idents_used = cpp_lt_capture (parse_in);
!
! if (flag_pph_fmt == 0)
! write_pph_file_object (stream, &idents_used);
! else if (flag_pph_fmt == 1)
! write_pph_file_summary (stream, &idents_used);
! else if (flag_pph_fmt == 2)
! write_pph_file_dump (stream, &idents_used);
! else
! error ("unrecognized -fpph-fmt value: %d", flag_pph_fmt);
!
! /*FIX pph: double free or corruption: cpp_lt_idents_destroy (&idents_used); */
fclose (stream);
}
+
+ /* Wrap a macro DEFINITION for printing in an error. */
+
+ static char *
+ wrap_macro_def (const char *definition)
+ {
+ char *string;
+ if (definition)
+ {
+ size_t length;
+ length = strlen (definition);
+ string = (char *) xmalloc (length+3);
+ string[0] = '"';
+ strcpy (string + 1, definition);
+ string[length + 1] = '"';
+ string[length + 2] = '\0';
+ }
+ else
+ string = xstrdup ("undefined");
+ return string;
+ }
+
+
+ /* Report a macro validation error in FILENAME for macro IDENT,
+ which should have the value EXPECTED but actually had the value FOUND. */
+
+ static void
+ report_validation_error (const char *filename,
+ const char *ident, const char *found,
+ const char *before, const char *after)
+ {
+ char* quote_found = wrap_macro_def (found);
+ char* quote_before = wrap_macro_def (before);
+ char* quote_after = wrap_macro_def (after);
+ error ("PPH file %s fails macro validation, "
+ "%s is %s and should be %s or %s\n",
+ filename, ident, quote_found, quote_before, quote_after);
+ free (quote_found);
+ free (quote_before);
+ free (quote_after);
+ }
+
+
+ /* Read PPH FILENAME from STREAM as an object. */
+
+ static void
+ read_pph_file_object (const char *filename, FILE *stream)
+ {
+ bool verified;
+ cpp_ident_use *bad_use;
+ const char *cur_def;
+ cpp_idents_used idents_used;
+
+ pth_load_identifiers (&idents_used, stream);
+ /*FIXME pph: This validation is weak. */
+ verified = cpp_lt_verify_1 (parse_in, &idents_used, &bad_use, &cur_def, true);
+ if (!verified)
+ report_validation_error (filename, bad_use->ident_str, cur_def,
+ bad_use->before_str, bad_use->after_str);
+ /* FIX pph: We cannot replay the macro definitions
+ as long as we are still reading the actual file.
+ cpp_lt_replay (parse_in, &idents_used);
+ */
+
+ /* FIX pph: Also read decls. */
+ }
+
+
/* Read PPH file. */
static void
! read_pph_file (const char *filename)
{
FILE *stream;
if (flag_pph_debug >= 1)
fprintf (pph_logfile, "PPH: Reading %s\n", filename);
*************** read_pph_file (const char* filename)
if (!stream)
fatal_error ("Cannot open PPH file for reading: %s: %m", filename);
! line = fgets (linebuf, sizeof linebuf, stream);
! if (line == NULL)
! fatal_error ("No line in PPH file %s: ", filename);
!
! eol = strchr (line, '\n');
! *eol = '\0';
!
! if (strcmp (filename, line) != 0)
! fatal_error ("Wrong content in PPH file %s: ", filename);
fclose (stream);
}
if (!stream)
fatal_error ("Cannot open PPH file for reading: %s: %m", filename);
! if (flag_pph_fmt == 0)
! read_pph_file_object (filename, stream);
fclose (stream);
}
*************** pth_include_handler (cpp_reader *reader
/* Record a #include or #include_next for PPH. */
static void
! pph_include_handler (cpp_reader *reader ATTRIBUTE_UNUSED,
location_t loc ATTRIBUTE_UNUSED,
const unsigned char *dname,
const char *name,
/* Record a #include or #include_next for PPH. */
static void
! pph_include_handler (cpp_reader *reader /*FIXME pph: ATTRIBUTE_UNUSED */,
location_t loc ATTRIBUTE_UNUSED,
const unsigned char *dname,
const char *name,
*************** pph_include_handler (cpp_reader *reader
}
pph_file = query_pph_include_map (name);
! if (pph_file != NULL)
read_pph_file (pph_file);
}
}
pph_file = query_pph_include_map (name);
! if (pph_file != NULL && ! cpp_included_before (reader, name, input_location))
read_pph_file (pph_file);
}
*************** pph_set_dependencies_for (tree t, VEC(tr
}
#define PPH_ARTIFICIAL(t) \
! (DECL_ARTIFICIAL (t) \
! && !(TREE_CODE (t) == TYPE_DECL && DECL_IMPLICIT_TYPEDEF_P (t)))
static bool
is_namespace (tree container)
}
#define PPH_ARTIFICIAL(t) \
! (DECL_ARTIFICIAL (t) && !DECL_IMPLICIT_TYPEDEF_P (t))
static bool
is_namespace (tree container)
*************** void
pph_init (void)
{
cpp_callbacks *cb;
+ cpp_lookaside *table;
if (flag_pph_logfile)
{
*************** pph_init (void)
cb = cpp_get_callbacks (parse_in);
cb->include = pph_include_handler;
+ /* FIXME pph: Use file change instead.
+ state->file_change_prev = cb->file_change;
+ cb->file_change = pph_file_change;
+ */
+
+ table = cpp_lt_exchange (parse_in,
+ cpp_lt_create (cpp_lt_order, flag_pth_debug));
+ gcc_assert (table == NULL);
}
*************** pph_finish (void)
{
const char *offending_file = cpp_main_missing_guard (parse_in);
if (offending_file == NULL)
! write_pph_output ();
else
error ("header lacks guard for PPH: %s", offending_file);
}
{
const char *offending_file = cpp_main_missing_guard (parse_in);
if (offending_file == NULL)
! write_pph_file ();
else
error ("header lacks guard for PPH: %s", offending_file);
}
===================================================================
*************** lt_query_macro (cpp_reader *reader, cpp_
{
static char *string = 0;
static unsigned int space = 0;
! unsigned int front, back, needed;
const char *value;
value = (const char *)_cpp_builtin_macro_text (reader, cpp_node);
- front = strlen (str);
back = strlen (value);
! needed = front + 1 + back + 1;
if (space < needed)
{
if (string != NULL)
{
static char *string = 0;
static unsigned int space = 0;
! unsigned int back, needed;
const char *value;
value = (const char *)_cpp_builtin_macro_text (reader, cpp_node);
back = strlen (value);
! needed = 1 + back + 1;
if (space < needed)
{
if (string != NULL)
*************** lt_query_macro (cpp_reader *reader, cpp_
string = XCNEWVEC (char, needed);
space = needed;
}
! strcpy (string, str);
! string[front] = '=';
! strcpy (string + front + 1, value);
!
definition = string;
}
}
else
! definition = (const char *) cpp_macro_definition (reader, cpp_node);
if (reader->lookaside_table->pth_debug_level >= 3)
fprintf (stderr, "PTH: macro %s is %s\n",
string = XCNEWVEC (char, needed);
space = needed;
}
! string[0] = ' ';
! strcpy (string + 1, value);
definition = string;
}
}
else
! {
! char c;
! definition = (const char *) cpp_macro_definition (reader, cpp_node);
! /* Skip over the macro name within the definition. */
! c = *definition;
! while ( ('0' <= c && c <= '9')
! || ('A' <= c && c <= 'Z')
! || ('a' <= c && c <= 'z')
! || (c == '_'))
! {
! c = *++definition;
! }
! }
if (reader->lookaside_table->pth_debug_level >= 3)
fprintf (stderr, "PTH: macro %s is %s\n",
*************** cpp_lt_capture (cpp_reader *reader)
inconsistency. A null means 'not a macro'. */
bool
! cpp_lt_verify (cpp_reader *reader, cpp_idents_used* identifiers,
! cpp_ident_use **bad_use, const char **cur_def)
{
unsigned int i;
unsigned int num_entries = identifiers->num_entries;
inconsistency. A null means 'not a macro'. */
bool
! cpp_lt_verify_1 (cpp_reader *reader, cpp_idents_used* identifiers,
! cpp_ident_use **bad_use, const char **cur_def,
! int permit_postdef)
{
unsigned int i;
unsigned int num_entries = identifiers->num_entries;
*************** cpp_lt_verify (cpp_reader *reader, cpp_i
/* It was not saved as a macro. */
if (cpp_node->type == NT_MACRO)
{
! /* But it is a macro now! */
! *bad_use = entry;
! *cur_def = (const char*) lt_query_macro (reader, cpp_node);
! goto fail;
}
/* Otherwise, both agree it is not a macro. */
}
/* It was not saved as a macro. */
if (cpp_node->type == NT_MACRO)
{
! /* But it is a macro now! */
! const char *definition;
! definition = (const char*) lt_query_macro (reader, cpp_node);
! if (permit_postdef)
! {
! /* Check to see if the current value is the after value. */
! unsigned int after_len = entry->after_len;
! /* strlen is required to avoid the prefix problem. */
! if (definition == NULL
! || after_len != strlen (definition)
! || memcmp (definition, entry->after_str, after_len) != 0)
! {
! /* They do not have the same value. */
! *bad_use = entry;
! *cur_def = definition;
! goto fail;
! }
! }
! else
! {
! *bad_use = entry;
! *cur_def = definition;
! goto fail;
! }
}
/* Otherwise, both agree it is not a macro. */
}
*************** fail:
return false;
}
/* Produce the macro definition syntax NEEDED by cpp_define from
the syntax GIVEN by cpp_macro_definition. */
static void
! cpp_lt_define_syntax (char *needed, const char *given)
{
char c;
- c = *given++;
-
/* Copy over macro identifier. */
! while ( ('0' <= c && c <= '9')
! || ('A' <= c && c <= 'Z')
! || ('a' <= c && c <= 'z')
! || (c == '_'))
{
*needed++ = c;
! c = *given++;
}
if (c == '(')
{
/* Copy over parameter list. */
return false;
}
+ bool
+ cpp_lt_verify (cpp_reader *reader, cpp_idents_used* identifiers,
+ cpp_ident_use **bad_use, const char **cur_def)
+ {
+ return cpp_lt_verify_1 (reader, identifiers, bad_use, cur_def, false);
+ }
+
/* Produce the macro definition syntax NEEDED by cpp_define from
the syntax GIVEN by cpp_macro_definition. */
static void
! cpp_lt_define_syntax (char *needed, const char *ident, const char *given)
{
char c;
/* Copy over macro identifier. */
! c = *ident++;
! while (c != '\0')
{
*needed++ = c;
! c = *ident++;
}
+ /* Copy over macro definition. */
+ c = *given++;
if (c == '(')
{
/* Copy over parameter list. */
*************** cpp_lt_define_syntax (char *needed, cons
/* Replace definition space by assignment. */
/* (c == ' ') */
*needed++ = '=';
- c = *given++;
! /* Copy over macro identifier. */
while (c != '\0')
{
*needed++ = c;
/* Replace definition space by assignment. */
/* (c == ' ') */
*needed++ = '=';
! /* Copy over macro value. */
! c = *given++;
while (c != '\0')
{
*needed++ = c;
*************** cpp_lt_replay (cpp_reader *reader, cpp_i
{
if (after_str != NULL)
{
! cpp_lt_define_syntax (buffer, after_str);
cpp_define (reader, buffer);
}
/* else consistently not macros */
{
if (after_str != NULL)
{
! cpp_lt_define_syntax (buffer, ident_str, after_str);
cpp_define (reader, buffer);
}
/* else consistently not macros */
*************** cpp_lt_replay (cpp_reader *reader, cpp_i
else if (strcmp (before_str, after_str) != 0)
{
cpp_undef (reader, ident_str);
! cpp_lt_define_syntax (buffer, after_str);
cpp_define (reader, buffer);
}
/* else macro with the same definition */
else if (strcmp (before_str, after_str) != 0)
{
cpp_undef (reader, ident_str);
! cpp_lt_define_syntax (buffer, ident_str, after_str);
cpp_define (reader, buffer);
}
/* else macro with the same definition */
*************** void
cpp_lt_idents_destroy (cpp_idents_used *identifiers)
{
obstack_free (identifiers->strings, NULL);
! XDELETEVEC (identifiers);
}
/* Mappings from hash to index. */
cpp_lt_idents_destroy (cpp_idents_used *identifiers)
{
obstack_free (identifiers->strings, NULL);
! XDELETEVEC (identifiers->entries);
}
/* Mappings from hash to index. */
===================================================================
*************** cpp_lt_capture (struct cpp_reader *reade
If not, set BAD_USE and CUR_DEF to indicate the first
inconsistency. A null means 'not a macro'. */
bool
+ cpp_lt_verify_1 (struct cpp_reader *reader, cpp_idents_used* identifiers,
+ cpp_ident_use **bad_use, const char **cur_def,
+ int permit_postdef);
+ bool
cpp_lt_verify (struct cpp_reader *reader, cpp_idents_used* identifiers,
cpp_ident_use **bad_use, const char **cur_def);