aboutsummaryrefslogtreecommitdiff
path: root/odb/parser.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-10-19 10:43:33 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-10-21 19:25:06 +0200
commit21cd079f538b8e175cd659c3d5d9c305b7ce7c6b (patch)
treec95766f8d3445beba9d92d038bcbe08d367d2263 /odb/parser.cxx
parent2d1702ccf69d152bf864c5cf5375b6c0d442b9f0 (diff)
Add name hint to the qualifies edge (cvr-qualification)
Diffstat (limited to 'odb/parser.cxx')
-rw-r--r--odb/parser.cxx58
1 files changed, 58 insertions, 0 deletions
diff --git a/odb/parser.cxx b/odb/parser.cxx
index 134aef1..a520b3b 100644
--- a/odb/parser.cxx
+++ b/odb/parser.cxx
@@ -1359,6 +1359,64 @@ emit_type (tree t,
//
qualifier& q (unit_->new_node<qualifier> (file, line, clmn, t, qc, qv, qr));
unit_->new_edge<qualifies> (q, r);
+
+ // See if there is a name hint for this type.
+ //
+ // If TREE_TYPE (TYPE_NAME (t)) != t then we have an inline qualifier,
+ // as in:
+ //
+ // const foo x;
+ //
+ // If they are equal, then there are two possible cases. The first is
+ // when we have a qualifier typedef, as in:
+ //
+ // typedef const foo cfoo;
+ // cfoo x;
+ //
+ // The second is when we have a qualifier typedef but what is actually
+ // used in the declaration is an inline qualifier, as in:
+ //
+ // typedef const foo cfoo;
+ // const foo x;
+ //
+ // Unfortunately, in GCC, these two cases are indistinguishable. In
+ // certain cases this can lead to a wrong hint being used for the base
+ // type, for example:
+ //
+ // typedef foo my_foo;
+ // typedef foo foo_t;
+ // typedef const foo_t cfoo;
+ //
+ // const my_foo x;
+ //
+ // Above, the hint will be foo_t while it should be my_foo.
+ //
+ tree bt (0);
+
+ if (tree decl = TYPE_NAME (t))
+ {
+ bt = TREE_TYPE (decl);
+
+ if (t == bt)
+ {
+ // A const type can be named only with a typedef. Get the
+ // original type.
+ //
+ tree ot (DECL_ORIGINAL_TYPE (decl));
+
+ // And chase it one more time to get rid of the qualification.
+ //
+ decl = TYPE_NAME (ot);
+ bt = decl != 0 ? TREE_TYPE (decl) : 0;
+ }
+ }
+
+ if (bt != 0)
+ {
+ if (names* hint = unit_->find_hint (bt))
+ e.hint (*hint);
+ }
+
process_named_pragmas (t, q);
return q;