diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2011-10-19 10:43:33 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2011-10-21 19:25:06 +0200 |
commit | 21cd079f538b8e175cd659c3d5d9c305b7ce7c6b (patch) | |
tree | c95766f8d3445beba9d92d038bcbe08d367d2263 | |
parent | 2d1702ccf69d152bf864c5cf5375b6c0d442b9f0 (diff) |
Add name hint to the qualifies edge (cvr-qualification)
-rw-r--r-- | odb/parser.cxx | 58 | ||||
-rw-r--r-- | odb/semantics/derived.cxx | 1 | ||||
-rw-r--r-- | odb/semantics/derived.hxx | 16 |
3 files changed, 75 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; diff --git a/odb/semantics/derived.cxx b/odb/semantics/derived.cxx index 14c568a..b6dec2d 100644 --- a/odb/semantics/derived.cxx +++ b/odb/semantics/derived.cxx @@ -10,6 +10,7 @@ namespace semantics { qualifies:: qualifies () + : hint_ (0) { } diff --git a/odb/semantics/derived.hxx b/odb/semantics/derived.hxx index 2860bca..890d752 100644 --- a/odb/semantics/derived.hxx +++ b/odb/semantics/derived.hxx @@ -43,6 +43,21 @@ namespace semantics return *qualifier_; } + // Name hint of the base type. + // + public: + void + hint (names& hint) + { + hint_ = &hint; + } + + names* + hint () const + { + return hint_; + } + public: qualifies (); @@ -61,6 +76,7 @@ namespace semantics protected: type_type* type_; qualifier_type* qualifier_; + names* hint_; }; class qualifier: public derived_type |