aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-decl.c
diff options
context:
space:
mode:
authorDodji Seketeli <dodji@redhat.com>2009-01-22 07:15:41 +0000
committerDodji Seketeli <dodji@gcc.gnu.org>2009-01-22 08:15:41 +0100
commit03c2a308f32b01bdb5bea5538bccbb9b885b47a9 (patch)
tree8c0ca9e4a8b6ac8aced92cf10fba12e1269c35c1 /gcc/c-decl.c
parent73cc93abd2d93d6d5dcbfb8654bc7718a13c2476 (diff)
downloadgcc-03c2a308f32b01bdb5bea5538bccbb9b885b47a9.zip
gcc-03c2a308f32b01bdb5bea5538bccbb9b885b47a9.tar.gz
gcc-03c2a308f32b01bdb5bea5538bccbb9b885b47a9.tar.bz2
Reverted commit 143546 related to PR c++/26693
From-SVN: r143562
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r--gcc/c-decl.c63
1 files changed, 62 insertions, 1 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 8b444d4..7f7f2b0 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -1971,6 +1971,67 @@ warn_if_shadowing (tree new_decl)
}
}
+
+/* Subroutine of pushdecl.
+
+ X is a TYPE_DECL for a typedef statement. Create a brand new
+ ..._TYPE node (which will be just a variant of the existing
+ ..._TYPE node with identical properties) and then install X
+ as the TYPE_NAME of this brand new (duplicate) ..._TYPE node.
+
+ The whole point here is to end up with a situation where each
+ and every ..._TYPE node the compiler creates will be uniquely
+ associated with AT MOST one node representing a typedef name.
+ This way, even though the compiler substitutes corresponding
+ ..._TYPE nodes for TYPE_DECL (i.e. "typedef name") nodes very
+ early on, later parts of the compiler can always do the reverse
+ translation and get back the corresponding typedef name. For
+ example, given:
+
+ typedef struct S MY_TYPE;
+ MY_TYPE object;
+
+ Later parts of the compiler might only know that `object' was of
+ type `struct S' if it were not for code just below. With this
+ code however, later parts of the compiler see something like:
+
+ struct S' == struct S
+ typedef struct S' MY_TYPE;
+ struct S' object;
+
+ And they can then deduce (from the node for type struct S') that
+ the original object declaration was:
+
+ MY_TYPE object;
+
+ Being able to do this is important for proper support of protoize,
+ and also for generating precise symbolic debugging information
+ which takes full account of the programmer's (typedef) vocabulary.
+
+ Obviously, we don't want to generate a duplicate ..._TYPE node if
+ the TYPE_DECL node that we are now processing really represents a
+ standard built-in type. */
+
+static void
+clone_underlying_type (tree x)
+{
+ if (DECL_IS_BUILTIN (x))
+ {
+ if (TYPE_NAME (TREE_TYPE (x)) == 0)
+ TYPE_NAME (TREE_TYPE (x)) = x;
+ }
+ else if (TREE_TYPE (x) != error_mark_node
+ && DECL_ORIGINAL_TYPE (x) == NULL_TREE)
+ {
+ tree tt = TREE_TYPE (x);
+ DECL_ORIGINAL_TYPE (x) = tt;
+ tt = build_variant_type_copy (tt);
+ TYPE_NAME (tt) = x;
+ TREE_USED (tt) = TREE_USED (x);
+ TREE_TYPE (x) = tt;
+ }
+}
+
/* Record a decl-node X as belonging to the current lexical scope.
Check for errors (such as an incompatible declaration for the same
name already seen in the same scope).
@@ -2193,7 +2254,7 @@ pushdecl (tree x)
skip_external_and_shadow_checks:
if (TREE_CODE (x) == TYPE_DECL)
- set_underlying_type (x);
+ clone_underlying_type (x);
bind (name, x, scope, /*invisible=*/false, nested);