aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>1999-08-03 01:37:47 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1999-08-03 01:37:47 +0000
commitf71f87f9ebc585a5092659aadc45ab2f12921a2d (patch)
treee60e4eb12e074384984174f31e71d89fb02af12b
parent246833ac171aa132fee598a93a86a819c6eaf4f4 (diff)
downloadgcc-f71f87f9ebc585a5092659aadc45ab2f12921a2d.zip
gcc-f71f87f9ebc585a5092659aadc45ab2f12921a2d.tar.gz
gcc-f71f87f9ebc585a5092659aadc45ab2f12921a2d.tar.bz2
invoke.texi (-fdump-translation-unit): New option.
* invoke.texi (-fdump-translation-unit): New option. * Make-lang.in (CXX_SRCS): Add dump.c. * Makefile.in (CXX_OBJS): Add dump.o. (dump.o): New target. * cp-tree.h (DECL_CONV_FN_P): Document. (DECL_OVERLOADED_OPERATOR_P): New function. (TYPE_PTRMEM_CLASS_TYPE): New macro. (TYPE_PTRMEM_POINTED_TO_TYPE): Likewise. (PTRMEM_CST_CLASS): Use TYPE_PTRMEM_CLASS_TYPE. (ASM_VOLATILE_P): New macro. (STMT_LINENO): Likewise. (cp_namespace_decls): New function. (dump_node_to_file): New function. * decl.c (cp_namespace_decls): New function. (walk_namespaces_r): Use it. (wrapup_globals_for_namespace): Likewise. * decl2.c (flag_dump_translation_unit): New variable. (lang_decode_option): Handle -fdump-translation-unit. (finish_file): If flag_dump_translation_unit is set, dump the translation unit. * dump.c: New file. * lang-options.h: Add -fdump-translation-unit. * pt.c (tsubst_template_parms): Robustify. (tsubst_decl): Use DECL_OVERLOADED_OPERATOR_P. (tsubst_expr): Use STMT_LINENO. * semantics.c (finish_asm_stmt): Eliminate duplicate code. Check for invalid cv-qualifiers even while building templates. From-SVN: r28434
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/cp/ChangeLog29
-rw-r--r--gcc/cp/Make-lang.in3
-rw-r--r--gcc/cp/Makefile.in4
-rw-r--r--gcc/cp/cp-tree.h38
-rw-r--r--gcc/cp/decl.c13
-rw-r--r--gcc/cp/decl2.c17
-rw-r--r--gcc/cp/dump.c861
-rw-r--r--gcc/cp/lang-options.h1
-rw-r--r--gcc/cp/pt.c38
-rw-r--r--gcc/cp/semantics.c25
-rw-r--r--gcc/invoke.texi8
12 files changed, 995 insertions, 46 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 58d47e3..6baa333 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,7 @@
+Mon Aug 2 18:29:32 1999 Mark Mitchell <mark@codesourcery.com>
+
+ * invoke.texi (-fdump-translation-unit): New option.
+
Mon Aug 2 17:10:24 1999 Mark Mitchell <mark@codesourcery.com>
* toplev.h (errorcount): Declare.
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 759442ac..886401a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,32 @@
+1999-08-02 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (CXX_SRCS): Add dump.c.
+ * Makefile.in (CXX_OBJS): Add dump.o.
+ (dump.o): New target.
+ * cp-tree.h (DECL_CONV_FN_P): Document.
+ (DECL_OVERLOADED_OPERATOR_P): New function.
+ (TYPE_PTRMEM_CLASS_TYPE): New macro.
+ (TYPE_PTRMEM_POINTED_TO_TYPE): Likewise.
+ (PTRMEM_CST_CLASS): Use TYPE_PTRMEM_CLASS_TYPE.
+ (ASM_VOLATILE_P): New macro.
+ (STMT_LINENO): Likewise.
+ (cp_namespace_decls): New function.
+ (dump_node_to_file): New function.
+ * decl.c (cp_namespace_decls): New function.
+ (walk_namespaces_r): Use it.
+ (wrapup_globals_for_namespace): Likewise.
+ * decl2.c (flag_dump_translation_unit): New variable.
+ (lang_decode_option): Handle -fdump-translation-unit.
+ (finish_file): If flag_dump_translation_unit is set, dump the
+ translation unit.
+ * dump.c: New file.
+ * lang-options.h: Add -fdump-translation-unit.
+ * pt.c (tsubst_template_parms): Robustify.
+ (tsubst_decl): Use DECL_OVERLOADED_OPERATOR_P.
+ (tsubst_expr): Use STMT_LINENO.
+ * semantics.c (finish_asm_stmt): Eliminate duplicate code. Check
+ for invalid cv-qualifiers even while building templates.
+
1999-08-02 Richard Henderson <rth@cygnus.com>
* call.c: Include defaults.h instead of expr.h.
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 72795da..2e681b8 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -117,7 +117,8 @@ CXX_SRCS = $(srcdir)/cp/call.c $(srcdir)/cp/decl2.c \
$(srcdir)/cp/search.c $(srcdir)/cp/typeck.c $(srcdir)/cp/decl.c \
$(srcdir)/cp/error.c $(srcdir)/cp/friend.c $(srcdir)/cp/init.c \
$(srcdir)/cp/parse.y $(srcdir)/cp/sig.c $(srcdir)/cp/typeck2.c \
- $(srcdir)/cp/repo.c $(srcdir)/cp/semantics.c
+ $(srcdir)/cp/repo.c $(srcdir)/cp/semantics.c \
+ $(srcdir)/cp/dump.c
cc1plus$(exeext): $(P) $(CXX_SRCS) $(LIBDEPS) stamp-objlist c-common.o c-pragma.o \
$(srcdir)/cp/cp-tree.h $(srcdir)/cp/cp-tree.def $(srcdir)/cp/gxx.gperf hash.o
diff --git a/gcc/cp/Makefile.in b/gcc/cp/Makefile.in
index edd3379..63f8580 100644
--- a/gcc/cp/Makefile.in
+++ b/gcc/cp/Makefile.in
@@ -188,7 +188,7 @@ INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config -I$(srcdir)
CXX_OBJS = call.o decl.o errfn.o expr.o pt.o sig.o typeck2.o \
class.o decl2.o error.o lex.o parse.o ptree.o rtti.o spew.o typeck.o cvt.o \
except.o friend.o init.o method.o search.o semantics.o tree.o xref.o \
- repo.o @extra_cxx_objs@
+ repo.o dump.o @extra_cxx_objs@
# Language-independent object files.
OBJS = `cat ../stamp-objlist` ../c-common.o ../c-pragma.o
@@ -306,7 +306,7 @@ repo.o : repo.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h \
$(srcdir)/../toplev.h
semantics.o: semantics.c $(CONFIG_H) $(CXX_TREE_H) lex.h \
$(srcdir)/../except.h $(srcdir)/../system.h $(srcdir)/../toplev.h
-
+dump.o: dump.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h
#
# These exist for maintenance purposes.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index e624102..c5af6fd 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -315,7 +315,8 @@ struct tree_srcloc
#define IDENTIFIER_VIRTUAL_P(NODE) TREE_LANG_FLAG_1(NODE)
-/* Nonzero if this identifier is the prefix for a mangled C++ operator name. */
+/* Nonzero if this identifier is the prefix for a mangled C++ operator
+ name. */
#define IDENTIFIER_OPNAME_P(NODE) TREE_LANG_FLAG_2(NODE)
/* Nonzero if this identifier is the name of a type-conversion
@@ -1296,9 +1297,14 @@ struct lang_decl
(DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (NODE)) \
&& DECL_LANGUAGE (NODE) == lang_cplusplus)
+/* Non-zero if NODE is a user-defined conversion operator. */
#define DECL_CONV_FN_P(NODE) \
(IDENTIFIER_TYPENAME_P (DECL_NAME (NODE)) && TREE_TYPE (DECL_NAME (NODE)))
+/* Non-zero if NODE is an overloaded operator. */
+#define DECL_OVERLOADED_OPERATOR_P(NODE) \
+ (IDENTIFIER_OPNAME_P (DECL_NAME ((NODE))))
+
/* For FUNCTION_DECLs: nonzero means that this function is a constructor
for an object with virtual baseclasses. */
#define DECL_CONSTRUCTOR_FOR_VBASE_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.constructor_for_vbase_attr)
@@ -1857,12 +1863,22 @@ extern int flag_new_for_scope;
#define DELTA2_FROM_PTRMEMFUNC(NODE) delta2_from_ptrmemfunc ((NODE))
#define PFN_FROM_PTRMEMFUNC(NODE) pfn_from_ptrmemfunc ((NODE))
+/* For a pointer-to-member type of the form `T X::*', this is `X'. */
+#define TYPE_PTRMEM_CLASS_TYPE(NODE) \
+ (TYPE_PTRMEM_P ((NODE)) \
+ ? TYPE_OFFSET_BASETYPE (TREE_TYPE ((NODE))) \
+ : TYPE_PTRMEMFUNC_OBJECT_TYPE ((NODE)))
+
+/* For a pointer-to-member type of the form `T X::*', this is `T'. */
+#define TYPE_PTRMEM_POINTED_TO_TYPE(NODE) \
+ (TYPE_PTRMEM_P ((NODE)) \
+ ? TREE_TYPE (TREE_TYPE (NODE)) \
+ : TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE ((NODE))))
+
/* For a pointer-to-member constant `X::Y' this is the RECORD_TYPE for
`X'. */
-#define PTRMEM_CST_CLASS(NODE) \
- (TYPE_PTRMEM_P (TREE_TYPE (NODE)) \
- ? TYPE_OFFSET_BASETYPE (TREE_TYPE (TREE_TYPE (NODE))) \
- : TYPE_PTRMEMFUNC_OBJECT_TYPE (TREE_TYPE (NODE)))
+#define PTRMEM_CST_CLASS(NODE) \
+ TYPE_PTRMEM_CLASS_TYPE (TREE_TYPE (NODE))
/* For a pointer-to-member constant `X::Y' this is the _DECL for
`Y'. */
@@ -2172,6 +2188,14 @@ extern int flag_new_for_scope;
#define ASM_INPUTS(NODE) TREE_OPERAND (NODE, 3)
#define ASM_CLOBBERS(NODE) TREE_OPERAND (NODE, 4)
+/* Nonzero for an ASM_STMT if the assembly statement is volatile. */
+#define ASM_VOLATILE_P(NODE) \
+ (ASM_CV_QUAL ((NODE)) != NULL_TREE)
+
+/* The line-number at which a statement began. */
+#define STMT_LINENO(NODE) \
+ (TREE_COMPLEXITY ((NODE)))
+
/* An enumeration of the kind of tags that C++ accepts. */
enum tag_types { record_type, class_type, union_type, enum_type,
signature_type };
@@ -2990,6 +3014,7 @@ typedef int (*walk_namespaces_fn) PROTO((tree, void *));
extern int walk_namespaces PROTO((walk_namespaces_fn,
void *));
extern int wrapup_globals_for_namespace PROTO((tree, void *));
+extern tree cp_namespace_decls PROTO((tree));
/* in decl2.c */
extern int check_java_method PROTO((tree));
@@ -3604,6 +3629,9 @@ extern void GNU_xref_assign PROTO((tree));
extern void GNU_xref_hier PROTO((tree, tree, int, int, int));
extern void GNU_xref_member PROTO((tree, tree));
+/* in dump.c */
+extern void dump_node_to_file PROTO ((tree, char *));
+
/* -- end of C++ */
#endif /* not _CP_TREE_H */
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index b60a5ec..46708ac 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -1808,6 +1808,15 @@ sigtable_decl_p (t, data)
&& IS_SIGNATURE (TREE_TYPE (t)));
}
+/* Return the declarations that are members of the namespace NS. */
+
+tree
+cp_namespace_decls (ns)
+ tree ns;
+{
+ return NAMESPACE_LEVEL (ns)->names;
+}
+
/* Walk all the namespaces contained NAMESPACE, including NAMESPACE
itself, calling F for each. The DATA is passed to F as well. */
@@ -1822,7 +1831,7 @@ walk_namespaces_r (namespace, f, data)
result |= (*f) (namespace, data);
- for (current = NAMESPACE_LEVEL (namespace)->names;
+ for (current = cp_namespace_decls (namespace);
current;
current = TREE_CHAIN (current))
{
@@ -1921,7 +1930,7 @@ wrapup_globals_for_namespace (namespace, data)
tree namespace;
void *data;
{
- tree globals = NAMESPACE_LEVEL (namespace)->names;
+ tree globals = cp_namespace_decls (namespace);
int len = list_length (globals);
tree *vec = (tree *) alloca (sizeof (tree) * len);
int i;
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index d5125fc..cbc6c23 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -246,6 +246,11 @@ int flag_optional_diags = 1;
int flag_const_strings = 1;
+/* If non-NULL, dump the tree structure for the entire translation
+ unit to this file. */
+
+char *flag_dump_translation_unit = 0;
+
/* Nonzero means warn about deprecated conversion from string constant to
`char *'. */
@@ -649,6 +654,13 @@ lang_decode_option (argc, argv)
name_mangling_version =
read_integral_parameter (p + 22, p - 2, name_mangling_version);
}
+ else if (!strncmp (p, "dump-translation-unit-", 22))
+ {
+ if (p[22] == '\0')
+ error ("no file specified with -fdump-translation-unit");
+ else
+ flag_dump_translation_unit = p + 22;
+ }
else for (j = 0;
!found && j < sizeof (lang_f_options) / sizeof (lang_f_options[0]);
j++)
@@ -3721,6 +3733,11 @@ finish_file ()
finish_repo ();
+ /* The entire file is now complete. If requested, dump everything
+ file. */
+ if (flag_dump_translation_unit)
+ dump_node_to_file (global_namespace, flag_dump_translation_unit);
+
this_time = get_run_time ();
parse_time -= this_time - start_time;
varconst_time += this_time - start_time;
diff --git a/gcc/cp/dump.c b/gcc/cp/dump.c
new file mode 100644
index 0000000..b22565c
--- /dev/null
+++ b/gcc/cp/dump.c
@@ -0,0 +1,861 @@
+/* Tree-dumping functionality for intermediate representation.
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ Written by Mark Mitchell <mark@codesourcery.com>
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* TODO: Class types.
+ Binfos. */
+
+#include "config.h"
+#include "system.h"
+#include "tree.h"
+#include "cp-tree.h"
+#include "splay-tree.h"
+
+/* Flags used with queue functions. */
+#define DUMP_NONE 0
+#define DUMP_CHILDREN 1
+#define DUMP_BINFO 2
+
+/* Information about a node to be dumped. */
+
+typedef struct dump_node_info
+{
+ /* The index for the node. */
+ unsigned int index;
+ /* Nonzero if we should dump the children of the node. */
+ unsigned int dump_children_p : 1;
+ /* Nonzero if the node is a binfo. */
+ unsigned int binfo_p : 1;
+} *dump_node_info_p;
+
+/* A dump_queue is a link in the queue of things to be dumped. */
+
+typedef struct dump_queue
+{
+ /* The queued tree node. */
+ splay_tree_node node;
+ /* The next node in the queue. */
+ struct dump_queue *next;
+} *dump_queue_p;
+
+/* A dump_info gives information about how we should perform the dump
+ and about the current state of the dump. */
+
+typedef struct dump_info
+{
+ /* The stream on which to dump the information. */
+ FILE *stream;
+ /* The next unused node index. */
+ unsigned int index;
+ /* The next column. */
+ unsigned int column;
+ /* The first node in the queue of nodes to be written out. */
+ dump_queue_p queue;
+ /* The last node in the queue. */
+ dump_queue_p queue_end;
+ /* Free queue nodes. */
+ dump_queue_p free_list;
+ /* The tree nodes which we have already written out. The
+ keys are the addresses of the nodes; the values are the integer
+ indices we assigned them. */
+ splay_tree nodes;
+} *dump_info_p;
+
+static unsigned int queue PROTO ((dump_info_p, tree, int));
+static void dump_index PROTO ((dump_info_p, unsigned int));
+static void queue_and_dump_index PROTO ((dump_info_p, char *, tree, int));
+static void queue_and_dump_type PROTO ((dump_info_p, tree, int));
+static void dequeue_and_dump PROTO ((dump_info_p));
+static void dump_new_line PROTO ((dump_info_p));
+static void dump_maybe_newline PROTO ((dump_info_p));
+static void dump_int PROTO ((dump_info_p, char *, int));
+static void dump_string PROTO ((dump_info_p, char *));
+static void dump_string_field PROTO ((dump_info_p, char *, char *));
+static void dump_node PROTO ((tree, FILE *));
+
+/* Add T to the end of the queue of nodes to dump. If DUMP_CHILDREN_P
+ is non-zero, then its children should be dumped as well. Returns
+ the index assigned to T. */
+
+static unsigned int
+queue (di, t, flags)
+ dump_info_p di;
+ tree t;
+ int flags;
+{
+ dump_queue_p dq;
+ dump_node_info_p dni;
+ unsigned int index;
+
+ /* Assign the next available index to T. */
+ index = ++di->index;
+
+ /* Obtain a new queue node. */
+ if (di->free_list)
+ {
+ dq = di->free_list;
+ di->free_list = dq->next;
+ }
+ else
+ dq = (dump_queue_p) xmalloc (sizeof (struct dump_queue));
+
+ /* Create a new entry in the splay-tree. */
+ dni = (dump_node_info_p) xmalloc (sizeof (struct dump_node_info));
+ dni->index = index;
+ dni->dump_children_p = flags & DUMP_CHILDREN;
+ dni->binfo_p = flags & DUMP_BINFO;
+ dq->node = splay_tree_insert (di->nodes, (splay_tree_key) t,
+ (splay_tree_value) dni);
+
+ /* Add it to the end of the queue. */
+ dq->next = 0;
+ if (!di->queue_end)
+ di->queue = dq;
+ else
+ di->queue_end->next = dq;
+ di->queue_end = dq;
+
+ /* Return the index. */
+ return index;
+}
+
+static void
+dump_index (di, index)
+ dump_info_p di;
+ unsigned int index;
+{
+ fprintf (di->stream, "@%-6u ", index);
+ di->column += 8;
+}
+
+/* If T has not already been output, queue it for subsequent output.
+ FIELD is a string to print before printing the index. Then, the
+ index of T is printed. */
+
+static void
+queue_and_dump_index (di, field, t, flags)
+ dump_info_p di;
+ char *field;
+ tree t;
+ int flags;
+{
+ unsigned int index;
+ splay_tree_node n;
+
+ /* If there's no node, just return. This makes for fewer checks in
+ our callers. */
+ if (!t)
+ return;
+
+ /* See if we've already queued or dumped this node. */
+ n = splay_tree_lookup (di->nodes, (splay_tree_key) t);
+ if (n)
+ index = ((dump_node_info_p) n->value)->index;
+ else
+ /* 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);
+}
+
+/* Dump the type of T. */
+
+static void
+queue_and_dump_type (di, t, dump_children_p)
+ dump_info_p di;
+ tree t;
+ int dump_children_p;
+{
+ queue_and_dump_index (di, "type", TREE_TYPE (t), dump_children_p);
+}
+
+/* Insert a new line in the dump output, and indent to an appropriate
+ place to start printing more fields. */
+
+static void
+dump_new_line (di)
+ dump_info_p di;
+{
+ fprintf (di->stream, "\n%25s", "");
+ di->column = 25;
+}
+
+/* If necessary, insert a new line. */
+
+static void
+dump_maybe_newline (di)
+ dump_info_p di;
+{
+ /* See if we need a new line. */
+ if (di->column > 53)
+ dump_new_line (di);
+ /* See if we need any padding. */
+ else if ((di->column - 25) % 14 != 0)
+ {
+ fprintf (di->stream, "%*s", 14 - ((di->column - 25) % 14), "");
+ di->column += 14 - (di->column - 25) % 14;
+ }
+}
+
+/* Dump I using FIELD to identity it. */
+
+static void
+dump_int (di, field, i)
+ dump_info_p di;
+ char *field;
+ int i;
+{
+ dump_maybe_newline (di);
+ fprintf (di->stream, "%-4s: %-7d ", field, i);
+ di->column += 14;
+}
+
+/* Dump the string S. */
+
+static void
+dump_string (di, string)
+ dump_info_p di;
+ char *string;
+{
+ 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. */
+
+static void
+dump_string_field (di, field, string)
+ dump_info_p di;
+ char *field;
+ char *string;
+{
+ 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. */
+
+static void
+dump_stmt (di, t)
+ dump_info_p di;
+ tree t;
+{
+ dump_int (di, "line", STMT_LINENO (t));
+}
+
+/* Dump the CHILD and its children. */
+#define dump_child(field, child) \
+ queue_and_dump_index (di, field, child, DUMP_CHILDREN)
+
+/* Dump the next node in the queue. */
+
+static void
+dequeue_and_dump (di)
+ dump_info_p di;
+{
+ dump_queue_p dq;
+ splay_tree_node stn;
+ dump_node_info_p dni;
+ tree t;
+ unsigned int index;
+ int dump_children_p;
+ enum tree_code code;
+ char code_class;
+
+ /* Get the next node from the queue. */
+ dq = di->queue;
+ stn = dq->node;
+ t = (tree) stn->key;
+ dni = (dump_node_info_p) stn->value;
+ index = dni->index;
+ dump_children_p = dni->dump_children_p;
+
+ /* Remove the node from the queue, and put it on the free list. */
+ di->queue = dq->next;
+ if (!di->queue)
+ di->queue_end = 0;
+ dq->next = di->free_list;
+ di->free_list = dq;
+
+ /* Print the node index. */
+ dump_index (di, index);
+ /* And the type of node this is. */
+ fprintf (di->stream, "%-16s ", tree_code_name[(int) TREE_CODE (t)]);
+ di->column = 25;
+
+ /* Figure out what kind of node this is. */
+ code = TREE_CODE (t);
+ code_class = TREE_CODE_CLASS (code);
+
+ /* Although BINFOs are TREE_VECs, we dump them specially so as to be
+ more informative. */
+ if (dni->binfo_p)
+ {
+ if (TREE_VIA_PUBLIC (t))
+ dump_string (di, "pub");
+ else if (TREE_VIA_PROTECTED (t))
+ dump_string (di, "prot");
+ else if (TREE_VIA_PRIVATE (t))
+ dump_string (di, "priv");
+ if (TREE_VIA_VIRTUAL (t))
+ dump_string (di, "virt");
+
+ if (dump_children_p)
+ {
+ dump_child ("type", BINFO_TYPE (t));
+ dump_child ("base", BINFO_BASETYPES (t));
+ }
+
+ goto done;
+ }
+
+ /* We can knock off a bunch of expression nodes in exactly the same
+ way. */
+ if (IS_EXPR_CODE_CLASS (code_class))
+ {
+ /* If we're dumping children, dump them now. */
+ if (dump_children_p)
+ {
+ queue_and_dump_type (di, t, 1);
+
+ switch (code_class)
+ {
+ case '1':
+ dump_child ("op 0", TREE_OPERAND (t, 0));
+ break;
+
+ case '2':
+ case '<':
+ dump_child ("op 0", TREE_OPERAND (t, 0));
+ dump_child ("op 1", TREE_OPERAND (t, 1));
+ break;
+
+ case 'e':
+ /* These nodes are handled explicitly below. */
+ break;
+
+ default:
+ my_friendly_abort (19990726);
+ }
+ }
+ }
+ else if (code_class == 'd')
+ {
+ /* All declarations have names. */
+ if (DECL_NAME (t))
+ dump_child ("name", DECL_NAME (t));
+ /* And types. */
+ if (dump_children_p)
+ {
+ queue_and_dump_type (di, t, 1);
+ queue_and_dump_index (di, "scpe", DECL_CONTEXT (t), 0);
+ }
+ /* And a source position. */
+ if (DECL_SOURCE_FILE (t))
+ {
+ char *filename = rindex (DECL_SOURCE_FILE (t), '/');
+ if (!filename)
+ filename = DECL_SOURCE_FILE (t);
+ else
+ /* 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;
+ }
+ /* And any declaration can be compiler-generated. */
+ if (DECL_ARTIFICIAL (t))
+ dump_string (di, "artificial");
+ if (TREE_CHAIN (t))
+ dump_child ("chan", TREE_CHAIN (t));
+ }
+ else if (code_class == 't')
+ {
+ /* All types have qualifiers. */
+ int quals = CP_TYPE_QUALS (t);
+ 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;
+ }
+
+ /* All types have associated declarations. */
+ dump_child ("name", TYPE_NAME (t));
+
+ if (dump_children_p)
+ {
+ /* All types have a main variant. */
+ if (TYPE_MAIN_VARIANT (t) != t)
+ dump_child ("unql", TYPE_MAIN_VARIANT (t));
+
+ /* And sizes. */
+ dump_child ("size", TYPE_SIZE (t));
+ }
+
+ /* All types have alignments. */
+ dump_int (di, "algn", TYPE_ALIGN (t));
+ }
+
+ /* Now handle the various kinds of nodes. */
+ switch (code)
+ {
+ int i;
+
+ case IDENTIFIER_NODE:
+ if (IDENTIFIER_OPNAME_P (t))
+ dump_string (di, "operator");
+ else if (IDENTIFIER_TYPENAME_P (t))
+ queue_and_dump_index (di, "tynm", TREE_TYPE (t), 0);
+ else if (t == anonymous_namespace_name)
+ dump_string (di, "unnamed");
+ else
+ {
+ dump_string_field (di, "strg", IDENTIFIER_POINTER (t));
+ dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
+ }
+ break;
+
+ case TREE_LIST:
+ if (dump_children_p)
+ {
+ dump_child ("purp", TREE_PURPOSE (t));
+ dump_child ("valu", TREE_VALUE (t));
+ dump_child ("chan", TREE_CHAIN (t));
+ }
+ break;
+
+ case TREE_VEC:
+ dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
+ if (dump_children_p)
+ for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
+ {
+ char buffer[32];
+ sprintf (buffer, "%u", i);
+ queue_and_dump_index (di, buffer, TREE_VEC_ELT (t, i), 1);
+ }
+ break;
+
+ case INTEGER_TYPE:
+ case ENUMERAL_TYPE:
+ dump_int (di, "prec", TYPE_PRECISION (t));
+ if (TREE_UNSIGNED (t))
+ dump_string (di, "unsigned");
+ if (dump_children_p)
+ {
+ dump_child ("min", TYPE_MIN_VALUE (t));
+ dump_child ("max", TYPE_MAX_VALUE (t));
+ }
+
+ if (code == ENUMERAL_TYPE && dump_children_p)
+ dump_child ("csts", TYPE_VALUES (t));
+ break;
+
+ case REAL_TYPE:
+ dump_int (di, "prec", TYPE_PRECISION (t));
+ break;
+
+ case POINTER_TYPE:
+ if (dump_children_p)
+ {
+ if (TYPE_PTRMEM_P (t))
+ {
+ dump_string (di, "ptrmem");
+ queue_and_dump_index (di, "ptd",
+ TYPE_PTRMEM_POINTED_TO_TYPE (t), 1);
+ queue_and_dump_index (di, "cls",
+ TYPE_PTRMEM_CLASS_TYPE (t), 1);
+ }
+ else
+ dump_child ("ptd", TREE_TYPE (t));
+ }
+ break;
+
+ case REFERENCE_TYPE:
+ if (dump_children_p)
+ dump_child ("refd", TREE_TYPE (t));
+ break;
+
+ case METHOD_TYPE:
+ if (dump_children_p)
+ dump_child ("clas", TYPE_METHOD_BASETYPE (t));
+ /* Fall through. */
+
+ case FUNCTION_TYPE:
+ if (dump_children_p)
+ {
+ dump_child ("retn", TREE_TYPE (t));
+ dump_child ("prms", TYPE_ARG_TYPES (t));
+ }
+ break;
+
+ case ARRAY_TYPE:
+ if (dump_children_p)
+ {
+ dump_child ("elts", TREE_TYPE (t));
+ dump_child ("domn", TYPE_DOMAIN (t));
+ }
+ break;
+
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ if (TYPE_PTRMEMFUNC_P (t))
+ {
+ dump_string (di, "ptrmem");
+ queue_and_dump_index (di, "ptd",
+ TYPE_PTRMEM_POINTED_TO_TYPE (t), 1);
+ queue_and_dump_index (di, "cls",
+ TYPE_PTRMEM_CLASS_TYPE (t), 1);
+ }
+ else
+ {
+ if (CLASSTYPE_DECLARED_CLASS (t))
+ dump_string (di, "class");
+ else if (TREE_CODE (t) == RECORD_TYPE)
+ dump_string (di, "struct");
+ else
+ dump_string (di, "union");
+
+ if (dump_children_p)
+ {
+ dump_child ("flds", TYPE_FIELDS (t));
+ dump_child ("fncs", TYPE_METHODS (t));
+ queue_and_dump_index (di, "binf", TYPE_BINFO (t),
+ DUMP_CHILDREN | DUMP_BINFO);
+ }
+ }
+ break;
+
+ case CONST_DECL:
+ if (dump_children_p)
+ dump_child ("cnst", DECL_INITIAL (t));
+ break;
+
+ case VAR_DECL:
+ case PARM_DECL:
+ case FIELD_DECL:
+ if (dump_children_p)
+ {
+ dump_child ("init", DECL_INITIAL (t));
+ dump_child ("size", DECL_SIZE (t));
+ }
+ dump_int (di, "algn", DECL_ALIGN (t));
+
+ if (TREE_CODE (t) == FIELD_DECL && dump_children_p)
+ dump_child ("bpos", DECL_FIELD_BITPOS (t));
+ break;
+
+ case FUNCTION_DECL:
+ if (dump_children_p)
+ {
+ queue_and_dump_index (di, "scpe", DECL_REAL_CONTEXT (t), 0);
+ dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
+ dump_child ("args", DECL_ARGUMENTS (t));
+ }
+ if (TREE_PUBLIC (t))
+ dump_string(di, "extern");
+ else
+ dump_string (di, "static");
+ if (DECL_FUNCTION_MEMBER_P (t))
+ dump_string (di, "member");
+ if (DECL_CONSTRUCTOR_P (t))
+ dump_string (di, "constructor");
+ if (DECL_DESTRUCTOR_P (t))
+ dump_string (di, "destructor");
+ if (DECL_OVERLOADED_OPERATOR_P (t))
+ dump_string (di, "operator");
+ if (DECL_CONV_FN_P (t))
+ dump_string (di, "conversion");
+ if (dump_children_p)
+ dump_child ("body", DECL_INITIAL (t));
+ break;
+
+ case NAMESPACE_DECL:
+ /* The fake `::std' namespace does not have DECL_LANG_SPECIFIC,
+ and therefore many other macros do not work on it. */
+ if (t == std_node)
+ break;
+ if (dump_children_p)
+ dump_child ("dcls", cp_namespace_decls (t));
+ break;
+
+ case OVERLOAD:
+ if (dump_children_p)
+ {
+ dump_child ("crnt", OVL_CURRENT (t));
+ dump_child ("chan", OVL_CHAIN (t));
+ }
+ break;
+
+ case ASM_STMT:
+ dump_stmt (di, t);
+ if (ASM_VOLATILE_P (t))
+ dump_string (di, "volatile");
+ if (dump_children_p)
+ {
+ dump_child ("strg", ASM_STRING (t));
+ dump_child ("outs", ASM_OUTPUTS (t));
+ dump_child ("ins", ASM_INPUTS (t));
+ dump_child ("clbr", ASM_CLOBBERS (t));
+ }
+ break;
+
+ case BREAK_STMT:
+ case CONTINUE_STMT:
+ dump_stmt (di, t);
+ break;
+
+ case CASE_LABEL:
+ /* Note that a case label is not like other statments; there is
+ no way to get the line-number of a case label. */
+ if (dump_children_p)
+ {
+ dump_child ("low", CASE_LOW (t));
+ dump_child ("high", CASE_HIGH (t));
+ }
+ break;
+
+ case COMPOUND_STMT:
+ dump_stmt (di, t);
+ if (dump_children_p)
+ dump_child ("body", COMPOUND_BODY (t));
+ break;
+
+ case DECL_STMT:
+ dump_stmt (di, t);
+#if 0
+ /* We do not yet have DECL_STMT_DECL; there are declarators and
+ such hanging about in DECL_STMTs. */
+ if (dump_children_p)
+ dump_child ("decl", DECL_STMT_DECL (t));
+#endif
+ break;
+
+ case DO_STMT:
+ dump_stmt (di, t);
+ if (dump_children_p)
+ {
+ dump_child ("body", DO_BODY (t));
+ dump_child ("cond", DO_COND (t));
+ }
+ break;
+
+ case EXPR_STMT:
+ dump_stmt (di, t);
+ if (dump_children_p)
+ dump_child ("expr", EXPR_STMT_EXPR (t));
+ break;
+
+ case FOR_STMT:
+ dump_stmt (di, t);
+ if (dump_children_p)
+ {
+ dump_child ("init", FOR_INIT_STMT (t));
+ dump_child ("cond", FOR_COND (t));
+ dump_child ("expr", FOR_EXPR (t));
+ dump_child ("body", FOR_BODY (t));
+ }
+ break;
+
+ case GOTO_STMT:
+ dump_stmt (di, t);
+ if (dump_children_p)
+ dump_child ("dest", GOTO_DESTINATION (t));
+ break;
+
+ case IF_STMT:
+ dump_stmt (di, t);
+ if (dump_children_p)
+ {
+ dump_child ("cond", IF_COND (t));
+ dump_child ("then", THEN_CLAUSE (t));
+ dump_child ("else", ELSE_CLAUSE (t));
+ }
+ break;
+
+ case RETURN_STMT:
+ dump_stmt (di, t);
+ if (dump_children_p)
+ dump_child ("expr", RETURN_EXPR (t));
+ break;
+
+ case SWITCH_STMT:
+ dump_stmt (di, t);
+ if (dump_children_p)
+ {
+ dump_child ("cond", SWITCH_COND (t));
+ dump_child ("body", SWITCH_BODY (t));
+ }
+ break;
+
+ case TRY_BLOCK:
+ dump_stmt (di, t);
+ if (dump_children_p)
+ {
+ dump_child ("body", TRY_STMTS (t));
+ dump_child ("hdlr", TRY_HANDLERS (t));
+ }
+ break;
+
+ case WHILE_STMT:
+ dump_stmt (di, t);
+ if (dump_children_p)
+ {
+ dump_child ("cond", WHILE_COND (t));
+ dump_child ("body", WHILE_BODY (t));
+ }
+ break;
+
+ case INTEGER_CST:
+ if (TREE_INT_CST_HIGH (t))
+ dump_int (di, "high", TREE_INT_CST_HIGH (t));
+ dump_int (di, "low", TREE_INT_CST_LOW (t));
+ break;
+
+ case STRING_CST:
+ fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
+ dump_int (di, "lngt", TREE_STRING_LENGTH (t));
+ break;
+
+ case PTRMEM_CST:
+ if (dump_children_p)
+ {
+ dump_child ("clas", PTRMEM_CST_CLASS (t));
+ dump_child ("mbr", PTRMEM_CST_MEMBER (t));
+ }
+ break;
+
+ case TRUTH_NOT_EXPR:
+ case ADDR_EXPR:
+ case INDIRECT_REF:
+ case THROW_EXPR:
+ /* These nodes are unary, but do not have code class `1'. */
+ if (dump_children_p)
+ dump_child ("op 0", TREE_OPERAND (t, 0));
+ break;
+
+ case TRUTH_ANDIF_EXPR:
+ case TRUTH_ORIF_EXPR:
+ case MODIFY_EXPR:
+ case COMPONENT_REF:
+ case COMPOUND_EXPR:
+ case COND_EXPR:
+ /* These nodes are binary, but do not have code class `2'. */
+ if (dump_children_p)
+ {
+ dump_child ("op 0", TREE_OPERAND (t, 0));
+ dump_child ("op 1", TREE_OPERAND (t, 1));
+ }
+ break;
+
+ case CALL_EXPR:
+ if (dump_children_p)
+ {
+ dump_child ("fn", TREE_OPERAND (t, 0));
+ dump_child ("args", TREE_OPERAND (t, 1));
+ }
+ break;
+
+ case CONSTRUCTOR:
+ if (dump_children_p)
+ dump_child ("elts", TREE_OPERAND (t, 1));
+ break;
+
+ default:
+ /* There are no additional fields to print. */
+ break;
+ }
+
+ done:
+ /* Terminate the line. */
+ fprintf (di->stream, "\n");
+}
+
+/* Dump T, and all its children, on STREAM. */
+
+static void
+dump_node (t, stream)
+ tree t;
+ FILE *stream;
+{
+ struct dump_info di;
+ dump_queue_p dq;
+ dump_queue_p next_dq;
+
+ /* Initialize the dump-information structure. */
+ di.stream = stream;
+ di.index = 0;
+ di.column = 0;
+ di.queue = 0;
+ di.queue_end = 0;
+ di.free_list = 0;
+ di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
+ (splay_tree_delete_value_fn) &free);
+
+ /* Queue up the first node. */
+ queue (&di, t, DUMP_CHILDREN);
+
+ /* Until the queue is empty, keep dumping nodes. */
+ while (di.queue)
+ dequeue_and_dump (&di);
+
+ /* Now, clean up. */
+ for (dq = di.free_list; dq; dq = next_dq)
+ {
+ next_dq = dq->next;
+ free (dq);
+ }
+ splay_tree_delete (di.nodes);
+}
+
+/* Dump T, and all its children, to FILE. */
+
+void
+dump_node_to_file (t, file)
+ tree t;
+ char *file;
+{
+ FILE *f;
+
+ f = fopen (file, "w");
+ if (!f)
+ cp_error ("could not open `%s'", file);
+ else
+ {
+ dump_node (t, f);
+ fclose (f);
+ }
+}
diff --git a/gcc/cp/lang-options.h b/gcc/cp/lang-options.h
index cfc6456..e919965 100644
--- a/gcc/cp/lang-options.h
+++ b/gcc/cp/lang-options.h
@@ -38,6 +38,7 @@ DEFINE_LANG_NAME ("C++")
{ "-fconst-strings", "" },
{ "-fno-const-strings", "Make string literals `char[]' instead of `const char[]'" },
{ "-fdefault-inline", "" },
+ { "-fdump-translation-unit-", "Dump the entire translation unit to a file"},
{ "-fno-default-inline", "Do not inline member functions by default"},
{ "-frtti", "" },
{ "-fno-rtti", "Do not generate run time type descriptor information" },
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index a847755..4e9b412 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -5307,8 +5307,8 @@ tsubst_template_parms (parms, args, complain)
tree args;
int complain;
{
- tree r;
- tree* new_parms = &r;
+ tree r = NULL_TREE;
+ tree* new_parms;
for (new_parms = &r;
TMPL_PARMS_DEPTH (parms) > TMPL_ARGS_DEPTH (args);
@@ -5822,7 +5822,7 @@ tsubst_decl (t, args, type, in_decl)
maybe_retrofit_in_chrg (r);
grok_ctor_properties (ctx, r);
}
- if (IDENTIFIER_OPNAME_P (DECL_NAME (r)))
+ else if (DECL_OVERLOADED_OPERATOR_P (r))
grok_op_properties (r, DECL_VIRTUAL_P (r), DECL_FRIEND_P (r));
}
break;
@@ -7077,13 +7077,13 @@ tsubst_expr (t, args, complain, in_decl)
switch (TREE_CODE (t))
{
case RETURN_STMT:
- lineno = TREE_COMPLEXITY (t);
+ lineno = STMT_LINENO (t);
finish_return_stmt (tsubst_expr (RETURN_EXPR (t),
args, complain, in_decl));
break;
case EXPR_STMT:
- lineno = TREE_COMPLEXITY (t);
+ lineno = STMT_LINENO (t);
finish_expr_stmt (tsubst_expr (EXPR_STMT_EXPR (t),
args, complain, in_decl));
break;
@@ -7093,7 +7093,7 @@ tsubst_expr (t, args, complain, in_decl)
int i = suspend_momentary ();
tree dcl, init;
- lineno = TREE_COMPLEXITY (t);
+ lineno = STMT_LINENO (t);
emit_line_note (input_filename, lineno);
dcl = start_decl
(tsubst (TREE_OPERAND (t, 0), args, complain, in_decl),
@@ -7109,7 +7109,7 @@ tsubst_expr (t, args, complain, in_decl)
case FOR_STMT:
{
tree tmp;
- lineno = TREE_COMPLEXITY (t);
+ lineno = STMT_LINENO (t);
begin_for_stmt ();
for (tmp = FOR_INIT_STMT (t); tmp; tmp = TREE_CHAIN (tmp))
@@ -7127,7 +7127,7 @@ tsubst_expr (t, args, complain, in_decl)
case WHILE_STMT:
{
- lineno = TREE_COMPLEXITY (t);
+ lineno = STMT_LINENO (t);
begin_while_stmt ();
finish_while_stmt_cond (tsubst_expr (WHILE_COND (t),
args, complain, in_decl),
@@ -7139,7 +7139,7 @@ tsubst_expr (t, args, complain, in_decl)
case DO_STMT:
{
- lineno = TREE_COMPLEXITY (t);
+ lineno = STMT_LINENO (t);
begin_do_stmt ();
tsubst_expr (DO_BODY (t), args, complain, in_decl);
finish_do_body (NULL_TREE);
@@ -7153,7 +7153,7 @@ tsubst_expr (t, args, complain, in_decl)
{
tree tmp;
- lineno = TREE_COMPLEXITY (t);
+ lineno = STMT_LINENO (t);
begin_if_stmt ();
finish_if_stmt_cond (tsubst_expr (IF_COND (t),
args, complain, in_decl),
@@ -7180,7 +7180,7 @@ tsubst_expr (t, args, complain, in_decl)
{
tree substmt;
- lineno = TREE_COMPLEXITY (t);
+ lineno = STMT_LINENO (t);
begin_compound_stmt (COMPOUND_STMT_NO_SCOPE (t));
for (substmt = COMPOUND_BODY (t);
substmt != NULL_TREE;
@@ -7192,12 +7192,12 @@ tsubst_expr (t, args, complain, in_decl)
break;
case BREAK_STMT:
- lineno = TREE_COMPLEXITY (t);
+ lineno = STMT_LINENO (t);
finish_break_stmt ();
break;
case CONTINUE_STMT:
- lineno = TREE_COMPLEXITY (t);
+ lineno = STMT_LINENO (t);
finish_continue_stmt ();
break;
@@ -7205,7 +7205,7 @@ tsubst_expr (t, args, complain, in_decl)
{
tree val, tmp;
- lineno = TREE_COMPLEXITY (t);
+ lineno = STMT_LINENO (t);
begin_switch_stmt ();
val = tsubst_expr (SWITCH_COND (t), args, complain, in_decl);
finish_switch_cond (val);
@@ -7230,7 +7230,7 @@ tsubst_expr (t, args, complain, in_decl)
break;
case GOTO_STMT:
- lineno = TREE_COMPLEXITY (t);
+ lineno = STMT_LINENO (t);
t = GOTO_DESTINATION (t);
if (TREE_CODE (t) != IDENTIFIER_NODE)
/* Computed goto's must be tsubst'd into. On the other hand,
@@ -7241,7 +7241,7 @@ tsubst_expr (t, args, complain, in_decl)
break;
case ASM_STMT:
- lineno = TREE_COMPLEXITY (t);
+ lineno = STMT_LINENO (t);
finish_asm_stmt (ASM_CV_QUAL (t),
tsubst_expr (ASM_STRING (t), args, complain, in_decl),
tsubst_expr (ASM_OUTPUTS (t), args, complain, in_decl),
@@ -7251,7 +7251,7 @@ tsubst_expr (t, args, complain, in_decl)
break;
case TRY_BLOCK:
- lineno = TREE_COMPLEXITY (t);
+ lineno = STMT_LINENO (t);
begin_try_block ();
tsubst_expr (TRY_STMTS (t), args, complain, in_decl);
finish_try_block (NULL_TREE);
@@ -7264,7 +7264,7 @@ tsubst_expr (t, args, complain, in_decl)
break;
case HANDLER:
- lineno = TREE_COMPLEXITY (t);
+ lineno = STMT_LINENO (t);
begin_handler ();
if (HANDLER_PARMS (t))
{
@@ -7281,7 +7281,7 @@ tsubst_expr (t, args, complain, in_decl)
break;
case TAG_DEFN:
- lineno = TREE_COMPLEXITY (t);
+ lineno = STMT_LINENO (t);
t = TREE_TYPE (t);
if (TREE_CODE (t) == ENUMERAL_TYPE)
tsubst (t, args, complain, NULL_TREE);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index b66efdf..18575ee 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -741,6 +741,14 @@ finish_asm_stmt (cv_qualifier, string, output_operands,
pop_obstacks ();
}
+ if (cv_qualifier != NULL_TREE
+ && cv_qualifier != ridpointers[(int) RID_VOLATILE])
+ {
+ cp_warning ("%s qualifier ignored on asm",
+ IDENTIFIER_POINTER (cv_qualifier));
+ cv_qualifier = NULL_TREE;
+ }
+
if (processing_template_decl)
{
tree r = build_min_nt (ASM_STMT, cv_qualifier, string,
@@ -756,30 +764,17 @@ finish_asm_stmt (cv_qualifier, string, output_operands,
{
tree t;
- if (cv_qualifier != NULL_TREE
- && cv_qualifier != ridpointers[(int) RID_VOLATILE])
- cp_warning ("%s qualifier ignored on asm",
- IDENTIFIER_POINTER (cv_qualifier));
-
for (t = input_operands; t; t = TREE_CHAIN (t))
TREE_VALUE (t) = decay_conversion (TREE_VALUE (t));
c_expand_asm_operands (string, output_operands,
input_operands,
clobbers,
- cv_qualifier
- == ridpointers[(int) RID_VOLATILE],
+ cv_qualifier != NULL_TREE,
input_filename, lineno);
}
else
- {
- /* Don't warn about redundant specification of 'volatile' here. */
- if (cv_qualifier != NULL_TREE
- && cv_qualifier != ridpointers[(int) RID_VOLATILE])
- cp_warning ("%s qualifier ignored on asm",
- IDENTIFIER_POINTER (cv_qualifier));
- expand_asm (string);
- }
+ expand_asm (string);
finish_stmt ();
}
diff --git a/gcc/invoke.texi b/gcc/invoke.texi
index 692f753..69be85b 100644
--- a/gcc/invoke.texi
+++ b/gcc/invoke.texi
@@ -139,8 +139,8 @@ in the following sections.
@item Debugging Options
@xref{Debugging Options,,Options for Debugging Your Program or GCC}.
@smallexample
--a -ax -d@var{letters} -fdump-unnumbered -fpretend-float
--fprofile-arcs -ftest-coverage
+-a -ax -d@var{letters} -fdump-unnumbered -fdump-translation-unit-@var{file}
+-fpretend-float -fprofile-arcs -ftest-coverage
-g -g@var{level} -gcoff -gdwarf -gdwarf-1 -gdwarf-1+ -gdwarf-2
-ggdb -gstabs -gstabs+ -gxcoff -gxcoff+
-p -pg -print-file-name=@var{library} -print-libgcc-file-name
@@ -2120,6 +2120,10 @@ numbers and line number note output. This makes it more feasible to
use diff on debugging dumps for compiler invokations with different
options, in particular with and without -g.
+@item -fdump-translation-unit-@var{file} (C++ only)
+Dump a representation of the tree structure for the entire translation
+unit to @var{file}.
+
@item -fpretend-float
When running a cross-compiler, pretend that the target machine uses the
same floating point format as the host machine. This causes incorrect