Blob Blame History Raw
From: Boris Kolpackov <boris@codesynthesis.com>
Date: Sat, 7 Feb 2015 11:07:12 +0000 (+0200)
Subject: Fix to work with GCC 5
X-Git-Url: http://scm.codesynthesis.com/?p=odb%2Fodb.git;a=commitdiff_plain;h=ee9c9f3db3eb4b689e565c282345b1f49bba5042;hp=00c779a294a86c2e9ce2d2a09216e169dd69a666

Fix to work with GCC 5
---

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;