summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp')
-rw-r--r--cpp/include/Slice/CPlusPlusUtil.h2
-rw-r--r--cpp/include/Slice/Parser.h14
-rw-r--r--cpp/src/Slice/CPlusPlusUtil.cpp20
-rw-r--r--cpp/src/Slice/Scanner.l2
-rw-r--r--cpp/src/slice2cpp/Gen.cpp18
-rw-r--r--cpp/test/Slice/errorDetection/ConstDef.err16
-rw-r--r--cpp/test/Slice/errorDetection/ConstDef.ice9
7 files changed, 59 insertions, 22 deletions
diff --git a/cpp/include/Slice/CPlusPlusUtil.h b/cpp/include/Slice/CPlusPlusUtil.h
index fff635b57a9..ccf7c6d7be7 100644
--- a/cpp/include/Slice/CPlusPlusUtil.h
+++ b/cpp/include/Slice/CPlusPlusUtil.h
@@ -25,6 +25,8 @@ struct ToIfdef
SLICE_API std::string changeInclude(const std::string&, const std::vector<std::string>&);
SLICE_API void printHeader(::IceUtil::Output&);
SLICE_API void printVersionCheck(::IceUtil::Output&);
+SLICE_API void Slice::printDefInt64Macro(::IceUtil::Output&);
+SLICE_API void Slice::printUndefInt64Macro(::IceUtil::Output&);
SLICE_API void printDllExportStuff(::IceUtil::Output&, const std::string&);
SLICE_API std::string typeToString(const TypePtr&);
diff --git a/cpp/include/Slice/Parser.h b/cpp/include/Slice/Parser.h
index ce3c9055488..222a8d880ab 100644
--- a/cpp/include/Slice/Parser.h
+++ b/cpp/include/Slice/Parser.h
@@ -37,22 +37,26 @@ namespace Slice
# define STRTOLL(a, b, c) _atoi64(a)
typedef __int64 Long;
typedef double Double;
- const Long INT32_MIN = -0x80000000i64;
+ const Long INT64_MAX = 0x7fffffffffffffffi64;
+ const Long INT64_MIN = -INT64_MAX - 1i64;
const Long INT32_MAX = 0x7fffffffi64;
+ const Long INT32_MIN = -INT32_MAX - 1i64;
#elif(__linux__) && defined(i386)
# define STRTOLL(a, b, c) strtoll((a), (b), (c))
typedef long long Long;
typedef double Double;
- const Long INT32_MIN = -0x80000000LL;
+ const Long INT64_MAX = 0x7fffffffffffffffLL;
+ const Long INT64_MIN = -INT64_MAX - 1LL;
const Long INT32_MAX = 0x7fffffffLL;
+ const Long INT32_MIN = -INT32_MAX - 1LL;
#else
# error "Unsupported operating system or platform!"
#endif
-const Long BYTE_MIN = 0x00;
-const Long BYTE_MAX = 0xff;
-const Long INT16_MIN = -0x8000;
const Long INT16_MAX = 0x7fff;
+const Long INT16_MIN = -INT16_MAX - 1;
+const Long BYTE_MAX = 0xff;
+const Long BYTE_MIN = 0x00;
class GrammarBase;
class SyntaxTreeBase;
diff --git a/cpp/src/Slice/CPlusPlusUtil.cpp b/cpp/src/Slice/CPlusPlusUtil.cpp
index 0c800c87ac4..79725c6f4b4 100644
--- a/cpp/src/Slice/CPlusPlusUtil.cpp
+++ b/cpp/src/Slice/CPlusPlusUtil.cpp
@@ -88,6 +88,26 @@ Slice::printVersionCheck(Output& out)
}
void
+Slice::printDefInt64Macro(Output& out)
+{
+ out << "\n";
+ out << "\n#if defined(_WIN32)";
+ out << "\n# define INT64LITERAL(n) n##i64";
+ out << "\n#elif defined(__linux__) && defined(i386)";
+ out << "\n# define INT64LITERAL(n) n##LL";
+ out << "\n#else";
+ out << "\n# error \"Unsupported operating system or platform!\"";
+ out << "\n#endif";
+}
+
+void
+Slice::printUndefInt64Macro(Output& out)
+{
+ out << "\n";
+ out << "\n#undef INT64LITERAL";
+}
+
+void
Slice::printDllExportStuff(Output& out, const string& dllExport)
{
if(dllExport.size())
diff --git a/cpp/src/Slice/Scanner.l b/cpp/src/Slice/Scanner.l
index 4cb68b02448..ea280da5d96 100644
--- a/cpp/src/Slice/Scanner.l
+++ b/cpp/src/Slice/Scanner.l
@@ -317,7 +317,7 @@ floating_literal (({fractional_constant}{exponent_part}?)|([[:digit:]]+{exponent
}
#else
itp->v = strtoll(yytext, 0, 0);
- if(errno == ERANGE)
+ if(errno == ERANGE && (itp->v == INT64_MIN || itp->v == INT64_MAX))
{
string msg = "integer constant `";
msg += yytext;
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp
index db6643bf6ba..06bec36200c 100644
--- a/cpp/src/slice2cpp/Gen.cpp
+++ b/cpp/src/slice2cpp/Gen.cpp
@@ -214,6 +214,8 @@ Slice::Gen::generate(const UnitPtr& unit)
_dllExport += " ";
}
+ printDefInt64Macro(H);
+
ProxyDeclVisitor proxyDeclVisitor(H, C, _dllExport);
unit->visit(&proxyDeclVisitor);
@@ -263,6 +265,8 @@ Slice::Gen::generate(const UnitPtr& unit)
ImplVisitor implVisitor(implH, implC, _dllExport);
unit->visit(&implVisitor);
}
+
+ printUndefInt64Macro(H);
}
Slice::Gen::TypesVisitor::TypesVisitor(Output& h, Output& c, const string& dllExport) :
@@ -935,11 +939,7 @@ Slice::Gen::TypesVisitor::visitConstDef(const ConstDefPtr& p)
H << nl << "const " << typeToString(p->type()) << " " << p->name() << " = ";
BuiltinPtr bp = BuiltinPtr::dynamicCast(p->type());
- if(bp && bp->kind() != Builtin::KindString)
- {
- H << p->value();
- }
- else
+ if(bp && bp->kind() == Builtin::KindString)
{
//
// Expand strings into the basic source character set. We can't use isalpha() and the like
@@ -981,6 +981,14 @@ Slice::Gen::TypesVisitor::visitConstDef(const ConstDefPtr& p)
H << "\""; // Closing "
}
+ else if(bp && bp->kind() == Builtin::KindLong)
+ {
+ H << "INT64LITERAL(" << p->value() << ")";
+ }
+ else
+ {
+ H << p->value();
+ }
H << ";";
}
diff --git a/cpp/test/Slice/errorDetection/ConstDef.err b/cpp/test/Slice/errorDetection/ConstDef.err
index d890adac9d4..f88b1e02c87 100644
--- a/cpp/test/Slice/errorDetection/ConstDef.err
+++ b/cpp/test/Slice/errorDetection/ConstDef.err
@@ -11,11 +11,11 @@ ConstDef.ice:49: initializer of type `bool' is incompatible with the type `long'
ConstDef.ice:51: missing constant name
ConstDef.ice:54: enumerator `two' is not defined in enumeration `::color'
ConstDef.ice:55: type of initializer is incompatible with the type of constant `ic10'
-ConstDef.ice:68: integer constant `-9223372036854775809' out of range
-ConstDef.ice:69: integer constant `+9223372036854775808' out of range
-ConstDef.ice:73: initializer `-2147483649' for constant `i3' out of range for type int
-ConstDef.ice:74: initializer `2147483648' for constant `i4' out of range for type int
-ConstDef.ice:78: initializer `-32769' for constant `s3' out of range for type short
-ConstDef.ice:79: initializer `32768' for constant `s4' out of range for type short
-ConstDef.ice:83: initializer `-1' for constant `b3' out of range for type byte
-ConstDef.ice:84: initializer `256' for constant `b4' out of range for type byte
+ConstDef.ice:71: integer constant `-9223372036854775809' out of range
+ConstDef.ice:72: integer constant `+9223372036854775808' out of range
+ConstDef.ice:76: initializer `-2147483649' for constant `i3' out of range for type int
+ConstDef.ice:77: initializer `2147483648' for constant `i4' out of range for type int
+ConstDef.ice:81: initializer `-32769' for constant `s3' out of range for type short
+ConstDef.ice:82: initializer `32768' for constant `s4' out of range for type short
+ConstDef.ice:86: initializer `-1' for constant `b3' out of range for type byte
+ConstDef.ice:87: initializer `256' for constant `b4' out of range for type byte
diff --git a/cpp/test/Slice/errorDetection/ConstDef.ice b/cpp/test/Slice/errorDetection/ConstDef.ice
index 2c8b214aae7..164b60032a6 100644
--- a/cpp/test/Slice/errorDetection/ConstDef.ice
+++ b/cpp/test/Slice/errorDetection/ConstDef.ice
@@ -61,10 +61,13 @@ const long r1 = 9223372036854775807; // LLONG_MAX, OK
const long r2 = -9223372036854775807; // -LLONG_MAX, OK
//
-// The following should work -- it's 0xffffffffffffffff. But strtoll()
-// has a bug and won't convert that (legal) value.
+// TODO: This should work, but doesn't. STLport can't handle inserting
+// LLONG_MIN onto a stream and inserts garbage. We can periodically try
+// this again as new versions of STLport come out...
//
-const long r3 = -9223372036854775808; // LLONG_MIN
+// const long r3 = -9223372036854775808; // LLONG_MIN, OK
+//
+
const long r4 = -9223372036854775809; // underflow
const long r5 = +9223372036854775808; // overflow