summaryrefslogtreecommitdiff
path: root/cpp/src/slice2cpp/Gen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/slice2cpp/Gen.cpp')
-rw-r--r--cpp/src/slice2cpp/Gen.cpp5543
1 files changed, 3945 insertions, 1598 deletions
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp
index 2e5e9b2a3f5..140438eb37e 100644
--- a/cpp/src/slice2cpp/Gen.cpp
+++ b/cpp/src/slice2cpp/Gen.cpp
@@ -14,7 +14,8 @@
#include <IceUtil/Functional.h>
#include <IceUtil/Iterator.h>
#include <IceUtil/InputUtil.h>
-#include <IceUtil/Unicode.h>
+#include <IceUtil/StringConverter.h>
+#include <IceUtil/StringUtil.h>
#include <Slice/Checksum.h>
#include <Slice/FileTracker.h>
#include <IceUtil/FileUtil.h>
@@ -30,8 +31,58 @@ using namespace IceUtilInternal;
namespace
{
+bool
+isConstexprType(const TypePtr& type)
+{
+ BuiltinPtr bp = BuiltinPtr::dynamicCast(type);
+ if(bp)
+ {
+ switch(bp->kind())
+ {
+ case Builtin::KindByte:
+ case Builtin::KindBool:
+ case Builtin::KindShort:
+ case Builtin::KindInt:
+ case Builtin::KindLong:
+ case Builtin::KindFloat:
+ case Builtin::KindDouble:
+ case Builtin::KindValue:
+ case Builtin::KindObject:
+ case Builtin::KindObjectProxy:
+ {
+ return true;
+ }
+ default:
+ {
+ return false;
+ }
+ }
+ }
+ else if(EnumPtr::dynamicCast(type) || ProxyPtr::dynamicCast(type) || ClassDeclPtr::dynamicCast(type))
+ {
+ return true;
+ }
+ else
+ {
+ StructPtr s = StructPtr::dynamicCast(type);
+ if(s)
+ {
+ DataMemberList members = s->dataMembers();
+ for(DataMemberList::const_iterator i = members.begin(); i != members.end(); ++i)
+ {
+ if(!isConstexprType((*i)->type()))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+}
+
string
-u32CodePoint(unsigned int value)
+u32CodePoint(unsigned int value, bool cpp11)
{
ostringstream s;
//
@@ -39,7 +90,7 @@ u32CodePoint(unsigned int value)
// With VC++ < 140 characters in the range of 0 to 0x9f cannot be represented
// with a universal character name (UCN).
//
- if(value <= 0x9f)
+ if(!cpp11 && value <= 0x9f)
{
switch(value)
{
@@ -79,28 +130,13 @@ u32CodePoint(unsigned int value)
}
void
-writeU8Buffer(const vector<unsigned char>& u8buffer, ::IceUtilInternal::Output& out)
+writeU8Buffer(const vector<unsigned char>& u8buffer, ::IceUtilInternal::Output& out, bool cpp11)
{
- vector<unsigned int> u32buffer;
- IceUtilInternal::ConversionResult result = convertUTF8ToUTF32(u8buffer, u32buffer, IceUtil::lenientConversion);
- switch(result)
- {
- case conversionOK:
- break;
- case sourceExhausted:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source exhausted");
- case sourceIllegal:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source illegal");
- default:
- {
- assert(0);
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__);
- }
- }
+ vector<unsigned int> u32buffer = toUTF32(u8buffer);
for(vector<unsigned int>::const_iterator c = u32buffer.begin(); c != u32buffer.end(); ++c)
{
- out << u32CodePoint(*c);
+ out << u32CodePoint(*c, cpp11);
}
}
@@ -123,7 +159,7 @@ getDeprecateSymbol(const ContainedPtr& p1, const ContainedPtr& p2)
void
writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const SyntaxTreeBasePtr& valueType,
- const string& value, int useWstring, const StringList& metaData)
+ const string& value, int useWstring, const StringList& metaData, bool cpp11 = false)
{
ConstPtr constant = ConstPtr::dynamicCast(valueType);
if(constant)
@@ -144,21 +180,21 @@ writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const Synt
"0123456789"
"_{}[]#()<>%:;.?*+-/^&|~!=,\\\"' ";
static const set<char> charSet(basicSourceChars.begin(), basicSourceChars.end());
-
- if((useWstring & TypeContextUseWstring) || findMetaData(metaData) == "wstring")
+ bool wide = (useWstring & TypeContextUseWstring) || findMetaData(metaData) == "wstring";
+ if(wide || cpp11)
{
//
- // Wide strings
+ // Wide strings or C++11 narrow string
//
vector<unsigned char> u8buffer; // Buffer to convert multibyte characters
- out << "L\"";
+ out << (wide ? "L\"" : "u8\"");
for(size_t i = 0; i < value.size();)
{
if(charSet.find(value[i]) == charSet.end())
{
if(static_cast<unsigned char>(value[i]) < 128) // Single byte character
{
- out << u32CodePoint(static_cast<unsigned char>(value[i]));
+ out << u32CodePoint(static_cast<unsigned char>(value[i]), cpp11);
}
else
{
@@ -172,7 +208,7 @@ writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const Synt
//
if(!u8buffer.empty())
{
- writeU8Buffer(u8buffer, out);
+ writeU8Buffer(u8buffer, out, cpp11);
u8buffer.clear();
}
@@ -210,7 +246,7 @@ writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const Synt
assert(codepoint.size() == sz);
IceUtil::Int64 v = IceUtilInternal::strToInt64(codepoint.c_str(), 0, 16);
- out << u32CodePoint(static_cast<unsigned int>(v));
+ out << u32CodePoint(static_cast<unsigned int>(v), cpp11);
i = j + 1 + sz;
}
@@ -239,12 +275,12 @@ writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const Synt
//
if(!u8buffer.empty())
{
- writeU8Buffer(u8buffer, out);
+ writeU8Buffer(u8buffer, out, cpp11);
u8buffer.clear();
}
out << "\"";
}
- else // narrow strings
+ else // C++98 narrow strings
{
out << "\""; // Opening "
@@ -302,23 +338,7 @@ writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const Synt
vector<unsigned int> u32buffer;
u32buffer.push_back(static_cast<unsigned int>(v));
- vector<unsigned char> u8buffer;
-
- IceUtilInternal::ConversionResult result = convertUTF32ToUTF8(u32buffer, u8buffer, IceUtil::lenientConversion);
- switch(result)
- {
- case conversionOK:
- break;
- case sourceExhausted:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source exhausted");
- case sourceIllegal:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source illegal");
- default:
- {
- assert(0);
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__);
- }
- }
+ vector<unsigned char> u8buffer = fromUTF32(u32buffer);
ostringstream s;
for(vector<unsigned char>::const_iterator q = u8buffer.begin(); q != u8buffer.end(); ++q)
@@ -356,7 +376,14 @@ writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const Synt
}
else if(bp && bp->kind() == Builtin::KindLong)
{
- out << "ICE_INT64(" << value << ")";
+ if(cpp11)
+ {
+ out << value << "LL";
+ }
+ else
+ {
+ out << "ICE_INT64(" << value << ")";
+ }
}
else if(bp && bp->kind() == Builtin::KindFloat)
{
@@ -372,7 +399,24 @@ writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const Synt
EnumPtr ep = EnumPtr::dynamicCast(type);
if(ep)
{
- out << fixKwd(value);
+ bool unscoped = findMetaData(ep->getMetaData(), cpp11 ? TypeContextCpp11 : 0) == "%unscoped";
+ if(!cpp11 || unscoped)
+ {
+ out << fixKwd(value);
+ }
+ else
+ {
+ string v = value;
+ string scope;
+ size_t pos = value.rfind("::");
+ if(pos != string::npos)
+ {
+ v = value.substr(pos + 2);
+ scope = value.substr(0, value.size() - v.size());
+ }
+
+ out << fixKwd(scope + ep->name() + "::" + v);
+ }
}
else
{
@@ -382,39 +426,34 @@ writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const Synt
}
}
-void
-writeMarshalUnmarshalDataMember(IceUtilInternal::Output& C, const DataMemberPtr& p, bool marshal)
-{
- writeMarshalUnmarshalCode(C, p->type(), p->optional(), p->tag(), fixKwd(p->name()), marshal, p->getMetaData());
-}
-
-void
-writeMarshalUnmarshalDataMemberInHolder(IceUtilInternal::Output& C, const string& holder, const DataMemberPtr& p, bool marshal)
+string
+toDllClassExport(const string& dllExport)
{
- writeMarshalUnmarshalCode(C, p->type(), p->optional(), p->tag(), holder + fixKwd(p->name()), marshal, p->getMetaData());
+ if(!dllExport.empty())
+ {
+ return "ICE_CLASS(" + dllExport.substr(0, dllExport.size() - 1) + ") ";
+ }
+ else
+ {
+ return "";
+ }
}
-void
-writeMarshalUnmarshalDataMembers(IceUtilInternal::Output& C,
- const DataMemberList& dataMembers,
- const DataMemberList& optionalDataMembers,
- bool marshal)
+string
+toDllMemberExport(const string& dllExport)
{
- for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ if(!dllExport.empty())
{
- if(!(*q)->optional())
- {
- writeMarshalUnmarshalDataMember(C, *q, marshal);
- }
+ return "ICE_MEMBER(" + dllExport.substr(0, dllExport.size() - 1) + ") ";
}
- for(DataMemberList::const_iterator q = optionalDataMembers.begin(); q != optionalDataMembers.end(); ++q)
+ else
{
- writeMarshalUnmarshalDataMember(C, *q, marshal);
+ return "";
}
}
void
-writeDataMemberInitializers(IceUtilInternal::Output& C, const DataMemberList& members, int useWstring)
+writeDataMemberInitializers(IceUtilInternal::Output& C, const DataMemberList& members, int useWstring, bool cpp11 = false)
{
bool first = true;
for(DataMemberList::const_iterator p = members.begin(); p != members.end(); ++p)
@@ -433,18 +472,163 @@ writeDataMemberInitializers(IceUtilInternal::Output& C, const DataMemberList& me
}
C << nl << memberName << '(';
writeConstantValue(C, (*p)->type(), (*p)->defaultValueType(), (*p)->defaultValue(), useWstring,
- (*p)->getMetaData());
+ (*p)->getMetaData(), cpp11);
C << ')';
}
}
}
+void
+writeInParamsLambda(IceUtilInternal::Output& C, const OperationPtr& p, const ParamDeclList& inParams)
+{
+ if(inParams.empty())
+ {
+ C << "nullptr";
+ }
+ else
+ {
+ C << "[&](::Ice::OutputStream* __os)";
+ C << sb;
+ writeMarshalCode(C, inParams, 0, true, TypeContextInParam | TypeContextCpp11);
+ if(p->sendsClasses(false))
+ {
+ C << nl << "__os->writePendingValues();";
+ }
+ C << eb;
+ }
+}
+
+void
+throwUserExceptionLambda(IceUtilInternal::Output& C, ExceptionList throws)
+{
+ if(throws.empty())
+ {
+ C << "nullptr";
+ }
+ else
+ {
+ throws.sort();
+ throws.unique();
+
+ //
+ // Arrange exceptions into most-derived to least-derived order. If we don't
+ // do this, a base exception handler can appear before a derived exception
+ // handler, causing compiler warnings and resulting in the base exception
+ // being marshaled instead of the derived exception.
+ //
+ throws.sort(Slice::DerivedToBaseCompare());
+
+ C << "[](const ::Ice::UserException& __ex)";
+ C << sb;
+ C << nl << "try";
+ C << sb;
+ C << nl << "__ex.ice_throw();";
+ C << eb;
+ //
+ // Generate a catch block for each legal user exception.
+ //
+ for(ExceptionList::const_iterator i = throws.begin(); i != throws.end(); ++i)
+ {
+ string scoped = (*i)->scoped();
+ C << nl << "catch(const " << fixKwd((*i)->scoped()) << "&)";
+ C << sb;
+ C << nl << "throw;";
+ C << eb;
+ }
+ C << nl << "catch(const ::Ice::UserException&)";
+ C << sb;
+ C << eb;
+ C << eb;
+ }
+}
+
+string
+resultStructName(const string& name, const string& scope = "", bool marshaledResult = false)
+{
+ assert(!name.empty());
+ string stName = IceUtilInternal::toUpper(name.substr(0, 1)) + name.substr(1);
+ stName += marshaledResult ? "MarshaledResult" : "Result";
+ if(!scope.empty())
+ {
+ stName = scope + "::" + stName;
+ }
+ return stName;
+}
+
+void
+emitOpNameResult(IceUtilInternal::Output& H, const OperationPtr& p, int useWstring)
+{
+ string name = p->name();
+
+ TypePtr ret = p->returnType();
+ string retS = returnTypeToString(ret, p->returnIsOptional(), p->getMetaData(), useWstring | TypeContextCpp11);
+
+ ParamDeclList outParams;
+ ParamDeclList paramList = p->parameters();
+
+ for(ParamDeclList::iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if((*q)->isOutParam())
+ {
+ outParams.push_back(*q);
+ }
+ }
+
+ if((outParams.size() > 1) || (ret && outParams.size() > 0))
+ {
+ //
+ // Generate OpNameResult struct
+ //
+ list<string> dataMembers;
+ string returnValueS = "returnValue";
+
+ for(ParamDeclList::iterator q = outParams.begin(); q != outParams.end(); ++q)
+ {
+ string typeString = typeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(),
+ useWstring | TypeContextCpp11);
+
+ dataMembers.push_back(typeString + " " + fixKwd((*q)->name()));
+
+ if((*q)->name() == "returnValue")
+ {
+ returnValueS = "_returnValue";
+ }
+ }
+
+ if(ret)
+ {
+ dataMembers.push_front(retS + " " + returnValueS);
+ }
+
+ H << sp;
+ H << nl << "struct " << resultStructName(name);
+ H << sb;
+ for(list<string>::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ H << nl << *q << ";";
+ }
+ H << eb << ";";
+ }
+}
+
+string
+condMove(bool moveIt, const string& str)
+{
+ return moveIt ? string("::std::move(") + str + ")" : str;
+}
+
+string
+condString(bool ok, const string& str)
+{
+ return ok ? str : "";
+}
+
}
Slice::Gen::Gen(const string& base, const string& headerExtension, const string& sourceExtension,
const vector<string>& extraHeaders, const string& include,
const vector<string>& includePaths, const string& dllExport, const string& dir,
- bool imp, bool checksum, bool stream, bool ice) :
+ bool implCpp98, bool implCpp11, bool checksum, bool ice) :
_base(base),
_headerExtension(headerExtension),
_implHeaderExtension(headerExtension),
@@ -454,9 +638,9 @@ Slice::Gen::Gen(const string& base, const string& headerExtension, const string&
_includePaths(includePaths),
_dllExport(dllExport),
_dir(dir),
- _impl(imp),
+ _implCpp98(implCpp98),
+ _implCpp11(implCpp11),
_checksum(checksum),
- _stream(stream),
_ice(ice)
{
for(vector<string>::iterator p = _includePaths.begin(); p != _includePaths.end(); ++p)
@@ -477,7 +661,7 @@ Slice::Gen::~Gen()
H << "\n#endif\n";
C << '\n';
- if(_impl)
+ if(_implCpp98 || _implCpp11)
{
implH << "\n\n#endif\n";
implC << '\n';
@@ -485,6 +669,38 @@ Slice::Gen::~Gen()
}
void
+Slice::Gen::generateChecksumMap(const UnitPtr& p)
+{
+ if(_checksum)
+ {
+ ChecksumMap map = createChecksums(p);
+ if(!map.empty())
+ {
+ C << sp << nl << "namespace";
+ C << nl << "{";
+ C << sp << nl << "const char* __sliceChecksums[] =";
+ C << sb;
+ for(ChecksumMap::const_iterator q = map.begin(); q != map.end(); ++q)
+ {
+ C << nl << "\"" << q->first << "\", \"";
+ ostringstream str;
+ str.flags(ios_base::hex);
+ str.fill('0');
+ for(vector<unsigned char>::const_iterator r = q->second.begin(); r != q->second.end(); ++r)
+ {
+ str << static_cast<int>(*r);
+ }
+ C << str.str() << "\",";
+ }
+ C << nl << "0";
+ C << eb << ';';
+ C << nl << "const IceInternal::SliceChecksumInit __sliceChecksumInit(__sliceChecksums);";
+ C << sp << nl << "}";
+ }
+ }
+}
+
+void
Slice::Gen::generate(const UnitPtr& p)
{
string file = p->topLevelFile();
@@ -498,7 +714,7 @@ Slice::Gen::generate(const UnitPtr& p)
_headerExtension = headerExtension;
}
- if(_impl)
+ if(_implCpp98 || _implCpp11)
{
string fileImplH = _base + "I." + _implHeaderExtension;
string fileImplC = _base + "I." + _sourceExtension;
@@ -540,7 +756,7 @@ Slice::Gen::generate(const UnitPtr& p)
}
FileTracker::instance()->addFile(fileImplC);
- string s = fileImplH;
+ string s = _base + "I." + _implHeaderExtension;
if(_include.size())
{
s = _include + '/' + s;
@@ -583,7 +799,7 @@ Slice::Gen::generate(const UnitPtr& p)
printGeneratedHeader(C, _base + ".ice");
- string s = fileH;
+ string s = _base + "." + _headerExtension;;
if(_include.size())
{
s = _include + '/' + s;
@@ -612,66 +828,61 @@ Slice::Gen::generate(const UnitPtr& p)
C << _base << "." << _headerExtension << ">";
C << "\n#include <IceUtil/PushDisableWarnings.h>";
-
H << "\n#include <IceUtil/PushDisableWarnings.h>";
H << "\n#include <Ice/ProxyF.h>";
H << "\n#include <Ice/ObjectF.h>";
+ H << "\n#include <Ice/ValueF.h>";
H << "\n#include <Ice/Exception.h>";
H << "\n#include <Ice/LocalObject.h>";
H << "\n#include <Ice/StreamHelpers.h>";
+ H << "\n#include <Ice/Comparable.h>";
if(p->hasNonLocalClassDefs())
{
H << "\n#include <Ice/Proxy.h>";
+ H << "\n#include <Ice/Object.h>";
H << "\n#include <Ice/GCObject.h>";
- H << "\n#include <Ice/AsyncResult.h>";
+ H << "\n#include <Ice/Value.h>";
H << "\n#include <Ice/Incoming.h>";
if(p->hasContentsWithMetaData("amd"))
{
H << "\n#include <Ice/IncomingAsync.h>";
}
C << "\n#include <Ice/LocalException.h>";
- C << "\n#include <Ice/ObjectFactory.h>";
- C << "\n#include <Ice/Outgoing.h>";
+ C << "\n#include <Ice/ValueFactory.h>";
C << "\n#include <Ice/OutgoingAsync.h>";
}
else if(p->hasLocalClassDefsWithAsync())
{
- H << "\n#include <Ice/Proxy.h>";
- H << "\n#include <Ice/AsyncResult.h>";
- C << "\n#include <Ice/OutgoingAsync.h>";
+ H << "\n#include <Ice/OutgoingAsync.h>";
}
else if(p->hasNonLocalClassDecls())
{
H << "\n#include <Ice/Proxy.h>";
}
- if(p->hasNonLocalDataOnlyClasses() || p->hasNonLocalExceptions())
+ if(p->hasNonLocalClassDefs() || p->hasNonLocalExceptions())
{
H << "\n#include <Ice/FactoryTableInit.h>";
}
H << "\n#include <IceUtil/ScopedArray.h>";
- H << "\n#include <IceUtil/Optional.h>";
+ H << "\n#include <Ice/Optional.h>";
- if(p->usesNonLocals())
+ if(p->hasExceptions())
{
- C << "\n#include <Ice/BasicStream.h>";
+ H << "\n#include <Ice/ExceptionHelpers.h>";
}
- if(_stream || p->hasNonLocalClassDefs() || p->hasNonLocalExceptions())
+ if(p->usesNonLocals())
{
- if(!p->hasNonLocalClassDefs())
- {
- C << "\n#include <Ice/LocalException.h>";
- }
-
- H << "\n#include <Ice/StreamF.h>";
+ C << "\n#include <Ice/InputStream.h>";
+ C << "\n#include <Ice/OutputStream.h>";
+ }
- if(_stream)
- {
- C << "\n#include <Ice/Stream.h>";
- }
+ if(p->hasNonLocalExceptions())
+ {
+ C << "\n#include <Ice/LocalException.h>";
}
if(p->hasContentsWithMetaData("preserve-slice"))
@@ -685,7 +896,6 @@ Slice::Gen::generate(const UnitPtr& p)
C << "\n#include <Ice/SliceChecksums.h>";
}
- C << "\n#include <IceUtil/Iterator.h>";
C << "\n#include <IceUtil/PopDisableWarnings.h>";
StringList includes = p->includeFiles();
@@ -730,96 +940,153 @@ Slice::Gen::generate(const UnitPtr& p)
_dllExport += " ";
}
- ProxyDeclVisitor proxyDeclVisitor(H, C, _dllExport);
- p->visit(&proxyDeclVisitor, false);
-
- ObjectDeclVisitor objectDeclVisitor(H, C, _dllExport);
- p->visit(&objectDeclVisitor, false);
+ H << sp;
+ H.zeroIndent();
+ H << nl << "#ifdef ICE_CPP11_MAPPING // C++11 mapping";
+ H.restoreIndent();
- TypesVisitor typesVisitor(H, C, _dllExport, _stream);
- p->visit(&typesVisitor, false);
+ C << sp;
+ C.zeroIndent();
+ C << nl << "#ifdef ICE_CPP11_MAPPING // C++11 mapping";
+ C.restoreIndent();
+ {
+ normalizeMetaData(p, true);
- StreamVisitor streamVisitor(H, C, _dllExport);
- p->visit(&streamVisitor, false);
+ Cpp11DeclVisitor declVisitor(H, C, _dllExport);
+ p->visit(&declVisitor, false);
- AsyncVisitor asyncVisitor(H, C, _dllExport);
- p->visit(&asyncVisitor, false);
+ Cpp11TypesVisitor typesVisitor(H, C, _dllExport);
+ p->visit(&typesVisitor, false);
- AsyncImplVisitor asyncImplVisitor(H, C, _dllExport);
- p->visit(&asyncImplVisitor, false);
+ Cpp11LocalObjectVisitor localObjectVisitor(H, C, _dllExport);
+ p->visit(&localObjectVisitor, false);
- //
- // The templates are emitted before the proxy definition
- // so the derivation hierarchy is known to the proxy:
- // the proxy relies on knowing the hierarchy to make the begin_
- // methods type-safe.
- //
- AsyncCallbackVisitor asyncCallbackVisitor(H, C, _dllExport);
- p->visit(&asyncCallbackVisitor, false);
+ Cpp11InterfaceVisitor interfaceVisitor(H, C, _dllExport);
+ p->visit(&interfaceVisitor, false);
- ProxyVisitor proxyVisitor(H, C, _dllExport);
- p->visit(&proxyVisitor, false);
+ Cpp11ValueVisitor valueVisitor(H, C, _dllExport);
+ p->visit(&valueVisitor, false);
- ObjectVisitor objectVisitor(H, C, _dllExport, _stream);
- p->visit(&objectVisitor, false);
+ Cpp11ProxyVisitor proxyVisitor(H, C, _dllExport);
+ p->visit(&proxyVisitor, false);
- //
- // We need to delay generating the template after the proxy
- // definition, because completed calls the begin_ method in the
- // proxy.
- //
- AsyncCallbackTemplateVisitor asyncCallbackTemplateVisitor(H, C, _dllExport);
- p->visit(&asyncCallbackTemplateVisitor, false);
+ Cpp11StreamVisitor streamVisitor(H, C, _dllExport);
+ p->visit(&streamVisitor, false);
- if(_impl)
- {
- implH << "\n#include <";
- if(_include.size())
+ if(_implCpp11)
{
- implH << _include << '/';
- }
- implH << _base << "." << _headerExtension << ">";
+ implH << "\n#include <";
+ if(_include.size())
+ {
+ implH << _include << '/';
+ }
+ implH << _base << "." << _headerExtension << ">";
+ implH << nl << "//base";
+ writeExtraHeaders(implC);
- writeExtraHeaders(implC);
+ implC << "\n#include <";
+ if(_include.size())
+ {
+ implC << _include << '/';
+ }
+ implC << _base << "I." << _implHeaderExtension << ">";
- implC << "\n#include <";
- if(_include.size())
- {
- implC << _include << '/';
+ Cpp11ImplVisitor implVisitor(implH, implC, _dllExport);
+ p->visit(&implVisitor, false);
}
- implC << _base << "I." << _implHeaderExtension << ">";
- ImplVisitor implVisitor(implH, implC, _dllExport);
- p->visit(&implVisitor, false);
+ Cpp11CompatibilityVisitor compatibilityVisitor(H, C, _dllExport);
+ p->visit(&compatibilityVisitor, false);
+
+ generateChecksumMap(p);
}
+ H << sp;
+ H.zeroIndent();
+ H << nl << "#else // C++98 mapping";
+ H.restoreIndent();
- if(_checksum)
+ C << sp;
+ C.zeroIndent();
+ C << nl << "#else // C++98 mapping";
+ C.restoreIndent();
{
- ChecksumMap map = createChecksums(p);
- if(!map.empty())
+ normalizeMetaData(p, false);
+
+ ProxyDeclVisitor proxyDeclVisitor(H, C, _dllExport);
+ p->visit(&proxyDeclVisitor, false);
+
+ ObjectDeclVisitor objectDeclVisitor(H, C, _dllExport);
+ p->visit(&objectDeclVisitor, false);
+
+ TypesVisitor typesVisitor(H, C, _dllExport);
+ p->visit(&typesVisitor, false);
+
+ AsyncVisitor asyncVisitor(H, C, _dllExport);
+ p->visit(&asyncVisitor, false);
+
+ AsyncImplVisitor asyncImplVisitor(H, C, _dllExport);
+ p->visit(&asyncImplVisitor, false);
+
+ //
+ // The templates are emitted before the proxy definition
+ // so the derivation hierarchy is known to the proxy:
+ // the proxy relies on knowing the hierarchy to make the begin_
+ // methods type-safe.
+ //
+ AsyncCallbackVisitor asyncCallbackVisitor(H, C, _dllExport);
+ p->visit(&asyncCallbackVisitor, false);
+
+ ProxyVisitor proxyVisitor(H, C, _dllExport);
+ p->visit(&proxyVisitor, false);
+
+ ObjectVisitor objectVisitor(H, C, _dllExport);
+ p->visit(&objectVisitor, false);
+
+ StreamVisitor streamVisitor(H, C, _dllExport);
+ p->visit(&streamVisitor, false);
+
+ //
+ // We need to delay generating the template after the proxy
+ // definition, because completed calls the begin_ method in the
+ // proxy.
+ //
+ AsyncCallbackTemplateVisitor asyncCallbackTemplateVisitor(H, C, _dllExport);
+ p->visit(&asyncCallbackTemplateVisitor, false);
+
+ if(_implCpp98)
{
- C << sp << nl << "namespace";
- C << nl << "{";
- C << sp << nl << "const char* __sliceChecksums[] =";
- C << sb;
- for(ChecksumMap::const_iterator q = map.begin(); q != map.end(); ++q)
+ implH << "\n#include <";
+ if(_include.size())
{
- C << nl << "\"" << q->first << "\", \"";
- ostringstream str;
- str.flags(ios_base::hex);
- str.fill('0');
- for(vector<unsigned char>::const_iterator r = q->second.begin(); r != q->second.end(); ++r)
- {
- str << static_cast<int>(*r);
- }
- C << str.str() << "\",";
+ implH << _include << '/';
}
- C << nl << "0";
- C << eb << ';';
- C << nl << "const IceInternal::SliceChecksumInit __sliceChecksumInit(__sliceChecksums);";
- C << sp << nl << "}";
+ implH << _base << "." << _headerExtension << ">";
+
+ writeExtraHeaders(implC);
+
+ implC << "\n#include <";
+ if(_include.size())
+ {
+ implC << _include << '/';
+ }
+ implC << _base << "I." << _implHeaderExtension << ">";
+
+ ImplVisitor implVisitor(implH, implC, _dllExport);
+ p->visit(&implVisitor, false);
}
+
+ generateChecksumMap(p);
}
+
+ H << sp;
+ H.zeroIndent();
+ H << nl << "#endif";
+ H.restoreIndent();
+
+ C << sp;
+ C.zeroIndent();
+ C << nl << "#endif";
+ C.restoreIndent();
}
void
@@ -858,8 +1125,8 @@ Slice::Gen::writeExtraHeaders(IceUtilInternal::Output& out)
}
}
-Slice::Gen::TypesVisitor::TypesVisitor(Output& h, Output& c, const string& dllExport, bool stream) :
- H(h), C(c), _dllExport(dllExport), _stream(stream), _doneStaticSymbol(false), _useWstring(false)
+Slice::Gen::TypesVisitor::TypesVisitor(Output& h, Output& c, const string& dllExport) :
+ H(h), C(c), _dllExport(dllExport), _doneStaticSymbol(false), _useWstring(false)
{
}
@@ -979,7 +1246,6 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
H << nl << "virtual ~" << name << "() throw();";
H << sp;
-
if(!p->isLocal())
{
string initName = p->flattenedScope() + p->name() + "_init";
@@ -1076,10 +1342,10 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
C << sb;
C << eb;
- H << nl << "virtual ::std::string ice_name() const;";
- C << sp << nl << "::std::string" << nl << scoped.substr(2) << "::ice_name() const";
+ H << nl << "virtual ::std::string ice_id() const;";
+ C << sp << nl << "::std::string" << nl << scoped.substr(2) << "::ice_id() const";
C << sb;
- C << nl << "return \"" << p->scoped().substr(2) << "\";";
+ C << nl << "return \"" << p->scoped() << "\";";
C << eb;
StringList metaData = p->getMetaData();
@@ -1137,135 +1403,73 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p)
if(preserved && !basePreserved)
{
- H << sp << nl << "virtual void __write(::IceInternal::BasicStream*) const;";
- H << nl << "virtual void __read(::IceInternal::BasicStream*);";
+ H << sp << nl << "virtual void __write(::Ice::OutputStream*) const;";
+ H << nl << "virtual void __read(::Ice::InputStream*);";
- if(_stream)
- {
- H << nl << "virtual void __write(const ::Ice::OutputStreamPtr&) const;";
- H << nl << "virtual void __read(const ::Ice::InputStreamPtr&);";
- }
- else
- {
- string baseName = base ? fixKwd(base->scoped()) : string("::Ice::UserException");
- H << nl << "using " << baseName << "::__write;";
- H << nl << "using " << baseName << "::__read;";
- }
+ string baseName = base ? fixKwd(base->scoped()) : string("::Ice::UserException");
+ H << nl << "using " << baseName << "::__write;";
+ H << nl << "using " << baseName << "::__read;";
}
H.dec();
H << sp << nl << "protected:";
H.inc();
- H << nl << "virtual void __writeImpl(::IceInternal::BasicStream*) const;";
- H << nl << "virtual void __readImpl(::IceInternal::BasicStream*);";
+ H << sp << nl << "virtual void __writeImpl(::Ice::OutputStream*) const;";
+ H << nl << "virtual void __readImpl(::Ice::InputStream*);";
- if(_stream)
- {
- H << nl << "virtual void __writeImpl(const ::Ice::OutputStreamPtr&) const;";
- H << nl << "virtual void __readImpl(const ::Ice::InputStreamPtr&);";
- }
- else
- {
- string baseName = base ? fixKwd(base->scoped()) : string("::Ice::UserException");
- H << nl << "using " << baseName << "::__writeImpl;";
- H << nl << "using " << baseName << "::__readImpl;";
- }
+ string baseName = base ? fixKwd(base->scoped()) : string("::Ice::UserException");
if(preserved && !basePreserved)
{
H << sp << nl << "::Ice::SlicedDataPtr __slicedData;";
- C << sp << nl << "void" << nl << scoped.substr(2) << "::__write(::IceInternal::BasicStream* __os) const";
+ C << sp << nl << "void" << nl << scoped.substr(2) << "::__write(::Ice::OutputStream* __os) const";
C << sb;
- C << nl << "__os->startWriteException(__slicedData);";
+ C << nl << "__os->startException(__slicedData);";
C << nl << "__writeImpl(__os);";
- C << nl << "__os->endWriteException();";
+ C << nl << "__os->endException();";
C << eb;
- C << sp << nl << "void" << nl << scoped.substr(2) << "::__read(::IceInternal::BasicStream* __is)";
+ C << sp << nl << "void" << nl << scoped.substr(2) << "::__read(::Ice::InputStream* __is)";
C << sb;
- C << nl << "__is->startReadException();";
+ C << nl << "__is->startException();";
C << nl << "__readImpl(__is);";
- C << nl << "__slicedData = __is->endReadException(true);";
+ C << nl << "__slicedData = __is->endException(true);";
C << eb;
}
- C << sp << nl << "void" << nl << scoped.substr(2) << "::__writeImpl(::IceInternal::BasicStream* __os) const";
+ C << sp << nl << "void" << nl << scoped.substr(2) << "::__writeImpl(::Ice::OutputStream* __os) const";
C << sb;
- C << nl << "__os->startWriteSlice(\"" << p->scoped() << "\", -1, " << (!base ? "true" : "false") << ");";
- writeMarshalUnmarshalDataMembers(C, p->dataMembers(), p->orderedOptionalDataMembers(), true);
- C << nl << "__os->endWriteSlice();";
+ C << nl << "__os->startSlice(\"" << p->scoped() << "\", -1, " << (!base ? "true" : "false") << ");";
+ C << nl << "Ice::StreamWriter< ::" << scoped.substr(2) << ", ::Ice::OutputStream>::write(__os, *this);";
+ C << nl << "__os->endSlice();";
if(base)
{
emitUpcall(base, "::__writeImpl(__os);");
}
C << eb;
- C << sp << nl << "void" << nl << scoped.substr(2) << "::__readImpl(::IceInternal::BasicStream* __is)";
+ C << sp << nl << "void" << nl << scoped.substr(2) << "::__readImpl(::Ice::InputStream* __is)";
C << sb;
- C << nl << "__is->startReadSlice();";
- writeMarshalUnmarshalDataMembers(C, p->dataMembers(), p->orderedOptionalDataMembers(), false);
- C << nl << "__is->endReadSlice();";
+ C << nl << "__is->startSlice();";
+ C << nl << "Ice::StreamReader< ::" << scoped.substr(2) << ", ::Ice::InputStream>::read(__is, *this);";
+ C << nl << "__is->endSlice();";
if(base)
{
emitUpcall(base, "::__readImpl(__is);");
}
C << eb;
-
- if(_stream)
- {
- if(preserved && !basePreserved)
- {
- C << sp << nl << "void" << nl << scoped.substr(2) << "::__write(const ::Ice::OutputStreamPtr& __os) const";
- C << sb;
- C << nl << "__os->startException(__slicedData);";
- C << nl << "__writeImpl(__os);";
- C << nl << "__os->endException();";
- C << eb;
-
- C << sp << nl << "void" << nl << scoped.substr(2) << "::__read(const ::Ice::InputStreamPtr& __is)";
- C << sb;
- C << nl << "__is->startException();";
- C << nl << "__readImpl(__is);";
- C << nl << "__slicedData = __is->endException(true);";
- C << eb;
- }
-
- C << sp << nl << "void" << nl << scoped.substr(2)
- << "::__writeImpl(const ::Ice::OutputStreamPtr& __os) const";
- C << sb;
- C << nl << "__os->startSlice(\"" << p->scoped() << "\", -1, " << (!base ? "true" : "false") << ");";
- writeMarshalUnmarshalDataMembers(C, p->dataMembers(), p->orderedOptionalDataMembers(), true);
- C << nl << "__os->endSlice();";
- if(base)
- {
- emitUpcall(base, "::__writeImpl(__os);");
- }
- C << eb;
-
- C << sp << nl << "void" << nl << scoped.substr(2)
- << "::__readImpl(const ::Ice::InputStreamPtr& __is)";
- C << sb;
- C << nl << "__is->startSlice();";
- writeMarshalUnmarshalDataMembers(C, p->dataMembers(), p->orderedOptionalDataMembers(), false);
- C << nl << "__is->endSlice();";
- if(base)
- {
- emitUpcall(base, "::__readImpl(__is);");
- }
- C << eb;
- }
}
H << eb << ';';
if(!p->isLocal())
{
//
- // We need an instance here to trigger initialization if the implementation is in a shared libarry.
+ // We need an instance here to trigger initialization if the implementation is in a static library.
// But we do this only once per source file, because a single instance is sufficient to initialize
- // all of the globals in a shared library.
+ // all of the globals in a compilation unit.
//
if(!_doneStaticSymbol)
{
@@ -1288,7 +1492,7 @@ Slice::Gen::TypesVisitor::visitStructStart(const StructPtr& p)
bool classMetaData = findMetaData(p->getMetaData()) == "%class";
if(classMetaData)
{
- H << sp << nl << "class " << _dllExport << name << " : public IceUtil::Shared";
+ H << sp << nl << "class " << name << " : public IceUtil::Shared";
H << sb;
H.dec();
H << nl << "public:";
@@ -1340,10 +1544,6 @@ Slice::Gen::TypesVisitor::visitStructStart(const StructPtr& p)
}
H << nl;
- if(!classMetaData)
- {
- H << _dllExport;
- }
if(paramDecls.size() == 1)
{
H << "explicit ";
@@ -1622,13 +1822,14 @@ Slice::Gen::ProxyDeclVisitor::visitClassDecl(const ClassDeclPtr& p)
string scoped = fixKwd(p->scoped());
H << sp << nl << "class " << name << ';';
- H << nl << _dllExport << "void __read(::IceInternal::BasicStream*, ::IceInternal::ProxyHandle< ::IceProxy"
+ H << nl << _dllExport << "void __read(::Ice::InputStream*, ::IceInternal::ProxyHandle< ::IceProxy"
<< scoped << ">&);";
H << nl << _dllExport << "::IceProxy::Ice::Object* upCast(::IceProxy" << scoped << "*);";
}
Slice::Gen::ProxyVisitor::ProxyVisitor(Output& h, Output& c, const string& dllExport) :
- H(h), C(c), _dllExport(dllExport), _useWstring(false)
+ H(h), C(c), _dllExport(dllExport), _dllClassExport(toDllClassExport(dllExport)),
+ _dllMemberExport(toDllMemberExport(dllExport)), _useWstring(false)
{
}
@@ -1691,49 +1892,74 @@ Slice::Gen::ProxyVisitor::visitClassDefStart(const ClassDefPtr& p)
string scoped = fixKwd(p->scoped());
ClassList bases = p->bases();
- H << sp << nl << "class " << _dllExport << name << " : ";
- if(bases.empty())
- {
- H << "virtual public ::IceProxy::Ice::Object";
- }
- else
+ if(bases.size() > 1)
{
+ //
+ // Generated helper class to deal with multiple inheritance
+ // when using Proxy template.
+ //
+
+ string baseName = fixKwd("_" + p->name() + "Base");
+
+ H << sp << nl << "class " << _dllClassExport << baseName << " : ";
H.useCurrentPosAsIndent();
- ClassList::const_iterator q = bases.begin();
- while(q != bases.end())
+ for(ClassList::const_iterator q = bases.begin(); q != bases.end();)
{
- H << "virtual public ::IceProxy" << fixKwd((*q)->scoped());
+ H << "public virtual ::IceProxy" << fixKwd((*q)->scoped());
if(++q != bases.end())
{
- H << ',' << nl;
+ H << ", " << nl;
}
}
H.restoreIndent();
+ H << sb;
+
+ H.dec();
+ H << nl << "public:";
+ H.inc();
+
+ // Out of line dtor to avoid weak vtable
+ H << sp << nl << _dllMemberExport << "virtual ~" << baseName << "();";
+ C << sp;
+ C << nl << "::IceProxy" << scope << baseName << "::~" << baseName << "()";
+ C << sb;
+ C << eb;
+
+ H.dec();
+ H << sp << nl << "protected:";
+ H.inc();
+
+ H << sp << nl << "virtual Object* __newInstance() const = 0;";
+ H << eb << ';';
}
+ H << sp << nl << "class " << _dllClassExport << name << " : ";
+ H << "public virtual ::Ice::Proxy<" << name << ", ";
+ if(bases.empty())
+ {
+ H << "::IceProxy::Ice::Object";
+ }
+ else if(bases.size() == 1)
+ {
+ H << "::IceProxy" << fixKwd(bases.front()->scoped());
+ }
+ else
+ {
+ H << fixKwd("_" + p->name() + "Base");
+ }
+ H << ">";
+
H << sb;
H.dec();
H << nl << "public:";
H.inc();
- if(_dllExport != "")
- {
- //
- // To export the virtual table
- //
- C << nl << "#ifdef __SUNPRO_CC";
- C << nl << "class " << _dllExport
- << "IceProxy" << scoped << ";";
- C << nl << "#endif";
- }
-
C << nl
<< _dllExport
- << "::IceProxy::Ice::Object* ::IceProxy" << scope << "upCast(::IceProxy" << scoped
- << "* p) { return p; }";
+ << "::IceProxy::Ice::Object* ::IceProxy" << scope << "upCast(::IceProxy" << scoped << "* p) { return p; }";
C << sp;
- C << nl << "void" << nl << "::IceProxy" << scope << "__read(::IceInternal::BasicStream* __is, "
+ C << nl << "void" << nl << "::IceProxy" << scope << "__read(::Ice::InputStream* __is, "
<< "::IceInternal::ProxyHandle< ::IceProxy" << scoped << ">& v)";
C << sb;
C << nl << "::Ice::ObjectPrx proxy;";
@@ -1759,143 +1985,25 @@ Slice::Gen::ProxyVisitor::visitClassDefEnd(const ClassDefPtr& p)
string scoped = fixKwd(p->scoped());
string scope = fixKwd(p->scope());
- //
- // "Overwrite" various non-virtual functions in ::IceProxy::Ice::Object that return an ObjectPrx and
- // are more usable when they return a <name>Prx
- //
-
- //
- // No identity!
- //
-
- H << nl << nl << "::IceInternal::ProxyHandle<" << name << "> ice_context(const ::Ice::Context& __context) const";
- H << sb;
- H << nl << "return dynamic_cast<" << name << "*>(::IceProxy::Ice::Object::ice_context(__context).get());";
- H << eb;
-
- //
- // No facet!
- //
-
- H << nl << nl << "::IceInternal::ProxyHandle<" << name << "> ice_adapterId(const ::std::string& __id) const";
- H << sb;
- H << nl << "return dynamic_cast<" << name << "*>(::IceProxy::Ice::Object::ice_adapterId(__id).get());";
- H << eb;
-
- H << nl << nl << "::IceInternal::ProxyHandle<" << name << "> ice_endpoints(const ::Ice::EndpointSeq& __endpoints) const";
- H << sb;
- H << nl << "return dynamic_cast<" << name << "*>(::IceProxy::Ice::Object::ice_endpoints(__endpoints).get());";
- H << eb;
-
- H << nl << nl << "::IceInternal::ProxyHandle<" << name << "> ice_locatorCacheTimeout(int __timeout) const";
- H << sb;
- H << nl << "return dynamic_cast<" << name << "*>(::IceProxy::Ice::Object::ice_locatorCacheTimeout(__timeout).get());";
- H << eb;
-
- H << nl << nl << "::IceInternal::ProxyHandle<" << name << "> ice_connectionCached(bool __cached) const";
- H << sb;
- H << nl << "return dynamic_cast<" << name << "*>(::IceProxy::Ice::Object::ice_connectionCached(__cached).get());";
- H << eb;
-
- H << nl << nl << "::IceInternal::ProxyHandle<" << name << "> ice_endpointSelection(::Ice::EndpointSelectionType __est) const";
- H << sb;
- H << nl << "return dynamic_cast<" << name << "*>(::IceProxy::Ice::Object::ice_endpointSelection(__est).get());";
- H << eb;
-
- H << nl << nl << "::IceInternal::ProxyHandle<" << name << "> ice_secure(bool __secure) const";
- H << sb;
- H << nl << "return dynamic_cast<" << name << "*>(::IceProxy::Ice::Object::ice_secure(__secure).get());";
- H << eb;
-
- H << nl << nl << "::IceInternal::ProxyHandle<" << name << "> ice_preferSecure(bool __preferSecure) const";
- H << sb;
- H << nl << "return dynamic_cast<" << name << "*>(::IceProxy::Ice::Object::ice_preferSecure(__preferSecure).get());";
- H << eb;
-
- H << nl << nl << "::IceInternal::ProxyHandle<" << name << "> ice_router(const ::Ice::RouterPrx& __router) const";
- H << sb;
- H << nl << "return dynamic_cast<" << name << "*>(::IceProxy::Ice::Object::ice_router(__router).get());";
- H << eb;
-
- H << nl << nl << "::IceInternal::ProxyHandle<" << name << "> ice_locator(const ::Ice::LocatorPrx& __locator) const";
- H << sb;
- H << nl << "return dynamic_cast<" << name << "*>(::IceProxy::Ice::Object::ice_locator(__locator).get());";
- H << eb;
-
- H << nl << nl << "::IceInternal::ProxyHandle<" << name << "> ice_collocationOptimized(bool __co) const";
- H << sb;
- H << nl << "return dynamic_cast<" << name << "*>(::IceProxy::Ice::Object::ice_collocationOptimized(__co).get());";
- H << eb;
-
- H << nl << nl << "::IceInternal::ProxyHandle<" << name << "> ice_invocationTimeout(int __timeout) const";
- H << sb;
- H << nl << "return dynamic_cast<" << name << "*>(::IceProxy::Ice::Object::ice_invocationTimeout(__timeout).get());";
- H << eb;
-
- H << nl << nl << "::IceInternal::ProxyHandle<" << name << "> ice_twoway() const";
- H << sb;
- H << nl << "return dynamic_cast<" << name << "*>(::IceProxy::Ice::Object::ice_twoway().get());";
- H << eb;
-
- H << nl << nl << "::IceInternal::ProxyHandle<" << name << "> ice_oneway() const";
- H << sb;
- H << nl << "return dynamic_cast<" << name << "*>(::IceProxy::Ice::Object::ice_oneway().get());";
- H << eb;
-
- H << nl << nl << "::IceInternal::ProxyHandle<" << name << "> ice_batchOneway() const";
- H << sb;
- H << nl << "return dynamic_cast<" << name << "*>(::IceProxy::Ice::Object::ice_batchOneway().get());";
- H << eb;
-
- H << nl << nl << "::IceInternal::ProxyHandle<" << name << "> ice_datagram() const";
- H << sb;
- H << nl << "return dynamic_cast<" << name << "*>(::IceProxy::Ice::Object::ice_datagram().get());";
- H << eb;
-
- H << nl << nl << "::IceInternal::ProxyHandle<" << name << "> ice_batchDatagram() const";
- H << sb;
- H << nl << "return dynamic_cast<" << name << "*>(::IceProxy::Ice::Object::ice_batchDatagram().get());";
- H << eb;
-
- H << nl << nl << "::IceInternal::ProxyHandle<" << name << "> ice_compress(bool __compress) const";
- H << sb;
- H << nl << "return dynamic_cast<" << name << "*>(::IceProxy::Ice::Object::ice_compress(__compress).get());";
- H << eb;
-
- H << nl << nl << "::IceInternal::ProxyHandle<" << name << "> ice_timeout(int __timeout) const";
- H << sb;
- H << nl << "return dynamic_cast<" << name << "*>(::IceProxy::Ice::Object::ice_timeout(__timeout).get());";
- H << eb;
-
- H << nl << nl << "::IceInternal::ProxyHandle<" << name << "> ice_connectionId(const ::std::string& __id) const";
- H << sb;
- H << nl << "return dynamic_cast<" << name << "*>(::IceProxy::Ice::Object::ice_connectionId(__id).get());";
- H << eb;
-
- H << nl << nl << "::IceInternal::ProxyHandle<" << name
- << "> ice_encodingVersion(const ::Ice::EncodingVersion& __v) const";
- H << sb;
- H << nl << "return dynamic_cast<" << name << "*>(::IceProxy::Ice::Object::ice_encodingVersion(__v).get());";
- H << eb;
-
- H << nl << nl << "static const ::std::string& ice_staticId();";
+ H << nl << nl << _dllMemberExport << "static const ::std::string& ice_staticId();";
H.dec();
- H << sp << nl << "private: ";
+ H << sp << nl << "protected: ";
H.inc();
- H << nl << "virtual ::IceProxy::Ice::Object* __newInstance() const;";
+ H << sp << nl << _dllMemberExport << "virtual ::IceProxy::Ice::Object* __newInstance() const;";
H << eb << ';';
C << sp;
- C << nl << "const ::std::string&" << nl << "IceProxy" << scoped << "::ice_staticId()";
+ C << nl << "::IceProxy::Ice::Object*";
+ C << nl << "IceProxy" << scoped << "::__newInstance() const";
C << sb;
- C << nl << "return "<< scoped << "::ice_staticId();";
+ C << nl << "return new " << name << ";";
C << eb;
- C << sp << nl << "::IceProxy::Ice::Object*";
- C << nl << "IceProxy" << scoped << "::__newInstance() const";
+ C << sp;
+ C << nl << "const ::std::string&" << nl << "IceProxy" << scoped << "::ice_staticId()";
C << sb;
- C << nl << "return new " << name << ";";
+ C << nl << "return " << scoped << "::ice_staticId();";
C << eb;
_useWstring = resetUseWstring(_useWstringHist);
@@ -2018,7 +2126,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p)
//
// Check if we need to generate a private ___end_ method. This is the case if the
- // when using certain mapping features such as cpp:array or cpp:range:array. While
+ // when using certain mapping features such as cpp:array. While
// the regular end_ method can't return pair<const TYPE*, const TYPE*> because the
// pointers would be invalid once end_ returns, we still want to allow using this
// alternate mapping with AMI response callbacks (to allow zero-copy for instance).
@@ -2037,219 +2145,21 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p)
string thisPointer = fixKwd(scope.substr(0, scope.size() - 2)) + "*";
string deprecateSymbol = getDeprecateSymbol(p, cl);
- H << sp << nl << deprecateSymbol << retS << ' ' << fixKwd(name) << spar << paramsDecl << epar;
- H << sb;
- H << nl;
+ H << sp << nl << deprecateSymbol << _dllMemberExport << retS << ' ' << fixKwd(name) << spar << paramsDecl
+ << "const ::Ice::Context& __ctx = ::Ice::noExplicitContext" << epar;
+ H << sb << nl;
if(ret)
{
H << "return ";
}
- H << fixKwd(name) << spar << args << "0" << epar << ';';
- H << eb;
- H << nl << deprecateSymbol << retS << ' ' << fixKwd(name) << spar << paramsDecl << "const ::Ice::Context& __ctx"
- << epar;
- H << sb;
- H << nl;
- if(ret)
- {
- H << "return ";
- }
- H << fixKwd(name) << spar << args << "&__ctx" << epar << ';';
- H << eb;
-
- H.zeroIndent();
- H << nl << "#ifdef ICE_CPP11";
- H.restoreIndent();
-
- string retEndArg = getEndArg(ret, p->getMetaData(), "__ret");
-
- //
- // COMPILERFIX VC compilers up to VC110 don't support more than 10 parameters with std::function due to
- // lack of variadic templates.
- //
- if(outDecls.size() > 10 || (outDecls.size() > 9 && !retInS.empty()))
- {
- H.zeroIndent();
- H << nl << "#if !defined(_MSC_VER) || _MSC_VER > 1700";
- H.restoreIndent();
- H << nl << "//";
- H << nl << "// COMPILERFIX VC compilers up to VC110 don't support more than 10 parameters with";
- H << nl << "// std::function due to lack of variadic templates.";
- H << nl << "//";
- }
-
- H << nl << "::Ice::AsyncResultPtr";
- H << nl << "begin_" << name << spar << paramsDeclAMI
- << "const ::IceInternal::Function<void " << spar;
- if(!retInS.empty())
- {
- H << retInS;
- }
- H << outDecls << epar << ">& __response, "
- << "const ::IceInternal::Function<void (const ::Ice::Exception&)>& __exception = "
- "::IceInternal::Function<void (const ::Ice::Exception&)>(), "
- << "const ::IceInternal::Function<void (bool)>& __sent = ::IceInternal::Function<void (bool)>()" << epar;
-
- H << sb;
- if(p->returnsData())
- {
- H << nl << "return __begin_" << name << spar << argsAMI << "0, __response, __exception, __sent" << epar << ";";
- }
- else
- {
- H << nl << "return begin_" << name << spar << argsAMI
- << "0, new ::IceInternal::Cpp11FnOnewayCallbackNC(__response, __exception, __sent)" << epar << ";";
-
- }
- H << eb;
-
- //
- // COMPILERFIX VC compilers up to VC110 don't support more than 10 parameters with std::function due to
- // lack of variadic templates.
- //
- if(outDecls.size() > 10 || (outDecls.size() > 9 && !retInS.empty()))
- {
- H.zeroIndent();
- H << nl << "#endif";
- H.restoreIndent();
- }
-
- H << nl << "::Ice::AsyncResultPtr";
- H << nl << "begin_" << name << spar << paramsDeclAMI
- << "const ::IceInternal::Function<void (const ::Ice::AsyncResultPtr&)>& __completed"
- << "const ::IceInternal::Function<void (const ::Ice::AsyncResultPtr&)>& __sent = "
- "::IceInternal::Function<void (const ::Ice::AsyncResultPtr&)>()" << epar;
- H << sb;
- H << nl << "return begin_" << name << spar << argsAMI << "0, ::Ice::newCallback(__completed, __sent), 0" << epar << ";";
- H << eb;
-
- //
- // COMPILERFIX VC compilers up to VC110 don't support more than 10 parameters with std::function due to
- // lack of variadic templates.
- //
- if(outDecls.size() > 10 || (outDecls.size() > 9 && !retInS.empty()))
- {
- H.zeroIndent();
- H << nl << "#if !defined(_MSC_VER) || _MSC_VER > 1700";
- H.restoreIndent();
- H << nl << "//";
- H << nl << "// COMPILERFIX VC compilers up to VC110 don't support more than 10 parameters with";
- H << nl << "// std::function due to lack of variadic templates.";
- H << nl << "//";
- }
-
- H << nl << "::Ice::AsyncResultPtr";
- H << nl << "begin_" << name << spar << paramsDeclAMI << "const ::Ice::Context& __ctx"
- << "const ::IceInternal::Function<void " << spar;
- if(!retInS.empty())
- {
- H << retInS;
- }
- H << outDecls << epar << ">& __response, "
- << "const ::IceInternal::Function<void (const ::Ice::Exception&)>& __exception = "
- "::IceInternal::Function<void (const ::Ice::Exception&)>(), "
- << "const ::IceInternal::Function<void (bool)>& __sent = ::IceInternal::Function<void (bool)>()" << epar;
-
- H << sb;
- if(p->returnsData())
- {
- H << nl << "return __begin_" << name << spar << argsAMI << "&__ctx, __response, __exception, __sent" << epar << ";";
- }
- else
- {
- H << nl << "return begin_" << name << spar << argsAMI
- << "&__ctx, new ::IceInternal::Cpp11FnOnewayCallbackNC(__response, __exception, __sent), 0" << epar << ";";
- }
- H << eb;
-
- //
- // COMPILERFIX VC compilers up to VC110 don't support more than 10 parameters with std::function due to
- // lack of variadic templates.
- //
- if(outDecls.size() > 10 || (outDecls.size() > 9 && !retInS.empty()))
- {
- H.zeroIndent();
- H << nl << "#endif";
- H.restoreIndent();
- }
-
- H << nl << "::Ice::AsyncResultPtr";
- H << nl << "begin_" << name << spar << paramsDeclAMI
- << "const ::Ice::Context& __ctx"
- << "const ::IceInternal::Function<void (const ::Ice::AsyncResultPtr&)>& __completed"
- << "const ::IceInternal::Function<void (const ::Ice::AsyncResultPtr&)>& __sent = "
- "::IceInternal::Function<void (const ::Ice::AsyncResultPtr&)>()" << epar;
- H << sb;
- H << nl << "return begin_" << name << spar << argsAMI << "&__ctx, ::Ice::newCallback(__completed, __sent)" << epar << ";";
- H << eb;
-
- if(p->returnsData())
- {
- //
- // COMPILERFIX VC compilers up to VC110 don't support more than 10 parameters with std::function due to
- // lack of variadic templates.
- //
- if(outDecls.size() > 10 || (outDecls.size() > 9 && !retInS.empty()))
- {
- H.zeroIndent();
- H << nl << "#if !defined(_MSC_VER) || _MSC_VER > 1700";
- H.restoreIndent();
- H << nl << "//";
- H << nl << "// COMPILERFIX VC compilers up to VC110 don't support more than 10 parameters with";
- H << nl << "// std::function due to lack of variadic templates.";
- H << nl << "//";
- }
-
- H << nl;
- H.dec();
- H << nl << "private:";
- H.inc();
-
-
- H << sp << nl << "::Ice::AsyncResultPtr __begin_" << name << spar << paramsDeclAMI
- << "const ::Ice::Context* __ctx" << "const ::IceInternal::Function<void " << spar;
-
-
- if(!retInS.empty())
- {
- H << retInS;
- }
- H << outDecls;
-
- H << epar << ">& __response, "
- << "const ::IceInternal::Function<void (const ::Ice::Exception&)>& __exception, "
- << "const ::IceInternal::Function<void (bool)>& __sent" << epar << ";";
-
- H << nl;
- H.dec();
- H << nl << "public:";
- H.inc();
- //
- // COMPILERFIX VC compilers up to VC110 don't support more than 10 parameters with std::function due to
- // lack of variadic templates.
- //
- if(outDecls.size() > 10 || (outDecls.size() > 9 && !retInS.empty()))
- {
- H.zeroIndent();
- H << nl << "#endif";
- H.restoreIndent();
- }
- }
-
- H.zeroIndent();
- H << nl << "#endif";
- H.restoreIndent();
-
- H << sp << nl << "::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI << epar;
- H << sb;
- H << nl << "return begin_" << name << spar << argsAMI << "0" << "::IceInternal::__dummyCallback" << "0"
- << epar << ';';
+ H << "end_" << name << spar << outParamNamesAMI << "__begin_" + name << spar << argsAMI;
+ H << "__ctx" << "::IceInternal::__dummyCallback" << "0" << "true" << epar << epar << ';';
H << eb;
H << sp << nl << "::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI
- << "const ::Ice::Context& __ctx" << epar;
+ << "const ::Ice::Context& __ctx = ::Ice::noExplicitContext" << epar;
H << sb;
- H << nl << "return begin_" << name << spar << argsAMI << "&__ctx" << "::IceInternal::__dummyCallback" << "0"
+ H << nl << "return __begin_" << name << spar << argsAMI << "__ctx" << "::IceInternal::__dummyCallback" << "0"
<< epar << ';';
H << eb;
@@ -2257,7 +2167,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p)
<< "const ::Ice::CallbackPtr& __del"
<< "const ::Ice::LocalObjectPtr& __cookie = 0" << epar;
H << sb;
- H << nl << "return begin_" << name << spar << argsAMI << "0" << "__del" << "__cookie" << epar << ';';
+ H << nl << "return __begin_" << name << spar << argsAMI << "::Ice::noExplicitContext" << "__del" << "__cookie" << epar << ';';
H << eb;
H << sp << nl << "::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI
@@ -2265,14 +2175,14 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p)
<< "const ::Ice::CallbackPtr& __del"
<< "const ::Ice::LocalObjectPtr& __cookie = 0" << epar;
H << sb;
- H << nl << "return begin_" << name << spar << argsAMI << "&__ctx" << "__del" << "__cookie" << epar << ';';
+ H << nl << "return __begin_" << name << spar << argsAMI << "__ctx" << "__del" << "__cookie" << epar << ';';
H << eb;
H << sp << nl << "::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI
<< "const " + delNameScoped + "Ptr& __del"
<< "const ::Ice::LocalObjectPtr& __cookie = 0" << epar;
H << sb;
- H << nl << "return begin_" << name << spar << argsAMI << "0" << "__del" << "__cookie" << epar << ';';
+ H << nl << "return __begin_" << name << spar << argsAMI << "::Ice::noExplicitContext" << "__del" << "__cookie" << epar << ';';
H << eb;
H << sp << nl << "::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI
@@ -2280,14 +2190,14 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p)
<< "const " + delNameScoped + "Ptr& __del"
<< "const ::Ice::LocalObjectPtr& __cookie = 0" << epar;
H << sb;
- H << nl << "return begin_" << name << spar << argsAMI << "&__ctx" << "__del" << "__cookie" << epar << ';';
+ H << nl << "return __begin_" << name << spar << argsAMI << "__ctx" << "__del" << "__cookie" << epar << ';';
H << eb;
- H << sp << nl << retS << " end_" << name << spar << outParamsDeclAMI
+ H << sp << nl << _dllMemberExport << retS << " end_" << name << spar << outParamsDeclAMI
<< "const ::Ice::AsyncResultPtr&" << epar << ';';
if(generatePrivateEnd)
{
- H << sp << nl << " void ___end_" << name << spar << outParamsDeclEndAMI;
+ H << sp << nl << _dllMemberExport << "void ___end_" << name << spar << outParamsDeclEndAMI;
H << "const ::Ice::AsyncResultPtr&" << epar << ';';
}
@@ -2295,137 +2205,26 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p)
H.dec();
H << nl << "private:";
H.inc();
- H << sp << nl << retS << ' ' << fixKwd(name) << spar << params << "const ::Ice::Context*" << epar
- << ';';
- H << nl << "::Ice::AsyncResultPtr begin_" << name << spar << paramsAMI << "const ::Ice::Context*"
+ H << sp << nl << _dllMemberExport << "::Ice::AsyncResultPtr __begin_" << name << spar
+ << paramsAMI << "const ::Ice::Context&"
<< "const ::IceInternal::CallbackBasePtr&"
- << "const ::Ice::LocalObjectPtr& __cookie = 0" << epar << ';';
+ << "const ::Ice::LocalObjectPtr& __cookie = 0"
+ << "bool sync = false" << epar << ';';
H << nl;
H.dec();
H << nl << "public:";
H.inc();
- C << sp << nl << retS << nl << "IceProxy" << scoped << spar << paramsDecl << "const ::Ice::Context* __ctx" << epar;
- C << sb;
- if(p->returnsData())
- {
- C << nl << "__checkTwowayOnly(" << flatName << ");";
- }
- C << nl << "::IceInternal::Outgoing __og(this, " << flatName << ", " << operationModeToString(p->sendMode())
- << ", __ctx);";
- if(inParams.empty())
- {
- C << nl << "__og.writeEmptyParams();";
- }
- else
- {
- C << nl << "try";
- C << sb;
- C << nl<< "::IceInternal::BasicStream* __os = __og.startWriteParams(" << opFormatTypeToString(p) << ");";
- writeMarshalCode(C, inParams, 0, true, TypeContextInParam);
- if(p->sendsClasses(false))
- {
- C << nl << "__os->writePendingObjects();";
- }
- C << nl << "__og.endWriteParams();";
- C << eb;
- C << nl << "catch(const ::Ice::LocalException& __ex)";
- C << sb;
- C << nl << "__og.abort(__ex);";
- C << eb;
- }
-
- if(!p->returnsData())
- {
- C << nl << "__invoke(__og);"; // Use helpers for methods that don't return data.
- }
- else
- {
- C << nl << "if(!__og.invoke())";
- C << sb;
- C << nl << "try";
- C << sb;
- C << nl << "__og.throwUserException();";
- C << eb;
-
- //
- // Generate a catch block for each legal user exception. This is necessary
- // to prevent an "impossible" user exception to be thrown if client and
- // and server use different exception specifications for an operation. For
- // example:
- //
- // Client compiled with:
- // exception A {};
- // exception B {};
- // interface I {
- // void op() throws A;
- // };
- //
- // Server compiled with:
- // exception A {};
- // exception B {};
- // interface I {
- // void op() throws B; // Differs from client
- // };
- //
- // We need the catch blocks so, if the server throws B from op(), the
- // client receives UnknownUserException instead of B.
- //
- ExceptionList throws = p->throws();
- throws.sort();
- throws.unique();
-#if defined(__SUNPRO_CC)
- throws.sort(derivedToBaseCompare);
-#else
- throws.sort(Slice::DerivedToBaseCompare());
-#endif
- for(ExceptionList::const_iterator i = throws.begin(); i != throws.end(); ++i)
- {
- C << nl << "catch(const " << fixKwd((*i)->scoped()) << "&)";
- C << sb;
- C << nl << "throw;";
- C << eb;
- }
- C << nl << "catch(const ::Ice::UserException& __ex)";
- C << sb;
- //
- // COMPILERFIX: Don't throw UnknownUserException directly. This is causing access
- // violation errors with Visual C++ 64bits optimized builds. See bug #2962.
- //
- C << nl << "::Ice::UnknownUserException __uue(__FILE__, __LINE__, __ex.ice_name());";
- C << nl << "throw __uue;";
- C << eb;
- C << eb;
-
- if(ret || !outParams.empty())
- {
- writeAllocateCode(C, ParamDeclList(), p, true, _useWstring);
- C << nl << "::IceInternal::BasicStream* __is = __og.startReadParams();";
- writeUnmarshalCode(C, outParams, p, true);
- if(p->returnsClasses(false))
- {
- C << nl << "__is->readPendingObjects();";
- }
- C << nl << "__og.endReadParams();";
- }
-
- if(ret)
- {
- C << nl << "return __ret;";
- }
- }
- C << eb;
-
- C << sp << nl << "::Ice::AsyncResultPtr" << nl << "IceProxy" << scope << "begin_" << name << spar << paramsDeclAMI
- << "const ::Ice::Context* __ctx" << "const ::IceInternal::CallbackBasePtr& __del"
- << "const ::Ice::LocalObjectPtr& __cookie" << epar;
+ C << sp << nl << "::Ice::AsyncResultPtr" << nl << "IceProxy" << scope << "__begin_" << name << spar << paramsDeclAMI
+ << "const ::Ice::Context& __ctx" << "const ::IceInternal::CallbackBasePtr& __del"
+ << "const ::Ice::LocalObjectPtr& __cookie" << "bool sync" << epar;
C << sb;
if(p->returnsData())
{
- C << nl << "__checkAsyncTwowayOnly(" << flatName << ");";
+ C << nl << "__checkTwowayOnly(" << flatName << ", sync);";
}
- C << nl << "::IceInternal::OutgoingAsyncPtr __result = new ::IceInternal::OutgoingAsync(this, ";
- C << flatName << ", __del, __cookie);";
+ C << nl << "::IceInternal::OutgoingAsyncPtr __result = new ::IceInternal::CallbackOutgoing(this, " << flatName
+ << ", __del, __cookie, sync);";
C << nl << "try";
C << sb;
C << nl << "__result->prepare(" << flatName << ", " << operationModeToString(p->sendMode()) << ", __ctx);";
@@ -2435,15 +2234,15 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p)
}
else
{
- C << nl << "::IceInternal::BasicStream* __os = __result->startWriteParams(" << opFormatTypeToString(p) <<");";
+ C << nl << "::Ice::OutputStream* __os = __result->startWriteParams(" << opFormatTypeToString(p) <<");";
writeMarshalCode(C, inParams, 0, true, TypeContextInParam);
if(p->sendsClasses(false))
{
- C << nl << "__os->writePendingObjects();";
+ C << nl << "__os->writePendingValues();";
}
C << nl << "__result->endWriteParams();";
}
- C << nl << "__result->invoke();";
+ C << nl << "__result->invoke(" << flatName << ");";
C << eb;
C << nl << "catch(const ::Ice::Exception& __ex)";
C << sb;
@@ -2452,140 +2251,6 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p)
C << nl << "return __result;";
C << eb;
- if(p->returnsData())
- {
- C << nl << nl << "#ifdef ICE_CPP11";
-
- //
- // COMPILERFIX VC compilers up to VC110 don't support more than 10 parameters with std::function due to
- // lack of variadic templates.
- //
- if(outDecls.size() > 10 || (outDecls.size() > 9 && !retInS.empty()))
- {
-
- C << nl << "#if !defined(_MSC_VER) || _MSC_VER > 1700";
-
- C << nl << "//";
- C << nl << "// COMPILERFIX VC compilers up to VC110 don't support more than 10 parameters with";
- C << nl << "// std::function due to lack of variadic templates.";
- C << nl << "//";
- }
-
- C << sp << nl << "::Ice::AsyncResultPtr" << nl
- << "IceProxy" << scope << "__begin_" << name << spar << paramsDeclAMI
- << "const ::Ice::Context* __ctx" << "const ::IceInternal::Function<void " << spar;
-
- if(!retInS.empty())
- {
- C << retInS;
- }
- C << outDecls;
-
- C << epar << ">& __response, "
- << "const ::IceInternal::Function<void (const ::Ice::Exception&)>& __exception, "
- << "const ::IceInternal::Function<void (bool)>& __sent" << epar;
-
- C << sb;
- C << nl << "class Cpp11CB : public ::IceInternal::Cpp11FnCallbackNC";
- C << sb;
- C.dec();
- C << nl << "public:";
- C.inc();
- C << sp << nl << "Cpp11CB" << spar << "const ::std::function<void " << spar;
- if(!retInS.empty())
- {
- C << retInS;
- }
- C << outDecls;
- C << epar << ">& responseFunc, "
- << "const ::std::function<void (const ::Ice::Exception&)>& exceptionFunc, "
- << "const ::std::function<void (bool)>& sentFunc" << epar << " :";
- C.inc();
- C << nl << "::IceInternal::Cpp11FnCallbackNC(exceptionFunc, sentFunc),";
- C << nl << "_response(responseFunc)";
- C.dec();
- C << sb;
- C << nl << "CallbackBase::checkCallback(true, responseFunc || exceptionFunc != nullptr);";
- C << eb;
-
- //
- // completed.
- //
- C << sp << nl << "virtual void completed(const ::Ice::AsyncResultPtr& __result) const";
- C << sb;
- C << nl << clScope << clName << "Prx __proxy = " << clScope << clName
- << "Prx::uncheckedCast(__result->getProxy());";
- writeAllocateCode(C, outParams, p, true, _useWstring | TypeContextInParam | TypeContextAMICallPrivateEnd);
- C << nl << "try";
- C << sb;
- C << nl;
- if(!usePrivateEnd(p))
- {
- if(ret)
- {
- C << retEndArg << " = ";
- }
- C << "__proxy->end_" << p->name() << spar << outEndArgs << "__result" << epar << ';';
- }
- else
- {
- C << "__proxy->___end_" << p->name() << spar << outEndArgs;
- if(ret)
- {
- C << retEndArg;
- }
- C << "__result" << epar << ';';
- }
- writeEndCode(C, outParams, p, true);
- C << eb;
- C << nl << "catch(const ::Ice::Exception& ex)";
- C << sb;
- C << nl << "Cpp11FnCallbackNC::exception(__result, ex);";
- C << nl << "return;";
- C << eb;
- C << nl << "if(_response != nullptr)";
- C << sb;
- C << nl << "_response" << spar;
- if(ret)
- {
- C << "__ret";
- }
- C << outParamNamesAMI;
- C << epar << ';';
- C << eb;
- C << eb;
-
- C.dec();
- C << nl << nl << "private:";
- C.inc();
- C << nl;
- C << nl << "::std::function<void " << spar;
-
- if(!retInS.empty())
- {
- C << retInS;
- }
- C << outDecls;
-
- C << epar << "> _response;";
-
- C << eb << ';';
-
- C << nl << "return begin_" << name << spar << argsAMI << "__ctx"
- << "new Cpp11CB(__response, __exception, __sent)" << epar << ';';
- C << eb;
-
- //
- // COMPILERFIX VC compilers up to VC110 don't support more than 10 parameters with std::function due to
- // lack of variadic templates.
- //
- if(outDecls.size() > 10 || (outDecls.size() > 9 && !retInS.empty()))
- {
- C << nl << "#endif";
- }
- C << nl << "#endif"; // ICE_CPP11
- }
-
C << sp << nl << retS << nl << "IceProxy" << scope << "end_" << name << spar << outParamsDeclAMI
<< "const ::Ice::AsyncResultPtr& __result" << epar;
C << sb;
@@ -2627,16 +2292,16 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p)
}
C << nl << "catch(const ::Ice::UserException& __ex)";
C << sb;
- C << nl << "throw ::Ice::UnknownUserException(__FILE__, __LINE__, __ex.ice_name());";
+ C << nl << "throw ::Ice::UnknownUserException(__FILE__, __LINE__, __ex.ice_id());";
C << eb;
C << eb;
if(ret || !outParams.empty())
{
- C << nl << "::IceInternal::BasicStream* __is = __result->__startReadParams();";
+ C << nl << "::Ice::InputStream* __is = __result->__startReadParams();";
writeUnmarshalCode(C, outParams, p, true, _useWstring | TypeContextAMIEnd);
if(p->returnsClasses(false))
{
- C << nl << "__is->readPendingObjects();";
+ C << nl << "__is->readPendingValues();";
}
C << nl << "__result->__endReadParams();";
}
@@ -2690,16 +2355,17 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p)
}
C << nl << "catch(const ::Ice::UserException& __ex)";
C << sb;
- C << nl << "throw ::Ice::UnknownUserException(__FILE__, __LINE__, __ex.ice_name());";
+ C << nl << "throw ::Ice::UnknownUserException(__FILE__, __LINE__, __ex.ice_id());";
C << eb;
C << eb;
+
if(ret || !outParams.empty())
{
- C << nl << "::IceInternal::BasicStream* __is = __result->__startReadParams();";
+ C << nl << "::Ice::InputStream* __is = __result->__startReadParams();";
writeUnmarshalCode(C, outParams, p, true, _useWstring | TypeContextAMIPrivateEnd);
if(p->returnsClasses(false))
{
- C << nl << "__is->readPendingObjects();";
+ C << nl << "__is->readPendingValues();";
}
C << nl << "__result->__endReadParams();";
}
@@ -2750,6 +2416,7 @@ Slice::Gen::ObjectDeclVisitor::visitClassDecl(const ClassDeclPtr& p)
H << nl << _dllExport << "::Ice::Object* upCast(" << scoped << "*);";
H << nl << "typedef ::IceInternal::Handle< " << scoped << "> " << p->name() << "Ptr;";
H << nl << "typedef ::IceInternal::ProxyHandle< ::IceProxy" << scoped << "> " << p->name() << "Prx;";
+ H << nl << "typedef " << p->name() << "Prx " << p->name() << "PrxPtr;";
H << nl << _dllExport << "void __patch(" << p->name() << "Ptr&, const ::Ice::ObjectPtr&);";
}
else
@@ -2770,8 +2437,8 @@ Slice::Gen::ObjectDeclVisitor::visitOperation(const OperationPtr& p)
}
}
-Slice::Gen::ObjectVisitor::ObjectVisitor(Output& h, Output& c, const string& dllExport, bool stream) :
- H(h), C(c), _dllExport(dllExport), _stream(stream), _doneStaticSymbol(false), _useWstring(false)
+Slice::Gen::ObjectVisitor::ObjectVisitor(Output& h, Output& c, const string& dllExport) :
+ H(h), C(c), _dllExport(dllExport), _doneStaticSymbol(false), _useWstring(false)
{
}
@@ -2826,11 +2493,11 @@ Slice::Gen::ObjectVisitor::visitClassDefStart(const ClassDefPtr& p)
{
if(p->isLocal())
{
- H << "virtual public ::Ice::LocalObject";
+ H << "public virtual ::Ice::LocalObject";
}
else
{
- H << "virtual public ::Ice::Object";
+ H << "public virtual ::Ice::Object";
}
}
else
@@ -2853,7 +2520,7 @@ Slice::Gen::ObjectVisitor::visitClassDefStart(const ClassDefPtr& p)
}
bool hasBaseClass = !bases.empty() && !bases.front()->isInterface();
- bool override = p->canBeCyclic() && (!hasBaseClass || !bases.front()->canBeCyclic());
+ bool override = !p->isLocal() && p->canBeCyclic() && (!hasBaseClass || !bases.front()->canBeCyclic());
bool hasGCObjectBaseClass = basePreserved || override || preserved;
if(!basePreserved && (override || preserved))
{
@@ -2879,6 +2546,12 @@ Slice::Gen::ObjectVisitor::visitClassDefStart(const ClassDefPtr& p)
H << nl << "typedef " << p->name() << "Ptr PointerType;";
}
+ H << sp << nl << "virtual ~" << name << "();";
+ C << sp;
+ C << nl << scoped.substr(2) << "::~" << name << "()";
+ C << sb;
+ C << eb;
+
vector<string> params;
vector<string> allTypes;
vector<string> allParamDecls;
@@ -2912,124 +2585,7 @@ Slice::Gen::ObjectVisitor::visitClassDefStart(const ClassDefPtr& p)
H << sb << eb;
}
- /*
- * Strong guarantee: commented-out code marked "Strong guarantee" generates
- * a copy-assignment operator that provides the strong exception guarantee.
- * For now, this is commented out, and we use the compiler-generated
- * copy-assignment operator. However, that one does not provide the strong
- * guarantee.
-
- H << ';';
- if(!p->isAbstract())
- {
- H << nl << name << "& operator=(const " << name << "&)";
- if(allDataMembers.empty())
- {
- H << " { return *this; }";
- }
- H << ';';
- }
-
- //
- // __swap() is static because classes may be abstract, so we
- // can't use a non-static member function when we do an upcall
- // from a non-abstract derived __swap to the __swap in an abstract base.
- //
- H << sp << nl << "static void __swap(" << name << "&, " << name << "&) throw()";
- if(allDataMembers.empty())
- {
- H << " {}";
- }
- H << ';';
- H << nl << "void swap(" << name << "& rhs) throw()";
- H << sb;
- if(!allDataMembers.empty())
- {
- H << nl << "__swap(*this, rhs);";
- }
- H << eb;
-
- * Strong guarantee
- */
-
emitOneShotConstructor(p);
- H << sp;
-
- /*
- * Strong guarantee
-
- if(!allDataMembers.empty())
- {
- C << sp << nl << "void";
- C << nl << scoped.substr(2) << "::__swap(" << name << "& __lhs, " << name << "& __rhs) throw()";
- C << sb;
-
- if(base)
- {
- emitUpcall(base, "::__swap(__lhs, __rhs);");
- }
-
- //
- // We use a map to remember for which types we have already declared
- // a temporary variable and reuse that variable if a class has
- // more than one member of the same type. That way, we don't use more
- // temporaries than necessary. (::std::swap() instantiates a new temporary
- // each time it is used.)
- //
- map<string, int> tmpMap;
- map<string, int>::iterator pos;
- int tmpCount = 0;
-
- for(q = dataMembers.begin(); q != dataMembers.end(); ++q)
- {
- string memberName = fixKwd((*q)->name());
- TypePtr type = (*q)->type();
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
- if(builtin && builtin->kind() != Builtin::KindString
- || EnumPtr::dynamicCast(type) || ProxyPtr::dynamicCast(type)
- || ClassDeclPtr::dynamicCast(type) || StructPtr::dynamicCast(type))
- {
- //
- // For built-in types (except string), enums, proxies, structs, and classes,
- // do the swap via a temporary variable.
- //
- string typeName = typeToString(type);
- pos = tmpMap.find(typeName);
- if(pos == tmpMap.end())
- {
- pos = tmpMap.insert(pos, make_pair(typeName, tmpCount));
- C << nl << typeName << " __tmp" << tmpCount << ';';
- tmpCount++;
- }
- C << nl << "__tmp" << pos->second << " = __rhs." << memberName << ';';
- C << nl << "__rhs." << memberName << " = __lhs." << memberName << ';';
- C << nl << "__lhs." << memberName << " = __tmp" << pos->second << ';';
- }
- else
- {
- //
- // For dictionaries, vectors, and maps, use the standard container's
- // swap() (which is usually optimized).
- //
- C << nl << "__lhs." << memberName << ".swap(__rhs." << memberName << ");";
- }
- }
- C << eb;
-
- if(!p->isAbstract())
- {
- C << sp << nl << scoped << "&";
- C << nl << scoped.substr(2) << "::operator=(const " << name << "& __rhs)";
- C << sb;
- C << nl << name << " __tmp(__rhs);";
- C << nl << "__swap(*this, __tmp);";
- C << nl << "return *this;";
- C << eb;
- }
- }
-
- * Strong guarantee
- */
}
if(!p->isLocal())
@@ -3045,7 +2601,7 @@ Slice::Gen::ObjectVisitor::visitClassDefStart(const ClassDefPtr& p)
if(!p->isInterface())
{
- H << nl << "virtual ::Ice::ObjectPtr ice_clone() const;";
+ H << sp << nl << "virtual ::Ice::ObjectPtr ice_clone() const;";
if(hasGCObjectBaseClass)
{
@@ -3062,8 +2618,6 @@ Slice::Gen::ObjectVisitor::visitClassDefStart(const ClassDefPtr& p)
C << sb;
if(!p->isAbstract())
{
-
-
C << nl << "::Ice::Object* __p = new " << name << "(*this);";
C << nl << "return __p;";
}
@@ -3101,16 +2655,11 @@ Slice::Gen::ObjectVisitor::visitClassDefStart(const ClassDefPtr& p)
H << sp;
H << nl << "virtual bool ice_isA"
- << "(const ::std::string&, const ::Ice::Current& = ::Ice::Current()) const;";
+ << "(const ::std::string&, const ::Ice::Current& = ::Ice::noExplicitCurrent) const;";
H << nl << "virtual ::std::vector< ::std::string> ice_ids"
- << "(const ::Ice::Current& = ::Ice::Current()) const;";
- H << nl << "virtual const ::std::string& ice_id(const ::Ice::Current& = ::Ice::Current()) const;";
- H << nl << "static const ::std::string& ice_staticId();";
-
- if(!dataMembers.empty())
- {
- H << sp;
- }
+ << "(const ::Ice::Current& = ::Ice::noExplicitCurrent) const;";
+ H << nl << "virtual const ::std::string& ice_id(const ::Ice::Current& = ::Ice::noExplicitCurrent) const;";
+ H << sp << nl << "static const ::std::string& ice_staticId();";
string flatName = p->flattenedScope() + p->name() + "_ids";
@@ -3149,7 +2698,7 @@ Slice::Gen::ObjectVisitor::visitClassDefStart(const ClassDefPtr& p)
C << nl << "const ::std::string&" << nl << scoped.substr(2)
<< "::ice_id(const ::Ice::Current&) const";
C << sb;
- C << nl << "return " << flatName << '[' << scopedPos << "];";
+ C << nl << "return ice_staticId();";
C << eb;
C << sp;
@@ -3195,6 +2744,8 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
bool basePreserved = p->inheritsMetaData("preserve-slice");
bool preserved = p->hasMetaData("preserve-slice");
+ bool inProtected = false;
+
if(!p->isLocal())
{
OperationList allOps = p->allOperations();
@@ -3212,8 +2763,7 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
allOpNames.unique();
H << sp;
- H << nl
- << "virtual ::Ice::DispatchStatus __dispatch(::IceInternal::Incoming&, const ::Ice::Current&);";
+ H << nl << "virtual bool __dispatch(::IceInternal::Incoming&, const ::Ice::Current&);";
string flatName = p->flattenedScope() + p->name() + "_all";
C << sp << nl << "namespace";
@@ -3232,8 +2782,8 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
C << eb << ';';
C << sp << nl << "}";
C << sp;
- C << nl << "::Ice::DispatchStatus" << nl << scoped.substr(2)
- << "::__dispatch(::IceInternal::Incoming& in, const ::Ice::Current& current)";
+ C << nl << "bool";
+ C << nl << scoped.substr(2) << "::__dispatch(::IceInternal::Incoming& in, const ::Ice::Current& current)";
C << sb;
C << nl << "::std::pair< const ::std::string*, const ::std::string*> r = "
@@ -3255,12 +2805,14 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
C << nl << "return ___" << *q << "(in, current);";
C << eb;
}
- C << eb;
- C << sp;
+ C << nl << "default:";
+ C << sb;
C << nl << "assert(false);";
C << nl << "throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, "
<< "current.facet, current.operation);";
C << eb;
+ C << eb;
+ C << eb;
//
// Check if we need to generate ice_operationAttributes()
@@ -3330,74 +2882,49 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
if(!p->isAbstract())
{
- H << sp << nl << "static ::Ice::ObjectFactoryPtr ice_factory();";
+ H << sp << nl << "static ::Ice::ValueFactoryPtr ice_factory();";
}
if(preserved && !basePreserved)
{
H << sp;
- H << nl << "virtual void __write(::IceInternal::BasicStream*) const;";
- H << nl << "virtual void __read(::IceInternal::BasicStream*);";
-
- if(_stream)
- {
- H << nl << "virtual void __write(const ::Ice::OutputStreamPtr&) const;";
- H << nl << "virtual void __read(const ::Ice::InputStreamPtr&);";
- }
- else
- {
- string baseName = base ? fixKwd(base->scoped()) : string("::Ice::Object");
- H << nl << "using " << baseName << "::__write;";
- H << nl << "using " << baseName << "::__read;";
- }
+ H << nl << "virtual void __write(::Ice::OutputStream*) const;";
+ H << nl << "virtual void __read(::Ice::InputStream*);";
}
H.dec();
H << sp << nl << "protected:";
+ inProtected = true;
H.inc();
- H << nl << "virtual void __writeImpl(::IceInternal::BasicStream*) const;";
- H << nl << "virtual void __readImpl(::IceInternal::BasicStream*);";
-
- if(_stream)
- {
- H << nl << "virtual void __writeImpl(const ::Ice::OutputStreamPtr&) const;";
- H << nl << "virtual void __readImpl(const ::Ice::InputStreamPtr&);";
- }
- else
- {
- string baseName = base ? fixKwd(base->scoped()) : string("::Ice::Object");
- H << nl << "using " << baseName << "::__writeImpl;";
- H << nl << "using " << baseName << "::__readImpl;";
- }
+ H << sp << nl << "virtual void __writeImpl(::Ice::OutputStream*) const;";
+ H << nl << "virtual void __readImpl(::Ice::InputStream*);";
if(preserved && !basePreserved)
{
C << sp;
- C << nl << "void" << nl << scoped.substr(2)
- << "::__write(::IceInternal::BasicStream* __os) const";
+ C << nl << "void" << nl << scoped.substr(2) << "::__write(::Ice::OutputStream* __os) const";
C << sb;
- C << nl << "__os->startWriteObject(__slicedData);";
+ C << nl << "__os->startValue(__slicedData);";
C << nl << "__writeImpl(__os);";
- C << nl << "__os->endWriteObject();";
+ C << nl << "__os->endValue();";
C << eb;
C << sp;
- C << nl << "void" << nl << scoped.substr(2) << "::__read(::IceInternal::BasicStream* __is)";
+ C << nl << "void" << nl << scoped.substr(2) << "::__read(::Ice::InputStream* __is)";
C << sb;
- C << nl << "__is->startReadObject();";
+ C << nl << "__is->startValue();";
C << nl << "__readImpl(__is);";
- C << nl << "__slicedData = __is->endReadObject(true);";
+ C << nl << "__slicedData = __is->endValue(true);";
C << eb;
}
C << sp;
- C << nl << "void" << nl << scoped.substr(2)
- << "::__writeImpl(::IceInternal::BasicStream* __os) const";
+ C << nl << "void" << nl << scoped.substr(2) << "::__writeImpl(::Ice::OutputStream* __os) const";
C << sb;
- C << nl << "__os->startWriteSlice(ice_staticId(), " << p->compactId() << (!base ? ", true" : ", false") << ");";
- writeMarshalUnmarshalDataMembers(C, p->dataMembers(), p->orderedOptionalDataMembers(), true);
- C << nl << "__os->endWriteSlice();";
+ C << nl << "__os->startSlice(ice_staticId(), " << p->compactId() << (!base ? ", true" : ", false") << ");";
+ C << nl << "Ice::StreamWriter< ::" << scoped.substr(2) << ", ::Ice::OutputStream>::write(__os, *this);";
+ C << nl << "__os->endSlice();";
if(base)
{
emitUpcall(base, "::__writeImpl(__os);");
@@ -3405,60 +2932,17 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
C << eb;
C << sp;
- C << nl << "void" << nl << scoped.substr(2) << "::__readImpl(::IceInternal::BasicStream* __is)";
+ C << nl << "void" << nl << scoped.substr(2) << "::__readImpl(::Ice::InputStream* __is)";
C << sb;
- C << nl << "__is->startReadSlice();";
- writeMarshalUnmarshalDataMembers(C, p->dataMembers(), p->orderedOptionalDataMembers(), false);
- C << nl << "__is->endReadSlice();";
+ C << nl << "__is->startSlice();";
+ C << nl << "Ice::StreamReader< ::" << scoped.substr(2) << ", ::Ice::InputStream>::read(__is, *this);";
+ C << nl << "__is->endSlice();";
if(base)
{
emitUpcall(base, "::__readImpl(__is);");
}
C << eb;
- if(_stream)
- {
- if(preserved && !basePreserved)
- {
- C << sp << nl << "void" << nl << scoped.substr(2) << "::__write(const ::Ice::OutputStreamPtr& __os) const";
- C << sb;
- C << nl << "__os->startObject(__slicedData);";
- C << nl << "__writeImpl(__os);";
- C << nl << "__os->endObject();";
- C << eb;
-
- C << sp << nl << "void" << nl << scoped.substr(2) << "::__read(const ::Ice::InputStreamPtr& __is)";
- C << sb;
- C << nl << "__is->startObject();";
- C << nl << "__readImpl(__is);";
- C << nl << "__slicedData = __is->endObject(true);";
- C << eb;
- }
-
- C << sp << nl << "void" << nl << scoped.substr(2)
- << "::__writeImpl(const ::Ice::OutputStreamPtr& __os) const";
- C << sb;
- C << nl << "__os->startSlice(ice_staticId(), " << p->compactId() << (!base ? ", true" : ", false") << ");";
- writeMarshalUnmarshalDataMembers(C, p->dataMembers(), p->orderedOptionalDataMembers(), true);
- C << nl << "__os->endSlice();";
- if(base)
- {
- emitUpcall(base, "::__writeImpl(__os);");
- }
- C << eb;
-
- C << sp << nl << "void" << nl << scoped.substr(2) << "::__readImpl(const ::Ice::InputStreamPtr& __is)";
- C << sb;
- C << nl << "__is->startSlice();";
- writeMarshalUnmarshalDataMembers(C, p->dataMembers(), p->orderedOptionalDataMembers(), false);
- C << nl << "__is->endSlice();";
- if(base)
- {
- emitUpcall(base, "::__readImpl(__is);");
- }
- C << eb;
- }
-
if(!p->isAbstract() || p->compactId() >= 0)
{
C << sp << nl << "namespace";
@@ -3467,22 +2951,22 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
if(!p->isAbstract())
{
string initName = p->flattenedScope() + p->name() + "_init";
- C << sp << nl << "const ::IceInternal::DefaultObjectFactoryInit< " << scoped << "> "
+ C << nl << "const ::IceInternal::DefaultValueFactoryInit< " << scoped << "> "
<< initName << "(\"" << p->scoped() << "\");";
}
if(p->compactId() >= 0)
{
string initName = p->flattenedScope() + p->name() + "_compactIdInit";
- C << sp << nl << "const ::IceInternal::CompactIdInit "
+ C << nl << "const ::IceInternal::CompactIdInit "
<< initName << "(\"" << p->scoped() << "\", " << p->compactId() << ");";
}
C << nl << "}";
if(!p->isAbstract())
{
- C << sp << nl << "::Ice::ObjectFactoryPtr" << nl << scoped.substr(2) << "::ice_factory()";
+ C << sp << nl << "::Ice::ValueFactoryPtr" << nl << scoped.substr(2) << "::ice_factory()";
C << sb;
- C << nl << "return ::IceInternal::factoryTable->getObjectFactory(" << scoped << "::ice_staticId());";
+ C << nl << "return ::IceInternal::factoryTable->getValueFactory(" << scoped << "::ice_staticId());";
C << eb;
}
}
@@ -3491,9 +2975,10 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
//
// Emit data members. Access visibility may be specified by metadata.
//
- bool inProtected = true;
+ bool generateFriend = false;
DataMemberList dataMembers = p->dataMembers();
bool prot = p->hasMetaData("protected");
+ bool needSp = true;
for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
{
if(prot || (*q)->hasMetaData("protected"))
@@ -3501,48 +2986,47 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
if(!inProtected)
{
H.dec();
- H << sp << nl << "protected:";
+ H << sp << nl << "protected:" << sp;
H.inc();
inProtected = true;
+ needSp = false;
}
+ generateFriend = true;
}
else
{
if(inProtected)
{
H.dec();
- H << sp << nl << "public:";
+ H << sp << nl << "public:" << sp;
H.inc();
inProtected = false;
+ needSp = false;
}
}
+ if(needSp)
+ {
+ H << sp;
+ needSp = false;
+ }
+
emitDataMember(*q);
}
- if(!p->isAbstract())
+ if(!p->isLocal() && preserved && !basePreserved)
{
- //
- // We add a protected destructor to force heap instantiation of the class.
- //
if(!inProtected)
{
H.dec();
- H << nl << "protected:";
+ H << sp << nl << "protected:";
H.inc();
inProtected = true;
}
- H << sp << nl << "virtual ~" << fixKwd(p->name()) << "() {}";
-
- if(!_doneStaticSymbol)
- {
- H.dec();
- H << sp << nl << "friend class " << p->name() << "__staticInit;";
- H.inc();
- }
+ H << sp << nl << "::Ice::SlicedDataPtr __slicedData;";
}
- if(!p->isLocal() && preserved && !basePreserved)
+ if(generateFriend)
{
if(!inProtected)
{
@@ -3551,7 +3035,12 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
H.inc();
inProtected = true;
}
- H << sp << nl << "::Ice::SlicedDataPtr __slicedData;";
+
+ H << sp;
+ H << nl << "template<typename T, typename S>";
+ H << nl << "friend struct Ice::StreamWriter;";
+ H << nl << "template<typename T, typename S>";
+ H << nl << "friend struct Ice::StreamReader;";
}
H << eb << ';';
@@ -3559,40 +3048,11 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
if(!p->isAbstract() && !p->isLocal() && !_doneStaticSymbol)
{
//
- // We need an instance here to trigger initialization if the implementation is in a shared library.
+ // We need an instance here to trigger initialization if the implementation is in a static library.
// But we do this only once per source file, because a single instance is sufficient to initialize
- // all of the globals in a shared library.
+ // all of the globals in a compilation unit.
//
- // For a Slice class Foo, we instantiate a dummy class Foo__staticInit instead of using a static
- // Foo instance directly because Foo has a protected destructor.
- //
- H.zeroIndent();
- H << nl << "#if !defined(_MSC_VER) || (_MSC_VER < 1900)";
- H.restoreIndent();
- H << nl << "//";
- H << nl << "// COMPILERFIX: Visual Studio 2015 update 1 fails to access";
- H << nl << "// the proected destructor from a friend class.";
- H << nl << "//";
-
- H << sp << nl << "class " << p->name() << "__staticInit";
- H << sb;
- H.dec();
- H << nl << "public:";
- H.inc();
- H << sp << nl << scoped << " _init;";
- H << eb << ';';
- _doneStaticSymbol = true;
- H << sp << nl << "static " << p->name() << "__staticInit _" << p->name() << "_init;";
-
- H.zeroIndent();
- H << nl << "#else";
- H.restoreIndent();
-
- H << nl << "static auto _" << p->name() << "_init = " << p->scoped() << "::ice_factory;";
-
- H.zeroIndent();
- H << nl << "#endif";
- H.restoreIndent();
+ H << nl << "static ::Ice::ValueFactoryPtr _" << p->name() << "_init = " << p->scoped() << "::ice_factory();";
}
if(p->isLocal())
@@ -3669,7 +3129,7 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p)
string paramsAMD = "(const " + classScopedAMD + '_' + name + "Ptr&, ";
string paramsDeclAMD = "(const " + classScopedAMD + '_' + name + "Ptr& __cb, ";
- string argsAMD = "(__cb, ";
+ string argsAMD = "(new IceAsync" + classScopedAMD + '_' + name + "(__inS), ";
ParamDeclList inParams;
ParamDeclList outParams;
@@ -3731,7 +3191,7 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p)
args += ", ";
}
- params += "const ::Ice::Current& = ::Ice::Current())";
+ params += "const ::Ice::Current& = ::Ice::noExplicitCurrent)";
paramsDecl += "const ::Ice::Current& __current)";
args += "__current)";
}
@@ -3742,11 +3202,11 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p)
args += ')';
}
- paramsAMD += "const ::Ice::Current& = ::Ice::Current())";
+ paramsAMD += "const ::Ice::Current& = ::Ice::noExplicitCurrent)";
paramsDeclAMD += "const ::Ice::Current& __current)";
argsAMD += "__current)";
- bool isConst = (p->mode() == Operation::Nonmutating) || p->hasMetaData("cpp:const");
+ string isConst = ((p->mode() == Operation::Nonmutating) || p->hasMetaData("cpp:const")) ? " const" : "";
bool amd = !cl->isLocal() && (cl->hasMetaData("amd") || p->hasMetaData("amd"));
string deprecateSymbol = getDeprecateSymbol(p, cl);
@@ -3754,69 +3214,46 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p)
H << sp;
if(!amd)
{
- H << nl << deprecateSymbol << "virtual " << retS << ' ' << fixKwd(name) << params
- << (isConst ? " const" : "") << " = 0;";
+ H << nl << deprecateSymbol << "virtual " << retS << ' ' << fixKwd(name) << params << isConst << " = 0;";
}
else
{
- H << nl << deprecateSymbol << "virtual void " << name << "_async" << paramsAMD
- << (isConst ? " const" : "") << " = 0;";
+ H << nl << deprecateSymbol << "virtual void " << name << "_async" << paramsAMD << isConst << " = 0;";
}
if(!cl->isLocal())
{
- H << nl << "::Ice::DispatchStatus ___" << name
- << "(::IceInternal::Incoming&, const ::Ice::Current&)" << (isConst ? " const" : "") << ';';
+ H << nl << "bool ___" << name << "(::IceInternal::Incoming&, const ::Ice::Current&)" << isConst << ';';
C << sp;
- C << nl << "::Ice::DispatchStatus" << nl << scope.substr(2) << "___" << name
- << "(::IceInternal::Incoming& __inS";
- C << ", const ::Ice::Current& __current)" << (isConst ? " const" : "");
+ C << nl << "bool" << nl << scope.substr(2) << "___" << name << "(::IceInternal::Incoming& __inS"
+ << ", const ::Ice::Current& __current)" << isConst;
C << sb;
- if(!amd)
- {
- ExceptionList throws = p->throws();
- throws.sort();
- throws.unique();
+ C << nl << "__checkMode(" << operationModeToString(p->mode()) << ", __current.mode);";
- //
- // Arrange exceptions into most-derived to least-derived order. If we don't
- // do this, a base exception handler can appear before a derived exception
- // handler, causing compiler warnings and resulting in the base exception
- // being marshaled instead of the derived exception.
- //
-
-#if defined(__SUNPRO_CC)
- throws.sort(derivedToBaseCompare);
-#else
- throws.sort(Slice::DerivedToBaseCompare());
-#endif
-
- C << nl << "__checkMode(" << operationModeToString(p->mode()) << ", __current.mode);";
-
- if(!inParams.empty())
- {
- C << nl << "::IceInternal::BasicStream* __is = __inS.startReadParams();";
- writeAllocateCode(C, inParams, 0, true, _useWstring | TypeContextInParam);
- writeUnmarshalCode(C, inParams, 0, true, TypeContextInParam);
- if(p->sendsClasses(false))
- {
- C << nl << "__is->readPendingObjects();";
- }
- C << nl << "__inS.endReadParams();";
- }
- else
+ if(!inParams.empty())
+ {
+ C << nl << "::Ice::InputStream* __is = __inS.startReadParams();";
+ writeAllocateCode(C, inParams, 0, true, _useWstring | TypeContextInParam);
+ writeUnmarshalCode(C, inParams, 0, true, TypeContextInParam);
+ if(p->sendsClasses(false))
{
- C << nl << "__inS.readEmptyParams();";
+ C << nl << "__is->readPendingValues();";
}
+ C << nl << "__inS.endReadParams();";
+ }
+ else
+ {
+ C << nl << "__inS.readEmptyParams();";
+ }
+ if(p->format() != DefaultFormat)
+ {
+ C << nl << "__inS.setFormat(" << opFormatTypeToString(p) << ");";
+ }
+ if(!amd)
+ {
writeAllocateCode(C, outParams, 0, true, _useWstring);
- if(!throws.empty())
- {
- C << nl << "try";
- C << sb;
- }
- C << nl;
if(ret)
{
C << retS << " __ret = ";
@@ -3824,74 +3261,29 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p)
C << fixKwd(name) << args << ';';
if(ret || !outParams.empty())
{
- C << nl << "::IceInternal::BasicStream* __os = __inS.__startWriteParams("
- << opFormatTypeToString(p) << ");";
+ C << nl << "::Ice::OutputStream* __os = __inS.startWriteParams();";
writeMarshalCode(C, outParams, p, true);
if(p->returnsClasses(false))
{
- C << nl << "__os->writePendingObjects();";
+ C << nl << "__os->writePendingValues();";
}
- C << nl << "__inS.__endWriteParams(true);";
+ C << nl << "__inS.endWriteParams();";
}
else
{
- C << nl << "__inS.__writeEmptyParams();";
- }
- C << nl << "return ::Ice::DispatchOK;";
- if(!throws.empty())
- {
- C << eb;
- ExceptionList::const_iterator r;
- for(r = throws.begin(); r != throws.end(); ++r)
- {
- C << nl << "catch(const " << fixKwd((*r)->scoped()) << "& __ex)";
- C << sb;
- C << nl << "__inS.__writeUserException(__ex, " << opFormatTypeToString(p) << ");";
- C << eb;
- }
- C << nl << "return ::Ice::DispatchUserException;";
+ C << nl << "__inS.writeEmptyParams();";
}
+ C << nl << "return false;";
}
else
{
- C << nl << "__checkMode(" << operationModeToString(p->mode()) << ", __current.mode);";
-
- if(!inParams.empty())
- {
- C << nl << "::IceInternal::BasicStream* __is = __inS.startReadParams();";
- writeAllocateCode(C, inParams, 0, true, _useWstring | TypeContextInParam);
- writeUnmarshalCode(C, inParams, 0, true, TypeContextInParam);
- if(p->sendsClasses(false))
- {
- C << nl << "__is->readPendingObjects();";
- }
- C << nl << "__inS.endReadParams();";
- }
- else
- {
- C << nl << "__inS.readEmptyParams();";
- }
-
- C << nl << classScopedAMD << '_' << name << "Ptr __cb = new IceAsync" << classScopedAMD << '_' << name
- << "(__inS);";
- C << nl << "try";
- C << sb;
C << nl << name << "_async" << argsAMD << ';';
- C << eb;
- C << nl << "catch(const ::std::exception& __ex)";
- C << sb;
- C << nl << "__cb->ice_exception(__ex);";
- C << eb;
- C << nl << "catch(...)";
- C << sb;
- C << nl << "__cb->ice_exception();";
- C << eb;
- C << nl << "return ::Ice::DispatchAsync;";
+ C << nl << "return true;";
}
C << eb;
}
- if(cl->isLocal() && (cl->hasMetaData("async") || p->hasMetaData("async")))
+ if(cl->isLocal() && (cl->hasMetaData("async-oneway") || p->hasMetaData("async-oneway")))
{
vector<string> paramsDeclAMI;
vector<string> outParamsDeclAMI;
@@ -3923,12 +3315,6 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p)
}
}
- H << nl << "// Only supported with C++ 11 support enabled";
- H << nl << "virtual ::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI
- << "const ::IceInternal::Function<void (const ::Ice::Exception&)>& exception"
- << "const ::IceInternal::Function<void (bool)>& sent = ::IceInternal::Function<void (bool)>()"
- << epar << " = 0;";
-
H << sp << nl << "virtual ::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI << epar << " = 0;";
H << sp << nl << "virtual ::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI
@@ -3952,7 +3338,7 @@ void
Slice::Gen::ObjectVisitor::emitDataMember(const DataMemberPtr& p)
{
string name = fixKwd(p->name());
- H << sp << nl << typeToString(p->type(), p->optional(), p->getMetaData(), _useWstring) << ' ' << name << ';';
+ H << nl << typeToString(p->type(), p->optional(), p->getMetaData(), _useWstring) << ' ' << name << ';';
}
void
@@ -4028,7 +3414,9 @@ void
Slice::Gen::ObjectVisitor::emitGCVisitCode(const TypePtr& p, const string& prefix, const string& name, int level)
{
BuiltinPtr builtin = BuiltinPtr::dynamicCast(p);
- if((builtin && BuiltinPtr::dynamicCast(p)->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(p))
+ if((builtin &&
+ (BuiltinPtr::dynamicCast(p)->kind() == Builtin::KindObject || BuiltinPtr::dynamicCast(p)->kind() == Builtin::KindValue)) ||
+ ClassDeclPtr::dynamicCast(p))
{
C << nl << "if(" << prefix << name << ')';
C << sb;
@@ -4215,7 +3603,7 @@ Slice::Gen::AsyncCallbackVisitor::AsyncCallbackVisitor(Output& h, Output&, const
bool
Slice::Gen::AsyncCallbackVisitor::visitModuleStart(const ModulePtr& p)
{
- if(!p->hasNonLocalClassDefs() && !p->hasContentsWithMetaData("async"))
+ if(!p->hasNonLocalClassDefs() && !p->hasContentsWithMetaData("async-oneway"))
{
return false;
}
@@ -4253,7 +3641,7 @@ Slice::Gen::AsyncCallbackVisitor::visitOperation(const OperationPtr& p)
{
ClassDefPtr cl = ClassDefPtr::dynamicCast(p->container());
- if(cl->isLocal() && !(cl->hasMetaData("async") || p->hasMetaData("async")))
+ if(cl->isLocal() && !(cl->hasMetaData("async-oneway") || p->hasMetaData("async-oneway")))
{
return;
}
@@ -4262,7 +3650,7 @@ Slice::Gen::AsyncCallbackVisitor::visitOperation(const OperationPtr& p)
// Write the callback base class and callback smart pointer.
//
string delName = "Callback_" + cl->name() + "_" + p->name();
- H << sp << nl << "class " << delName << "_Base : virtual public ::IceInternal::CallbackBase { };";
+ H << sp << nl << "class " << delName << "_Base : public virtual ::IceInternal::CallbackBase { };";
H << nl << "typedef ::IceUtil::Handle< " << delName << "_Base> " << delName << "Ptr;";
}
@@ -4300,7 +3688,6 @@ void
Slice::Gen::AsyncCallbackTemplateVisitor::visitModuleEnd(const ModulePtr&)
{
_useWstring = resetUseWstring(_useWstringHist);
-
H << sp << nl << '}';
}
@@ -4489,7 +3876,9 @@ Slice::Gen::AsyncCallbackTemplateVisitor::generateOperation(const OperationPtr&
H << epar << ';';
H << eb;
H << eb;
+ H.dec();
H << sp << nl << "private:";
+ H.inc();
H << sp << nl << "Response _response;";
}
H << eb << ';';
@@ -4574,57 +3963,8 @@ Slice::Gen::ImplVisitor::ImplVisitor(Output& h, Output& c, const string& dllExpo
{
}
-void
-Slice::Gen::ImplVisitor::writeDecl(Output& out, const string& name, const TypePtr& type, const StringList& metaData)
-{
- out << nl << typeToString(type, metaData, _useWstring) << ' ' << name;
-
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
- if(builtin)
- {
- switch(builtin->kind())
- {
- case Builtin::KindBool:
- {
- out << " = false";
- break;
- }
- case Builtin::KindByte:
- case Builtin::KindShort:
- case Builtin::KindInt:
- case Builtin::KindLong:
- {
- out << " = 0";
- break;
- }
- case Builtin::KindFloat:
- case Builtin::KindDouble:
- {
- out << " = 0.0";
- break;
- }
- case Builtin::KindString:
- case Builtin::KindObject:
- case Builtin::KindObjectProxy:
- case Builtin::KindLocalObject:
- {
- break;
- }
- }
- }
-
- EnumPtr en = EnumPtr::dynamicCast(type);
- if(en)
- {
- EnumeratorList enumerators = en->getEnumerators();
- out << " = " << fixKwd(en->scope()) << fixKwd(enumerators.front()->name());
- }
-
- out << ';';
-}
-
-void
-Slice::Gen::ImplVisitor::writeReturn(Output& out, const TypePtr& type, const StringList& metaData)
+string
+Slice::Gen::ImplVisitor::defaultValue(const TypePtr& type, const StringList& metaData) const
{
BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
if(builtin)
@@ -4633,84 +3973,76 @@ Slice::Gen::ImplVisitor::writeReturn(Output& out, const TypePtr& type, const Str
{
case Builtin::KindBool:
{
- out << nl << "return false;";
- break;
+ return "false";
}
case Builtin::KindByte:
case Builtin::KindShort:
case Builtin::KindInt:
case Builtin::KindLong:
{
- out << nl << "return 0;";
- break;
+ return "0";
}
case Builtin::KindFloat:
case Builtin::KindDouble:
{
- out << nl << "return 0.0;";
- break;
+ return "0.0";
}
case Builtin::KindString:
{
- out << nl << "return ::std::string();";
- break;
+ return "::std::string()";
}
+ case Builtin::KindValue:
case Builtin::KindObject:
case Builtin::KindObjectProxy:
case Builtin::KindLocalObject:
{
- out << nl << "return 0;";
- break;
+ return "0";
}
}
}
else
{
ProxyPtr prx = ProxyPtr::dynamicCast(type);
- if(prx)
+
+ if(ProxyPtr::dynamicCast(type) || ClassDeclPtr::dynamicCast(type))
{
- out << nl << "return 0;";
+ return "0";
}
- else
+
+ StructPtr st = StructPtr::dynamicCast(type);
+ if(st)
{
- ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
- if(cl)
- {
- out << nl << "return 0;";
- }
- else
- {
- StructPtr st = StructPtr::dynamicCast(type);
- if(st)
- {
- out << nl << "return " << fixKwd(st->scoped()) << "();";
- }
- else
- {
- EnumPtr en = EnumPtr::dynamicCast(type);
- if(en)
- {
- EnumeratorList enumerators = en->getEnumerators();
- out << nl << "return " << fixKwd(en->scope()) << fixKwd(enumerators.front()->name()) << ';';
- }
- else
- {
- SequencePtr seq = SequencePtr::dynamicCast(type);
- if(seq)
- {
- out << nl << "return " << typeToString(seq, metaData, _useWstring) << "();";
- }
- else
- {
- DictionaryPtr dict = DictionaryPtr::dynamicCast(type);
- assert(dict);
- out << nl << "return " << fixKwd(dict->scoped()) << "();";
- }
- }
- }
- }
+ return fixKwd(st->scoped()) + "()";
+ }
+
+ EnumPtr en = EnumPtr::dynamicCast(type);
+ if(en)
+ {
+ EnumeratorList enumerators = en->getEnumerators();
+ return fixKwd(en->scope() + enumerators.front()->name());
+ }
+
+ SequencePtr seq = SequencePtr::dynamicCast(type);
+ if(seq)
+ {
+ return typeToString(seq, metaData, _useWstring | TypeContextCpp11) + "()";
+ }
+
+ DictionaryPtr dict = DictionaryPtr::dynamicCast(type);
+ if(dict)
+ {
+ return fixKwd(dict->scoped()) + "()";
}
}
+
+ assert(false);
+ return "???";
+}
+
+void
+Slice::Gen::ImplVisitor::writeReturn(Output& out, const TypePtr& type, const StringList& metaData)
+{
+ out << nl << "return " << defaultValue(type, metaData) << ";";
}
bool
@@ -4720,32 +4052,8 @@ Slice::Gen::ImplVisitor::visitModuleStart(const ModulePtr& p)
{
return false;
}
-
_useWstring = setUseWstring(p, _useWstringHist, _useWstring);
-
- set<string> includes;
- ClassList classes = p->classes();
- for(ClassList::const_iterator q = classes.begin(); q != classes.end(); ++q)
- {
- ClassList bases = (*q)->bases();
- for(ClassList::const_iterator r = bases.begin(); r != bases.end(); ++r)
- {
- if((*r)->isAbstract())
- {
- includes.insert((*r)->name());
- }
- }
- }
-
- for(set<string>::const_iterator it = includes.begin(); it != includes.end(); ++it)
- {
- H << nl << "#include <" << *it << "I.h>";
- }
-
- string name = fixKwd(p->name());
-
- H << sp << nl << "namespace " << name << nl << '{';
-
+ H << sp << nl << "namespace " << fixKwd(p->name()) << nl << '{';
return true;
}
@@ -4771,38 +4079,25 @@ Slice::Gen::ImplVisitor::visitClassDefStart(const ClassDefPtr& p)
string name = p->name();
string scope = fixKwd(p->scope());
string cls = scope.substr(2) + name + "I";
- string classScopedAMD = scope + "AMD_" + name;
ClassList bases = p->bases();
H << sp;
- H << nl << "class " << name << "I : ";
- H.useCurrentPosAsIndent();
- H << "virtual public " << fixKwd(name);
- for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q)
- {
- H << ',' << nl << "virtual public " << fixKwd((*q)->scope());
- if((*q)->isAbstract())
- {
- H << (*q)->name() << "I";
- }
- else
- {
- H << fixKwd((*q)->name());
- }
- }
- H.restoreIndent();
+ H << nl << "class " << name << "I : public virtual " << fixKwd(name);
H << sb;
H.dec();
H << nl << "public:";
H.inc();
- OperationList ops = p->operations();
+ OperationList ops = p->allOperations();
for(OperationList::const_iterator r = ops.begin(); r != ops.end(); ++r)
{
OperationPtr op = (*r);
string opName = op->name();
+ string isConst = ((op->mode() == Operation::Nonmutating) || op->hasMetaData("cpp:const")) ? " const" : "";
+
+ string classScopedAMD = scope + "AMD_" + ClassDefPtr::dynamicCast(op->container())->name();
TypePtr ret = op->returnType();
string retS = returnTypeToString(ret, op->returnIsOptional(), op->getMetaData(), _useWstring);
@@ -4824,10 +4119,7 @@ Slice::Gen::ImplVisitor::visitClassDefStart(const ClassDefPtr& p)
}
H << ',' << nl << "const Ice::Current&";
H.restoreIndent();
-
- bool isConst = (op->mode() == Operation::Nonmutating) || op->hasMetaData("cpp:const");
-
- H << ")" << (isConst ? " const" : "") << ';';
+ H << ")" << isConst << ';';
C << sp << nl << "void" << nl << scope << name << "I::" << opName << "_async(";
C.useCurrentPosAsIndent();
@@ -4842,7 +4134,7 @@ Slice::Gen::ImplVisitor::visitClassDefStart(const ClassDefPtr& p)
}
C << ',' << nl << "const Ice::Current& current";
C.restoreIndent();
- C << ")" << (isConst ? " const" : "");
+ C << ")" << isConst;
C << sb;
string result = "r";
@@ -4854,22 +4146,11 @@ Slice::Gen::ImplVisitor::visitClassDefStart(const ClassDefPtr& p)
break;
}
}
- if(ret)
- {
- writeDecl(C, result, ret, op->getMetaData());
- }
- for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
- {
- if((*q)->isOutParam())
- {
- writeDecl(C, fixKwd((*q)->name()), (*q)->type(), (*q)->getMetaData());
- }
- }
C << nl << opName << "CB->ice_response(";
if(ret)
{
- C << result;
+ C << defaultValue(ret, op->getMetaData());
}
for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
{
@@ -4879,7 +4160,7 @@ Slice::Gen::ImplVisitor::visitClassDefStart(const ClassDefPtr& p)
{
C << ", ";
}
- C << fixKwd((*q)->name());
+ C << defaultValue((*q)->type(), op->getMetaData());
}
}
C << ");";
@@ -4897,17 +4178,14 @@ Slice::Gen::ImplVisitor::visitClassDefStart(const ClassDefPtr& p)
{
H << ',' << nl;
}
- StringList metaData = (*q)->getMetaData();
- string typeString;
if((*q)->isOutParam())
{
- typeString = outputTypeToString((*q)->type(), (*q)->optional(), metaData, _useWstring);
+ H << outputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring);
}
else
{
- typeString = inputTypeToString((*q)->type(), (*q)->optional(), metaData, _useWstring);
+ H << inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring);
}
- H << typeString;
}
if(!p->isLocal())
{
@@ -4919,9 +4197,9 @@ Slice::Gen::ImplVisitor::visitClassDefStart(const ClassDefPtr& p)
}
H.restoreIndent();
- bool isConst = (op->mode() == Operation::Nonmutating) || op->hasMetaData("cpp:const");
+ string isConst = ((op->mode() == Operation::Nonmutating) || op->hasMetaData("cpp:const")) ? " const" : "";
- H << ")" << (isConst ? " const" : "") << ';';
+ H << ")" << isConst << ';';
C << sp << nl << retS << nl;
C << scope.substr(2) << name << "I::" << fixKwd(opName) << '(';
@@ -4932,17 +4210,16 @@ Slice::Gen::ImplVisitor::visitClassDefStart(const ClassDefPtr& p)
{
C << ',' << nl;
}
- StringList metaData = (*q)->getMetaData();
- string typeString;
if((*q)->isOutParam())
{
- typeString = outputTypeToString((*q)->type(), (*q)->optional(), metaData, _useWstring);
+ C << outputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring) << " "
+ << fixKwd((*q)->name());
}
else
{
- typeString = inputTypeToString((*q)->type(), (*q)->optional(), metaData, _useWstring);
+ C << inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring) << " /*"
+ << fixKwd((*q)->name()) << "*/";
}
- C << typeString << ' ' << fixKwd((*q)->name());
}
if(!p->isLocal())
{
@@ -4954,7 +4231,7 @@ Slice::Gen::ImplVisitor::visitClassDefStart(const ClassDefPtr& p)
}
C.restoreIndent();
C << ')';
- C << (isConst ? " const" : "");
+ C << isConst;
C << sb;
if(ret)
@@ -4973,8 +4250,8 @@ Slice::Gen::ImplVisitor::visitClassDefStart(const ClassDefPtr& p)
return true;
}
-Slice::Gen::AsyncVisitor::AsyncVisitor(Output& h, Output&, const string& dllExport) :
- H(h), _dllExport(dllExport), _useWstring(false)
+Slice::Gen::AsyncVisitor::AsyncVisitor(Output& h, Output& c, const string& dllExport) :
+ H(h), C(c), _dllExport(dllExport), _useWstring(false)
{
}
@@ -5084,17 +4361,27 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p)
}
}
- paramsInvoke.push_back("const ::Ice::Context*");
- paramsDeclInvoke.push_back("const ::Ice::Context* __ctx");
+ paramsInvoke.push_back("const ::Ice::Context&");
+ paramsDeclInvoke.push_back("const ::Ice::Context& __ctx");
if(cl->hasMetaData("amd") || p->hasMetaData("amd"))
{
- H << sp << nl << "class " << _dllExport << classNameAMD << '_' << name
- << " : virtual public ::Ice::AMDCallback";
+ string cbName = classNameAMD + '_' + name;
+
+ H << sp << nl << "class " << _dllExport << cbName
+ << " : public virtual ::Ice::AMDCallback";
H << sb;
H.dec();
H << nl << "public:";
H.inc();
+
+ // Out of line dtor to avoid weak vtable
+ H << sp << nl << "virtual ~" << cbName << "();";
+ C << sp;
+ C << nl << classScope.substr(2) << cbName << "::~" << cbName << "()";
+ C << sb;
+ C << eb;
+
H << sp;
H << nl << "virtual void ice_response" << spar << paramsAMD << epar << " = 0;";
H << eb << ';';
@@ -5186,22 +4473,6 @@ Slice::Gen::AsyncImplVisitor::visitOperation(const OperationPtr& p)
string paramsDecl;
string args;
- ExceptionList throws = p->throws();
- throws.sort();
- throws.unique();
-
- //
- // Arrange exceptions into most-derived to least-derived order. If we don't
- // do this, a base exception handler can appear before a derived exception
- // handler, causing compiler warnings and resulting in the base exception
- // being marshaled instead of the derived exception.
- //
-#if defined(__SUNPRO_CC)
- throws.sort(derivedToBaseCompare);
-#else
- throws.sort(Slice::DerivedToBaseCompare());
-#endif
-
TypePtr ret = p->returnType();
string retS = inputTypeToString(ret, p->returnIsOptional(), p->getMetaData(), _useWstring);
@@ -5253,12 +4524,6 @@ Slice::Gen::AsyncImplVisitor::visitOperation(const OperationPtr& p)
H << sp;
H << nl << "virtual void ice_response(" << params << ");";
- if(!throws.empty())
- {
- H << nl << "// COMPILERFIX: The using directive avoid compiler warnings with -Woverloaded-virtual";
- H << nl << "using ::IceInternal::IncomingAsync::ice_exception;";
- H << nl << "virtual void ice_exception(const ::std::exception&);";
- }
H << eb << ';';
C << sp << nl << "IceAsync" << classScopedAMD << '_' << name << "::" << classNameAMD << '_' << name
@@ -5269,65 +4534,25 @@ Slice::Gen::AsyncImplVisitor::visitOperation(const OperationPtr& p)
C << sb;
C << eb;
- C << sp << nl << "void" << nl << "IceAsync" << classScopedAMD << '_' << name << "::ice_response("
- << paramsDecl << ')';
- C << sb;
- C << nl << "if(__validateResponse(true))";
+ C << sp << nl << "void";
+ C << nl << "IceAsync" << classScopedAMD << '_' << name << "::ice_response(" << paramsDecl << ')';
C << sb;
if(ret || !outParams.empty())
{
- C << nl << "try";
- C << sb;
- C << nl << "::IceInternal::BasicStream* __os = __startWriteParams(" << opFormatTypeToString(p) << ");";
+ C << nl << "::Ice::OutputStream* __os = startWriteParams();";
writeMarshalCode(C, outParams, p, false, TypeContextInParam);
if(p->returnsClasses(false))
{
- C << nl << "__os->writePendingObjects();";
+ C << nl << "__os->writePendingValues();";
}
- C << nl << "__endWriteParams(true);";
- C << eb;
- C << nl << "catch(const ::Ice::Exception& __ex)";
- C << sb;
- C << nl << "__exception(__ex);";
- C << nl << "return;";
- C << eb;
+ C << nl << "endWriteParams();";
}
else
{
- C << nl << "__writeEmptyParams();";
+ C << nl << "writeEmptyParams();";
}
- C << nl << "__response();";
- C << eb;
+ C << nl << "completed();";
C << eb;
-
- if(!throws.empty())
- {
- C << sp << nl << "void" << nl << "IceAsync" << classScopedAMD << '_' << name
- << "::ice_exception(const ::std::exception& ex)";
- C << sb;
- for(ExceptionList::const_iterator r = throws.begin(); r != throws.end(); ++r)
- {
- C << nl;
- if(r != throws.begin())
- {
- C << "else ";
- }
- C << "if(const " << fixKwd((*r)->scoped()) << "* __ex = dynamic_cast<const " << fixKwd((*r)->scoped())
- << "*>(&ex))";
- C << sb;
- C << nl <<"if(__validateResponse(false))";
- C << sb;
- C << nl << "__writeUserException(*__ex, " << opFormatTypeToString(p) << ");";
- C << nl << "__response();";
- C << eb;
- C << eb;
- }
- C << nl << "else";
- C << sb;
- C << nl << "::IceInternal::IncomingAsync::ice_exception(ex);";
- C << eb;
- C << eb;
- }
}
Slice::Gen::StreamVisitor::StreamVisitor(Output& h, Output& c, const string& dllExport) :
@@ -5342,6 +4567,7 @@ Slice::Gen::StreamVisitor::visitModuleStart(const ModulePtr& m)
{
if(!m->hasNonLocalContained(Contained::ContainedTypeStruct) &&
!m->hasNonLocalContained(Contained::ContainedTypeEnum) &&
+ !m->hasNonLocalContained(Contained::ContainedTypeClass) &&
!m->hasNonLocalContained(Contained::ContainedTypeException))
{
return false;
@@ -5353,7 +4579,7 @@ Slice::Gen::StreamVisitor::visitModuleStart(const ModulePtr& m)
// Only emit this for the top-level module.
//
H << sp;
- H << nl << "namespace Ice" << nl << '{';
+ H << nl << "namespace Ice" << nl << '{' << sp;
C << sp;
C << nl << "namespace Ice" << nl << '{';
@@ -5376,6 +4602,16 @@ Slice::Gen::StreamVisitor::visitModuleEnd(const ModulePtr& m)
}
bool
+Slice::Gen::StreamVisitor::visitClassDefStart(const ClassDefPtr& c)
+{
+ if(!c->isLocal())
+ {
+ writeStreamHelpers(H, c, c->dataMembers(), c->hasBaseDataMembers(), true, false);
+ }
+ return false;
+}
+
+bool
Slice::Gen::StreamVisitor::visitExceptionStart(const ExceptionPtr& p)
{
if(!p->isLocal())
@@ -5386,6 +4622,8 @@ Slice::Gen::StreamVisitor::visitExceptionStart(const ExceptionPtr& p)
H << sb;
H << nl << "static const StreamHelperCategory helper = StreamHelperCategoryUserException;";
H << eb << ";" << nl;
+
+ writeStreamHelpers(H, p, p->dataMembers(), p->hasBaseDataMembers(), true, false);
}
return false;
}
@@ -5424,53 +4662,7 @@ Slice::Gen::StreamVisitor::visitStructStart(const StructPtr& p)
}
H << eb << ";" << nl;
- DataMemberList dataMembers = p->dataMembers();
-
- string holder = classMetaData ? "v->" : "v.";
-
- H << nl << "template<class S>";
- H << nl << "struct StreamWriter< " << fullStructName << ", S>";
- H << sb;
- H << nl << "static void write(S* __os, const " << fullStructName << "& v)";
- H << sb;
- for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
- {
- writeMarshalUnmarshalDataMemberInHolder(H, holder, *q, true);
- }
- H << eb;
- H << eb << ";" << nl;
-
- H << nl << "template<class S>";
- H << nl << "struct StreamReader< " << fullStructName << ", S>";
- H << sb;
- H << nl << "static void read(S* __is, " << fullStructName << "& v)";
- H << sb;
- for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
- {
- writeMarshalUnmarshalDataMemberInHolder(H, holder, *q, false);
- }
- H << eb;
- H << eb << ";" << nl;
-
- if(!_dllExport.empty())
- {
- //
- // We tell "importers" that the implementation exports these instantiations
- //
- H << nl << "#if defined(ICE_HAS_DECLSPEC_IMPORT_EXPORT) && !defined(";
- H << _dllExport.substr(0, _dllExport.size() - 1) + "_EXPORTS) && !defined(ICE_STATIC_LIBS)";
- H << nl << "template struct " << _dllExport << "StreamWriter< " << fullStructName << ", ::IceInternal::BasicStream>;";
- H << nl << "template struct " << _dllExport << "StreamReader< " << fullStructName << ", ::IceInternal::BasicStream>;";
- H << nl << "#endif" << nl;
-
- //
- // The instantations:
- //
- C << nl << "#if defined(ICE_HAS_DECLSPEC_IMPORT_EXPORT) && !defined(ICE_STATIC_LIBS)";
- C << nl << "template struct " << _dllExport << "StreamWriter< " << fullStructName << ", ::IceInternal::BasicStream>;";
- C << nl << "template struct " << _dllExport << "StreamReader< " << fullStructName << ", ::IceInternal::BasicStream>;";
- C << nl << "#endif";
- }
+ writeStreamHelpers(H, p, p->dataMembers(), false, true, false);
}
return false;
}
@@ -5507,6 +4699,7 @@ Slice::Gen::MetaDataVisitor::visitUnitStart(const UnitPtr& p)
//
// Validate global metadata in the top-level file and all included files.
+ // Note that these metadata can only be cpp:, never cpp98: or cpp11:
//
StringList files = p->allFiles();
@@ -5698,13 +4891,36 @@ void
Slice::Gen::MetaDataVisitor::validate(const SyntaxTreeBasePtr& cont, const StringList& metaData,
const string& file, const string& line, bool /*inParam*/)
{
- static const string prefix = "cpp:";
+ static const string cppPrefix = "cpp:";
+ static const string cpp11Prefix = "cpp11:";
+ static const string cpp98Prefix = "cpp98:";
+
for(StringList::const_iterator p = metaData.begin(); p != metaData.end(); ++p)
{
string s = *p;
+
if(_history.count(s) == 0)
{
- if(s.find(prefix) == 0)
+ string prefix;
+ bool cpp98 = false;
+ bool cpp11 = false;
+
+ if(s.find(cppPrefix) == 0)
+ {
+ prefix = cppPrefix;
+ }
+ else if(s.find(cpp98Prefix) == 0)
+ {
+ prefix = cpp98Prefix;
+ cpp98 = true;
+ }
+ else if(s.find(cpp11Prefix) == 0)
+ {
+ prefix = cpp11Prefix;
+ cpp11 = true;
+ }
+
+ if(!prefix.empty())
{
string ss = s.substr(prefix.size());
if(ss == "type:wstring" || ss == "type:string")
@@ -5737,18 +4953,46 @@ Slice::Gen::MetaDataVisitor::validate(const SyntaxTreeBasePtr& cont, const Strin
{
continue;
}
- if(StructPtr::dynamicCast(cont) && (ss == "class" || ss == "comparable"))
+ if(!cpp11 && StructPtr::dynamicCast(cont) && (ss == "class" || ss == "comparable"))
{
continue;
}
- if(ClassDefPtr::dynamicCast(cont) && ss == "virtual")
+
{
- continue;
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(cont);
+ if(cl && ((!cpp11 && ss == "virtual") ||
+ (cl->isLocal() && ss.find("type:") == 0) ||
+ (!cpp11 && cl->isLocal() && ss == "comparable")))
+ {
+ continue;
+ }
}
if(ExceptionPtr::dynamicCast(cont) && ss == "ice_print")
{
continue;
}
+ if(!cpp98 && EnumPtr::dynamicCast(cont) && ss == "unscoped")
+ {
+ continue;
+ }
+
+ {
+ ClassDeclPtr cl = ClassDeclPtr::dynamicCast(cont);
+ if(cl && cl->isLocal() && ss.find("type:") == 0)
+ {
+ continue;
+ }
+ }
+ emitWarning(file, line, "ignoring invalid metadata `" + s + "'");
+ }
+
+ if(s.find("delegate") == 0)
+ {
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(cont);
+ if(cl && cl->isDelegate())
+ {
+ continue;
+ }
emitWarning(file, line, "ignoring invalid metadata `" + s + "'");
}
_history.insert(s);
@@ -5756,6 +5000,249 @@ Slice::Gen::MetaDataVisitor::validate(const SyntaxTreeBasePtr& cont, const Strin
}
}
+
+void
+Slice::Gen::normalizeMetaData(const UnitPtr& u, bool cpp11)
+{
+ NormalizeMetaDataVisitor visitor(cpp11);
+ u->visit(&visitor, false);
+}
+
+Slice::Gen::NormalizeMetaDataVisitor::NormalizeMetaDataVisitor(bool cpp11) :
+ _cpp11(cpp11)
+{
+}
+
+bool
+Slice::Gen::NormalizeMetaDataVisitor::visitUnitStart(const UnitPtr& p)
+{
+ return true;
+}
+
+bool
+Slice::Gen::NormalizeMetaDataVisitor::visitModuleStart(const ModulePtr& p)
+{
+ p->setMetaData(normalize(p->getMetaData()));
+ return true;
+}
+
+void
+Slice::Gen::NormalizeMetaDataVisitor::visitModuleEnd(const ModulePtr&)
+{
+}
+
+void
+Slice::Gen::NormalizeMetaDataVisitor::visitClassDecl(const ClassDeclPtr& p)
+{
+ p->setMetaData(normalize(p->getMetaData()));
+}
+
+bool
+Slice::Gen::NormalizeMetaDataVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ p->setMetaData(normalize(p->getMetaData()));
+ return true;
+}
+
+void
+Slice::Gen::NormalizeMetaDataVisitor::visitClassDefEnd(const ClassDefPtr&)
+{
+}
+
+bool
+Slice::Gen::NormalizeMetaDataVisitor::visitExceptionStart(const ExceptionPtr& p)
+{
+ p->setMetaData(normalize(p->getMetaData()));
+ return true;
+}
+
+void
+Slice::Gen::NormalizeMetaDataVisitor::visitExceptionEnd(const ExceptionPtr&)
+{
+}
+
+bool
+Slice::Gen::NormalizeMetaDataVisitor::visitStructStart(const StructPtr& p)
+{
+ p->setMetaData(normalize(p->getMetaData()));
+ return true;
+}
+
+void
+Slice::Gen::NormalizeMetaDataVisitor::visitStructEnd(const StructPtr&)
+{
+}
+
+void
+Slice::Gen::NormalizeMetaDataVisitor::visitOperation(const OperationPtr& p)
+{
+ p->setMetaData(normalize(p->getMetaData()));
+
+ ParamDeclList params = p->parameters();
+ for(ParamDeclList::iterator q = params.begin(); q != params.end(); ++q)
+ {
+ (*q)->setMetaData(normalize((*q)->getMetaData()));
+ }
+}
+
+void
+Slice::Gen::NormalizeMetaDataVisitor::visitDataMember(const DataMemberPtr& p)
+{
+ p->setMetaData(normalize(p->getMetaData()));
+}
+
+void
+Slice::Gen::NormalizeMetaDataVisitor::visitSequence(const SequencePtr& p)
+{
+ p->setMetaData(normalize(p->getMetaData()));
+}
+
+void
+Slice::Gen::NormalizeMetaDataVisitor::visitDictionary(const DictionaryPtr& p)
+{
+ p->setMetaData(normalize(p->getMetaData()));
+}
+
+void
+Slice::Gen::NormalizeMetaDataVisitor::visitEnum(const EnumPtr& p)
+{
+ p->setMetaData(normalize(p->getMetaData()));
+}
+
+void
+Slice::Gen::NormalizeMetaDataVisitor::visitConst(const ConstPtr& p)
+{
+ p->setMetaData(normalize(p->getMetaData()));
+}
+
+
+StringList
+Slice::Gen::NormalizeMetaDataVisitor::normalize(const StringList& metaData)
+{
+ //
+ // if _cpp11: transform "cpp:" into "cpp-all:" and "cpp"
+ // + transform "cpp11:" into "cpp:" in front
+ //
+ // if !_cpp11: remove "cpp:", transform "cpp-all:" into "cpp"
+ // + transform "cpp98:" into "cpp:" in front
+
+ //
+ // Note: global metadata like header-ext exists only in cpp:
+ // form and are not processed at all
+ //
+
+ StringList result;
+
+ static const string cppPrefixTable[] =
+ {
+ "array",
+ "class",
+ "comparable",
+ "const",
+ "ice_print",
+ "range",
+ "type:",
+ "unscoped",
+ "view-type:",
+ "virtual",
+ ""
+ };
+
+ static const string cppPrefix = "cpp:";
+ static const string cppAllPrefix = "cpp-all:";
+
+ //
+ // First look for the higher priority cpp98/cpp11, that go to the
+ // front of result
+ //
+
+ static const string cpp11Prefix = "cpp11:";
+ static const string cpp98Prefix = "cpp98:";
+
+ const string altCppPrefix = _cpp11 ? cpp11Prefix : cpp98Prefix;
+
+ for(StringList::const_iterator p = metaData.begin(); p != metaData.end(); ++p)
+ {
+ string s = *p;
+
+ unsigned int i = 0;
+ bool found = false;
+ while(!found)
+ {
+ string m = cppPrefixTable[i++];
+ if(m.empty())
+ {
+ break;
+ }
+ if(s.find(altCppPrefix + m) == 0)
+ {
+ found = true;
+ }
+ }
+
+ if(found)
+ {
+ s.replace(0, altCppPrefix.length(), cppPrefix);
+ result.push_back(s);
+ }
+ }
+
+ //
+ // Then look for the lower-priority "cpp:" / "cpp-all:", pushed back later
+ //
+
+ const string prefix = _cpp11 ? cppPrefix : cppAllPrefix;
+
+ for(StringList::const_iterator p = metaData.begin(); p != metaData.end(); ++p)
+ {
+ string s = *p;
+
+ unsigned int i = 0;
+ bool foundPrefix = false;
+ bool foundOld = false;
+ while(!foundPrefix && !foundOld)
+ {
+ string m = cppPrefixTable[i++];
+ if(m.empty())
+ {
+ break; // while
+ }
+ if(s.find(prefix + m) == 0)
+ {
+ foundPrefix = true;
+ }
+ else if(!_cpp11 && s.find(cppPrefix + m) == 0)
+ {
+ //
+ // We want to filter-out "cpp:" when !_cpp11
+ //
+ foundOld = true;
+ }
+ }
+
+ if(foundPrefix)
+ {
+ if(_cpp11)
+ {
+ result.push_back(s);
+ s.replace(0, prefix.length(), cppAllPrefix);
+ result.push_back(s);
+ }
+ else
+ {
+ s.replace(0, prefix.length(), cppPrefix);
+ result.push_back(s);
+ }
+ }
+ else if(_cpp11 || !foundOld)
+ {
+ result.push_back(s);
+ }
+ }
+
+ return result;
+}
+
int
Slice::Gen::setUseWstring(ContainedPtr p, list<int>& hist, int use)
{
@@ -5794,3 +5281,2863 @@ Slice::Gen::getHeaderExt(const string& file, const UnitPtr& unit)
}
return ext;
}
+
+// C++11 visitors
+Slice::Gen::Cpp11DeclVisitor::Cpp11DeclVisitor(Output& h, Output& c, const string& dllExport) :
+ H(h), C(c), _dllExport(dllExport)
+{
+}
+
+bool
+Slice::Gen::Cpp11DeclVisitor::visitUnitStart(const UnitPtr& p)
+{
+ if(!p->hasClassDecls() && !p->hasNonLocalExceptions())
+ {
+ return false;
+ }
+ C << sp << nl << "namespace" << nl << "{";
+ return true;
+}
+
+void
+Slice::Gen::Cpp11DeclVisitor::visitUnitEnd(const UnitPtr& p)
+{
+ C << sp << nl << "}";
+}
+
+bool
+Slice::Gen::Cpp11DeclVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(p->hasClassDecls())
+ {
+ H << sp << nl << "namespace " << fixKwd(p->name()) << nl << '{' << sp;
+ }
+ return true;
+}
+
+void
+Slice::Gen::Cpp11DeclVisitor::visitModuleEnd(const ModulePtr& p)
+{
+ if(p->hasClassDecls())
+ {
+ H << sp << nl << '}';
+ }
+}
+
+void
+Slice::Gen::Cpp11DeclVisitor::visitClassDecl(const ClassDeclPtr& p)
+{
+ ClassDefPtr def = p->definition();
+ if(def && def->isDelegate())
+ {
+ return;
+ }
+
+ H << nl << "class " << fixKwd(p->name()) << ';';
+ if(p->isInterface() || (def && !def->allOperations().empty()))
+ {
+ H << nl << "class " << p->name() << "Prx;";
+ }
+}
+
+bool
+Slice::Gen::Cpp11DeclVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ if(p->isLocal())
+ {
+ return false;
+ }
+
+ if(!p->isInterface())
+ {
+ C << sp;
+
+ C << nl << "const ::IceInternal::DefaultValueFactoryInit<" << fixKwd(p->scoped()) << "> ";
+ C << p->flattenedScope() + p->name() + "_init" << "(\"" << p->scoped() << "\");";
+
+ if(p->compactId() >= 0)
+ {
+ string n = p->flattenedScope() + p->name() + "_compactIdInit ";
+ C << "const ::IceInternal::CompactIdInit " << n << "(\"" << p->scoped() << "\", " << p->compactId() << ");";
+ }
+ }
+
+ OperationList allOps = p->allOperations();
+ if(p->isInterface() || !allOps.empty())
+ {
+ C << sp;
+
+ ClassList allBases = p->allBases();
+ StringList ids;
+ transform(allBases.begin(), allBases.end(), back_inserter(ids), ::IceUtil::constMemFun(&Contained::scoped));
+ StringList other;
+ other.push_back(p->scoped());
+ other.push_back("::Ice::Object");
+ other.sort();
+ ids.merge(other);
+ ids.unique();
+
+ C << nl << "const ::std::string " << p->flattenedScope() << p->name() << "_ids[" << ids.size() << "] =";
+ C << sb;
+ for(StringList::const_iterator r = ids.begin(); r != ids.end();)
+ {
+ C << nl << '"' << *r << '"';
+ if(++r != ids.end())
+ {
+ C << ',';
+ }
+ }
+ C << eb << ';';
+
+ StringList allOpNames;
+ transform(allOps.begin(), allOps.end(), back_inserter(allOpNames), ::IceUtil::constMemFun(&Contained::name));
+ allOpNames.push_back("ice_id");
+ allOpNames.push_back("ice_ids");
+ allOpNames.push_back("ice_isA");
+ allOpNames.push_back("ice_ping");
+ allOpNames.sort();
+ allOpNames.unique();
+
+ C << nl << "const ::std::string " << p->flattenedScope() << p->name() << "_ops[] =";
+ C << sb;
+ for(StringList::const_iterator q = allOpNames.begin(); q != allOpNames.end();)
+ {
+ C << nl << '"' << *q << '"';
+ if(++q != allOpNames.end())
+ {
+ C << ',';
+ }
+ }
+ C << eb << ';';
+ }
+
+ return true;
+}
+
+bool
+Slice::Gen::Cpp11DeclVisitor::visitExceptionStart(const ExceptionPtr& p)
+{
+ if(p->isLocal())
+ {
+ return false;
+ }
+
+ C << sp;
+ C << nl << "const ::IceInternal::DefaultUserExceptionFactoryInit<" << fixKwd(p->scoped()) << "> ";
+ C << p->flattenedScope() + p->name() + "_init" << "(\"" << p->scoped() << "\");";
+ return false;
+}
+
+void
+Slice::Gen::Cpp11DeclVisitor::visitOperation(const OperationPtr& p)
+{
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(p->container());
+ if(cl && !cl->isLocal())
+ {
+ string flatName = p->flattenedScope() + p->name() + "_name";
+ C << nl << "const ::std::string " << flatName << " = \"" << p->name() << "\";";
+ }
+}
+
+Slice::Gen::Cpp11TypesVisitor::Cpp11TypesVisitor(Output& h, Output& c, const string& dllExport) :
+ H(h), C(c), _dllExport(dllExport), _dllClassExport(toDllClassExport(dllExport)),
+ _dllMemberExport(toDllMemberExport(dllExport)), _doneStaticSymbol(false), _useWstring(false)
+{
+}
+
+bool
+Slice::Gen::Cpp11TypesVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!p->hasOtherConstructedOrExceptions())
+ {
+ return false;
+ }
+
+ _useWstring = setUseWstring(p, _useWstringHist, _useWstring);
+ H << sp << nl << "namespace " << fixKwd(p->name()) << nl << '{';
+ return true;
+}
+
+void
+Slice::Gen::Cpp11TypesVisitor::visitModuleEnd(const ModulePtr& p)
+{
+ if(p->hasStructs())
+ {
+ H << sp << nl << "using Ice::operator<;";
+ H << nl << "using Ice::operator<=;";
+ H << nl << "using Ice::operator>;";
+ H << nl << "using Ice::operator>=;";
+ H << nl << "using Ice::operator==;";
+ H << nl << "using Ice::operator!=;";
+ }
+ H << sp << nl << '}';
+ _useWstring = resetUseWstring(_useWstringHist);
+}
+
+bool
+Slice::Gen::Cpp11TypesVisitor::visitClassDefStart(const ClassDefPtr&)
+{
+ return false;
+}
+
+bool
+Slice::Gen::Cpp11TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
+{
+ _useWstring = setUseWstring(p, _useWstringHist, _useWstring);
+
+ string name = fixKwd(p->name());
+ string scoped = fixKwd(p->scoped());
+ ExceptionPtr base = p->base();
+ DataMemberList dataMembers = p->dataMembers();
+ DataMemberList allDataMembers = p->allDataMembers();
+ DataMemberList baseDataMembers;
+
+ vector<string> params;
+ vector<string> allTypes;
+ vector<string> allParamDecls;
+ vector<string> baseParams;
+
+ for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ params.push_back(fixKwd((*q)->name()));
+ }
+
+ for(DataMemberList::const_iterator q = allDataMembers.begin(); q != allDataMembers.end(); ++q)
+ {
+ string typeName = inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(),
+ _useWstring | TypeContextCpp11);
+ allTypes.push_back(typeName);
+ allParamDecls.push_back(typeName + " " + fixKwd("__ice_" + (*q)->name()));
+ }
+
+ if(base)
+ {
+ baseDataMembers = base->allDataMembers();
+ for(DataMemberList::const_iterator q = baseDataMembers.begin(); q != baseDataMembers.end(); ++q)
+ {
+ baseParams.push_back(fixKwd("__ice_" + (*q)->name()));
+ }
+ }
+
+ string helperClass = p->isLocal() ? "Ice::LocalExceptionHelper" : "Ice::UserExceptionHelper";
+ string baseClass = base ? fixKwd(base->scoped()) : (p->isLocal() ? "::Ice::LocalException" : "::Ice::UserException");
+ string templateParameters = name + ", " + baseClass;
+
+ H << sp << nl;
+ H << "class " << _dllClassExport << name << " : public ::" << helperClass << "<" << templateParameters << ">";
+ H << sb;
+
+ H.dec();
+ H << nl << "public:";
+ H.inc();
+
+ // Out of line dtor to avoid weak vtable
+ H << sp << nl << _dllMemberExport << "virtual ~" << name << "();";
+ C << sp;
+ C << nl << scoped.substr(2) << "::~" << name << "()";
+ C << sb;
+ C << eb;
+
+ if(p->isLocal())
+ {
+ H << sp << nl << name << "(const char* __ice_file, int __ice_line) : ";
+ H << "::Ice::LocalExceptionHelper" << "<" << templateParameters << ">";
+ H << "(__ice_file, __ice_line)";
+ H << sb;
+ H << eb;
+ }
+ else
+ {
+ H << sp << nl << name << "() = default;";
+ }
+
+ if(!allDataMembers.empty())
+ {
+ H << sp << nl << name << "(";
+ if(p->isLocal())
+ {
+ H << "const char* __ice_file, int __ice_line";
+ if(!allParamDecls.empty())
+ {
+ H << ", ";
+ }
+ }
+
+ for(vector<string>::const_iterator q = allParamDecls.begin(); q != allParamDecls.end(); ++q)
+ {
+ if(q != allParamDecls.begin())
+ {
+ H << ", ";
+ }
+ H << (*q);
+ }
+ H << ") :";
+ H.inc();
+ if(base && (p->isLocal() || !baseDataMembers.empty()))
+ {
+ H << nl << "::" << helperClass << "<" << templateParameters << ">" << "(";
+ if(p->isLocal())
+ {
+ H << "__ice_file, __ice_line";
+ if(!baseDataMembers.empty())
+ {
+ H << ", ";
+ }
+ }
+
+ for(DataMemberList::const_iterator q = baseDataMembers.begin(); q != baseDataMembers.end(); ++q)
+ {
+ if(q != baseDataMembers.begin())
+ {
+ H << ", ";
+ }
+ if(isMovable((*q)->type()))
+ {
+ H << "::std::move(" << fixKwd("__ice_" + (*q)->name()) << ")";
+ }
+ else
+ {
+ H << fixKwd("__ice_" + (*q)->name());
+ }
+ }
+
+ H << ")";
+ if(!dataMembers.empty())
+ {
+ H << ",";
+ }
+ }
+ else if(p->isLocal())
+ {
+ H << " ::Ice::LocalExceptionHelper" << "<" << templateParameters << ">";
+ H << "(__ice_file, __ice_line)";
+ if(!dataMembers.empty())
+ {
+ H << ",";
+ }
+ }
+
+ for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ if(q != dataMembers.begin())
+ {
+ H << ", ";
+ }
+ if(isMovable((*q)->type()))
+ {
+ H << nl << fixKwd((*q)->name()) << "(::std::move(" << fixKwd("__ice_" + (*q)->name()) << "))";
+ }
+ else
+ {
+ H << nl << fixKwd((*q)->name()) << "(" << fixKwd("__ice_" + (*q)->name()) << ")";
+ }
+ }
+
+ H.dec();
+ H << sb;
+ H << eb;
+ }
+
+ writeIceTuple(H, p->allDataMembers(), _useWstring);
+
+ H << sp;
+ H << nl << _dllMemberExport << "static const ::std::string& ice_staticId();";
+
+
+ C << sp << nl << "const ::std::string&" << nl << scoped.substr(2) << "::ice_staticId()";
+ C << sb;
+ //
+ // Use local static so that ice_staticId() is usable during static construction.
+ //
+ C << nl << "static const ::std::string typeId = \"" << p->scoped() << "\";";
+ C << nl << "return typeId;";
+ C << eb;
+
+ StringList metaData = p->getMetaData();
+ if(find(metaData.begin(), metaData.end(), "cpp:ice_print") != metaData.end())
+ {
+ H << nl << _dllMemberExport << "virtual void ice_print(::std::ostream&) const override;";
+ }
+
+ if(!p->isLocal() && p->usesClasses(false))
+ {
+ if(!base || (base && !base->usesClasses(false)))
+ {
+ H << sp << nl << _dllMemberExport << "virtual bool __usesClasses() const override;";
+
+ C << sp << nl << "bool";
+ C << nl << scoped.substr(2) << "::__usesClasses() const";
+ C << sb;
+ C << nl << "return true;";
+ C << eb;
+ }
+ }
+
+ if(!dataMembers.empty())
+ {
+ H << sp;
+ }
+ return true;
+}
+
+void
+Slice::Gen::Cpp11TypesVisitor::visitExceptionEnd(const ExceptionPtr& p)
+{
+ string name = fixKwd(p->name());
+ string scope = fixKwd(p->scope());
+ string scoped = fixKwd(p->scoped());
+ string factoryName;
+
+ if(!p->isLocal())
+ {
+ ExceptionPtr base = p->base();
+ bool basePreserved = p->inheritsMetaData("preserve-slice");
+ bool preserved = p->hasMetaData("preserve-slice");
+
+ if(preserved && !basePreserved)
+ {
+ H << sp << nl << _dllMemberExport << "virtual void __write(::Ice::OutputStream*) const override;";
+ H << nl << _dllMemberExport << "virtual void __read(::Ice::InputStream*) override;";
+
+ H << sp << nl << "::std::shared_ptr<::Ice::SlicedData> __slicedData;";
+
+ C << sp << nl << "void" << nl << scoped.substr(2) << "::__write(::Ice::OutputStream* __os) const";
+ C << sb;
+ C << nl << "__os->startException(__slicedData);";
+ C << nl << "__writeImpl(__os);";
+ C << nl << "__os->endException();";
+ C << eb;
+
+ C << sp << nl << "void" << nl << scoped.substr(2) << "::__read(::Ice::InputStream* __is)";
+ C << sb;
+ C << nl << "__is->startException();";
+ C << nl << "__readImpl(__is);";
+ C << nl << "__slicedData = __is->endException(true);";
+ C << eb;
+ }
+ }
+ H << eb << ';';
+
+ if(!p->isLocal())
+ {
+ //
+ // We need an instance here to trigger initialization if the implementation is in a shared libarry.
+ // But we do this only once per source file, because a single instance is sufficient to initialize
+ // all of the globals in a shared library.
+ //
+ if(!_doneStaticSymbol)
+ {
+ _doneStaticSymbol = true;
+ H << sp << nl << "static " << name << " __" << p->name() << "_init;";
+ }
+ }
+
+ _useWstring = resetUseWstring(_useWstringHist);
+}
+
+bool
+Slice::Gen::Cpp11TypesVisitor::visitStructStart(const StructPtr& p)
+{
+ _useWstring = setUseWstring(p, _useWstringHist, _useWstring);
+
+ H << sp << nl << "struct " << fixKwd(p->name());
+ H << sb;
+
+ return true;
+}
+
+void
+Slice::Gen::Cpp11TypesVisitor::visitStructEnd(const StructPtr& p)
+{
+ writeIceTuple(H, p->dataMembers(), _useWstring);
+ H << eb << ';';
+ _useWstring = resetUseWstring(_useWstringHist);
+}
+
+void
+Slice::Gen::Cpp11TypesVisitor::visitDataMember(const DataMemberPtr& p)
+{
+ string name = fixKwd(p->name());
+ H << nl << typeToString(p->type(), p->optional(), p->getMetaData(), _useWstring | TypeContextCpp11)
+ << ' ' << name;
+
+ string defaultValue = p->defaultValue();
+ if(!defaultValue.empty())
+ {
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(p->type());
+ if(p->optional() && builtin->kind() == Builtin::KindString)
+ {
+ //
+ // = "<string literal>" doesn't work for optional<std::string>
+ //
+ H << '{';
+ writeConstantValue(H, p->type(), p->defaultValueType(), defaultValue, _useWstring, p->getMetaData(), true);
+ H << '}';
+ }
+ else
+ {
+ H << " = ";
+ writeConstantValue(H, p->type(), p->defaultValueType(), defaultValue, _useWstring, p->getMetaData(), true);
+ }
+ }
+
+ H << ';';
+}
+
+void
+Slice::Gen::Cpp11TypesVisitor::visitSequence(const SequencePtr& p)
+{
+ string name = fixKwd(p->name());
+ TypePtr type = p->type();
+ int typeCtx = p->isLocal() ? (_useWstring | TypeContextLocal) : _useWstring;
+ string s = typeToString(type, p->typeMetaData(), typeCtx | TypeContextCpp11);
+ StringList metaData = p->getMetaData();
+
+ string seqType = findMetaData(metaData, _useWstring);
+ H << sp;
+
+ if(!seqType.empty())
+ {
+ H << nl << "using " << name << " = " << seqType << ';';
+ }
+ else
+ {
+ H << nl << "using " << name << " = ::std::vector<" << s << ">;";
+ }
+}
+
+void
+Slice::Gen::Cpp11TypesVisitor::visitDictionary(const DictionaryPtr& p)
+{
+ string name = fixKwd(p->name());
+ string dictType = findMetaData(p->getMetaData());
+ int typeCtx = p->isLocal() ? (_useWstring | TypeContextLocal) : _useWstring;
+ if(dictType.empty())
+ {
+ //
+ // A default std::map dictionary
+ //
+ TypePtr keyType = p->keyType();
+ TypePtr valueType = p->valueType();
+ string ks = typeToString(keyType, p->keyMetaData(), typeCtx | TypeContextCpp11);
+ string vs = typeToString(valueType, p->valueMetaData(), typeCtx | TypeContextCpp11);
+
+ H << sp << nl << "using " << name << " = ::std::map<" << ks << ", " << vs << ">;";
+ }
+ else
+ {
+ //
+ // A custom dictionary
+ //
+ H << sp << nl << "using " << name << " = " << dictType << ';';
+ }
+}
+
+Slice::Gen::Cpp11ProxyVisitor::Cpp11ProxyVisitor(Output& h, Output& c, const string& dllExport) :
+ H(h), C(c), _dllClassExport(toDllClassExport(dllExport)), _dllMemberExport(toDllMemberExport(dllExport)),
+ _useWstring(false)
+{
+}
+
+bool
+Slice::Gen::Cpp11ProxyVisitor::visitUnitStart(const UnitPtr& p)
+{
+ return true;
+}
+
+void
+Slice::Gen::Cpp11ProxyVisitor::visitUnitEnd(const UnitPtr&)
+{
+}
+
+bool
+Slice::Gen::Cpp11ProxyVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!p->hasNonLocalClassDefs())
+ {
+ return false;
+ }
+
+ _useWstring = setUseWstring(p, _useWstringHist, _useWstring);
+
+ H << sp << nl << "namespace " << fixKwd(p->name()) << nl << '{';
+ return true;
+}
+
+void
+Slice::Gen::Cpp11ProxyVisitor::visitModuleEnd(const ModulePtr&)
+{
+ H << sp << nl << '}';
+
+ _useWstring = resetUseWstring(_useWstringHist);
+}
+
+bool
+Slice::Gen::Cpp11ProxyVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ if(p->isLocal() || (!p->isInterface() && p->allOperations().empty()))
+ {
+ return false;
+ }
+
+ _useWstring = setUseWstring(p, _useWstringHist, _useWstring);
+
+ string name = fixKwd(p->name());
+ string scope = fixKwd(p->scope());
+ string scoped = fixKwd(p->scoped());
+ ClassList bases = p->bases();
+
+ ClassDefPtr base;
+ if(!bases.empty() && !bases.front()->isInterface())
+ {
+ base = bases.front();
+ }
+
+ H << sp << nl << "class " << _dllClassExport << p->name() << "Prx : public virtual ::Ice::Proxy<"
+ << fixKwd(p->name() + "Prx") << ", ";
+ if(bases.empty() || (base && base->allOperations().empty()))
+ {
+ H << "::Ice::ObjectPrx";
+ }
+ else
+ {
+ ClassList::const_iterator q = bases.begin();
+ while(q != bases.end())
+ {
+ H << fixKwd((*q)->scoped() + "Prx");
+ if(++q != bases.end())
+ {
+ H << ", ";
+ }
+ }
+ }
+ H << ">";
+
+ H << sb;
+ H.dec();
+ H << nl << "public:";
+ H.inc();
+ return true;
+}
+
+void
+Slice::Gen::Cpp11ProxyVisitor::visitClassDefEnd(const ClassDefPtr& p)
+{
+ string prx = fixKwd(p->name() + "Prx");
+
+ H << sp;
+ H << nl << _dllMemberExport << "static const ::std::string& ice_staticId();";
+
+ H.dec();
+ H << sp << nl << "protected: ";
+ H.inc();
+ H << sp << nl << prx << "() = default;";
+ H << nl << "friend ::std::shared_ptr<" << prx << "> IceInternal::createProxy<" << prx << ">();";
+ H << sp;
+ H << nl << _dllMemberExport << "virtual ::std::shared_ptr<::Ice::ObjectPrx> __newInstance() const override;";
+ H << eb << ';';
+
+ string suffix = p->isInterface() ? "" : "Disp";
+ string scoped = fixKwd(p->scoped() + "Prx");
+
+ C << sp;
+ C << nl << "::std::shared_ptr<::Ice::ObjectPrx>";
+ C << nl << scoped.substr(2) << "::__newInstance() const";
+ C << sb;
+ C << nl << "return ::IceInternal::createProxy<" << prx << ">();";
+ C << eb;
+ C << sp;
+ C << nl << "const ::std::string&" << nl << scoped.substr(2) << "::ice_staticId()";
+ C << sb;
+ C << nl << "return "<< fixKwd(p->scope() + p->name() + suffix).substr(2) << "::ice_staticId();";
+ C << eb;
+
+ _useWstring = resetUseWstring(_useWstringHist);
+}
+
+void
+Slice::Gen::Cpp11ProxyVisitor::visitOperation(const OperationPtr& p)
+{
+ string name = p->name();
+ string flatName = p->flattenedScope() + p->name() + "_name";
+
+ TypePtr ret = p->returnType();
+
+ bool retIsOpt = p->returnIsOptional();
+ string retS = returnTypeToString(ret, retIsOpt, p->getMetaData(), _useWstring | TypeContextCpp11);
+
+ ContainerPtr container = p->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container);
+
+ vector<string> params;
+ vector<string> paramsDecl;
+
+ vector<string> inParamsS;
+ vector<string> inParamsDecl;
+
+ vector<string> futureOutParams;
+ vector<string> lambdaOutParams;
+
+ ParamDeclList paramList = p->parameters();
+ ParamDeclList inParams;
+ ParamDeclList outParams;
+
+ string returnValueS = "returnValue";
+ bool outParamsHasOpt = false;
+
+ if(ret)
+ {
+ futureOutParams.push_back(typeToString(ret, retIsOpt, p->getMetaData(), _useWstring | TypeContextCpp11));
+
+ lambdaOutParams.push_back(
+ typeToString(ret, retIsOpt, p->getMetaData(), _useWstring | TypeContextInParam | TypeContextCpp11));
+
+ outParamsHasOpt |= p->returnIsOptional();
+ }
+
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ string paramName = fixKwd(paramPrefix + (*q)->name());
+ StringList metaData = (*q)->getMetaData();
+
+ if((*q)->isOutParam())
+ {
+ futureOutParams.push_back(typeToString((*q)->type(), (*q)->optional(), metaData,
+ _useWstring | TypeContextCpp11));
+ lambdaOutParams.push_back(typeToString((*q)->type(), (*q)->optional(), metaData,
+ _useWstring | TypeContextInParam | TypeContextCpp11));
+
+ string outputTypeString = outputTypeToString((*q)->type(), (*q)->optional(), metaData,
+ _useWstring | TypeContextCpp11);
+
+ params.push_back(outputTypeString);
+ paramsDecl.push_back(outputTypeString + ' ' + paramName);
+
+ outParamsHasOpt |= (*q)->optional();
+ outParams.push_back(*q);
+
+ if((*q)->name() == "returnValue")
+ {
+ returnValueS = "_returnValue";
+ }
+ }
+ else
+ {
+ string typeString = inputTypeToString((*q)->type(), (*q)->optional(), metaData,
+ _useWstring | TypeContextCpp11);
+
+ params.push_back(typeString);
+ paramsDecl.push_back(typeString + ' ' + paramName);
+
+ inParamsS.push_back(typeString);
+ inParamsDecl.push_back(typeString + ' ' + paramName);
+ inParams.push_back(*q);
+ }
+ }
+
+ string scoped = fixKwd(cl->scope() + cl->name() + "Prx" + "::").substr(2);
+
+ string futureT;
+ if(futureOutParams.empty())
+ {
+ futureT = "void";
+ }
+ else if(futureOutParams.size() == 1)
+ {
+ futureT = futureOutParams[0];
+ }
+ else
+ {
+ string resultScope = fixKwd(cl->scope() + cl->name());
+ futureT = resultStructName(name, resultScope);
+ }
+
+ string deprecateSymbol = getDeprecateSymbol(p, cl);
+
+ //
+ // Synchronous operation
+ //
+ H << sp << nl << deprecateSymbol << retS << ' ' << fixKwd(name) << spar << paramsDecl;
+ H << "const ::Ice::Context& __ctx = Ice::noExplicitContext" << epar;
+ H << sb;
+ H << nl;
+ if(futureOutParams.size() == 1)
+ {
+ if(ret)
+ {
+ H << "return ";
+ }
+ else
+ {
+ H << paramPrefix << (*outParams.begin())->name() << " = ";
+ }
+ }
+ else if(futureOutParams.size() > 1)
+ {
+ H << "auto __result = ";
+ }
+
+ H << "makePromiseOutgoing<" << futureT << ">";
+
+ H << spar << "true, this" << string("&" + scoped + "__" + name);
+ for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end(); ++q)
+ {
+ H << fixKwd(paramPrefix + (*q)->name());
+ }
+ H << "__ctx" << epar << ".get();";
+ if(futureOutParams.size() > 1)
+ {
+ for(ParamDeclList::const_iterator q = outParams.begin(); q != outParams.end(); ++q)
+ {
+ H << nl << paramPrefix << (*q)->name() << " = ";
+ H << condMove(isMovable((*q)->type()), "__result." + fixKwd((*q)->name())) + ";";
+ }
+ if(ret)
+ {
+ H << nl << "return " + condMove(isMovable(ret), "__result." + returnValueS) + ";";
+ }
+ }
+ H << eb;
+
+ //
+ // Promise based asynchronous operation
+ //
+ H << sp;
+ H << nl << "template<template<typename> class P = ::std::promise>";
+ H << nl << deprecateSymbol << "auto " << name << "Async" << spar << inParamsDecl;
+ H << "const ::Ice::Context& __ctx = Ice::noExplicitContext" << epar;
+ H.inc();
+ H << nl << "-> decltype(::std::declval<P<" << futureT << ">>().get_future())";
+ H.dec();
+ H << sb;
+
+ H << nl << "return makePromiseOutgoing<" << futureT << ", P>" << spar;
+
+ H << "false, this" << string("&" + scoped + "__" + name);
+ for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end(); ++q)
+ {
+ H << fixKwd(paramPrefix + (*q)->name());
+ }
+ H << "__ctx" << epar << ";";
+ H << eb;
+
+
+ //
+ // Lambda based asynchronous operation
+ //
+ bool lambdaCustomOut = (lambdaOutParams != futureOutParams);
+
+ H << sp;
+ H << nl;
+ if(lambdaCustomOut)
+ {
+ H << _dllMemberExport;
+ }
+ H << "::std::function<void()>";
+ H << nl << name << "Async(";
+ H.useCurrentPosAsIndent();
+ if(!inParamsDecl.empty())
+ {
+ if(lambdaCustomOut)
+ {
+ for(vector<string>::const_iterator q = inParamsS.begin(); q != inParamsS.end(); ++q)
+ {
+ H << *q << ", ";
+ }
+ }
+ else
+ {
+ for(vector<string>::const_iterator q = inParamsDecl.begin(); q != inParamsDecl.end(); ++q)
+ {
+ H << *q << ", ";
+ }
+ }
+ H << nl;
+ }
+
+ H << "::std::function<void" << spar << lambdaOutParams << epar << ">"
+ + condString(!lambdaCustomOut, " __response") + ",";
+ H << nl << "::std::function<void(::std::exception_ptr)>"
+ + condString(!lambdaCustomOut, " __ex") + " = nullptr,";
+ H << nl << "::std::function<void(bool)>"
+ + condString(!lambdaCustomOut," __sent") + " = nullptr,";
+ H << nl << "const ::Ice::Context&"
+ + condString(!lambdaCustomOut, "__ctx") + " = Ice::noExplicitContext)" + condString(lambdaCustomOut, ";");
+
+ H.restoreIndent();
+ if(lambdaCustomOut)
+ {
+ //
+ // "Custom" implementation in .cpp file
+ //
+
+ C << sp;
+ C << nl << "::std::function<void()>";
+ C << nl << scoped << name << "Async(";
+ C.useCurrentPosAsIndent();
+ if(!inParamsDecl.empty())
+ {
+ for(vector<string>::const_iterator q = inParamsDecl.begin(); q != inParamsDecl.end(); ++q)
+ {
+ C << *q << ", ";
+ }
+ C << nl;
+ }
+ C << "::std::function<void " << spar << lambdaOutParams << epar << "> __response,";
+ C << nl << "::std::function<void(::std::exception_ptr)> __ex,";
+ C << nl << "::std::function<void(bool)> __sent,";
+ C << nl << "const ::Ice::Context& __ctx)";
+ C.restoreIndent();
+ C << sb;
+ if(p->returnsData())
+ {
+ C << nl << "__checkTwowayOnly(" << flatName << ");";
+ }
+
+ C << nl << "::std::function<void(::Ice::InputStream*)> __read;";
+ C << nl << "if(__response)";
+ C << sb;
+ C << nl << "__read = [__response](::Ice::InputStream* __is)";
+ C << sb;
+ C << nl << "__is->startEncapsulation();";
+ writeAllocateCode(C, outParams, p, true, _useWstring | TypeContextInParam | TypeContextCpp11);
+ writeUnmarshalCode(C, outParams, p, true, _useWstring | TypeContextInParam | TypeContextCpp11);
+
+ if(p->returnsClasses(false))
+ {
+ C << nl << "__is->readPendingValues();";
+ }
+ C << nl << "__is->endEncapsulation();";
+ C << nl << "try" << sb;
+ C << nl << "__response" << spar;
+ if(ret)
+ {
+ C << "__ret";
+ }
+ for(ParamDeclList::const_iterator q = outParams.begin(); q != outParams.end(); ++q)
+ {
+ C << fixKwd(paramPrefix + (*q)->name());
+ }
+ C << epar << ";";
+ C << eb;
+ C << nl << "catch(...)";
+ C << sb;
+ C << nl << "throw ::std::current_exception();";
+ C << eb;
+ C << eb << ";";
+ C << eb;
+ C << nl << "auto __outAsync = ::std::make_shared<::IceInternal::CustomLambdaOutgoing>(";
+ C << "shared_from_this(), __read, __ex, __sent);";
+ C << sp;
+
+ C << nl << "__outAsync->invoke(" << flatName << ", ";
+ C << operationModeToString(p->sendMode(), true) << ", " << opFormatTypeToString(p) << ", __ctx, ";
+ C.inc();
+ C << nl;
+
+ writeInParamsLambda(C, p, inParams);
+ C << "," << nl;
+ throwUserExceptionLambda(C, p->throws());
+
+ C.dec();
+ C << ");";
+ C << nl << "return [__outAsync]() { __outAsync->cancel(); };";
+ C << eb;
+ }
+ else
+ {
+ //
+ // Simple implementation directly in header file
+ //
+
+ H << sb;
+ if(futureOutParams.size() > 1)
+ {
+ H << nl << "auto __responseCb = [__response](" << futureT << "&& result)";
+ H << sb;
+ H << nl << "__response" << spar;
+
+ if(ret)
+ {
+ H << condMove(isMovable(ret), string("result.") + returnValueS);
+ }
+ for(ParamDeclList::const_iterator q = outParams.begin(); q != outParams.end(); ++q)
+ {
+ H << condMove(isMovable((*q)->type()), "result." + fixKwd((*q)->name()));
+ }
+ H << epar << ";" << eb << ";";
+ }
+
+ H << nl << "return makeLambdaOutgoing<" << futureT << ">" << spar;
+
+ H << (futureOutParams.size() > 1 ? "__responseCb" : "__response") << "__ex" << "__sent" << "this";
+ H << string("&" + scoped + "__" + name);
+ for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end(); ++q)
+ {
+ H << fixKwd(paramPrefix + (*q)->name());
+ }
+ H << "__ctx" << epar << ";";
+ H << eb;
+ }
+
+ //
+ // Private implementation
+ //
+
+ H << sp;
+ H << nl << _dllMemberExport << "void __" << name << spar;
+ H << "const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<" + futureT + ">>&";
+ H << inParamsS;
+ H << "const ::Ice::Context&";
+ H << epar << ";";
+
+ C << sp;
+ C << nl << "void" << nl << scoped << "__" << name << spar;
+ C << "const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<" + futureT + ">>& __outAsync";
+ C << inParamsDecl << "const ::Ice::Context& __ctx";
+ C << epar;
+ C << sb;
+ if(p->returnsData())
+ {
+ C << nl << "__checkTwowayOnly(" << flatName << ");";
+ }
+ C << nl << "__outAsync->invoke(" << flatName << ", ";
+ C << operationModeToString(p->sendMode(), true) << ", " << opFormatTypeToString(p) << ", __ctx, ";
+ C.inc();
+ C << nl;
+
+ writeInParamsLambda(C, p, inParams);
+ C << "," << nl;
+ throwUserExceptionLambda(C, p->throws());
+
+ if(futureOutParams.size() > 1)
+ {
+ //
+ // Generate a read method if there are more than one ret/out parameter. If there's
+ // only one, we rely on the default read method from LambdaOutgoing
+ // except if the unique ret/out is optional or is an array/range.
+ //
+ C << "," << nl << "[](::Ice::InputStream* __is)";
+ C << sb;
+ C << nl << futureT << " v;";
+ writeUnmarshalCode(C, outParams, p, false, _useWstring | TypeContextCpp11, returnValueS, "v");
+
+ if(p->returnsClasses(false))
+ {
+ C << nl << "__is->readPendingValues();";
+ }
+ C << nl << "return v;";
+ C << eb;
+ }
+ else if(outParamsHasOpt || p->returnsClasses(false))
+ {
+ //
+ // If there's only one optional ret/out parameter, we still need to generate
+ // a read method, we can't rely on the default read method which wouldn't
+ // known which tag to use.
+ //
+ C << "," << nl << "[](::Ice::InputStream* __is)";
+ C << sb;
+
+ writeAllocateCode(C, outParams, p, true, _useWstring | TypeContextCpp11);
+ writeUnmarshalCode(C, outParams, p, true, _useWstring | TypeContextCpp11);
+
+ if(p->returnsClasses(false))
+ {
+ C << nl << "__is->readPendingValues();";
+ }
+
+ if(ret)
+ {
+ C << nl << "return __ret;";
+ }
+ else
+ {
+ C << nl << "return " << fixKwd(paramPrefix + outParams.front()->name()) << ";";
+ }
+ C << eb;
+ }
+
+ C.dec();
+ C << ");" << eb;
+}
+
+void
+Slice::Gen::Cpp11TypesVisitor::visitEnum(const EnumPtr& p)
+{
+ bool unscoped = findMetaData(p->getMetaData(), TypeContextCpp11) == "%unscoped";
+ H << sp << nl << "enum ";
+ if(!unscoped)
+ {
+ H << "class ";
+ }
+ H << fixKwd(p->name());
+ if(!unscoped && p->maxValue() <= 0xFF)
+ {
+ H << " : unsigned char";
+ }
+ H << sb;
+
+ EnumeratorList enumerators = p->getEnumerators();
+ //
+ // Check if any of the enumerators were assigned an explicit value.
+ //
+ const bool explicitValue = p->explicitValue();
+ for(EnumeratorList::const_iterator en = enumerators.begin(); en != enumerators.end();)
+ {
+ H << nl << fixKwd((*en)->name());
+ //
+ // If any of the enumerators were assigned an explicit value, we emit
+ // an explicit value for *all* enumerators.
+ //
+ if(explicitValue)
+ {
+ H << " = " << int64ToString((*en)->value());
+ }
+ if(++en != enumerators.end())
+ {
+ H << ',';
+ }
+ }
+ H << eb << ';';
+}
+
+void
+Slice::Gen::Cpp11TypesVisitor::visitConst(const ConstPtr& p)
+{
+ H << sp;
+ H << nl << (isConstexprType(p->type()) ? "constexpr " : "const ")
+ << typeToString(p->type(), p->typeMetaData(), _useWstring | TypeContextCpp11) << " " << fixKwd(p->name())
+ << " = ";
+ writeConstantValue(H, p->type(), p->valueType(), p->value(), _useWstring, p->typeMetaData(), true);
+ H << ';';
+}
+
+void
+Slice::Gen::Cpp11TypesVisitor::emitUpcall(const ExceptionPtr& base, const string& call, bool isLocal)
+{
+ C << nl << (base ? fixKwd(base->scoped()) : string(isLocal ? "::Ice::LocalException" : "::Ice::UserException"))
+ << call;
+}
+
+Slice::Gen::Cpp11ObjectVisitor::Cpp11ObjectVisitor(::IceUtilInternal::Output& h,
+ ::IceUtilInternal::Output& c,
+ const std::string& dllExport) :
+ H(h),
+ C(c),
+ _dllExport(dllExport),
+ _dllClassExport(toDllClassExport(dllExport)), _dllMemberExport(toDllMemberExport(dllExport)),
+ _doneStaticSymbol(false),
+ _useWstring(false)
+{
+}
+
+void
+Slice::Gen::Cpp11ObjectVisitor::emitDataMember(const DataMemberPtr& p)
+{
+ string name = fixKwd(p->name());
+ H << nl << typeToString(p->type(), p->optional(), p->getMetaData(),
+ _useWstring | TypeContextCpp11) << ' ' << name;
+
+ string defaultValue = p->defaultValue();
+ if(!defaultValue.empty())
+ {
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(p->type());
+ if(p->optional() && builtin && builtin->kind() == Builtin::KindString)
+ {
+ //
+ // = "<string literal>" doesn't work for optional<std::string>
+ //
+ H << '{';
+ writeConstantValue(H, p->type(), p->defaultValueType(), defaultValue, _useWstring, p->getMetaData(), true);
+ H << '}';
+ }
+ else
+ {
+ H << " = ";
+ writeConstantValue(H, p->type(), p->defaultValueType(), defaultValue, _useWstring, p->getMetaData(), true);
+ }
+ }
+ H << ";";
+}
+
+void
+Slice::Gen::Cpp11InterfaceVisitor::emitUpcall(const ClassDefPtr& base, const string& call)
+{
+ C << nl << (base ? fixKwd(base->scoped()) : string("::Ice::Object")) << call;
+}
+
+void
+Slice::Gen::Cpp11ValueVisitor::emitUpcall(const ClassDefPtr& base, const string& call)
+{
+ C << nl << (base ? fixKwd(base->scoped()) : string("::Ice::Value")) << call;
+}
+
+Slice::Gen::Cpp11LocalObjectVisitor::Cpp11LocalObjectVisitor(::IceUtilInternal::Output& h,
+ ::IceUtilInternal::Output& c,
+ const std::string& dllExport) :
+ Cpp11ObjectVisitor(h, c, dllExport)
+{
+}
+
+bool
+Slice::Gen::Cpp11LocalObjectVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!p->hasLocalClassDefs())
+ {
+ return false;
+ }
+
+ _useWstring = setUseWstring(p, _useWstringHist, _useWstring);
+ string name = fixKwd(p->name());
+ H << sp << nl << "namespace " << name << nl << '{';
+ return true;
+}
+
+void
+Slice::Gen::Cpp11LocalObjectVisitor::visitModuleEnd(const ModulePtr&)
+{
+ H << sp;
+ H << nl << '}';
+ _useWstring = resetUseWstring(_useWstringHist);
+}
+
+bool
+Slice::Gen::Cpp11LocalObjectVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ if(!p->isLocal())
+ {
+ return false;
+ }
+ if(p->isDelegate())
+ {
+ return false;
+ }
+
+ string name = fixKwd(p->name());
+ string scope = fixKwd(p->scope());
+ string scoped = fixKwd(p->scoped());
+ ClassList bases = p->bases();
+ ClassDefPtr base;
+ if(!bases.empty() && !bases.front()->isInterface())
+ {
+ base = bases.front();
+ }
+ DataMemberList dataMembers = p->dataMembers();
+ DataMemberList allDataMembers = p->allDataMembers();
+
+ H << sp << nl << "class " << _dllClassExport << name;
+ H.useCurrentPosAsIndent();
+ if(!bases.empty())
+ {
+ H << " : ";
+ ClassList::const_iterator q = bases.begin();
+ bool virtualInheritance = p->isInterface();
+ while(q != bases.end())
+ {
+ if(virtualInheritance || (*q)->isInterface())
+ {
+ H << "virtual ";
+ }
+
+ H << "public " << fixKwd((*q)->scoped());
+ if(++q != bases.end())
+ {
+ H << ',' << nl;
+ }
+ }
+ }
+
+ H.restoreIndent();
+ H << sb;
+ H.dec();
+ H << nl << "public:" << sp;
+ H.inc();
+
+ //
+ // Out of line virtual dtor to avoid weak vtable
+ //
+ H << sp << nl << _dllMemberExport << "virtual ~" << name << "();";
+ C << sp << nl << scoped.substr(2) << "::~" << name << "()";
+ C << sb;
+ C << eb;
+
+ vector<string> params;
+ vector<string> allTypes;
+ vector<string> allParamDecls;
+
+ for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ params.push_back(fixKwd((*q)->name()));
+ }
+
+ for(DataMemberList::const_iterator q = allDataMembers.begin(); q != allDataMembers.end(); ++q)
+ {
+ string typeName = inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring);
+ allTypes.push_back(typeName);
+ allParamDecls.push_back(typeName + " __ice_" + (*q)->name());
+ }
+
+ if(!p->isInterface())
+ {
+ if(p->hasDefaultValues())
+ {
+ H << sp << nl << name << "() :";
+ H.inc();
+ writeDataMemberInitializers(H, dataMembers, _useWstring | TypeContextCpp11);
+ H.dec();
+ H << sb;
+ H << eb;
+ }
+ else
+ {
+ H << sp << nl << name << "() = default;";
+ }
+
+ emitOneShotConstructor(p);
+ }
+
+ if(p->hasMetaData("cpp:comparable"))
+ {
+ H << sp;
+ H << nl << "virtual bool operator==(const " << p->name() << "&) const = 0;";
+ H << nl << "virtual bool operator<(const " << p->name() << "&) const = 0;";
+ }
+ return true;
+}
+
+void
+Slice::Gen::Cpp11LocalObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
+{
+ string scoped = fixKwd(p->scoped());
+ string scope = fixKwd(p->scope());
+ ClassList bases = p->bases();
+ ClassDefPtr base;
+ if(!bases.empty() && !bases.front()->isInterface())
+ {
+ base = bases.front();
+ }
+
+ //
+ // Emit data members. Access visibility may be specified by metadata.
+ //
+ bool inProtected = false;
+ DataMemberList dataMembers = p->dataMembers();
+ bool prot = p->hasMetaData("protected");
+ bool needSp = true;
+ for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ if(prot || (*q)->hasMetaData("protected"))
+ {
+ if(!inProtected)
+ {
+ H.dec();
+ H << sp << nl << "protected:" << sp;
+ H.inc();
+ inProtected = true;
+ needSp = false;
+ }
+ }
+ else
+ {
+ if(inProtected)
+ {
+ H.dec();
+ H << sp << nl << "public:" << sp;
+ H.inc();
+ inProtected = false;
+ needSp = false;
+ }
+ }
+
+ if(needSp)
+ {
+ H << sp;
+ needSp = false;
+ }
+
+ emitDataMember(*q);
+ }
+
+ H << eb << ';';
+}
+
+bool
+Slice::Gen::Cpp11LocalObjectVisitor::visitExceptionStart(const ExceptionPtr&)
+{
+ return false;
+}
+
+bool
+Slice::Gen::Cpp11LocalObjectVisitor::visitStructStart(const StructPtr&)
+{
+ return false;
+}
+
+void
+Slice::Gen::Cpp11LocalObjectVisitor::visitOperation(const OperationPtr& p)
+{
+ string name = p->name();
+ string scoped = fixKwd(p->scoped());
+ string scope = fixKwd(p->scope());
+
+ int typeCtx = _useWstring | TypeContextLocal | TypeContextCpp11;
+ TypePtr ret = p->returnType();
+ string retS = returnTypeToString(ret, p->returnIsOptional(), p->getMetaData(),
+ typeCtx | TypeContextCpp11);
+
+ string params = "(";
+ string paramsDecl = "(";
+ string args = "(";
+
+ ContainerPtr container = p->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container);
+ string classScope = fixKwd(cl->scope());
+
+ ParamDeclList inParams;
+ ParamDeclList outParams;
+ ParamDeclList paramList = p->parameters();
+ vector< string> outDecls;
+ for(ParamDeclList::iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ string paramName = fixKwd(string(paramPrefix) + (*q)->name());
+ TypePtr type = (*q)->type();
+ bool isOutParam = (*q)->isOutParam();
+ string typeString;
+ if(isOutParam)
+ {
+ outParams.push_back(*q);
+ typeString = outputTypeToString(type, (*q)->optional(), (*q)->getMetaData(), typeCtx);
+ }
+ else
+ {
+ inParams.push_back(*q);
+ typeString = inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), typeCtx);
+ }
+
+ if(q != paramList.begin())
+ {
+ params += ", ";
+ paramsDecl += ", ";
+ args += ", ";
+ }
+
+ params += typeString;
+ paramsDecl += typeString;
+ paramsDecl += ' ';
+ paramsDecl += paramName;
+ args += paramName;
+
+ if(isOutParam)
+ {
+ outDecls.push_back(typeString);
+ }
+ }
+
+ params += ')';
+ paramsDecl += ')';
+ args += ')';
+
+ string isConst = ((p->mode() == Operation::Nonmutating) || p->hasMetaData("cpp:const")) ? " const" : "";
+
+ string deprecateSymbol = getDeprecateSymbol(p, cl);
+
+ H << sp;
+ H << nl << deprecateSymbol << "virtual " << retS << ' ' << fixKwd(name) << params << isConst << " = 0;";
+
+ if(cl->hasMetaData("async-oneway") || p->hasMetaData("async-oneway"))
+ {
+ vector<string> paramsDeclAMI;
+ vector<string> outParamsDeclAMI;
+
+ ParamDeclList paramList = p->parameters();
+ for(ParamDeclList::const_iterator r = paramList.begin(); r != paramList.end(); ++r)
+ {
+ string paramName = fixKwd((*r)->name());
+
+ StringList metaData = (*r)->getMetaData();
+ string typeString;
+ if(!(*r)->isOutParam())
+ {
+ typeString = inputTypeToString((*r)->type(), (*r)->optional(), metaData, typeCtx);
+ paramsDeclAMI.push_back(typeString + ' ' + paramName);
+ }
+ }
+
+ H << sp;
+ H << nl << "virtual ::std::function<void()>";
+ H << nl << name << "Async(";
+ H.useCurrentPosAsIndent();
+ for(vector<string>::const_iterator i = paramsDeclAMI.begin(); i != paramsDeclAMI.end(); ++i)
+ {
+ H << *i << ",";
+ }
+ if(!paramsDeclAMI.empty())
+ {
+ H << nl;
+ }
+ H << "::std::function<void(::std::exception_ptr)> exception,";
+ H << nl << "::std::function<void(bool)> sent = nullptr) = 0;";
+ H.restoreIndent();
+
+ H << sp;
+ H << nl << "template<template<typename> class P = ::std::promise>";
+ H << nl << deprecateSymbol << "auto " << name << "Async" << spar << paramsDeclAMI << epar;
+ H.inc();
+ H << nl << "-> decltype(::std::declval<P<bool>>().get_future())";
+ H.dec();
+ H << sb;
+ H << nl << "using Promise = P<bool>;";
+ H << nl << "auto __promise = ::std::make_shared<Promise>();";
+
+ H << nl << name << "Async(";
+ H.useCurrentPosAsIndent();
+ for(vector<string>::const_iterator i = paramsDeclAMI.begin(); i != paramsDeclAMI.end(); ++i)
+ {
+ H << *i << ",";
+ }
+ if(!paramsDeclAMI.empty())
+ {
+ H << nl;
+ }
+ H << "[__promise](::std::exception_ptr __ex)";
+ H << sb;
+ H << nl << "__promise->set_exception(::std::move(__ex));";
+ H << eb << ",";
+ H << nl << "[__promise](bool __b)";
+ H << sb;
+ H << nl << "__promise->set_value(__b);";
+ H << eb << ");";
+ H.restoreIndent();
+
+ H << nl << "return __promise->get_future();";
+ H << eb;
+ }
+}
+
+Slice::Gen::Cpp11InterfaceVisitor::Cpp11InterfaceVisitor(::IceUtilInternal::Output& h,
+ ::IceUtilInternal::Output& c,
+ const std::string& dllExport) :
+ Cpp11ObjectVisitor(h, c, dllExport)
+{
+}
+
+bool
+Slice::Gen::Cpp11InterfaceVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!p->hasNonLocalInterfaceDefs())
+ {
+ return false;
+ }
+
+ _useWstring = setUseWstring(p, _useWstringHist, _useWstring);
+ string name = fixKwd(p->name());
+ H << sp << nl << "namespace " << name << nl << '{';
+ return true;
+}
+
+void
+Slice::Gen::Cpp11InterfaceVisitor::visitModuleEnd(const ModulePtr&)
+{
+ H << sp;
+ H << nl << '}';
+
+ _useWstring = resetUseWstring(_useWstringHist);
+}
+
+bool
+Slice::Gen::Cpp11InterfaceVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ if(p->isLocal() || (!p->isInterface() && p->allOperations().empty()))
+ {
+ return false;
+ }
+
+ _useWstring = setUseWstring(p, _useWstringHist, _useWstring);
+
+ string suffix = p->isInterface() ? "" : "Disp";
+
+ string name = fixKwd(p->name() + suffix);
+ string scope = fixKwd(p->scope());
+ string scoped = fixKwd(p->scope() + p->name() + suffix);
+ ClassList bases = p->bases();
+ ClassDefPtr base;
+ if(!bases.empty() && !bases.front()->isInterface())
+ {
+ base = bases.front();
+ }
+
+ H << sp << nl << "class " << _dllExport << name << " : ";
+ H.useCurrentPosAsIndent();
+ if(bases.empty() || (base && base->allOperations().empty()))
+ {
+ H << "public virtual ::Ice::Object";
+ }
+ else
+ {
+ ClassList::const_iterator q = bases.begin();
+ while(q != bases.end())
+ {
+ string baseSuffix = (*q)->isInterface() ? "" : "Disp";
+ string baseScoped = fixKwd((*q)->scope() + (*q)->name() + baseSuffix);
+
+ H << "public virtual " << baseScoped;
+ if(++q != bases.end())
+ {
+ H << ',' << nl;
+ }
+ }
+ }
+
+ H.restoreIndent();
+ H << sb;
+ H.dec();
+ H << nl << "public:" << sp;
+ H.inc();
+
+ //
+ // In C++, a nested type cannot have the same name as the enclosing type
+ //
+ if(name != "ProxyType")
+ {
+ H << nl << "using ProxyType = " << p->name() << "Prx;";
+ }
+
+ vector<string> params;
+ vector<string> allTypes;
+ vector<string> allParamDecls;
+
+ ClassList allBases = p->allBases();
+ StringList ids;
+ transform(allBases.begin(), allBases.end(), back_inserter(ids), ::IceUtil::constMemFun(&Contained::scoped));
+ StringList other;
+ other.push_back(p->scoped());
+ other.push_back("::Ice::Object");
+ other.sort();
+ ids.merge(other);
+ ids.unique();
+ StringList::const_iterator scopedIter = find(ids.begin(), ids.end(), p->scoped());
+ assert(scopedIter != ids.end());
+
+ H << sp;
+ H << nl << "virtual bool ice_isA(::std::string, const ::Ice::Current& = ::Ice::noExplicitCurrent) const override;";
+ H << nl
+ << "virtual ::std::vector<::std::string> ice_ids(const ::Ice::Current& = ::Ice::noExplicitCurrent) const override;";
+ H << nl << "virtual ::std::string ice_id(const ::Ice::Current& = ::Ice::noExplicitCurrent) const override;";
+ H << sp << nl << "static const ::std::string& ice_staticId();";
+
+ string flatName = p->flattenedScope() + p->name() + "_ids";
+
+ C << sp;
+ C << nl << "bool" << nl << scoped.substr(2) << "::ice_isA(::std::string _s, const ::Ice::Current&) const";
+ C << sb;
+ C << nl << "return ::std::binary_search(" << flatName << ", " << flatName << " + " << ids.size() << ", _s);";
+ C << eb;
+
+ C << sp;
+ C << nl << "::std::vector<::std::string>" << nl << scoped.substr(2) << "::ice_ids(const ::Ice::Current&) const";
+ C << sb;
+ C << nl << "return ::std::vector<::std::string>(&" << flatName << "[0], &" << flatName << '[' << ids.size() << "]);";
+ C << eb;
+
+ C << sp;
+ C << nl << "::std::string" << nl << scoped.substr(2) << "::ice_id(const ::Ice::Current&) const";
+ C << sb;
+ C << nl << "return ice_staticId();";
+ C << eb;
+
+ C << sp;
+ C << nl << "const ::std::string&" << nl << scoped.substr(2) << "::ice_staticId()";
+ C << sb;
+ //
+ // Use local static so that ice_staticId() is usable during static construction.
+ //
+ C << nl << "static const ::std::string typeId = \"" << *scopedIter << "\";";
+ C << nl << "return typeId;";
+ C << eb;
+ return true;
+}
+
+void
+Slice::Gen::Cpp11InterfaceVisitor::visitClassDefEnd(const ClassDefPtr& p)
+{
+ string suffix = p->isInterface() ? "" : "Disp";
+ string scoped = fixKwd(p->scope() + p->name() + suffix);
+
+ string scope = fixKwd(p->scope());
+ string name = fixKwd(p->name() + suffix);
+ ClassList bases = p->bases();
+ ClassDefPtr base;
+ if(!bases.empty() && !bases.front()->isInterface())
+ {
+ base = bases.front();
+ }
+
+ OperationList allOps = p->allOperations();
+ if(!allOps.empty())
+ {
+ StringList allOpNames;
+ transform(allOps.begin(), allOps.end(), back_inserter(allOpNames), ::IceUtil::constMemFun(&Contained::name));
+ allOpNames.push_back("ice_id");
+ allOpNames.push_back("ice_ids");
+ allOpNames.push_back("ice_isA");
+ allOpNames.push_back("ice_ping");
+ allOpNames.sort();
+ allOpNames.unique();
+
+ string flatName = p->flattenedScope() + p->name() + "_ops";
+
+ H << sp;
+ H << nl << "virtual bool __dispatch(::IceInternal::Incoming&, const ::Ice::Current&) override;";
+
+ C << sp;
+ C << nl << "bool";
+ C << nl << scoped.substr(2) << "::__dispatch(::IceInternal::Incoming& in, const ::Ice::Current& c)";
+ C << sb;
+
+ C << nl << "::std::pair< const ::std::string*, const ::std::string*> r = "
+ << "::std::equal_range(" << flatName << ", " << flatName << " + " << allOpNames.size() << ", c.operation);";
+ C << nl << "if(r.first == r.second)";
+ C << sb;
+ C << nl << "throw ::Ice::OperationNotExistException(__FILE__, __LINE__, c.id, c.facet, c.operation);";
+ C << eb;
+ C << sp;
+ C << nl << "switch(r.first - " << flatName << ')';
+ C << sb;
+ int i = 0;
+ for(StringList::const_iterator q = allOpNames.begin(); q != allOpNames.end(); ++q)
+ {
+ C << nl << "case " << i++ << ':';
+ C << sb;
+ C << nl << "return ___" << *q << "(in, c);";
+ C << eb;
+ }
+ C << nl << "default:";
+ C << sb;
+ C << nl << "assert(false);";
+ C << nl << "throw ::Ice::OperationNotExistException(__FILE__, __LINE__, c.id, c.facet, c.operation);";
+ C << eb;
+ C << eb;
+ C << eb;
+ }
+
+ H << eb << ';';
+
+ _useWstring = resetUseWstring(_useWstringHist);
+}
+
+bool
+Slice::Gen::Cpp11InterfaceVisitor::visitExceptionStart(const ExceptionPtr&)
+{
+ return false;
+}
+
+bool
+Slice::Gen::Cpp11InterfaceVisitor::visitStructStart(const StructPtr&)
+{
+ return false;
+}
+
+void
+Slice::Gen::Cpp11InterfaceVisitor::visitOperation(const OperationPtr& p)
+{
+ string name = p->name();
+
+ TypePtr ret = p->returnType();
+
+ vector<string> params;
+ vector<string> args;
+
+ vector<string> responseParams;
+ vector<string> responseParamsDecl;
+
+ ContainerPtr container = p->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container);
+ string classScope = fixKwd(cl->scope());
+
+ string suffix = cl->isInterface() ? "" : "Disp";
+ string scope = fixKwd(cl->scope() + cl->name() + suffix + "::");
+ string scoped = fixKwd(cl->scope() + cl->name() + suffix + "::" + p->name());
+
+ bool amd = (cl->hasMetaData("amd") || p->hasMetaData("amd"));
+
+ if(p->hasMarshaledResult())
+ {
+
+ }
+
+ if(ret)
+ {
+ string typeS = inputTypeToString(ret, p->returnIsOptional(), p->getMetaData(), _useWstring | TypeContextCpp11);
+ responseParams.push_back(typeS);
+ responseParamsDecl.push_back(typeS + " __ret");
+ }
+
+ string retS;
+ if(amd)
+ {
+ retS = "void";
+ }
+ else if(p->hasMarshaledResult())
+ {
+ retS = resultStructName(name, "", true);
+ }
+ else
+ {
+ retS = returnTypeToString(ret, p->returnIsOptional(), p->getMetaData(), _useWstring | TypeContextCpp11);
+ }
+
+ ParamDeclList inParams;
+ ParamDeclList outParams;
+ ParamDeclList paramList = p->parameters();
+ for(ParamDeclList::iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ TypePtr type = (*q)->type();
+ string paramName = fixKwd(string(paramPrefix) + (*q)->name());
+ bool isOutParam = (*q)->isOutParam();
+ string typeString;
+ int typeCtx = _useWstring | TypeContextCpp11;
+ if(!isOutParam)
+ {
+ inParams.push_back(*q);
+ params.push_back(typeToString(type, (*q)->optional(), (*q)->getMetaData(), typeCtx | TypeContextInParam));
+ args.push_back(condMove(isMovable(type) && !isOutParam, paramName));
+ }
+ else
+ {
+ outParams.push_back(*q);
+ if(!p->hasMarshaledResult() && !amd)
+ {
+ params.push_back(outputTypeToString(type, (*q)->optional(), (*q)->getMetaData(), typeCtx));
+ args.push_back(condMove(isMovable(type) && !isOutParam, paramName));
+ }
+
+ string responseTypeS = inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), typeCtx);
+ responseParams.push_back(responseTypeS);
+ responseParamsDecl.push_back(responseTypeS + " " + paramName);
+ }
+ }
+ if(amd)
+ {
+ if(p->hasMarshaledResult())
+ {
+ string resultName = resultStructName(name, "", true);
+ params.push_back("::std::function<void(const " + resultName + "&)>");
+ args.push_back("inS->response<" + resultName + ">()");
+ }
+ else
+ {
+ params.push_back("::std::function<void(" + joinString(responseParams, ",") + ")>");
+ args.push_back(ret || !outParams.empty() ? "__responseCB" : "inS->response()");
+ }
+ params.push_back("::std::function<void(::std::exception_ptr)>");
+ args.push_back("inS->exception()");
+ }
+ params.push_back("const ::Ice::Current& = ::Ice::noExplicitCurrent");
+ args.push_back("__current");
+
+ if(cl->isInterface())
+ {
+ emitOpNameResult(H, p, _useWstring);
+ }
+
+ if(p->hasMarshaledResult())
+ {
+ string resultName = resultStructName(name, "", true);
+ H << sp;
+ H << nl << "class " << resultName << " : public ::Ice::MarshaledResult";
+ H << sb;
+ H.dec();
+ H << nl << "public:";
+ H.inc();
+ H << nl << resultName << spar << responseParams << "const ::Ice::Current&" << epar << ";";
+ H << eb << ';';
+
+ C << sp << nl << scope.substr(2) << resultName << "::" << resultName;
+ C << spar << responseParamsDecl << "const ::Ice::Current& __current" << epar << ":";
+ C.inc();
+ C << nl << "MarshaledResult(__current)";
+ C.dec();
+ C << sb;
+ C << nl << "__os->startEncapsulation(__current.encoding, " << opFormatTypeToString(p) << ");";
+ writeMarshalCode(C, outParams, p, true, TypeContextCpp11);
+ if(p->returnsClasses(false))
+ {
+ C << nl << "__os->writePendingValues();";
+ }
+ C << nl << "__os->endEncapsulation();";
+ C << eb;
+ }
+
+ string isConst = ((p->mode() == Operation::Nonmutating) || p->hasMetaData("cpp:const")) ? " const" : "";
+
+ string opName = amd ? (name + "Async") : fixKwd(name);
+ string deprecateSymbol = getDeprecateSymbol(p, cl);
+
+ H << sp;
+ H << nl << deprecateSymbol << "virtual " << retS << ' ' << opName << spar << params << epar << isConst << " = 0;";
+ H << nl << "bool ___" << name << "(::IceInternal::Incoming&, const ::Ice::Current&)" << isConst << ';';
+
+ C << sp;
+ C << nl << "bool";
+ C << nl << scope.substr(2);
+ C << "___" << name << "(::IceInternal::Incoming& __inS" << ", const ::Ice::Current& __current)" << isConst;
+ C << sb;
+ C << nl << "__checkMode(" << operationModeToString(p->mode(), true) << ", __current.mode);";
+
+ if(!inParams.empty())
+ {
+ C << nl << "auto __is = __inS.startReadParams();";
+ writeAllocateCode(C, inParams, 0, true, _useWstring | TypeContextInParam | TypeContextCpp11);
+ writeUnmarshalCode(C, inParams, 0, true, _useWstring | TypeContextInParam | TypeContextCpp11);
+ if(p->sendsClasses(false))
+ {
+ C << nl << "__is->readPendingValues();";
+ }
+ C << nl << "__inS.endReadParams();";
+ }
+ else
+ {
+ C << nl << "__inS.readEmptyParams();";
+ }
+ if(p->format() != DefaultFormat)
+ {
+ C << nl << "__inS.setFormat(" << opFormatTypeToString(p) << ");";
+ }
+
+ if(!amd)
+ {
+ writeAllocateCode(C, outParams, 0, true, _useWstring | TypeContextCpp11);
+ if(p->hasMarshaledResult())
+ {
+ C << nl << "__inS.setMarshaledResult(";
+ }
+ else if(ret)
+ {
+ C << nl << retS << " __ret = ";
+ }
+ else
+ {
+ C << nl;
+ }
+
+ C << opName << spar << args << epar;
+ if(p->hasMarshaledResult())
+ {
+ C << ");";
+ }
+ else
+ {
+ C << ";";
+ if(ret || !outParams.empty())
+ {
+ C << nl << "auto __os = __inS.startWriteParams();";
+ writeMarshalCode(C, outParams, p, true, TypeContextCpp11);
+ if(p->returnsClasses(false))
+ {
+ C << nl << "__os->writePendingValues();";
+ }
+ C << nl << "__inS.endWriteParams();";
+ }
+ else
+ {
+ C << nl << "__inS.writeEmptyParams();";
+ }
+ }
+ C << nl << "return false;";
+ }
+ else
+ {
+ C << nl << "auto inS = ::IceInternal::IncomingAsync::create(__inS);";
+ if(!p->hasMarshaledResult() && (ret || !outParams.empty()))
+ {
+ C << nl << "auto __responseCB = [inS]" << spar << responseParamsDecl << epar;
+ C << sb;
+ C << nl << "auto __os = inS->startWriteParams();";
+ writeMarshalCode(C, outParams, p, true, TypeContextCpp11);
+ if(p->returnsClasses(false))
+ {
+ C << nl << "__os->writePendingValues();";
+ }
+ C << nl << "inS->endWriteParams();";
+ C << nl << "inS->completed();";
+ C << eb << ';';
+ }
+ C << nl << opName << spar << args << epar << ';';
+ C << nl << "return true;";
+ }
+ C << eb;
+}
+
+Slice::Gen::Cpp11ValueVisitor::Cpp11ValueVisitor(::IceUtilInternal::Output& h,
+ ::IceUtilInternal::Output& c,
+ const std::string& dllExport) :
+ Cpp11ObjectVisitor(h, c, dllExport)
+{
+}
+
+bool
+Slice::Gen::Cpp11ValueVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!p->hasValueDefs())
+ {
+ return false;
+ }
+
+ _useWstring = setUseWstring(p, _useWstringHist, _useWstring);
+ string name = fixKwd(p->name());
+ H << sp << nl << "namespace " << name << nl << '{';
+ return true;
+}
+
+void
+Slice::Gen::Cpp11ValueVisitor::visitModuleEnd(const ModulePtr&)
+{
+ H << sp;
+ H << nl << '}';
+
+ _useWstring = resetUseWstring(_useWstringHist);
+}
+
+bool
+Slice::Gen::Cpp11ValueVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ if(p->isLocal() || p->isInterface())
+ {
+ return false;
+ }
+ _useWstring = setUseWstring(p, _useWstringHist, _useWstring);
+
+ string name = fixKwd(p->name());
+ string scope = fixKwd(p->scope());
+ string scoped = fixKwd(p->scoped());
+ ClassList bases = p->bases();
+ ClassDefPtr base;
+ if(!bases.empty())
+ {
+ base = bases.front();
+ }
+ DataMemberList dataMembers = p->dataMembers();
+ DataMemberList allDataMembers = p->allDataMembers();
+
+ H << sp << nl << "class " << _dllClassExport << name << " : public ::Ice::ValueHelper<" << name << ", ";
+
+ if(!base || (base && base->isInterface()))
+ {
+ H << "Ice::Value";
+ }
+ else
+ {
+ H << fixKwd(base->scoped());
+ }
+ H << ">";
+ H << sb;
+ H.dec();
+ H << nl << "public:" << sp;
+ H.inc();
+
+ // Out of line dtor to avoid weak vtable
+ H << nl << _dllMemberExport << "virtual ~" << name << "();";
+ C << sp;
+ C << nl << scoped.substr(2) << "::~" << name << "()";
+ C << sb;
+ C << eb;
+
+ vector<string> params;
+
+ for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ params.push_back(fixKwd((*q)->name()));
+ }
+
+ H << sp << nl << name << "() = default;";
+
+ emitOneShotConstructor(p);
+
+ writeIceTuple(H, p->allDataMembers(), _useWstring);
+
+ H << sp << nl << _dllMemberExport << "static const ::std::string& ice_staticId();";
+ return true;
+}
+
+void
+Slice::Gen::Cpp11ValueVisitor::visitClassDefEnd(const ClassDefPtr& p)
+{
+ string scoped = fixKwd(p->scoped());
+ string scope = fixKwd(p->scope());
+ string name = fixKwd(p->name());
+ ClassList bases = p->bases();
+ ClassDefPtr base;
+ if(!bases.empty() && !bases.front()->isInterface())
+ {
+ base = bases.front();
+ }
+ bool basePreserved = p->inheritsMetaData("preserve-slice");
+ bool preserved = p->hasMetaData("preserve-slice");
+
+ if(preserved && !basePreserved)
+ {
+ H << sp;
+ H << nl << "virtual void __write(::Ice::OutputStream*) const override;";
+ H << nl << "virtual void __read(::Ice::InputStream*) override;";
+
+ C << sp;
+ C << nl << "void" << nl << scoped.substr(2) << "::__write(::Ice::OutputStream* __os) const";
+ C << sb;
+ C << nl << "__os->startValue(__slicedData);";
+ C << nl << "__writeImpl(__os);";
+ C << nl << "__os->endValue();";
+ C << eb;
+
+ C << sp;
+ C << nl << "void" << nl << scoped.substr(2) << "::__read(::Ice::InputStream* __is)";
+ C << sb;
+ C << nl << "__is->startValue();";
+ C << nl << "__readImpl(__is);";
+ C << nl << "__slicedData = __is->endValue(true);";
+ C << eb;
+ }
+
+ C << sp;
+ C << nl << "const ::std::string&" << nl << scoped.substr(2) << "::ice_staticId()";
+ C << sb;
+ //
+ // Use local static so that ice_staticId() is usable during static construction.
+ //
+ C << nl << "static const ::std::string typeId = \"" << p->scoped() << "\";";
+ C << nl << "return typeId;";
+ C << eb;
+
+ //
+ // Emit data members. Access visibility may be specified by metadata.
+ //
+ bool inProtected = false;
+ bool generateFriend = false;
+ DataMemberList dataMembers = p->dataMembers();
+ bool prot = p->hasMetaData("protected");
+ bool needSp = true;
+
+ for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ if(prot || (*q)->hasMetaData("protected"))
+ {
+ if(!inProtected)
+ {
+ H.dec();
+ H << sp << nl << "protected:" << sp;
+ H.inc();
+ inProtected = true;
+ needSp = false;
+ }
+ generateFriend = true;
+ }
+ else
+ {
+ if(inProtected)
+ {
+ H.dec();
+ H << sp << nl << "public:" << sp;
+ H.inc();
+ inProtected = false;
+ needSp = false;
+ }
+ }
+
+ if(needSp)
+ {
+ H << sp;
+ needSp = false;
+ }
+
+ emitDataMember(*q);
+ }
+
+ if(preserved && !basePreserved)
+ {
+ if(!inProtected)
+ {
+ H.dec();
+ H << sp << nl << "protected:";
+ H.inc();
+ inProtected = true;
+ }
+ H << sp << nl << "::std::shared_ptr<::Ice::SlicedData> __slicedData;";
+ }
+
+ if(generateFriend)
+ {
+ if(!inProtected)
+ {
+ H.dec();
+ H << sp << nl << "protected:";
+ H.inc();
+ inProtected = true;
+ }
+
+ H << sp;
+ H << nl << "template<typename T, typename S>";
+ H << nl << "friend struct Ice::StreamWriter;";
+ H << nl << "template<typename T, typename S>";
+ H << nl << "friend struct Ice::StreamReader;";
+ }
+
+ H << eb << ';';
+
+ if(!_doneStaticSymbol)
+ {
+ //
+ // We need an instance here to trigger initialization if the implementation is in a static library.
+ // But we do this only once per source file, because a single instance is sufficient to initialize
+ // all of the globals in a compilation unit.
+ //
+ _doneStaticSymbol = true;
+ H << sp << nl << "static " << fixKwd(p->name()) << " _" << p->name() << "_init;";
+ }
+
+ _useWstring = resetUseWstring(_useWstringHist);
+}
+
+bool
+Slice::Gen::Cpp11ValueVisitor::visitExceptionStart(const ExceptionPtr&)
+{
+ return false;
+}
+
+bool
+Slice::Gen::Cpp11ValueVisitor::visitStructStart(const StructPtr&)
+{
+ return false;
+}
+
+void
+Slice::Gen::Cpp11ValueVisitor::visitOperation(const OperationPtr& p)
+{
+ emitOpNameResult(H, p, _useWstring);
+}
+
+bool
+Slice::Gen::Cpp11ObjectVisitor::emitVirtualBaseInitializers(const ClassDefPtr& derived, const ClassDefPtr& base)
+{
+ DataMemberList allDataMembers = base->allDataMembers();
+ if(allDataMembers.empty())
+ {
+ return false;
+ }
+
+ string upcall = "(";
+ for(DataMemberList::const_iterator q = allDataMembers.begin(); q != allDataMembers.end(); ++q)
+ {
+ if(q != allDataMembers.begin())
+ {
+ upcall += ", ";
+ }
+ if(isMovable((*q)->type()))
+ {
+ upcall += "::std::move(__ice_" + (*q)->name() + ")";
+ }
+ else
+ {
+ upcall += "__ice_" + (*q)->name();
+ }
+ }
+ upcall += ")";
+
+ if(base->isLocal())
+ {
+ H << nl << fixKwd(base->scoped());
+ }
+ else
+ {
+ H << nl << "Ice::ValueHelper<" << fixKwd(derived->scoped()) << ", " << fixKwd(base->scoped()) << ">";
+ }
+ H << upcall;
+ return true;
+}
+
+void
+Slice::Gen::Cpp11ObjectVisitor::emitOneShotConstructor(const ClassDefPtr& p)
+{
+ DataMemberList allDataMembers = p->allDataMembers();
+
+ if(!allDataMembers.empty())
+ {
+ vector<string> allParamDecls;
+ DataMemberList dataMembers = p->dataMembers();
+
+ for(DataMemberList::const_iterator q = allDataMembers.begin(); q != allDataMembers.end(); ++q)
+ {
+ string typeName = inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(),
+ _useWstring | TypeContextCpp11);
+ allParamDecls.push_back(typeName + " __ice_" + (*q)->name());
+ }
+
+ H << sp << nl;
+ if(allParamDecls.size() == 1)
+ {
+ H << "explicit ";
+ }
+ H << fixKwd(p->name()) << spar << allParamDecls << epar << " :";
+ H.inc();
+
+ ClassList bases = p->bases();
+
+ if(!bases.empty() && !bases.front()->isInterface())
+ {
+ if(emitVirtualBaseInitializers(p, bases.front()))
+ {
+ if(!dataMembers.empty())
+ {
+ H << ',';
+ }
+ }
+ }
+
+ if(!dataMembers.empty())
+ {
+ H << nl;
+ }
+
+ for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ if(q != dataMembers.begin())
+ {
+ H << ',' << nl;
+ }
+ string memberName = fixKwd((*q)->name());
+ if(isMovable((*q)->type()))
+ {
+ H << memberName << "(::std::move(" << "__ice_" << (*q)->name() << "))";
+ }
+ else
+ {
+ H << memberName << '(' << "__ice_" << (*q)->name() << ')';
+ }
+ }
+
+ H.dec();
+ H << sb;
+ H << eb;
+ }
+}
+
+Slice::Gen::Cpp11StreamVisitor::Cpp11StreamVisitor(Output& h, Output& c, const string& dllExport) :
+ H(h),
+ C(c),
+ _dllExport(dllExport)
+{
+}
+
+bool
+Slice::Gen::Cpp11StreamVisitor::visitModuleStart(const ModulePtr& m)
+{
+ if(!m->hasNonLocalContained(Contained::ContainedTypeStruct) &&
+ !m->hasNonLocalContained(Contained::ContainedTypeEnum) &&
+ !m->hasNonLocalContained(Contained::ContainedTypeException) &&
+ !m->hasNonLocalContained(Contained::ContainedTypeClass))
+ {
+ return false;
+ }
+
+ if(UnitPtr::dynamicCast(m->container()))
+ {
+ //
+ // Only emit this for the top-level module.
+ //
+ H << sp;
+ H << nl << "namespace Ice" << nl << '{' << sp;
+
+ if(m->hasNonLocalContained(Contained::ContainedTypeStruct))
+ {
+ C << sp;
+ C << nl << "namespace Ice" << nl << '{';
+ }
+ }
+ return true;
+}
+
+void
+Slice::Gen::Cpp11StreamVisitor::visitModuleEnd(const ModulePtr& m)
+{
+ if(UnitPtr::dynamicCast(m->container()))
+ {
+ //
+ // Only emit this for the top-level module.
+ //
+ H << nl << '}';
+ if(m->hasNonLocalContained(Contained::ContainedTypeStruct))
+ {
+ C << nl << '}';
+ }
+ }
+}
+
+bool
+Slice::Gen::Cpp11StreamVisitor::visitStructStart(const StructPtr& p)
+{
+ if(p->isLocal())
+ {
+ return false;
+ }
+
+ string scoped = fixKwd(p->scoped());
+
+ H << nl << "template<>";
+ H << nl << "struct StreamableTraits< " << scoped << ">";
+ H << sb;
+ H << nl << "static const StreamHelperCategory helper = StreamHelperCategoryStruct;";
+ H << nl << "static const int minWireSize = " << p->minWireSize() << ";";
+ H << nl << "static const bool fixedLength = " << (p->isVariableLength() ? "false" : "true") << ";";
+ H << eb << ";" << nl;
+
+ writeStreamHelpers(H, p, p->dataMembers(), false, false, true);
+
+ return false;
+}
+
+bool
+Slice::Gen::Cpp11StreamVisitor::visitClassDefStart(const ClassDefPtr& c)
+{
+ if(!c->isLocal() && !c->isInterface())
+ {
+ writeStreamHelpers(H,c, c->dataMembers(), c->hasBaseDataMembers(), true, true);
+ }
+ return false;
+}
+
+void
+Slice::Gen::Cpp11StreamVisitor::visitExceptionEnd(const ExceptionPtr& p)
+{
+ if(!p->isLocal())
+ {
+ writeStreamHelpers(H,p, p->dataMembers(), p->hasBaseDataMembers(), true, true);
+ }
+}
+
+void
+Slice::Gen::Cpp11StreamVisitor::visitEnum(const EnumPtr& p)
+{
+ if(!p->isLocal())
+ {
+ string scoped = fixKwd(p->scoped());
+ H << nl << "template<>";
+ H << nl << "struct StreamableTraits< " << scoped << ">";
+ H << sb;
+ H << nl << "static const StreamHelperCategory helper = StreamHelperCategoryEnum;";
+ H << nl << "static const int minValue = " << p->minValue() << ";";
+ H << nl << "static const int maxValue = " << p->maxValue() << ";";
+ H << nl << "static const int minWireSize = " << p->minWireSize() << ";";
+ H << nl << "static const bool fixedLength = false;";
+ H << eb << ";" << nl;
+ }
+}
+
+
+Slice::Gen::Cpp11CompatibilityVisitor::Cpp11CompatibilityVisitor(Output& h, Output&, const string& dllExport) :
+ H(h),
+ _dllExport(dllExport)
+{
+}
+
+bool
+Slice::Gen::Cpp11CompatibilityVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!p->hasClassDecls())
+ {
+ return false;
+ }
+
+ string name = fixKwd(p->name());
+
+ H << sp << nl << "namespace " << name << nl << '{';
+ return true;
+}
+
+void
+Slice::Gen::Cpp11CompatibilityVisitor::visitModuleEnd(const ModulePtr&)
+{
+ H << sp;
+ H << nl << '}';
+}
+
+void
+Slice::Gen::Cpp11CompatibilityVisitor::visitClassDecl(const ClassDeclPtr& p)
+{
+ if(p->definition() && p->definition()->isDelegate())
+ {
+ return;
+ }
+
+ string name = fixKwd(p->name());
+ string scoped = fixKwd(p->scoped());
+
+ H << sp << nl << "using " << p->name() << "Ptr = ::std::shared_ptr<" << name << ">;";
+
+ if(!p->isLocal())
+ {
+ ClassDefPtr def = p->definition();
+ if(p->isInterface() || (def && !def->allOperations().empty()))
+ {
+ H << nl << "using " << p->name() << "PrxPtr = ::std::shared_ptr<" << p->name() << "Prx>;";
+ }
+ }
+}
+
+Slice::Gen::Cpp11ImplVisitor::Cpp11ImplVisitor(Output& h, Output& c, const string& dllExport) :
+ H(h), C(c), _dllExport(dllExport), _useWstring(false)
+{
+}
+
+string
+Slice::Gen::Cpp11ImplVisitor::defaultValue(const TypePtr& type, const StringList& metaData) const
+{
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
+ if(builtin)
+ {
+ switch(builtin->kind())
+ {
+ case Builtin::KindBool:
+ {
+ return "false";
+ }
+ case Builtin::KindByte:
+ case Builtin::KindShort:
+ case Builtin::KindInt:
+ case Builtin::KindLong:
+ {
+ return "0";
+ }
+ case Builtin::KindFloat:
+ case Builtin::KindDouble:
+ {
+ return "0.0";
+ }
+ case Builtin::KindString:
+ {
+ return "::std::string()";
+ }
+ case Builtin::KindValue:
+ case Builtin::KindObject:
+ case Builtin::KindObjectProxy:
+ case Builtin::KindLocalObject:
+ {
+ return "nullptr";
+ }
+ }
+ }
+ else
+ {
+ ProxyPtr prx = ProxyPtr::dynamicCast(type);
+
+ if(ProxyPtr::dynamicCast(type) || ClassDeclPtr::dynamicCast(type))
+ {
+ return "nullptr";
+ }
+
+ StructPtr st = StructPtr::dynamicCast(type);
+ if(st)
+ {
+ return fixKwd(st->scoped()) + "()";
+ }
+
+ EnumPtr en = EnumPtr::dynamicCast(type);
+ if(en)
+ {
+ EnumeratorList enumerators = en->getEnumerators();
+ return fixKwd(en->scoped() + "::" + enumerators.front()->name());
+ }
+
+ SequencePtr seq = SequencePtr::dynamicCast(type);
+ if(seq)
+ {
+ return typeToString(seq, metaData, _useWstring | TypeContextCpp11) + "()";
+ }
+
+ DictionaryPtr dict = DictionaryPtr::dynamicCast(type);
+ if(dict)
+ {
+ return fixKwd(dict->scoped()) + "()";
+ }
+ }
+
+ assert(false);
+ return "???";
+}
+
+void
+Slice::Gen::Cpp11ImplVisitor::writeReturn(Output& out, const TypePtr& type, const StringList& metaData)
+{
+ out << nl << "return " << defaultValue(type, metaData) << ";";
+}
+
+bool
+Slice::Gen::Cpp11ImplVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!p->hasClassDefs())
+ {
+ return false;
+ }
+
+ _useWstring = setUseWstring(p, _useWstringHist, _useWstring);
+
+ string name = fixKwd(p->name());
+
+ H << sp << nl << "namespace " << name << nl << '{';
+
+ return true;
+}
+
+void
+Slice::Gen::Cpp11ImplVisitor::visitModuleEnd(const ModulePtr&)
+{
+ H << sp;
+ H << nl << '}';
+
+ _useWstring = resetUseWstring(_useWstringHist);
+}
+
+bool
+Slice::Gen::Cpp11ImplVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ if(!p->isAbstract())
+ {
+ return false;
+ }
+
+ _useWstring = setUseWstring(p, _useWstringHist, _useWstring);
+
+ string name = p->name();
+ string scope = fixKwd(p->scope());
+ string cls = scope.substr(2) + name + "I";
+ ClassList bases = p->bases();
+
+ H << sp;
+ H << nl << "class " << name << "I : ";
+ H.useCurrentPosAsIndent();
+ H << "public virtual ";
+
+ if(p->isInterface() || p->isLocal())
+ {
+ H << fixKwd(name);
+ }
+ else
+ {
+ H << fixKwd(name + "Disp");
+ }
+ H.restoreIndent();
+
+ H << sb;
+ H.dec();
+ H << nl << "public:";
+ H.inc();
+
+ OperationList ops = p->allOperations();
+
+ for(OperationList::const_iterator r = ops.begin(); r != ops.end(); ++r)
+ {
+ OperationPtr op = (*r);
+ string opName = op->name();
+
+ TypePtr ret = op->returnType();
+ string retS = returnTypeToString(ret, op->returnIsOptional(), op->getMetaData(),
+ _useWstring | TypeContextCpp11);
+
+ ParamDeclList params = op->parameters();
+ ParamDeclList outParams;
+ ParamDeclList inParams;
+ for(ParamDeclList::const_iterator q = params.begin(); q != params.end(); ++q)
+ {
+ if((*q)->isOutParam())
+ {
+ outParams.push_back(*q);
+ }
+ else
+ {
+ inParams.push_back(*q);
+ }
+ }
+
+ if(!p->isLocal() && (p->hasMetaData("amd") || op->hasMetaData("amd")))
+ {
+ string responseParams;
+ string responseParamsDecl;
+
+ H << sp << nl << "virtual void " << opName << "Async(";
+ H.useCurrentPosAsIndent();
+ for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end(); ++q)
+ {
+ H << typeToString((*q)->type(), (*q)->optional(),
+ (*q)->getMetaData(), _useWstring | TypeContextInParam | TypeContextCpp11)
+ << "," << nl;
+ }
+
+ if(ret)
+ {
+ string typeS = inputTypeToString(ret, op->returnIsOptional(), op->getMetaData(),
+ _useWstring | TypeContextCpp11);
+ responseParams = typeS;
+ responseParamsDecl = typeS + " __ret";
+ if(!outParams.empty())
+ {
+ responseParams += ", ";
+ responseParamsDecl += ", ";
+ }
+ }
+
+ for(ParamDeclList::iterator q = outParams.begin(); q != outParams.end(); ++q)
+ {
+ if(q != outParams.begin())
+ {
+ responseParams += ", ";
+ responseParamsDecl += ", ";
+ }
+ string typeS = inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(),
+ _useWstring | TypeContextCpp11);
+ responseParams += typeS;
+ responseParamsDecl += typeS + " " + fixKwd(string(paramPrefix) + (*q)->name());
+ }
+
+ string isConst = ((op->mode() == Operation::Nonmutating) || op->hasMetaData("cpp:const")) ? " const" : "";
+
+ H << "std::function<void(" << responseParams << ")>,";
+ H << nl << "std::function<void(std::exception_ptr)>,";
+ H << nl << "const Ice::Current&)" << isConst << " override;";
+ H.restoreIndent();
+
+ C << sp << nl << "void" << nl << scope << name << "I::" << opName << "Async(";
+ C.useCurrentPosAsIndent();
+ for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end(); ++q)
+ {
+ C << typeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(),
+ _useWstring | TypeContextInParam | TypeContextCpp11);
+ C << ' ' << fixKwd((*q)->name()) << "," << nl;
+ }
+
+ C << "std::function<void(" << responseParams << ")> " << opName << "_response,";
+ C << nl << "std::function<void(std::exception_ptr)>,";
+ C << nl << "const Ice::Current& current)" << isConst;
+ C.restoreIndent();
+ C << sb;
+
+ string result = "r";
+ for(ParamDeclList::const_iterator q = params.begin(); q != params.end(); ++q)
+ {
+ if((*q)->name() == result)
+ {
+ result = "_" + result;
+ break;
+ }
+ }
+
+ C << nl << opName << "_response(";
+ if(ret)
+ {
+ C << defaultValue(ret, op->getMetaData());
+ }
+ for(ParamDeclList::const_iterator q = outParams.begin(); q != outParams.end(); ++q)
+ {
+ if(ret || q != outParams.begin())
+ {
+ C << ", ";
+ }
+ C << defaultValue((*q)->type(), op->getMetaData());
+ }
+ C << ");";
+
+ C << eb;
+ }
+ else
+ {
+ H << sp << nl << "virtual " << retS << ' ' << fixKwd(opName) << '(';
+ H.useCurrentPosAsIndent();
+ ParamDeclList paramList = op->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if(q != paramList.begin())
+ {
+ H << ',' << nl;
+ }
+ StringList metaData = (*q)->getMetaData();
+ string typeString;
+ if((*q)->isOutParam())
+ {
+ typeString = outputTypeToString((*q)->type(), (*q)->optional(), metaData,
+ _useWstring | TypeContextCpp11);
+ }
+ else
+ {
+ typeString = typeToString((*q)->type(), (*q)->optional(), metaData,
+ _useWstring | TypeContextInParam | TypeContextCpp11);
+ }
+ H << typeString;
+ }
+ if(!p->isLocal())
+ {
+ if(!paramList.empty())
+ {
+ H << ',' << nl;
+ }
+ H << "const Ice::Current&";
+ }
+ H.restoreIndent();
+
+ string isConst = ((op->mode() == Operation::Nonmutating) || op->hasMetaData("cpp:const")) ? " const" : "";
+
+ H << ")" << isConst << " override;";
+
+ C << sp << nl << retS << nl;
+ C << scope.substr(2) << name << "I::" << fixKwd(opName) << '(';
+ C.useCurrentPosAsIndent();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if(q != paramList.begin())
+ {
+ C << ',' << nl;
+ }
+ StringList metaData = (*q)->getMetaData();
+ string typeString;
+ if((*q)->isOutParam())
+ {
+ C << outputTypeToString((*q)->type(), (*q)->optional(), metaData, _useWstring | TypeContextCpp11)
+ << " "
+ << fixKwd((*q)->name());
+ }
+ else
+ {
+ C << typeToString((*q)->type(), (*q)->optional(), metaData,
+ _useWstring | TypeContextInParam | TypeContextCpp11)
+ << " /*" << fixKwd((*q)->name()) << "*/";
+ }
+ }
+ if(!p->isLocal())
+ {
+ if(!paramList.empty())
+ {
+ C << ',' << nl;
+ }
+ C << "const Ice::Current& current";
+ }
+ C.restoreIndent();
+ C << ')';
+ C << isConst;
+ C << sb;
+
+ for(ParamDeclList::const_iterator q = outParams.begin(); q != outParams.end(); ++q)
+ {
+ C << nl << fixKwd((*q)->name()) << " = " << defaultValue((*q)->type(), op->getMetaData()) << ";";
+ }
+
+ if(ret)
+ {
+ writeReturn(C, ret, op->getMetaData());
+ }
+
+ C << eb;
+ }
+ }
+
+ H << eb << ';';
+
+ _useWstring = resetUseWstring(_useWstringHist);
+
+ return true;
+}