This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
-fdump-translation-unit-xml
- From: Lorenzo Delana <ldelana at libero dot it>
- To: <gcc at gcc dot gnu dot org>
- Date: Sat, 28 Sep 2002 18:01:45 +0000
- Subject: -fdump-translation-unit-xml
If you try to parse the result to `-fdump-translation-unit' you meet some
problems specially for the question about where a string end, etc..
This problem was addressed in the past by someone in this list...
Someone of you know http://www.gccxml.org, that creates a patch to GCC totally
apart ( not intrusive ), but this patch is actually uncompleted (
eg.templates, etc.. ) and need you to understand a new semantic of nodes...
well, can be simplified and collected respect to the raw translation unit
dump of gcc...
In any case I made a patch to tree.h and tree-dump.c, to let
-fdump-translation-unit-xml to dump the .tu file in XML mode, so you get
something like:
<?xml version='1.0'?>
<!DOCTYPE GXXTranslationUnit SYSTEM "GXXTranslationUnit.dtd">
<GXXTranslationUnit>
<Node index="1" codename="namespace_decl">
<ChildField name="name" value="2"/>
<StringField name="srcp" value="<internal>:0"/>
<ChildField name="dcls" value="3"/>
</Node>
<Node index="2" codename="identifier_node">
<String name="strg" value="::"/>
<Integer name="lngt" value="2"/>
</Node>
<Node index="3" codename="function_decl">
<ChildField name="name" value="4"/>
<ChildField name="type" value="5"/>
<StringField name="srcp" value="t.cxx:27"/>
<ChildField name="chan" value="6"/>
<String value="C"/>
<String value="extern"/>
<ChildField name="body" value="7"/>
</Node>
<Node index="4" codename="identifier_node">
<String name="strg" value="main"/>
<Integer name="lngt" value="4"/>
</Node>
<Node index="5" codename="function_type">
<ChildField name="size" value="8"/>
<Integer name="algn" value="64"/>
<ChildField name="retn" value="9"/>
<ChildField name="prms" value="10"/>
</Node>
<Node index="6" codename="namespace_decl">
<ChildField name="name" value="11"/>
<ChildField name="type" value="12"/>
<StringField name="srcp" value="t.cxx:3"/>
<ChildField name="chan" value="13"/>
<ChildField name="dcls" value="14"/>
</Node>
<Node index="7" codename="compound_stmt">
<Integer name="line" value="32"/>
<ChildField name="body" value="15"/>
<ChildField name="next" value="16"/>
</Node>
<Node index="8" codename="integer_cst">
<ChildField name="type" value="17"/>
<Integer name="low" value="64"/>
</Node>
<Node index="9" codename="integer_type">
<ChildField name="name" value="18"/>
<ChildField name="size" value="19"/>
<Integer name="algn" value="32"/>
<Integer name="prec" value="32"/>
<ChildField name="min" value="20"/>
<ChildField name="max" value="21"/>
</Node>
<Node index="10" codename="tree_list">
<ChildField name="valu" value="12"/>
</Node>
...
<Node index="889" codename="type_decl">
<ChildField name="name" value="890"/>
<ChildField name="type" value="9"/>
<StringField name="srcp" value="<internal>:0"/>
<ChildField name="chan" value="491"/>
</Node>
<Node index="890" codename="identifier_node">
<String name="strg" value="__builtin_ptrdiff_t"/>
<Integer name="lngt" value="19"/>
</Node>
</GXXTranslationUnit>
Instead of:
@1 namespace_decl name: @2 srcp: <internal>:0
dcls: @3
@2 identifier_node strg: :: lngt: 2
@3 function_decl name: @4 type: @5 srcp: t.cxx:27
chan: @6 C extern
body: @7
@4 identifier_node strg: main lngt: 4
@5 function_type size: @8 algn: 64 retn: @9
prms: @10
@6 namespace_decl name: @11 type: @12 srcp: t.cxx:3
chan: @13 dcls: @14
@7 compound_stmt line: 32 body: @15 next: @16
@8 integer_cst type: @17 low : 64
@9 integer_type name: @18 size: @19 algn: 32
prec: 32 min : @20 max : @21
@10 tree_list valu: @12
...
@889 type_decl name: @890 type: @9 srcp: <internal>:0
chan: @491
@890 identifier_node strg: __builtin_ptrdiff_t lngt: 19
---------------------------------
The XML version are longer by simpler to parse...:)
The simple DTD applied is this:
<!ELEMENT GXXTranslationUnit (TUNode)>
<!ELEMENT Node
(ChildField|PointerField|IntegerField|StringField|QualifierField|SourceposField)>
<!ATTLIST Node index CDATA #REQUIRED
codename CDATA #REQUIRED>
<!ELEMENT Field EMPTY>
<!ATTLIST Field name CDATA #IMPLIED
value CDATA #REQUIRED>
<!ELEMENT ChildField (Field)>
<!ELEMENT PointerField (Field)>
<!ELEMENT IntegerField (Field)>
<!ELEMENT StringField (Field)>
---------------------
The DTD struct:
GXXTranslationUnit -->
Node ( index, codename ) -->
Field ( name, value )
Where "Field" can be one of:
"ChildField": states a field where the value means a Node `index'
"PointerField": states a field where the value means a pointer in HEX
"IntegerField": states a field where the value means a signed integer value
"StringField": states a field, when exists name attribute
(eg.dump_string_field), or a simple string keyword (eg.dump_string), like "C"
or "C++" or "operator", etc.. where value represents the string itself
Some final words:
- with this xml output you don't have nothing that the .tu file in XML mode,
without modifications
- the { Child, Pointer, Integer, String }Field, specification let you to know
exactly when a field is an integer or a child, or some other type... For
example may be that in certain case a field "low" is dumped as an integer,
other times are dumped as a child! with this specification no ambiguities are
allowed.
Follow, the patches relative to the GCC-3.2 release version:
==> 1) tree.h:
add this line:
#define TDF_XML (1 << 2 ) /* dump as XML too */
after #define TDF_SLIM ...
==> 2) and tree-dump.c
=== START OF: tree-dump.c-diff ===
--- /usr/src/gcc-3.2/gcc/tree-dump.c 2002-03-16 01:07:54.000000000 +0000
+++ tree-dump.c 2002-09-28 17:58:04.000000000 +0000
@@ -116,11 +116,15 @@
/* If we haven't, add it to the queue. */
index = queue (di, t, flags);
- /* Print the index of the node. */
- dump_maybe_newline (di);
- fprintf (di->stream, "%-4s: ", field);
- di->column += 6;
- dump_index (di, index);
+ if (di->flags == TDF_XML)
+ fprintf (di->stream, " <ChildField name=\"%s\" value=\"%u\"/>\n",
field, index);
+ else {
+ /* Print the index of the node. */
+ dump_maybe_newline (di);
+ fprintf (di->stream, "%-4s: ", field);
+ di->column += 6;
+ dump_index (di, index);
+ }
}
/* Dump the type of T. */
@@ -145,6 +149,7 @@
dump_new_line (di)
dump_info_p di;
{
+ if (di->flags == TDF_XML) return;
fprintf (di->stream, "\n%*s", SOL_COLUMN, "");
di->column = SOL_COLUMN;
}
@@ -157,6 +162,8 @@
{
int extra;
+ if (di->flags == TDF_XML) return;
+
/* See if we need a new line. */
if (di->column > EOL_COLUMN)
dump_new_line (di);
@@ -176,9 +183,14 @@
const char *field;
void *ptr;
{
- dump_maybe_newline (di);
- fprintf (di->stream, "%-4s: %-8lx ", field, (long) ptr);
- di->column += 15;
+ if (di->flags == TDF_XML)
+ fprintf (di->stream, " <Pointer name=\"%s\" value=\"%lx\"/>\n", field,
(long) ptr );
+ else
+ {
+ dump_maybe_newline (di);
+ fprintf (di->stream, "%-4s: %-8lx ", field, (long) ptr);
+ di->column += 15;
+ }
}
/* Dump integer I using FIELD to identify it. */
@@ -189,9 +201,14 @@
const char *field;
int i;
{
- dump_maybe_newline (di);
- fprintf (di->stream, "%-4s: %-7d ", field, i);
- di->column += 14;
+ if (di->flags == TDF_XML)
+ fprintf (di->stream, " <Integer name=\"%s\" value=\"%d\"/>\n", field,
i );
+ else
+ {
+ dump_maybe_newline (di);
+ fprintf (di->stream, "%-4s: %-7d ", field, i);
+ di->column += 14;
+ }
}
/* Dump the string S. */
@@ -201,12 +218,17 @@
dump_info_p di;
const char *string;
{
- dump_maybe_newline (di);
- fprintf (di->stream, "%-13s ", string);
- if (strlen (string) > 13)
- di->column += strlen (string) + 1;
+ if (di->flags == TDF_XML)
+ fprintf (di->stream, " <String value=\"%s\"/>\n", string );
else
- di->column += 14;
+ {
+ dump_maybe_newline (di);
+ fprintf (di->stream, "%-13s ", string);
+ if (strlen (string) > 13)
+ di->column += strlen (string) + 1;
+ else
+ di->column += 14;
+ }
}
/* Dump the string field S. */
@@ -217,12 +239,17 @@
const char *field;
const char *string;
{
- dump_maybe_newline (di);
- fprintf (di->stream, "%-4s: %-7s ", field, string);
- if (strlen (string) > 7)
- di->column += 6 + strlen (string) + 1;
+ if (di->flags == TDF_XML)
+ fprintf (di->stream, " <String name=\"%s\" value=\"%s\"/>\n", field,
string );
else
- di->column += 14;
+ {
+ dump_maybe_newline (di);
+ fprintf (di->stream, "%-4s: %-7s ", field, string);
+ if (strlen (string) > 7)
+ di->column += 6 + strlen (string) + 1;
+ else
+ di->column += 14;
+ }
}
/* Dump information common to statements from STMT. */
@@ -232,7 +259,10 @@
dump_info_p di;
tree t;
{
- dump_int (di, "line", STMT_LINENO (t));
+ if (di->flags == TDF_XML)
+ fprintf (di->stream, " <Integer name=\"line\" value=\"%d\"/>\n",
STMT_LINENO (t));
+ else
+ dump_int (di, "line", STMT_LINENO (t));
}
/* Dump the next statement after STMT. */
@@ -272,17 +302,25 @@
if (!di->queue)
di->queue_end = 0;
dq->next = di->free_list;
- di->free_list = dq;
+ di->free_list = dq;
- /* Print the node index. */
- dump_index (di, index);
+ if (di->flags != TDF_XML)
+ {
+ /* Print the node index. */
+ dump_index (di, index);
+ }
/* And the type of node this is. */
if (dni->binfo_p)
code_name = "binfo";
else
code_name = tree_code_name[(int) TREE_CODE (t)];
- fprintf (di->stream, "%-16s ", code_name);
- di->column = 25;
+ if (di->flags != TDF_XML)
+ {
+ fprintf (di->stream, "%-16s ", code_name);
+ di->column = 25;
+ }
+ else
+ fprintf (di->stream, " <Node index=\"%u\" codename=\"%s\">\n", index,
code_name );
/* Figure out what kind of node this is. */
code = TREE_CODE (t);
@@ -355,10 +393,16 @@
/* Skip the slash. */
++filename;
- dump_maybe_newline (di);
- fprintf (di->stream, "srcp: %s:%-6d ", filename,
- DECL_SOURCE_LINE (t));
- di->column += 6 + strlen (filename) + 8;
+ if (di->flags == TDF_XML)
+ fprintf (di->stream, " <StringField name=\"srcp\"
value=\"%s:%d\"/>\n",
+ filename, DECL_SOURCE_LINE(t));
+ else
+ {
+ dump_maybe_newline (di);
+ fprintf (di->stream, "srcp: %s:%-6d ", filename,
+ DECL_SOURCE_LINE (t));
+ di->column += 6 + strlen (filename) + 8;
+ }
}
/* And any declaration can be compiler-generated. */
if (DECL_ARTIFICIAL (t))
@@ -373,12 +417,20 @@
if (quals != TYPE_UNQUALIFIED)
{
- fprintf (di->stream, "qual: %c%c%c ",
- (quals & TYPE_QUAL_CONST) ? 'c' : ' ',
- (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ',
- (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ');
- di->column += 14;
- }
+ if (di->flags == TDF_XML)
+ fprintf (di->stream, " <StringField name=\"qual\"
value=\"%c%c%c\"/>\n",
+ (quals & TYPE_QUAL_CONST) ? 'c' : ' ',
+ (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ',
+ (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ');
+ else
+ {
+ fprintf (di->stream, "qual: %c%c%c ",
+ (quals & TYPE_QUAL_CONST) ? 'c' : ' ',
+ (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ',
+ (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ');
+ di->column += 14;
+ }
+ }
/* All types have associated declarations. */
dump_child ("name", TYPE_NAME (t));
@@ -649,8 +701,14 @@
break;
case STRING_CST:
- fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
- dump_int (di, "lngt", TREE_STRING_LENGTH (t));
+ if (di->flags == TDF_XML)
+ fprintf (di->stream, " <StringField name=\"strg\"
value=\"%s\"/>\n",
+ TREE_STRING_POINTER (t));
+ else
+ {
+ fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
+ dump_int (di, "lngt", TREE_STRING_LENGTH (t));
+ }
break;
case TRUTH_NOT_EXPR:
@@ -734,8 +792,13 @@
if (dump_flag (di, TDF_ADDRESS, NULL))
dump_pointer (di, "addr", (void *)t);
- /* Terminate the line. */
- fprintf (di->stream, "\n");
+ if (di->flags == TDF_XML)
+ fprintf (di->stream, " </Node>\n");
+ else
+ {
+ /* Terminate the line. */
+ fprintf (di->stream, "\n");
+ }
}
/* Return non-zero if FLAG has been specified for the dump, and NODE
@@ -773,6 +836,12 @@
di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
(splay_tree_delete_value_fn) &free);
+ if ( di.flags == TDF_XML ) {
+ fprintf( stream, "<?xml version='1.0'?>\n" );
+ fprintf( stream, "<!DOCTYPE GXXTranslationUnit SYSTEM
\"GXXTranslationUnit.dtd\">\n" );
+ fprintf( stream, "<GXXTranslationUnit>\n" );
+ }
+
/* Queue up the first node. */
queue (&di, t, DUMP_NONE);
@@ -780,6 +849,11 @@
while (di.queue)
dequeue_and_dump (&di);
+ if ( di.flags == TDF_XML ) {
+ fprintf( stream, "</GXXTranslationUnit>\n" );
+ }
+
+
/* Now, clean up. */
for (dq = di.free_list; dq; dq = next_dq)
{
@@ -822,6 +896,7 @@
{
{"address", TDF_ADDRESS},
{"slim", TDF_SLIM},
+ {"xml", TDF_XML},
{"all", ~0},
{NULL, 0}
};
@@ -838,10 +913,11 @@
{
FILE *stream;
char *name;
-
+
+ printf( "Opening %s for phase %d suffix = %s\n", dump_base_name, phase,
dump_files[phase].suffix );
if (!dump_files[phase].state)
return NULL;
-
+ printf( "Opened %s for phase %d\n", dump_base_name, phase );
name = concat (dump_base_name, dump_files[phase].suffix, NULL);
stream = fopen (name, dump_files[phase].state < 0 ? "w" : "a");
if (!stream)
=== END OF: tree-dump.c-diff ===