aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2012-09-17 08:17:06 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2012-09-17 08:17:06 +0200
commit76088fe3dfdf541281942b43cb72b021b6fd2ee3 (patch)
treed85ded1a5f23b0227914a1841e4323e91b2170ad
parent9b7f203f1f8a40765649312442efa9602335f757 (diff)
Convert integer and floating default values immediately2.1.0
It appears that GCC 4.8 reuses token tree nodes that are returned during pragma parsing. So saving such nodes for later no longer works.
-rw-r--r--odb/context.hxx19
-rw-r--r--odb/pragma.cxx64
-rw-r--r--odb/relational/model.cxx72
3 files changed, 73 insertions, 82 deletions
diff --git a/odb/context.hxx b/odb/context.hxx
index 8ae110a..4503e7f 100644
--- a/odb/context.hxx
+++ b/odb/context.hxx
@@ -117,15 +117,22 @@ struct default_value
{
reset, // Default value reset.
null,
- boolean,
- number, // Integer of floating-point number. Value contains sign.
- string,
- enumerator // Value is the name, node is the tree node.
+ boolean, // Literal contains value (true or false).
+ integer, // Integer number. Literal contains sign.
+ floating, // Floating-point number.
+ string, // Literal contains value.
+ enumerator // Literal is the name, enum_value is the tree node.
};
kind_type kind;
- std::string value;
- tree node;
+ std::string literal;
+
+ union
+ {
+ tree enum_value;
+ unsigned long long int_value;
+ double float_value;
+ };
};
// Database potentially-qualified name.
diff --git a/odb/pragma.cxx b/odb/pragma.cxx
index afdbd1d..911afce 100644
--- a/odb/pragma.cxx
+++ b/odb/pragma.cxx
@@ -5,6 +5,7 @@
#include <odb/gcc.hxx>
#include <cctype> // std::isalnum
+#include <limits>
#include <vector>
#include <sstream>
@@ -1800,7 +1801,7 @@ handle_pragma (cxx_lexer& l,
case CPP_STRING:
{
dv.kind = default_value::string;
- dv.value = tl;
+ dv.literal = tl;
tt = l.next (tl, &tn);
break;
}
@@ -1820,10 +1821,10 @@ handle_pragma (cxx_lexer& l,
{
// We have a potentially scopped enumerator name.
//
- dv.node = resolve_scoped_name (
- l, tt, tl, tn, current_scope (), dv.value, false, p);
+ dv.enum_value = resolve_scoped_name (
+ l, tt, tl, tn, current_scope (), dv.literal, false, p);
- if (dv.node == 0)
+ if (dv.enum_value == 0)
return; // Diagnostics has already been issued.
dv.kind = default_value::enumerator;
@@ -1833,7 +1834,7 @@ handle_pragma (cxx_lexer& l,
case CPP_PLUS:
{
if (tt == CPP_MINUS)
- dv.value = "-";
+ dv.literal = "-";
tt = l.next (tl, &tn);
@@ -1849,17 +1850,52 @@ handle_pragma (cxx_lexer& l,
}
case CPP_NUMBER:
{
- int tc (TREE_CODE (tn));
-
- if (tc != INTEGER_CST && tc != REAL_CST)
+ ///////
+ switch (TREE_CODE (tn))
{
- error (l) << "unexpected numeric constant in db pragma " << p
- << endl;
- return;
+ case INTEGER_CST:
+ {
+ HOST_WIDE_INT hwl (TREE_INT_CST_LOW (tn));
+ HOST_WIDE_INT hwh (TREE_INT_CST_HIGH (tn));
+
+ unsigned long long l (hwl);
+ unsigned long long h (hwh);
+ unsigned short width (HOST_BITS_PER_WIDE_INT);
+
+ dv.int_value = (h << width) + l;
+ dv.kind = default_value::integer;
+ break;
+ }
+ case REAL_CST:
+ {
+ REAL_VALUE_TYPE d (TREE_REAL_CST (tn));
+
+ if (REAL_VALUE_ISINF (d))
+ dv.float_value = numeric_limits<double>::infinity ();
+ else if (REAL_VALUE_ISNAN (d))
+ dv.float_value = numeric_limits<double>::quiet_NaN ();
+ else
+ {
+ char tmp[256];
+ real_to_decimal (tmp, &d, sizeof (tmp), 0, true);
+ istringstream is (tmp);
+ is >> dv.float_value;
+ }
+
+ if (dv.literal == "-")
+ dv.float_value = -dv.float_value;
+
+ dv.kind = default_value::floating;
+ break;
+ }
+ default:
+ {
+ error (l) << "unexpected numeric constant in db pragma " << p
+ << endl;
+ return;
+ }
}
- dv.node = tn;
- dv.kind = default_value::number;
tt = l.next (tl, &tn);
break;
}
@@ -1870,7 +1906,7 @@ handle_pragma (cxx_lexer& l,
if (tt == CPP_KEYWORD && (tl == "true" || tl == "false"))
{
dv.kind = default_value::boolean;
- dv.value = tl;
+ dv.literal = tl;
tt = l.next (tl, &tn);
}
else
diff --git a/odb/relational/model.cxx b/odb/relational/model.cxx
index 48c9bd2..6b8db1b 100644
--- a/odb/relational/model.cxx
+++ b/odb/relational/model.cxx
@@ -2,12 +2,6 @@
// copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC
// license : GNU GPL v3; see accompanying LICENSE file
-#include <odb/gcc.hxx>
-
-#include <cassert>
-#include <limits>
-#include <sstream>
-
#include <odb/diagnostics.hxx>
#include <odb/relational/model.hxx>
@@ -39,77 +33,31 @@ namespace relational
{
case default_value::reset:
{
- // No default value.
- return "";
+ return ""; // No default value.
}
case default_value::null:
{
return default_null (m);
- break;
}
case default_value::boolean:
{
- return default_bool (m, dv->value == "true");
- break;
+ return default_bool (m, dv->literal == "true");
+ }
+ case default_value::integer:
+ {
+ return default_integer (m, dv->int_value, dv->literal == "-");
}
- case default_value::number:
+ case default_value::floating:
{
- tree n (dv->node);
-
- switch (TREE_CODE (n))
- {
- case INTEGER_CST:
- {
- 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 default_integer (m, v, dv->value == "-");
- break;
- }
- case REAL_CST:
- {
- double v;
-
- REAL_VALUE_TYPE d (TREE_REAL_CST (n));
-
- if (REAL_VALUE_ISINF (d))
- v = numeric_limits<double>::infinity ();
- else if (REAL_VALUE_ISNAN (d))
- v = numeric_limits<double>::quiet_NaN ();
- else
- {
- char tmp[256];
- real_to_decimal (tmp, &d, sizeof (tmp), 0, true);
- istringstream is (tmp);
- is >> v;
- }
-
- if (dv->value == "-")
- v = -v;
-
- return default_float (m, v);
- break;
- }
- default:
- assert (false);
- }
- break;
+ return default_float (m, dv->float_value);
}
case default_value::string:
{
- return default_string (m, dv->value);
- break;
+ return default_string (m, dv->literal);
}
case default_value::enumerator:
{
- return default_enum (m, dv->node, dv->value);
- break;
+ return default_enum (m, dv->enum_value, dv->literal);
}
}