diff options
author | dodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-01-22 07:15:41 +0000 |
---|---|---|
committer | dodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-01-22 07:15:41 +0000 |
commit | b2694749353bbe9821baf9676bd913637c06afe8 (patch) | |
tree | 8c0ca9e4a8b6ac8aced92cf10fba12e1269c35c1 /gcc/c-decl.c | |
parent | b98f0f6e796e2781be192e6a5aad6cfc752c839e (diff) | |
download | gcc-b2694749353bbe9821baf9676bd913637c06afe8.tar.gz |
Reverted commit 143546 related to PR c++/26693
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@143562 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r-- | gcc/c-decl.c | 63 |
1 files changed, 62 insertions, 1 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 8b444d4177a..7f7f2b00ac7 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); |