aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-02-07 13:07:12 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-02-07 13:07:12 +0200
commitee9c9f3db3eb4b689e565c282345b1f49bba5042 (patch)
tree2add5cd40b963dcd0f0a6e49a96f18180c1b96e5
parent00c779a294a86c2e9ce2d2a09216e169dd69a666 (diff)
Fix to work with GCC 5
-rw-r--r--odb/cxx-lexer.cxx4
-rw-r--r--odb/gcc-fwd.hxx4
-rw-r--r--odb/gcc.hxx33
-rw-r--r--odb/include.cxx11
-rw-r--r--odb/parser.cxx79
-rw-r--r--odb/plugin.cxx15
-rw-r--r--odb/pragma.cxx27
-rw-r--r--odb/processor.cxx107
-rw-r--r--odb/relational/source.hxx2
-rw-r--r--odb/semantics/elements.cxx67
10 files changed, 183 insertions, 166 deletions
diff --git a/odb/cxx-lexer.cxx b/odb/cxx-lexer.cxx
index ae07bd2..fea05d7 100644
--- a/odb/cxx-lexer.cxx
+++ b/odb/cxx-lexer.cxx
@@ -181,7 +181,11 @@ cxx_string_lexer::
cxx_string_lexer ()
: reader_ (0)
{
+#if BUILDING_GCC_MAJOR >= 5
+ linemap_init (&line_map_, UNKNOWN_LOCATION);
+#else
linemap_init (&line_map_);
+#endif
#if BUILDING_GCC_MAJOR > 4 || BUILDING_GCC_MAJOR == 4 && BUILDING_GCC_MINOR > 6
line_map_.round_alloc_size = ggc_round_alloc_size;
diff --git a/odb/gcc-fwd.hxx b/odb/gcc-fwd.hxx
index fdb447a..a120f05 100644
--- a/odb/gcc-fwd.hxx
+++ b/odb/gcc-fwd.hxx
@@ -12,6 +12,10 @@
# include <config.h>
#endif
+#if BUILDING_GCC_MAJOR >= 5
+# include <stdint.h> // Needed by coretypes.h
+#endif
+
extern "C"
{
// The hwint.h header uses gcc_checking_assert macro from system.h. But
diff --git a/odb/gcc.hxx b/odb/gcc.hxx
index dc15071..504b59b 100644
--- a/odb/gcc.hxx
+++ b/odb/gcc.hxx
@@ -33,6 +33,11 @@ extern "C"
{
#endif
+// GCC's system.h below includes safe-ctype.h which "disables" versions
+// from ctype.h. Well, now it's gonna learn how it feels to be disabled.
+//
+#define SAFE_CTYPE_H
+
#include <gcc-plugin.h>
#include <config.h>
@@ -65,6 +70,34 @@ extern "C"
} // extern "C"
#endif
+// Get the value of INTEGER_CST reinterpreted as unsigned.
+//
+inline unsigned long long
+integer_value (tree n)
+{
+ unsigned long long val;
+
+#if BUILDING_GCC_MAJOR >= 5
+ if (tree_fits_uhwi_p (n))
+ val = static_cast<unsigned long long> (tree_to_uhwi (n));
+ else
+ val = static_cast<unsigned long long> (tree_to_shwi (n));
+#else
+ HOST_WIDE_INT hwl (TREE_INT_CST_LOW (n));
+ HOST_WIDE_INT hwh (TREE_INT_CST_HIGH (n));
+ unsigned short width (HOST_BITS_PER_WIDE_INT);
+
+ if (hwh == 0)
+ val = static_cast<unsigned long long> (hwl);
+ else if (hwh == -1 && hwl != 0)
+ val = static_cast<unsigned long long> (hwl);
+ else
+ val = static_cast<unsigned long long> ((hwh << width) + hwl);
+#endif
+
+ return val;
+}
+
// Since 4.7.0 the location may point inside a macro rather than at
// the expansion point. We are only really interested in the expansion
// points so we use the real_source_location() wrapper rather than
diff --git a/odb/include.cxx b/odb/include.cxx
index 84e07e7..c397993 100644
--- a/odb/include.cxx
+++ b/odb/include.cxx
@@ -496,12 +496,9 @@ namespace
std::locale loc_;
options const& options_;
};
-}
-namespace include
-{
bool
- generate (bool header)
+ generate_impl (bool header)
{
bool r (false);
@@ -718,3 +715,9 @@ namespace include
return r;
}
}
+
+namespace include
+{
+ bool
+ generate (bool header) {return generate_impl (header);}
+}
diff --git a/odb/parser.cxx b/odb/parser.cxx
index c568efa..a8e6a6a 100644
--- a/odb/parser.cxx
+++ b/odb/parser.cxx
@@ -932,6 +932,9 @@ emit ()
if (ns.compare (0, pfx.size (), pfx) == 0)
break;
+ if (trace)
+ ts << "closing namespace " << scope_->name () << endl;
+
scope_ = &scope_->scope_ ();
}
@@ -949,7 +952,7 @@ emit ()
string n (ns, b, e == string::npos ? e : e - b);
if (trace)
- ts << "creating namespace " << n << " for "
+ ts << "opening namespace " << n << " for "
<< DECL_SOURCE_FILE (decl) << ":"
<< DECL_SOURCE_LINE (decl) << endl;
@@ -1164,8 +1167,8 @@ emit_type_decl (tree decl)
{
string s (emit_type_name (t, false));
- ts << "typedef " << s << " (" << &node << ") -> " << name << " at "
- << f << ":" << l << endl;
+ ts << "typedef " << s << " (" << &node << ") -> " << name
+ << " at " << f << ":" << l << endl;
}
return 0;
@@ -1461,18 +1464,7 @@ emit_enum (tree e,
tree decl (TREE_VALUE (er));
tree tval (DECL_INITIAL (decl));
- HOST_WIDE_INT hwl (TREE_INT_CST_LOW (tval));
- HOST_WIDE_INT hwh (TREE_INT_CST_HIGH (tval));
- unsigned short width (HOST_BITS_PER_WIDE_INT);
-
- unsigned long long val;
-
- if (hwh == 0)
- val = static_cast<unsigned long long> (hwl);
- else if (hwh == -1 && hwl != 0)
- val = static_cast<unsigned long long> (hwl);
- else
- val = static_cast<unsigned long long> ((hwh << width) + hwl);
+ unsigned long long val (integer_value (tval));
// There doesn't seem to be a way to get the proper position for
// each enumerator.
@@ -1810,28 +1802,22 @@ create_type (tree t,
if (TREE_CODE (max) == INTEGER_CST)
{
- HOST_WIDE_INT hwl (TREE_INT_CST_LOW (max));
- HOST_WIDE_INT hwh (TREE_INT_CST_HIGH (max));
+ size = integer_value (max);
// The docs say that TYPE_DOMAIN will be NULL if the
- // array doesn't specify bounds. In reality, both
- // low and high parts are set to HOST_WIDE_INT_MAX.
+ // array doesn't specify bounds. In reality, it is
+ // set to ~0.
//
- if (hwl != ~(HOST_WIDE_INT) (0) && hwh != ~(HOST_WIDE_INT) (0))
- {
- unsigned long long l (hwl);
- unsigned long long h (hwh);
- unsigned short width (HOST_BITS_PER_WIDE_INT);
+ if (size == ~(unsigned long long) (0))
+ size = 0;
- size = (h << width) + l + 1;
- }
+ size++; // Convert max index to size.
}
else
{
error (file, line, clmn)
<< "non-integer array index " <<
- gcc_tree_code_name(TREE_CODE (max))
- << endl;
+ gcc_tree_code_name(TREE_CODE (max)) << endl;
throw failed ();
}
@@ -2041,17 +2027,14 @@ emit_type_name (tree type, bool direct)
if (TREE_CODE (max) == INTEGER_CST)
{
- HOST_WIDE_INT hwl (TREE_INT_CST_LOW (max));
- HOST_WIDE_INT hwh (TREE_INT_CST_HIGH (max));
+ size = integer_value (max);
- if (hwl != ~(HOST_WIDE_INT) (0) && hwh != ~(HOST_WIDE_INT) (0))
- {
- unsigned long long l (hwl);
- unsigned long long h (hwh);
- unsigned short width (HOST_BITS_PER_WIDE_INT);
+ // Same as above.
+ //
+ if (size == ~(unsigned long long) (0))
+ size = 0;
- size = (h << width) + l + 1;
- }
+ size++;
}
else
{
@@ -2227,15 +2210,23 @@ fq_scope (tree decl)
string s, tmp;
for (tree scope (CP_DECL_CONTEXT (decl));
- scope != global_namespace;
- scope = CP_DECL_CONTEXT (scope))
+ scope != global_namespace;)
{
- tree n = DECL_NAME (scope);
+ tree prev (CP_DECL_CONTEXT (scope));
+
+ // If this is an inline namespace, pretend it doesn't exist.
+ //
+ if (!is_associated_namespace (prev, scope))
+ {
+ tree n = DECL_NAME (scope);
+
+ tmp = "::";
+ tmp += (n != NULL_TREE ? IDENTIFIER_POINTER (n) : "");
+ tmp += s;
+ s.swap (tmp);
+ }
- tmp = "::";
- tmp += (n != NULL_TREE ? IDENTIFIER_POINTER (n) : "");
- tmp += s;
- s.swap (tmp);
+ scope = prev;
}
return s;
diff --git a/odb/plugin.cxx b/odb/plugin.cxx
index ec4aaeb..e32f225 100644
--- a/odb/plugin.cxx
+++ b/odb/plugin.cxx
@@ -277,10 +277,7 @@ plugin_init (plugin_name_args* plugin_info, plugin_gcc_version*)
//
{
strings argv_str;
- vector<char*> argv;
-
argv_str.push_back (plugin_info->base_name);
- argv.push_back (const_cast<char*> (argv_str.back ().c_str ()));
for (int i (0); i < plugin_info->argc; ++i)
{
@@ -319,22 +316,22 @@ plugin_init (plugin_name_args* plugin_info, plugin_gcc_version*)
opt += a.key;
argv_str.push_back (opt);
- argv.push_back (const_cast<char*> (argv_str.back ().c_str ()));
if (!v.empty ())
- {
argv_str.push_back (v);
- argv.push_back (const_cast<char*> (argv_str.back ().c_str ()));
- }
}
+ vector<char*> argv;
+ for (strings::iterator i (argv_str.begin ()); i != argv_str.end (); ++i)
+ argv.push_back (const_cast<char*> (i->c_str ()));
+
+ int argc (static_cast<int> (argv.size ()));
+
if (inputs_.empty ())
inputs_.push_back (file_);
// Two-phase options parsing, similar to the driver.
//
- int argc (static_cast<int> (argv.size ()));
-
cli::argv_file_scanner::option_info oi[3];
oi[0].option = "--options-file";
oi[0].search_func = 0;
diff --git a/odb/pragma.cxx b/odb/pragma.cxx
index db0a155..c8a3254 100644
--- a/odb/pragma.cxx
+++ b/odb/pragma.cxx
@@ -31,20 +31,6 @@ ns_loc_pragmas ns_loc_pragmas_;
database pragma_db_;
multi_database pragma_multi_;
-static unsigned long long
-integer (tree n)
-{
- HOST_WIDE_INT hwl (TREE_INT_CST_LOW (n));
- HOST_WIDE_INT hwh (TREE_INT_CST_HIGH (n));
-
- unsigned long long l (hwl);
- unsigned long long h (hwh);
- unsigned short width (HOST_BITS_PER_WIDE_INT);
-
- unsigned long long v ((h << width) + l);
- return v;
-}
-
template <typename X>
void
accumulate (compiler::context& ctx, string const& k, any const& v, location_t)
@@ -226,7 +212,7 @@ parse_expression (cxx_lexer& l,
case INTEGER_CST:
{
tree type (TREE_TYPE (tn));
- unsigned long long v (integer (tn));
+ unsigned long long v (integer_value (tn));
ostringstream os;
os << v;
@@ -734,7 +720,7 @@ handle_pragma (cxx_lexer& l,
return;
}
- v.base = integer (tn);
+ v.base = integer_value (tn);
if (v.base == 0)
{
@@ -756,7 +742,7 @@ handle_pragma (cxx_lexer& l,
return;
}
- v.current = integer (tn);
+ v.current = integer_value (tn);
if (v.current == 0)
{
@@ -1550,7 +1536,7 @@ handle_pragma (cxx_lexer& l,
return;
}
- unsigned long long b (integer (tn));
+ unsigned long long b (integer_value (tn));
if (b == 0 || b == 1)
{
@@ -2217,12 +2203,11 @@ handle_pragma (cxx_lexer& l,
}
case CPP_NUMBER:
{
- ///////
switch (TREE_CODE (tn))
{
case INTEGER_CST:
{
- dv.int_value = integer (tn);
+ dv.int_value = integer_value (tn);
dv.kind = default_value::integer;
break;
}
@@ -2531,7 +2516,7 @@ handle_pragma (cxx_lexer& l,
return;
}
- unsigned long long v (integer (tn));
+ unsigned long long v (integer_value (tn));
if (v == 0)
{
diff --git a/odb/processor.cxx b/odb/processor.cxx
index 1971472..a808a52 100644
--- a/odb/processor.cxx
+++ b/odb/processor.cxx
@@ -285,7 +285,7 @@ namespace
// Otherwise look for a by value modifier, which is a function
// with a single argument.
//
- else if (DECL_CHAIN (a) == void_list_node)
+ else if (TREE_CHAIN (a) == void_list_node)
{
// In the lax mode any function with a single argument works
// for us. And we don't care what it returns.
@@ -1028,20 +1028,7 @@ namespace
if (init == error_mark_node || TREE_CODE (init) != INTEGER_CST)
throw operation_failed ();
- unsigned long long e;
-
- {
- HOST_WIDE_INT hwl (TREE_INT_CST_LOW (init));
- HOST_WIDE_INT hwh (TREE_INT_CST_HIGH (init));
-
- unsigned long long l (hwl);
- unsigned long long h (hwh);
- unsigned short width (HOST_BITS_PER_WIDE_INT);
-
- e = (h << width) + l;
- }
-
- null_handler = static_cast<bool> (e);
+ null_handler = static_cast<bool> (integer_value (init));
t.set ("wrapper-null-handler", null_handler);
}
catch (operation_failed const&)
@@ -1077,20 +1064,8 @@ namespace
if (init == error_mark_node || TREE_CODE (init) != INTEGER_CST)
throw operation_failed ();
- unsigned long long e;
-
- {
- HOST_WIDE_INT hwl (TREE_INT_CST_LOW (init));
- HOST_WIDE_INT hwh (TREE_INT_CST_HIGH (init));
-
- unsigned long long l (hwl);
- unsigned long long h (hwh);
- unsigned short width (HOST_BITS_PER_WIDE_INT);
-
- e = (h << width) + l;
- }
-
- t.set ("wrapper-null-default", static_cast<bool> (e));
+ t.set ("wrapper-null-default",
+ static_cast<bool> (integer_value (init)));
}
catch (operation_failed const&)
{
@@ -1250,20 +1225,8 @@ namespace
if (init == error_mark_node || TREE_CODE (init) != INTEGER_CST)
throw operation_failed ();
- unsigned long long e;
-
- {
- HOST_WIDE_INT hwl (TREE_INT_CST_LOW (init));
- HOST_WIDE_INT hwh (TREE_INT_CST_HIGH (init));
-
- unsigned long long l (hwl);
- unsigned long long h (hwh);
- unsigned short width (HOST_BITS_PER_WIDE_INT);
-
- e = (h << width) + l;
- }
-
- pointer_kind_type pk = static_cast<pointer_kind_type> (e);
+ pointer_kind_type pk = static_cast<pointer_kind_type> (
+ integer_value (init));
t.set ("pointer-kind", pk);
}
catch (operation_failed const&)
@@ -1296,20 +1259,7 @@ namespace
if (init == error_mark_node || TREE_CODE (init) != INTEGER_CST)
throw operation_failed ();
- unsigned long long e;
-
- {
- HOST_WIDE_INT hwl (TREE_INT_CST_LOW (init));
- HOST_WIDE_INT hwh (TREE_INT_CST_HIGH (init));
-
- unsigned long long l (hwl);
- unsigned long long h (hwh);
- unsigned short width (HOST_BITS_PER_WIDE_INT);
-
- e = (h << width) + l;
- }
-
- t.set ("pointer-lazy", static_cast<bool> (e));
+ t.set ("pointer-lazy", static_cast<bool> (integer_value (init)));
}
catch (operation_failed const&)
{
@@ -1552,20 +1502,7 @@ namespace
if (init == error_mark_node || TREE_CODE (init) != INTEGER_CST)
throw operation_failed ();
- unsigned long long e;
-
- {
- HOST_WIDE_INT hwl (TREE_INT_CST_LOW (init));
- HOST_WIDE_INT hwh (TREE_INT_CST_HIGH (init));
-
- unsigned long long l (hwl);
- unsigned long long h (hwh);
- unsigned short width (HOST_BITS_PER_WIDE_INT);
-
- e = (h << width) + l;
- }
-
- ck = static_cast<container_kind_type> (e);
+ ck = static_cast<container_kind_type> (integer_value (init));
}
catch (operation_failed const&)
{
@@ -1601,20 +1538,7 @@ namespace
if (init == error_mark_node || TREE_CODE (init) != INTEGER_CST)
throw operation_failed ();
- unsigned long long e;
-
- {
- HOST_WIDE_INT hwl (TREE_INT_CST_LOW (init));
- HOST_WIDE_INT hwh (TREE_INT_CST_HIGH (init));
-
- unsigned long long l (hwl);
- unsigned long long h (hwh);
- unsigned short width (HOST_BITS_PER_WIDE_INT);
-
- e = (h << width) + l;
- }
-
- smart = static_cast<bool> (e);
+ smart = static_cast<bool> (integer_value (init));
}
catch (operation_failed const&)
{
@@ -3003,6 +2927,19 @@ namespace
tree decl (resolve_name (t, resolve_scope, false));
tree scope (CP_DECL_CONTEXT (decl));
+ // If this is an inline namespace, skip it until we get
+ // to the non-inline one.
+ //
+ while (scope != global_namespace)
+ {
+ tree prev (CP_DECL_CONTEXT (scope));
+
+ if (!is_associated_namespace (prev, scope))
+ break;
+
+ scope = prev;
+ }
+
if (scope != global_namespace)
{
ptr += "::";
diff --git a/odb/relational/source.hxx b/odb/relational/source.hxx
index dea8f96..716aa10 100644
--- a/odb/relational/source.hxx
+++ b/odb/relational/source.hxx
@@ -6689,7 +6689,7 @@ namespace relational
virtual string
join_syntax (view_object const& vo)
{
- const char* r;
+ const char* r (0);
switch (vo.join)
{
diff --git a/odb/semantics/elements.cxx b/odb/semantics/elements.cxx
index 65d6118..21e3260 100644
--- a/odb/semantics/elements.cxx
+++ b/odb/semantics/elements.cxx
@@ -113,8 +113,25 @@ namespace semantics
tree s (CP_DECL_CONTEXT (decl));
- if (TREE_CODE (s) == TYPE_DECL)
+ gcc_tree_code_type tc (TREE_CODE (s));
+
+ if (tc == TYPE_DECL)
s = TREE_TYPE (s);
+ else if (tc == NAMESPACE_DECL)
+ {
+ // "Unwind" any inline namespaces since they are not in
+ // semantic grapth.
+ //
+ while (s != global_namespace)
+ {
+ tree prev (CP_DECL_CONTEXT (s));
+
+ if (!is_associated_namespace (prev, s))
+ break;
+
+ s = prev;
+ }
+ }
if (nameable* n = dynamic_cast<nameable*> (unit ().find (s)))
return scope.find (n) || n->fq_anonymous_ (&scope);
@@ -155,12 +172,23 @@ namespace semantics
bool punc (false);
bool scoped (false);
- for (cpp_ttype tt = l.next (t); tt != CPP_EOF; tt = l.next (t))
+ // Names returned by GCC's type_as_string() (on which this function
+ // is called) include inline namespaces (e.g., std::__cxx11::string).
+ // So, besides fully-qualifying names, this function also needs to get
+ // rid of those. The idea is to resolve names as we lex them, skipping
+ // inline namespaces and stopping once we reach something other than a
+ // namespace.
+ //
+ tree ns (global_namespace);
+ tree id;
+
+ for (cpp_ttype tt = l.next (t, &id); tt != CPP_EOF; tt = l.next (t, &id))
{
if (punc && tt > CPP_LAST_PUNCTUATOR)
r += ' ';
punc = false;
+ tree new_ns (global_namespace); // By default, revert to global.
switch (static_cast<unsigned> (tt))
{
@@ -181,6 +209,35 @@ namespace semantics
}
case CPP_NAME:
{
+ // Check if this is a namespace and, if so, whether it is
+ // inline.
+ //
+ if (ns != 0)
+ {
+ new_ns = lookup_qualified_name (ns, id, false, false);
+
+ if (new_ns == error_mark_node ||
+ TREE_CODE (new_ns) != NAMESPACE_DECL)
+ new_ns = 0; // Not a namespace, stop resolving.
+ else
+ {
+ // Check if this is an inline namespace and skip it if so.
+ //
+ if (is_associated_namespace (ns, new_ns))
+ {
+ // Skip also the following scope operator. Strictly speaking
+ // there could be none (i.e., this is a name of an inline
+ // namespace) but we only use this function to print names
+ // of anonymous types.
+ //
+ assert (l.next (t) == CPP_SCOPE);
+ continue;
+ }
+ }
+ }
+ else
+ new_ns = 0; // Keep it disabled until we hit a new name.
+
// If the name was not preceeded with '::', qualify it.
//
if (!scoped)
@@ -202,6 +259,11 @@ namespace semantics
punc = true;
break;
}
+ case CPP_SCOPE:
+ {
+ new_ns = ns; // Don't change the namespace.
+ // Fall through.
+ }
default:
{
r += t;
@@ -210,6 +272,7 @@ namespace semantics
}
scoped = (tt == CPP_SCOPE);
+ ns = new_ns;
}
return r;