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.cpp6419
1 files changed, 4327 insertions, 2092 deletions
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp
index 9621ec14f08..e0e00588311 100644
--- a/cpp/src/slice2cpp/Gen.cpp
+++ b/cpp/src/slice2cpp/Gen.cpp
@@ -13,8 +13,7 @@
#include <Slice/CPlusPlusUtil.h>
#include <IceUtil/Functional.h>
#include <IceUtil/Iterator.h>
-#include <IceUtil/InputUtil.h>
-#include <IceUtil/Unicode.h>
+#include <IceUtil/StringUtil.h>
#include <Slice/Checksum.h>
#include <Slice/FileTracker.h>
#include <IceUtil/FileUtil.h>
@@ -30,80 +29,57 @@ using namespace IceUtilInternal;
namespace
{
-string
-u32CodePoint(unsigned int value)
+bool
+isConstexprType(const TypePtr& type)
{
- ostringstream s;
- //
- // COMPILERFIX:
- // With VC++ < 140 characters in the range of 0 to 0x9f cannot be represented
- // with a universal character name (UCN).
- //
- if(value <= 0x9f)
+ BuiltinPtr bp = BuiltinPtr::dynamicCast(type);
+ if(bp)
{
- switch(value)
+ switch(bp->kind())
{
- case 0x22:
- {
- s << "\\\"";
- break;
- }
- case 0x5c:
+ 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:
{
- s << "\\\\";
- break;
+ return true;
}
default:
{
- s << "\\";
- s << oct;
- s.width(3);
- s.fill('0');
- s << value;
- break;
+ return false;
}
}
}
- //
- // UCN valid characters
- //
- else
+ else if(EnumPtr::dynamicCast(type) || ProxyPtr::dynamicCast(type) || ClassDeclPtr::dynamicCast(type))
{
- s << "\\U";
- s << hex;
- s.width(8);
- s.fill('0');
- s << value;
+ return true;
}
- return s.str();
-}
-
-void
-writeU8Buffer(const vector<unsigned char>& u8buffer, ::IceUtilInternal::Output& out)
-{
- vector<unsigned int> u32buffer;
- IceUtilInternal::ConversionResult result = convertUTF8ToUTF32(u8buffer, u32buffer, IceUtil::lenientConversion);
- switch(result)
+ else
{
- case conversionOK:
- break;
- case sourceExhausted:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source exhausted");
- case sourceIllegal:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source illegal");
- default:
+ StructPtr s = StructPtr::dynamicCast(type);
+ if(s)
{
- assert(0);
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__);
+ DataMemberList members = s->dataMembers();
+ for(DataMemberList::const_iterator i = members.begin(); i != members.end(); ++i)
+ {
+ if(!isConstexprType((*i)->type()))
+ {
+ return false;
+ }
+ }
+ return true;
}
- }
-
- for(vector<unsigned int>::const_iterator c = u32buffer.begin(); c != u32buffer.end(); ++c)
- {
- out << u32CodePoint(*c);
+ return false;
}
}
+
string
getDeprecateSymbol(const ContainedPtr& p1, const ContainedPtr& p2)
{
@@ -123,7 +99,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)
@@ -135,228 +111,28 @@ writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const Synt
BuiltinPtr bp = BuiltinPtr::dynamicCast(type);
if(bp && bp->kind() == Builtin::KindString)
{
- //
- // Expand strings into the basic source character set. We can't use isalpha() and the like
- // here because they are sensitive to the current locale.
- //
- static const string basicSourceChars = "abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "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
- //
- vector<unsigned char> u8buffer; // Buffer to convert multibyte characters
- out << "L\"";
- 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]));
- }
- else
- {
- u8buffer.push_back(value[i]);
- }
- }
- else
- {
- //
- // Write any pedding characters in the utf8 buffer
- //
- if(!u8buffer.empty())
- {
- writeU8Buffer(u8buffer, out);
- u8buffer.clear();
- }
-
- switch(value[i])
- {
- case '\\':
- {
- string s = "\\";
- size_t j = i + 1;
- for(; j < value.size(); ++j)
- {
- if(value[j] != '\\')
- {
- break;
- }
- s += "\\";
- }
-
- //
- // An even number of slash \ will escape the backslash and
- // the codepoint will be interpreted as its charaters
- //
- // \\U00000041 - ['\\', 'U', '0', '0', '0', '0', '0', '0', '4', '1']
- // \\\U00000041 - ['\\', 'A'] (41 is the codepoint for 'A')
- //
- if(s.size() % 2 != 0 && (value[j] == 'U' || value[j] == 'u'))
- {
- //
- // Convert codepoint to UTF8 bytes and write the escaped bytes
- //
- out << s.substr(0, s.size() - 1);
-
- size_t sz = value[j] == 'U' ? 8 : 4;
- string codepoint = value.substr(j + 1, sz);
- assert(codepoint.size() == sz);
-
- IceUtil::Int64 v = IceUtilInternal::strToInt64(codepoint.c_str(), 0, 16);
- out << u32CodePoint(static_cast<unsigned int>(v));
-
- i = j + 1 + sz;
- }
- else
- {
- out << s;
- i = j;
- }
- continue;
- }
- case '"':
- {
- out << "\\";
- break;
- }
- }
-
- out << value[i]; // Print normally if in basic source character set
- }
- i++;
-
- }
-
- //
- // Write any pedding characters in the utf8 buffer
- //
- if(!u8buffer.empty())
- {
- writeU8Buffer(u8buffer, out);
- u8buffer.clear();
- }
+ out << (wide ? "L\"" : "u8\"");
+ out << toStringLiteral(value, "\a\b\f\n\r\t\v", "?", UCN, cpp11 ? 0 : 0x9F + 1);
out << "\"";
}
- else // narrow strings
+ else // C++98 narrow strings
{
- out << "\""; // Opening "
-
- for(size_t i = 0; i < value.size();)
- {
- if(charSet.find(value[i]) == charSet.end())
- {
- unsigned char uc = value[i]; // char may be signed, so make it positive
- ostringstream s;
- s << "\\"; // Print as octal if not in basic source character set
- s.width(3);
- s.fill('0');
- s << oct;
- s << static_cast<unsigned>(uc);
- out << s.str();
- }
- else
- {
- switch(value[i])
- {
- case '\\':
- {
- string s = "\\";
- size_t j = i + 1;
- for(; j < value.size(); ++j)
- {
- if(value[j] != '\\')
- {
- break;
- }
- s += "\\";
- }
-
- //
- // An even number of slash \ will escape the backslash and
- // the codepoint will be interpreted as its charaters
- //
- // \\U00000041 - ['\\', 'U', '0', '0', '0', '0', '0', '0', '4', '1']
- // \\\U00000041 - ['\\', 'A'] (41 is the codepoint for 'A')
- //
- if(s.size() % 2 != 0 && (value[j] == 'U' || value[j] == 'u'))
- {
- //
- // Convert codepoint to UTF8 bytes and write the escaped bytes
- //
- out << s.substr(0, s.size() - 1);
-
- size_t sz = value[j] == 'U' ? 8 : 4;
- string codepoint = value.substr(j + 1, sz);
- assert(codepoint.size() == sz);
-
- IceUtil::Int64 v = IceUtilInternal::strToInt64(codepoint.c_str(), 0, 16);
-
-
- 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__);
- }
- }
-
- ostringstream s;
- for(vector<unsigned char>::const_iterator q = u8buffer.begin(); q != u8buffer.end(); ++q)
- {
- s << "\\";
- s.fill('0');
- s.width(3);
- s << oct;
- s << static_cast<unsigned int>(*q);
- }
- out << s.str();
-
- i = j + 1 + sz;
- }
- else
- {
- out << s;
- i = j;
- }
- continue;
- }
- case '"':
- {
- out << "\\";
- break;
- }
- }
-
- out << value[i]; // Print normally if in basic source character set
- }
- ++i;
- }
- out << "\""; // Closing "
+ out << "\"" << toStringLiteral(value, "\a\b\f\n\r\t\v", "?", Octal, 0) << "\"";
}
}
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)
{
@@ -370,11 +146,32 @@ writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const Synt
else
{
EnumPtr ep = EnumPtr::dynamicCast(type);
- if(ep)
+ if(ep && valueType)
{
- out << fixKwd(value);
+ EnumeratorPtr enumerator = EnumeratorPtr::dynamicCast(valueType);
+ assert(enumerator);
+
+ bool unscoped = (cpp11 && findMetaData(ep->getMetaData(), TypeContextCpp11) == "%unscoped") ||
+ (!cpp11 && findMetaData(ep->getMetaData()) != "%scoped");
+
+ if(unscoped)
+ {
+ out << fixKwd(ep->scope() + enumerator->name());
+ }
+ else
+ {
+ if(cpp11)
+ {
+ out << fixKwd(enumerator->scoped());
+ }
+ else
+ {
+ out << fixKwd(ep->scope() + ep->name() + enumerator->name())
+;
+ }
+ }
}
- else
+ else if(!ep)
{
out << value;
}
@@ -382,39 +179,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 +225,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* ostr)";
+ C << sb;
+ writeMarshalCode(C, inParams, 0, true, TypeContextInParam | TypeContextCpp11);
+ if(p->sendsClasses(false))
+ {
+ C << nl << "ostr->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 +391,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 +414,7 @@ Slice::Gen::~Gen()
H << "\n#endif\n";
C << '\n';
- if(_impl)
+ if(_implCpp98 || _implCpp11)
{
implH << "\n\n#endif\n";
implC << '\n';
@@ -485,12 +422,44 @@ 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* iceSliceChecksums[] =";
+ 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 iceSliceChecksumInit(iceSliceChecksums);";
+ C << sp << nl << "}";
+ }
+ }
+}
+
+void
Slice::Gen::generate(const UnitPtr& p)
{
string file = p->topLevelFile();
//
- // Give precedence to header-ext global metadata.
+ // Give precedence to header-ext/source-ext global metadata.
//
string headerExtension = getHeaderExt(file, p);
if(!headerExtension.empty())
@@ -498,7 +467,28 @@ Slice::Gen::generate(const UnitPtr& p)
_headerExtension = headerExtension;
}
- if(_impl)
+ string sourceExtension = getSourceExt(file, p);
+ if(!sourceExtension.empty())
+ {
+ _sourceExtension = sourceExtension;
+ }
+
+ //
+ // Give precedence to --dll-export command-line option
+ //
+ if(_dllExport.empty())
+ {
+ DefinitionContextPtr dc = p->findDefinitionContext(file);
+ assert(dc);
+ static const string dllExportPrefix = "cpp:dll-export:";
+ string meta = dc->findMetaData(dllExportPrefix);
+ if(meta.size() > dllExportPrefix.size())
+ {
+ _dllExport = meta.substr(dllExportPrefix.size());
+ }
+ }
+
+ if(_implCpp98 || _implCpp11)
{
string fileImplH = _base + "I." + _implHeaderExtension;
string fileImplC = _base + "I." + _sourceExtension;
@@ -540,7 +530,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 +573,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 +602,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 +670,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();
@@ -710,17 +694,41 @@ Slice::Gen::generate(const UnitPtr& p)
DefinitionContextPtr dc = p->findDefinitionContext(file);
assert(dc);
StringList globalMetaData = dc->getMetaData();
- for(StringList::const_iterator q = globalMetaData.begin(); q != globalMetaData.end(); ++q)
+ for(StringList::const_iterator q = globalMetaData.begin(); q != globalMetaData.end();)
{
- string s = *q;
+ string s = *q++;
static const string includePrefix = "cpp:include:";
- if(s.find(includePrefix) == 0 && s.size() > includePrefix.size())
+ if(s.find(includePrefix) == 0)
{
- H << nl << "#include <" << s.substr(includePrefix.size()) << ">";
+ if(s.size() > includePrefix.size())
+ {
+ H << nl << "#include <" << s.substr(includePrefix.size()) << ">";
+ }
+ else
+ {
+ ostringstream ostr;
+ ostr << "ignoring invalid global metadata `" << s << "'";
+ dc->warning(InvalidMetaData, file, -1, ostr.str());
+ globalMetaData.remove(s);
+ }
}
}
+ dc->setMetaData(globalMetaData);
}
+ //
+ // Disable shadow warnings in .cpp file
+ //
+ C << sp;
+ C.zeroIndent();
+ C << nl << "#if defined(_MSC_VER)";
+ C << nl << "# pragma warning(disable:4458) // declaration of ... hides class member";
+ C << nl << "#elif defined(__clang__)";
+ C << nl << "# pragma clang diagnostic ignored \"-Wshadow\"";
+ C << nl << "#elif defined(__GNUC__)";
+ C << nl << "# pragma GCC diagnostic ignored \"-Wshadow\"";
+ C << nl << "#endif";
+
printVersionCheck(H);
printVersionCheck(C);
@@ -730,96 +738,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 +923,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)
{
}
@@ -904,21 +969,15 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
DataMemberList allDataMembers = p->allDataMembers();
bool hasDefaultValues = p->hasDefaultValues();
- 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);
allTypes.push_back(typeName);
- allParamDecls.push_back(typeName + " __ice_" + fixKwd((*q)->name()));
+ allParamDecls.push_back(typeName + " iceP_" + (*q)->name());
}
if(base)
@@ -926,7 +985,7 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
DataMemberList baseDataMembers = base->allDataMembers();
for(DataMemberList::const_iterator q = baseDataMembers.begin(); q != baseDataMembers.end(); ++q)
{
- baseParams.push_back("__ice_" + fixKwd((*q)->name()));
+ baseParams.push_back("iceP_" + (*q)->name());
}
}
@@ -979,10 +1038,9 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
H << nl << "virtual ~" << name << "() throw();";
H << sp;
-
if(!p->isLocal())
{
- string initName = p->flattenedScope() + p->name() + "_init";
+ string initName = "iceC" + p->flattenedScope() + p->name() + "_init";
C << sp << nl << "namespace";
C << nl << "{";
@@ -995,10 +1053,10 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
if(p->isLocal())
{
- C << sp << nl << scoped.substr(2) << "::" << name << spar << "const char* __file" << "int __line" << epar
+ C << sp << nl << scoped.substr(2) << "::" << name << spar << "const char* file_" << "int line_" << epar
<< " :";
C.inc();
- emitUpcall(base, "(__file, __line)", true);
+ emitUpcall(base, "(file_, line_)", true);
if(p->hasDefaultValues())
{
C << ", ";
@@ -1024,10 +1082,10 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
C << scoped.substr(2) << "::" << name << spar;
if(p->isLocal())
{
- C << "const char* __file" << "int __line";
+ C << "const char* file_" << "int line_";
}
C << allParamDecls << epar;
- if(p->isLocal() || !baseParams.empty() || !params.empty())
+ if(p->isLocal() || !baseParams.empty() || !dataMembers.empty())
{
C << " :";
C.inc();
@@ -1037,7 +1095,7 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
upcall = "(";
if(p->isLocal())
{
- upcall += "__file, __line";
+ upcall += "file_, line_";
}
for(vector<string>::const_iterator pi = baseParams.begin(); pi != baseParams.end(); ++pi)
{
@@ -1049,21 +1107,21 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
}
upcall += ")";
}
- if(!params.empty())
+ if(!dataMembers.empty())
{
upcall += ",";
}
emitUpcall(base, upcall, p->isLocal());
}
- for(vector<string>::const_iterator pi = params.begin(); pi != params.end(); ++pi)
+ for(DataMemberList::const_iterator d = dataMembers.begin(); d != dataMembers.end(); ++d)
{
- if(pi != params.begin())
+ if(d != dataMembers.begin())
{
C << ",";
}
- C << nl << *pi << "(__ice_" << *pi << ')';
+ C << nl << fixKwd((*d)->name()) << "(iceP_" << (*d)->name() << ')';
}
- if(p->isLocal() || !baseParams.empty() || !params.empty())
+ if(p->isLocal() || !baseParams.empty() || !dataMembers.empty())
{
C.dec();
}
@@ -1076,10 +1134,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();
@@ -1104,10 +1162,10 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
{
if(!base || (base && !base->usesClasses(false)))
{
- H << sp << nl << "virtual bool __usesClasses() const;";
+ H << sp << nl << "virtual bool _usesClasses() const;";
C << sp << nl << "bool";
- C << nl << scoped.substr(2) << "::__usesClasses() const";
+ C << nl << scoped.substr(2) << "::_usesClasses() const";
C << sb;
C << nl << "return true;";
C << eb;
@@ -1137,140 +1195,78 @@ 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;";
+ 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* ostr) const";
C << sb;
- C << nl << "__os->startWriteException(__slicedData);";
- C << nl << "__writeImpl(__os);";
- C << nl << "__os->endWriteException();";
+ C << nl << "ostr->startException(_slicedData);";
+ C << nl << "_writeImpl(ostr);";
+ C << nl << "ostr->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* istr)";
C << sb;
- C << nl << "__is->startReadException();";
- C << nl << "__readImpl(__is);";
- C << nl << "__slicedData = __is->endReadException(true);";
+ C << nl << "istr->startException();";
+ C << nl << "_readImpl(istr);";
+ C << nl << "_slicedData = istr->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* ostr) 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 << "ostr->startSlice(\"" << p->scoped() << "\", -1, " << (!base ? "true" : "false") << ");";
+ C << nl << "Ice::StreamWriter< ::" << scoped.substr(2) << ", ::Ice::OutputStream>::write(ostr, *this);";
+ C << nl << "ostr->endSlice();";
if(base)
{
- emitUpcall(base, "::__writeImpl(__os);");
+ emitUpcall(base, "::_writeImpl(ostr);");
}
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* istr)";
C << sb;
- C << nl << "__is->startReadSlice();";
- writeMarshalUnmarshalDataMembers(C, p->dataMembers(), p->orderedOptionalDataMembers(), false);
- C << nl << "__is->endReadSlice();";
+ C << nl << "istr->startSlice();";
+ C << nl << "Ice::StreamReader< ::" << scoped.substr(2) << ", ::Ice::InputStream>::read(istr, *this);";
+ C << nl << "istr->endSlice();";
if(base)
{
- emitUpcall(base, "::__readImpl(__is);");
+ emitUpcall(base, "::_readImpl(istr);");
}
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)
{
_doneStaticSymbol = true;
- H << sp << nl << "static " << name << " __" << p->name() << "_init;";
+ H << sp << nl << "static " << name << " _iceS_" << p->name() << "_init;";
}
}
@@ -1288,7 +1284,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:";
@@ -1336,14 +1332,10 @@ Slice::Gen::TypesVisitor::visitStructStart(const StructPtr& p)
{
string typeName = inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring);
types.push_back(typeName);
- paramDecls.push_back(typeName + " __ice_" + (*q)->name());
+ paramDecls.push_back(typeName + " iceP_" + (*q)->name());
}
H << nl;
- if(!classMetaData)
- {
- H << _dllExport;
- }
if(paramDecls.size() == 1)
{
H << "explicit ";
@@ -1358,7 +1350,7 @@ Slice::Gen::TypesVisitor::visitStructStart(const StructPtr& p)
H << ',';
}
string memberName = fixKwd((*q)->name());
- H << nl << memberName << '(' << "__ice_" << (*q)->name() << ')';
+ H << nl << memberName << '(' << "iceP_" << (*q)->name() << ')';
}
H.dec();
@@ -1392,34 +1384,34 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p)
bool containsSequence = false;
if((Dictionary::legalKeyType(p, containsSequence) && !containsSequence) || p->hasMetaData("cpp:comparable"))
{
- H << sp << nl << "bool operator==(const " << name << "& __rhs) const";
+ H << sp << nl << "bool operator==(const " << name << "& rhs_) const";
H << sb;
- H << nl << "if(this == &__rhs)";
+ H << nl << "if(this == &rhs_)";
H << sb;
H << nl << "return true;";
H << eb;
for(vector<string>::const_iterator pi = params.begin(); pi != params.end(); ++pi)
{
- H << nl << "if(" << *pi << " != __rhs." << *pi << ')';
+ H << nl << "if(" << *pi << " != rhs_." << *pi << ')';
H << sb;
H << nl << "return false;";
H << eb;
}
H << nl << "return true;";
H << eb;
- H << sp << nl << "bool operator<(const " << name << "& __rhs) const";
+ H << sp << nl << "bool operator<(const " << name << "& rhs_) const";
H << sb;
- H << nl << "if(this == &__rhs)";
+ H << nl << "if(this == &rhs_)";
H << sb;
H << nl << "return false;";
H << eb;
for(vector<string>::const_iterator pi = params.begin(); pi != params.end(); ++pi)
{
- H << nl << "if(" << *pi << " < __rhs." << *pi << ')';
+ H << nl << "if(" << *pi << " < rhs_." << *pi << ')';
H << sb;
H << nl << "return true;";
H << eb;
- H << nl << "else if(__rhs." << *pi << " < " << *pi << ')';
+ H << nl << "else if(rhs_." << *pi << " < " << *pi << ')';
H << sb;
H << nl << "return false;";
H << eb;
@@ -1427,21 +1419,21 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p)
H << nl << "return false;";
H << eb;
- H << sp << nl << "bool operator!=(const " << name << "& __rhs) const";
+ H << sp << nl << "bool operator!=(const " << name << "& rhs_) const";
H << sb;
- H << nl << "return !operator==(__rhs);";
+ H << nl << "return !operator==(rhs_);";
H << eb;
- H << nl << "bool operator<=(const " << name << "& __rhs) const";
+ H << nl << "bool operator<=(const " << name << "& rhs_) const";
H << sb;
- H << nl << "return operator<(__rhs) || operator==(__rhs);";
+ H << nl << "return operator<(rhs_) || operator==(rhs_);";
H << eb;
- H << nl << "bool operator>(const " << name << "& __rhs) const";
+ H << nl << "bool operator>(const " << name << "& rhs_) const";
H << sb;
- H << nl << "return !operator<(__rhs) && !operator==(__rhs);";
+ H << nl << "return !operator<(rhs_) && !operator==(rhs_);";
H << eb;
- H << nl << "bool operator>=(const " << name << "& __rhs) const";
+ H << nl << "bool operator>=(const " << name << "& rhs_) const";
H << sb;
- H << nl << "return !operator<(__rhs);";
+ H << nl << "return !operator<(rhs_);";
H << eb;
}
H << eb << ';';
@@ -1518,7 +1510,9 @@ void
Slice::Gen::TypesVisitor::visitEnum(const EnumPtr& p)
{
string name = fixKwd(p->name());
- EnumeratorList enumerators = p->getEnumerators();
+ EnumeratorList enumerators = p->enumerators();
+
+ string enumeratorPrefix = findMetaData(p->getMetaData()) == "%scoped" ? name : "";
//
// Check if any of the enumerators were assigned an explicit value.
@@ -1531,7 +1525,7 @@ Slice::Gen::TypesVisitor::visitEnum(const EnumPtr& p)
EnumeratorList::const_iterator en = enumerators.begin();
while(en != enumerators.end())
{
- H << nl << fixKwd((*en)->name());
+ H << nl << fixKwd(enumeratorPrefix + (*en)->name());
//
// If any of the enumerators were assigned an explicit value, we emit
// an explicit value for *all* enumerators.
@@ -1622,13 +1616,19 @@ 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"
+ //
+ // Underscore prefix because it's a private function that should not clash with
+ // an interface named 'readProxy'
+ // Note that _readProxy is always in the IceProxy::... namespace
+ //
+ H << nl << _dllExport << "void _readProxy(::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,53 +1691,78 @@ 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 << "_readProxy(::Ice::InputStream* istr, "
<< "::IceInternal::ProxyHandle< ::IceProxy" << scoped << ">& v)";
C << sb;
C << nl << "::Ice::ObjectPrx proxy;";
- C << nl << "__is->read(proxy);";
+ C << nl << "istr->read(proxy);";
C << nl << "if(!proxy)";
C << sb;
C << nl << "v = 0;";
@@ -1745,7 +1770,7 @@ Slice::Gen::ProxyVisitor::visitClassDefStart(const ClassDefPtr& p)
C << nl << "else";
C << sb;
C << nl << "v = new ::IceProxy" << scoped << ';';
- C << nl << "v->__copyFrom(proxy);";
+ C << nl << "v->_copyFrom(proxy);";
C << eb;
C << eb;
@@ -1759,143 +1784,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);
@@ -1937,7 +1844,7 @@ void
Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p)
{
string name = p->name();
- string flatName = p->flattenedScope() + p->name() + "_name";
+ string flatName = "iceC" + p->flattenedScope() + p->name() + "_name";
string scoped = fixKwd(p->scoped());
string scope = fixKwd(p->scope());
@@ -2017,12 +1924,12 @@ 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
+ // Check if we need to generate a private _iceI_end_ method. This is the case if the
+ // 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).
- // For this purpose, we generate a special ___end method which is used by the
+ // For this purpose, we generate a special _iceI_end method which is used by the
// completed implementation of the generated Callback_Inft_opName operation
// delegate.
//
@@ -2031,263 +1938,65 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p)
{
string typeStringEndAMI = outputTypeToString(ret, p->returnIsOptional(), p->getMetaData(),
_useWstring | TypeContextAMIPrivateEnd);
- outParamsDeclEndAMI.push_back(typeStringEndAMI + ' ' + "__ret");
+ outParamsDeclEndAMI.push_back(typeStringEndAMI + ' ' + "ret");
}
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& context = ::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 << "_iceI_begin_" + name << spar << argsAMI;
+ H << "context" << "::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& context = ::Ice::noExplicitContext" << epar;
H << sb;
- H << nl << "return begin_" << name << spar << argsAMI << "&__ctx" << "::IceInternal::__dummyCallback" << "0"
+ H << nl << "return _iceI_begin_" << name << spar << argsAMI << "context" << "::IceInternal::dummyCallback" << "0"
<< epar << ';';
H << eb;
H << sp << nl << "::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI
- << "const ::Ice::CallbackPtr& __del"
- << "const ::Ice::LocalObjectPtr& __cookie = 0" << epar;
+ << "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 _iceI_begin_" << name << spar << argsAMI << "::Ice::noExplicitContext" << "del" << "cookie" << epar << ';';
H << eb;
H << sp << nl << "::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI
- << "const ::Ice::Context& __ctx"
- << "const ::Ice::CallbackPtr& __del"
- << "const ::Ice::LocalObjectPtr& __cookie = 0" << epar;
+ << "const ::Ice::Context& context"
+ << "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 _iceI_begin_" << name << spar << argsAMI << "context" << "del" << "cookie" << epar << ';';
H << eb;
H << sp << nl << "::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI
- << "const " + delNameScoped + "Ptr& __del"
- << "const ::Ice::LocalObjectPtr& __cookie = 0" << epar;
+ << "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 _iceI_begin_" << name << spar << argsAMI << "::Ice::noExplicitContext" << "del" << "cookie" << epar << ';';
H << eb;
H << sp << nl << "::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI
- << "const ::Ice::Context& __ctx"
- << "const " + delNameScoped + "Ptr& __del"
- << "const ::Ice::LocalObjectPtr& __cookie = 0" << epar;
+ << "const ::Ice::Context& context"
+ << "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 _iceI_begin_" << name << spar << argsAMI << "context" << "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 _iceI_end_" << name << spar << outParamsDeclEndAMI;
H << "const ::Ice::AsyncResultPtr&" << epar << ';';
}
@@ -2295,316 +2004,71 @@ 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 _iceI_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 << "_iceI_begin_" << name << spar << paramsDeclAMI
+ << "const ::Ice::Context& context" << "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);";
+ C << nl << "result->prepare(" << flatName << ", " << operationModeToString(p->sendMode()) << ", context);";
if(inParams.empty())
{
- C << nl << "__result->writeEmptyParams();";
+ C << nl << "result->writeEmptyParams();";
}
else
{
- C << nl << "::IceInternal::BasicStream* __os = __result->startWriteParams(" << opFormatTypeToString(p) <<");";
+ C << nl << "::Ice::OutputStream* ostr = result->startWriteParams(" << opFormatTypeToString(p, false) <<");";
writeMarshalCode(C, inParams, 0, true, TypeContextInParam);
if(p->sendsClasses(false))
{
- C << nl << "__os->writePendingObjects();";
+ C << nl << "ostr->writePendingValues();";
}
- C << nl << "__result->endWriteParams();";
+ C << nl << "result->endWriteParams();";
}
- C << nl << "__result->invoke();";
+ C << nl << "result->invoke(" << flatName << ");";
C << eb;
- C << nl << "catch(const ::Ice::Exception& __ex)";
+ C << nl << "catch(const ::Ice::Exception& ex)";
C << sb;
- C << nl << "__result->abort(__ex);";
+ C << nl << "result->abort(ex);";
C << eb;
- C << nl << "return __result;";
+ 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;
+ << "const ::Ice::AsyncResultPtr& result" << epar;
C << sb;
if(p->returnsData())
{
- C << nl << "::Ice::AsyncResult::__check(__result, this, " << flatName << ");";
+ C << nl << "::Ice::AsyncResult::check(result, this, " << flatName << ");";
//
// COMPILERFIX: It's necessary to generate the allocate code here before
- // this if(!__result->wait()). If generated after this if block, we get
+ // this if(!result->wait()). If generated after this if block, we get
// access violations errors with the test/Ice/slicing/objects test on VC9
// and Windows 64 bits when compiled with optimization (see bug 4400).
//
writeAllocateCode(C, ParamDeclList(), p, true, _useWstring | TypeContextAMIEnd);
- C << nl << "if(!__result->__wait())";
+ C << nl << "if(!result->waitForResponse())";
C << sb;
C << nl << "try";
C << sb;
- C << nl << "__result->__throwUserException();";
+ C << nl << "result->throwUserException();";
C << eb;
//
// Generate a catch block for each legal user exception.
@@ -2625,33 +2089,33 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p)
C << nl << "throw;";
C << eb;
}
- C << nl << "catch(const ::Ice::UserException& __ex)";
+ 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* istr = result->startReadParams();";
writeUnmarshalCode(C, outParams, p, true, _useWstring | TypeContextAMIEnd);
if(p->returnsClasses(false))
{
- C << nl << "__is->readPendingObjects();";
+ C << nl << "istr->readPendingValues();";
}
- C << nl << "__result->__endReadParams();";
+ C << nl << "result->endReadParams();";
}
else
{
- C << nl << "__result->__readEmptyParams();";
+ C << nl << "result->readEmptyParams();";
}
if(ret)
{
- C << nl << "return __ret;";
+ C << nl << "return ret;";
}
}
else
{
- C << nl << "__end(__result, " << flatName << ");";
+ C << nl << "_end(result, " << flatName << ");";
}
C << eb;
@@ -2659,15 +2123,15 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p)
{
assert(p->returnsData());
- C << sp << nl << "void IceProxy" << scope << "___end_" << name << spar << outParamsDeclEndAMI
- << "const ::Ice::AsyncResultPtr& __result" << epar;
+ C << sp << nl << "void IceProxy" << scope << "_iceI_end_" << name << spar << outParamsDeclEndAMI
+ << "const ::Ice::AsyncResultPtr& result" << epar;
C << sb;
- C << nl << "::Ice::AsyncResult::__check(__result, this, " << flatName << ");";
- C << nl << "if(!__result->__wait())";
+ C << nl << "::Ice::AsyncResult::check(result, this, " << flatName << ");";
+ C << nl << "if(!result->waitForResponse())";
C << sb;
C << nl << "try";
C << sb;
- C << nl << "__result->__throwUserException();";
+ C << nl << "result->throwUserException();";
C << eb;
//
// Generate a catch block for each legal user exception.
@@ -2688,24 +2152,25 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p)
C << nl << "throw;";
C << eb;
}
- C << nl << "catch(const ::Ice::UserException& __ex)";
+ 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* istr = result->startReadParams();";
writeUnmarshalCode(C, outParams, p, true, _useWstring | TypeContextAMIPrivateEnd);
if(p->returnsClasses(false))
{
- C << nl << "__is->readPendingObjects();";
+ C << nl << "istr->readPendingValues();";
}
- C << nl << "__result->__endReadParams();";
+ C << nl << "result->endReadParams();";
}
else
{
- C << nl << "__result->__readEmptyParams();";
+ C << nl << "result->readEmptyParams();";
}
C << eb;
}
@@ -2747,10 +2212,20 @@ Slice::Gen::ObjectDeclVisitor::visitClassDecl(const ClassDeclPtr& p)
H << sp << nl << "class " << name << ';';
if(!p->isLocal())
{
+ //
+ // upCast is not _upCast nor _iceUpCast for historical reasons. IceInternal::Handle
+ // depends on this name
+ //
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 << _dllExport << "void __patch(" << p->name() << "Ptr&, const ::Ice::ObjectPtr&);";
+ H << nl << "typedef " << p->name() << "Prx " << p->name() << "PrxPtr;";
+
+ //
+ // _ice prefix because this function is in the Slice module namespace, where the user
+ // is allowed to define classes, functions etc. that start with _.
+ //
+ H << nl << _dllExport << "void _icePatchObjectPtr(" << p->name() << "Ptr&, const ::Ice::ObjectPtr&);";
}
else
{
@@ -2765,13 +2240,13 @@ Slice::Gen::ObjectDeclVisitor::visitOperation(const OperationPtr& p)
ClassDefPtr cl = ClassDefPtr::dynamicCast(p->container());
if(cl && !cl->isLocal())
{
- string flatName = p->flattenedScope() + p->name() + "_name";
+ string flatName = "iceC" + p->flattenedScope() + p->name() + "_name";
C << sp << nl << "const ::std::string " << flatName << " = \"" << p->name() << "\";";
}
}
-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 +2301,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 +2328,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 +2354,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;
@@ -2892,7 +2373,7 @@ Slice::Gen::ObjectVisitor::visitClassDefStart(const ClassDefPtr& p)
{
string typeName = inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring);
allTypes.push_back(typeName);
- allParamDecls.push_back(typeName + " __ice_" + (*q)->name());
+ allParamDecls.push_back(typeName + " iceP_" + (*q)->name());
}
if(!p->isInterface())
@@ -2912,131 +2393,15 @@ 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())
{
C << sp << nl
<< _dllExport
- << "::Ice::Object* " << scope.substr(2) << "upCast(" << scoped << "* p) { return p; }";
+ << "::Ice::Object* " << scope.substr(2) << "upCast(" << scoped << "* p) { return p; }"
+ << nl;
//
// It would make sense to provide a covariant ice_clone(); unfortunately many compilers
@@ -3045,7 +2410,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,10 +2427,8 @@ Slice::Gen::ObjectVisitor::visitClassDefStart(const ClassDefPtr& p)
C << sb;
if(!p->isAbstract())
{
-
-
- C << nl << "::Ice::Object* __p = new " << name << "(*this);";
- C << nl << "return __p;";
+ C << nl << "::Ice::Object* p = new " << name << "(*this);";
+ C << nl << "return p;";
}
else
{
@@ -3101,18 +2464,13 @@ 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();";
+ << "(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();";
- if(!dataMembers.empty())
- {
- H << sp;
- }
-
- string flatName = p->flattenedScope() + p->name() + "_ids";
+ string flatName = "iceC" + p->flattenedScope() + p->name() + "_ids";
C << sp << nl << "namespace";
C << nl << "{";
@@ -3132,9 +2490,9 @@ Slice::Gen::ObjectVisitor::visitClassDefStart(const ClassDefPtr& p)
C << sp;
C << nl << "bool" << nl << scoped.substr(2)
- << "::ice_isA(const ::std::string& _s, const ::Ice::Current&) const";
+ << "::ice_isA(const ::std::string& s, const ::Ice::Current&) const";
C << sb;
- C << nl << "return ::std::binary_search(" << flatName << ", " << flatName << " + " << ids.size() << ", _s);";
+ C << nl << "return ::std::binary_search(" << flatName << ", " << flatName << " + " << ids.size() << ", s);";
C << eb;
C << sp;
@@ -3149,7 +2507,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 +2553,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,10 +2572,9 @@ 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 _iceDispatch(::IceInternal::Incoming&, const ::Ice::Current&);";
- string flatName = p->flattenedScope() + p->name() + "_all";
+ string flatName = "iceC" + p->flattenedScope() + p->name() + "_all";
C << sp << nl << "namespace";
C << nl << "{";
C << nl << "const ::std::string " << flatName << "[] =";
@@ -3232,11 +2591,11 @@ 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) << "::_iceDispatch(::IceInternal::Incoming& in, const ::Ice::Current& current)";
C << sb;
- C << nl << "::std::pair< const ::std::string*, const ::std::string*> r = "
+ C << nl << "::std::pair<const ::std::string*, const ::std::string*> r = "
<< "::std::equal_range(" << flatName << ", " << flatName << " + " << allOpNames.size()
<< ", current.operation);";
C << nl << "if(r.first == r.second)";
@@ -3252,15 +2611,17 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
{
C << nl << "case " << i++ << ':';
C << sb;
- C << nl << "return ___" << *q << "(in, current);";
+ C << nl << "return _iceD_" << *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()
@@ -3281,7 +2642,7 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
H << nl
<< "virtual ::Ice::Int ice_operationAttributes(const ::std::string&) const;";
- string opAttrFlatName = p->flattenedScope() + p->name() + "_operationAttributes";
+ string opAttrFlatName = "iceC" + p->flattenedScope() + p->name() + "_operationAttributes";
C << sp << nl << "namespace";
C << nl << "{";
@@ -3315,7 +2676,7 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
<< "::ice_operationAttributes(const ::std::string& opName) const";
C << sb;
- C << nl << "::std::pair< const ::std::string*, const ::std::string*> r = "
+ C << nl << "::std::pair<const ::std::string*, const ::std::string*> r = "
<< "::std::equal_range(" << flatName << ", " << flatName << " + " << allOpNames.size()
<< ", opName);";
C << nl << "if(r.first == r.second)";
@@ -3330,135 +2691,67 @@ 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 _iceWrite(::Ice::OutputStream*) const;";
+ H << nl << "virtual void _iceRead(::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 _iceWriteImpl(::Ice::OutputStream*) const;";
+ H << nl << "virtual void _iceReadImpl(::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) << "::_iceWrite(::Ice::OutputStream* ostr) const";
C << sb;
- C << nl << "__os->startWriteObject(__slicedData);";
- C << nl << "__writeImpl(__os);";
- C << nl << "__os->endWriteObject();";
+ C << nl << "ostr->startValue(_iceSlicedData);";
+ C << nl << "_iceWriteImpl(ostr);";
+ C << nl << "ostr->endValue();";
C << eb;
C << sp;
- C << nl << "void" << nl << scoped.substr(2) << "::__read(::IceInternal::BasicStream* __is)";
+ C << nl << "void" << nl << scoped.substr(2) << "::_iceRead(::Ice::InputStream* istr)";
C << sb;
- C << nl << "__is->startReadObject();";
- C << nl << "__readImpl(__is);";
- C << nl << "__slicedData = __is->endReadObject(true);";
+ C << nl << "istr->startValue();";
+ C << nl << "_iceReadImpl(istr);";
+ C << nl << "_iceSlicedData = istr->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) << "::_iceWriteImpl(::Ice::OutputStream* ostr) 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 << "ostr->startSlice(ice_staticId(), " << p->compactId() << (!base ? ", true" : ", false") << ");";
+ C << nl << "Ice::StreamWriter< ::" << scoped.substr(2) << ", ::Ice::OutputStream>::write(ostr, *this);";
+ C << nl << "ostr->endSlice();";
if(base)
{
- emitUpcall(base, "::__writeImpl(__os);");
+ emitUpcall(base, "::_iceWriteImpl(ostr);");
}
C << eb;
C << sp;
- C << nl << "void" << nl << scoped.substr(2) << "::__readImpl(::IceInternal::BasicStream* __is)";
+ C << nl << "void" << nl << scoped.substr(2) << "::_iceReadImpl(::Ice::InputStream* istr)";
C << sb;
- C << nl << "__is->startReadSlice();";
- writeMarshalUnmarshalDataMembers(C, p->dataMembers(), p->orderedOptionalDataMembers(), false);
- C << nl << "__is->endReadSlice();";
+ C << nl << "istr->startSlice();";
+ C << nl << "Ice::StreamReader< ::" << scoped.substr(2) << ", ::Ice::InputStream>::read(istr, *this);";
+ C << nl << "istr->endSlice();";
if(base)
{
- emitUpcall(base, "::__readImpl(__is);");
+ emitUpcall(base, "::_iceReadImpl(istr);");
}
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";
@@ -3466,23 +2759,23 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
if(!p->isAbstract())
{
- string initName = p->flattenedScope() + p->name() + "_init";
- C << sp << nl << "const ::IceInternal::DefaultObjectFactoryInit< " << scoped << "> "
+ string initName = "iceC" + p->flattenedScope() + p->name() + "_init";
+ 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 "
+ string initName = "iceC" + p->flattenedScope() + p->name() + "_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 +2784,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 +2795,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 _iceSlicedData;";
}
- if(!p->isLocal() && preserved && !basePreserved)
+ if(generateFriend)
{
if(!inProtected)
{
@@ -3551,7 +2844,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,59 +2857,30 @@ 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.
- //
- // 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.
+ // all of the globals in a compilation unit.
//
- 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 _iceS_" << p->name() << "_init = " << fixKwd(p->scoped()) << "::ice_factory();";
}
if(p->isLocal())
{
H << sp;
- H << nl << "inline bool operator==(const " << fixKwd(p->name()) << "& l, const " << fixKwd(p->name()) << "& r)";
+ H << nl << "inline bool operator==(const " << fixKwd(p->name()) << "& lhs, const " << fixKwd(p->name()) << "& rhs)";
H << sb;
- H << nl << "return static_cast<const ::Ice::LocalObject&>(l) == static_cast<const ::Ice::LocalObject&>(r);";
+ H << nl << "return static_cast<const ::Ice::LocalObject&>(lhs) == static_cast<const ::Ice::LocalObject&>(rhs);";
H << eb;
H << sp;
- H << nl << "inline bool operator<(const " << fixKwd(p->name()) << "& l, const " << fixKwd(p->name()) << "& r)";
+ H << nl << "inline bool operator<(const " << fixKwd(p->name()) << "& lhs, const " << fixKwd(p->name()) << "& rhs)";
H << sb;
- H << nl << "return static_cast<const ::Ice::LocalObject&>(l) < static_cast<const ::Ice::LocalObject&>(r);";
+ H << nl << "return static_cast<const ::Ice::LocalObject&>(lhs) < static_cast<const ::Ice::LocalObject&>(rhs);";
H << eb;
}
else
{
C << sp << nl << "void " << _dllExport;
- C << nl << scope.substr(2) << "__patch(" << p->name() << "Ptr& handle, const ::Ice::ObjectPtr& v)";
+ C << nl << scope.substr(2) << "_icePatchObjectPtr(" << p->name() << "Ptr& handle, const ::Ice::ObjectPtr& v)";
C << sb;
C << nl << "handle = " << scope << p->name() << "Ptr::dynamicCast(v);";
C << nl << "if(v && !handle)";
@@ -3621,14 +2890,14 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
C << eb;
H << sp;
- H << nl << "inline bool operator==(const " << fixKwd(p->name()) << "& l, const " << fixKwd(p->name()) << "& r)";
+ H << nl << "inline bool operator==(const " << fixKwd(p->name()) << "& lhs, const " << fixKwd(p->name()) << "& rhs)";
H << sb;
- H << nl << "return static_cast<const ::Ice::Object&>(l) == static_cast<const ::Ice::Object&>(r);";
+ H << nl << "return static_cast<const ::Ice::Object&>(lhs) == static_cast<const ::Ice::Object&>(rhs);";
H << eb;
H << sp;
- H << nl << "inline bool operator<(const " << fixKwd(p->name()) << "& l, const " << fixKwd(p->name()) << "& r)";
+ H << nl << "inline bool operator<(const " << fixKwd(p->name()) << "& lhs, const " << fixKwd(p->name()) << "& rhs)";
H << sb;
- H << nl << "return static_cast<const ::Ice::Object&>(l) < static_cast<const ::Ice::Object&>(r);";
+ H << nl << "return static_cast<const ::Ice::Object&>(lhs) < static_cast<const ::Ice::Object&>(rhs);";
H << eb;
}
@@ -3668,8 +2937,7 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p)
string classScopedAMD = classScope + classNameAMD;
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;
@@ -3709,10 +2977,6 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p)
{
paramsAMD += typeString;
paramsAMD += ", ";
- paramsDeclAMD += typeString;
- paramsDeclAMD += ' ';
- paramsDeclAMD += paramName;
- paramsDeclAMD += ", ";
argsAMD += paramName;
argsAMD += ", ";
}
@@ -3731,9 +2995,9 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p)
args += ", ";
}
- params += "const ::Ice::Current& = ::Ice::Current())";
- paramsDecl += "const ::Ice::Current& __current)";
- args += "__current)";
+ params += "const ::Ice::Current& = ::Ice::noExplicitCurrent)";
+ paramsDecl += "const ::Ice::Current& current)";
+ args += "current)";
}
else
{
@@ -3742,11 +3006,11 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p)
args += ')';
}
- paramsAMD += "const ::Ice::Current& = ::Ice::Current())";
- paramsDeclAMD += "const ::Ice::Current& __current)";
- argsAMD += "__current)";
+ paramsAMD += "const ::Ice::Current& = ::Ice::noExplicitCurrent)";
+ argsAMD += "current)";
- bool isConst = (p->mode() == Operation::Nonmutating) || p->hasMetaData("cpp:const");
+ string isConst = ((p->mode() == Operation::Nonmutating) || p->hasMetaData("cpp:const")) ? " const" : "";
+ string noExcept = (cl->isLocal() && p->hasMetaData("cpp:noexcept")) ? " ICE_NOEXCEPT" : "";
bool amd = !cl->isLocal() && (cl->hasMetaData("amd") || p->hasMetaData("amd"));
string deprecateSymbol = getDeprecateSymbol(p, cl);
@@ -3754,144 +3018,82 @@ 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 << noExcept << " = 0;";
}
else
{
- H << nl << deprecateSymbol << "virtual void " << name << "_async" << paramsAMD
- << (isConst ? " const" : "") << " = 0;";
+ H << nl << deprecateSymbol
+ << "virtual void " << name << "_async" << paramsAMD << isConst << noExcept << " = 0;";
}
if(!cl->isLocal())
{
- H << nl << "::Ice::DispatchStatus ___" << name
- << "(::IceInternal::Incoming&, const ::Ice::Current&)" << (isConst ? " const" : "") << ';';
+ H << nl << "bool _iceD_" << 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" : "");
+ //
+ // inS, ret, current etc. may shadow class-with-operations data members in C++98
+ //
+ C << nl << "bool" << nl << scope.substr(2) << "_iceD_" << name << "(::IceInternal::Incoming& inS"
+ << ", const ::Ice::Current& current)" << isConst;
C << sb;
- if(!amd)
- {
- 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.
- //
+ C << nl << "_iceCheckMode(" << operationModeToString(p->mode()) << ", current.mode);";
-#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* istr = 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 << "istr->readPendingValues();";
}
+ C << nl << "inS.endReadParams();";
+ }
+ else
+ {
+ C << nl << "inS.readEmptyParams();";
+ }
+ if(p->format() != DefaultFormat)
+ {
+ C << nl << "inS.setFormat(" << opFormatTypeToString(p, false) << ");";
+ }
- writeAllocateCode(C, outParams, 0, true, _useWstring);
- if(!throws.empty())
- {
- C << nl << "try";
- C << sb;
- }
+ if(!amd)
+ {
+ writeAllocateCode(C, outParams, 0, true, _useWstring, "ret");
C << nl;
if(ret)
{
- C << retS << " __ret = ";
+ C << retS << " ret = ";
}
- C << fixKwd(name) << args << ';';
+ C << "this->" << fixKwd(name) << args << ';';
if(ret || !outParams.empty())
{
- C << nl << "::IceInternal::BasicStream* __os = __inS.__startWriteParams("
- << opFormatTypeToString(p) << ");";
- writeMarshalCode(C, outParams, p, true);
+ C << nl << "::Ice::OutputStream* ostr = inS.startWriteParams();";
+ writeMarshalCode(C, outParams, p, true, 0);
if(p->returnsClasses(false))
{
- C << nl << "__os->writePendingObjects();";
+ C << nl << "ostr->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 << "this->" << name << "_async" << argsAMD << ';';
+ 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,25 +3125,19 @@ 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
- << "const ::Ice::CallbackPtr& __del"
- << "const ::Ice::LocalObjectPtr& __cookie = 0" << epar << " = 0;";
+ << "const ::Ice::CallbackPtr& del"
+ << "const ::Ice::LocalObjectPtr& cookie = 0" << epar << " = 0;";
string clScope = fixKwd(cl->scope());
string delName = "Callback_" + cl->name() + "_" + name;
string delNameScoped = clScope + delName;
H << sp << nl << "virtual ::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI
- << "const " + delNameScoped + "Ptr& __del"
- << "const ::Ice::LocalObjectPtr& __cookie = 0" << epar << " = 0;";
+ << "const " + delNameScoped + "Ptr& del"
+ << "const ::Ice::LocalObjectPtr& cookie = 0" << epar << " = 0;";
H << sp << nl << "virtual " << retS << " end_" << name << spar << outParamsDeclAMI
<< "const ::Ice::AsyncResultPtr&" << epar << " = 0;";
@@ -3952,7 +3148,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
@@ -3976,7 +3172,7 @@ Slice::Gen::ObjectVisitor::emitGCFunctions(const ClassDefPtr& p)
bool preserved = basePreserved || p->hasMetaData("preserve-slice");
//
- // __gcVisit() is overridden by the basemost class that can be
+ // _iceGcVisit() is overridden by the basemost class that can be
// cyclic, plus all classes derived from that class.
//
// We also override these methods for the initial preserved class in a
@@ -3984,22 +3180,22 @@ Slice::Gen::ObjectVisitor::emitGCFunctions(const ClassDefPtr& p)
//
if(canBeCyclic || (preserved && !basePreserved))
{
- H << nl << "virtual void __gcVisitMembers(::IceInternal::GCVisitor&);";
+ H << nl << "virtual void _iceGcVisitMembers(::IceInternal::GCVisitor&);";
- C << sp << nl << "void" << nl << scoped.substr(2) << "::__gcVisitMembers(::IceInternal::GCVisitor& _v)";
+ C << sp << nl << "void" << nl << scoped.substr(2) << "::_iceGcVisitMembers(::IceInternal::GCVisitor& v_)";
C << sb;
bool hasCyclicBase = base && base->canBeCyclic();
if(hasCyclicBase || basePreserved)
{
- emitUpcall(bases.front(), "::__gcVisitMembers(_v);");
+ emitUpcall(bases.front(), "::_iceGcVisitMembers(v_);");
}
if(preserved && !basePreserved)
{
- C << nl << "if(__slicedData)";
+ C << nl << "if(_iceSlicedData)";
C << sb;
- C << nl << "__slicedData->__gcVisitMembers(_v);";
+ C << nl << "_iceSlicedData->_iceGcVisitMembers(v_);";
C << eb;
}
@@ -4028,7 +3224,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;
@@ -4036,11 +3234,11 @@ Slice::Gen::ObjectVisitor::emitGCVisitCode(const TypePtr& p, const string& prefi
if(decl)
{
string scope = fixKwd(decl->scope());
- C << nl << "if((" << scope << "upCast(" << prefix << name << ".get())->__gcVisit(_v)))";
+ C << nl << "if((" << scope << "upCast(" << prefix << name << ".get())->_iceGcVisit(v_)))";
}
else
{
- C << nl << "if((" << prefix << name << ".get())->__gcVisit(_v))";
+ C << nl << "if((" << prefix << name << ".get())->_iceGcVisit(v_))";
}
C << sb;
C << nl << prefix << name << " = 0;";
@@ -4124,7 +3322,7 @@ Slice::Gen::ObjectVisitor::emitVirtualBaseInitializers(const ClassDefPtr& p, boo
{
upcall += ", ";
}
- upcall += "__ice_" + (*q)->name();
+ upcall += "iceP_" + (*q)->name();
}
upcall += ")";
@@ -4152,7 +3350,7 @@ Slice::Gen::ObjectVisitor::emitOneShotConstructor(const ClassDefPtr& p)
string typeName = inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring);
bool dataMember = std::find(dataMembers.begin(), dataMembers.end(), (*q)) != dataMembers.end();
allParamDecls.push_back(typeName + ((dataMember || callBaseConstuctors) ?
- (" __ice_" + (*q)->name()) : (" /*__ice_" + (*q)->name() + "*/")));
+ (" iceP_" + (*q)->name()) : (" /*iceP_" + (*q)->name() + "*/")));
}
H << sp << nl;
@@ -4192,7 +3390,7 @@ Slice::Gen::ObjectVisitor::emitOneShotConstructor(const ClassDefPtr& p)
H << ',' << nl;
}
string memberName = fixKwd((*q)->name());
- H << memberName << '(' << "__ice_" << (*q)->name() << ')';
+ H << memberName << '(' << "iceP_" << (*q)->name() << ')';
}
H.dec();
@@ -4215,7 +3413,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 +3451,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 +3460,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 +3498,6 @@ void
Slice::Gen::AsyncCallbackTemplateVisitor::visitModuleEnd(const ModulePtr&)
{
_useWstring = resetUseWstring(_useWstringHist);
-
H << sp << nl << '}';
}
@@ -4340,7 +3537,7 @@ Slice::Gen::AsyncCallbackTemplateVisitor::generateOperation(const OperationPtr&
TypePtr ret = p->returnType();
string retS = inputTypeToString(ret, p->returnIsOptional(), p->getMetaData(), _useWstring);
- string retEndArg = getEndArg(ret, p->getMetaData(), "__ret");
+ string retEndArg = getEndArg(ret, p->getMetaData(), "ret");
ParamDeclList outParams;
vector<string> outArgs;
@@ -4354,7 +3551,7 @@ Slice::Gen::AsyncCallbackTemplateVisitor::generateOperation(const OperationPtr&
if((*q)->isOutParam())
{
outParams.push_back(*q);
- outArgs.push_back(fixKwd((*q)->name()));
+ outArgs.push_back("iceP_" + (*q)->name());
outEndArgs.push_back(getEndArg((*q)->type(), (*q)->getMetaData(), outArgs.back()));
outDecls.push_back(inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring));
}
@@ -4441,11 +3638,11 @@ Slice::Gen::AsyncCallbackTemplateVisitor::generateOperation(const OperationPtr&
//
// completed.
//
- H << sp << nl << "virtual void completed(const ::Ice::AsyncResultPtr& __result) const";
+ H << sp << nl << "virtual void completed(const ::Ice::AsyncResultPtr& result) const";
H << sb;
- H << nl << clScope << clName << "Prx __proxy = " << clScope << clName
- << "Prx::uncheckedCast(__result->getProxy());";
- writeAllocateCode(H, outParams, p, false, _useWstring | TypeContextInParam | TypeContextAMICallPrivateEnd);
+ H << nl << clScope << clName << "Prx proxy = " << clScope << clName
+ << "Prx::uncheckedCast(result->getProxy());";
+ writeAllocateCode(H, outParams, p, true, _useWstring | TypeContextInParam | TypeContextAMICallPrivateEnd);
H << nl << "try";
H << sb;
H << nl;
@@ -4455,23 +3652,23 @@ Slice::Gen::AsyncCallbackTemplateVisitor::generateOperation(const OperationPtr&
{
H << retEndArg << " = ";
}
- H << "__proxy->end_" << p->name() << spar << outEndArgs << "__result" << epar << ';';
+ H << "proxy->end_" << p->name() << spar << outEndArgs << "result" << epar << ';';
}
else
{
- H << "__proxy->___end_" << p->name() << spar << outEndArgs;
+ H << "proxy->_iceI_end_" << p->name() << spar << outEndArgs;
if(ret)
{
H << retEndArg;
}
- H << "__result" << epar << ';';
+ H << "result" << epar << ';';
}
- writeEndCode(H, outParams, p);
+ writeEndCode(H, outParams, p, true);
H << eb;
H << nl << "catch(const ::Ice::Exception& ex)";
H << sb;
- H << nl << "" << baseD << "::exception(__result, ex);";
+ H << nl << "" << baseD << "::exception(result, ex);";
H << nl << "return;";
H << eb;
H << nl << "if(_response)";
@@ -4479,17 +3676,19 @@ Slice::Gen::AsyncCallbackTemplateVisitor::generateOperation(const OperationPtr&
H << nl << "(" << baseD << "::_callback.get()->*_response)" << spar;
if(ret)
{
- H << "__ret";
+ H << "ret";
}
H << outArgs;
if(withCookie)
{
- H << "CT::dynamicCast(__result->getCookie())";
+ H << "CT::dynamicCast(result->getCookie())";
}
H << epar << ';';
H << eb;
H << eb;
+ H.dec();
H << sp << nl << "private:";
+ H.inc();
H << sp << nl << "Response _response;";
}
H << eb << ';';
@@ -4574,57 +3773,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 +3783,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->enumerators();
+ 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 +3862,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 +3889,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 +3929,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 +3944,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 +3956,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 +3970,7 @@ Slice::Gen::ImplVisitor::visitClassDefStart(const ClassDefPtr& p)
{
C << ", ";
}
- C << fixKwd((*q)->name());
+ C << defaultValue((*q)->type(), op->getMetaData());
}
}
C << ");";
@@ -4897,17 +3988,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 +4007,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 +4020,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 +4041,7 @@ Slice::Gen::ImplVisitor::visitClassDefStart(const ClassDefPtr& p)
}
C.restoreIndent();
C << ')';
- C << (isConst ? " const" : "");
+ C << isConst;
C << sb;
if(ret)
@@ -4973,8 +4060,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)
{
}
@@ -5041,10 +4128,8 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p)
vector<string> args;
vector<string> paramsInvoke;
- vector<string> paramsDeclInvoke;
paramsInvoke.push_back("const " + proxyName + "&");
- paramsDeclInvoke.push_back("const " + proxyName + "& __prx");
TypePtr ret = p->returnType();
string retS = inputTypeToString(ret, p->returnIsOptional(), p->getMetaData(), _useWstring);
@@ -5053,8 +4138,8 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p)
{
params.push_back(retS);
paramsAMD.push_back(inputTypeToString(ret, p->returnIsOptional(), p->getMetaData(), _useWstring));
- paramsDecl.push_back(retS + " __ret");
- args.push_back("__ret");
+ paramsDecl.push_back(retS + " ret");
+ args.push_back("ret");
}
ParamDeclList inParams;
@@ -5078,23 +4163,30 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p)
else
{
paramsInvoke.push_back(typeString);
- paramsDeclInvoke.push_back(typeString + ' ' + paramName);
-
inParams.push_back(*q);
}
}
- paramsInvoke.push_back("const ::Ice::Context*");
- paramsDeclInvoke.push_back("const ::Ice::Context* __ctx");
+ paramsInvoke.push_back("const ::Ice::Context&");
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 +4278,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);
@@ -5210,8 +4286,8 @@ Slice::Gen::AsyncImplVisitor::visitOperation(const OperationPtr& p)
params += retS;
paramsDecl += retS;
paramsDecl += ' ';
- paramsDecl += "__ret";
- args += "__ret";
+ paramsDecl += "ret";
+ args += "ret";
}
ParamDeclList outParams;
@@ -5253,12 +4329,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 +4339,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* ostr = startWriteParams();";
writeMarshalCode(C, outParams, p, false, TypeContextInParam);
if(p->returnsClasses(false))
{
- C << nl << "__os->writePendingObjects();";
+ C << nl << "ostr->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 +4372,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 +4384,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 +4407,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 +4427,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 +4467,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 +4504,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();
@@ -5517,39 +4515,71 @@ Slice::Gen::MetaDataVisitor::visitUnitStart(const UnitPtr& p)
assert(dc);
StringList globalMetaData = dc->getMetaData();
int headerExtension = 0;
- for(StringList::const_iterator r = globalMetaData.begin(); r != globalMetaData.end(); ++r)
+ int sourceExtension = 0;
+ int dllExport = 0;
+ for(StringList::const_iterator r = globalMetaData.begin(); r != globalMetaData.end();)
{
- string s = *r;
- if(_history.count(s) == 0)
+ string s = *r++;
+ if(s.find(prefix) == 0)
{
- if(s.find(prefix) == 0)
+ static const string cppIncludePrefix = "cpp:include:";
+ static const string cppHeaderExtPrefix = "cpp:header-ext:";
+ static const string cppSourceExtPrefix = "cpp:source-ext:";
+ static const string cppDllExportPrefix = "cpp:dll-export:";
+
+ if(s.find(cppIncludePrefix) == 0 && s.size() > cppIncludePrefix.size())
{
- static const string cppIncludePrefix = "cpp:include:";
- static const string cppHeaderExtPrefix = "cpp:header-ext:";
- if(s.find(cppIncludePrefix) == 0 && s.size() > cppIncludePrefix.size())
+ continue;
+ }
+ else if(s.find(cppHeaderExtPrefix) == 0 && s.size() > cppHeaderExtPrefix.size())
+ {
+ headerExtension++;
+ if(headerExtension > 1)
{
- continue;
+ ostringstream ostr;
+ ostr << "ignoring invalid global metadata `" << s
+ << "': directive can appear only once per file";
+ dc->warning(InvalidMetaData, file, -1, ostr.str());
+ globalMetaData.remove(s);
}
- else if(s.find(cppHeaderExtPrefix) == 0 && s.size() > cppHeaderExtPrefix.size())
+ continue;
+ }
+ else if(s.find(cppSourceExtPrefix) == 0 && s.size() > cppSourceExtPrefix.size())
+ {
+ sourceExtension++;
+ if(sourceExtension > 1)
{
- headerExtension++;
- if(headerExtension > 1)
- {
- ostringstream ostr;
- ostr << "ignoring invalid global metadata `" << s
- << "': directive can appear only once per file";
- emitWarning(file, -1, ostr.str());
- _history.insert(s);
- }
- continue;
+ ostringstream ostr;
+ ostr << "ignoring invalid global metadata `" << s
+ << "': directive can appear only once per file";
+ dc->warning(InvalidMetaData, file, -1, ostr.str());
+ globalMetaData.remove(s);
}
- ostringstream ostr;
- ostr << "ignoring invalid global metadata `" << s << "'";
- emitWarning(file, -1, ostr.str());
+ continue;
+ }
+ else if(s.find(cppDllExportPrefix) == 0 && s.size() > cppDllExportPrefix.size())
+ {
+ dllExport++;
+ if(dllExport > 1)
+ {
+ ostringstream ostr;
+ ostr << "ignoring invalid global metadata `" << s
+ << "': directive can appear only once per file";
+ dc->warning(InvalidMetaData, file, -1, ostr.str());
+
+ globalMetaData.remove(s);
+ }
+ continue;
}
- _history.insert(s);
+
+ ostringstream ostr;
+ ostr << "ignoring invalid global metadata `" << s << "'";
+ dc->warning(InvalidMetaData, file, -1, ostr.str());
+ globalMetaData.remove(s);
}
+
}
+ dc->setMetaData(globalMetaData);
}
return true;
@@ -5558,7 +4588,8 @@ Slice::Gen::MetaDataVisitor::visitUnitStart(const UnitPtr& p)
bool
Slice::Gen::MetaDataVisitor::visitModuleStart(const ModulePtr& p)
{
- validate(p, p->getMetaData(), p->file(), p->line());
+ StringList metaData = validate(p, p->getMetaData(), p->file(), p->line());
+ p->setMetaData(metaData);
return true;
}
@@ -5570,13 +4601,15 @@ Slice::Gen::MetaDataVisitor::visitModuleEnd(const ModulePtr&)
void
Slice::Gen::MetaDataVisitor::visitClassDecl(const ClassDeclPtr& p)
{
- validate(p, p->getMetaData(), p->file(), p->line());
+ StringList metaData = validate(p, p->getMetaData(), p->file(), p->line());
+ p->setMetaData(metaData);
}
bool
Slice::Gen::MetaDataVisitor::visitClassDefStart(const ClassDefPtr& p)
{
- validate(p, p->getMetaData(), p->file(), p->line());
+ StringList metaData = validate(p, p->getMetaData(), p->file(), p->line());
+ p->setMetaData(metaData);
return true;
}
@@ -5588,7 +4621,8 @@ Slice::Gen::MetaDataVisitor::visitClassDefEnd(const ClassDefPtr&)
bool
Slice::Gen::MetaDataVisitor::visitExceptionStart(const ExceptionPtr& p)
{
- validate(p, p->getMetaData(), p->file(), p->line());
+ StringList metaData = validate(p, p->getMetaData(), p->file(), p->line());
+ p->setMetaData(metaData);
return true;
}
@@ -5600,7 +4634,8 @@ Slice::Gen::MetaDataVisitor::visitExceptionEnd(const ExceptionPtr&)
bool
Slice::Gen::MetaDataVisitor::visitStructStart(const StructPtr& p)
{
- validate(p, p->getMetaData(), p->file(), p->line());
+ StringList metaData = validate(p, p->getMetaData(), p->file(), p->line());
+ p->setMetaData(metaData);
return true;
}
@@ -5612,148 +4647,456 @@ Slice::Gen::MetaDataVisitor::visitStructEnd(const StructPtr&)
void
Slice::Gen::MetaDataVisitor::visitOperation(const OperationPtr& p)
{
-
- bool ami = false;
ClassDefPtr cl = ClassDefPtr::dynamicCast(p->container());
- if(cl->hasMetaData("amd") || p->hasMetaData("amd"))
- {
- ami = true;
- }
- if(p->hasMetaData("UserException"))
+ StringList metaData = p->getMetaData();
+
+ const UnitPtr unit = p->unit();
+ const DefinitionContextPtr dc = unit->findDefinitionContext(p->file());
+ assert(dc);
+ if(!cl->isLocal() && p->hasMetaData("cpp:noexcept"))
{
- if(!cl->isLocal())
- {
- ostringstream ostr;
- ostr << "ignoring invalid metadata `UserException': directive applies only to local operations "
- << "but enclosing " << (cl->isInterface() ? "interface" : "class") << "`" << cl->name()
- << "' is not local";
- emitWarning(p->file(), p->line(), ostr.str());
- }
+ dc->warning(InvalidMetaData, p->file(), p->line(),
+ "ignoring metadata `cpp:noexcept' for non local interface");
+ metaData.remove("cpp:noexcept");
}
- StringList metaData = p->getMetaData();
- metaData.remove("cpp:const");
-
TypePtr returnType = p->returnType();
- if(!metaData.empty())
+ if(!returnType)
{
- if(!returnType)
+ for(StringList::const_iterator q = metaData.begin(); q != metaData.end();)
{
- for(StringList::const_iterator q = metaData.begin(); q != metaData.end(); ++q)
+ string s = *q++;
+ if(s.find("cpp:type:") == 0 || s.find("cpp:view-type:") == 0 ||
+ s.find("cpp:range") == 0 || s == "cpp:array")
{
- if(q->find("cpp:type:", 0) == 0 || q->find("cpp:view-type:", 0) == 0
- || (*q) == "cpp:array" || q->find("cpp:range", 0) == 0)
- {
- emitWarning(p->file(), p->line(), "ignoring invalid metadata `" + *q +
- "' for operation with void return type");
- break;
- }
+ dc->warning(InvalidMetaData, p->file(), p->line(),
+ "ignoring invalid metadata `" + s + "' for operation with void return type");
+ metaData.remove(s);
+ continue;
}
}
- else
- {
- validate(returnType, metaData, p->file(), p->line(), ami);
- }
+ }
+ else
+ {
+ metaData = validate(returnType, metaData, p->file(), p->line(), true);
}
+ p->setMetaData(metaData);
+
ParamDeclList params = p->parameters();
for(ParamDeclList::iterator q = params.begin(); q != params.end(); ++q)
{
- validate((*q)->type(), (*q)->getMetaData(), p->file(), (*q)->line(), ami || !(*q)->isOutParam());
+ metaData = validate((*q)->type(), (*q)->getMetaData(), p->file(), (*q)->line(), true);
+ (*q)->setMetaData(metaData);
}
}
void
Slice::Gen::MetaDataVisitor::visitDataMember(const DataMemberPtr& p)
{
- validate(p->type(), p->getMetaData(), p->file(), p->line());
+ StringList metaData = validate(p->type(), p->getMetaData(), p->file(), p->line());
+ p->setMetaData(metaData);
}
void
Slice::Gen::MetaDataVisitor::visitSequence(const SequencePtr& p)
{
- validate(p, p->getMetaData(), p->file(), p->line());
+ StringList metaData = validate(p, p->getMetaData(), p->file(), p->line());
+ p->setMetaData(metaData);
}
void
Slice::Gen::MetaDataVisitor::visitDictionary(const DictionaryPtr& p)
{
- validate(p, p->getMetaData(), p->file(), p->line());
+ StringList metaData = validate(p, p->getMetaData(), p->file(), p->line());
+ p->setMetaData(metaData);
}
void
Slice::Gen::MetaDataVisitor::visitEnum(const EnumPtr& p)
{
- validate(p, p->getMetaData(), p->file(), p->line());
+ StringList metaData = validate(p, p->getMetaData(), p->file(), p->line());
+ p->setMetaData(metaData);
}
void
Slice::Gen::MetaDataVisitor::visitConst(const ConstPtr& p)
{
- validate(p, p->getMetaData(), p->file(), p->line());
+ StringList metaData = validate(p, p->getMetaData(), p->file(), p->line());
+ p->setMetaData(metaData);
}
-void
+StringList
Slice::Gen::MetaDataVisitor::validate(const SyntaxTreeBasePtr& cont, const StringList& metaData,
- const string& file, const string& line, bool /*inParam*/)
+ const string& file, const string& line, bool operation)
{
- static const string prefix = "cpp:";
- for(StringList::const_iterator p = metaData.begin(); p != metaData.end(); ++p)
+ static const string cppPrefix = "cpp:";
+ static const string cpp11Prefix = "cpp11:";
+ static const string cpp98Prefix = "cpp98:";
+
+ const UnitPtr unit = cont->unit();
+ const DefinitionContextPtr dc = unit->findDefinitionContext(file);
+ assert(dc);
+ StringList newMetaData = metaData;
+ for(StringList::const_iterator p = newMetaData.begin(); p != newMetaData.end();)
{
- string s = *p;
- if(_history.count(s) == 0)
+ string s = *p++;
+
+ string prefix;
+ bool cpp98 = false;
+ bool cpp11 = false;
+
+ if(s.find(cppPrefix) == 0)
{
- if(s.find(prefix) == 0)
+ prefix = cppPrefix;
+ }
+ else if(s.find(cpp98Prefix) == 0)
+ {
+ prefix = cpp98Prefix;
+ cpp98 = true;
+ }
+ else if(s.find(cpp11Prefix) == 0)
+ {
+ prefix = cpp11Prefix;
+ cpp11 = true;
+ }
+
+ if(s == "cpp:const" && operation)
+ {
+ continue;
+ }
+ if(!prefix.empty())
+ {
+ string ss = s.substr(prefix.size());
+ if(ss == "type:wstring" || ss == "type:string")
{
- string ss = s.substr(prefix.size());
- if(ss == "type:wstring" || ss == "type:string")
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(cont);
+ ModulePtr module = ModulePtr::dynamicCast(cont);
+ ClassDefPtr clss = ClassDefPtr::dynamicCast(cont);
+ StructPtr strct = StructPtr::dynamicCast(cont);
+ ExceptionPtr exception = ExceptionPtr::dynamicCast(cont);
+ if((builtin && builtin->kind() == Builtin::KindString) || module || clss || strct || exception)
{
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(cont);
- ModulePtr module = ModulePtr::dynamicCast(cont);
- ClassDefPtr clss = ClassDefPtr::dynamicCast(cont);
- StructPtr strct = StructPtr::dynamicCast(cont);
- ExceptionPtr exception = ExceptionPtr::dynamicCast(cont);
- if((builtin && builtin->kind() == Builtin::KindString) || module || clss || strct || exception)
- {
- continue;
- }
- }
- if(BuiltinPtr::dynamicCast(cont) && (ss.find("type:") == 0 || ss.find("view-type:") == 0))
- {
- if(BuiltinPtr::dynamicCast(cont)->kind() == Builtin::KindString)
- {
- continue;
- }
- }
- if(SequencePtr::dynamicCast(cont))
- {
- if(ss.find("type:") == 0 || ss.find("view-type:") == 0 || ss == "array" || ss.find("range") == 0)
- {
- continue;
- }
+ continue;
}
- if(DictionaryPtr::dynamicCast(cont) && (ss.find("type:") == 0 || ss.find("view-type:") == 0))
+ }
+ if(BuiltinPtr::dynamicCast(cont) && (ss.find("type:") == 0 || ss.find("view-type:") == 0))
+ {
+ if(BuiltinPtr::dynamicCast(cont)->kind() == Builtin::KindString)
{
continue;
}
- if(StructPtr::dynamicCast(cont) && (ss == "class" || ss == "comparable"))
+ }
+ if(SequencePtr::dynamicCast(cont))
+ {
+ if(ss.find("type:") == 0 || ss.find("view-type:") == 0 || ss == "array" || ss.find("range") == 0)
{
continue;
}
- if(ClassDefPtr::dynamicCast(cont) && ss == "virtual")
+ }
+ if(DictionaryPtr::dynamicCast(cont) && (ss.find("type:") == 0 || ss.find("view-type:") == 0))
+ {
+ continue;
+ }
+ if(!cpp11 && StructPtr::dynamicCast(cont) && (ss == "class" || ss == "comparable"))
+ {
+ 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")
+ }
+ if(ExceptionPtr::dynamicCast(cont) && ss == "ice_print")
+ {
+ continue;
+ }
+ if(!cpp11 && EnumPtr::dynamicCast(cont) && ss == "scoped")
+ {
+ 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 + "'");
}
- _history.insert(s);
+
+ dc->warning(InvalidMetaData, file, line, "ignoring invalid metadata `" + s + "'");
+ newMetaData.remove(s);
+ continue;
+ }
+
+ if(s.find("delegate") == 0)
+ {
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(cont);
+ if(cl && cl->isDelegate())
+ {
+ continue;
+ }
+
+ dc->warning(InvalidMetaData, file, line, "ignoring invalid metadata `" + s + "'");
+ newMetaData.remove(s);
+ continue;
}
}
+ return newMetaData;
+}
+
+
+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",
+ "scoped",
+ "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
@@ -5794,3 +5137,2895 @@ Slice::Gen::getHeaderExt(const string& file, const UnitPtr& unit)
}
return ext;
}
+
+string
+Slice::Gen::getSourceExt(const string& file, const UnitPtr& unit)
+{
+ string ext;
+ static const string sourceExtPrefix = "cpp:source-ext:";
+ DefinitionContextPtr dc = unit->findDefinitionContext(file);
+ assert(dc);
+ string meta = dc->findMetaData(sourceExtPrefix);
+ if(meta.size() > sourceExtPrefix.size())
+ {
+ ext = meta.substr(sourceExtPrefix.size());
+ }
+ 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 << "iceC" + p->flattenedScope() + p->name() + "_init" << "(\"" << p->scoped() << "\");";
+
+ if(p->compactId() >= 0)
+ {
+ string n = "iceC" + 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 iceC" << 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 iceC" << 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 << "iceC" + 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 = "iceC" + 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 + " iceP_" + (*q)->name());
+ }
+
+ if(base)
+ {
+ baseDataMembers = base->allDataMembers();
+ for(DataMemberList::const_iterator q = baseDataMembers.begin(); q != baseDataMembers.end(); ++q)
+ {
+ baseParams.push_back("iceP_" + (*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 << "();";
+
+ // Default copy ctor
+ H << sp << nl << name << "(const " << name << "&) = default;";
+
+ C << sp;
+ C << nl << scoped.substr(2) << "::~" << name << "()";
+ C << sb;
+ C << eb;
+
+ if(p->isLocal())
+ {
+ H << sp << nl << name << "(const char* file_, int line_) : ";
+ H << "::Ice::LocalExceptionHelper" << "<" << templateParameters << ">";
+ H << "(file_, line_)";
+ H << sb;
+ H << eb;
+ }
+ else
+ {
+ H << sp << nl << name << "() = default;";
+ }
+
+ if(!allDataMembers.empty())
+ {
+ H << sp << nl << name << "(";
+ if(p->isLocal())
+ {
+ H << "const char* file_, int 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 << "file_, 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(iceP_" << (*q)->name() << ")";
+ }
+ else
+ {
+ H << "iceP_" << (*q)->name();
+ }
+ }
+
+ H << ")";
+ if(!dataMembers.empty())
+ {
+ H << ",";
+ }
+ }
+ else if(p->isLocal())
+ {
+ H << " ::Ice::LocalExceptionHelper" << "<" << templateParameters << ">";
+ H << "(file_, 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(iceP_" << (*q)->name() << "))";
+ }
+ else
+ {
+ H << nl << fixKwd((*q)->name()) << "(iceP_" << (*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* ostr) const";
+ C << sb;
+ C << nl << "ostr->startException(_slicedData);";
+ C << nl << "_writeImpl(ostr);";
+ C << nl << "ostr->endException();";
+ C << eb;
+
+ C << sp << nl << "void" << nl << scoped.substr(2) << "::_read(::Ice::InputStream* istr)";
+ C << sb;
+ C << nl << "istr->startException();";
+ C << nl << "_readImpl(istr);";
+ C << nl << "_slicedData = istr->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 << " _iceS_" << 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 = "iceC" + 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& context = 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 + "_iceI_" + name);
+ for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end(); ++q)
+ {
+ H << fixKwd(paramPrefix + (*q)->name());
+ }
+ H << "context" << 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& context = 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 + "_iceI_" + name);
+ for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end(); ++q)
+ {
+ H << fixKwd(paramPrefix + (*q)->name());
+ }
+ H << "context" << 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, " context") + " = 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& context)";
+ 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* istr)";
+ C << sb;
+ C << nl << "istr->startEncapsulation();";
+ writeAllocateCode(C, outParams, p, true, _useWstring | TypeContextInParam | TypeContextCpp11);
+ writeUnmarshalCode(C, outParams, p, true, _useWstring | TypeContextInParam | TypeContextCpp11);
+
+ if(p->returnsClasses(false))
+ {
+ C << nl << "istr->readPendingValues();";
+ }
+ C << nl << "istr->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, true) << ", context, ";
+ 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 _makeLamdaOutgoing<" << futureT << ">" << spar;
+
+ H << (futureOutParams.size() > 1 ? "responseCb" : "response") << "ex" << "sent" << "this";
+ H << string("&" + scoped + "_iceI_" + name);
+ for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end(); ++q)
+ {
+ H << fixKwd(paramPrefix + (*q)->name());
+ }
+ H << "context" << epar << ";";
+ H << eb;
+ }
+
+ //
+ // Private implementation
+ //
+
+ H << sp;
+ H << nl << _dllMemberExport << "void _iceI_" << 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 << "_iceI_" << name << spar;
+ C << "const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<" + futureT + ">>& outAsync";
+ C << inParamsDecl << "const ::Ice::Context& context";
+ C << epar;
+ C << sb;
+ if(p->returnsData())
+ {
+ C << nl << "_checkTwowayOnly(" << flatName << ");";
+ }
+ C << nl << "outAsync->invoke(" << flatName << ", ";
+ C << operationModeToString(p->sendMode(), true) << ", " << opFormatTypeToString(p, true) << ", context, ";
+ 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* istr)";
+ C << sb;
+ C << nl << futureT << " v;";
+ writeUnmarshalCode(C, outParams, p, false, _useWstring | TypeContextCpp11, "", returnValueS, "v");
+
+ if(p->returnsClasses(false))
+ {
+ C << nl << "istr->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* istr)";
+ C << sb;
+
+ writeAllocateCode(C, outParams, p, true, _useWstring | TypeContextCpp11);
+ writeUnmarshalCode(C, outParams, p, true, _useWstring | TypeContextCpp11);
+
+ if(p->returnsClasses(false))
+ {
+ C << nl << "istr->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->enumerators();
+ //
+ // 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 << 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 + " iceP_" + (*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;";
+ }
+
+ H << sp << nl << name << "(const " << name << "&) = default;";
+ H << nl << name << "(" << name << "&&) = default;";
+ H << nl << name << "& operator=(const " << name << "&) = default;";
+ H << nl << name << "& operator=(" << 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 noExcept = p->hasMetaData("cpp:noexcept") ? " noexcept" : "";
+
+ string deprecateSymbol = getDeprecateSymbol(p, cl);
+
+ H << sp;
+ H << nl << deprecateSymbol << "virtual " << retS << ' ' << fixKwd(name) << params << isConst << noExcept << " = 0;";
+
+ if(cl->hasMetaData("async-oneway") || p->hasMetaData("async-oneway"))
+ {
+ vector<string> paramsDeclAMI;
+ vector<string> outParamsDeclAMI;
+ vector<string> paramsArgAMI;
+ 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);
+ paramsArgAMI.push_back(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 = paramsArgAMI.begin(); i != paramsArgAMI.end(); ++i)
+ {
+ H << *i << ",";
+ }
+ if(!paramsArgAMI.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 = "iceC" + 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 = "iceC" + p->flattenedScope() + p->name() + "_ops";
+
+ H << sp;
+ H << nl << "virtual bool _iceDispatch(::IceInternal::Incoming&, const ::Ice::Current&) override;";
+
+ C << sp;
+ C << nl << "bool";
+ C << nl << scoped.substr(2) << "::_iceDispatch(::IceInternal::Incoming& in, const ::Ice::Current& current)";
+ C << sb;
+
+ C << nl << "::std::pair<const ::std::string*, const ::std::string*> r = "
+ << "::std::equal_range(" << flatName << ", " << flatName << " + " << allOpNames.size() << ", current.operation);";
+ C << nl << "if(r.first == r.second)";
+ C << sb;
+ C << nl << "throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.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 _iceD_" << *q << "(in, current);";
+ C << eb;
+ }
+ 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;
+ }
+
+ 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("inA->response<" + resultName + ">()");
+ }
+ else
+ {
+ params.push_back("::std::function<void(" + joinString(responseParams, ",") + ")>");
+ args.push_back(ret || !outParams.empty() ? "responseCB" : "inA->response()");
+ }
+ params.push_back("::std::function<void(::std::exception_ptr)>");
+ args.push_back("inA->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 << "ostr->startEncapsulation(current.encoding, " << opFormatTypeToString(p, true) << ");";
+ writeMarshalCode(C, outParams, p, true, TypeContextCpp11, "ostr");
+ if(p->returnsClasses(false))
+ {
+ C << nl << "ostr->writePendingValues();";
+ }
+ C << nl << "ostr->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 _iceD_" << name << "(::IceInternal::Incoming&, const ::Ice::Current&)" << isConst << ';';
+
+ C << sp;
+ C << nl << "bool";
+ C << nl << scope.substr(2);
+ C << "_iceD_" << name << "(::IceInternal::Incoming& inS" << ", const ::Ice::Current& current)" << isConst;
+ C << sb;
+ C << nl << "_iceCheckMode(" << operationModeToString(p->mode(), true) << ", current.mode);";
+
+ if(!inParams.empty())
+ {
+ C << nl << "auto istr = inS.startReadParams();";
+ writeAllocateCode(C, inParams, 0, true, _useWstring | TypeContextInParam | TypeContextCpp11);
+ writeUnmarshalCode(C, inParams, 0, true, _useWstring | TypeContextInParam | TypeContextCpp11);
+ if(p->sendsClasses(false))
+ {
+ C << nl << "istr->readPendingValues();";
+ }
+ C << nl << "inS.endReadParams();";
+ }
+ else
+ {
+ C << nl << "inS.readEmptyParams();";
+ }
+ if(p->format() != DefaultFormat)
+ {
+ C << nl << "inS.setFormat(" << opFormatTypeToString(p, true) << ");";
+ }
+
+ 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 << "this->" << opName << spar << args << epar;
+ if(p->hasMarshaledResult())
+ {
+ C << ");";
+ }
+ else
+ {
+ C << ";";
+ if(ret || !outParams.empty())
+ {
+ C << nl << "auto ostr = inS.startWriteParams();";
+ writeMarshalCode(C, outParams, p, true, TypeContextCpp11);
+ if(p->returnsClasses(false))
+ {
+ C << nl << "ostr->writePendingValues();";
+ }
+ C << nl << "inS.endWriteParams();";
+ }
+ else
+ {
+ C << nl << "inS.writeEmptyParams();";
+ }
+ }
+ C << nl << "return false;";
+ }
+ else
+ {
+ C << nl << "auto inA = ::IceInternal::IncomingAsync::create(inS);";
+ if(!p->hasMarshaledResult() && (ret || !outParams.empty()))
+ {
+ C << nl << "auto responseCB = [inA]" << spar << responseParamsDecl << epar;
+ C << sb;
+ C << nl << "auto ostr = inA->startWriteParams();";
+ writeMarshalCode(C, outParams, p, true, TypeContextCpp11);
+ if(p->returnsClasses(false))
+ {
+ C << nl << "ostr->writePendingValues();";
+ }
+ C << nl << "inA->endWriteParams();";
+ C << nl << "inA->completed();";
+ C << eb << ';';
+ }
+ C << nl << "this->" << 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;";
+
+ H << sp << nl << name << "(const " << name << "&) = default;";
+ H << nl << name << "(" << name << "&&) = default;";
+ H << nl << name << "& operator=(const " << name << "&) = default;";
+ H << nl << name << "& operator=(" << 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 _iceWrite(::Ice::OutputStream*) const override;";
+ H << nl << "virtual void _iceRead(::Ice::InputStream*) override;";
+
+ C << sp;
+ C << nl << "void" << nl << scoped.substr(2) << "::_iceWrite(::Ice::OutputStream* ostr) const";
+ C << sb;
+ C << nl << "ostr->startValue(_iceSlicedData);";
+ C << nl << "_iceWriteImpl(ostr);";
+ C << nl << "ostr->endValue();";
+ C << eb;
+
+ C << sp;
+ C << nl << "void" << nl << scoped.substr(2) << "::_iceRead(::Ice::InputStream* istr)";
+ C << sb;
+ C << nl << "istr->startValue();";
+ C << nl << "_iceReadImpl(istr);";
+ C << nl << "_iceSlicedData = istr->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> _iceSlicedData;";
+ }
+
+ 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()) << " _iceS_" << 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(iceP_" + (*q)->name() + ")";
+ }
+ else
+ {
+ upcall += "iceP_" + (*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 + " iceP_" + (*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(iceP_" << (*q)->name() << "))";
+ }
+ else
+ {
+ H << memberName << "(iceP_" << (*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->enumerators();
+ 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;
+}